plugins/basecommands.sp
author Borja Ferrer <faluco@alliedmods.net>
Mon Oct 01 21:20:30 2007 +0000 (2007-10-01)
changeset 1515 3e112467aacd
parent 1510 de71b8774afc
child 1518 5c2bbd2506fc
permissions -rw-r--r--
fixed amb991, dispatchkeyvalue natives had wrong offsets
dvander@910
     1
/**
ds@1330
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
ds@1330
     4
 * SourceMod Basic Commands Plugin
ds@913
     5
 * Implements basic admin commands.
ds@1330
     6
 *
ds@1330
     7
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     8
 * =============================================================================
dvander@910
     9
 *
ds@1330
    10
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
    11
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    12
 * Free Software Foundation.
ds@1330
    13
 * 
ds@1330
    14
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    16
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    17
 * details.
dvander@910
    18
 *
ds@1330
    19
 * You should have received a copy of the GNU General Public License along with
ds@1330
    20
 * this program.  If not, see <http://www.gnu.org/licenses/>.
teame06@1211
    21
 *
ds@1330
    22
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    23
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    24
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    25
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    26
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    27
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    28
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    29
 * or <http://www.sourcemod.net/license.php>.
ds@913
    30
 *
ds@913
    31
 * Version: $Id$
dvander@910
    32
 */
dvander@910
    33
ds@989
    34
#pragma semicolon 1
dvander@910
    35
ds@989
    36
#include <sourcemod>
dvander@1510
    37
#undef REQUIRE_PLUGIN
dvander@1510
    38
#include <adminmenu>
ds@913
    39
teame06@1211
    40
public Plugin:myinfo =
dvander@910
    41
{
dvander@910
    42
	name = "Basic Commands",
dvander@910
    43
	author = "AlliedModders LLC",
dvander@910
    44
	description = "Basic Admin Commands",
dvander@910
    45
	version = SOURCEMOD_VERSION,
dvander@910
    46
	url = "http://www.sourcemod.net/"
dvander@910
    47
};
dvander@910
    48
dvander@1510
    49
new Handle:hTopMenu = INVALID_HANDLE;
dvander@1510
    50
dvander@1510
    51
#include "basecommands/kick.sp"
dvander@1510
    52
dvander@910
    53
public OnPluginStart()
dvander@910
    54
{
dvander@1027
    55
	LoadTranslations("common.phrases");
teame06@1211
    56
dvander@910
    57
	RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]");
dvander@917
    58
	RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map <map>");
dvander@918
    59
	RegAdminCmd("sm_rcon", Command_Rcon, ADMFLAG_RCON, "sm_rcon <args>");
dvander@920
    60
	RegAdminCmd("sm_cvar", Command_Cvar, ADMFLAG_CONVARS, "sm_cvar <cvar> [value]");
dvander@921
    61
	RegAdminCmd("sm_execcfg", Command_ExecCfg, ADMFLAG_CONFIG, "sm_execcfg <filename>");
dvander@923
    62
	RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]");
dvander@1162
    63
	RegAdminCmd("sm_reloadadmins", Command_ReloadAdmins, ADMFLAG_BAN, "sm_reloadadmins");
ferret99gt@1276
    64
	RegAdminCmd("sm_cancelvote", Command_CancelVote, ADMFLAG_VOTE, "sm_cancelvote");
dvander@1510
    65
	
dvander@1510
    66
	/* Account for late loading */
dvander@1510
    67
	new Handle:topmenu;
dvander@1510
    68
	if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
dvander@1510
    69
	{
dvander@1510
    70
		OnAdminMenuReady(topmenu);
dvander@1510
    71
	}
dvander@1510
    72
}
dvander@1510
    73
dvander@1510
    74
