plugins/basecommands.sp
author David Anderson <dvander@alliedmods.net>
Fri Jul 11 06:51:21 2008 +0000 (2008-07-11)
branchrefac-jit
changeset 2192 7602d7fb60d9
parent 2168 c24a6fa957db
permissions -rw-r--r--
fixed a compat regression, forgot msvc does funky things with overloaded virtual calls
dvander@2168
     1
/**
dvander@2168
     2
 * vim: set ts=4 :
dvander@2168
     3
 * =============================================================================
dvander@2168
     4
 * SourceMod Basic Commands Plugin
dvander@2168
     5
 * Implements basic admin commands.
dvander@2168
     6
 *
dvander@2168
     7
 * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
dvander@2168
     8
 * =============================================================================
dvander@2168
     9
 *
dvander@2168
    10
 * This program is free software; you can redistribute it and/or modify it under
dvander@2168
    11
 * the terms of the GNU General Public License, version 3.0, as published by the
dvander@2168
    12
 * Free Software Foundation.
dvander@2168
    13
 * 
dvander@2168
    14
 * This program is distributed in the hope that it will be useful, but WITHOUT
dvander@2168
    15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@2168
    16
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
dvander@2168
    17
 * details.
dvander@2168
    18
 *
dvander@2168
    19
 * You should have received a copy of the GNU General Public License along with
dvander@2168
    20
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@2168
    21
 *
dvander@2168
    22
 * As a special exception, AlliedModders LLC gives you permission to link the
dvander@2168
    23
 * code of this program (as well as its derivative 1works) to "Half-Life 2," the
dvander@2168
    24
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
dvander@2168
    25
 * by the Valve Corporation.  You must obey the GNU General Public License in
dvander@2168
    26
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
dvander@2168
    27
 * this exception to all derivative works.  AlliedModders LLC defines further
dvander@2168
    28
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
dvander@2168
    29
 * or <http://www.sourcemod.net/license.php>.
dvander@2168
    30
 *
dvander@2168
    31
 * Version: $Id$
dvander@2168
    32
 */
dvander@2168
    33
dvander@2168
    34
#pragma semicolon 1
dvander@2168
    35
dvander@2168
    36
#include <sourcemod>
dvander@2168
    37
#undef REQUIRE_PLUGIN
dvander@2168
    38
#include <adminmenu>
dvander@2168
    39
dvander@2168
    40
public Plugin:myinfo =
dvander@2168
    41
{
dvander@2168
    42
	name = "Basic Commands",
dvander@2168
    43
	author = "AlliedModders LLC",
dvander@2168
    44
	description = "Basic Admin Commands",
dvander@2168
    45
	version = SOURCEMOD_VERSION,
dvander@2168
    46
	url = "http://www.sourcemod.net/"
dvander@2168
    47
};
dvander@2168
    48
dvander@2168
    49
new Handle:hTopMenu = INVALID_HANDLE;
dvander@2168
    50
dvander@2168
    51
new Handle:g_MapList;
dvander@2168
    52
new Handle:g_ProtectedVars;
dvander@2168
    53
dvander@2168
    54
#include "basecommands/kick.sp"
dvander@2168
    55
#include "basecommands/reloadadmins.sp"
dvander@2168
    56
#include "basecommands/cancelvote.sp"
dvander@2168
    57
#include "basecommands/who.sp"
dvander@2168
    58
#include "basecommands/map.sp"
dvander@2168
    59
#include "basecommands/execcfg.sp"
dvander@2168
    60
dvander@2168
    61
public OnPluginStart()
dvander@2168
    62
{
dvander@2168
    63
	LoadTranslations("common.phrases");
dvander@2168
    64
	LoadTranslations("plugin.basecommands");
dvander@2168
    65
dvander@2168
    66
	RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]");
dvander@2168
    67
	RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map <map>");
dvander@2168
    68
	RegAdminCmd("sm_rcon", Command_Rcon, ADMFLAG_RCON, "sm_rcon <args>");
dvander@2168
    69
	RegAdminCmd("sm_cvar", Command_Cvar, ADMFLAG_CONVARS, "sm_cvar <cvar> [value]");
dvander@2168
    70
	RegAdminCmd("sm_execcfg", Command_ExecCfg, ADMFLAG_CONFIG, "sm_execcfg <filename>");
