core/smn_console.cpp
author David Anderson <dvander@alliedmods.net>
Sun Oct 21 17:58:35 2007 +0000 (2007-10-21)
changeset 1620 fd5c786ca8e5
parent 1582 6f18465dd9f9
child 1643 2ea224c9e9a1
permissions -rw-r--r--
atcprintf() is now fully re-entrant, meaning translations can be used from inside translations
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"
dvander@1429
    42
#include "AdminCache.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());
faluco@1541
   110
	if (IsFlagSet(pConVar, FCVAR_PROTECTED))
ds@936
   111
	{
ds@936
   112
		pEvent->SetString("cvarvalue", "***PROTECTED***");
dvander@1582
   113
	}
dvander@1582
   114
	else
dvander@1582
   115
	{
ds@936
   116
		pEvent->SetString("cvarvalue", pConVar->GetString());
ds@936
   117
	}
ds@936
   118
ds@936
   119
	gameevents->FireEvent(pEvent);
ds@936
   120
}
ds@936
   121
dvander@498
   122
static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
   123
{
dvander@498
   124
	char *name, *defaultVal, *helpText;
dvander@498
   125
dvander@498
   126
	pContext->LocalToString(params[1], &name);
dvander@498
   127
dvander@498
   128
	// While the engine seems to accept a blank convar name, it causes a crash upon server quit
dvander@498
   129
	if (name == NULL || strcmp(name, "") == 0)
dvander@498
   130
	{
ds@582
   131
		return pContext->ThrowNativeError("Convar with blank name is not permitted");
dvander@498
   132
	}
dvander@498
   133
dvander@498
   134
	pContext->LocalToString(params[2], &defaultVal);
dvander@498
   135
	pContext->LocalToString(params[3], &helpText);
dvander@498
   136
dvander@498
   137
	bool hasMin = params[5] ? true : false;
dvander@498
   138
	bool hasMax = params[7] ? true : false;
dvander@498
   139
	float min = sp_ctof(params[6]);
dvander@498
   140
	float max = sp_ctof(params[8]);
dvander@498
   141
ds@582
   142
	Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
ds@582
   143
ds@582
   144
	if (hndl == BAD_HANDLE)
ds@582
   145
	{
dvander@1582
   146
		return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same might already exist.", name);
ds@582
   147
	}
ds@582
   148
ds@582
   149
	return hndl;
dvander@498
   150
}
dvander@498
   151
dvander@498
   152
static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
   153
{
dvander@498
   154
	char *name;
dvander@498
   155
dvander@498
   156
	pContext->LocalToString(params[1], &name);
dvander@498
   157
dvander@498
   158
	return g_ConVarManager.FindConVar(name);
dvander@498
   159
}
dvander@498
   160
dvander@498
   161
static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498
   162
{
dvander@498
   163
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   164
	HandleError err;
ds@576
   165
	ConVar *pConVar;
dvander@498
   166
dvander@1582
   167
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   168
		!= HandleError_None)
dvander@498
   169
	{
ds@581
   170
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   171
	}
dvander@498
   172
ds@582
   173
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582
   174
ds@582
   175
	if (!pFunction)
ds@582
   176
	{
ds@582
   177
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582
   178
	}
ds@582
   179
ds@582
   180
	g_ConVarManager.HookConVarChange(pConVar, pFunction);
dvander@498
   181
dvander@498
   182
	return 1;
dvander@498
   183
}
dvander@498
   184
dvander@498
   185
static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498
   186
{
dvander@498
   187
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   188
	HandleError err;
ds@576
   189
	ConVar *pConVar;
dvander@498
   190
dvander@1582
   191
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   192
		!= HandleError_None)
dvander@498
   193
	{
ds@581
   194
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   195
	}
dvander@498
   196
ds@582
   197
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582
   198
ds@582
   199
	if (!pFunction)
ds@582
   200
	{
ds@582
   201
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582
   202
	}
ds@582
   203
ds@582
   204
	g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
dvander@498
   205
dvander@498
   206
	return 1;
dvander@498
   207
}
dvander@498
   208
dvander@498
   209
static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
dvander@498
   210
{
dvander@498
   211
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   212
	HandleError err;
ds@576
   213
	ConVar *pConVar;
dvander@498
   214
dvander@1582
   215
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   216
		!= HandleError_None)
dvander@498
   217
	{
ds@581
   218
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   219
	}
dvander@498
   220
ds@576
   221
	return pConVar->GetBool();
dvander@498
   222
}
dvander@498
   223
dvander@498
   224
static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
dvander@498
   225
{
dvander@498
   226
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   227
	HandleError err;
ds@576
   228
	ConVar *pConVar;
dvander@498
   229
dvander@1582
   230
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   231
		!= HandleError_None)
dvander@498
   232
	{
ds@581
   233
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   234
	}
dvander@498
   235