public OnAdminMenuReady(Handle:topmenu)
dvander@1510
    75
{
dvander@1510
    76
	/* Block us from being called twice */
dvander@1510
    77
	if (topmenu == hTopMenu)
dvander@1510
    78
	{
dvander@1510
    79
		return;
dvander@1510
    80
	}
dvander@1510
    81
	
dvander@1510
    82
	/* Save the Handle */
dvander@1510
    83
	hTopMenu = topmenu;
dvander@1510
    84
	
dvander@1510
    85
	/* Build the "Player Commands" category */
dvander@1510
    86
	new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
dvander@1510
    87
	
dvander@1510
    88
	if (player_commands != INVALID_TOPMENUOBJECT)
dvander@1510
    89
	{
dvander@1510
    90
		AddToTopMenu(hTopMenu, 
dvander@1510
    91
			"Kick",
dvander@1510
    92
			TopMenuObject_Item,
dvander@1510
    93
			AdminMenu_Kick,
dvander@1510
    94
			player_commands,
dvander@1510
    95
			"sm_kick",
dvander@1510
    96
			ADMFLAG_KICK);
dvander@1510
    97
	}
dvander@1510
    98
}
dvander@1510
    99
dvander@1510
   100
public OnLibraryRemoved(const String:name[])
dvander@1510
   101
{
dvander@1510
   102
	if (strcmp(name, "adminmenu") == 0)
dvander@1510
   103
	{
dvander@1510
   104
		hTopMenu = INVALID_HANDLE;
dvander@1510
   105
	}
dvander@927
   106
}
dvander@927
   107
dvander@1162
   108
public Action:Command_ReloadAdmins(client, args)
dvander@1162
   109
{
dvander@1162
   110
	/* Dump it all! */
dvander@1162
   111
	DumpAdminCache(AdminCache_Groups, true);
dvander@1162
   112
	DumpAdminCache(AdminCache_Overrides, true);
teame06@1211
   113
dvander@1378
   114
	LogAction(client, -1, "\"%L\" refreshed the admin cache.", client);
dvander@1162
   115
	ReplyToCommand(client, "[SM] %t", "Admin cache refreshed");
teame06@1211
   116
dvander@1162
   117
	return Plugin_Handled;
dvander@1162
   118
}
dvander@1162
   119
dvander@923
   120
#define FLAG_STRINGS		14
dvander@923
   121
new String:g_FlagNames[FLAG_STRINGS][20] =
dvander@923
   122
{
dvander@1376
   123
	"res",
dvander@923
   124
	"admin",
dvander@923
   125
	"kick",
dvander@923
   126
	"ban",
dvander@923
   127
	"unban",
dvander@923
   128
	"slay",
dvander@923
   129
	"map",
dvander@923
   130
	"cvars",
dvander@923
   131
	"cfg",
dvander@923
   132
	"chat",
dvander@923
   133
	"vote",
dvander@923
   134
	"pass",
dvander@923
   135
	"rcon",
dvander@923
   136
	"cheat"
dvander@923
   137
};
dvander@923
   138
dvander@1376
   139
CustomFlagsToString(String:buffer[], maxlength, flags)
dvander@1376
   140
{
dvander@1376
   141
	decl String:joins[6][6];
dvander@1376
   142
	new total;
dvander@1376
   143
	
dvander@1376
   144
	for (new i=_:Admin_Custom1; i<=_:Admin_Custom6; i++)
dvander@1376
   145
	{
dvander@1376
   146
		if (flags & (1<<i))
dvander@1376
   147
		{
dvander@1376
   148
			IntToString(i - _:Admin_Custom1 + 1, joins[total++], 6);
dvander@1376
   149
		}
dvander@1376
   150
	}
dvander@1376
   151
	
dvander@1376
   152
	ImplodeStrings(joins, total, ",", buffer, maxlength);
dvander@1376
   153
	
dvander@1376
   154
	return total;
dvander@1376
   155
}
dvander@1376
   156
dvander@923
   157
FlagsToString(String:buffer[], maxlength, flags)
dvander@923
   158
{
dvander@1376
   159
	decl String:joins[FLAG_STRINGS+1][32];
dvander@923
   160
	new total;
teame06@1211
   161
dvander@923
   162
	for (new i=0; i<FLAG_STRINGS; i++)
dvander@923
   163
	{
dvander@923
   164
		if (flags & (1<<i))
dvander@923
   165
		{
dvander@1376
   166
			strcopy(joins[total++], 32, g_FlagNames[i]);
dvander@923
   167
		}
dvander@923
   168
	}
dvander@1376
   169
	
dvander@1376
   170
	decl String:custom_flags[32];
dvander@1376
   171
	if (CustomFlagsToString(custom_flags, sizeof(custom_flags), flags))
dvander@1376
   172
	{
dvander@1376
   173
		Format(joins[total++], 32, "custom(%s)", custom_flags);
dvander@1376
   174
	}
teame06@1211
   175
dvander@923
   176
	ImplodeStrings(joins, total, ", ", buffer, maxlength);
dvander@923
   177
}
dvander@923
   178
