core/smn_console.cpp
author Phong Dang <teame06@gmail.com>
Wed Aug 01 07:29:40 2007 +0000 (2007-08-01)
changeset 1241 2e8046793bc9
parent 1231 17badaf66ce4
child 1273 9afc766f8e9c
permissions -rw-r--r--
Added check to make sure player are alive to perform sm_slap, sm_burn, sm_slay.
dvander@498
     1
/**
ds@653
     2
 * vim: set ts=4 :
dvander@1231
     3
 * ================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
dvander@1231
     6
 * ================================================================
dvander@562
     7
 *
dvander@1231
     8
 * This program is free software; you can redistribute it and/or 
dvander@1231
     9
 * modify it under the terms of the GNU General Public License, 
dvander@1231
    10
 * version 3.0, as published by the Free Software Foundation.
dvander@1231
    11
 * 
dvander@1231
    12
 * This program is distributed in the hope that it will be useful,
dvander@1231
    13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
dvander@1231
    14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dvander@1231
    15
 * GNU General Public License for more details.
dvander@1231
    16
 *
dvander@1231
    17
 * You should have received a copy of the GNU General Public License
dvander@1231
    18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
dvander@1231
    20
 * As a special exception, AlliedModders LLC gives you permission to 
dvander@1231
    21
 * link the code of this program (as well as its derivative works) to 
dvander@1231
    22
 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
dvander@1231
    23
 * Game MODs that run on software by the Valve Corporation.  You must 
dvander@1231
    24
 * obey the GNU General Public License in all respects for all other 
dvander@1231
    25
 * code used. Additionally, AlliedModders LLC grants this exception 
dvander@1231
    26
 * to all derivative works. AlliedModders LLC defines further 
dvander@1231
    27
 * exceptions, found in LICENSE.txt (as of this writing, version 
dvander@1231
    28
 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
dvander@562
    29
 *
dvander@562
    30
 * Version: $Id$
dvander@562
    31
 */
dvander@498
    32
dvander@498
    33
#include "sm_globals.h"
ds@696
    34
#include "HalfLife2.h"
dvander@498
    35
#include "sourcemm_api.h"
dvander@498
    36
#include "HandleSys.h"
ds@580
    37
#include "ConVarManager.h"
ds@579
    38
#include "ConCmdManager.h"
dvander@514
    39
#include "PluginSys.h"
dvander@518
    40
#include "sm_stringutil.h"
dvander@591
    41
#include "PlayerManager.h"
dvander@893
    42
#include "ChatTriggers.h"
ds@936
    43
#include <inetchannel.h>
ds@936
    44
#include <bitbuf.h>
ds@936
    45
ds@936
    46
#define NET_SETCONVAR	5
dvander@498
    47
ds@714
    48
enum ConVarBounds
ds@714
    49
{
ds@714
    50
	ConVarBound_Upper = 0,
ds@714
    51
	ConVarBound_Lower
ds@714
    52
};
ds@714
    53
dvander@1119
    54
HandleType_t hCmdIterType = 0;
dvander@1119
    55
dvander@1119
    56
struct GlobCmdIter
dvander@1119
    57
{
dvander@1119
    58
	bool started;
dvander@1119
    59
	List<ConCmdInfo *>::iterator iter;
dvander@1119
    60
};
dvander@1119
    61
dvander@1119
    62
class ConsoleHelpers : 
dvander@1119
    63
	public SMGlobalClass,
dvander@1119
    64
	public IHandleTypeDispatch
dvander@1119
    65
{
dvander@1119
    66
public:
dvander@1119
    67
	virtual void OnSourceModAllInitialized()
dvander@1119
    68
	{
dvander@1119
    69
		HandleAccess access;
dvander@1119
    70
		g_HandleSys.InitAccessDefaults(NULL, &access);
dvander@1119
    71
		access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER | HANDLE_RESTRICT_IDENTITY;
dvander@1119
    72
dvander@1119
    73
		hCmdIterType = g_HandleSys.CreateType(NULL, this, 0, NULL, &access, g_pCoreIdent, NULL);
dvander@1119
    74
	}
dvander@1119
    75
	virtual void OnHandleDestroy(HandleType_t type, void *object)
dvander@1119
    76
	{
dvander@1119
    77
		GlobCmdIter *iter = (GlobCmdIter *)object;
dvander@1119
    78
		delete iter;
dvander@1119
    79
	}
dvander@1119
    80
} s_ConsoleHelpers;
dvander@1119
    81
ds@936
    82