ds@576
   236
	return pConVar->GetInt();
dvander@498
   237
}
dvander@498
   238
dvander@498
   239
/* This handles both SetConVarBool() and SetConVarInt() */
dvander@498
   240
static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
dvander@498
   241
{
dvander@498
   242
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   243
	HandleError err;
ds@576
   244
	ConVar *pConVar;
dvander@498
   245
dvander@1582
   246
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   247
		!= HandleError_None)
dvander@498
   248
	{
ds@581
   249
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   250
	}
dvander@498
   251
ds@576
   252
	pConVar->SetValue(params[2]);
dvander@498
   253
ds@936
   254
	/* Should we replicate it? */
faluco@1541
   255
	if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@936
   256
	{
ds@936
   257
		ReplicateConVar(pConVar);
ds@936
   258
	}
ds@936
   259
ds@936
   260
	/* Should we notify clients? */
faluco@1541
   261
	if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@936
   262
	{
ds@936
   263
		NotifyConVar(pConVar);
ds@936
   264
	}
ds@936
   265
dvander@498
   266
	return 1;
dvander@498
   267
}
dvander@498
   268
dvander@498
   269
static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498
   270
{
dvander@498
   271
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   272
	HandleError err;
ds@576
   273
	ConVar *pConVar;
dvander@498
   274
dvander@1582
   275
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   276
		!= HandleError_None)
dvander@498
   277
	{
ds@581
   278
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   279
	}
dvander@498
   280
	
ds@576
   281
	float value = pConVar->GetFloat();
dvander@498
   282
dvander@498
   283
	return sp_ftoc(value);
dvander@498
   284
}
dvander@498
   285
dvander@498
   286
static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498
   287
{
dvander@498
   288
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   289
	HandleError err;
ds@576
   290
	ConVar *pConVar;
dvander@498
   291
dvander@1582
   292
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   293
		!= HandleError_None)
dvander@498
   294
	{
ds@581
   295
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   296
	}
dvander@498
   297
dvander@498
   298
	float value = sp_ctof(params[2]);
ds@576
   299
	pConVar->SetValue(value);
dvander@498
   300
ds@936
   301
	/* Should we replicate it? */
faluco@1541
   302
	if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@936
   303
	{
ds@936
   304
		ReplicateConVar(pConVar);
ds@936
   305
	}
ds@936
   306
ds@936
   307
	/* Should we notify clients? */
faluco@1541
   308
	if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@936
   309
	{
ds@936
   310
		NotifyConVar(pConVar);
ds@936
   311
	}
ds@936
   312
dvander@498
   313
	return 1;
dvander@498
   314
}
dvander@498
   315
dvander@498
   316
static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498
   317
{
dvander@498
   318
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   319
	HandleError err;
ds@576
   320
	ConVar *pConVar;
dvander@498
   321
dvander@1582
   322
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   323
		!= HandleError_None)
dvander@498
   324
	{
ds@581
   325
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   326
	}
dvander@498
   327
ds@576
   328
	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
dvander@498
   329
dvander@498
   330
	return 1;
dvander@498
   331
}
dvander@498
   332
dvander@498
   333
static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498
   334
{
dvander@498
   335
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   336
	HandleError err;
ds@576
   337
	ConVar *pConVar;
dvander@498
   338
dvander@1582
   339
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   340
		!= HandleError_None)
dvander@498
   341
	{
ds@581
   342
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   343
	}
dvander@498
   344
dvander@498
   345
	char *value;
dvander@498
   346
	pContext->LocalToString(params[2], &value);
dvander@498
   347
ds@576
   348
	pConVar->SetValue(value);
dvander@498
   349
ds@936
   350
	/* Should we replicate it? */
faluco@1541
   351
	if (params[3] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@936
   352
	{
ds@936
   353
		ReplicateConVar(pConVar);
ds@936
   354
	}
ds@936
   355
ds@936
   356
	/* Should we notify clients? */
faluco@1541
   357
	if (params[4] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@936
   358
	{
ds@936
   359
		NotifyConVar(pConVar);
ds@936
   360
	}
ds@936
   361
dvander@498
   362
	return 1;
dvander@498
   363
}
dvander@498
   364
ds@1301
   365
static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
ds@1301
   366
{
ds@1301
   367
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@1301
   368
	HandleError err;
ds@1301
   369
	ConVar *pConVar;
ds@1301
   370
dvander@1582
   371
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
ds@1301
   372
		!= HandleError_None)
ds@1301
   373
	{
ds@1301
   374
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
ds@1301
   375
	}
ds@1301
   376
ds@1301
   377
	pConVar->Revert();
ds@1301
   378
	
ds@1301
   379
	/* Should we replicate it? */
faluco@1541
   380
	if (params[2] && IsFlagSet(pConVar, FCVAR_REPLICATED))
ds@1301
   381
	{
ds@1301
   382
		ReplicateConVar(pConVar);
ds@1301
   383
	}
ds@1301
   384
ds@1301
   385
	/* Should we notify clients? */
faluco@1541
   386
	if (params[3] && IsFlagSet(pConVar, FCVAR_NOTIFY))
ds@1301
   387
	{
ds@1301
   388
		NotifyConVar(pConVar);
ds@1301
   389
	}
ds@1301
   390
ds@1301
   391
	return 1;
ds@1301
   392
}
ds@1301
   393
