core/smn_console.cpp
author David Anderson <dvander@alliedmods.net>
Wed Jun 06 22:31:54 2007 +0000 (2007-06-06)
changeset 896 e30eef2642ba
parent 895 a1068846fee8
child 910 153c052460af
permissions -rw-r--r--
added config options for chat triggers
dvander@498
     1
/**
ds@653
     2
 * vim: set ts=4 :
dvander@562
     3
 * ===============================================================
dvander@562
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@562
     5
 * ===============================================================
dvander@562
     6
 *
dvander@562
     7
 * This file is not open source and may not be copied without explicit
dvander@562
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@562
     9
 * in whole or significant part.
dvander@562
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@562
    11
 *
dvander@562
    12
 * Version: $Id$
dvander@562
    13
 */
dvander@498
    14
dvander@498
    15
#include "sm_globals.h"
ds@696
    16
#include "HalfLife2.h"
dvander@498
    17
#include "sourcemm_api.h"
dvander@498
    18
#include "HandleSys.h"
ds@580
    19
#include "ConVarManager.h"
ds@579
    20
#include "ConCmdManager.h"
dvander@514
    21
#include "PluginSys.h"
dvander@518
    22
#include "sm_stringutil.h"
dvander@591
    23
#include "PlayerManager.h"
dvander@893
    24
#include "ChatTriggers.h"
dvander@498
    25
ds@714
    26
enum ConVarBounds
ds@714
    27
{
ds@714
    28
	ConVarBound_Upper = 0,
ds@714
    29
	ConVarBound_Lower
ds@714
    30
};
ds@714
    31
dvander@498
    32
static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
    33
{
dvander@498
    34
	char *name, *defaultVal, *helpText;
dvander@498
    35
dvander@498
    36
	pContext->LocalToString(params[1], &name);
dvander@498
    37
dvander@498
    38
	// While the engine seems to accept a blank convar name, it causes a crash upon server quit
dvander@498
    39
	if (name == NULL || strcmp(name, "") == 0)
dvander@498
    40
	{
ds@582
    41
		return pContext->ThrowNativeError("Convar with blank name is not permitted");
dvander@498
    42
	}
dvander@498
    43
dvander@498
    44
	pContext->LocalToString(params[2], &defaultVal);
dvander@498
    45
	pContext->LocalToString(params[3], &helpText);
dvander@498
    46
dvander@498
    47
	bool hasMin = params[5] ? true : false;
dvander@498
    48
	bool hasMax = params[7] ? true : false;
dvander@498
    49
	float min = sp_ctof(params[6]);
dvander@498
    50
	float max = sp_ctof(params[8]);
dvander@498
    51
ds@582
    52
	Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
ds@582
    53
ds@582
    54
	if (hndl == BAD_HANDLE)
ds@582
    55
	{
ds@582
    56
		return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same name already exists.", name);
ds@582
    57
	}
ds@582
    58
ds@582
    59
	return hndl;
dvander@498
    60
}
dvander@498
    61
dvander@498
    62
static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
    63
{
dvander@498
    64
	char *name;
dvander@498
    65
dvander@498
    66
	pContext->LocalToString(params[1], &name);
dvander@498
    67
dvander@498
    68
	return g_ConVarManager.FindConVar(name);
dvander@498
    69
}
dvander@498
    70
dvander@498
    71
static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498
    72
{
dvander@498
    73
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
    74
	HandleError err;
ds@576
    75
	ConVar *pConVar;
dvander@498
    76
ds@576
    77
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
    78
		!= HandleError_None)
dvander@498
    79
	{
ds@581
    80
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
    81
	}
dvander@498
    82
ds@582
    83
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582
    84
ds@582
    85
	if (!pFunction)
ds@582
    86
	{
ds@582
    87
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582
    88
	}
ds@582
    89
ds@582
    90
	g_ConVarManager.HookConVarChange(pConVar, pFunction);
dvander@498
    91
dvander@498
    92
	return 1;
dvander@498
    93
}
dvander@498
    94
dvander@498
    95