static void ReplicateConVar(ConVar *pConVar)
ds@936
    83
{
ds@936
    84
	int maxClients = g_Players.GetMaxClients();
ds@936
    85
ds@936
    86
	char data[256];
ds@936
    87
	bf_write buffer(data, sizeof(data));
ds@936
    88
ds@936
    89
	buffer.WriteUBitLong(NET_SETCONVAR, 5);
ds@936
    90
	buffer.WriteByte(1);
ds@936
    91
	buffer.WriteString(pConVar->GetName());
ds@936
    92
	buffer.WriteString(pConVar->GetString());
ds@936
    93
ds@936
    94
	for (int i = 1; i <= maxClients; i++)
ds@936
    95
	{
ds@936
    96
		CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
ds@936
    97
ds@936
    98
		if (pPlayer && pPlayer->IsInGame() && !pPlayer->IsFakeClient())
ds@936
    99
		{
ds@936
   100
			INetChannel *netchan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(i));
ds@936
   101
			netchan->SendData(buffer);
ds@936
   102
		}
ds@936
   103
	}
ds@936
   104
}
ds@936
   105
ds@936
   106
static void NotifyConVar(ConVar *pConVar)
ds@936
   107
{
ds@936
   108
	IGameEvent *pEvent = gameevents->CreateEvent("server_cvar");
ds@936
   109
	pEvent->SetString("cvarname", pConVar->GetName());
ds@936
   110
	if (pConVar->IsBitSet(FCVAR_PROTECTED))
ds@936
   111
	{
ds@936
   112
		pEvent->SetString("cvarvalue", "***PROTECTED***");
ds@936
   113
	} else {
ds@936
   114
		pEvent->SetString("cvarvalue", pConVar->GetString());
ds@936
   115
	}
ds@936
   116
ds@936
   117
	gameevents->FireEvent(pEvent);
ds@936
   118
}
ds@936
   119
dvander@498
   120
static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
   121
{
dvander@498
   122
	char *name, *defaultVal, *helpText;
dvander@498
   123
dvander@498
   124
	pContext->LocalToString(params[1], &name);
dvander@498
   125
dvander@498
   126
	// While the engine seems to accept a blank convar name, it causes a crash upon server quit
dvander@498
   127
	if (name == NULL || strcmp(name, "") == 0)
dvander@498
   128
	{
ds@582
   129
		return pContext->ThrowNativeError("Convar with blank name is not permitted");
dvander@498
   130
	}
dvander@498
   131
dvander@498
   132
	pContext->LocalToString(params[2], &defaultVal);
dvander@498
   133
	pContext->LocalToString(params[3], &helpText);
dvander@498
   134
dvander@498
   135
	bool hasMin = params[5] ? true : false;
dvander@498
   136
	bool hasMax = params[7] ? true : false;
dvander@498
   137
	float min = sp_ctof(params[6]);
dvander@498
   138
	float max = sp_ctof(params[8]);
dvander@498
   139
ds@582
   140
	Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
ds@582
   141
ds@582
   142
	if (hndl == BAD_HANDLE)
ds@582
   143
	{
ds@582
   144
		return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same name already exists.", name);
ds@582
   145
	}
ds@582
   146
ds@582
   147
	return hndl;
dvander@498
   148
}
dvander@498
   149
dvander@498
   150
static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
   151
{
dvander@498
   152
	char *name;
dvander@498
   153
dvander@498
   154
	pContext->LocalToString(params[1], &name);
dvander@498
   155
dvander@498
   156
	return g_ConVarManager.FindConVar(name);
dvander@498
   157
}
dvander@498
   158
dvander@498
   159
static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498
   160
{
dvander@498
   161
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   162
	HandleError err;
ds@576
   163
	ConVar *pConVar;
dvander@498
   164
ds@576
   165
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   166
		!= HandleError_None)
dvander@498
   167
	{
ds@581
   168
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   169
	}
dvander@498
   170
ds@582
   171
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582
   172
ds@582
   173
	if (!pFunction)
ds@582
   174
	{
ds@582
   175
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582
   176
	}
ds@582
   177
ds@582
   178
	g_ConVarManager.HookConVarChange(pConVar, pFunction);
dvander@498
   179
dvander@498
   180
	return 1;
dvander@498
   181
}
dvander@498
   182
dvander@498
   183
static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498
   184
{
dvander@498
   185
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   186
	HandleError err;
ds@576
   187
	ConVar *pConVar;
dvander@498
   188
ds@576
   189
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   190
		!= HandleError_None)
dvander@498
   191
	{
ds@581
   192
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   193
	}
dvander@498
   194
ds@582
   195
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582
   196
ds@582
   197
	if (!pFunction)
ds@582
   198
	{
ds@582
   199
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582
   200
	}
ds@582
   201
ds@582
   202
	g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
dvander@498
   203
dvander@498
   204
	return 1;
dvander@498
   205
}
dvander@498
   206
dvander@498
   207
static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
dvander@498
   208
{
dvander@498
   209
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   210
	HandleError err;
ds@576
   211
	ConVar *pConVar;
dvander@498
   212
ds@576
   213
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   214
		!= HandleError_None)
dvander@498
   215
	{
ds@581
   216
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   217
	}
dvander@498
   218
ds@576
   219
	return pConVar->GetBool();
dvander@498
   220
}
dvander@498
   221
dvander@498
   222