dvander@498
   394
static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498
   395
{
dvander@498
   396
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   397
	HandleError err;
ds@576
   398
	ConVar *pConVar;
dvander@498
   399
dvander@1582
   400
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   401
		!= HandleError_None)
dvander@498
   402
	{
ds@581
   403
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   404
	}
dvander@498
   405
ds@576
   406
	return pConVar->GetFlags();
dvander@498
   407
}
dvander@498
   408
dvander@498
   409
static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498
   410
{
dvander@498
   411
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   412
	HandleError err;
ds@576
   413
	ConVar *pConVar;
dvander@498
   414
dvander@1582
   415
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   416
		!= HandleError_None)
dvander@498
   417
	{
ds@581
   418
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   419
	}
dvander@498
   420
ds@576
   421
	pConVar->SetFlags(params[2]);
dvander@498
   422
dvander@498
   423
	return 1;
dvander@498
   424
}
dvander@498
   425
ds@714
   426
static cell_t sm_GetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498
   427
{
dvander@498
   428
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   429
	HandleError err;
ds@576
   430
	ConVar *pConVar;
dvander@498
   431
dvander@1582
   432
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   433
		!= HandleError_None)
dvander@498
   434
	{
ds@581
   435
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   436
	}
dvander@498
   437
dvander@498
   438
	cell_t *addr;
ds@714
   439
	bool hasBound;
ds@714
   440
	float bound;
dvander@498
   441
ds@714
   442
	switch (params[2])
ds@714
   443
	{
ds@714
   444
	case ConVarBound_Upper:
ds@714
   445
		hasBound = pConVar->GetMax(bound);
ds@714
   446
		break;
ds@714
   447
	case ConVarBound_Lower:
ds@714
   448
		hasBound = pConVar->GetMin(bound);
ds@714
   449
		break;
ds@714
   450
	default:
ds@714
   451
		return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714
   452
	}
ds@714
   453
	
ds@714
   454
	pContext->LocalToPhysAddr(params[3], &addr);
ds@714
   455
	*addr = sp_ftoc(bound);
dvander@498
   456
ds@714
   457
	return hasBound;
dvander@498
   458
}
dvander@498
   459
ds@714
   460
static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498
   461
{
dvander@498
   462
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   463
	HandleError err;
ds@576
   464
	ConVar *pConVar;
dvander@498
   465
dvander@1582
   466
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   467
		!= HandleError_None)
dvander@498
   468
	{
ds@581
   469
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   470
	}
dvander@498
   471
ds@714
   472
	switch (params[2])
ds@714
   473
	{
ds@714
   474
	case ConVarBound_Upper:
ds@714
   475
		pConVar->SetMax(params[3] ? true : false, sp_ctof(params[4]));
ds@714
   476
		break;
ds@714
   477
	case ConVarBound_Lower:
ds@714
   478
		pConVar->SetMin(params[3] ? true : false, sp_ctof(params[4]));
ds@714
   479
		break;
ds@714
   480
	default:
ds@714
   481
		return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714
   482
	}
dvander@498
   483
ds@714
   484
	return 1;
dvander@498
   485
}
dvander@498
   486
dvander@498
   487
static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
dvander@498
   488
{
dvander@498
   489
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   490
	HandleError err;
ds@576
   491
	ConVar *pConVar;
dvander@498
   492
dvander@1582
   493
	if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
dvander@498
   494
		!= HandleError_None)
dvander@498
   495
	{
ds@581
   496
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   497
	}
dvander@498
   498
ds@576
   499
	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
dvander@498
   500
dvander@498
   501
	return 1;
dvander@498
   502
}
dvander@498
   503
ds@696
   504
static bool s_QueryAlreadyWarned = false;
ds@696
   505
ds@696
   506