static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *params)
dvander@498
    96
{
dvander@498
    97
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
    98
	HandleError err;
ds@576
    99
	ConVar *pConVar;
dvander@498
   100
ds@576
   101
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   102
		!= HandleError_None)
dvander@498
   103
	{
ds@581
   104
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   105
	}
dvander@498
   106
ds@582
   107
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
ds@582
   108
ds@582
   109
	if (!pFunction)
ds@582
   110
	{
ds@582
   111
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@582
   112
	}
ds@582
   113
ds@582
   114
	g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
dvander@498
   115
dvander@498
   116
	return 1;
dvander@498
   117
}
dvander@498
   118
dvander@498
   119
static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
dvander@498
   120
{
dvander@498
   121
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   122
	HandleError err;
ds@576
   123
	ConVar *pConVar;
dvander@498
   124
ds@576
   125
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   126
		!= HandleError_None)
dvander@498
   127
	{
ds@581
   128
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   129
	}
dvander@498
   130
ds@576
   131
	return pConVar->GetBool();
dvander@498
   132
}
dvander@498
   133
dvander@498
   134
static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
dvander@498
   135
{
dvander@498
   136
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   137
	HandleError err;
ds@576
   138
	ConVar *pConVar;
dvander@498
   139
ds@576
   140
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   141
		!= HandleError_None)
dvander@498
   142
	{
ds@581
   143
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   144
	}
dvander@498
   145
ds@576
   146
	return pConVar->GetInt();
dvander@498
   147
}
dvander@498
   148
dvander@498
   149
/* This handles both SetConVarBool() and SetConVarInt() */
dvander@498
   150
static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
dvander@498
   151
{
dvander@498
   152
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   153
	HandleError err;
ds@576
   154
	ConVar *pConVar;
dvander@498
   155
ds@576
   156
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   157
		!= HandleError_None)
dvander@498
   158
	{
ds@581
   159
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   160
	}
dvander@498
   161
ds@576
   162
	pConVar->SetValue(params[2]);
dvander@498
   163
dvander@498
   164
	return 1;
dvander@498
   165
}
dvander@498
   166
dvander@498
   167
static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498
   168
{
dvander@498
   169
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   170
	HandleError err;
ds@576
   171
	ConVar *pConVar;
dvander@498
   172
ds@576
   173
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   174
		!= HandleError_None)
dvander@498
   175
	{
ds@581
   176
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   177
	}
dvander@498
   178
	
ds@576
   179
	float value = pConVar->GetFloat();
dvander@498
   180
dvander@498
   181
	return sp_ftoc(value);
dvander@498
   182
}
dvander@498
   183
dvander@498
   184
static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
dvander@498
   185
{
dvander@498
   186
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   187
	HandleError err;
ds@576
   188
	ConVar *pConVar;
dvander@498
   189
ds@576
   190
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   191
		!= HandleError_None)
dvander@498
   192
	{
ds@581
   193
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   194
	}
dvander@498
   195
dvander@498
   196
	float value = sp_ctof(params[2]);
ds@576
   197
	pConVar->SetValue(value);
dvander@498
   198
dvander@498
   199
	return 1;
dvander@498
   200
}
dvander@498
   201
dvander@498
   202
static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498
   203
{
dvander@498
   204
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   205
	HandleError err;
ds@576
   206
	ConVar *pConVar;
dvander@498
   207
ds@576
   208
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   209
		!= HandleError_None)
dvander@498
   210
	{
ds@581
   211
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   212
	}
dvander@498
   213
ds@576
   214
	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
dvander@498
   215
dvander@498
   216
	return 1;
dvander@498
   217
}
dvander@498
   218
dvander@498
   219
static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
dvander@498
   220
{
dvander@498
   221
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   222
	HandleError err;
ds@576
   223
	ConVar *pConVar;
dvander@498
   224
ds@576
   225
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   226
		!= HandleError_None)
dvander@498
   227
	{
ds@581
   228
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   229
	}
dvander@498
   230
dvander@498
   231
	char *value;
dvander@498
   232
	pContext->LocalToString(params[2], &value);
dvander@498
   233
ds@576
   234
	pConVar->SetValue(value);
dvander@498
   235
dvander@498
   236
	return 1;