static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
dvander@498
   223
{
dvander@498
   224
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   225
	HandleError err;
ds@576
   226
	ConVar *pConVar;
dvander@498
   227
ds@576
   228
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   229
		!= HandleError_None)
dvander@498
   230
	{
ds@581
   231
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   232
	}
dvander@498
   233
ds@576
   234
	return pConVar->GetInt();
dvander@498
   235
}
dvander@498
   236
dvander@498
   237
/* This handles both SetConVarBool() and SetConVarInt() */
dvander@498
   238
static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
dvander@498
   239
{
dvander@498
   240
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   241
	HandleError err;
ds@576
   242
	ConVar *pConVar;
dvander@498
   243
ds@576
   244
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   245
		!= HandleError_None)
dvander@498
   246
	{
ds@581
   247
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   248
	}
dvander@498
   249
ds@576
   250
	pConVar->SetValue(params[2]);
dvander@498
   251
ds@936
   252
	/* Should we replicate it? */
ds@936
   253
	if (params[3] && pConVar->IsBitSet(FCVAR_REPLICATED))
ds@936
   254
	{
ds@936
   255
		ReplicateConVar(pConVar);
ds@936
   256
	}
ds@936
   257
ds@936
   258
	/* Should we notify clients? */
ds@936
   259
	if (params[4] && pConVar->IsBitSet(FCVAR_NOTIFY))
ds@936
   260
	{
ds@936
   261
		NotifyConVar(pConVar);
ds@936
   262
	}
ds@936
   263
dvander@498
   264
	return 1;
dvander@498
   265
}
dvander@498
   266
dvander@498
   267
static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498
   268
{
dvander@498
   269
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   270
	HandleError err;
ds@576
   271
	ConVar *pConVar;
dvander@498
   272
ds@576
   273
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   274
		!= HandleError_None)
dvander@498
   275
	{
ds@581
   276
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   277
	}
dvander@498
   278
	
ds@576
   279
	float value = pConVar->GetFloat();
dvander@498
   280
dvander@498
   281
	return sp_ftoc(value);
dvander@498
   282
}
dvander@498
   283
dvander@498
   284
static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498
   285
{
dvander@498
   286
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   287
	HandleError err;
ds@576
   288
	ConVar *pConVar;
dvander@498
   289
ds@576
   290
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   291
		!= HandleError_None)
dvander@498
   292
	{
ds@581
   293
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   294
	}
dvander@498
   295
dvander@498
   296
	float value = sp_ctof(params[2]);
ds@576
   297
	pConVar->SetValue(value);
dvander@498
   298
ds@936
   299
	/* Should we replicate it? */
ds@936
   300
	if (params[3] && pConVar->IsBitSet(FCVAR_REPLICATED))
ds@936
   301
	{
ds@936
   302
		ReplicateConVar(pConVar);
ds@936
   303
	}
ds@936
   304
ds@936
   305
	/* Should we notify clients? */
ds@936
   306
	if (params[4] && pConVar->IsBitSet(FCVAR_NOTIFY))
ds@936
   307
	{
ds@936
   308
		NotifyConVar(pConVar);
ds@936
   309
	}
ds@936
   310
dvander@498
   311
	return 1;
dvander@498
   312
}
dvander@498
   313
dvander@498
   314
static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498
   315
{
dvander@498
   316
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   317
	HandleError err;
ds@576
   318
	ConVar *pConVar;
dvander@498
   319
ds@576
   320
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   321
		!= HandleError_None)
dvander@498
   322
	{
ds@581
   323
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   324
	}
dvander@498
   325
ds@576
   326
	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
dvander@498
   327
dvander@498
   328
	return 1;
dvander@498
   329
}
dvander@498
   330
dvander@498
   331
static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498
   332
{
dvander@498
   333
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   334
	HandleError err;
ds@576
   335
	ConVar *pConVar;
dvander@498
   336
ds@576
   337
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   338
		!= HandleError_None)
dvander@498
   339
	{
ds@581
   340
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   341
	}
dvander@498
   342
dvander@498
   343
	char *value;
dvander@498
   344
	pContext->LocalToString(params[2], &value);
dvander@498
   345
ds@576
   346
	pConVar->SetValue(value);
dvander@498
   347
ds@936
   348
	/* Should we replicate it? */
ds@936
   349
	if (params[3] && pConVar->IsBitSet(FCVAR_REPLICATED))
ds@936
   350
	{
ds@936
   351
		ReplicateConVar(pConVar);
ds@936
   352
	}
ds@936
   353
ds@936
   354
	/* Should we notify clients? */
ds@936
   355
	if (params[4] && pConVar->IsBitSet(FCVAR_NOTIFY))
ds@936
   356
	{
ds@936
   357
		NotifyConVar(pConVar);
ds@936
   358
	}
ds@936
   359
dvander@498
   360
	return 1;
dvander@498
   361
}
dvander@498
   362
dvander@498
   363