static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *params)
ds@696
   507
{
ds@696
   508
	CPlayer *pPlayer;
ds@696
   509
	char *name;
ds@696
   510
	IPluginFunction *pCallback;
ds@696
   511
dvander@1581
   512
	if (!g_ConVarManager.IsQueryingSupported())
ds@696
   513
	{
ds@696
   514
		if (!s_QueryAlreadyWarned)
ds@696
   515
		{
ds@696
   516
			s_QueryAlreadyWarned = true;
ds@696
   517
			return pContext->ThrowNativeError("Game does not support client convar querying (one time warning)");
ds@696
   518
		}
ds@696
   519
ds@696
   520
		return 0;
ds@696
   521
	}
ds@696
   522
ds@696
   523
	pPlayer = g_Players.GetPlayerByIndex(params[1]);
ds@696
   524
ds@696
   525
	if (!pPlayer)
ds@696
   526
	{
ds@994
   527
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
ds@696
   528
	}
ds@696
   529
ds@697
   530
	if (!pPlayer->IsConnected())
ds@696
   531
	{
ds@994
   532
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
ds@697
   533
	}
ds@697
   534
ds@697
   535
	/* Trying a query on a bot results in callback not be fired, so don't bother */
ds@697
   536
	if (pPlayer->IsFakeClient())
ds@697
   537
	{
ds@697
   538
		return 0;
ds@696
   539
	}
ds@696
   540
ds@696
   541
	pContext->LocalToString(params[2], &name);
ds@696
   542
	pCallback = pContext->GetFunctionById(params[3]);
ds@696
   543
ds@696
   544
	if (!pCallback)
ds@696
   545
	{
ds@696
   546
		return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
ds@696
   547
	}
ds@696
   548
ds@696
   549
	return g_ConVarManager.QueryClientConVar(pPlayer->GetEdict(), name, pCallback, params[4]);
ds@696
   550
}
ds@696
   551
dvander@498
   552
static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
dvander@498
   553
{
dvander@498
   554
	char *name,*help;
dvander@498
   555
	IPluginFunction *pFunction;
dvander@498
   556
dvander@498
   557
	pContext->LocalToString(params[1], &name);
dvander@498
   558
	pContext->LocalToString(params[3], &help);
dvander@498
   559
	pFunction = pContext->GetFunctionById(params[2]);
dvander@498
   560
dvander@498
   561
	if (!pFunction)
dvander@498
   562
	{
dvander@498
   563
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@498
   564
	}
dvander@498
   565
ds@579
   566
	if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
ds@579
   567
	{
ds@579
   568
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   569
	}
dvander@498
   570
dvander@498
   571
	return 1;
dvander@498
   572
}
dvander@498
   573
dvander@500
   574
static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
dvander@500
   575
{
dvander@500
   576
	char *name,*help;
dvander@500
   577
	IPluginFunction *pFunction;
dvander@500
   578
dvander@500
   579
	pContext->LocalToString(params[1], &name);
dvander@500
   580
	pContext->LocalToString(params[3], &help);
dvander@500
   581
	pFunction = pContext->GetFunctionById(params[2]);
dvander@500
   582
dvander@500
   583
	if (!pFunction)
dvander@500
   584
	{
dvander@500
   585
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@500
   586
	}
dvander@500
   587
ds@579
   588
	if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
ds@579
   589
	{
ds@579
   590
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   591
	}
dvander@500
   592
dvander@500
   593
	return 1;
dvander@500
   594
}
dvander@500
   595
dvander@514
   596
static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
dvander@514
   597
{
dvander@514
   598
	char *name,*help;
dvander@514
   599
	const char *group;
dvander@514
   600
	IPluginFunction *pFunction;
dvander@514
   601
	FlagBits flags = params[3];
dvander@514
   602
	int cmdflags = params[6];
dvander@514
   603
dvander@514
   604
	pContext->LocalToString(params[1], &name);
dvander@514
   605
	pContext->LocalToString(params[4], &help);
dvander@514
   606
	pContext->LocalToString(params[5], (char **)&group);
dvander@514
   607
	pFunction = pContext->GetFunctionById(params[2]);
dvander@514
   608
dvander@514
   609
	if (group[0] == '\0')
dvander@514
   610
	{
dvander@514
   611
		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@514
   612
		group = pPlugin->GetFilename();
dvander@514
   613
	}
dvander@514
   614
dvander@514
   615
	if (!pFunction)
dvander@514
   616
	{
dvander@514
   617
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@514
   618
	}
dvander@514
   619
ds@579
   620
	if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
ds@579
   621
	{
ds@579
   622
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   623
	}
dvander@514
   624
dvander@514
   625
	return 1;
dvander@514
   626
}
dvander@514
   627
dvander@517
   628
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
dvander@517
   629
{
dvander@1544
   630
	const CCommand *pCmd = g_HL2.PeekCommandStack();
dvander@1544
   631
dvander@1544
   632
	if (!pCmd)
dvander@1544
   633
	{
dvander@1544
   634
		return pContext->ThrowNativeError("No command callback available");
dvander@1544
   635
	}
dvander@1544
   636
dvander@1544
   637
	return pCmd->ArgC() - 1;
dvander@517
   638
}
dvander@517
   639
dvander@517
   640
