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: };