2 * ===============================================================
3 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
4 * ===============================================================
6 * This file is not open source and may not be copied without explicit
7 * written permission of AlliedModders LLC. This file may not be redistributed
8 * in whole or significant part.
9 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
14 #include "sm_globals.h"
15 #include "sourcemm_api.h"
16 #include "HandleSys.h"
17 #include "CConVarManager.h"
18 #include "CConCmdManager.h"
19 #include "PluginSys.h"
20 #include "sm_stringutil.h"
21 #include "CPlayerManager.h"
23 static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
25 char *name, *defaultVal, *helpText;
27 pContext->LocalToString(params[1], &name);
29 // While the engine seems to accept a blank convar name, it causes a crash upon server quit
30 if (name == NULL || strcmp(name, "") == 0)
32 return pContext->ThrowNativeError("Null or blank convar name is not allowed");
35 pContext->LocalToString(params[2], &defaultVal);
36 pContext->LocalToString(params[3], &helpText);
38 bool hasMin = params[5] ? true : false;
39 bool hasMax = params[7] ? true : false;
40 float min = sp_ctof(params[6]);
41 float max = sp_ctof(params[8]);
43 return g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
46 static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
50 pContext->LocalToString(params[1], &name);
52 // While the engine seems to accept a blank convar name, it causes a crash upon server quit
53 if (name == NULL || strcmp(name, "") == 0)
58 return g_ConVarManager.FindConVar(name);
61 static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
63 Handle_t hndl = static_cast<Handle_t>(params[1]);
67 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
70 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
73 g_ConVarManager.HookConVarChange(pContext, cvar, static_cast<funcid_t>(params[2]));
78 static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
80 Handle_t hndl = static_cast<Handle_t>(params[1]);
84 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
87 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
90 g_ConVarManager.UnhookConVarChange(pContext, cvar, static_cast<funcid_t>(params[2]));
95 static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
97 Handle_t hndl = static_cast<Handle_t>(params[1]);
101 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
104 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
107 return cvar->GetBool();
110 static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
112 Handle_t hndl = static_cast<Handle_t>(params[1]);
116 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
119 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
122 return cvar->GetInt();
125 /* This handles both SetConVarBool() and SetConVarInt() */
126 static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
128 Handle_t hndl = static_cast<Handle_t>(params[1]);
132 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
135 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
138 cvar->SetValue(params[2]);
143 static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
145 Handle_t hndl = static_cast<Handle_t>(params[1]);
149 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
152 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
155 float value = cvar->GetFloat();
157 return sp_ftoc(value);
160 static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
162 Handle_t hndl = static_cast<Handle_t>(params[1]);
166 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
169 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
172 float value = sp_ctof(params[2]);
173 cvar->SetValue(value);
178 static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
180 Handle_t hndl = static_cast<Handle_t>(params[1]);
184 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
187 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
190 pContext->StringToLocalUTF8(params[2], params[3], cvar->GetString(), NULL);
195 static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
197 Handle_t hndl = static_cast<Handle_t>(params[1]);
201 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
204 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
208 pContext->LocalToString(params[2], &value);
210 cvar->SetValue(value);
215 static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
217 Handle_t hndl = static_cast<Handle_t>(params[1]);
221 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
224 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
227 return cvar->GetFlags();
230 static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
232 Handle_t hndl = static_cast<Handle_t>(params[1]);
236 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
239 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
242 cvar->SetFlags(params[2]);
247 static cell_t sm_GetConVarMin(IPluginContext *pContext, const cell_t *params)
249 Handle_t hndl = static_cast<Handle_t>(params[1]);
253 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
256 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
263 pContext->LocalToPhysAddr(params[2], &addr);
265 hasMin = cvar->GetMin(min);
266 *addr = sp_ftoc(min);
271 static cell_t sm_GetConVarMax(IPluginContext *pContext, const cell_t *params)
273 Handle_t hndl = static_cast<Handle_t>(params[1]);
277 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
280 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
287 pContext->LocalToPhysAddr(params[2], &addr);
289 hasMax = cvar->GetMax(max);
290 *addr = sp_ftoc(max);
295 static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
297 Handle_t hndl = static_cast<Handle_t>(params[1]);
301 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
304 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
307 pContext->StringToLocalUTF8(params[2], params[3], cvar->GetName(), NULL);
312 static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
314 Handle_t hndl = static_cast<Handle_t>(params[1]);
318 if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
321 return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
329 static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
332 IPluginFunction *pFunction;
334 pContext->LocalToString(params[1], &name);
335 pContext->LocalToString(params[3], &help);
336 pFunction = pContext->GetFunctionById(params[2]);
340 return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
343 g_ConCmds.AddServerCommand(pFunction, name, help, params[4]);
348 static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
351 IPluginFunction *pFunction;
353 pContext->LocalToString(params[1], &name);
354 pContext->LocalToString(params[3], &help);
355 pFunction = pContext->GetFunctionById(params[2]);
359 return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
362 g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]);
367 static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
371 IPluginFunction *pFunction;
372 FlagBits flags = params[3];
373 int cmdflags = params[6];
375 pContext->LocalToString(params[1], &name);
376 pContext->LocalToString(params[4], &help);
377 pContext->LocalToString(params[5], (char **)&group);
378 pFunction = pContext->GetFunctionById(params[2]);
380 if (group[0] == '\0')
382 CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
383 group = pPlugin->GetFilename();
388 return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
391 g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags);
396 static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
398 return engine->Cmd_Argc() - 1;
401 static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
403 const char *arg = engine->Cmd_Argv(params[1]);
405 pContext->StringToLocalUTF8(params[2], params[3], arg, NULL);
410 static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
412 const char *args = engine->Cmd_Args();
414 pContext->StringToLocalUTF8(params[1], params[2], args, NULL);
419 static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
425 pCtx->LocalToString(params[1], &fmt);
426 size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
428 buffer[res++] = '\n';
431 META_CONPRINT(buffer);
436 static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
438 int index = params[1];
439 if ((index < 0) || (index > g_Players.GetMaxClients()))
441 return pCtx->ThrowNativeError("Invalid client index %d", index);
444 CPlayer *pPlayer = NULL;
447 pPlayer = g_Players.GetPlayerByIndex(index);
448 if (!pPlayer->IsInGame())
450 return pCtx->ThrowNativeError("Client %d is not in game", index);
453 /* Silent fail on bots, engine will crash */
454 if (pPlayer->IsFakeClient())
464 pCtx->LocalToString(params[2], &fmt);
465 size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
467 buffer[res++] = '\n';
472 engine->ClientPrintf(pPlayer->GetEdict(), buffer);
474 META_CONPRINT(buffer);
480 static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
483 size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
485 /* One byte for null terminator, one for newline */
486 buffer[len++] = '\n';
489 engine->ServerCommand(buffer);
494 static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
497 size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
499 /* One byte for null terminator, one for newline */
500 buffer[len++] = '\n';
503 engine->InsertServerCommand(buffer);
508 static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
510 engine->ServerExecute();
515 static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
517 CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
521 return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
524 if (!pPlayer->IsConnected())
526 return pContext->ThrowNativeError("Player %d is not connected", params[1]);
530 g_SourceMod.FormatString(buffer, sizeof(buffer)-1, pContext, params, 2);
532 engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
537 REGISTER_NATIVES(consoleNatives)
539 {"CreateConVar", sm_CreateConVar},
540 {"FindConVar", sm_FindConVar},
541 {"HookConVarChange", sm_HookConVarChange},
542 {"UnhookConVarChange", sm_UnhookConVarChange},
543 {"GetConVarBool", sm_GetConVarBool},
544 {"SetConVarBool", sm_SetConVarNum},
545 {"GetConVarInt", sm_GetConVarInt},
546 {"SetConVarInt", sm_SetConVarNum},
547 {"GetConVarFloat", sm_GetConVarFloat},
548 {"SetConVarFloat", sm_SetConVarFloat},
549 {"GetConVarString", sm_GetConVarString},
550 {"SetConVarString", sm_SetConVarString},
551 {"GetConVarFlags", sm_GetConVarFlags},
552 {"SetConVarFlags", sm_SetConVarFlags},
553 {"GetConVarName", sm_GetConVarName},
554 {"GetConVarMin", sm_GetConVarMin},
555 {"GetConVarMax", sm_GetConVarMax},
556 {"ResetConVar", sm_ResetConVar},
557 {"RegServerCmd", sm_RegServerCmd},
558 {"RegConsoleCmd", sm_RegConsoleCmd},
559 {"GetCmdArgString", sm_GetCmdArgString},
560 {"GetCmdArgs", sm_GetCmdArgs},
561 {"GetCmdArg", sm_GetCmdArg},
562 {"PrintToServer", sm_PrintToServer},
563 {"PrintToConsole", sm_PrintToConsole},
564 {"RegAdminCmd", sm_RegAdminCmd},
565 {"ServerCommand", sm_ServerCommand},
566 {"InsertServerCommand", sm_InsertServerCommand},
567 {"ServerExecute", sm_ServerExecute},
568 {"ClientCommand", sm_ClientCommand},