static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
dvander@517
   641
{
dvander@1544
   642
	const CCommand *pCmd = g_HL2.PeekCommandStack();
dvander@1544
   643
dvander@1544
   644
	if (!pCmd)
dvander@1544
   645
	{
dvander@1544
   646
		return pContext->ThrowNativeError("No command callback available");
dvander@1544
   647
	}
dvander@1544
   648
dvander@1421
   649
	size_t length;
dvander@1544
   650
dvander@1544
   651
	const char *arg = pCmd->Arg(params[1]);
dvander@517
   652
	
dvander@1544
   653
	pContext->StringToLocalUTF8(params[2], params[3], arg ? arg : "", &length);
dvander@517
   654
dvander@1421
   655
	return (cell_t)length;
dvander@517
   656
}
dvander@517
   657
dvander@517
   658
static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
dvander@517
   659
{
dvander@1544
   660
	const CCommand *pCmd = g_HL2.PeekCommandStack();
dvander@1544
   661
dvander@1544
   662
	if (!pCmd)
dvander@1544
   663
	{
dvander@1544
   664
		return pContext->ThrowNativeError("No command callback available");
dvander@1544
   665
	}
dvander@1544
   666
dvander@1544
   667
	const char *args = pCmd->ArgS();
dvander@1421
   668
	size_t length;
dvander@517
   669
dvander@633
   670
	if (!args)
dvander@633
   671
	{
dvander@633
   672
		args = "";
dvander@633
   673
	}
dvander@633
   674
dvander@1421
   675
	pContext->StringToLocalUTF8(params[1], params[2], args, &length);
dvander@517
   676
dvander@1421
   677
	return (cell_t)length;
dvander@517
   678
}
dvander@517
   679
dvander@518
   680
static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
dvander@518
   681
{
dvander@518
   682
	char buffer[1024];
dvander@518
   683
	char *fmt;
dvander@518
   684
	int arg = 2;
dvander@518
   685
dvander@518
   686
	pCtx->LocalToString(params[1], &fmt);
dvander@518
   687
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518
   688
dvander@518
   689
	buffer[res++] = '\n';
dvander@518
   690
	buffer[res] = '\0';
dvander@518
   691
dvander@518
   692
	META_CONPRINT(buffer);
dvander@518
   693
dvander@518
   694
	return 1;
dvander@518
   695
}
dvander@518
   696
dvander@518
   697
static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
dvander@518
   698
{
dvander@518
   699
	int index = params[1];
dvander@520
   700
	if ((index < 0) || (index > g_Players.GetMaxClients()))
dvander@518
   701
	{
ds@994
   702
		return pCtx->ThrowNativeError("Client index %d is invalid", index);
dvander@518
   703
	}
dvander@518
   704
dvander@520
   705
	CPlayer *pPlayer = NULL;
dvander@520
   706
	if (index != 0)
dvander@518
   707
	{
dvander@520
   708
		pPlayer = g_Players.GetPlayerByIndex(index);
dvander@520
   709
		if (!pPlayer->IsInGame())
dvander@520
   710
		{
dvander@520
   711
			return pCtx->ThrowNativeError("Client %d is not in game", index);
dvander@520
   712
		}
dvander@520
   713
		
dvander@520
   714
		/* Silent fail on bots, engine will crash */
dvander@520
   715
		if (pPlayer->IsFakeClient())
dvander@520
   716
		{
dvander@520
   717
			return 0;
dvander@520
   718
		}
dvander@519
   719
	}
dvander@518
   720
dvander@518
   721
	char buffer[1024];
dvander@518
   722
	char *fmt;
dvander@518
   723
	int arg = 3;
dvander@518
   724
dvander@518
   725
	pCtx->LocalToString(params[2], &fmt);
dvander@518
   726
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518
   727
dvander@518
   728
	buffer[res++] = '\n';
dvander@518
   729
	buffer[res] = '\0';
dvander@518
   730
dvander@520
   731
	if (index != 0)
dvander@520
   732
	{
dvander@520
   733
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@520
   734
	} else {
dvander@520
   735
		META_CONPRINT(buffer);
dvander@520
   736
	}
dvander@518
   737
dvander@518
   738
	return 1;
dvander@518
   739
}
dvander@518
   740
dvander@522
   741
static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522
   742
{
dvander@1273
   743
	g_SourceMod.SetGlobalTarget(LANG_SERVER);
dvander@1273
   744
dvander@522
   745
	char buffer[1024];
dvander@522
   746
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522
   747
dvander@1273
   748
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1273
   749
	{
dvander@1273
   750
		return 0;
dvander@1273
   751
	}
dvander@1011
   752
dvander@522
   753
	/* One byte for null terminator, one for newline */
dvander@522
   754
	buffer[len++] = '\n';
dvander@522
   755
	buffer[len] = '\0';
dvander@522
   756
dvander@522
   757
	engine->ServerCommand(buffer);
dvander@522
   758
dvander@522
   759
	return 1;
dvander@522
   760
}
dvander@522
   761
