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