dvander@498
   237
}
dvander@498
   238
dvander@498
   239
static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498
   240
{
dvander@498
   241
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   242
	HandleError err;
ds@576
   243
	ConVar *pConVar;
dvander@498
   244
ds@576
   245
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   246
		!= HandleError_None)
dvander@498
   247
	{
ds@581
   248
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   249
	}
dvander@498
   250
ds@576
   251
	return pConVar->GetFlags();
dvander@498
   252
}
dvander@498
   253
dvander@498
   254
static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
dvander@498
   255
{
dvander@498
   256
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   257
	HandleError err;
ds@576
   258
	ConVar *pConVar;
dvander@498
   259
ds@576
   260
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   261
		!= HandleError_None)
dvander@498
   262
	{
ds@581
   263
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   264
	}
dvander@498
   265
ds@576
   266
	pConVar->SetFlags(params[2]);
dvander@498
   267
dvander@498
   268
	return 1;
dvander@498
   269
}
dvander@498
   270
ds@714
   271
static cell_t sm_GetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498
   272
{
dvander@498
   273
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   274
	HandleError err;
ds@576
   275
	ConVar *pConVar;
dvander@498
   276
ds@576
   277
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   278
		!= HandleError_None)
dvander@498
   279
	{
ds@581
   280
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   281
	}
dvander@498
   282
dvander@498
   283
	cell_t *addr;
ds@714
   284
	bool hasBound;
ds@714
   285
	float bound;
dvander@498
   286
ds@714
   287
	switch (params[2])
ds@714
   288
	{
ds@714
   289
	case ConVarBound_Upper:
ds@714
   290
		hasBound = pConVar->GetMax(bound);
ds@714
   291
		break;
ds@714
   292
	case ConVarBound_Lower:
ds@714
   293
		hasBound = pConVar->GetMin(bound);
ds@714
   294
		break;
ds@714
   295
	default:
ds@714
   296
		return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714
   297
	}
ds@714
   298
	
ds@714
   299
	pContext->LocalToPhysAddr(params[3], &addr);
ds@714
   300
	*addr = sp_ftoc(bound);
dvander@498
   301
ds@714
   302
	return hasBound;
dvander@498
   303
}
dvander@498
   304
ds@714
   305
static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
dvander@498
   306
{
dvander@498
   307
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   308
	HandleError err;
ds@576
   309
	ConVar *pConVar;
dvander@498
   310
ds@576
   311
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   312
		!= HandleError_None)
dvander@498
   313
	{
ds@581
   314
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   315
	}
dvander@498
   316
ds@714
   317
	switch (params[2])
ds@714
   318
	{
ds@714
   319
	case ConVarBound_Upper:
ds@714
   320
		pConVar->SetMax(params[3] ? true : false, sp_ctof(params[4]));
ds@714
   321
		break;
ds@714
   322
	case ConVarBound_Lower:
ds@714
   323
		pConVar->SetMin(params[3] ? true : false, sp_ctof(params[4]));
ds@714
   324
		break;
ds@714
   325
	default:
ds@714
   326
		return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
ds@714
   327
	}
dvander@498
   328
ds@714
   329
	return 1;
dvander@498
   330
}
dvander@498
   331
dvander@498
   332
static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
dvander@498
   333
{
dvander@498
   334
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   335
	HandleError err;
ds@576
   336
	ConVar *pConVar;
dvander@498
   337
ds@576
   338
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   339
		!= HandleError_None)
dvander@498
   340
	{
ds@581
   341
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   342
	}
dvander@498
   343
ds@576
   344
	pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
dvander@498
   345
dvander@498
   346
	return 1;
dvander@498
   347
}
dvander@498
   348
dvander@498
   349
static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
dvander@498
   350
{
dvander@498
   351
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@498
   352
	HandleError err;
ds@576
   353
	ConVar *pConVar;
dvander@498
   354
ds@576
   355
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
dvander@498
   356
		!= HandleError_None)
dvander@498
   357
	{
ds@581
   358
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
dvander@498
   359
	}
dvander@498
   360
ds@576
   361
	pConVar->Revert();
dvander@498
   362
dvander@498
   363
	return 1;
