plugins/basecommands.sp
author David Anderson <dvander@alliedmods.net>
Fri Jun 08 04:40:40 2007 +0000 (2007-06-08)
changeset 926 b42be6b5f221
parent 925 2cd3d817b5ab
child 927 a60cedac2a1a
permissions -rw-r--r--
added request amb369, part 1
     1 /**
     2  * basecommands.sp
     3  * Implements basic admin commands.
     4  * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
     5  *
     6  * This program is free software; you can redistribute it and/or
     7  * modify it under the terms of the GNU General Public License
     8  * as published by the Free Software Foundation; either version 2
     9  * of the License, or (at your option) any later version.
    10  *
    11  * This program is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  * 
    16  * You should have received a copy of the GNU General Public License
    17  * along with this program; if not, write to the Free Software
    18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    19  *
    20  * Version: $Id$
    21  */
    22 
    23 #include <sourcemod>
    24 
    25 #pragma semicolon 1
    26 
    27 public Plugin:myinfo = 
    28 {
    29 	name = "Basic Commands",
    30 	author = "AlliedModders LLC",
    31 	description = "Basic Admin Commands",
    32 	version = SOURCEMOD_VERSION,
    33 	url = "http://www.sourcemod.net/"
    34 };
    35 
    36 new Handle:hBanForward = INVALID_HANDLE;
    37 
    38 public OnPluginStart()
    39 {
    40 	LoadTranslations("common.cfg");
    41 	LoadTranslations("plugin.basecommands.cfg");
    42 	RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]");
    43 	RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map <map>");
    44 	RegAdminCmd("sm_rcon", Command_Rcon, ADMFLAG_RCON, "sm_rcon <args>");
    45 	RegAdminCmd("sm_cvar", Command_Cvar, ADMFLAG_CONVARS, "sm_cvar <cvar> [value]");
    46 	RegAdminCmd("sm_execcfg", Command_ExecCfg, ADMFLAG_CONFIG, "sm_execcfg <filename>");
    47 	RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]");
    48 	RegAdminCmd("sm_ban", Command_Ban, ADMFLAG_BAN, "sm_ban <#userid|name> <minutes|0> [reason]");
    49 	RegAdminCmd("sm_unban", Command_Unban, ADMFLAG_UNBAN, "sm_unban <steamid>");
    50 	
    51 	hBanForward = CreateGlobalForward("OnClientBanned", ET_Ignore, Param_Cell, Param_Cell, Param_String);
    52 }
    53 
    54 public Action:Command_Unban(client, args)
    55 {
    56 	if (args < 1)
    57 	{
    58 		ReplyToCommand(client, "[SM] Usage: sm_unban <steamid>");
    59 		return Plugin_Handled;
    60 	}
    61 	
    62 	new String:arg[50], start=0;
    63 	GetCmdArgString(arg, sizeof(arg));
    64 	
    65 	if (strncmp(arg, "STEAM_0:", 8) == 0)
    66 	{
    67 		start = 8;
    68 	} else if (strncmp(arg, "0:1:", 4) == 0 || strncmp(arg, "0:0:", 4) == 0)
    69 	{
    70 		start = 2;
    71 	}
    72 	
    73 	LogMessage("\"%L\" removed ban (filter \"%s\")", arg[start]);
    74 	ServerCommand("removeid \"%s\"", arg[start]);
    75 	ReplyToCommand(client, "[SM] %t", "Removed bans matching", arg);
    76 	
    77 	return Plugin_Handled;
    78 }
    79 
    80 public Action:Command_Ban(client, args)
    81 {
    82 	if (args < 2)
    83 	{
    84 		ReplyToCommand(client, "[SM] Usage: sm_ban <#userid|name> <minutes|0> [reason]");
    85 		return Plugin_Handled;
    86 	}
    87 	
    88 	new String:arg[65];
    89 	GetCmdArg(1, arg, sizeof(arg));
    90 	
    91 	new clients[2];
    92 	new numClients = SearchForClients(arg, clients, 2);
    93 	
    94 	if (numClients == 0)
    95 	{
    96 		ReplyToCommand(client, "[SM] %t", "No matching client");
    97 		return Plugin_Handled;
    98 	} else if (numClients > 1) {
    99 		ReplyToCommand(client, "[SM] %t", "More than one client matches", arg);
   100 		return Plugin_Handled;
   101 	} else if (!CanUserTarget(client, clients[0])) {
   102 		ReplyToCommand(client, "[SM] %t", "Unable to target");
   103 		return Plugin_Handled;
   104 	} else if (IsFakeClient(clients[0])) {
   105 		ReplyToCommand(client, "[SM] %t", "Cannot target bot");
   106 		return Plugin_Handled;
   107 	}
   108 	
   109 	new String:s_time[12];
   110 	GetCmdArg(2, s_time, sizeof(s_time));
   111 	
   112 	new time = StringToInt(s_time);
   113 	
   114 	decl String:reason[128];
   115 	if (args >= 3)
   116 	{
   117 		GetCmdArg(3, reason, sizeof(reason));
   118 	} else {
   119 		reason[0] = '\0';
   120 	}
   121 	
   122 	new userid = GetClientUserId(clients[0]);
   123 	GetClientName(clients[0], arg, sizeof(arg));
   124 	
   125 	if (time)
   126 	{
   127 		if (reason[0] == '\0')
   128 		{
   129 			ShowActivity(client, "%t", "Permabanned player", arg);
   130 		} else {
   131 			ShowActivity(client, "%t", "Permabanned player reason", arg, reason);
   132 		}
   133 	} else {
   134 		if (reason[0] == '\0')
   135 		{
   136 			ShowActivity(client, "%t", "Banned player", arg, time);
   137 		} else {
   138 			ShowActivity(client, "%t", "Banned player reason", arg, time, reason);
   139 		}
   140 	}
   141 	
   142 	LogMessage("\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, clients[0], time, reason);
   143 	
   144 	/* Fire the ban forward */
   145 	Call_StartForward(hBanForward);
   146 	Call_PushCell(client);
   147 	Call_PushCell(clients[0]);
   148 	Call_PushString(reason);
   149 	Call_Finish();
   150 
   151 	if (reason[0] == '\0')
   152 	{
   153 		strcopy(reason, sizeof(reason), "Banned");
   154 	}
   155 	
   156 	ServerCommand("banid %d %d", time, userid);
   157 	ServerCommand("kickid %d \"%s\"", userid, reason);
   158 	
   159 	if (time == 0)
   160 	{
   161 		ServerCommand("writeid");
   162 	}
   163 	
   164 	return Plugin_Handled;
   165 }
   166 
   167 #define FLAG_STRINGS		14
   168 new String:g_FlagNames[FLAG_STRINGS][20] =
   169 {
   170 	"reservation",
   171 	"admin",
   172 	"kick",
   173 	"ban",
   174 	"unban",
   175 	"slay",
   176 	"map",
   177 	"cvars",
   178 	"cfg",
   179 	"chat",
   180 	"vote",
   181 	"pass",
   182 	"rcon",
   183 	"cheat"
   184 };
   185 
   186 FlagsToString(String:buffer[], maxlength, flags)
   187 {
   188 	new String:joins[FLAG_STRINGS][20];
   189 	new total;
   190 	
   191 	for (new i=0; i<FLAG_STRINGS; i++)
   192 	{
   193 		if (flags & (1<<i))
   194 		{
   195 			strcopy(joins[total++], 20, g_FlagNames[i]);
   196 		}
   197 	}
   198 	
   199 	ImplodeStrings(joins, total, ", ", buffer, maxlength);
   200 }
   201 
   202 public Action:Command_Who(client, args)
   203 {
   204 	if (args < 1)
   205 	{
   206 		/* Display header */
   207 		new String:t_access[16], String:t_name[16];
   208 		Format(t_access, sizeof(t_access), "%t", "Access", client);
   209 		Format(t_name, sizeof(t_name), "%t", "Name", client);
   210 		
   211 		PrintToConsole(client, "%-24.23s %s", t_name, t_access);
   212 		
   213 		/* List all players */
   214 		new maxClients = GetMaxClients();
   215 		new String:flagstring[255];
   216 				
   217 		for (new i=1; i<=maxClients; i++)
   218 		{
   219 			if (!IsClientInGame(i))
   220 			{
   221 				continue;
   222 			}
   223 			new flags = GetUserFlagBits(i);
   224 			if (flags == 0)
   225 			{
   226 				strcopy(flagstring, sizeof(flagstring), "none");
   227 			} else if (flags & ADMFLAG_ROOT) {
   228 				strcopy(flagstring, sizeof(flagstring), "root");
   229 			} else {
   230 				FlagsToString(flagstring, sizeof(flagstring), flags);
   231 			}
   232 			decl String:name[65];
   233 			GetClientName(i, name, sizeof(name));
   234 			PrintToConsole(client, "%d. %-24.23s %s", i, name, flagstring);
   235 		}
   236 		
   237 		if (GetCmdReplySource() == SM_REPLY_TO_CHAT)
   238 		{
   239 			ReplyToCommand(client, "[SM] %t", "See console for output");
   240 		}
   241 		
   242 		return Plugin_Handled;
   243 	}
   244 	
   245 	new String:arg[65];
   246 	GetCmdArg(1, arg, sizeof(arg));
   247 	
   248 	new clients[2];
   249 	new numClients = SearchForClients(arg, clients, 2);
   250 	
   251 	if (numClients == 0)
   252 	{
   253 		ReplyToCommand(client, "[SM] %t", "No matching client");
   254 		return Plugin_Handled;
   255 	} else if (numClients > 1) {
   256 		ReplyToCommand(client, "[SM] %t", "More than one client matches", arg);
   257 		return Plugin_Handled;
   258 	}
   259 	
   260 	new flags = GetUserFlagBits(clients[0]);
   261 	new String:flagstring[255];
   262 	if (flags == 0)
   263 	{
   264 		strcopy(flagstring, sizeof(flagstring), "none");
   265 	} else if (flags & ADMFLAG_ROOT) {
   266 		strcopy(flagstring, sizeof(flagstring), "root");
   267 	} else {
   268 		FlagsToString(flagstring, sizeof(flagstring), flags);
   269 	}
   270 	
   271 	ReplyToCommand(client, "[SM] %t: %s", "Access", flagstring);
   272 	
   273 	return Plugin_Handled;
   274 }
   275 
   276 public Action:Command_ExecCfg(client, args)
   277 {
   278 	if (args < 1)
   279 	{
   280 		ReplyToCommand(client, "[SM] Usage: sm_execcfg <filename>");
   281 		return Plugin_Handled;
   282 	}
   283 	
   284 	new String:path[64] = "cfg/";
   285 	GetCmdArg(1, path[4], sizeof(path)-4);
   286 	
   287 	if (!FileExists(path))
   288 	{
   289 		ReplyToCommand(client, "[SM] %t", "Config not found", path[4]);
   290 		return Plugin_Handled;
   291 	}
   292 	
   293 	ShowActivity(client, "%t", "Executed config", path[4]);
   294 	
   295 	LogMessage("\"%L\" executed config (file \"%s\")", client, path[4]);
   296 		
   297 	ServerCommand("exec \"%s\"", path[4]);
   298 	
   299 	return Plugin_Handled;
   300 }
   301 
   302 public Action:Command_Cvar(client, args)
   303 {
   304 	if (args < 1)
   305 	{
   306 		ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar> [value]");
   307 		return Plugin_Handled;
   308 	}
   309 	
   310 	new String:cvarname[33];
   311 	GetCmdArg(1, cvarname, sizeof(cvarname));
   312 	
   313 	new Handle:hndl = FindConVar(cvarname);
   314 	if (hndl == INVALID_HANDLE)
   315 	{
   316 		ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname);
   317 		return Plugin_Handled;
   318 	}
   319 	
   320 	new bool:allowed = false;
   321 	if (GetConVarFlags(hndl) & FCVAR_PROTECTED)
   322 	{
   323 		/* If they're root, allow anything */
   324 		if ((GetUserFlagBits(client) & ADMFLAG_ROOT) == ADMFLAG_ROOT)
   325 		{
   326 			allowed = true;
   327 		}
   328 		/* If they're not root, and getting sv_password, see if they have ADMFLAG_PASSWORD */
   329 		else if (StrEqual(cvarname, "sv_password") && (GetUserFlagBits(client) & ADMFLAG_PASSWORD))
   330 		{
   331 			allowed = true;
   332 		}
   333 	} 
   334 	/* Do a check for the cheat cvar */
   335 	else if (StrEqual(cvarname, "sv_cheats"))
   336 	{
   337 		if (GetUserFlagBits(client) & ADMFLAG_CHEATS)
   338 		{
   339 			allowed = true;
   340 		}
   341 	}
   342 	/* If we drop down to here, it was a normal cvar. */
   343 	else
   344 	{
   345 		allowed = true;
   346 	}
   347 	
   348 	if (!allowed)
   349 	{
   350 		ReplyToCommand(client, "[SM] %t", "No access to cvar");
   351 		return Plugin_Handled;
   352 	}
   353 	
   354 	decl String:value[255];
   355 	if (args < 2)
   356 	{
   357 		GetConVarString(hndl, value, sizeof(value));
   358 		
   359 		ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value);
   360 		return Plugin_Handled;
   361 	}
   362 	
   363 	GetCmdArg(2, value, sizeof(value));
   364 	
   365 	if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED)
   366 	{
   367 		ShowActivity(client, "%t", "Cvar changed", cvarname, value);
   368 	} else {
   369 		ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
   370 	}
   371 	
   372 	LogMessage("\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
   373 	
   374 	SetConVarString(hndl, value);
   375 		
   376 	return Plugin_Handled;
   377 }
   378 
   379 public Action:Command_Rcon(client, args)
   380 {
   381 	if (args < 1)
   382 	{
   383 		ReplyToCommand(client, "[SM] Usage: sm_rcon <args>");
   384 		return Plugin_Handled;
   385 	}
   386 	
   387 	decl String:argstring[255];
   388 	GetCmdArgString(argstring, sizeof(argstring));
   389 	
   390 	LogMessage("\"%L\" console command (cmdline \"%s\")", client, argstring);
   391 	
   392 	ServerCommand("%s", argstring);
   393 	
   394 	return Plugin_Handled;
   395 }
   396 
   397 public Action:Command_Map(client, args)
   398 {
   399 	if (args < 1)
   400 	{
   401 		ReplyToCommand(client, "[SM] Usage: sm_map <map>");
   402 		return Plugin_Handled;
   403 	}
   404 	
   405 	new String:map[64];
   406 	GetCmdArg(1, map, sizeof(map));
   407 	
   408 	if (!IsMapValid(map))
   409 	{
   410 		ReplyToCommand(client, "[SM] %t", "Map was not found", map);
   411 		return Plugin_Handled;
   412 	}
   413 	
   414 	ShowActivity(client, "%t", "Changing map", map);
   415 	
   416 	LogMessage("\"%L\" changed map to \"%s\"", client, map);
   417 	
   418 	new Handle:dp;
   419 	CreateDataTimer(3.0, Timer_ChangeMap, dp);
   420 	WritePackString(dp, map);
   421 	
   422 	return Plugin_Handled;
   423 }
   424 
   425 public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
   426 {
   427 	new String:map[65];
   428 	
   429 	ResetPack(dp);
   430 	ReadPackString(dp, map, sizeof(map));
   431 	
   432 	ServerCommand("changelevel \"%s\"", map);
   433 	
   434 	return Plugin_Stop;
   435 }
   436 
   437 public Action:Command_Kick(client, args)
   438 {
   439 	if (args < 1)
   440 	{
   441 		ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]");
   442 		return Plugin_Handled;
   443 	}
   444 	
   445 	new String:arg[65];
   446 	GetCmdArg(1, arg, sizeof(arg));
   447 	
   448 	new clients[2];
   449 	new numClients = SearchForClients(arg, clients, 2);
   450 	
   451 	if (numClients == 0)
   452 	{
   453 		ReplyToCommand(client, "[SM] %t", "No matching client");
   454 		return Plugin_Handled;
   455 	} else if (numClients > 1) {
   456 		ReplyToCommand(client, "[SM] %t", "More than one client matches", arg);
   457 		return Plugin_Handled;
   458 	} else if (!CanUserTarget(client, clients[0])) {
   459 		ReplyToCommand(client, "[SM] %t", "Unable to target");
   460 		return Plugin_Handled;
   461 	}
   462 	
   463 	new userid = GetClientUserId(clients[0]);
   464 	new String:name[65];
   465 	
   466 	GetClientName(clients[0], name, sizeof(name));
   467 	
   468 	decl String:reason[256];
   469 	if (args < 2)
   470 	{
   471 		/* Safely null terminate */
   472 		reason[0] = '\0';
   473 	} else {
   474 		GetCmdArg(2, reason, sizeof(reason));
   475 	}
   476 	
   477 	ShowActivity(client, "%t", "Kicked player", name);
   478 	
   479 	LogMessage("\"%L\" kicked \"%L\" (reason \"%s\")", client, clients[0], reason);
   480 	
   481 	if (args < 2)
   482 	{
   483 		ServerCommand("kickid %d", userid);
   484 	} else {
   485 		ServerCommand("kickid %d \"%s\"", userid, reason);
   486 	}
   487 	
   488 	return Plugin_Handled;
   489 }