dvander@522
   762
static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522
   763
{
dvander@1273
   764
	g_SourceMod.SetGlobalTarget(LANG_SERVER);
dvander@1273
   765
dvander@522
   766
	char buffer[1024];
dvander@522
   767
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522
   768
dvander@1273
   769
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1273
   770
	{
dvander@1273
   771
		return 0;
dvander@1273
   772
	}
dvander@1011
   773
dvander@522
   774
	/* One byte for null terminator, one for newline */
dvander@522
   775
	buffer[len++] = '\n';
dvander@522
   776
	buffer[len] = '\0';
dvander@522
   777
faluco@1541
   778
	InsertServerCommand(buffer);
dvander@522
   779
dvander@522
   780
	return 1;
dvander@522
   781
}
dvander@522
   782
dvander@522
   783
static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
dvander@522
   784
{
dvander@522
   785
	engine->ServerExecute();
dvander@522
   786
dvander@522
   787
	return 1;
dvander@522
   788
}
dvander@522
   789
dvander@532
   790
static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@532
   791
{
dvander@532
   792
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@532
   793
dvander@532
   794
	if (!pPlayer)
dvander@532
   795
	{
ds@994
   796
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@532
   797
	}
dvander@532
   798
dvander@532
   799
	if (!pPlayer->IsConnected())
dvander@532
   800
	{
ds@994
   801
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@532
   802
	}
dvander@532
   803
dvander@1011
   804
	g_SourceMod.SetGlobalTarget(params[1]);
dvander@1011
   805
dvander@532
   806
	char buffer[256];
ds@873
   807
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@532
   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@532
   814
	engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
dvander@532
   815
dvander@532
   816
	return 1;
dvander@532
   817
}
dvander@532
   818
dvander@893
   819
static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@893
   820
{
dvander@893
   821
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893
   822
dvander@893
   823
	if (!pPlayer)
dvander@893
   824
	{
ds@994
   825
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893
   826
	}
dvander@893
   827
dvander@893
   828
	if (!pPlayer->IsConnected())
dvander@893
   829
	{
ds@994
   830
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893
   831
	}
dvander@893
   832
dvander@893
   833
	char buffer[256];
dvander@893
   834
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@893
   835
dvander@1273
   836
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1273
   837
	{
dvander@1273
   838
		return 0;
dvander@1273
   839
	}
dvander@1273
   840
dvander@893
   841
	serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), buffer);
dvander@1337
   842
dvander@1337
   843
	return 1;
dvander@1337
   844
}
dvander@1337
   845
dvander@1337
   846
static cell_t FakeClientCommandEx(IPluginContext *pContext, const cell_t *params)
dvander@1337
   847
{
dvander@1337
   848
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@1337
   849
dvander@1337
   850
	if (!pPlayer)
dvander@1337
   851
	{
dvander@1337
   852
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@1337
   853
	}
dvander@1337
   854
dvander@1337
   855
	if (!pPlayer->IsConnected())
dvander@1337
   856
	{
dvander@1337
   857
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@1337
   858
	}
dvander@1337
   859
dvander@1337
   860
	char buffer[256];
dvander@1337
   861
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@1337
   862
dvander@1337
   863
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1337
   864
	{
dvander@1337
   865
		return 0;
dvander@1337
   866
	}
dvander@1337
   867
dvander@1338
   868
	g_HL2.AddToFakeCliCmdQueue(params[1], engine->GetPlayerUserId(pPlayer->GetEdict()), buffer);
dvander@893
   869
dvander@893
   870
	return 1;
dvander@893
   871
}
dvander@893
   872
dvander@893
   873
static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
dvander@893
   874
{
dvander@1011
   875
	g_SourceMod.SetGlobalTarget(params[1]);
dvander@1011
   876
dvander@893
   877
	/* Build the format string */
dvander@893
   878
	char buffer[1024];
dvander@893
   879
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 2);
dvander@893
   880
dvander@1273
   881
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1273
   882
	{
dvander@1273
   883
		return 0;
dvander@1273
   884
	}
dvander@1273
   885
dvander@893
   886
	/* If we're printing to the server, shortcut out */
dvander@893
   887
	if (params[1] == 0)
dvander@893
   888
	{
dvander@893
   889
		/* Print */
dvander@893
   890
		buffer[len++] = '\n';
dvander@893
   891
		buffer[len] = '\0';
dvander@893
   892
		META_CONPRINT(buffer);
dvander@893
   893
		return 1;
dvander@893
   894
	}
dvander@893
   895
dvander@893
   896
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893
   897
dvander@893
   898
	if (!pPlayer)
dvander@893
   899
	{
dvander@893
   900
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893
   901
	}
dvander@893
   902
dvander@893
   903
	if (!pPlayer->IsConnected())
