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