core/smn_console.cpp
author Scott Ehlert <ds@alliedmods.net>
Sat Apr 14 04:49:08 2007 +0000 (2007-04-14)
changeset 697 9b8bf8377d84
parent 696 d5cc8d0fa899
child 714 93b19876407e
permissions -rw-r--r--
Oh forgot this - QueryClientConVar returns 0 on bots now.
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     7  * This file is not open source and may not be copied without explicit
     8  * written permission of AlliedModders LLC.  This file may not be redistributed 
     9  * in whole or significant part.
    10  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include "sm_globals.h"
    16 #include "HalfLife2.h"
    17 #include "sourcemm_api.h"
    18 #include "HandleSys.h"
    19 #include "ConVarManager.h"
    20 #include "ConCmdManager.h"
    21 #include "PluginSys.h"
    22 #include "sm_stringutil.h"
    23 #include "PlayerManager.h"
    24 
    25 static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
    26 {
    27 	char *name, *defaultVal, *helpText;
    28 
    29 	pContext->LocalToString(params[1], &name);
    30 
    31 	// While the engine seems to accept a blank convar name, it causes a crash upon server quit
    32 	if (name == NULL || strcmp(name, "") == 0)
    33 	{
    34 		return pContext->ThrowNativeError("Convar with blank name is not permitted");
    35 	}
    36 
    37 	pContext->LocalToString(params[2], &defaultVal);
    38 	pContext->LocalToString(params[3], &helpText);
    39 
    40 	bool hasMin = params[5] ? true : false;
    41 	bool hasMax = params[7] ? true : false;
    42 	float min = sp_ctof(params[6]);
    43 	float max = sp_ctof(params[8]);
    44 
    45 	Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
    46 
    47 	if (hndl == BAD_HANDLE)
    48 	{
    49 		return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same name already exists.", name);
    50 	}
    51 
    52 	return hndl;
    53 }
    54 
    55 static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
    56 {
    57 	char *name;
    58 
    59 	pContext->LocalToString(params[1], &name);
    60 
    61 	return g_ConVarManager.FindConVar(name);
    62 }
    63 
    64 static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
    65 {
    66 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    67 	HandleError err;
    68 	ConVar *pConVar;
    69 
    70 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
    71 		!= HandleError_None)
    72 	{
    73 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
    74 	}
    75 
    76 	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
    77 
    78 	if (!pFunction)
    79 	{
    80 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
    81 	}
    82 
    83 	g_ConVarManager.HookConVarChange(pConVar, pFunction);
    84 
    85 	return 1;
    86 }
    87 
    88 static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
    89 {
    90 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    91 	HandleError err;
    92 	ConVar *pConVar;
    93 
    94 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
    95 		!= HandleError_None)
    96 	{
    97 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
    98 	}
    99 
   100 	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
   101 
   102 	if (!pFunction)
   103 	{
   104 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   105 	}
   106 
   107 	g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
   108 
   109 	return 1;
   110 }
   111 
   112 static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
   113 {
   114 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   115 	HandleError err;
   116 	ConVar *pConVar;
   117 
   118 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   119 		!= HandleError_None)
   120 	{
   121 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   122 	}
   123 
   124 	return pConVar->GetBool();
   125 }
   126 
   127 static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
   128 {
   129 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   130 	HandleError err;
   131 	ConVar *pConVar;
   132 
   133 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   134 		!= HandleError_None)
   135 	{
   136 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   137 	}
   138 
   139 	return pConVar->GetInt();
   140 }
   141 
   142 /* This handles both SetConVarBool() and SetConVarInt() */
   143 static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
   144 {
   145 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   146 	HandleError err;
   147 	ConVar *pConVar;
   148 
   149 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   150 		!= HandleError_None)
   151 	{
   152 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   153 	}
   154 
   155 	pConVar->SetValue(params[2]);
   156 
   157 	return 1;
   158 }
   159 
   160 static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
   161 {
   162 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   163 	HandleError err;
   164 	ConVar *pConVar;
   165 
   166 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   167 		!= HandleError_None)
   168 	{
   169 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   170 	}
   171 	
   172 	float value = pConVar->GetFloat();
   173 
   174 	return sp_ftoc(value);
   175 }
   176 
   177 static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
   178 {
   179 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   180 	HandleError err;
   181 	ConVar *pConVar;
   182 
   183 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   184 		!= HandleError_None)
   185 	{
   186 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   187 	}
   188 
   189 	float value = sp_ctof(params[2]);
   190 	pConVar->SetValue(value);
   191 
   192 	return 1;
   193 }
   194 
   195 static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
   196 {
   197 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   198 	HandleError err;
   199 	ConVar *pConVar;
   200 
   201 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   202 		!= HandleError_None)
   203 	{
   204 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   205 	}
   206 
   207 	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
   208 
   209 	return 1;
   210 }
   211 
   212 static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
   213 {
   214 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   215 	HandleError err;
   216 	ConVar *pConVar;
   217 
   218 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   219 		!= HandleError_None)
   220 	{
   221 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   222 	}
   223 
   224 	char *value;
   225 	pContext->LocalToString(params[2], &value);
   226 
   227 	pConVar->SetValue(value);
   228 
   229 	return 1;
   230 }
   231 
   232 static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
   233 {
   234 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   235 	HandleError err;
   236 	ConVar *pConVar;
   237 
   238 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   239 		!= HandleError_None)
   240 	{
   241 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   242 	}
   243 
   244 	return pConVar->GetFlags();
   245 }
   246 
   247 static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
   248 {
   249 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   250 	HandleError err;
   251 	ConVar *pConVar;
   252 
   253 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   254 		!= HandleError_None)
   255 	{
   256 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   257 	}
   258 
   259 	pConVar->SetFlags(params[2]);
   260 
   261 	return 1;
   262 }
   263 
   264 static cell_t sm_GetConVarMin(IPluginContext *pContext, const cell_t *params)
   265 {
   266 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   267 	HandleError err;
   268 	ConVar *pConVar;
   269 
   270 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   271 		!= HandleError_None)
   272 	{
   273 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   274 	}
   275 
   276 	cell_t *addr;
   277 	bool hasMin;
   278 	float min;
   279 
   280 	pContext->LocalToPhysAddr(params[2], &addr);
   281 
   282 	hasMin = pConVar->GetMin(min);
   283 	*addr = sp_ftoc(min);
   284 
   285 	return hasMin;
   286 }
   287 
   288 static cell_t sm_GetConVarMax(IPluginContext *pContext, const cell_t *params)
   289 {
   290 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   291 	HandleError err;
   292 	ConVar *pConVar;
   293 
   294 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   295 		!= HandleError_None)
   296 	{
   297 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   298 	}
   299 
   300 	cell_t *addr;
   301 	bool hasMax;
   302 	float max;
   303 
   304 	pContext->LocalToPhysAddr(params[2], &addr);
   305 
   306 	hasMax = pConVar->GetMax(max);
   307 	*addr = sp_ftoc(max);
   308 
   309 	return hasMax;
   310 }
   311 
   312 static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
   313 {
   314 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   315 	HandleError err;
   316 	ConVar *pConVar;
   317 
   318 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   319 		!= HandleError_None)
   320 	{
   321 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   322 	}
   323 
   324 	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
   325 
   326 	return 1;
   327 }
   328 
   329 static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
   330 {
   331 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   332 	HandleError err;
   333 	ConVar *pConVar;
   334 
   335 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
   336 		!= HandleError_None)
   337 	{
   338 		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
   339 	}
   340 
   341 	pConVar->Revert();
   342 
   343 	return 1;
   344 }
   345 
   346 static bool s_QueryAlreadyWarned = false;
   347 
   348 static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *params)
   349 {
   350 	CPlayer *pPlayer;
   351 	char *name;
   352 	IPluginFunction *pCallback;
   353 
   354 	if (g_IsOriginalEngine)
   355 	{
   356 		if (!s_QueryAlreadyWarned)
   357 		{
   358 			s_QueryAlreadyWarned = true;
   359 			return pContext->ThrowNativeError("Game does not support client convar querying (one time warning)");
   360 		}
   361 
   362 		return 0;
   363 	}
   364 
   365 	pPlayer = g_Players.GetPlayerByIndex(params[1]);
   366 
   367 	if (!pPlayer)
   368 	{
   369 		return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
   370 	}
   371 
   372 	if (!pPlayer->IsConnected())
   373 	{
   374 		return pContext->ThrowNativeError("Player %d is not connected", params[1]);
   375 	}
   376 
   377 	/* Trying a query on a bot results in callback not be fired, so don't bother */
   378 	if (pPlayer->IsFakeClient())
   379 	{
   380 		return 0;
   381 	}
   382 
   383 	pContext->LocalToString(params[2], &name);
   384 	pCallback = pContext->GetFunctionById(params[3]);
   385 
   386 	if (!pCallback)
   387 	{
   388 		return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
   389 	}
   390 
   391 	return g_ConVarManager.QueryClientConVar(pPlayer->GetEdict(), name, pCallback, params[4]);
   392 }
   393 
   394 static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
   395 {
   396 	char *name,*help;
   397 	IPluginFunction *pFunction;
   398 
   399 	pContext->LocalToString(params[1], &name);
   400 	pContext->LocalToString(params[3], &help);
   401 	pFunction = pContext->GetFunctionById(params[2]);
   402 
   403 	if (!pFunction)
   404 	{
   405 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   406 	}
   407 
   408 	if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
   409 	{
   410 		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
   411 	}
   412 
   413 	return 1;
   414 }
   415 
   416 static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
   417 {
   418 	char *name,*help;
   419 	IPluginFunction *pFunction;
   420 
   421 	pContext->LocalToString(params[1], &name);
   422 	pContext->LocalToString(params[3], &help);
   423 	pFunction = pContext->GetFunctionById(params[2]);
   424 
   425 	if (!pFunction)
   426 	{
   427 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   428 	}
   429 
   430 	if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
   431 	{
   432 		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
   433 	}
   434 
   435 	return 1;
   436 }
   437 
   438 static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
   439 {
   440 	char *name,*help;
   441 	const char *group;
   442 	IPluginFunction *pFunction;
   443 	FlagBits flags = params[3];
   444 	int cmdflags = params[6];
   445 
   446 	pContext->LocalToString(params[1], &name);
   447 	pContext->LocalToString(params[4], &help);
   448 	pContext->LocalToString(params[5], (char **)&group);
   449 	pFunction = pContext->GetFunctionById(params[2]);
   450 
   451 	if (group[0] == '\0')
   452 	{
   453 		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   454 		group = pPlugin->GetFilename();
   455 	}
   456 
   457 	if (!pFunction)
   458 	{
   459 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   460 	}
   461 
   462 	if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
   463 	{
   464 		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
   465 	}
   466 
   467 	return 1;
   468 }
   469 
   470 static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
   471 {
   472 	return engine->Cmd_Argc() - 1;
   473 }
   474 
   475 static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
   476 {
   477 	const char *arg = engine->Cmd_Argv(params[1]);
   478 	
   479 	pContext->StringToLocalUTF8(params[2], params[3], arg, NULL);
   480 
   481 	return 1;
   482 }
   483 
   484 static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
   485 {
   486 	const char *args = engine->Cmd_Args();
   487 
   488 	if (!args)
   489 	{
   490 		args = "";
   491 	}
   492 
   493 	pContext->StringToLocalUTF8(params[1], params[2], args, NULL);
   494 
   495 	return 1;
   496 }
   497 
   498 static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
   499 {
   500 	char buffer[1024];
   501 	char *fmt;
   502 	int arg = 2;
   503 
   504 	pCtx->LocalToString(params[1], &fmt);
   505 	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
   506 
   507 	buffer[res++] = '\n';
   508 	buffer[res] = '\0';
   509 
   510 	META_CONPRINT(buffer);
   511 
   512 	return 1;
   513 }
   514 
   515 static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
   516 {
   517 	int index = params[1];
   518 	if ((index < 0) || (index > g_Players.GetMaxClients()))
   519 	{
   520 		return pCtx->ThrowNativeError("Invalid client index %d", index);
   521 	}
   522 
   523 	CPlayer *pPlayer = NULL;
   524 	if (index != 0)
   525 	{
   526 		pPlayer = g_Players.GetPlayerByIndex(index);
   527 		if (!pPlayer->IsInGame())
   528 		{
   529 			return pCtx->ThrowNativeError("Client %d is not in game", index);
   530 		}
   531 		
   532 		/* Silent fail on bots, engine will crash */
   533 		if (pPlayer->IsFakeClient())
   534 		{
   535 			return 0;
   536 		}
   537 	}
   538 
   539 	char buffer[1024];
   540 	char *fmt;
   541 	int arg = 3;
   542 
   543 	pCtx->LocalToString(params[2], &fmt);
   544 	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
   545 
   546 	buffer[res++] = '\n';
   547 	buffer[res] = '\0';
   548 
   549 	if (index != 0)
   550 	{
   551 		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
   552 	} else {
   553 		META_CONPRINT(buffer);
   554 	}
   555 
   556 	return 1;
   557 }
   558 
   559 static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
   560 {
   561 	char buffer[1024];
   562 	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
   563 
   564 	/* One byte for null terminator, one for newline */
   565 	buffer[len++] = '\n';
   566 	buffer[len] = '\0';
   567 
   568 	engine->ServerCommand(buffer);
   569 
   570 	return 1;
   571 }
   572 
   573 static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
   574 {
   575 	char buffer[1024];
   576 	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
   577 
   578 	/* One byte for null terminator, one for newline */
   579 	buffer[len++] = '\n';
   580 	buffer[len] = '\0';
   581 
   582 	engine->InsertServerCommand(buffer);
   583 
   584 	return 1;
   585 }
   586 
   587 static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
   588 {
   589 	engine->ServerExecute();
   590 
   591 	return 1;
   592 }
   593 
   594 static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
   595 {
   596 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
   597 
   598 	if (!pPlayer)
   599 	{
   600 		return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
   601 	}
   602 
   603 	if (!pPlayer->IsConnected())
   604 	{
   605 		return pContext->ThrowNativeError("Player %d is not connected", params[1]);
   606 	}
   607 
   608 	char buffer[256];
   609 	g_SourceMod.FormatString(buffer, sizeof(buffer)-1, pContext, params, 2);
   610 
   611 	engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
   612 
   613 	return 1;
   614 }
   615 
   616 REGISTER_NATIVES(consoleNatives)
   617 {
   618 	{"CreateConVar",		sm_CreateConVar},
   619 	{"FindConVar",			sm_FindConVar},
   620 	{"HookConVarChange",	sm_HookConVarChange},
   621 	{"UnhookConVarChange",	sm_UnhookConVarChange},
   622 	{"GetConVarBool",		sm_GetConVarBool},
   623 	{"SetConVarBool",		sm_SetConVarNum},
   624 	{"GetConVarInt",		sm_GetConVarInt},
   625 	{"SetConVarInt",		sm_SetConVarNum},
   626 	{"GetConVarFloat",		sm_GetConVarFloat},
   627 	{"SetConVarFloat",		sm_SetConVarFloat},
   628 	{"GetConVarString",		sm_GetConVarString},
   629 	{"SetConVarString",		sm_SetConVarString},
   630 	{"GetConVarFlags",		sm_GetConVarFlags},
   631 	{"SetConVarFlags",		sm_SetConVarFlags},
   632 	{"GetConVarName",		sm_GetConVarName},
   633 	{"GetConVarMin",		sm_GetConVarMin},
   634 	{"GetConVarMax",		sm_GetConVarMax},
   635 	{"ResetConVar",			sm_ResetConVar},
   636 	{"QueryClientConVar",	sm_QueryClientConVar},
   637 	{"RegServerCmd",		sm_RegServerCmd},
   638 	{"RegConsoleCmd",		sm_RegConsoleCmd},
   639 	{"GetCmdArgString",		sm_GetCmdArgString},
   640 	{"GetCmdArgs",			sm_GetCmdArgs},
   641 	{"GetCmdArg",			sm_GetCmdArg},
   642 	{"PrintToServer",		sm_PrintToServer},
   643 	{"PrintToConsole",		sm_PrintToConsole},
   644 	{"RegAdminCmd",			sm_RegAdminCmd},
   645 	{"ServerCommand",		sm_ServerCommand},
   646 	{"InsertServerCommand",	sm_InsertServerCommand},
   647 	{"ServerExecute",		sm_ServerExecute},
   648 	{"ClientCommand",		sm_ClientCommand},
   649 	{NULL,					NULL}
   650 };