dvander@498: /**
ds@653: * vim: set ts=4 :
ds@1330: * =============================================================================
dvander@1231: * SourceMod
ds@1947: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
ds@1330: * =============================================================================
dvander@562: *
ds@1330: * This program is free software; you can redistribute it and/or modify it under
ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330: * Free Software Foundation.
dvander@1231: *
ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
ds@1330: * details.
dvander@1231: *
ds@1330: * You should have received a copy of the GNU General Public License along with
ds@1330: * this program. If not, see .
dvander@1231: *
ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in
ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants
ds@1330: * this exception to all derivative works. AlliedModders LLC defines further
ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330: * or .
dvander@562: *
dvander@562: * Version: $Id$
dvander@562: */
dvander@498:
dvander@498: #include "sm_globals.h"
ds@696: #include "HalfLife2.h"
dvander@498: #include "sourcemm_api.h"
dvander@498: #include "HandleSys.h"
ds@580: #include "ConVarManager.h"
ds@579: #include "ConCmdManager.h"
dvander@514: #include "PluginSys.h"
dvander@518: #include "sm_stringutil.h"
dvander@591: #include "PlayerManager.h"
dvander@893: #include "ChatTriggers.h"
dvander@1429: #include "AdminCache.h"
ds@936: #include
ds@936: #include
faluco@1643: #include
ds@936:
ds@2400: #if SOURCE_ENGINE == SE_LEFT4DEAD
ds@2400: #define NET_SETCONVAR 6
ds@2400: #else
ds@936: #define NET_SETCONVAR 5
ds@2400: #endif
dvander@498:
ds@714: enum ConVarBounds
ds@714: {
ds@714: ConVarBound_Upper = 0,
ds@714: ConVarBound_Lower
ds@714: };
ds@714:
dvander@1119: HandleType_t hCmdIterType = 0;
dvander@1795: HandleType_t htConCmdIter = 0;
dvander@1119:
dvander@1119: struct GlobCmdIter
dvander@1119: {
dvander@1119: bool started;
dvander@1119: List::iterator iter;
dvander@1119: };
dvander@1119:
dvander@1795: struct ConCmdIter
dvander@1795: {
ds@2400: #if SOURCE_ENGINE == SE_LEFT4DEAD
ds@2400: ICvarIteratorInternal *pLast;
ds@2400: #else
dvander@1795: const ConCommandBase *pLast;
ds@2400: #endif
dvander@1795: };
dvander@1795:
dvander@1119: class ConsoleHelpers :
dvander@1119: public SMGlobalClass,
dvander@1119: public IHandleTypeDispatch
dvander@1119: {
dvander@1119: public:
dvander@1119: virtual void OnSourceModAllInitialized()
dvander@1119: {
dvander@1119: HandleAccess access;
dvander@1795:
dvander@1119: g_HandleSys.InitAccessDefaults(NULL, &access);
dvander@1795:
dvander@1795: htConCmdIter = g_HandleSys.CreateType("ConCmdIter", this, 0, NULL, &access, g_pCoreIdent, NULL);
dvander@1795:
dvander@1119: access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER | HANDLE_RESTRICT_IDENTITY;
dvander@1119:
dvander@1795: hCmdIterType = g_HandleSys.CreateType("CmdIter", this, 0, NULL, &access, g_pCoreIdent, NULL);
dvander@1119: }
dvander@1119: virtual void OnHandleDestroy(HandleType_t type, void *object)
dvander@1119: {
dvander@1795: if (type == hCmdIterType)
dvander@1795: {
dvander@1795: GlobCmdIter *iter = (GlobCmdIter *)object;
dvander@1795: delete iter;
dvander@1795: }
dvander@1795: else if (type == htConCmdIter)
dvander@1795: {
dvander@1795: ConCmdIter *iter = (ConCmdIter * )object;
ds@2439: #if SOURCE_ENGINE == SE_LEFT4DEAD
ds@2439: // ICvarIteratorInternal has no virtual destructor
ds@2439: g_pMemAlloc->Free(iter->pLast);
ds@2439: #endif
dvander@1795: delete iter;
dvander@1795: }
dvander@1795: }
dvander@1795: virtual bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
dvander@1795: {
dvander@1795: if (type == htConCmdIter)
dvander@1795: {
dvander@1795: *pSize = sizeof(ConCmdIter);
dvander@1795: return true;
dvander@1795: }
dvander@1795: else if (type == hCmdIterType)
dvander@1795: {
dvander@1795: *pSize = sizeof(GlobCmdIter);
dvander@1795: return true;
dvander@1795: }
dvander@1795: return false;
dvander@1119: }
dvander@1119: } s_ConsoleHelpers;
dvander@1119:
faluco@1643: class CommandFlagsHelper : public IConCommandTracker
faluco@1643: {
faluco@1643: public:
faluco@1643: void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
faluco@1643: {
faluco@1643: m_CmdFlags.remove(name);
faluco@1643: }
faluco@1643: bool GetFlags(const char *name, int *flags)
faluco@1643: {
faluco@1643: ConCommandBase **ppCmd;
faluco@1643: ConCommandBase *pCmd;
faluco@1643: if ((ppCmd=m_CmdFlags.retrieve(name)))
faluco@1643: {
faluco@1643: TrackConCommandBase((*ppCmd), this);
faluco@1643: *flags = (*ppCmd)->GetFlags();
faluco@1643: return true;
faluco@1643: }
ds@2400: else if ((pCmd=FindCommandBase(name)))
faluco@1643: {
faluco@1643: m_CmdFlags.insert(name, pCmd);
faluco@1643: TrackConCommandBase(pCmd, this);
faluco@1643: *flags = pCmd->GetFlags();
faluco@1643: return true;
faluco@1643: }
faluco@1643: else
faluco@1643: {
faluco@1643: return false;
faluco@1643: }
faluco@1643: }
faluco@1643: bool SetFlags(const char *name, int flags)
faluco@1643: {
faluco@1643: ConCommandBase **ppCmd;
faluco@1643: ConCommandBase *pCmd;
faluco@1643: if ((ppCmd=m_CmdFlags.retrieve(name)))
faluco@1643: {
faluco@1643: (*ppCmd)->SetFlags(flags);
faluco@1643: TrackConCommandBase((*ppCmd), this);
faluco@1643: return true;
faluco@1643: }
ds@2400: else if ((pCmd=FindCommandBase(name)))
faluco@1643: {
faluco@1643: m_CmdFlags.insert(name, pCmd);
faluco@1643: pCmd->SetFlags(flags);
faluco@1643: TrackConCommandBase(pCmd, this);
faluco@1643: return true;
faluco@1643: }
faluco@1643: else
faluco@1643: {
faluco@1643: return false;
faluco@1643: }
faluco@1643: }
faluco@1643: private:
faluco@1643: KTrie m_CmdFlags;
faluco@1643: } s_CommandFlagsHelper;
faluco@1643:
ds@2400: #if SOURCE_ENGINE >= SE_ORANGEBOX
ds@936: static void ReplicateConVar(ConVar *pConVar)
ds@936: {
ds@936: int maxClients = g_Players.GetMaxClients();
ds@936:
ds@936: char data[256];
ds@936: bf_write buffer(data, sizeof(data));
ds@936:
ds@936: buffer.WriteUBitLong(NET_SETCONVAR, 5);
ds@936: buffer.WriteByte(1);
ds@936: buffer.WriteString(pConVar->GetName());
ds@936: buffer.WriteString(pConVar->GetString());
ds@936:
ds@936: for (int i = 1; i <= maxClients; i++)
ds@936: {
ds@936: CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
ds@936:
ds@936: if (pPlayer && pPlayer->IsInGame() && !pPlayer->IsFakeClient())
ds@936: {
ds@936: INetChannel *netchan = static_cast(engine->GetPlayerNetInfo(i));
ds@936: netchan->SendData(buffer);
ds@936: }
ds@936: }
ds@936: }
ds@936:
ds@936: static void NotifyConVar(ConVar *pConVar)
ds@936: {
ds@936: IGameEvent *pEvent = gameevents->CreateEvent("server_cvar");
ds@936: pEvent->SetString("cvarname", pConVar->GetName());
faluco@1541: if (IsFlagSet(pConVar, FCVAR_PROTECTED))
ds@936: {
ds@936: pEvent->SetString("cvarvalue", "***PROTECTED***");
dvander@1582: }
dvander@1582: else
dvander@1582: {
ds@936: pEvent->SetString("cvarvalue", pConVar->GetString());
ds@936: }
ds@936:
ds@936: gameevents->FireEvent(pEvent);
ds@936: }
ds@2397: #endif
ds@936:
dvander@498: static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: char *name, *defaultVal, *helpText;
dvander@498:
dvander@498: pContext->LocalToString(params[1], &name);
dvander@498:
dvander@498: // While the engine seems to accept a blank convar name, it causes a crash upon server quit
dvander@498: if (name == NULL || strcmp(name, "") == 0)
dvander@498: {
ds@582: return pContext->ThrowNativeError("Convar with blank name is not permitted");
dvander@498: }
dvander@498:
dvander@498: pContext->LocalToString(params[2], &defaultVal);
dvander@498: pContext->LocalToString(params[3], &helpText);
dvander@498:
dvander@498: bool hasMin = params[5] ? true : false;
dvander@498: bool hasMax = params[7] ? true : false;
dvander@498: float min = sp_ctof(params[6]);
dvander@498: float max = sp_ctof(params[8]);
dvander@498:
ds@582: Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
ds@582:
ds@582: if (hndl == BAD_HANDLE)
ds@582: {
dvander@1582: return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same might already exist.", name);
ds@582: }
ds@582:
ds@582: return hndl;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: char *name;
dvander@498:
dvander@498: pContext->LocalToString(params[1], &name);
dvander@498:
dvander@498: return g_ConVarManager.FindConVar(name);
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@582: IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582:
ds@582: if (!pFunction)
ds@582: {
ds@582: return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582: }
ds@582:
ds@582: g_ConVarManager.HookConVarChange(pConVar, pFunction);
dvander@498:
dvander@498: return 1;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@582: IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582:
ds@582: if (!pFunction)
ds@582: {
ds@582: return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582: }
ds@582:
ds@582: g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
dvander@498:
dvander@498: return 1;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: return pConVar->GetBool();
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: return pConVar->GetInt();
dvander@498: }
dvander@498:
dvander@498: /* This handles both SetConVarBool() and SetConVarInt() */
dvander@498: static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: pConVar->SetValue(params[2]);
dvander@498:
ds@2400: #if SOURCE_ENGINE >= SE_ORANGEBOX
ds@936: /* Should we replicate it? */
faluco@1541: if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@936: {
ds@936: ReplicateConVar(pConVar);
ds@936: }
ds@936:
ds@936: /* Should we notify clients? */
faluco@1541: if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@936: {
ds@936: NotifyConVar(pConVar);
ds@936: }
ds@2396: #endif
ds@936:
dvander@498: return 1;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: float value = pConVar->GetFloat();
dvander@498:
dvander@498: return sp_ftoc(value);
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
dvander@498: float value = sp_ctof(params[2]);
ds@576: pConVar->SetValue(value);
dvander@498:
ds@2400: #if SOURCE_ENGINE >= SE_ORANGEBOX
ds@936: /* Should we replicate it? */
faluco@1541: if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@936: {
ds@936: ReplicateConVar(pConVar);
ds@936: }
ds@936:
ds@936: /* Should we notify clients? */
faluco@1541: if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@936: {
ds@936: NotifyConVar(pConVar);
ds@936: }
ds@2396: #endif
ds@936:
dvander@498: return 1;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
dvander@498:
dvander@498: return 1;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
dvander@498: char *value;
dvander@498: pContext->LocalToString(params[2], &value);
dvander@498:
ds@576: pConVar->SetValue(value);
dvander@498:
ds@2400: #if SOURCE_ENGINE >= SE_ORANGEBOX
ds@936: /* Should we replicate it? */
faluco@1541: if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@936: {
ds@936: ReplicateConVar(pConVar);
ds@936: }
ds@936:
ds@936: /* Should we notify clients? */
faluco@1541: if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@936: {
ds@936: NotifyConVar(pConVar);
ds@936: }
ds@2396: #endif
ds@936:
dvander@498: return 1;
dvander@498: }
dvander@498:
ds@1301: static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
ds@1301: {
ds@1301: Handle_t hndl = static_cast(params[1]);
ds@1301: HandleError err;
ds@1301: ConVar *pConVar;
ds@1301:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
ds@1301: != HandleError_None)
ds@1301: {
ds@1301: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
ds@1301: }
ds@1301:
ds@1301: pConVar->Revert();
ds@1301:
ds@2400: #if SOURCE_ENGINE >= SE_ORANGEBOX
ds@1301: /* Should we replicate it? */
ds@2396: if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@1301: {
ds@1301: ReplicateConVar(pConVar);
ds@1301: }
ds@1301:
ds@1301: /* Should we notify clients? */
ds@2396: if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@1301: {
ds@1301: NotifyConVar(pConVar);
ds@1301: }
ds@2396: #endif
ds@1301:
ds@1301: return 1;
ds@1301: }
ds@1301:
dvander@498: static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: return pConVar->GetFlags();
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: pConVar->SetFlags(params[2]);
dvander@498:
dvander@498: return 1;
dvander@498: }
dvander@498:
ds@714: static cell_t sm_GetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
dvander@498: cell_t *addr;
ds@714: bool hasBound;
ds@714: float bound;
dvander@498:
ds@714: switch (params[2])
ds@714: {
ds@714: case ConVarBound_Upper:
ds@714: hasBound = pConVar->GetMax(bound);
ds@714: break;
ds@714: case ConVarBound_Lower:
ds@714: hasBound = pConVar->GetMin(bound);
ds@714: break;
ds@714: default:
ds@714: return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714: }
ds@714:
ds@714: pContext->LocalToPhysAddr(params[3], &addr);
ds@714: *addr = sp_ftoc(bound);
dvander@498:
ds@714: return hasBound;
dvander@498: }
dvander@498:
ds@714: static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@714: switch (params[2])
ds@714: {
ds@714: case ConVarBound_Upper:
ds@714: pConVar->SetMax(params[3] ? true : false, sp_ctof(params[4]));
ds@714: break;
ds@714: case ConVarBound_Lower:
ds@714: pConVar->SetMin(params[3] ? true : false, sp_ctof(params[4]));
ds@714: break;
ds@714: default:
ds@714: return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714: }
dvander@498:
ds@714: return 1;
dvander@498: }
dvander@498:
dvander@498: static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: Handle_t hndl = static_cast(params[1]);
dvander@498: HandleError err;
ds@576: ConVar *pConVar;
dvander@498:
dvander@1582: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498: != HandleError_None)
dvander@498: {
ds@581: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498: }
dvander@498:
ds@576: pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
dvander@498:
dvander@498: return 1;
dvander@498: }
dvander@498:
ds@696: static bool s_QueryAlreadyWarned = false;
ds@696:
ds@696: static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *params)
ds@696: {
ds@696: CPlayer *pPlayer;
ds@696: char *name;
ds@696: IPluginFunction *pCallback;
ds@696:
dvander@1581: if (!g_ConVarManager.IsQueryingSupported())
ds@696: {
ds@696: if (!s_QueryAlreadyWarned)
ds@696: {
ds@696: s_QueryAlreadyWarned = true;
ds@696: return pContext->ThrowNativeError("Game does not support client convar querying (one time warning)");
ds@696: }
ds@696:
ds@696: return 0;
ds@696: }
ds@696:
ds@696: pPlayer = g_Players.GetPlayerByIndex(params[1]);
ds@696:
ds@696: if (!pPlayer)
ds@696: {
ds@994: return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
ds@696: }
ds@696:
ds@697: if (!pPlayer->IsConnected())
ds@696: {
ds@994: return pContext->ThrowNativeError("Client %d is not connected", params[1]);
ds@697: }
ds@697:
ds@697: /* Trying a query on a bot results in callback not be fired, so don't bother */
ds@697: if (pPlayer->IsFakeClient())
ds@697: {
ds@697: return 0;
ds@696: }
ds@696:
ds@696: pContext->LocalToString(params[2], &name);
ds@696: pCallback = pContext->GetFunctionById(params[3]);
ds@696:
ds@696: if (!pCallback)
ds@696: {
ds@696: return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
ds@696: }
ds@696:
ds@696: return g_ConVarManager.QueryClientConVar(pPlayer->GetEdict(), name, pCallback, params[4]);
ds@696: }
ds@696:
dvander@498: static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
dvander@498: {
dvander@498: char *name,*help;
dvander@498: IPluginFunction *pFunction;
dvander@498:
dvander@498: pContext->LocalToString(params[1], &name);
dvander@498: pContext->LocalToString(params[3], &help);
dvander@498: pFunction = pContext->GetFunctionById(params[2]);
dvander@498:
dvander@498: if (!pFunction)
dvander@498: {
dvander@498: return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@498: }
dvander@498:
ds@579: if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
ds@579: {
ds@579: return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579: }
dvander@498:
dvander@498: return 1;
dvander@498: }
dvander@498:
dvander@500: static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
dvander@500: {
dvander@500: char *name,*help;
dvander@500: IPluginFunction *pFunction;
dvander@500:
dvander@500: pContext->LocalToString(params[1], &name);
dvander@500: pContext->LocalToString(params[3], &help);
dvander@500: pFunction = pContext->GetFunctionById(params[2]);
dvander@500:
dvander@500: if (!pFunction)
dvander@500: {
dvander@500: return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@500: }
dvander@500:
ds@579: if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
ds@579: {
ds@579: return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579: }
dvander@500:
dvander@500: return 1;
dvander@500: }
dvander@500:
dvander@514: static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
dvander@514: {
dvander@514: char *name,*help;
dvander@514: const char *group;
dvander@514: IPluginFunction *pFunction;
dvander@514: FlagBits flags = params[3];
dvander@514: int cmdflags = params[6];
dvander@514:
dvander@514: pContext->LocalToString(params[1], &name);
dvander@514: pContext->LocalToString(params[4], &help);
dvander@514: pContext->LocalToString(params[5], (char **)&group);
dvander@514: pFunction = pContext->GetFunctionById(params[2]);
dvander@514:
dvander@514: if (group[0] == '\0')
dvander@514: {
dvander@514: CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@514: group = pPlugin->GetFilename();
dvander@514: }
dvander@514:
dvander@514: if (!pFunction)
dvander@514: {
dvander@514: return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@514: }
dvander@514:
ds@579: if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
ds@579: {
ds@579: return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579: }
dvander@514:
dvander@514: return 1;
dvander@514: }
dvander@514:
dvander@517: static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
dvander@517: {
dvander@1544: const CCommand *pCmd = g_HL2.PeekCommandStack();
dvander@1544:
dvander@1544: if (!pCmd)
dvander@1544: {
dvander@1544: return pContext->ThrowNativeError("No command callback available");
dvander@1544: }
dvander@1544:
dvander@1544: return pCmd->ArgC() - 1;
dvander@517: }
dvander@517:
dvander@517: static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
dvander@517: {
dvander@1544: const CCommand *pCmd = g_HL2.PeekCommandStack();
dvander@1544:
dvander@1544: if (!pCmd)
dvander@1544: {
dvander@1544: return pContext->ThrowNativeError("No command callback available");
dvander@1544: }
dvander@1544:
dvander@1421: size_t length;
dvander@1544:
dvander@1544: const char *arg = pCmd->Arg(params[1]);
dvander@517:
dvander@1544: pContext->StringToLocalUTF8(params[2], params[3], arg ? arg : "", &length);
dvander@517:
dvander@1421: return (cell_t)length;
dvander@517: }
dvander@517:
dvander@517: static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
dvander@517: {
dvander@1544: const CCommand *pCmd = g_HL2.PeekCommandStack();
dvander@1544:
dvander@1544: if (!pCmd)
dvander@1544: {
dvander@1544: return pContext->ThrowNativeError("No command callback available");
dvander@1544: }
dvander@1544:
dvander@1544: const char *args = pCmd->ArgS();
dvander@1421: size_t length;
dvander@517:
dvander@633: if (!args)
dvander@633: {
dvander@633: args = "";
dvander@633: }
dvander@633:
dvander@1421: pContext->StringToLocalUTF8(params[1], params[2], args, &length);
dvander@517:
dvander@1421: return (cell_t)length;
dvander@517: }
dvander@517:
dvander@518: static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
dvander@518: {
dvander@518: char buffer[1024];
dvander@518: char *fmt;
dvander@518: int arg = 2;
dvander@518:
dvander@518: pCtx->LocalToString(params[1], &fmt);
dvander@518: size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518:
dvander@518: buffer[res++] = '\n';
dvander@518: buffer[res] = '\0';
dvander@518:
dvander@518: META_CONPRINT(buffer);
dvander@518:
dvander@518: return 1;
dvander@518: }
dvander@518:
dvander@518: static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
dvander@518: {
dvander@518: int index = params[1];
dvander@520: if ((index < 0) || (index > g_Players.GetMaxClients()))
dvander@518: {
ds@994: return pCtx->ThrowNativeError("Client index %d is invalid", index);
dvander@518: }
dvander@518:
dvander@520: CPlayer *pPlayer = NULL;
dvander@520: if (index != 0)
dvander@518: {
dvander@520: pPlayer = g_Players.GetPlayerByIndex(index);
dvander@520: if (!pPlayer->IsInGame())
dvander@520: {
dvander@520: return pCtx->ThrowNativeError("Client %d is not in game", index);
dvander@520: }
dvander@520:
dvander@520: /* Silent fail on bots, engine will crash */
dvander@520: if (pPlayer->IsFakeClient())
dvander@520: {
dvander@520: return 0;
dvander@520: }
dvander@519: }
dvander@518:
dvander@518: char buffer[1024];
dvander@518: char *fmt;
dvander@518: int arg = 3;
dvander@518:
dvander@518: pCtx->LocalToString(params[2], &fmt);
dvander@518: size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518:
dvander@518: buffer[res++] = '\n';
dvander@518: buffer[res] = '\0';
dvander@518:
dvander@520: if (index != 0)
dvander@520: {
dvander@520: engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@520: } else {
dvander@520: META_CONPRINT(buffer);
dvander@520: }
dvander@518:
dvander@518: return 1;
dvander@518: }
dvander@518:
dvander@522: static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522: {
dvander@2042: g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1273:
dvander@522: char buffer[1024];
dvander@522: size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522:
dvander@2193: if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1273: {
dvander@1273: return 0;
dvander@1273: }
dvander@1011:
dvander@522: /* One byte for null terminator, one for newline */
dvander@522: buffer[len++] = '\n';
dvander@522: buffer[len] = '\0';
dvander@522:
dvander@522: engine->ServerCommand(buffer);
dvander@522:
dvander@522: return 1;
dvander@522: }
dvander@522:
dvander@522: static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522: {
dvander@2042: g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1273:
dvander@522: char buffer[1024];
dvander@522: size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522:
dvander@2193: if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1273: {
dvander@1273: return 0;
dvander@1273: }
dvander@1011:
dvander@522: /* One byte for null terminator, one for newline */
dvander@522: buffer[len++] = '\n';
dvander@522: buffer[len] = '\0';
dvander@522:
faluco@1541: InsertServerCommand(buffer);
dvander@522:
dvander@522: return 1;
dvander@522: }
dvander@522:
dvander@522: static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
dvander@522: {
dvander@522: engine->ServerExecute();
dvander@522:
dvander@522: return 1;
dvander@522: }
dvander@522:
dvander@532: static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@532: {
dvander@532: CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@532:
dvander@532: if (!pPlayer)
dvander@532: {
ds@994: return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@532: }
dvander@532:
dvander@532: if (!pPlayer->IsConnected())
dvander@532: {
ds@994: return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@532: }
dvander@532:
dvander@1011: g_SourceMod.SetGlobalTarget(params[1]);
dvander@1011:
dvander@532: char buffer[256];
ds@873: g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@532:
dvander@2193: if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1273: {
dvander@1273: return 0;
dvander@1273: }
dvander@1273:
dvander@532: engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
dvander@532:
dvander@532: return 1;
dvander@532: }
dvander@532:
dvander@893: static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@893: {
dvander@893: CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893:
dvander@893: if (!pPlayer)
dvander@893: {
ds@994: return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893: }
dvander@893:
dvander@893: if (!pPlayer->IsConnected())
dvander@893: {
ds@994: return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893: }
dvander@893:
dvander@893: char buffer[256];
dvander@893: g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@893:
dvander@2193: if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1273: {
dvander@1273: return 0;
dvander@1273: }
dvander@1273:
dvander@893: serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), buffer);
dvander@1337:
dvander@1337: return 1;
dvander@1337: }
dvander@1337:
dvander@1337: static cell_t FakeClientCommandEx(IPluginContext *pContext, const cell_t *params)
dvander@1337: {
dvander@1337: CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@1337:
dvander@1337: if (!pPlayer)
dvander@1337: {
dvander@1337: return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@1337: }
dvander@1337:
dvander@1337: if (!pPlayer->IsConnected())
dvander@1337: {
dvander@1337: return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@1337: }
dvander@1337:
dvander@1337: char buffer[256];
dvander@1337: g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@1337:
dvander@2193: if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1337: {
dvander@1337: return 0;
dvander@1337: }
dvander@1337:
dvander@1338: g_HL2.AddToFakeCliCmdQueue(params[1], engine->GetPlayerUserId(pPlayer->GetEdict()), buffer);
dvander@893:
dvander@893: return 1;
dvander@893: }
dvander@893:
dvander@893: static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
dvander@893: {
dvander@1011: g_SourceMod.SetGlobalTarget(params[1]);
dvander@1011:
dvander@893: /* Build the format string */
dvander@893: char buffer[1024];
dvander@893: size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 2);
dvander@893:
dvander@2193: if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1273: {
dvander@1273: return 0;
dvander@1273: }
dvander@1273:
dvander@893: /* If we're printing to the server, shortcut out */
dvander@893: if (params[1] == 0)
dvander@893: {
dvander@893: /* Print */
dvander@893: buffer[len++] = '\n';
dvander@893: buffer[len] = '\0';
dvander@893: META_CONPRINT(buffer);
dvander@893: return 1;
dvander@893: }
dvander@893:
dvander@893: CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893:
dvander@893: if (!pPlayer)
dvander@893: {
dvander@893: return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893: }
dvander@893:
dvander@893: if (!pPlayer->IsConnected())
dvander@893: {
dvander@893: return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893: }
dvander@893:
dvander@910: g_SourceMod.SetGlobalTarget(params[1]);
dvander@910:
dvander@893: unsigned int replyto = g_ChatTriggers.GetReplyTo();
dvander@893: if (replyto == SM_REPLY_CONSOLE)
dvander@893: {
dvander@893: buffer[len++] = '\n';
dvander@893: buffer[len] = '\0';
dvander@893: engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@893: } else if (replyto == SM_REPLY_CHAT) {
dvander@893: if (len >= 191)
dvander@893: {
dvander@893: len = 191;
dvander@893: }
dvander@893: buffer[len] = '\0';
dvander@893: g_HL2.TextMsg(params[1], HUD_PRINTTALK, buffer);
dvander@893: }
dvander@893:
dvander@893: return 1;
dvander@893: }
dvander@893:
dvander@923: static cell_t GetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
dvander@923: {
dvander@923: return g_ChatTriggers.GetReplyTo();
dvander@923: }
dvander@923:
dvander@1071: static cell_t SetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
dvander@1071: {
dvander@1071: return g_ChatTriggers.SetReplyTo(params[1]);
dvander@1071: }
dvander@1071:
dvander@1119: static cell_t GetCommandIterator(IPluginContext *pContext, const cell_t *params)
dvander@1119: {
dvander@1119: GlobCmdIter *iter = new GlobCmdIter;
dvander@1119: iter->started = false;
dvander@1119:
dvander@1119: Handle_t hndl = g_HandleSys.CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
dvander@1119: if (hndl == BAD_HANDLE)
dvander@1119: {
dvander@1119: delete iter;
dvander@1119: }
dvander@1119:
dvander@1119: return hndl;
dvander@1119: }
dvander@1119:
dvander@1119: static cell_t ReadCommandIterator(IPluginContext *pContext, const cell_t *params)
dvander@1119: {
dvander@1119: GlobCmdIter *iter;
dvander@1119: HandleError err;
dvander@1119: HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1119:
dvander@1119: if ((err = g_HandleSys.ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
dvander@1119: != HandleError_None)
dvander@1119: {
dvander@1119: return pContext->ThrowNativeError("Invalid GlobCmdIter Handle %x", params[1]);
dvander@1119: }
dvander@1119:
dvander@1119: const List &cmds = g_ConCmds.GetCommandList();
dvander@1119:
dvander@1119: if (!iter->started)
dvander@1119: {
dvander@1119: iter->iter = cmds.begin();
dvander@1119: iter->started = true;
dvander@1119: }
dvander@1119:
dvander@1119: while (iter->iter != cmds.end()
dvander@1119: && !(*(iter->iter))->sourceMod)
dvander@1119: {
dvander@1119: iter->iter++;
dvander@1119: }
dvander@1119:
dvander@1119: if (iter->iter == cmds.end())
dvander@1119: {
dvander@1119: return 0;
dvander@1119: }
dvander@1119:
dvander@1119: ConCmdInfo *pInfo = (*(iter->iter));
dvander@1119:
dvander@1119: pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
dvander@1119: pContext->StringToLocalUTF8(params[5], params[6], pInfo->pCmd->GetHelpText(), NULL);
dvander@1119:
dvander@1119: cell_t *addr;
dvander@1119: pContext->LocalToPhysAddr(params[4], &addr);
dvander@1119: *addr = pInfo->admin.eflags;
dvander@1119:
dvander@1119: iter->iter++;
dvander@1119:
dvander@1119: return 1;
dvander@1119: }
dvander@1119:
dvander@1119: static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params)
dvander@1119: {
dvander@1119: if (params[1] == 0)
dvander@1119: {
dvander@1119: return 1;
dvander@1119: }
dvander@1119:
dvander@1119: char *cmd;
dvander@1119: pContext->LocalToString(params[2], &cmd);
dvander@1119:
dvander@1429: /* Auto-detect a command if we can */
dvander@1399: FlagBits bits = params[3];
dvander@1429: bool found_command = false;
dvander@1429: if (params[0] < 4 || !params[4])
dvander@1399: {
dvander@1429: found_command = g_ConCmds.LookForCommandAdminFlags(cmd, &bits);
dvander@1429: }
dvander@1429:
dvander@1429: if (!found_command)
dvander@1429: {
dvander@1429: g_Admins.GetCommandOverride(cmd, Override_Command, &bits);
dvander@1399: }
dvander@1399:
dvander@1399: return g_ConCmds.CheckCommandAccess(params[1], cmd, bits) ? 1 : 0;
dvander@1119: }
dvander@1119:
dvander@1469: static cell_t IsChatTrigger(IPluginContext *pContext, const cell_t *params)
dvander@1469: {
dvander@1469: return g_ChatTriggers.IsChatTrigger() ? 1 : 0;
dvander@1469: }
dvander@1469:
faluco@1643: static cell_t SetCommandFlags(IPluginContext *pContext, const cell_t *params)
faluco@1643: {
faluco@1643: char *name;
faluco@1643: pContext->LocalToString(params[1], &name);
faluco@1643:
faluco@1643: return (s_CommandFlagsHelper.SetFlags(name, params[2])) ? 1 : 0;
faluco@1643: }
faluco@1643:
faluco@1643: static cell_t GetCommandFlags(IPluginContext *pContext, const cell_t *params)
faluco@1643: {
faluco@1643: char *name;
faluco@1643: int flags;
faluco@1643: pContext->LocalToString(params[1], &name);
faluco@1643:
faluco@1643: return (s_CommandFlagsHelper.GetFlags(name, &flags)) ? flags : -1;
faluco@1643: }
faluco@1643:
dvander@1795: static cell_t FindFirstConCommand(IPluginContext *pContext, const cell_t *params)
dvander@1795: {
dvander@1795: Handle_t hndl;
dvander@1795: ConCmdIter *pIter;
dvander@1795: cell_t *pIsCmd, *pFlags;
dvander@1795: const ConCommandBase *pConCmd;
faluco@1893: const char *desc;
dvander@1795:
dvander@1795: pContext->LocalToPhysAddr(params[3], &pIsCmd);
dvander@1795: pContext->LocalToPhysAddr(params[4], &pFlags);
dvander@1795:
ds@2400: #if SOURCE_ENGINE == SE_LEFT4DEAD
ds@2400: ICvarIteratorInternal *cvarIter = icvar->FactoryInternalIterator();
ds@2400: cvarIter->SetFirst();
ds@2400: if (!cvarIter->IsValid())
ds@2400: {
ds@2400: return BAD_HANDLE;
ds@2400: }
ds@2400: pConCmd = cvarIter->Get();
ds@2400: #else
dvander@1795: pConCmd = icvar->GetCommands();
dvander@1795: if (pConCmd == NULL)
dvander@1795: {
dvander@1795: return BAD_HANDLE;
dvander@1795: }
ds@2400: #endif
dvander@1795:
dvander@1795: pContext->StringToLocalUTF8(params[1], params[2], pConCmd->GetName(), NULL);
dvander@1795: *pIsCmd = pConCmd->IsCommand() ? 1 : 0;
dvander@1795: *pFlags = pConCmd->GetFlags();
dvander@1795:
faluco@1893: if (params[6])
faluco@1893: {
faluco@1893: desc = pConCmd->GetHelpText();
faluco@1893: pContext->StringToLocalUTF8(params[5], params[6], (desc && desc[0]) ? desc : "", NULL);
faluco@1893: }
faluco@1893:
dvander@1795: pIter = new ConCmdIter;
ds@2400: #if SOURCE_ENGINE == SE_LEFT4DEAD
ds@2400: pIter->pLast = cvarIter;
ds@2400: #else
dvander@1795: pIter->pLast = pConCmd;
ds@2400: #endif
dvander@1795:
dvander@1795: if ((hndl = g_HandleSys.CreateHandle(htConCmdIter, pIter, pContext->GetIdentity(), g_pCoreIdent, NULL))
dvander@1795: == BAD_HANDLE)
dvander@1795: {
dvander@1795: delete pIter;
dvander@1795: return BAD_HANDLE;
dvander@1795: }
dvander@1795:
dvander@1795: return hndl;
dvander@1795: }
dvander@1795:
dvander@1795: static cell_t FindNextConCommand(IPluginContext *pContext, const cell_t *params)
dvander@1795: {
dvander@1795: HandleError err;
dvander@1795: ConCmdIter *pIter;
dvander@1795: cell_t *pIsCmd, *pFlags;
faluco@1893: const char *desc;
ds@2400: const ConCommandBase *pConCmd;
dvander@1795: HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1795:
dvander@1795: if ((err = g_HandleSys.ReadHandle(params[1], htConCmdIter, &sec, (void **)&pIter)) != HandleError_None)
dvander@1795: {
dvander@1795: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1795: }
dvander@1795:
dvander@1795: if (pIter->pLast == NULL)
dvander@1795: {
dvander@1795: return 0;
dvander@1795: }
dvander@1795:
ds@2400: #if SOURCE_ENGINE == SE_LEFT4DEAD
ds@2400: ICvarIteratorInternal *cvarIter = pIter->pLast;
ds@2400: cvarIter->Next();
ds@2400: if (!cvarIter->IsValid())
dvander@1795: {
dvander@1795: return 0;
dvander@1795: }
ds@2400: pConCmd = cvarIter->Get();
ds@2400: #else
ds@2400: pConCmd = pIter->pLast->GetNext();
ds@2400: if (pConCmd == NULL)
ds@2400: {
ds@2400: return 0;
ds@2400: }
ds@2400: pIter->pLast = pConCmd;
ds@2400: #endif
dvander@1795:
dvander@1795: pContext->LocalToPhysAddr(params[4], &pIsCmd);
dvander@1795: pContext->LocalToPhysAddr(params[5], &pFlags);
dvander@1795:
ds@2400: pContext->StringToLocalUTF8(params[2], params[3], pConCmd->GetName(), NULL);
ds@2400: *pIsCmd = pConCmd->IsCommand() ? 1 : 0;
ds@2400: *pFlags = pConCmd->GetFlags();
dvander@1795:
faluco@1893: if (params[7])
faluco@1893: {
ds@2400: desc = pConCmd->GetHelpText();
faluco@1893: pContext->StringToLocalUTF8(params[6], params[7], (desc && desc[0]) ? desc : "", NULL);
faluco@1893: }
faluco@1893:
dvander@1795: return 1;
dvander@1795: }
dvander@1795:
pred@1852: static cell_t SendConVarValue(IPluginContext *pContext, const cell_t *params)
pred@1852: {
pred@1852: Handle_t hndl = static_cast(params[2]);
pred@1852: HandleError err;
pred@1852: ConVar *pConVar;
pred@1852:
pred@1852: char *value;
pred@1852: pContext->LocalToString(params[3], &value);
pred@1852:
pred@1852: if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
pred@1852: != HandleError_None)
pred@1852: {
pred@1852: return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
pred@1852: }
pred@1852:
pred@1852: char data[256];
pred@1852: bf_write buffer(data, sizeof(data));
pred@1852:
pred@1852: buffer.WriteUBitLong(NET_SETCONVAR, 5);
pred@1852: buffer.WriteByte(1);
pred@1852: buffer.WriteString(pConVar->GetName());
pred@1852: buffer.WriteString(value);
pred@1852:
pred@1852: CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
pred@1852:
pred@1852: if (!pPlayer)
pred@1852: {
pred@1852: return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
pred@1852: }
pred@1852:
pred@1852: if (!pPlayer->IsConnected())
pred@1852: {
pred@1852: return pContext->ThrowNativeError("Client %d is not connected", params[1]);
pred@1852: }
pred@1852:
pred@1852: if (pPlayer->IsFakeClient())
pred@1852: {
pred@1852: return pContext->ThrowNativeError("Client %d is fake and cannot be targeted", params[1]);
pred@1852: }
pred@1852:
pred@1852: INetChannel *netchan = static_cast(engine->GetPlayerNetInfo(params[1]));
pred@1852: netchan->SendData(buffer);
pred@1852:
pred@1852: return 1;
pred@1852: }
pred@1852:
dvander@518: REGISTER_NATIVES(consoleNatives)
dvander@498: {
dvander@498: {"CreateConVar", sm_CreateConVar},
dvander@498: {"FindConVar", sm_FindConVar},
dvander@498: {"HookConVarChange", sm_HookConVarChange},
dvander@498: {"UnhookConVarChange", sm_UnhookConVarChange},
dvander@498: {"GetConVarBool", sm_GetConVarBool},
dvander@498: {"SetConVarBool", sm_SetConVarNum},
dvander@498: {"GetConVarInt", sm_GetConVarInt},
dvander@498: {"SetConVarInt", sm_SetConVarNum},
dvander@498: {"GetConVarFloat", sm_GetConVarFloat},
dvander@498: {"SetConVarFloat", sm_SetConVarFloat},
dvander@498: {"GetConVarString", sm_GetConVarString},
dvander@498: {"SetConVarString", sm_SetConVarString},
dvander@498: {"GetConVarFlags", sm_GetConVarFlags},
dvander@498: {"SetConVarFlags", sm_SetConVarFlags},
ds@1301: {"ResetConVar", sm_ResetConVar},
dvander@498: {"GetConVarName", sm_GetConVarName},
ds@714: {"GetConVarBounds", sm_GetConVarBounds},
ds@714: {"SetConVarBounds", sm_SetConVarBounds},
ds@696: {"QueryClientConVar", sm_QueryClientConVar},
dvander@498: {"RegServerCmd", sm_RegServerCmd},
dvander@500: {"RegConsoleCmd", sm_RegConsoleCmd},
dvander@517: {"GetCmdArgString", sm_GetCmdArgString},
dvander@517: {"GetCmdArgs", sm_GetCmdArgs},
dvander@517: {"GetCmdArg", sm_GetCmdArg},
dvander@518: {"PrintToServer", sm_PrintToServer},
dvander@518: {"PrintToConsole", sm_PrintToConsole},
dvander@520: {"RegAdminCmd", sm_RegAdminCmd},
dvander@522: {"ServerCommand", sm_ServerCommand},
dvander@522: {"InsertServerCommand", sm_InsertServerCommand},
dvander@522: {"ServerExecute", sm_ServerExecute},
dvander@532: {"ClientCommand", sm_ClientCommand},
dvander@893: {"FakeClientCommand", FakeClientCommand},
dvander@893: {"ReplyToCommand", ReplyToCommand},
dvander@923: {"GetCmdReplySource", GetCmdReplyTarget},
dvander@1077: {"SetCmdReplySource", SetCmdReplyTarget},
dvander@1119: {"GetCommandIterator", GetCommandIterator},
dvander@1119: {"ReadCommandIterator", ReadCommandIterator},
dvander@1119: {"CheckCommandAccess", CheckCommandAccess},
dvander@1338: {"FakeClientCommandEx", FakeClientCommandEx},
dvander@1469: {"IsChatTrigger", IsChatTrigger},
faluco@1643: {"SetCommandFlags", SetCommandFlags},
faluco@1643: {"GetCommandFlags", GetCommandFlags},
dvander@1795: {"FindFirstConCommand", FindFirstConCommand},
dvander@1795: {"FindNextConCommand", FindNextConCommand},
pred@1852: {"SendConVarValue", SendConVarValue},
dvander@498: {NULL, NULL}
dvander@498: };