dvander@2168
    71
	RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]");
dvander@2168
    72
	RegAdminCmd("sm_reloadadmins", Command_ReloadAdmins, ADMFLAG_BAN, "sm_reloadadmins");
dvander@2168
    73
	RegAdminCmd("sm_cancelvote", Command_CancelVote, ADMFLAG_VOTE, "sm_cancelvote");
dvander@2168
    74
	RegConsoleCmd("sm_revote", Command_ReVote);
dvander@2168
    75
	
dvander@2168
    76
	/* Account for late loading */
dvander@2168
    77
	new Handle:topmenu;
dvander@2168
    78
	if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
dvander@2168
    79
	{
dvander@2168
    80
		OnAdminMenuReady(topmenu);
dvander@2168
    81
	}
dvander@2168
    82
	
dvander@2168
    83
	g_MapList = CreateMenu(MenuHandler_ChangeMap);
dvander@2168
    84
	SetMenuTitle(g_MapList, "Please select a map");
dvander@2168
    85
	SetMenuExitBackButton(g_MapList, true);
dvander@2168
    86
	
dvander@2168
    87
	decl String:mapListPath[PLATFORM_MAX_PATH];
dvander@2168
    88
	BuildPath(Path_SM, mapListPath, sizeof(mapListPath), "configs/adminmenu_maplist.ini");
dvander@2168
    89
	SetMapListCompatBind("sm_map menu", mapListPath);
dvander@2168
    90
	
dvander@2168
    91
	g_ProtectedVars = CreateTrie();
dvander@2168
    92
	ProtectVar("rcon_password");
dvander@2168
    93
	ProtectVar("sm_show_activity");
dvander@2168
    94
	ProtectVar("sm_immunity_mode");
dvander@2168
    95
}
dvander@2168
    96
dvander@2168
    97
public OnMapStart()
dvander@2168
    98
{
dvander@2168
    99
	ParseConfigs();
dvander@2168
   100
}
dvander@2168
   101
dvander@2168
   102
public OnConfigsExecuted()
dvander@2168
   103
{
dvander@2168
   104
	LoadMapList(g_MapList);
dvander@2168
   105
}
dvander@2168
   106
dvander@2168
   107
ProtectVar(const String:cvar[])
dvander@2168
   108
{
dvander@2168
   109
	SetTrieValue(g_ProtectedVars, cvar, 1);
dvander@2168
   110
}
dvander@2168
   111
dvander@2168
   112
bool:IsVarProtected(const String:cvar[])
dvander@2168
   113
{
dvander@2168
   114
	decl dummy_value;
dvander@2168
   115
	return GetTrieValue(g_ProtectedVars, cvar, dummy_value);
dvander@2168
   116
}
dvander@2168
   117
dvander@2168
   118
public OnAdminMenuReady(Handle:topmenu)
dvander@2168
   119
{
dvander@2168
   120
	/* Block us from being called twice */
dvander@2168
   121
	if (topmenu == hTopMenu)
dvander@2168
   122
	{
dvander@2168
   123
		return;
dvander@2168
   124
	}
dvander@2168
   125
	
dvander@2168
   126
	/* Save the Handle */
dvander@2168
   127
	hTopMenu = topmenu;
dvander@2168
   128
	
dvander@2168
   129
	/* Build the "Player Commands" category */
dvander@2168
   130
	new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
dvander@2168
   131
	
dvander@2168
   132
	if (player_commands != INVALID_TOPMENUOBJECT)
dvander@2168
   133
	{
dvander@2168
   134
		AddToTopMenu(hTopMenu, 
dvander@2168
   135
			"sm_kick",
dvander@2168
   136
			TopMenuObject_Item,
dvander@2168
   137
			AdminMenu_Kick,
dvander@2168
   138
			player_commands,
dvander@2168
   139
			"sm_kick",
dvander@2168
   140
			ADMFLAG_KICK);
dvander@2168
   141
			
dvander@2168
   142
		AddToTopMenu(hTopMenu,
dvander@2168
   143
			"sm_who",
dvander@2168
   144
			TopMenuObject_Item,
dvander@2168
   145
			AdminMenu_Who,
dvander@2168
   146
			player_commands,
dvander@2168
   147
			"sm_who",
dvander@2168
   148
			ADMFLAG_GENERIC);
dvander@2168
   149
	}
dvander@2168
   150
dvander@2168
   151
	new TopMenuObject:server_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_SERVERCOMMANDS);