dvander@498
   364
}
dvander@498
   365
ds@696
   366
static bool s_QueryAlreadyWarned = false;
ds@696
   367
ds@696
   368
static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *params)
ds@696
   369
{
ds@696
   370
	CPlayer *pPlayer;
ds@696
   371
	char *name;
ds@696
   372
	IPluginFunction *pCallback;
ds@696
   373
ds@696
   374
	if (g_IsOriginalEngine)
ds@696
   375
	{
ds@696
   376
		if (!s_QueryAlreadyWarned)
ds@696
   377
		{
ds@696
   378
			s_QueryAlreadyWarned = true;
ds@696
   379
			return pContext->ThrowNativeError("Game does not support client convar querying (one time warning)");
ds@696
   380
		}
ds@696
   381
ds@696
   382
		return 0;
ds@696
   383
	}
ds@696
   384
ds@696
   385
	pPlayer = g_Players.GetPlayerByIndex(params[1]);
ds@696
   386
ds@696
   387
	if (!pPlayer)
ds@696
   388
	{
ds@696
   389
		return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
ds@696
   390
	}
ds@696
   391
ds@697
   392
	if (!pPlayer->IsConnected())
ds@696
   393
	{
ds@697
   394
		return pContext->ThrowNativeError("Player %d is not connected", params[1]);
ds@697
   395
	}
ds@697
   396
ds@697
   397
	/* Trying a query on a bot results in callback not be fired, so don't bother */
ds@697
   398
	if (pPlayer->IsFakeClient())
ds@697
   399
	{
ds@697
   400
		return 0;
ds@696
   401
	}
ds@696
   402
ds@696
   403
	pContext->LocalToString(params[2], &name);
ds@696
   404
	pCallback = pContext->GetFunctionById(params[3]);
ds@696
   405
ds@696
   406
	if (!pCallback)
ds@696
   407
	{
ds@696
   408
		return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
ds@696
   409
	}
ds@696
   410
ds@696
   411
	return g_ConVarManager.QueryClientConVar(pPlayer->GetEdict(), name, pCallback, params[4]);
ds@696
   412
}
ds@696
   413
dvander@498
   414
static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
dvander@498
   415
{
dvander@498
   416
	char *name,*help;
dvander@498
   417
	IPluginFunction *pFunction;
dvander@498
   418
dvander@498
   419
	pContext->LocalToString(params[1], &name);
dvander@498
   420
	pContext->LocalToString(params[3], &help);
dvander@498
   421
	pFunction = pContext->GetFunctionById(params[2]);
dvander@498
   422
dvander@498
   423
	if (!pFunction)
dvander@498
   424
	{
dvander@498
   425
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@498
   426
	}
dvander@498
   427
ds@579
   428
	if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
ds@579
   429
	{
ds@579
   430
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   431
	}
dvander@498
   432
dvander@498
   433
	return 1;
dvander@498
   434
}
dvander@498
   435
dvander@500
   436
static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
dvander@500
   437
{
dvander@500
   438
	char *name,*help;
dvander@500
   439
	IPluginFunction *pFunction;
dvander@500
   440
dvander@500
   441
	pContext->LocalToString(params[1], &name);
dvander@500
   442
	pContext->LocalToString(params[3], &help);
dvander@500
   443
	pFunction = pContext->GetFunctionById(params[2]);
dvander@500
   444
dvander@500
   445
	if (!pFunction)
dvander@500
   446
	{
dvander@500
   447
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@500
   448
	}
dvander@500
   449
ds@579
   450
	if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
ds@579
   451
	{
ds@579
   452
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   453
	}
dvander@500
   454
dvander@500
   455
	return 1;
dvander@500
   456
}
dvander@500
   457
dvander@514
   458