static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498
   364
{
dvander@498
   365
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   366
	HandleError err;
ds@576
   367
	ConVar *pConVar;
dvander@498
   368
ds@576
   369
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   370
		!= HandleError_None)
dvander@498
   371
	{
ds@581
   372
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   373
	}
dvander@498
   374
ds@576
   375
	return pConVar->GetFlags();
dvander@498
   376
}
dvander@498
   377
dvander@498
   378
static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498
   379
{
dvander@498
   380
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   381
	HandleError err;
ds@576
   382
	ConVar *pConVar;
dvander@498
   383
ds@576
   384
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   385
		!= HandleError_None)
dvander@498
   386
	{
ds@581
   387
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   388
	}
dvander@498
   389
ds@576
   390
	pConVar->SetFlags(params[2]);
dvander@498
   391
dvander@498
   392
	return 1;
dvander@498
   393
}
dvander@498
   394
ds@714
   395
static cell_t sm_GetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498
   396
{
dvander@498
   397
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   398
	HandleError err;
ds@576
   399
	ConVar *pConVar;
dvander@498
   400
ds@576
   401
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   402
		!= HandleError_None)
dvander@498
   403
	{
ds@581
   404
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   405
	}
dvander@498
   406
dvander@498
   407
	cell_t *addr;
ds@714
   408
	bool hasBound;
ds@714
   409
	float bound;
dvander@498
   410
ds@714
   411
	switch (params[2])
ds@714
   412
	{
ds@714
   413
	case ConVarBound_Upper:
ds@714
   414
		hasBound = pConVar->GetMax(bound);
ds@714
   415
		break;
ds@714
   416
	case ConVarBound_Lower:
ds@714
   417
		hasBound = pConVar->GetMin(bound);
ds@714
   418
		break;
ds@714
   419
	default:
ds@714
   420
		return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714
   421
	}
ds@714
   422
	
ds@714
   423
	pContext->LocalToPhysAddr(params[3], &addr);
ds@714
   424
	*addr = sp_ftoc(bound);
dvander@498
   425
ds@714
   426
	return hasBound;
dvander@498
   427
}
dvander@498
   428
ds@714
   429
static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498
   430
{
dvander@498
   431
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   432
	HandleError err;
ds@576
   433
	ConVar *pConVar;
dvander@498
   434
ds@576
   435
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   436
		!= HandleError_None)
dvander@498
   437
	{
ds@581
   438
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   439
	}
dvander@498
   440
ds@714
   441
	switch (params[2])
ds@714
   442
	{
ds@714
   443
	case ConVarBound_Upper:
ds@714
   444
		pConVar->SetMax(params[3] ? true : false, sp_ctof(params[4]));
ds@714
   445
		break;
ds@714
   446
	case ConVarBound_Lower:
ds@714
   447
		pConVar->SetMin(params[3] ? true : false, sp_ctof(params[4]));
ds@714
   448
		break;
ds@714
   449
	default:
ds@714
   450
		return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714
   451
	}
dvander@498
   452
ds@714
   453
	return 1;
dvander@498
   454
}
dvander@498
   455
dvander@498
   456
static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
dvander@498
   457
{
dvander@498
   458
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   459
	HandleError err;
ds@576
   460
	ConVar *pConVar;
dvander@498
   461
ds@576
   462
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   463
		!= HandleError_None)
dvander@498
   464
	{
ds@581
   465
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   466
	}
dvander@498
   467
ds@576
   468
	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
dvander@498
   469
dvander@498
   470
	return 1;
dvander@498
   471
}
dvander@498
   472
dvander@498
   473
static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
   474
{
dvander@498
   475
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   476
	HandleError err;
ds@576
   477
	ConVar *pConVar;
dvander@498
   478
ds@576
   479
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   480
		!= HandleError_None)
dvander@498
   481
	{
ds@581
   482
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   483
	}
dvander@498
   484
ds@576
   485
	pConVar->Revert();
dvander@498
   486
dvander@498
   487
	return 1;
dvander@498
   488
}
dvander@498
   489
ds@696
   490
static bool s_QueryAlreadyWarned = false;
ds@696
   491
ds@696
   492