dvander@2168
   152
dvander@2168
   153
	if (server_commands != INVALID_TOPMENUOBJECT)
dvander@2168
   154
	{
dvander@2168
   155
		AddToTopMenu(hTopMenu,
dvander@2168
   156
			"sm_reloadadmins",
dvander@2168
   157
			TopMenuObject_Item,
dvander@2168
   158
			AdminMenu_ReloadAdmins,
dvander@2168
   159
			server_commands,
dvander@2168
   160
			"sm_reloadadmins",
dvander@2168
   161
			ADMFLAG_BAN);
dvander@2168
   162
			
dvander@2168
   163
		AddToTopMenu(hTopMenu,
dvander@2168
   164
			"sm_map",
dvander@2168
   165
			TopMenuObject_Item,
dvander@2168
   166
			AdminMenu_Map,
dvander@2168
   167
			server_commands,
dvander@2168
   168
			"sm_map",
dvander@2168
   169
			ADMFLAG_CHANGEMAP);
dvander@2168
   170
			
dvander@2168
   171
		AddToTopMenu(hTopMenu,
dvander@2168
   172
			"sm_execcfg",
dvander@2168
   173
			TopMenuObject_Item,
dvander@2168
   174
			AdminMenu_ExecCFG,
dvander@2168
   175
			server_commands,
dvander@2168
   176
			"sm_execcfg",
dvander@2168
   177
			ADMFLAG_CONFIG);		
dvander@2168
   178
	}
dvander@2168
   179
dvander@2168
   180
	new TopMenuObject:voting_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_VOTINGCOMMANDS);
dvander@2168
   181
dvander@2168
   182
	if (voting_commands != INVALID_TOPMENUOBJECT)
dvander@2168
   183
	{
dvander@2168
   184
		AddToTopMenu(hTopMenu,
dvander@2168
   185
			"sm_cancelvote",
dvander@2168
   186
			TopMenuObject_Item,
dvander@2168
   187
			AdminMenu_CancelVote,
dvander@2168
   188
			voting_commands,
dvander@2168
   189
			"sm_cancelvote",
dvander@2168
   190
			ADMFLAG_VOTE);
dvander@2168
   191
	}
dvander@2168
   192
}
dvander@2168
   193
dvander@2168
   194
public OnLibraryRemoved(const String:name[])
dvander@2168
   195
{
dvander@2168
   196
	if (strcmp(name, "adminmenu") == 0)
dvander@2168
   197
	{
dvander@2168
   198
		hTopMenu = INVALID_HANDLE;
dvander@2168
   199
	}
dvander@2168
   200
}
dvander@2168
   201
dvander@2168
   202
#define FLAG_STRINGS		14
dvander@2168
   203
new String:g_FlagNames[FLAG_STRINGS][20] =
dvander@2168
   204
{
dvander@2168
   205
	"res",
dvander@2168
   206
	"admin",
dvander@2168
   207
	"kick",
dvander@2168
   208
	"ban",
dvander@2168
   209
	"unban",
dvander@2168
   210
	"slay",
dvander@2168
   211
	"map",
dvander@2168
   212
	"cvars",
dvander@2168
   213
	"cfg",
dvander@2168
   214
	"chat",
dvander@2168
   215
	"vote",
dvander@2168
   216
	"pass",
dvander@2168
   217
	"rcon",
dvander@2168
   218
	"cheat"
dvander@2168
   219
};
dvander@2168
   220
dvander@2168
   221
CustomFlagsToString(String:buffer[], maxlength, flags)
dvander@2168
   222
{
dvander@2168
   223
	decl String:joins[6][6];
dvander@2168
   224
	new total;
dvander@2168
   225
	
dvander@2168
   226
	for (new i=_:Admin_Custom1; i<=_:Admin_Custom6; i++)
dvander@2168
   227
	{
dvander@2168
   228
		if (flags & (1<<i))
dvander@2168
   229
		{
dvander@2168
   230
			IntToString(i - _:Admin_Custom1 + 1, joins[total++], 6);
dvander@2168
   231
		}
dvander@2168
   232
	}
dvander@2168
   233
	
dvander@2168
   234
	ImplodeStrings(joins, total, ",", buffer, maxlength);
dvander@2168
   235
	
dvander@2168
   236
	return total;
dvander@2168
   237
}
dvander@2168
   238