dvander@923
   179
public Action:Command_Who(client, args)
dvander@923
   180
{
dvander@923
   181
	if (args < 1)
dvander@923
   182
	{
dvander@923
   183
		/* Display header */
faluco@1118
   184
		decl String:t_access[16], String:t_name[16];
dvander@923
   185
		Format(t_access, sizeof(t_access), "%t", "Access", client);
dvander@923
   186
		Format(t_name, sizeof(t_name), "%t", "Name", client);
teame06@1211
   187
dvander@923
   188
		PrintToConsole(client, "%-24.23s %s", t_name, t_access);
teame06@1211
   189
dvander@923
   190
		/* List all players */
dvander@923
   191
		new maxClients = GetMaxClients();
faluco@1118
   192
		decl String:flagstring[255];
teame06@1211
   193
dvander@923
   194
		for (new i=1; i<=maxClients; i++)
dvander@923
   195
		{
dvander@923
   196
			if (!IsClientInGame(i))
dvander@923
   197
			{
dvander@923
   198
				continue;
dvander@923
   199
			}
dvander@923
   200
			new flags = GetUserFlagBits(i);
dvander@923
   201
			if (flags == 0)
dvander@923
   202
			{
dvander@923
   203
				strcopy(flagstring, sizeof(flagstring), "none");
dvander@923
   204
			} else if (flags & ADMFLAG_ROOT) {
dvander@923
   205
				strcopy(flagstring, sizeof(flagstring), "root");
dvander@923
   206
			} else {
dvander@923
   207
				FlagsToString(flagstring, sizeof(flagstring), flags);
dvander@923
   208
			}
dvander@923
   209
			decl String:name[65];
dvander@923
   210
			GetClientName(i, name, sizeof(name));
dvander@923
   211
			PrintToConsole(client, "%d. %-24.23s %s", i, name, flagstring);
dvander@923
   212
		}
teame06@1211
   213
dvander@923
   214
		if (GetCmdReplySource() == SM_REPLY_TO_CHAT)
dvander@923
   215
		{
dvander@923
   216
			ReplyToCommand(client, "[SM] %t", "See console for output");
dvander@923
   217
		}
teame06@1211
   218
dvander@923
   219
		return Plugin_Handled;
dvander@923
   220
	}
teame06@1211
   221
faluco@1118
   222
	decl String:arg[65];
dvander@923
   223
	GetCmdArg(1, arg, sizeof(arg));
teame06@1211
   224
dvander@923
   225
	new clients[2];
dvander@923
   226
	new numClients = SearchForClients(arg, clients, 2);
teame06@1211
   227
dvander@923
   228
	if (numClients == 0)
dvander@923
   229
	{
dvander@923
   230
		ReplyToCommand(client, "[SM] %t", "No matching client");
dvander@923
   231
		return Plugin_Handled;
dvander@923
   232
	} else if (numClients > 1) {
dvander@923
   233
		ReplyToCommand(client, "[SM] %t", "More than one client matches", arg);
dvander@923
   234
		return Plugin_Handled;
dvander@923
   235
	}
teame06@1211
   236
dvander@923
   237
	new flags = GetUserFlagBits(clients[0]);
faluco@1118
   238
	decl String:flagstring[255];
dvander@923
   239
	if (flags == 0)
dvander@923
   240
	{
dvander@923
   241
		strcopy(flagstring, sizeof(flagstring), "none");
dvander@923
   242
	} else if (flags & ADMFLAG_ROOT) {
dvander@923
   243
		strcopy(flagstring, sizeof(flagstring), "root");
dvander@923
   244
	} else {
dvander@923
   245
		FlagsToString(flagstring, sizeof(flagstring), flags);
dvander@923
   246
	}
teame06@1211
   247
dvander@923
   248
	ReplyToCommand(client, "[SM] %t: %s", "Access", flagstring);
teame06@1211
   249
dvander@923
   250
	return Plugin_Handled;
dvander@921
   251
}
dvander@921
   252
dvander@921
   253