static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *params)
ds@696
   493
{
ds@696
   494
	CPlayer *pPlayer;
ds@696
   495
	char *name;
ds@696
   496
	IPluginFunction *pCallback;
ds@696
   497
ds@696
   498
	if (g_IsOriginalEngine)
ds@696
   499
	{
ds@696
   500
		if (!s_QueryAlreadyWarned)
ds@696
   501
		{
ds@696
   502
			s_QueryAlreadyWarned = true;
ds@696
   503
			return pContext->ThrowNativeError("Game does not support client convar querying (one time warning)");
ds@696
   504
		}
ds@696
   505
ds@696
   506
		return 0;
ds@696
   507
	}
ds@696
   508
ds@696
   509
	pPlayer = g_Players.GetPlayerByIndex(params[1]);
ds@696
   510
ds@696
   511
	if (!pPlayer)
ds@696
   512
	{
ds@994
   513
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
ds@696
   514
	}
ds@696
   515
ds@697
   516
	if (!pPlayer->IsConnected())
ds@696
   517
	{
ds@994
   518
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
ds@697
   519
	}
ds@697
   520
ds@697
   521
	/* Trying a query on a bot results in callback not be fired, so don't bother */
ds@697
   522
	if (pPlayer->IsFakeClient())
ds@697
   523
	{
ds@697
   524
		return 0;
ds@696
   525
	}
ds@696
   526
ds@696
   527
	pContext->LocalToString(params[2], &name);
ds@696
   528
	pCallback = pContext->GetFunctionById(params[3]);
ds@696
   529
ds@696
   530
	if (!pCallback)
ds@696
   531
	{
ds@696
   532
		return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
ds@696
   533
	}
ds@696
   534
ds@696
   535
	return g_ConVarManager.QueryClientConVar(pPlayer->GetEdict(), name, pCallback, params[4]);
ds@696
   536
}
ds@696
   537
dvander@498
   538
static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
dvander@498
   539
{
dvander@498
   540
	char *name,*help;
dvander@498
   541
	IPluginFunction *pFunction;
dvander@498
   542
dvander@498
   543
	pContext->LocalToString(params[1], &name);
dvander@498
   544
	pContext->LocalToString(params[3], &help);
dvander@498
   545
	pFunction = pContext->GetFunctionById(params[2]);
dvander@498
   546
dvander@498
   547
	if (!pFunction)
dvander@498
   548
	{
dvander@498
   549
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@498
   550
	}
dvander@498
   551
ds@579
   552
	if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
ds@579
   553
	{
ds@579
   554
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   555
	}
dvander@498
   556
dvander@498
   557
	return 1;
dvander@498
   558
}
dvander@498
   559
dvander@500
   560
static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
dvander@500
   561
{
dvander@500
   562
	char *name,*help;
dvander@500
   563
	IPluginFunction *pFunction;
dvander@500
   564
dvander@500
   565
	pContext->LocalToString(params[1], &name);
dvander@500
   566
	pContext->LocalToString(params[3], &help);
dvander@500
   567
	pFunction = pContext->GetFunctionById(params[2]);
dvander@500
   568
dvander@500
   569
	if (!pFunction)
dvander@500
   570
	{
dvander@500
   571
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@500
   572
	}
dvander@500
   573
ds@579
   574
	if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
ds@579
   575
	{
ds@579
   576
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   577
	}
dvander@500
   578
dvander@500
   579
	return 1;
dvander@500
   580
}
dvander@500
   581
dvander@514
   582
static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
dvander@514
   583
{
dvander@514
   584
	char *name,*help;
dvander@514
   585
	const char *group;
dvander@514
   586
	IPluginFunction *pFunction;
dvander@514
   587
	FlagBits flags = params[3];
dvander@514
   588
	int cmdflags = params[6];
dvander@514
   589
dvander@514
   590
	pContext->LocalToString(params[1], &name);
dvander@514
   591
	pContext->LocalToString(params[4], &help);
dvander@514
   592
	pContext->LocalToString(params[5], (char **)&group);
dvander@514
   593
	pFunction = pContext->GetFunctionById(params[2]);
dvander@514
   594
dvander@514
   595
	if (group[0] == '\0')
dvander@514
   596
	{
dvander@514
   597
		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@514
   598
		group = pPlugin->GetFilename();
dvander@514
   599
	}
dvander@514
   600
dvander@514
   601
	if (!pFunction)
dvander@514
   602
	{
dvander@514
   603
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@514
   604
	}
dvander@514
   605
ds@579
   606
	if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
ds@579
   607
	{
ds@579
   608
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   609
	}
dvander@514
   610
dvander@514
   611
	return 1;
dvander@514
   612
}
dvander@514
   613
dvander@517
   614
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
dvander@517
   615
{
dvander@517
   616
	return engine->Cmd_Argc() - 1;
dvander@517
   617
}
dvander@517
   618
dvander@517
   619
static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
dvander@517
   620
{
dvander@517
   621
	const char *arg = engine->Cmd_Argv(params[1]);
dvander@517
   622
	
dvander@517
   623
	pContext->StringToLocalUTF8(params[2], params[3], arg, NULL);
dvander@517
   624
dvander@517
   625
	return 1;
dvander@517
   626
}
dvander@517
   627
dvander@517
   628
static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
dvander@517
   629
{
dvander@517
   630
	const char *args = engine->Cmd_Args();
dvander@517
   631
dvander@633
   632
	if (!args)
dvander@633
   633
	{
dvander@633
   634
		args = "";
dvander@633
   635
	}
dvander@633
   636
dvander@517
   637
	pContext->StringToLocalUTF8(params[1], params[2], args, NULL);
dvander@517
   638
dvander@517
   639
	return 1;
dvander@517
   640
}
dvander@517
   641
dvander@518
   642