static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
dvander@514
   459
{
dvander@514
   460
	char *name,*help;
dvander@514
   461
	const char *group;
dvander@514
   462
	IPluginFunction *pFunction;
dvander@514
   463
	FlagBits flags = params[3];
dvander@514
   464
	int cmdflags = params[6];
dvander@514
   465
dvander@514
   466
	pContext->LocalToString(params[1], &name);
dvander@514
   467
	pContext->LocalToString(params[4], &help);
dvander@514
   468
	pContext->LocalToString(params[5], (char **)&group);
dvander@514
   469
	pFunction = pContext->GetFunctionById(params[2]);
dvander@514
   470
dvander@514
   471
	if (group[0] == '\0')
dvander@514
   472
	{
dvander@514
   473
		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@514
   474
		group = pPlugin->GetFilename();
dvander@514
   475
	}
dvander@514
   476
dvander@514
   477
	if (!pFunction)
dvander@514
   478
	{
dvander@514
   479
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@514
   480
	}
dvander@514
   481
ds@579
   482
	if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
ds@579
   483
	{
ds@579
   484
		return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
ds@579
   485
	}
dvander@514
   486
dvander@514
   487
	return 1;
dvander@514
   488
}
dvander@514
   489
dvander@517
   490
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
dvander@517
   491
{
dvander@517
   492
	return engine->Cmd_Argc() - 1;
dvander@517
   493
}
dvander@517
   494
dvander@517
   495
static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
dvander@517
   496
{
dvander@517
   497
	const char *arg = engine->Cmd_Argv(params[1]);
dvander@517
   498
	
dvander@517
   499
	pContext->StringToLocalUTF8(params[2], params[3], arg, NULL);
dvander@517
   500
dvander@517
   501
	return 1;
dvander@517
   502
}
dvander@517
   503
dvander@517
   504
static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
dvander@517
   505
{
dvander@517
   506
	const char *args = engine->Cmd_Args();
dvander@517
   507
dvander@633
   508
	if (!args)
dvander@633
   509
	{
dvander@633
   510
		args = "";
dvander@633
   511
	}
dvander@633
   512
dvander@517
   513
	pContext->StringToLocalUTF8(params[1], params[2], args, NULL);
dvander@517
   514
dvander@517
   515
	return 1;
dvander@517
   516
}
dvander@517
   517
dvander@518
   518
static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
dvander@518
   519
{
dvander@518
   520
	char buffer[1024];
dvander@518
   521
	char *fmt;
dvander@518
   522
	int arg = 2;
dvander@518
   523
dvander@518
   524
	pCtx->LocalToString(params[1], &fmt);
dvander@518
   525
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518
   526
dvander@518
   527
	buffer[res++] = '\n';
dvander@518
   528
	buffer[res] = '\0';
dvander@518
   529
dvander@518
   530
	META_CONPRINT(buffer);
dvander@518
   531
dvander@518
   532
	return 1;
dvander@518
   533
}
dvander@518
   534
dvander@518
   535
static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
dvander@518
   536
{
dvander@518
   537
	int index = params[1];
dvander@520
   538
	if ((index < 0) || (index > g_Players.GetMaxClients()))
dvander@518
   539
	{
dvander@518
   540
		return pCtx->ThrowNativeError("Invalid client index %d", index);
dvander@518
   541
	}
dvander@518
   542
dvander@520
   543
	CPlayer *pPlayer = NULL;
dvander@520
   544
	if (index != 0)
dvander@518
   545
	{
dvander@520
   546
		pPlayer = g_Players.GetPlayerByIndex(index);
dvander@520
   547
		if (!pPlayer->IsInGame())
dvander@520
   548
		{
dvander@520
   549
			return pCtx->ThrowNativeError("Client %d is not in game", index);
dvander@520
   550
		}
dvander@520
   551
		
dvander@520
   552
		/* Silent fail on bots, engine will crash */
dvander@520
   553
		if (pPlayer->IsFakeClient())
dvander@520
   554
		{
dvander@520
   555
			return 0;
dvander@520
   556
		}
dvander@519
   557
	}
dvander@518
   558
dvander@518
   559
	char buffer[1024];
dvander@518
   560
	char *fmt;
dvander@518
   561
	int arg = 3;
dvander@518
   562
dvander@518
   563
	pCtx->LocalToString(params[2], &fmt);
dvander@518
   564
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);
dvander@518
   565
dvander@518
   566
	buffer[res++] = '\n';
dvander@518
   567
	buffer[res] = '\0';
dvander@518
   568
