core/smn_console.cpp
author David Anderson <dvander@alliedmods.net>
Mon Feb 26 09:21:08 2007 +0000 (2007-02-26)
changeset 539 fa7e8a232a18
parent 532 fe6bb91d79b1
child 562 cfce5c6faef6
permissions -rw-r--r--
fixed stupid export
     1 /**
     2 * ===============================================================
     3 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     4 * ===============================================================
     5 *
     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
    10 *
    11 * Version: $Id$
    12 */
    13 
    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"
    22 
    23 static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
    24 {
    25 	char *name, *defaultVal, *helpText;
    26 
    27 	pContext->LocalToString(params[1], &name);
    28 
    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)
    31 	{
    32 		return pContext->ThrowNativeError("Null or blank convar name is not allowed");
    33 	}
    34 
    35 	pContext->LocalToString(params[2], &defaultVal);
    36 	pContext->LocalToString(params[3], &helpText);
    37 
    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]);
    42 
    43 	return g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
    44 }
    45 
    46 static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
    47 {
    48 	char *name;
    49 
    50 	pContext->LocalToString(params[1], &name);
    51 
    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)
    54 	{
    55 		return BAD_HANDLE;
    56 	}
    57 
    58 	return g_ConVarManager.FindConVar(name);
    59 }
    60 
    61 static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
    62 {
    63 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    64 	HandleError err;
    65 	ConVar *cvar;
    66 
    67 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
    68 		!= HandleError_None)
    69 	{
    70 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
    71 	}
    72 
    73 	g_ConVarManager.HookConVarChange(pContext, cvar, static_cast<funcid_t>(params[2]));
    74 
    75 	return 1;
    76 }
    77 
    78 static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
    79 {
    80 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    81 	HandleError err;
    82 	ConVar *cvar;
    83 
    84 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
    85 		!= HandleError_None)
    86 	{
    87 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
    88 	}
    89 
    90 	g_ConVarManager.UnhookConVarChange(pContext, cvar, static_cast<funcid_t>(params[2]));
    91 
    92 	return 1;
    93 }
    94 
    95 static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
    96 {
    97 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    98 	HandleError err;
    99 	ConVar *cvar;
   100 
   101 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   102 		!= HandleError_None)
   103 	{
   104 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   105 	}
   106 
   107 	return cvar->GetBool();
   108 }
   109 
   110 static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
   111 {
   112 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   113 	HandleError err;
   114 	ConVar *cvar;
   115 
   116 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   117 		!= HandleError_None)
   118 	{
   119 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   120 	}
   121 
   122 	return cvar->GetInt();
   123 }
   124 
   125 /* This handles both SetConVarBool() and SetConVarInt() */
   126 static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
   127 {
   128 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   129 	HandleError err;
   130 	ConVar *cvar;
   131 
   132 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   133 		!= HandleError_None)
   134 	{
   135 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   136 	}
   137 
   138 	cvar->SetValue(params[2]);
   139 
   140 	return 1;
   141 }
   142 
   143 static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
   144 {
   145 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   146 	HandleError err;
   147 	ConVar *cvar;
   148 
   149 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   150 		!= HandleError_None)
   151 	{
   152 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   153 	}
   154 	
   155 	float value = cvar->GetFloat();
   156 
   157 	return sp_ftoc(value);
   158 }
   159 
   160 static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
   161 {
   162 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   163 	HandleError err;
   164 	ConVar *cvar;
   165 
   166 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   167 		!= HandleError_None)
   168 	{
   169 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   170 	}
   171 
   172 	float value = sp_ctof(params[2]);
   173 	cvar->SetValue(value);
   174 
   175 	return 1;
   176 }
   177 
   178 static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
   179 {
   180 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   181 	HandleError err;
   182 	ConVar *cvar;
   183 
   184 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   185 		!= HandleError_None)
   186 	{
   187 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   188 	}
   189 
   190 	pContext->StringToLocalUTF8(params[2], params[3], cvar->GetString(), NULL);
   191 
   192 	return 1;
   193 }
   194 
   195 static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
   196 {
   197 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   198 	HandleError err;
   199 	ConVar *cvar;
   200 
   201 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   202 		!= HandleError_None)
   203 	{
   204 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   205 	}
   206 
   207 	char *value;
   208 	pContext->LocalToString(params[2], &value);
   209 
   210 	cvar->SetValue(value);
   211 
   212 	return 1;
   213 }
   214 
   215 static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
   216 {
   217 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   218 	HandleError err;
   219 	ConVar *cvar;
   220 
   221 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   222 		!= HandleError_None)
   223 	{
   224 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   225 	}
   226 
   227 	return cvar->GetFlags();
   228 }
   229 
   230 static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
   231 {
   232 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   233 	HandleError err;
   234 	ConVar *cvar;
   235 
   236 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   237 		!= HandleError_None)
   238 	{
   239 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   240 	}
   241 
   242 	cvar->SetFlags(params[2]);
   243 
   244 	return 1;
   245 }
   246 
   247 static cell_t sm_GetConVarMin(IPluginContext *pContext, const cell_t *params)
   248 {
   249 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   250 	HandleError err;
   251 	ConVar *cvar;
   252 
   253 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   254 		!= HandleError_None)
   255 	{
   256 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   257 	}
   258 
   259 	cell_t *addr;
   260 	bool hasMin;
   261 	float min;
   262 
   263 	pContext->LocalToPhysAddr(params[2], &addr);
   264 
   265 	hasMin = cvar->GetMin(min);
   266 	*addr = sp_ftoc(min);
   267 
   268 	return hasMin;
   269 }
   270 
   271 static cell_t sm_GetConVarMax(IPluginContext *pContext, const cell_t *params)
   272 {
   273 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   274 	HandleError err;
   275 	ConVar *cvar;
   276 
   277 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   278 		!= HandleError_None)
   279 	{
   280 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   281 	}
   282 
   283 	cell_t *addr;
   284 	bool hasMax;
   285 	float max;
   286 
   287 	pContext->LocalToPhysAddr(params[2], &addr);
   288 
   289 	hasMax = cvar->GetMax(max);
   290 	*addr = sp_ftoc(max);
   291 
   292 	return hasMax;
   293 }
   294 
   295 static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
   296 {
   297 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   298 	HandleError err;
   299 	ConVar *cvar;
   300 
   301 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   302 		!= HandleError_None)
   303 	{
   304 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   305 	}
   306 
   307 	pContext->StringToLocalUTF8(params[2], params[3], cvar->GetName(), NULL);
   308 
   309 	return 1;
   310 }
   311 
   312 static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
   313 {
   314 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   315 	HandleError err;
   316 	ConVar *cvar;
   317 
   318 	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
   319 		!= HandleError_None)
   320 	{
   321 		return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
   322 	}
   323 
   324 	cvar->Revert();
   325 
   326 	return 1;
   327 }
   328 
   329 static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
   330 {
   331 	char *name,*help;
   332 	IPluginFunction *pFunction;
   333 
   334 	pContext->LocalToString(params[1], &name);
   335 	pContext->LocalToString(params[3], &help);
   336 	pFunction = pContext->GetFunctionById(params[2]);
   337 
   338 	if (!pFunction)
   339 	{
   340 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   341 	}
   342 
   343 	g_ConCmds.AddServerCommand(pFunction, name, help, params[4]);
   344 
   345 	return 1;
   346 }
   347 
   348 static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
   349 {
   350 	char *name,*help;
   351 	IPluginFunction *pFunction;
   352 
   353 	pContext->LocalToString(params[1], &name);
   354 	pContext->LocalToString(params[3], &help);
   355 	pFunction = pContext->GetFunctionById(params[2]);
   356 
   357 	if (!pFunction)
   358 	{
   359 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   360 	}
   361 
   362 	g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]);
   363 
   364 	return 1;
   365 }
   366 
   367 static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
   368 {
   369 	char *name,*help;
   370 	const char *group;
   371 	IPluginFunction *pFunction;
   372 	FlagBits flags = params[3];
   373 	int cmdflags = params[6];
   374 
   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]);
   379 
   380 	if (group[0] == '\0')
   381 	{
   382 		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   383 		group = pPlugin->GetFilename();
   384 	}
   385 
   386 	if (!pFunction)
   387 	{
   388 		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   389 	}
   390 
   391 	g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags);
   392 
   393 	return 1;
   394 }
   395 
   396 static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
   397 {
   398 	return engine->Cmd_Argc() - 1;
   399 }
   400 
   401 static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
   402 {
   403 	const char *arg = engine->Cmd_Argv(params[1]);
   404 	
   405 	pContext->StringToLocalUTF8(params[2], params[3], arg, NULL);
   406 
   407 	return 1;
   408 }
   409 
   410 static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
   411 {
   412 	const char *args = engine->Cmd_Args();
   413 
   414 	pContext->StringToLocalUTF8(params[1], params[2], args, NULL);
   415 
   416 	return 1;
   417 }
   418 
   419 static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
   420 {
   421 	char buffer[1024];
   422 	char *fmt;
   423 	int arg = 2;
   424 
   425 	pCtx->LocalToString(params[1], &fmt);
   426 	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
   427 
   428 	buffer[res++] = '\n';
   429 	buffer[res] = '\0';
   430 
   431 	META_CONPRINT(buffer);
   432 
   433 	return 1;
   434 }
   435 
   436 static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
   437 {
   438 	int index = params[1];
   439 	if ((index < 0) || (index > g_Players.GetMaxClients()))
   440 	{
   441 		return pCtx->ThrowNativeError("Invalid client index %d", index);
   442 	}
   443 
   444 	CPlayer *pPlayer = NULL;
   445 	if (index != 0)
   446 	{
   447 		pPlayer = g_Players.GetPlayerByIndex(index);
   448 		if (!pPlayer->IsInGame())
   449 		{
   450 			return pCtx->ThrowNativeError("Client %d is not in game", index);
   451 		}
   452 		
   453 		/* Silent fail on bots, engine will crash */
   454 		if (pPlayer->IsFakeClient())
   455 		{
   456 			return 0;
   457 		}
   458 	}
   459 
   460 	char buffer[1024];
   461 	char *fmt;
   462 	int arg = 3;
   463 
   464 	pCtx->LocalToString(params[2], &fmt);
   465 	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
   466 
   467 	buffer[res++] = '\n';
   468 	buffer[res] = '\0';
   469 
   470 	if (index != 0)
   471 	{
   472 		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
   473 	} else {
   474 		META_CONPRINT(buffer);
   475 	}
   476 
   477 	return 1;
   478 }
   479 
   480 static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
   481 {
   482 	char buffer[1024];
   483 	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
   484 
   485 	/* One byte for null terminator, one for newline */
   486 	buffer[len++] = '\n';
   487 	buffer[len] = '\0';
   488 
   489 	engine->ServerCommand(buffer);
   490 
   491 	return 1;
   492 }
   493 
   494 static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
   495 {
   496 	char buffer[1024];
   497 	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
   498 
   499 	/* One byte for null terminator, one for newline */
   500 	buffer[len++] = '\n';
   501 	buffer[len] = '\0';
   502 
   503 	engine->InsertServerCommand(buffer);
   504 
   505 	return 1;
   506 }
   507 
   508 static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
   509 {
   510 	engine->ServerExecute();
   511 
   512 	return 1;
   513 }
   514 
   515 static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
   516 {
   517 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
   518 
   519 	if (!pPlayer)
   520 	{
   521 		return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
   522 	}
   523 
   524 	if (!pPlayer->IsConnected())
   525 	{
   526 		return pContext->ThrowNativeError("Player %d is not connected", params[1]);
   527 	}
   528 
   529 	char buffer[256];
   530 	g_SourceMod.FormatString(buffer, sizeof(buffer)-1, pContext, params, 2);
   531 
   532 	engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
   533 
   534 	return 1;
   535 }
   536 
   537 REGISTER_NATIVES(consoleNatives)
   538 {
   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},
   569 	{NULL,					NULL}
   570 };