static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
dvander@518
   643
{
dvander@518
   644
	char buffer[1024];
dvander@518
   645
	char *fmt;
dvander@518
   646
	int arg = 2;
dvander@518
   647
dvander@518
   648
	pCtx->LocalToString(params[1], &fmt);
dvander@518
   649
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518
   650
dvander@518
   651
	buffer[res++] = '\n';
dvander@518
   652
	buffer[res] = '\0';
dvander@518
   653
dvander@518
   654
	META_CONPRINT(buffer);
dvander@518
   655
dvander@518
   656
	return 1;
dvander@518
   657
}
dvander@518
   658
dvander@518
   659
static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
dvander@518
   660
{
dvander@518
   661
	int index = params[1];
dvander@520
   662
	if ((index < 0) || (index > g_Players.GetMaxClients()))
dvander@518
   663
	{
ds@994
   664
		return pCtx->ThrowNativeError("Client index %d is invalid", index);
dvander@518
   665
	}
dvander@518
   666
dvander@520
   667
	CPlayer *pPlayer = NULL;
dvander@520
   668
	if (index != 0)
dvander@518
   669
	{
dvander@520
   670
		pPlayer = g_Players.GetPlayerByIndex(index);
dvander@520
   671
		if (!pPlayer->IsInGame())
dvander@520
   672
		{
dvander@520
   673
			return pCtx->ThrowNativeError("Client %d is not in game", index);
dvander@520
   674
		}
dvander@520
   675
		
dvander@520
   676
		/* Silent fail on bots, engine will crash */
dvander@520
   677
		if (pPlayer->IsFakeClient())
dvander@520
   678
		{
dvander@520
   679
			return 0;
dvander@520
   680
		}
dvander@519
   681
	}
dvander@518
   682
dvander@518
   683
	char buffer[1024];
dvander@518
   684
	char *fmt;
dvander@518
   685
	int arg = 3;
dvander@518
   686
dvander@518
   687
	pCtx->LocalToString(params[2], &fmt);
dvander@518
   688
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518
   689
dvander@518
   690
	buffer[res++] = '\n';
dvander@518
   691
	buffer[res] = '\0';
dvander@518
   692
dvander@520
   693
	if (index != 0)
dvander@520
   694
	{
dvander@520
   695
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@520
   696
	} else {
dvander@520
   697
		META_CONPRINT(buffer);
dvander@520
   698
	}
dvander@518
   699
dvander@518
   700
	return 1;
dvander@518
   701
}
dvander@518
   702
dvander@522
   703
static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522
   704
{
dvander@522
   705
	char buffer[1024];
dvander@522
   706
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522
   707
dvander@1011
   708
	g_SourceMod.SetGlobalTarget(LANG_SERVER);
dvander@1011
   709
dvander@522
   710
	/* One byte for null terminator, one for newline */
dvander@522
   711
	buffer[len++] = '\n';
dvander@522
   712
	buffer[len] = '\0';
dvander@522
   713
dvander@522
   714
	engine->ServerCommand(buffer);
dvander@522
   715
dvander@522
   716
	return 1;
dvander@522
   717
}
dvander@522
   718
dvander@522
   719
static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522
   720
{
dvander@522
   721
	char buffer[1024];
dvander@522
   722
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522
   723
dvander@1011
   724
	g_SourceMod.SetGlobalTarget(LANG_SERVER);
dvander@1011
   725
dvander@522
   726
	/* One byte for null terminator, one for newline */
dvander@522
   727
	buffer[len++] = '\n';
dvander@522
   728
	buffer[len] = '\0';
dvander@522
   729
dvander@522
   730
	engine->InsertServerCommand(buffer);
dvander@522
   731
dvander@522
   732
	return 1;
dvander@522
   733
}
dvander@522
   734
dvander@522
   735
static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
dvander@522
   736
{
dvander@522
   737
	engine->ServerExecute();
dvander@522
   738
dvander@522
   739
	return 1;
dvander@522
   740
}
dvander@522
   741
dvander@532
   742
static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@532
   743
{
dvander@532
   744
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@532
   745
dvander@532
   746
	if (!pPlayer)
dvander@532
   747
	{
ds@994
   748
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@532
   749
	}
dvander@532
   750
dvander@532
   751
	if (!pPlayer->IsConnected())
dvander@532
   752
	{
ds@994
   753
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@532
   754
	}
dvander@532
   755
dvander@1011
   756
	g_SourceMod.SetGlobalTarget(params[1]);
dvander@1011
   757
dvander@532
   758
	char buffer[256];
ds@873
   759
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@532
   760
dvander@532
   761
	engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
dvander@532
   762
dvander@532
   763
	return 1;
dvander@532
   764
}
dvander@532
   765
dvander@893
   766
dvander@893
   767