dvander@893
   904
	{
dvander@893
   905
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893
   906
	}
dvander@893
   907
dvander@910
   908
	g_SourceMod.SetGlobalTarget(params[1]);
dvander@910
   909
dvander@893
   910
	unsigned int replyto = g_ChatTriggers.GetReplyTo();
dvander@893
   911
	if (replyto == SM_REPLY_CONSOLE)
dvander@893
   912
	{
dvander@893
   913
		buffer[len++] = '\n';
dvander@893
   914
		buffer[len] = '\0';
dvander@893
   915
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@893
   916
	} else if (replyto == SM_REPLY_CHAT) {
dvander@893
   917
		if (len >= 191)
dvander@893
   918
		{
dvander@893
   919
			len = 191;
dvander@893
   920
		}
dvander@893
   921
		buffer[len] = '\0';
dvander@893
   922
		g_HL2.TextMsg(params[1], HUD_PRINTTALK, buffer);
dvander@893
   923
	}
dvander@893
   924
dvander@893
   925
	return 1;
dvander@893
   926
}
dvander@893
   927
dvander@923
   928
static cell_t GetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
dvander@923
   929
{
dvander@923
   930
	return g_ChatTriggers.GetReplyTo();
dvander@923
   931
}
dvander@923
   932
dvander@1071
   933
static cell_t SetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
dvander@1071
   934
{
dvander@1071
   935
	return g_ChatTriggers.SetReplyTo(params[1]);
dvander@1071
   936
}
dvander@1071
   937
dvander@1119
   938
static cell_t GetCommandIterator(IPluginContext *pContext, const cell_t *params)
dvander@1119
   939
{
dvander@1119
   940
	GlobCmdIter *iter = new GlobCmdIter;
dvander@1119
   941
	iter->started = false;
dvander@1119
   942
dvander@1119
   943
	Handle_t hndl = g_HandleSys.CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
dvander@1119
   944
	if (hndl == BAD_HANDLE)
dvander@1119
   945
	{
dvander@1119
   946
		delete iter;
dvander@1119
   947
	}
dvander@1119
   948
dvander@1119
   949
	return hndl;
dvander@1119
   950
}
dvander@1119
   951
dvander@1119
   952
static cell_t ReadCommandIterator(IPluginContext *pContext, const cell_t *params)
dvander@1119
   953
{
dvander@1119
   954
	GlobCmdIter *iter;
dvander@1119
   955
	HandleError err;
dvander@1119
   956
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1119
   957
dvander@1119
   958
	if ((err = g_HandleSys.ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
dvander@1119
   959
		!= HandleError_None)
dvander@1119
   960
	{
dvander@1119
   961
		return pContext->ThrowNativeError("Invalid GlobCmdIter Handle %x", params[1]);
dvander@1119
   962
	}
dvander@1119
   963
dvander@1119
   964
	const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
dvander@1119
   965
dvander@1119
   966
	if (!iter->started)
dvander@1119
   967
	{
dvander@1119
   968
		iter->iter = cmds.begin();
dvander@1119
   969
		iter->started = true;
dvander@1119
   970
	}
dvander@1119
   971
dvander@1119
   972
	while (iter->iter != cmds.end()
dvander@1119
   973
			&& !(*(iter->iter))->sourceMod)
dvander@1119
   974
	{
dvander@1119
   975
		iter->iter++;
dvander@1119
   976
	}
dvander@1119
   977
dvander@1119
   978
	if (iter->iter == cmds.end())
dvander@1119
   979
	{
dvander@1119
   980
		return 0;
dvander@1119
   981
	}
dvander@1119
   982
dvander@1119
   983
	ConCmdInfo *pInfo = (*(iter->iter));
dvander@1119
   984
dvander@1119
   985
	pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
dvander@1119
   986
	pContext->StringToLocalUTF8(params[5], params[6], pInfo->pCmd->GetHelpText(), NULL);
dvander@1119
   987
	
dvander@1119
   988
	cell_t *addr;
dvander@1119
   989
	pContext->LocalToPhysAddr(params[4], &addr);
dvander@1119
   990
	*addr = pInfo->admin.eflags;
dvander@1119
   991
dvander@1119
   992
	iter->iter++;
dvander@1119
   993
dvander@1119
   994
	return 1;
dvander@1119
   995
}
dvander@1119
   996
dvander@1119
   997
static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params)
dvander@1119
   998
{
dvander@1119
   999
	if (params[1] == 0)
dvander@1119
  1000
	{
dvander@1119
  1001
		return 1;
dvander@1119
  1002
	}
dvander@1119
  1003
dvander@1119
  1004
	char *cmd;
dvander@1119
  1005
	pContext->LocalToString(params[2], &cmd);
dvander@1119
  1006
dvander@1429
  1007
	/* Auto-detect a command if we can */
dvander@1399
  1008
	FlagBits bits = params[3];
dvander@1429
  1009
	bool found_command = false;
dvander@1429
  1010
	if (params[0] < 4 || !params[4])
dvander@1399
  1011
	{
dvander@1429
  1012
		found_command = g_ConCmds.LookForCommandAdminFlags(cmd, &bits);
dvander@1429
  1013
	}
dvander@1429
  1014
	
dvander@1429
  1015
	if (!found_command)
dvander@1429
  1016
	{
dvander@1429
  1017
		g_Admins.GetCommandOverride(cmd, Override_Command, &bits);
dvander@1399
  1018
	}
dvander@1399
  1019
dvander@1399
  1020
	return g_ConCmds.CheckCommandAccess(params[1], cmd, bits) ? 1 : 0;
dvander@1119
  1021
}
dvander@1119
  1022