dvander@520
   569
	if (index != 0)
dvander@520
   570
	{
dvander@520
   571
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@520
   572
	} else {
dvander@520
   573
		META_CONPRINT(buffer);
dvander@520
   574
	}
dvander@518
   575
dvander@518
   576
	return 1;
dvander@518
   577
}
dvander@518
   578
dvander@522
   579
static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522
   580
{
dvander@522
   581
	char buffer[1024];
dvander@522
   582
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522
   583
dvander@522
   584
	/* One byte for null terminator, one for newline */
dvander@522
   585
	buffer[len++] = '\n';
dvander@522
   586
	buffer[len] = '\0';
dvander@522
   587
dvander@522
   588
	engine->ServerCommand(buffer);
dvander@522
   589
dvander@522
   590
	return 1;
dvander@522
   591
}
dvander@522
   592
dvander@522
   593
static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
dvander@522
   594
{
dvander@522
   595
	char buffer[1024];
dvander@522
   596
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
dvander@522
   597
dvander@522
   598
	/* One byte for null terminator, one for newline */
dvander@522
   599
	buffer[len++] = '\n';
dvander@522
   600
	buffer[len] = '\0';
dvander@522
   601
dvander@522
   602
	engine->InsertServerCommand(buffer);
dvander@522
   603
dvander@522
   604
	return 1;
dvander@522
   605
}
dvander@522
   606
dvander@522
   607
static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
dvander@522
   608
{
dvander@522
   609
	engine->ServerExecute();
dvander@522
   610
dvander@522
   611
	return 1;
dvander@522
   612
}
dvander@522
   613
dvander@532
   614
static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@532
   615
{
dvander@532
   616
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@532
   617
dvander@532
   618
	if (!pPlayer)
dvander@532
   619
	{
dvander@532
   620
		return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
dvander@532
   621
	}
dvander@532
   622
dvander@532
   623
	if (!pPlayer->IsConnected())
dvander@532
   624
	{
dvander@532
   625
		return pContext->ThrowNativeError("Player %d is not connected", params[1]);
dvander@532
   626
	}
dvander@532
   627
dvander@532
   628
	char buffer[256];
ds@873
   629
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@532
   630
dvander@532
   631
	engine->ClientCommand(pPlayer->GetEdict(), "%s", buffer);
dvander@532
   632
dvander@532
   633
	return 1;
dvander@532
   634
}
dvander@532
   635
dvander@893
   636
dvander@893
   637
static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
dvander@893
   638
{
dvander@893
   639
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893
   640
dvander@893
   641
	if (!pPlayer)
dvander@893
   642
	{
dvander@893
   643
		return pContext->ThrowNativeError("Player %d is not a valid player", params[1]);
dvander@893
   644
	}
dvander@893
   645
dvander@893
   646
	if (!pPlayer->IsConnected())
dvander@893
   647
	{
dvander@893
   648
		return pContext->ThrowNativeError("Player %d is not connected", params[1]);
dvander@893
   649
	}
dvander@893
   650
dvander@893
   651
	char buffer[256];
dvander@893
   652
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@893
   653
dvander@893
   654
	unsigned int old = g_ChatTriggers.SetReplyTo(SM_REPLY_CONSOLE);
dvander@893
   655
	serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), buffer);
dvander@893
   656
	g_ChatTriggers.SetReplyTo(old);
dvander@893
   657
dvander@893
   658
	return 1;
dvander@893
   659
}
dvander@893
   660
dvander@893
   661
static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
dvander@893
   662
{
dvander@893
   663
	/* Build the format string */
dvander@893
   664
	char buffer[1024];
dvander@893
   665
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 2);
dvander@893
   666
dvander@893
   667
	/* If we're printing to the server, shortcut out */
dvander@893
   668
	if (params[1] == 0)
dvander@893
   669
	{
dvander@893
   670
		/* Print */
dvander@893
   671
		buffer[len++] = '\n';
dvander@893
   672
		buffer[len] = '\0';
dvander@893
   673
		META_CONPRINT(buffer);
dvander@893
   674
		return 1;
dvander@893
   675
	}
dvander@893
   676
dvander@893
   677
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@893
   678