static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@893
   768
{
dvander@893
   769
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893
   770
dvander@893
   771
	if (!pPlayer)
dvander@893
   772
	{
ds@994
   773
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893
   774
	}
dvander@893
   775
dvander@893
   776
	if (!pPlayer->IsConnected())
dvander@893
   777
	{
ds@994
   778
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893
   779
	}
dvander@893
   780
dvander@893
   781
	char buffer[256];
dvander@893
   782
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@893
   783
dvander@893
   784
	unsigned int old = g_ChatTriggers.SetReplyTo(SM_REPLY_CONSOLE);
dvander@893
   785
	serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), buffer);
dvander@893
   786
	g_ChatTriggers.SetReplyTo(old);
dvander@893
   787
dvander@893
   788
	return 1;
dvander@893
   789
}
dvander@893
   790
dvander@893
   791
static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
dvander@893
   792
{
dvander@1011
   793
	g_SourceMod.SetGlobalTarget(params[1]);
dvander@1011
   794
dvander@893
   795
	/* Build the format string */
dvander@893
   796
	char buffer[1024];
dvander@893
   797
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 2);
dvander@893
   798
dvander@893
   799
	/* If we're printing to the server, shortcut out */
dvander@893
   800
	if (params[1] == 0)
dvander@893
   801
	{
dvander@893
   802
		/* Print */
dvander@893
   803
		buffer[len++] = '\n';
dvander@893
   804
		buffer[len] = '\0';
dvander@893
   805
		META_CONPRINT(buffer);
dvander@893
   806
		return 1;
dvander@893
   807
	}
dvander@893
   808
dvander@893
   809
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893
   810
dvander@893
   811
	if (!pPlayer)
dvander@893
   812
	{
dvander@893
   813
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893
   814
	}
dvander@893
   815
dvander@893
   816
	if (!pPlayer->IsConnected())
dvander@893
   817
	{
dvander@893
   818
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893
   819
	}
dvander@893
   820
dvander@910
   821
	g_SourceMod.SetGlobalTarget(params[1]);
dvander@910
   822
dvander@893
   823
	unsigned int replyto = g_ChatTriggers.GetReplyTo();
dvander@893
   824
	if (replyto == SM_REPLY_CONSOLE)
dvander@893
   825
	{
dvander@893
   826
		buffer[len++] = '\n';
dvander@893
   827
		buffer[len] = '\0';
dvander@893
   828
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@893
   829
	} else if (replyto == SM_REPLY_CHAT) {
dvander@893
   830
		if (len >= 191)
dvander@893
   831
		{
dvander@893
   832
			len = 191;
dvander@893
   833
		}
dvander@893
   834
		buffer[len] = '\0';
dvander@893
   835
		g_HL2.TextMsg(params[1], HUD_PRINTTALK, buffer);
dvander@893
   836
	}
dvander@893
   837
dvander@893
   838
	return 1;
dvander@893
   839
}
dvander@893
   840
dvander@923
   841
static cell_t GetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
dvander@923
   842
{
dvander@923
   843
	return g_ChatTriggers.GetReplyTo();
dvander@923
   844
}
dvander@923
   845
dvander@1071
   846
static cell_t SetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
dvander@1071
   847
{
dvander@1071
   848
	return g_ChatTriggers.SetReplyTo(params[1]);
dvander@1071
   849
}
dvander@1071
   850
dvander@1119
   851
static cell_t GetCommandIterator(IPluginContext *pContext, const cell_t *params)
dvander@1119
   852
{
dvander@1119
   853
	GlobCmdIter *iter = new GlobCmdIter;
dvander@1119
   854
	iter->started = false;
dvander@1119
   855
dvander@1119
   856
	Handle_t hndl = g_HandleSys.CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
dvander@1119
   857
	if (hndl == BAD_HANDLE)
dvander@1119
   858
	{
dvander@1119
   859
		delete iter;
dvander@1119
   860
	}
dvander@1119
   861
dvander@1119
   862
	return hndl;
dvander@1119
   863
}
dvander@1119
   864
dvander@1119
   865