public Action:Command_ExecCfg(client, args)
dvander@921
   254
{
dvander@921
   255
	if (args < 1)
dvander@921
   256
	{
dvander@921
   257
		ReplyToCommand(client, "[SM] Usage: sm_execcfg <filename>");
dvander@921
   258
		return Plugin_Handled;
dvander@921
   259
	}
teame06@1211
   260
dvander@921
   261
	new String:path[64] = "cfg/";
dvander@921
   262
	GetCmdArg(1, path[4], sizeof(path)-4);
teame06@1211
   263
dvander@921
   264
	if (!FileExists(path))
dvander@921
   265
	{
dvander@921
   266
		ReplyToCommand(client, "[SM] %t", "Config not found", path[4]);
dvander@921
   267
		return Plugin_Handled;
dvander@921
   268
	}
teame06@1211
   269
dvander@924
   270
	ShowActivity(client, "%t", "Executed config", path[4]);
teame06@1211
   271
dvander@1378
   272
	LogAction(client, -1, "\"%L\" executed config (file \"%s\")", client, path[4]);
teame06@1211
   273
dvander@921
   274
	ServerCommand("exec \"%s\"", path[4]);
teame06@1211
   275
dvander@921
   276
	return Plugin_Handled;
dvander@920
   277
}
dvander@920
   278
dvander@920
   279
public Action:Command_Cvar(client, args)
dvander@920
   280
{
dvander@920
   281
	if (args < 1)
dvander@920
   282
	{
dvander@920
   283
		ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar> [value]");
dvander@920
   284
		return Plugin_Handled;
dvander@920
   285
	}
teame06@1211
   286
faluco@1118
   287
	decl String:cvarname[33];
dvander@920
   288
	GetCmdArg(1, cvarname, sizeof(cvarname));
teame06@1211
   289
dvander@920
   290
	new Handle:hndl = FindConVar(cvarname);
dvander@920
   291
	if (hndl == INVALID_HANDLE)
dvander@920
   292
	{
dvander@920
   293
		ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname);
dvander@920
   294
		return Plugin_Handled;
dvander@920
   295
	}
teame06@1211
   296
dvander@920
   297
	new bool:allowed = false;
dvander@920
   298
	if (GetConVarFlags(hndl) & FCVAR_PROTECTED)
dvander@920
   299
	{
dvander@920
   300
		/* If they're root, allow anything */
dvander@920
   301
		if ((GetUserFlagBits(client) & ADMFLAG_ROOT) == ADMFLAG_ROOT)
dvander@920
   302
		{
dvander@920
   303
			allowed = true;
dvander@920
   304
		}
dvander@920
   305
		/* If they're not root, and getting sv_password, see if they have ADMFLAG_PASSWORD */
dvander@920
   306
		else if (StrEqual(cvarname, "sv_password") && (GetUserFlagBits(client) & ADMFLAG_PASSWORD))
dvander@920
   307
		{
dvander@920
   308
			allowed = true;
dvander@920
   309
		}
teame06@1211
   310
	}
dvander@920
   311
	/* Do a check for the cheat cvar */
dvander@920
   312
	else if (StrEqual(cvarname, "sv_cheats"))
dvander@920
   313
	{
dvander@929
   314
		if (GetUserFlagBits(client) & ADMFLAG_CHEATS
dvander@929
   315
			|| GetUserFlagBits(client) & ADMFLAG_ROOT)
dvander@920
   316
		{
dvander@920
   317
			allowed = true;
dvander@920
   318
		}
dvander@920
   319
	}
dvander@920
   320
	/* If we drop down to here, it was a normal cvar. */
dvander@920
   321
	else
dvander@920
   322
	{
dvander@920
   323
		allowed = true;
dvander@920
   324
	}
teame06@1211
   325
dvander@920
   326
	if (!allowed)
dvander@920
   327
	{
dvander@920
   328
		ReplyToCommand(client, "[SM] %t", "No access to cvar");
dvander@920
   329
		return Plugin_Handled;
dvander@920
   330
	}
teame06@1211
   331
dvander@920
   332
	decl String:value[255];
dvander@920
   333
	if (args < 2)
dvander@920
   334
	{
dvander@920
   335
		GetConVarString(hndl, value, sizeof(value));
teame06@1211
   336
dvander@920
   337
		ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value);
dvander@920
   338
		return Plugin_Handled;
