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