dvander@2168
   239
FlagsToString(String:buffer[], maxlength, flags)
dvander@2168
   240
{
dvander@2168
   241
	decl String:joins[FLAG_STRINGS+1][32];
dvander@2168
   242
	new total;
dvander@2168
   243
dvander@2168
   244
	for (new i=0; i<FLAG_STRINGS; i++)
dvander@2168
   245
	{
dvander@2168
   246
		if (flags & (1<<i))
dvander@2168
   247
		{
dvander@2168
   248
			strcopy(joins[total++], 32, g_FlagNames[i]);
dvander@2168
   249
		}
dvander@2168
   250
	}
dvander@2168
   251
	
dvander@2168
   252
	decl String:custom_flags[32];
dvander@2168
   253
	if (CustomFlagsToString(custom_flags, sizeof(custom_flags), flags))
dvander@2168
   254
	{
dvander@2168
   255
		Format(joins[total++], 32, "custom(%s)", custom_flags);
dvander@2168
   256
	}
dvander@2168
   257
dvander@2168
   258
	ImplodeStrings(joins, total, ", ", buffer, maxlength);
dvander@2168
   259
}
dvander@2168
   260
dvander@2168
   261
public Action:Command_Cvar(client, args)
dvander@2168
   262
{
dvander@2168
   263
	if (args < 1)
dvander@2168
   264
	{
dvander@2168
   265
		if (client == 0)
dvander@2168
   266
		{
dvander@2168
   267
			ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar|protect> [value]");
dvander@2168
   268
		}
dvander@2168
   269
		else
dvander@2168
   270
		{
dvander@2168
   271
			ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar> [value]");
dvander@2168
   272
		}
dvander@2168
   273
		return Plugin_Handled;
dvander@2168
   274
	}
dvander@2168
   275
dvander@2168
   276
	decl String:cvarname[64];
dvander@2168
   277
	GetCmdArg(1, cvarname, sizeof(cvarname));
dvander@2168
   278
	
dvander@2168
   279
	if (client == 0 && StrEqual(cvarname, "protect"))
dvander@2168
   280
	{
dvander@2168
   281
		if (args < 2)
dvander@2168
   282
		{
dvander@2168
   283
			ReplyToCommand(client, "[SM] Usage: sm_cvar <protect> <cvar>");
dvander@2168
   284
			return Plugin_Handled;
dvander@2168
   285
		}
dvander@2168
   286
		GetCmdArg(2, cvarname, sizeof(cvarname));
dvander@2168
   287
		ProtectVar(cvarname);
dvander@2168
   288
		ReplyToCommand(client, "[SM] %t", "Cvar is now protected", cvarname);
dvander@2168
   289
		return Plugin_Handled;
dvander@2168
   290
	}
dvander@2168
   291
dvander@2168
   292
	new Handle:hndl = FindConVar(cvarname);
dvander@2168
   293
	if (hndl == INVALID_HANDLE)
dvander@2168
   294
	{
dvander@2168
   295
		ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname);
dvander@2168
   296
		return Plugin_Handled;
dvander@2168
   297
	}
dvander@2168
   298
	
dvander@2168
   299
	new bool:allowed = false;
dvander@2168
   300
	new client_flags = client == 0 ? ADMFLAG_ROOT : GetUserFlagBits(client);
dvander@2168
   301
	
dvander@2168
   302
	if (client_flags & ADMFLAG_ROOT)
dvander@2168
   303
	{
dvander@2168
   304
		allowed = true;
dvander@2168
   305
	}
dvander@2168
   306
	else
