1.1 --- a/core/smn_console.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,1146 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "sm_globals.h"
1.36 -#include "HalfLife2.h"
1.37 -#include "sourcemm_api.h"
1.38 -#include "HandleSys.h"
1.39 -#include "ConVarManager.h"
1.40 -#include "ConCmdManager.h"
1.41 -#include "PluginSys.h"
1.42 -#include "sm_stringutil.h"
1.43 -#include "PlayerManager.h"
1.44 -#include "ChatTriggers.h"
1.45 -#include "AdminCache.h"
1.46 -#include <inetchannel.h>
1.47 -#include <bitbuf.h>
1.48 -#include <sm_trie_tpl.h>
1.49 -
1.50 -#define NET_SETCONVAR 5
1.51 -
1.52 -enum ConVarBounds
1.53 -{
1.54 - ConVarBound_Upper = 0,
1.55 - ConVarBound_Lower
1.56 -};
1.57 -
1.58 -HandleType_t hCmdIterType = 0;
1.59 -
1.60 -struct GlobCmdIter
1.61 -{
1.62 - bool started;
1.63 - List<ConCmdInfo *>::iterator iter;
1.64 -};
1.65 -
1.66 -class ConsoleHelpers :
1.67 - public SMGlobalClass,
1.68 - public IHandleTypeDispatch
1.69 -{
1.70 -public:
1.71 - virtual void OnSourceModAllInitialized()
1.72 - {
1.73 - HandleAccess access;
1.74 - g_HandleSys.InitAccessDefaults(NULL, &access);
1.75 - access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER | HANDLE_RESTRICT_IDENTITY;
1.76 -
1.77 - hCmdIterType = g_HandleSys.CreateType(NULL, this, 0, NULL, &access, g_pCoreIdent, NULL);
1.78 - }
1.79 - virtual void OnHandleDestroy(HandleType_t type, void *object)
1.80 - {
1.81 - GlobCmdIter *iter = (GlobCmdIter *)object;
1.82 - delete iter;
1.83 - }
1.84 -} s_ConsoleHelpers;
1.85 -
1.86 -class CommandFlagsHelper : public IConCommandTracker
1.87 -{
1.88 -public:
1.89 - void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
1.90 - {
1.91 - m_CmdFlags.remove(name);
1.92 - }
1.93 - bool GetFlags(const char *name, int *flags)
1.94 - {
1.95 - ConCommandBase **ppCmd;
1.96 - ConCommandBase *pCmd;
1.97 - if ((ppCmd=m_CmdFlags.retrieve(name)))
1.98 - {
1.99 - TrackConCommandBase((*ppCmd), this);
1.100 - *flags = (*ppCmd)->GetFlags();
1.101 - return true;
1.102 - }
1.103 - else if ((pCmd=FindConCommandBase(name)))
1.104 - {
1.105 - m_CmdFlags.insert(name, pCmd);
1.106 - TrackConCommandBase(pCmd, this);
1.107 - *flags = pCmd->GetFlags();
1.108 - return true;
1.109 - }
1.110 - else
1.111 - {
1.112 - return false;
1.113 - }
1.114 - }
1.115 - bool SetFlags(const char *name, int flags)
1.116 - {
1.117 - ConCommandBase **ppCmd;
1.118 - ConCommandBase *pCmd;
1.119 - if ((ppCmd=m_CmdFlags.retrieve(name)))
1.120 - {
1.121 - (*ppCmd)->SetFlags(flags);
1.122 - TrackConCommandBase((*ppCmd), this);
1.123 - return true;
1.124 - }
1.125 - else if ((pCmd=FindConCommandBase(name)))
1.126 - {
1.127 - m_CmdFlags.insert(name, pCmd);
1.128 - pCmd->SetFlags(flags);
1.129 - TrackConCommandBase(pCmd, this);
1.130 - return true;
1.131 - }
1.132 - else
1.133 - {
1.134 - return false;
1.135 - }
1.136 - }
1.137 -private:
1.138 - KTrie<ConCommandBase *> m_CmdFlags;
1.139 -} s_CommandFlagsHelper;
1.140 -
1.141 -static void ReplicateConVar(ConVar *pConVar)
1.142 -{
1.143 - int maxClients = g_Players.GetMaxClients();
1.144 -
1.145 - char data[256];
1.146 - bf_write buffer(data, sizeof(data));
1.147 -
1.148 - buffer.WriteUBitLong(NET_SETCONVAR, 5);
1.149 - buffer.WriteByte(1);
1.150 - buffer.WriteString(pConVar->GetName());
1.151 - buffer.WriteString(pConVar->GetString());
1.152 -
1.153 - for (int i = 1; i <= maxClients; i++)
1.154 - {
1.155 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
1.156 -
1.157 - if (pPlayer && pPlayer->IsInGame() && !pPlayer->IsFakeClient())
1.158 - {
1.159 - INetChannel *netchan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(i));
1.160 - netchan->SendData(buffer);
1.161 - }
1.162 - }
1.163 -}
1.164 -
1.165 -static void NotifyConVar(ConVar *pConVar)
1.166 -{
1.167 - IGameEvent *pEvent = gameevents->CreateEvent("server_cvar");
1.168 - pEvent->SetString("cvarname", pConVar->GetName());
1.169 - if (IsFlagSet(pConVar, FCVAR_PROTECTED))
1.170 - {
1.171 - pEvent->SetString("cvarvalue", "***PROTECTED***");
1.172 - }
1.173 - else
1.174 - {
1.175 - pEvent->SetString("cvarvalue", pConVar->GetString());
1.176 - }
1.177 -
1.178 - gameevents->FireEvent(pEvent);
1.179 -}
1.180 -
1.181 -static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
1.182 -{
1.183 - char *name, *defaultVal, *helpText;
1.184 -
1.185 - pContext->LocalToString(params[1], &name);
1.186 -
1.187 - // While the engine seems to accept a blank convar name, it causes a crash upon server quit
1.188 - if (name == NULL || strcmp(name, "") == 0)
1.189 - {
1.190 - return pContext->ThrowNativeError("Convar with blank name is not permitted");
1.191 - }
1.192 -
1.193 - pContext->LocalToString(params[2], &defaultVal);
1.194 - pContext->LocalToString(params[3], &helpText);
1.195 -
1.196 - bool hasMin = params[5] ? true : false;
1.197 - bool hasMax = params[7] ? true : false;
1.198 - float min = sp_ctof(params[6]);
1.199 - float max = sp_ctof(params[8]);
1.200 -
1.201 - Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
1.202 -
1.203 - if (hndl == BAD_HANDLE)
1.204 - {
1.205 - return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same might already exist.", name);
1.206 - }
1.207 -
1.208 - return hndl;
1.209 -}
1.210 -
1.211 -static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
1.212 -{
1.213 - char *name;
1.214 -
1.215 - pContext->LocalToString(params[1], &name);
1.216 -
1.217 - return g_ConVarManager.FindConVar(name);
1.218 -}
1.219 -
1.220 -static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
1.221 -{
1.222 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.223 - HandleError err;
1.224 - ConVar *pConVar;
1.225 -
1.226 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.227 - != HandleError_None)
1.228 - {
1.229 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.230 - }
1.231 -
1.232 - IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
1.233 -
1.234 - if (!pFunction)
1.235 - {
1.236 - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.237 - }
1.238 -
1.239 - g_ConVarManager.HookConVarChange(pConVar, pFunction);
1.240 -
1.241 - return 1;
1.242 -}
1.243 -
1.244 -static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
1.245 -{
1.246 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.247 - HandleError err;
1.248 - ConVar *pConVar;
1.249 -
1.250 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.251 - != HandleError_None)
1.252 - {
1.253 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.254 - }
1.255 -
1.256 - IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
1.257 -
1.258 - if (!pFunction)
1.259 - {
1.260 - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.261 - }
1.262 -
1.263 - g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
1.264 -
1.265 - return 1;
1.266 -}
1.267 -
1.268 -static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
1.269 -{
1.270 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.271 - HandleError err;
1.272 - ConVar *pConVar;
1.273 -
1.274 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.275 - != HandleError_None)
1.276 - {
1.277 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.278 - }
1.279 -
1.280 - return pConVar->GetBool();
1.281 -}
1.282 -
1.283 -static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
1.284 -{
1.285 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.286 - HandleError err;
1.287 - ConVar *pConVar;
1.288 -
1.289 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.290 - != HandleError_None)
1.291 - {
1.292 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.293 - }
1.294 -
1.295 - return pConVar->GetInt();
1.296 -}
1.297 -
1.298 -/* This handles both SetConVarBool() and SetConVarInt() */
1.299 -static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
1.300 -{
1.301 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.302 - HandleError err;
1.303 - ConVar *pConVar;
1.304 -
1.305 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.306 - != HandleError_None)
1.307 - {
1.308 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.309 - }
1.310 -
1.311 - pConVar->SetValue(params[2]);
1.312 -
1.313 - /* Should we replicate it? */
1.314 - if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
1.315 - {
1.316 - ReplicateConVar(pConVar);
1.317 - }
1.318 -
1.319 - /* Should we notify clients? */
1.320 - if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
1.321 - {
1.322 - NotifyConVar(pConVar);
1.323 - }
1.324 -
1.325 - return 1;
1.326 -}
1.327 -
1.328 -static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
1.329 -{
1.330 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.331 - HandleError err;
1.332 - ConVar *pConVar;
1.333 -
1.334 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.335 - != HandleError_None)
1.336 - {
1.337 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.338 - }
1.339 -
1.340 - float value = pConVar->GetFloat();
1.341 -
1.342 - return sp_ftoc(value);
1.343 -}
1.344 -
1.345 -static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
1.346 -{
1.347 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.348 - HandleError err;
1.349 - ConVar *pConVar;
1.350 -
1.351 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.352 - != HandleError_None)
1.353 - {
1.354 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.355 - }
1.356 -
1.357 - float value = sp_ctof(params[2]);
1.358 - pConVar->SetValue(value);
1.359 -
1.360 - /* Should we replicate it? */
1.361 - if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
1.362 - {
1.363 - ReplicateConVar(pConVar);
1.364 - }
1.365 -
1.366 - /* Should we notify clients? */
1.367 - if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
1.368 - {
1.369 - NotifyConVar(pConVar);
1.370 - }
1.371 -
1.372 - return 1;
1.373 -}
1.374 -
1.375 -static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
1.376 -{
1.377 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.378 - HandleError err;
1.379 - ConVar *pConVar;
1.380 -
1.381 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.382 - != HandleError_None)
1.383 - {
1.384 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.385 - }
1.386 -
1.387 - pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
1.388 -
1.389 - return 1;
1.390 -}
1.391 -
1.392 -static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
1.393 -{
1.394 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.395 - HandleError err;
1.396 - ConVar *pConVar;
1.397 -
1.398 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.399 - != HandleError_None)
1.400 - {
1.401 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.402 - }
1.403 -
1.404 - char *value;
1.405 - pContext->LocalToString(params[2], &value);
1.406 -
1.407 - pConVar->SetValue(value);
1.408 -
1.409 - /* Should we replicate it? */
1.410 - if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
1.411 - {
1.412 - ReplicateConVar(pConVar);
1.413 - }
1.414 -
1.415 - /* Should we notify clients? */
1.416 - if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
1.417 - {
1.418 - NotifyConVar(pConVar);
1.419 - }
1.420 -
1.421 - return 1;
1.422 -}
1.423 -
1.424 -static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
1.425 -{
1.426 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.427 - HandleError err;
1.428 - ConVar *pConVar;
1.429 -
1.430 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.431 - != HandleError_None)
1.432 - {
1.433 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.434 - }
1.435 -
1.436 - pConVar->Revert();
1.437 -
1.438 - /* Should we replicate it? */
1.439 - if (params[2] && IsFlagSet(pConVar, FCVAR_REPLICATED))
1.440 - {
1.441 - ReplicateConVar(pConVar);
1.442 - }
1.443 -
1.444 - /* Should we notify clients? */
1.445 - if (params[3] && IsFlagSet(pConVar, FCVAR_NOTIFY))
1.446 - {
1.447 - NotifyConVar(pConVar);
1.448 - }
1.449 -
1.450 - return 1;
1.451 -}
1.452 -
1.453 -static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
1.454 -{
1.455 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.456 - HandleError err;
1.457 - ConVar *pConVar;
1.458 -
1.459 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.460 - != HandleError_None)
1.461 - {
1.462 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.463 - }
1.464 -
1.465 - return pConVar->GetFlags();
1.466 -}
1.467 -
1.468 -static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
1.469 -{
1.470 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.471 - HandleError err;
1.472 - ConVar *pConVar;
1.473 -
1.474 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.475 - != HandleError_None)
1.476 - {
1.477 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.478 - }
1.479 -
1.480 - pConVar->SetFlags(params[2]);
1.481 -
1.482 - return 1;
1.483 -}
1.484 -
1.485 -static cell_t sm_GetConVarBounds(IPluginContext *pContext, const cell_t *params)
1.486 -{
1.487 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.488 - HandleError err;
1.489 - ConVar *pConVar;
1.490 -
1.491 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.492 - != HandleError_None)
1.493 - {
1.494 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.495 - }
1.496 -
1.497 - cell_t *addr;
1.498 - bool hasBound;
1.499 - float bound;
1.500 -
1.501 - switch (params[2])
1.502 - {
1.503 - case ConVarBound_Upper:
1.504 - hasBound = pConVar->GetMax(bound);
1.505 - break;
1.506 - case ConVarBound_Lower:
1.507 - hasBound = pConVar->GetMin(bound);
1.508 - break;
1.509 - default:
1.510 - return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
1.511 - }
1.512 -
1.513 - pContext->LocalToPhysAddr(params[3], &addr);
1.514 - *addr = sp_ftoc(bound);
1.515 -
1.516 - return hasBound;
1.517 -}
1.518 -
1.519 -static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
1.520 -{
1.521 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.522 - HandleError err;
1.523 - ConVar *pConVar;
1.524 -
1.525 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.526 - != HandleError_None)
1.527 - {
1.528 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.529 - }
1.530 -
1.531 - switch (params[2])
1.532 - {
1.533 - case ConVarBound_Upper:
1.534 - pConVar->SetMax(params[3] ? true : false, sp_ctof(params[4]));
1.535 - break;
1.536 - case ConVarBound_Lower:
1.537 - pConVar->SetMin(params[3] ? true : false, sp_ctof(params[4]));
1.538 - break;
1.539 - default:
1.540 - return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
1.541 - }
1.542 -
1.543 - return 1;
1.544 -}
1.545 -
1.546 -static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
1.547 -{
1.548 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.549 - HandleError err;
1.550 - ConVar *pConVar;
1.551 -
1.552 - if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
1.553 - != HandleError_None)
1.554 - {
1.555 - return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
1.556 - }
1.557 -
1.558 - pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
1.559 -
1.560 - return 1;
1.561 -}
1.562 -
1.563 -static bool s_QueryAlreadyWarned = false;
1.564 -
1.565 -static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *params)
1.566 -{
1.567 - CPlayer *pPlayer;
1.568 - char *name;
1.569 - IPluginFunction *pCallback;
1.570 -
1.571 - if (!g_ConVarManager.IsQueryingSupported())
1.572 - {
1.573 - if (!s_QueryAlreadyWarned)
1.574 - {
1.575 - s_QueryAlreadyWarned = true;
1.576 - return pContext->ThrowNativeError("Game does not support client convar querying (one time warning)");
1.577 - }
1.578 -
1.579 - return 0;
1.580 - }
1.581 -
1.582 - pPlayer = g_Players.GetPlayerByIndex(params[1]);
1.583 -
1.584 - if (!pPlayer)
1.585 - {
1.586 - return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
1.587 - }
1.588 -
1.589 - if (!pPlayer->IsConnected())
1.590 - {
1.591 - return pContext->ThrowNativeError("Client %d is not connected", params[1]);
1.592 - }
1.593 -
1.594 - /* Trying a query on a bot results in callback not be fired, so don't bother */
1.595 - if (pPlayer->IsFakeClient())
1.596 - {
1.597 - return 0;
1.598 - }
1.599 -
1.600 - pContext->LocalToString(params[2], &name);
1.601 - pCallback = pContext->GetFunctionById(params[3]);
1.602 -
1.603 - if (!pCallback)
1.604 - {
1.605 - return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
1.606 - }
1.607 -
1.608 - return g_ConVarManager.QueryClientConVar(pPlayer->GetEdict(), name, pCallback, params[4]);
1.609 -}
1.610 -
1.611 -static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
1.612 -{
1.613 - char *name,*help;
1.614 - IPluginFunction *pFunction;
1.615 -
1.616 - pContext->LocalToString(params[1], &name);
1.617 - pContext->LocalToString(params[3], &help);
1.618 - pFunction = pContext->GetFunctionById(params[2]);
1.619 -
1.620 - if (!pFunction)
1.621 - {
1.622 - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.623 - }
1.624 -
1.625 - if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
1.626 - {
1.627 - return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
1.628 - }
1.629 -
1.630 - return 1;
1.631 -}
1.632 -
1.633 -static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
1.634 -{
1.635 - char *name,*help;
1.636 - IPluginFunction *pFunction;
1.637 -
1.638 - pContext->LocalToString(params[1], &name);
1.639 - pContext->LocalToString(params[3], &help);
1.640 - pFunction = pContext->GetFunctionById(params[2]);
1.641 -
1.642 - if (!pFunction)
1.643 - {
1.644 - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.645 - }
1.646 -
1.647 - if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
1.648 - {
1.649 - return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
1.650 - }
1.651 -
1.652 - return 1;
1.653 -}
1.654 -
1.655 -static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
1.656 -{
1.657 - char *name,*help;
1.658 - const char *group;
1.659 - IPluginFunction *pFunction;
1.660 - FlagBits flags = params[3];
1.661 - int cmdflags = params[6];
1.662 -
1.663 - pContext->LocalToString(params[1], &name);
1.664 - pContext->LocalToString(params[4], &help);
1.665 - pContext->LocalToString(params[5], (char **)&group);
1.666 - pFunction = pContext->GetFunctionById(params[2]);
1.667 -
1.668 - if (group[0] == '\0')
1.669 - {
1.670 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.671 - group = pPlugin->GetFilename();
1.672 - }
1.673 -
1.674 - if (!pFunction)
1.675 - {
1.676 - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.677 - }
1.678 -
1.679 - if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
1.680 - {
1.681 - return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
1.682 - }
1.683 -
1.684 - return 1;
1.685 -}
1.686 -
1.687 -static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
1.688 -{
1.689 - const CCommand *pCmd = g_HL2.PeekCommandStack();
1.690 -
1.691 - if (!pCmd)
1.692 - {
1.693 - return pContext->ThrowNativeError("No command callback available");
1.694 - }
1.695 -
1.696 - return pCmd->ArgC() - 1;
1.697 -}
1.698 -
1.699 -static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
1.700 -{
1.701 - const CCommand *pCmd = g_HL2.PeekCommandStack();
1.702 -
1.703 - if (!pCmd)
1.704 - {
1.705 - return pContext->ThrowNativeError("No command callback available");
1.706 - }
1.707 -
1.708 - size_t length;
1.709 -
1.710 - const char *arg = pCmd->Arg(params[1]);
1.711 -
1.712 - pContext->StringToLocalUTF8(params[2], params[3], arg ? arg : "", &length);
1.713 -
1.714 - return (cell_t)length;
1.715 -}
1.716 -
1.717 -static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
1.718 -{
1.719 - const CCommand *pCmd = g_HL2.PeekCommandStack();
1.720 -
1.721 - if (!pCmd)
1.722 - {
1.723 - return pContext->ThrowNativeError("No command callback available");
1.724 - }
1.725 -
1.726 - const char *args = pCmd->ArgS();
1.727 - size_t length;
1.728 -
1.729 - if (!args)
1.730 - {
1.731 - args = "";
1.732 - }
1.733 -
1.734 - pContext->StringToLocalUTF8(params[1], params[2], args, &length);
1.735 -
1.736 - return (cell_t)length;
1.737 -}
1.738 -
1.739 -static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
1.740 -{
1.741 - char buffer[1024];
1.742 - char *fmt;
1.743 - int arg = 2;
1.744 -
1.745 - pCtx->LocalToString(params[1], &fmt);
1.746 - size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
1.747 -
1.748 - buffer[res++] = '\n';
1.749 - buffer[res] = '\0';
1.750 -
1.751 - META_CONPRINT(buffer);
1.752 -
1.753 - return 1;
1.754 -}
1.755 -
1.756 -static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
1.757 -{
1.758 - int index = params[1];
1.759 - if ((index < 0) || (index > g_Players.GetMaxClients()))
1.760 - {
1.761 - return pCtx->ThrowNativeError("Client index %d is invalid", index);
1.762 - }
1.763 -
1.764 - CPlayer *pPlayer = NULL;
1.765 - if (index != 0)
1.766 - {
1.767 - pPlayer = g_Players.GetPlayerByIndex(index);
1.768 - if (!pPlayer->IsInGame())
1.769 - {
1.770 - return pCtx->ThrowNativeError("Client %d is not in game", index);
1.771 - }
1.772 -
1.773 - /* Silent fail on bots, engine will crash */
1.774 - if (pPlayer->IsFakeClient())
1.775 - {
1.776 - return 0;
1.777 - }
1.778 - }
1.779 -
1.780 - char buffer[1024];
1.781 - char *fmt;
1.782 - int arg = 3;
1.783 -
1.784 - pCtx->LocalToString(params[2], &fmt);
1.785 - size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
1.786 -
1.787 - buffer[res++] = '\n';
1.788 - buffer[res] = '\0';
1.789 -
1.790 - if (index != 0)
1.791 - {
1.792 - engine->ClientPrintf(pPlayer->GetEdict(), buffer);
1.793 - } else {
1.794 - META_CONPRINT(buffer);
1.795 - }
1.796 -
1.797 - return 1;
1.798 -}
1.799 -
1.800 -static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
1.801 -{
1.802 - g_SourceMod.SetGlobalTarget(LANG_SERVER);
1.803 -
1.804 - char buffer[1024];
1.805 - size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
1.806 -
1.807 - if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1.808 - {
1.809 - return 0;
1.810 - }
1.811 -
1.812 - /* One byte for null terminator, one for newline */
1.813 - buffer[len++] = '\n';
1.814 - buffer[len] = '\0';
1.815 -
1.816 - engine->ServerCommand(buffer);
1.817 -
1.818 - return 1;
1.819 -}
1.820 -
1.821 -static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
1.822 -{
1.823 - g_SourceMod.SetGlobalTarget(LANG_SERVER);
1.824 -
1.825 - char buffer[1024];
1.826 - size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
1.827 -
1.828 - if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1.829 - {
1.830 - return 0;
1.831 - }
1.832 -
1.833 - /* One byte for null terminator, one for newline */
1.834 - buffer[len++] = '\n';
1.835 - buffer[len] = '\0';
1.836 -
1.837 - InsertServerCommand(buffer);
1.838 -
1.839 - return 1;
1.840 -}
1.841 -
1.842 -static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
1.843 -{
1.844 - engine->ServerExecute();
1.845 -
1.846 - return 1;
1.847 -}
1.848 -
1.849 -static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
1.850 -{
1.851 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
1.852 -
1.853 - if (!pPlayer)
1.854 - {
1.855 - return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
1.856 - }
1.857 -
1.858 - if (!pPlayer->IsConnected())
1.859 - {
1.860 - return pContext->ThrowNativeError("Client %d is not connected", params[1]);
1.861 - }
1.862 -
1.863 - g_SourceMod.SetGlobalTarget(params[1]);
1.864 -
1.865 - char buffer[256];
1.866 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1.867 -
1.868 - if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1.869 - {
1.870 - return 0;
1.871 - }
1.872 -
1.873 - engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
1.874 -
1.875 - return 1;
1.876 -}
1.877 -
1.878 -static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
1.879 -{
1.880 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
1.881 -
1.882 - if (!pPlayer)
1.883 - {
1.884 - return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
1.885 - }
1.886 -
1.887 - if (!pPlayer->IsConnected())
1.888 - {
1.889 - return pContext->ThrowNativeError("Client %d is not connected", params[1]);
1.890 - }
1.891 -
1.892 - char buffer[256];
1.893 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1.894 -
1.895 - if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1.896 - {
1.897 - return 0;
1.898 - }
1.899 -
1.900 - serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), buffer);
1.901 -
1.902 - return 1;
1.903 -}
1.904 -
1.905 -static cell_t FakeClientCommandEx(IPluginContext *pContext, const cell_t *params)
1.906 -{
1.907 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
1.908 -
1.909 - if (!pPlayer)
1.910 - {
1.911 - return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
1.912 - }
1.913 -
1.914 - if (!pPlayer->IsConnected())
1.915 - {
1.916 - return pContext->ThrowNativeError("Client %d is not connected", params[1]);
1.917 - }
1.918 -
1.919 - char buffer[256];
1.920 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1.921 -
1.922 - if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1.923 - {
1.924 - return 0;
1.925 - }
1.926 -
1.927 - g_HL2.AddToFakeCliCmdQueue(params[1], engine->GetPlayerUserId(pPlayer->GetEdict()), buffer);
1.928 -
1.929 - return 1;
1.930 -}
1.931 -
1.932 -static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
1.933 -{
1.934 - g_SourceMod.SetGlobalTarget(params[1]);
1.935 -
1.936 - /* Build the format string */
1.937 - char buffer[1024];
1.938 - size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 2);
1.939 -
1.940 - if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1.941 - {
1.942 - return 0;
1.943 - }
1.944 -
1.945 - /* If we're printing to the server, shortcut out */
1.946 - if (params[1] == 0)
1.947 - {
1.948 - /* Print */
1.949 - buffer[len++] = '\n';
1.950 - buffer[len] = '\0';
1.951 - META_CONPRINT(buffer);
1.952 - return 1;
1.953 - }
1.954 -
1.955 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
1.956 -
1.957 - if (!pPlayer)
1.958 - {
1.959 - return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
1.960 - }
1.961 -
1.962 - if (!pPlayer->IsConnected())
1.963 - {
1.964 - return pContext->ThrowNativeError("Client %d is not connected", params[1]);
1.965 - }
1.966 -
1.967 - g_SourceMod.SetGlobalTarget(params[1]);
1.968 -
1.969 - unsigned int replyto = g_ChatTriggers.GetReplyTo();
1.970 - if (replyto == SM_REPLY_CONSOLE)
1.971 - {
1.972 - buffer[len++] = '\n';
1.973 - buffer[len] = '\0';
1.974 - engine->ClientPrintf(pPlayer->GetEdict(), buffer);
1.975 - } else if (replyto == SM_REPLY_CHAT) {
1.976 - if (len >= 191)
1.977 - {
1.978 - len = 191;
1.979 - }
1.980 - buffer[len] = '\0';
1.981 - g_HL2.TextMsg(params[1], HUD_PRINTTALK, buffer);
1.982 - }
1.983 -
1.984 - return 1;
1.985 -}
1.986 -
1.987 -static cell_t GetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
1.988 -{
1.989 - return g_ChatTriggers.GetReplyTo();
1.990 -}
1.991 -
1.992 -static cell_t SetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
1.993 -{
1.994 - return g_ChatTriggers.SetReplyTo(params[1]);
1.995 -}
1.996 -
1.997 -static cell_t GetCommandIterator(IPluginContext *pContext, const cell_t *params)
1.998 -{
1.999 - GlobCmdIter *iter = new GlobCmdIter;
1.1000 - iter->started = false;
1.1001 -
1.1002 - Handle_t hndl = g_HandleSys.CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.1003 - if (hndl == BAD_HANDLE)
1.1004 - {
1.1005 - delete iter;
1.1006 - }
1.1007 -
1.1008 - return hndl;
1.1009 -}
1.1010 -
1.1011 -static cell_t ReadCommandIterator(IPluginContext *pContext, const cell_t *params)
1.1012 -{
1.1013 - GlobCmdIter *iter;
1.1014 - HandleError err;
1.1015 - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.1016 -
1.1017 - if ((err = g_HandleSys.ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
1.1018 - != HandleError_None)
1.1019 - {
1.1020 - return pContext->ThrowNativeError("Invalid GlobCmdIter Handle %x", params[1]);
1.1021 - }
1.1022 -
1.1023 - const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
1.1024 -
1.1025 - if (!iter->started)
1.1026 - {
1.1027 - iter->iter = cmds.begin();
1.1028 - iter->started = true;
1.1029 - }
1.1030 -
1.1031 - while (iter->iter != cmds.end()
1.1032 - && !(*(iter->iter))->sourceMod)
1.1033 - {
1.1034 - iter->iter++;
1.1035 - }
1.1036 -
1.1037 - if (iter->iter == cmds.end())
1.1038 - {
1.1039 - return 0;
1.1040 - }
1.1041 -
1.1042 - ConCmdInfo *pInfo = (*(iter->iter));
1.1043 -
1.1044 - pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
1.1045 - pContext->StringToLocalUTF8(params[5], params[6], pInfo->pCmd->GetHelpText(), NULL);
1.1046 -
1.1047 - cell_t *addr;
1.1048 - pContext->LocalToPhysAddr(params[4], &addr);
1.1049 - *addr = pInfo->admin.eflags;
1.1050 -
1.1051 - iter->iter++;
1.1052 -
1.1053 - return 1;
1.1054 -}
1.1055 -
1.1056 -static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params)
1.1057 -{
1.1058 - if (params[1] == 0)
1.1059 - {
1.1060 - return 1;
1.1061 - }
1.1062 -
1.1063 - char *cmd;
1.1064 - pContext->LocalToString(params[2], &cmd);
1.1065 -
1.1066 - /* Auto-detect a command if we can */
1.1067 - FlagBits bits = params[3];
1.1068 - bool found_command = false;
1.1069 - if (params[0] < 4 || !params[4])
1.1070 - {
1.1071 - found_command = g_ConCmds.LookForCommandAdminFlags(cmd, &bits);
1.1072 - }
1.1073 -
1.1074 - if (!found_command)
1.1075 - {
1.1076 - g_Admins.GetCommandOverride(cmd, Override_Command, &bits);
1.1077 - }
1.1078 -
1.1079 - return g_ConCmds.CheckCommandAccess(params[1], cmd, bits) ? 1 : 0;
1.1080 -}
1.1081 -
1.1082 -static cell_t IsChatTrigger(IPluginContext *pContext, const cell_t *params)
1.1083 -{
1.1084 - return g_ChatTriggers.IsChatTrigger() ? 1 : 0;
1.1085 -}
1.1086 -
1.1087 -static cell_t SetCommandFlags(IPluginContext *pContext, const cell_t *params)
1.1088 -{
1.1089 - char *name;
1.1090 - pContext->LocalToString(params[1], &name);
1.1091 -
1.1092 - return (s_CommandFlagsHelper.SetFlags(name, params[2])) ? 1 : 0;
1.1093 -}
1.1094 -
1.1095 -static cell_t GetCommandFlags(IPluginContext *pContext, const cell_t *params)
1.1096 -{
1.1097 - char *name;
1.1098 - int flags;
1.1099 - pContext->LocalToString(params[1], &name);
1.1100 -
1.1101 - return (s_CommandFlagsHelper.GetFlags(name, &flags)) ? flags : -1;
1.1102 -}
1.1103 -
1.1104 -REGISTER_NATIVES(consoleNatives)
1.1105 -{
1.1106 - {"CreateConVar", sm_CreateConVar},
1.1107 - {"FindConVar", sm_FindConVar},
1.1108 - {"HookConVarChange", sm_HookConVarChange},
1.1109 - {"UnhookConVarChange", sm_UnhookConVarChange},
1.1110 - {"GetConVarBool", sm_GetConVarBool},
1.1111 - {"SetConVarBool", sm_SetConVarNum},
1.1112 - {"GetConVarInt", sm_GetConVarInt},
1.1113 - {"SetConVarInt", sm_SetConVarNum},
1.1114 - {"GetConVarFloat", sm_GetConVarFloat},
1.1115 - {"SetConVarFloat", sm_SetConVarFloat},
1.1116 - {"GetConVarString", sm_GetConVarString},
1.1117 - {"SetConVarString", sm_SetConVarString},
1.1118 - {"GetConVarFlags", sm_GetConVarFlags},
1.1119 - {"SetConVarFlags", sm_SetConVarFlags},
1.1120 - {"ResetConVar", sm_ResetConVar},
1.1121 - {"GetConVarName", sm_GetConVarName},
1.1122 - {"GetConVarBounds", sm_GetConVarBounds},
1.1123 - {"SetConVarBounds", sm_SetConVarBounds},
1.1124 - {"QueryClientConVar", sm_QueryClientConVar},
1.1125 - {"RegServerCmd", sm_RegServerCmd},
1.1126 - {"RegConsoleCmd", sm_RegConsoleCmd},
1.1127 - {"GetCmdArgString", sm_GetCmdArgString},
1.1128 - {"GetCmdArgs", sm_GetCmdArgs},
1.1129 - {"GetCmdArg", sm_GetCmdArg},
1.1130 - {"PrintToServer", sm_PrintToServer},
1.1131 - {"PrintToConsole", sm_PrintToConsole},
1.1132 - {"RegAdminCmd", sm_RegAdminCmd},
1.1133 - {"ServerCommand", sm_ServerCommand},
1.1134 - {"InsertServerCommand", sm_InsertServerCommand},
1.1135 - {"ServerExecute", sm_ServerExecute},
1.1136 - {"ClientCommand", sm_ClientCommand},
1.1137 - {"FakeClientCommand", FakeClientCommand},
1.1138 - {"ReplyToCommand", ReplyToCommand},
1.1139 - {"GetCmdReplySource", GetCmdReplyTarget},
1.1140 - {"SetCmdReplySource", SetCmdReplyTarget},
1.1141 - {"GetCommandIterator", GetCommandIterator},
1.1142 - {"ReadCommandIterator", ReadCommandIterator},
1.1143 - {"CheckCommandAccess", CheckCommandAccess},
1.1144 - {"FakeClientCommandEx", FakeClientCommandEx},
1.1145 - {"IsChatTrigger", IsChatTrigger},
1.1146 - {"SetCommandFlags", SetCommandFlags},
1.1147 - {"GetCommandFlags", GetCommandFlags},
1.1148 - {NULL, NULL}
1.1149 -};