static cell_t ReadCommandIterator(IPluginContext *pContext, const cell_t *params)
dvander@1119
   866
{
dvander@1119
   867
	GlobCmdIter *iter;
dvander@1119
   868
	HandleError err;
dvander@1119
   869
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1119
   870
dvander@1119
   871
	if ((err = g_HandleSys.ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
dvander@1119
   872
		!= HandleError_None)
dvander@1119
   873
	{
dvander@1119
   874
		return pContext->ThrowNativeError("Invalid GlobCmdIter Handle %x", params[1]);
dvander@1119
   875
	}
dvander@1119
   876
dvander@1119
   877
	const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
dvander@1119
   878
dvander@1119
   879
	if (!iter->started)
dvander@1119
   880
	{
dvander@1119
   881
		iter->iter = cmds.begin();
dvander@1119
   882
		iter->started = true;
dvander@1119
   883
	}
dvander@1119
   884
dvander@1119
   885
	while (iter->iter != cmds.end()
dvander@1119
   886
			&& !(*(iter->iter))->sourceMod)
dvander@1119
   887
	{
dvander@1119
   888
		iter->iter++;
dvander@1119
   889
	}
dvander@1119
   890
dvander@1119
   891
	if (iter->iter == cmds.end())
dvander@1119
   892
	{
dvander@1119
   893
		return 0;
dvander@1119
   894
	}
dvander@1119
   895
dvander@1119
   896
	ConCmdInfo *pInfo = (*(iter->iter));
dvander@1119
   897
dvander@1119
   898
	pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
dvander@1119
   899
	pContext->StringToLocalUTF8(params[5], params[6], pInfo->pCmd->GetHelpText(), NULL);
dvander@1119
   900
	
dvander@1119
   901
	cell_t *addr;
dvander@1119
   902
	pContext->LocalToPhysAddr(params[4], &addr);
dvander@1119
   903
	*addr = pInfo->admin.eflags;
dvander@1119
   904
dvander@1119
   905
	iter->iter++;
dvander@1119
   906
dvander@1119
   907
	return 1;
dvander@1119
   908
}
dvander@1119
   909
dvander@1119
   910
static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params)
dvander@1119
   911
{
dvander@1119
   912
	if (params[1] == 0)
dvander@1119
   913
	{
dvander@1119
   914
		return 1;
dvander@1119
   915
	}
dvander@1119
   916
dvander@1119
   917
	char *cmd;
dvander@1119
   918
	pContext->LocalToString(params[2], &cmd);
dvander@1119
   919
dvander@1119
   920
	return g_ConCmds.CheckCommandAccess(params[1], cmd, params[3]) ? 1 : 0;
dvander@1119
   921
}
dvander@1119
   922
dvander@518
   923
REGISTER_NATIVES(consoleNatives)
dvander@498
   924
{
dvander@498
   925
	{"CreateConVar",		sm_CreateConVar},
dvander@498
   926
	{"FindConVar",			sm_FindConVar},
dvander@498
   927
	{"HookConVarChange",	sm_HookConVarChange},
dvander@498
   928
	{"UnhookConVarChange",	sm_UnhookConVarChange},
dvander@498
   929
	{"GetConVarBool",		sm_GetConVarBool},
dvander@498
   930
	{"SetConVarBool",		sm_SetConVarNum},
dvander@498
   931
	{"GetConVarInt",		sm_GetConVarInt},
dvander@498
   932
	{"SetConVarInt",		sm_SetConVarNum},
dvander@498
   933
	{"GetConVarFloat",		sm_GetConVarFloat},
dvander@498
   934
	{"SetConVarFloat",		sm_SetConVarFloat},
dvander@498
   935
	{"GetConVarString",		sm_GetConVarString},
dvander@498
   936
	{"SetConVarString",		sm_SetConVarString},
dvander@498
   937
	{"GetConVarFlags",		sm_GetConVarFlags},
dvander@498
   938
	{"SetConVarFlags",		sm_SetConVarFlags},
dvander@498
   939
	{"GetConVarName",		sm_GetConVarName},
ds@714
   940
	{"GetConVarBounds",		sm_GetConVarBounds},
ds@714
   941
	{"SetConVarBounds",		sm_SetConVarBounds},
dvander@498
   942
	{"ResetConVar",			sm_ResetConVar},
ds@696
   943
	{"QueryClientConVar",	sm_QueryClientConVar},
dvander@498
   944
	{"RegServerCmd",		sm_RegServerCmd},
dvander@500
   945
	{"RegConsoleCmd",		sm_RegConsoleCmd},
dvander@517
   946
	{"GetCmdArgString",		sm_GetCmdArgString},
dvander@517
   947
	{"GetCmdArgs",			sm_GetCmdArgs},
dvander@517
   948
	{"GetCmdArg",			sm_GetCmdArg},
dvander@518
   949
	{"PrintToServer",		sm_PrintToServer},
dvander@518
   950
	{"PrintToConsole",		sm_PrintToConsole},
dvander@520
   951
	{"RegAdminCmd",			sm_RegAdminCmd},
dvander@522
   952
	{"ServerCommand",		sm_ServerCommand},
dvander@522
   953
	{"InsertServerCommand",	sm_InsertServerCommand},
dvander@522
   954
	{"ServerExecute",		sm_ServerExecute},
dvander@532
   955
	{"ClientCommand",		sm_ClientCommand},
dvander@893
   956
	{"FakeClientCommand",	FakeClientCommand},
dvander@893
   957
	{"ReplyToCommand",		ReplyToCommand},
dvander@923
   958
	{"GetCmdReplySource",	GetCmdReplyTarget},
dvander@1077
   959
	{"SetCmdReplySource",	SetCmdReplyTarget},
dvander@1119
   960
	{"GetCommandIterator",	GetCommandIterator},
dvander@1119
   961
	{"ReadCommandIterator",	ReadCommandIterator},
dvander@1119
   962
	{"CheckCommandAccess",	CheckCommandAccess},
dvander@498
   963
	{NULL,					NULL}
dvander@498
   964
};