dvander@893
   679
	if (!pPlayer)
dvander@893
   680
	{
dvander@893
   681
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@893
   682
	}
dvander@893
   683
dvander@893
   684
	if (!pPlayer->IsConnected())
dvander@893
   685
	{
dvander@893
   686
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@893
   687
	}
dvander@893
   688
dvander@893
   689
	unsigned int replyto = g_ChatTriggers.GetReplyTo();
dvander@893
   690
	if (replyto == SM_REPLY_CONSOLE)
dvander@893
   691
	{
dvander@893
   692
		buffer[len++] = '\n';
dvander@893
   693
		buffer[len] = '\0';
dvander@893
   694
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
dvander@893
   695
	} else if (replyto == SM_REPLY_CHAT) {
dvander@893
   696
		if (len >= 191)
dvander@893
   697
		{
dvander@893
   698
			len = 191;
dvander@893
   699
		}
dvander@893
   700
		buffer[len] = '\0';
dvander@893
   701
		g_HL2.TextMsg(params[1], HUD_PRINTTALK, buffer);
dvander@893
   702
	}
dvander@893
   703
dvander@893
   704
	return 1;
dvander@893
   705
}
dvander@893
   706
dvander@518
   707
REGISTER_NATIVES(consoleNatives)
dvander@498
   708
{
dvander@498
   709
	{"CreateConVar",		sm_CreateConVar},
dvander@498
   710
	{"FindConVar",			sm_FindConVar},
dvander@498
   711
	{"HookConVarChange",	sm_HookConVarChange},
dvander@498
   712
	{"UnhookConVarChange",	sm_UnhookConVarChange},
dvander@498
   713
	{"GetConVarBool",		sm_GetConVarBool},
dvander@498
   714
	{"SetConVarBool",		sm_SetConVarNum},
dvander@498
   715
	{"GetConVarInt",		sm_GetConVarInt},
dvander@498
   716
	{"SetConVarInt",		sm_SetConVarNum},
dvander@498
   717
	{"GetConVarFloat",		sm_GetConVarFloat},
dvander@498
   718
	{"SetConVarFloat",		sm_SetConVarFloat},
dvander@498
   719
	{"GetConVarString",		sm_GetConVarString},
dvander@498
   720
	{"SetConVarString",		sm_SetConVarString},
dvander@498
   721
	{"GetConVarFlags",		sm_GetConVarFlags},
dvander@498
   722
	{"SetConVarFlags",		sm_SetConVarFlags},
dvander@498
   723
	{"GetConVarName",		sm_GetConVarName},
ds@714
   724
	{"GetConVarBounds",		sm_GetConVarBounds},
ds@714
   725
	{"SetConVarBounds",		sm_SetConVarBounds},
dvander@498
   726
	{"ResetConVar",			sm_ResetConVar},
ds@696
   727
	{"QueryClientConVar",	sm_QueryClientConVar},
dvander@498
   728
	{"RegServerCmd",		sm_RegServerCmd},
dvander@500
   729
	{"RegConsoleCmd",		sm_RegConsoleCmd},
dvander@517
   730
	{"GetCmdArgString",		sm_GetCmdArgString},
dvander@517
   731
	{"GetCmdArgs",			sm_GetCmdArgs},
dvander@517
   732
	{"GetCmdArg",			sm_GetCmdArg},
dvander@518
   733
	{"PrintToServer",		sm_PrintToServer},
dvander@518
   734
	{"PrintToConsole",		sm_PrintToConsole},
dvander@520
   735
	{"RegAdminCmd",			sm_RegAdminCmd},
dvander@522
   736
	{"ServerCommand",		sm_ServerCommand},
dvander@522
   737
	{"InsertServerCommand",	sm_InsertServerCommand},
dvander@522
   738
	{"ServerExecute",		sm_ServerExecute},
dvander@532
   739
	{"ClientCommand",		sm_ClientCommand},
dvander@893
   740
	{"FakeClientCommand",	FakeClientCommand},
dvander@893
   741
	{"ReplyToCommand",		ReplyToCommand},
dvander@498
   742
	{NULL,					NULL}
dvander@498
   743
};