dvander@1469
  1023
static cell_t IsChatTrigger(IPluginContext *pContext, const cell_t *params)
dvander@1469
  1024
{
dvander@1469
  1025
	return g_ChatTriggers.IsChatTrigger() ? 1 : 0;
dvander@1469
  1026
}
dvander@1469
  1027
dvander@518
  1028
REGISTER_NATIVES(consoleNatives)
dvander@498
  1029
{
dvander@498
  1030
	{"CreateConVar",		sm_CreateConVar},
dvander@498
  1031
	{"FindConVar",			sm_FindConVar},
dvander@498
  1032
	{"HookConVarChange",	sm_HookConVarChange},
dvander@498
  1033
	{"UnhookConVarChange",	sm_UnhookConVarChange},
dvander@498
  1034
	{"GetConVarBool",		sm_GetConVarBool},
dvander@498
  1035
	{"SetConVarBool",		sm_SetConVarNum},
dvander@498
  1036
	{"GetConVarInt",		sm_GetConVarInt},
dvander@498
  1037
	{"SetConVarInt",		sm_SetConVarNum},
dvander@498
  1038
	{"GetConVarFloat",		sm_GetConVarFloat},
dvander@498
  1039
	{"SetConVarFloat",		sm_SetConVarFloat},
dvander@498
  1040
	{"GetConVarString",		sm_GetConVarString},
dvander@498
  1041
	{"SetConVarString",		sm_SetConVarString},
dvander@498
  1042
	{"GetConVarFlags",		sm_GetConVarFlags},
dvander@498
  1043
	{"SetConVarFlags",		sm_SetConVarFlags},
ds@1301
  1044
	{"ResetConVar",			sm_ResetConVar},
dvander@498
  1045
	{"GetConVarName",		sm_GetConVarName},
ds@714
  1046
	{"GetConVarBounds",		sm_GetConVarBounds},
ds@714
  1047
	{"SetConVarBounds",		sm_SetConVarBounds},
ds@696
  1048
	{"QueryClientConVar",	sm_QueryClientConVar},
dvander@498
  1049
	{"RegServerCmd",		sm_RegServerCmd},
dvander@500
  1050
	{"RegConsoleCmd",		sm_RegConsoleCmd},
dvander@517
  1051
	{"GetCmdArgString",		sm_GetCmdArgString},
dvander@517
  1052
	{"GetCmdArgs",			sm_GetCmdArgs},
dvander@517
  1053
	{"GetCmdArg",			sm_GetCmdArg},
dvander@518
  1054
	{"PrintToServer",		sm_PrintToServer},
dvander@518
  1055
	{"PrintToConsole",		sm_PrintToConsole},
dvander@520
  1056
	{"RegAdminCmd",			sm_RegAdminCmd},
dvander@522
  1057
	{"ServerCommand",		sm_ServerCommand},
dvander@522
  1058
	{"InsertServerCommand",	sm_InsertServerCommand},
dvander@522
  1059
	{"ServerExecute",		sm_ServerExecute},
dvander@532
  1060
	{"ClientCommand",		sm_ClientCommand},
dvander@893
  1061
	{"FakeClientCommand",	FakeClientCommand},
dvander@893
  1062
	{"ReplyToCommand",		ReplyToCommand},
dvander@923
  1063
	{"GetCmdReplySource",	GetCmdReplyTarget},
dvander@1077
  1064
	{"SetCmdReplySource",	SetCmdReplyTarget},
dvander@1119
  1065
	{"GetCommandIterator",	GetCommandIterator},
dvander@1119
  1066
	{"ReadCommandIterator",	ReadCommandIterator},
dvander@1119
  1067
	{"CheckCommandAccess",	CheckCommandAccess},
dvander@1338
  1068
	{"FakeClientCommandEx",	FakeClientCommandEx},
dvander@1469
  1069
	{"IsChatTrigger",		IsChatTrigger},
dvander@498
  1070
	{NULL,					NULL}
dvander@498
  1071
};