dvander@2168
   307
	{
dvander@2168
   308
		if (GetConVarFlags(hndl) & FCVAR_PROTECTED)
dvander@2168
   309
		{
dvander@2168
   310
			allowed = ((client_flags & ADMFLAG_PASSWORD) == ADMFLAG_PASSWORD);
dvander@2168
   311
		}
dvander@2168
   312
		else if (StrEqual(cvarname, "sv_cheats"))
dvander@2168
   313
		{
dvander@2168
   314
			allowed = ((client_flags & ADMFLAG_CHEATS) == ADMFLAG_CHEATS);
dvander@2168
   315
		}
dvander@2168
   316
		else if (!IsVarProtected(cvarname))
dvander@2168
   317
		{
dvander@2168
   318
			allowed = true;
dvander@2168
   319
		}
dvander@2168
   320
	}
dvander@2168
   321
	
dvander@2168
   322
	if (!allowed)
dvander@2168
   323
	{
dvander@2168
   324
		ReplyToCommand(client, "[SM] %t", "No access to cvar");
dvander@2168
   325
		return Plugin_Handled;
dvander@2168
   326
	}
dvander@2168
   327
dvander@2168
   328
	decl String:value[255];
dvander@2168
   329
	if (args < 2)
dvander@2168
   330
	{
dvander@2168
   331
		GetConVarString(hndl, value, sizeof(value));
dvander@2168
   332
dvander@2168
   333
		ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value);
dvander@2168
   334
		return Plugin_Handled;
dvander@2168
   335
	}
dvander@2168
   336
dvander@2168
   337
	GetCmdArg(2, value, sizeof(value));
dvander@2168
   338
dvander@2168
   339
	if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED)
dvander@2168
   340
	{
dvander@2168
   341
		ShowActivity2(client, "[SM] ", "%t", "Cvar changed", cvarname, value);
dvander@2168
   342
	}
dvander@2168
   343
	else
dvander@2168
   344
	{
dvander@2168
   345
		ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
dvander@2168
   346
	}
dvander@2168
   347
dvander@2168
   348
	LogAction(client, -1, "\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
dvander@2168
   349
dvander@2168
   350
	SetConVarString(hndl, value, true);
dvander@2168
   351
dvander@2168
   352
	return Plugin_Handled;
dvander@2168
   353
}
dvander@2168
   354
dvander@2168
   355
public Action:Command_Rcon(client, args)
dvander@2168
   356
{
dvander@2168
   357
	if (args < 1)
dvander@2168
   358
	{
dvander@2168
   359
		ReplyToCommand(client, "[SM] Usage: sm_rcon <args>");
dvander@2168
   360
		return Plugin_Handled;
dvander@2168
   361
	}
dvander@2168
   362
dvander@2168
   363
	decl String:argstring[255];
dvander@2168
   364
	GetCmdArgString(argstring, sizeof(argstring));
dvander@2168
   365
dvander@2168
   366
	LogAction(client, -1, "\"%L\" console command (cmdline \"%s\")", client, argstring);
dvander@2168
   367
dvander@2168
   368
	ServerCommand("%s", argstring);
dvander@2168
   369
dvander@2168
   370
	return Plugin_Handled;
dvander@2168
   371
}
dvander@2168
   372
dvander@2168
   373
public Action:Command_ReVote(client, args)
dvander@2168
   374
{
dvander@2168
   375
	if (client == 0)
dvander@2168
   376
	{
dvander@2168
   377
		ReplyToCommand(client, "[SM] %t", "Command is in-game only");
dvander@2168
   378
		return Plugin_Handled;
dvander@2168
   379
	}
dvander@2168
   380
	
dvander@2168
   381
	if (!IsVoteInProgress())
dvander@2168
   382
	{
dvander@2168
   383
		ReplyToCommand(client, "[SM] %t", "Vote Not In Progress");
dvander@2168
   384
		return Plugin_Handled;
dvander@2168
   385
	}
dvander@2168
   386
	
dvander@2168
   387
	if (!IsClientInVotePool(client))
dvander@2168
   388
	{
dvander@2168
   389
		ReplyToCommand(client, "[SM] %t", "Cannot participate in vote");
dvander@2168
   390
		return Plugin_Handled;
dvander@2168
   391
	}
dvander@2168
   392
	
dvander@2168
   393
	if (!RedrawClientVoteMenu(client))
dvander@2168
   394
	{
dvander@2168
   395
		ReplyToCommand(client, "[SM] %t", "Cannot change vote");
dvander@2168
   396
	}
dvander@2168
   397
	
dvander@2168
   398
	return Plugin_Handled;
dvander@2168
   399
}