dvander@920
   339
	}
teame06@1211
   340
dvander@920
   341
	GetCmdArg(2, value, sizeof(value));
teame06@1211
   342
dvander@920
   343
	if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED)
dvander@920
   344
	{
dvander@920
   345
		ShowActivity(client, "%t", "Cvar changed", cvarname, value);
dvander@924
   346
	} else {
dvander@924
   347
		ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
dvander@920
   348
	}
teame06@1211
   349
dvander@1378
   350
	LogAction(client, -1, "\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
teame06@1211
   351
ds@937
   352
	SetConVarString(hndl, value, true);
teame06@1211
   353
dvander@920
   354
	return Plugin_Handled;
dvander@918
   355
}
dvander@918
   356
dvander@918
   357
public Action:Command_Rcon(client, args)
dvander@918
   358
{
dvander@918
   359
	if (args < 1)
dvander@918
   360
	{
dvander@918
   361
		ReplyToCommand(client, "[SM] Usage: sm_rcon <args>");
dvander@918
   362
		return Plugin_Handled;
dvander@918
   363
	}
teame06@1211
   364
dvander@918
   365
	decl String:argstring[255];
dvander@918
   366
	GetCmdArgString(argstring, sizeof(argstring));
teame06@1211
   367
dvander@1378
   368
	LogAction(client, -1, "\"%L\" console command (cmdline \"%s\")", client, argstring);
teame06@1211
   369
dvander@918
   370
	ServerCommand("%s", argstring);
teame06@1211
   371
dvander@918
   372
	return Plugin_Handled;
dvander@917
   373
}
dvander@917
   374
dvander@917
   375
public Action:Command_Map(client, args)
dvander@917
   376
{
dvander@917
   377
	if (args < 1)
dvander@917
   378
	{
dvander@917
   379
		ReplyToCommand(client, "[SM] Usage: sm_map <map>");
dvander@917
   380
		return Plugin_Handled;
dvander@917
   381
	}
teame06@1211
   382
faluco@1118
   383
	decl String:map[64];
dvander@917
   384
	GetCmdArg(1, map, sizeof(map));
teame06@1211
   385
dvander@917
   386
	if (!IsMapValid(map))
dvander@917
   387
	{
dvander@917
   388
		ReplyToCommand(client, "[SM] %t", "Map was not found", map);
dvander@917
   389
		return Plugin_Handled;
dvander@917
   390
	}
teame06@1211
   391
dvander@924
   392
	ShowActivity(client, "%t", "Changing map", map);
teame06@1211
   393
dvander@1378
   394
	LogAction(client, -1, "\"%L\" changed map to \"%s\"", client, map);
teame06@1211
   395
dvander@918
   396
	new Handle:dp;
dvander@917
   397
	CreateDataTimer(3.0, Timer_ChangeMap, dp);
dvander@917
   398
	WritePackString(dp, map);
teame06@1211
   399
dvander@917
   400
	return Plugin_Handled;
dvander@917
   401
}
dvander@917
   402
dvander@917
   403
public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
dvander@917
   404
{
faluco@1118
   405
	decl String:map[65];
teame06@1211
   406
dvander@917
   407
	ResetPack(dp);
dvander@917
   408
	ReadPackString(dp, map, sizeof(map));
teame06@1211
   409
dvander@917
   410
	ServerCommand("changelevel \"%s\"", map);
teame06@1211
   411
dvander@917
   412
	return Plugin_Stop;
dvander@910
   413
}
dvander@910
   414
ferret99gt@1276
   415
public Action:Command_CancelVote(client, args)
ferret99gt@1276
   416
{
ferret99gt@1278
   417
	if (!IsVoteInProgress())
ferret99gt@1276
   418
	{
ferret99gt@1276
   419
		ReplyToCommand(client, "[SM] %t", "Vote Not In Progress");
ferret99gt@1276
   420
		return Plugin_Handled;
ferret99gt@1276
   421
	}
ferret99gt@1276
   422
ferret99gt@1276
   423
	ShowActivity(client, "%t", "Cancelled Vote");
ferret99gt@1276
   424
	
ferret99gt@1276
   425
	CancelVote();
ferret99gt@1276
   426
	
ferret99gt@1276
   427
	return Plugin_Handled;
dvander@1417
   428
}
dvander@1510
   429