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