plugins/basecommands.sp
author Phong Dang <teame06@gmail.com>
Sun Jul 29 00:26:18 2007 +0000 (2007-07-29)
changeset 1200 623603b49096
parent 1197 d8e2d3c4643b
child 1211 990912ee1e1e
permissions -rw-r--r--
Fixed AskPluginLoad would still allowed plugin to load even if it returned false.
     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 #pragma semicolon 1
    24 
    25 #include <sourcemod>
    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 new Handle:hAddBanForward = INVALID_HANDLE;
    38 new Handle:hBanRemoved = INVALID_HANDLE;
    39 
    40 public OnPluginStart()
    41 {
    42 	LoadTranslations("common.phrases");
    43 	
    44 	RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]");
    45 	RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map <map>");
    46 	RegAdminCmd("sm_rcon", Command_Rcon, ADMFLAG_RCON, "sm_rcon <args>");
    47 	RegAdminCmd("sm_cvar", Command_Cvar, ADMFLAG_CONVARS, "sm_cvar <cvar> [value]");
    48 	RegAdminCmd("sm_execcfg", Command_ExecCfg, ADMFLAG_CONFIG, "sm_execcfg <filename>");
    49 	RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]");
    50 	RegAdminCmd("sm_ban", Command_Ban, ADMFLAG_BAN, "sm_ban <#userid|name> <minutes|0> [reason]");
    51 	RegAdminCmd("sm_unban", Command_Unban, ADMFLAG_UNBAN, "sm_unban <steamid>");
    52 	RegAdminCmd("sm_addban", Command_AddBan, ADMFLAG_RCON, "sm_addban <time> <steamid> [reason]");
    53 	RegAdminCmd("sm_banip", Command_BanIp, ADMFLAG_RCON, "sm_banip <time> <ip> [reason]");
    54 	RegAdminCmd("sm_reloadadmins", Command_ReloadAdmins, ADMFLAG_BAN, "sm_reloadadmins");
    55 	
    56 	hBanForward = CreateGlobalForward("OnClientBanned", ET_Hook, Param_Cell, Param_Cell, Param_Cell, Param_String);
    57 	hAddBanForward = CreateGlobalForward("OnBanAdded", ET_Hook, Param_Cell, Param_String, Param_Cell, Param_String);
    58 	hBanRemoved = CreateGlobalForward("OnBanRemoved", ET_Hook, Param_Cell, Param_String);
    59 }
    60 
    61 public Action:Command_ReloadAdmins(client, args)
    62 {
    63 	/* Dump it all! */
    64 	DumpAdminCache(AdminCache_Groups, true);
    65 	DumpAdminCache(AdminCache_Overrides, true);
    66 	
    67 	LogMessage("\"%L\" refreshed the admin cache.", client);
    68 	ReplyToCommand(client, "[SM] %t", "Admin cache refreshed");
    69 	
    70 	return Plugin_Handled;
    71 }
    72 
    73 public Action:Command_BanIp(client, args)
    74 {
    75 	if (args < 2)
    76 	{
    77 		ReplyToCommand(client, "[SM] Usage: sm_banip <time> <ip> [reason]");
    78 		return Plugin_Handled;
    79 	}
    80 	
    81 	decl String:arg[50], String:time[20];
    82 	GetCmdArg(1, time, sizeof(time));
    83 	GetCmdArg(2, arg, sizeof(arg));
    84 	
    85 	new minutes = StringToInt(time);
    86 	
    87 	decl String:reason[128];
    88 	if (args >= 3)
    89 	{
    90 		GetCmdArg(3, reason, sizeof(reason));
    91 	}
    92 	
    93 	new Action:act = Plugin_Continue;
    94 	Call_StartForward(hAddBanForward);
    95 	Call_PushCell(client);
    96 	Call_PushString(arg);
    97 	Call_PushCell(minutes);
    98 	Call_PushString(reason);
    99 	Call_Finish(act);
   100 	
   101 	if (act < Plugin_Handled)
   102 	{
   103 		LogMessage("\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")", client, minutes, arg, reason);
   104 		ReplyToCommand(client, "[SM] %t", "Ban added");
   105 	}
   106 	
   107 	if (act < Plugin_Stop)
   108 	{
   109 		ServerCommand("banip %d %s", minutes, arg);
   110 		ServerCommand("writeip");
   111 	}
   112 	
   113 	return Plugin_Handled;
   114 }
   115 
   116 public Action:Command_AddBan(client, args)
   117 {
   118 	if (args < 2)
   119 	{
   120 		ReplyToCommand(client, "[SM] Usage: sm_addban <time> <steamid> [reason]");
   121 		return Plugin_Handled;
   122 	}
   123 	
   124 	decl String:arg[50], String:time[20];
   125 	GetCmdArg(1, time, sizeof(time));
   126 	GetCmdArg(2, arg, sizeof(arg));
   127 	
   128 	new minutes = StringToInt(time);
   129 	
   130 	decl String:reason[128];
   131 	if (args >= 3)
   132 	{
   133 		GetCmdArg(3, reason, sizeof(reason));
   134 	}
   135 	
   136 	new Action:act = Plugin_Continue;
   137 	Call_StartForward(hAddBanForward);
   138 	Call_PushCell(client);
   139 	Call_PushString(arg);
   140 	Call_PushCell(minutes);
   141 	Call_PushString(reason);
   142 	Call_Finish(act);
   143 	
   144 	if (act < Plugin_Handled)
   145 	{
   146 		LogMessage("\"%L\" added ban (minutes \"%d\") (id \"%s\") (reason \"%s\")", client, minutes, arg, reason);
   147 		ReplyToCommand(client, "[SM] %t", "Ban added");
   148 	}
   149 	
   150 	if (act < Plugin_Stop)
   151 	{
   152 		ServerCommand("banid %d %s", minutes, arg);
   153 		ServerCommand("writeid");
   154 	}
   155 	
   156 	return Plugin_Handled;
   157 }
   158 
   159 public Action:Command_Unban(client, args)
   160 {
   161 	if (args < 1)
   162 	{
   163 		ReplyToCommand(client, "[SM] Usage: sm_unban <steamid>");
   164 		return Plugin_Handled;
   165 	}
   166 	
   167 	decl String:arg[50];
   168 	new start=0;
   169 	decl String:new_arg[50];
   170 	GetCmdArgString(arg, sizeof(arg));
   171 	
   172 	if (strncmp(arg, "STEAM_0:", 8) == 0)
   173 	{
   174 		start = 8;
   175 	} else if (strncmp(arg, "0:1:", 4) == 0 || strncmp(arg, "0:0:", 4) == 0)
   176 	{
   177 		start = 2;
   178 	}
   179 	
   180 	Format(new_arg, sizeof(new_arg), "STEAM_0:%s", arg[start]);
   181 	
   182 	new Action:act = Plugin_Continue;
   183 	Call_StartForward(hBanRemoved);
   184 	Call_PushCell(client);
   185 	Call_PushString(new_arg);
   186 	Call_Finish(act);
   187 	
   188 	if (act < Plugin_Handled)
   189 	{
   190 		LogMessage("\"%L\" removed ban (filter \"%s\")", client, arg[start]);
   191 		ReplyToCommand(client, "[SM] %t", "Removed bans matching", arg);
   192 	}
   193 	
   194 	if (act < Plugin_Stop)
   195 	{
   196 		ServerCommand("removeid \"%s\"", arg[start]);
   197 		ServerCommand("writeid");
   198 	}
   199 	
   200 	return Plugin_Handled;
   201 }
   202 
   203 public Action:Command_Ban(client, args)
   204 {
   205 	if (args < 2)
   206 	{
   207 		ReplyToCommand(client, "[SM] Usage: sm_ban <#userid|name> <minutes|0> [reason]");
   208 		return Plugin_Handled;
   209 	}
   210 	
   211 	decl String:arg[65];
   212 	GetCmdArg(1, arg, sizeof(arg));
   213 	
   214 	new target = FindTarget(client, arg, true);
   215 	if (target == -1)
   216 	{
   217 		return Plugin_Handled;
   218 	}
   219 	
   220 	decl String:s_time[12];
   221 	GetCmdArg(2, s_time, sizeof(s_time));
   222 	
   223 	new time = StringToInt(s_time);
   224 	
   225 	decl String:reason[128];
   226 	if (args >= 3)
   227 	{
   228 		GetCmdArg(3, reason, sizeof(reason));
   229 	} else {
   230 		reason[0] = '\0';
   231 	}
   232 	
   233 	decl String:authid[64];
   234 	GetClientAuthString(target, authid, sizeof(authid));
   235 	GetClientName(target, arg, sizeof(arg));
   236 	
   237 	/* Fire the ban forward */
   238 	new Action:act = Plugin_Continue;
   239 	Call_StartForward(hBanForward);
   240 	Call_PushCell(client);
   241 	Call_PushCell(target);
   242 	Call_PushCell(time);
   243 	Call_PushString(reason);
   244 	Call_Finish(act);
   245 	
   246 	if (act < Plugin_Handled)
   247 	{
   248 		if (!time)
   249 		{
   250 			if (reason[0] == '\0')
   251 			{
   252 				ShowActivity(client, "%t", "Permabanned player", arg);
   253 			} else {
   254 				ShowActivity(client, "%t", "Permabanned player reason", arg, reason);
   255 			}
   256 		} else {
   257 			if (reason[0] == '\0')
   258 			{
   259 				ShowActivity(client, "%t", "Banned player", arg, time);
   260 			} else {
   261 				ShowActivity(client, "%t", "Banned player reason", arg, time, reason);
   262 			}
   263 		}
   264 		LogMessage("\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason);
   265 	}
   266 
   267 	if (act < Plugin_Stop)
   268 	{
   269 		if (reason[0] == '\0')
   270 		{
   271 			strcopy(reason, sizeof(reason), "Banned");
   272 		}
   273 		
   274 		ServerCommand("banid %d %s", time, authid);
   275 		KickClient(target, "%s", reason);
   276 		
   277 		if (time == 0)
   278 		{
   279 			ServerCommand("writeid");
   280 		}
   281 	}
   282 	
   283 	return Plugin_Handled;
   284 }
   285 
   286 #define FLAG_STRINGS		14
   287 new String:g_FlagNames[FLAG_STRINGS][20] =
   288 {
   289 	"reservation",
   290 	"admin",
   291 	"kick",
   292 	"ban",
   293 	"unban",
   294 	"slay",
   295 	"map",
   296 	"cvars",
   297 	"cfg",
   298 	"chat",
   299 	"vote",
   300 	"pass",
   301 	"rcon",
   302 	"cheat"
   303 };
   304 
   305 FlagsToString(String:buffer[], maxlength, flags)
   306 {
   307 	decl String:joins[FLAG_STRINGS][20];
   308 	new total;
   309 	
   310 	for (new i=0; i<FLAG_STRINGS; i++)
   311 	{
   312 		if (flags & (1<<i))
   313 		{
   314 			strcopy(joins[total++], 20, g_FlagNames[i]);
   315 		}
   316 	}
   317 	
   318 	ImplodeStrings(joins, total, ", ", buffer, maxlength);
   319 }
   320 
   321 public Action:Command_Who(client, args)
   322 {
   323 	if (args < 1)
   324 	{
   325 		/* Display header */
   326 		decl String:t_access[16], String:t_name[16];
   327 		Format(t_access, sizeof(t_access), "%t", "Access", client);
   328 		Format(t_name, sizeof(t_name), "%t", "Name", client);
   329 		
   330 		PrintToConsole(client, "%-24.23s %s", t_name, t_access);
   331 		
   332 		/* List all players */
   333 		new maxClients = GetMaxClients();
   334 		decl String:flagstring[255];
   335 				
   336 		for (new i=1; i<=maxClients; i++)
   337 		{
   338 			if (!IsClientInGame(i))
   339 			{
   340 				continue;
   341 			}
   342 			new flags = GetUserFlagBits(i);
   343 			if (flags == 0)
   344 			{
   345 				strcopy(flagstring, sizeof(flagstring), "none");
   346 			} else if (flags & ADMFLAG_ROOT) {
   347 				strcopy(flagstring, sizeof(flagstring), "root");
   348 			} else {
   349 				FlagsToString(flagstring, sizeof(flagstring), flags);
   350 			}
   351 			decl String:name[65];
   352 			GetClientName(i, name, sizeof(name));
   353 			PrintToConsole(client, "%d. %-24.23s %s", i, name, flagstring);
   354 		}
   355 		
   356 		if (GetCmdReplySource() == SM_REPLY_TO_CHAT)
   357 		{
   358 			ReplyToCommand(client, "[SM] %t", "See console for output");
   359 		}
   360 		
   361 		return Plugin_Handled;
   362 	}
   363 	
   364 	decl String:arg[65];
   365 	GetCmdArg(1, arg, sizeof(arg));
   366 	
   367 	new clients[2];
   368 	new numClients = SearchForClients(arg, clients, 2);
   369 	
   370 	if (numClients == 0)
   371 	{
   372 		ReplyToCommand(client, "[SM] %t", "No matching client");
   373 		return Plugin_Handled;
   374 	} else if (numClients > 1) {
   375 		ReplyToCommand(client, "[SM] %t", "More than one client matches", arg);
   376 		return Plugin_Handled;
   377 	}
   378 	
   379 	new flags = GetUserFlagBits(clients[0]);
   380 	decl String:flagstring[255];
   381 	if (flags == 0)
   382 	{
   383 		strcopy(flagstring, sizeof(flagstring), "none");
   384 	} else if (flags & ADMFLAG_ROOT) {
   385 		strcopy(flagstring, sizeof(flagstring), "root");
   386 	} else {
   387 		FlagsToString(flagstring, sizeof(flagstring), flags);
   388 	}
   389 	
   390 	ReplyToCommand(client, "[SM] %t: %s", "Access", flagstring);
   391 	
   392 	return Plugin_Handled;
   393 }
   394 
   395 public Action:Command_ExecCfg(client, args)
   396 {
   397 	if (args < 1)
   398 	{
   399 		ReplyToCommand(client, "[SM] Usage: sm_execcfg <filename>");
   400 		return Plugin_Handled;
   401 	}
   402 	
   403 	new String:path[64] = "cfg/";
   404 	GetCmdArg(1, path[4], sizeof(path)-4);
   405 	
   406 	if (!FileExists(path))
   407 	{
   408 		ReplyToCommand(client, "[SM] %t", "Config not found", path[4]);
   409 		return Plugin_Handled;
   410 	}
   411 	
   412 	ShowActivity(client, "%t", "Executed config", path[4]);
   413 	
   414 	LogMessage("\"%L\" executed config (file \"%s\")", client, path[4]);
   415 		
   416 	ServerCommand("exec \"%s\"", path[4]);
   417 	
   418 	return Plugin_Handled;
   419 }
   420 
   421 public Action:Command_Cvar(client, args)
   422 {
   423 	if (args < 1)
   424 	{
   425 		ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar> [value]");
   426 		return Plugin_Handled;
   427 	}
   428 	
   429 	decl String:cvarname[33];
   430 	GetCmdArg(1, cvarname, sizeof(cvarname));
   431 	
   432 	new Handle:hndl = FindConVar(cvarname);
   433 	if (hndl == INVALID_HANDLE)
   434 	{
   435 		ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname);
   436 		return Plugin_Handled;
   437 	}
   438 	
   439 	new bool:allowed = false;
   440 	if (GetConVarFlags(hndl) & FCVAR_PROTECTED)
   441 	{
   442 		/* If they're root, allow anything */
   443 		if ((GetUserFlagBits(client) & ADMFLAG_ROOT) == ADMFLAG_ROOT)
   444 		{
   445 			allowed = true;
   446 		}
   447 		/* If they're not root, and getting sv_password, see if they have ADMFLAG_PASSWORD */
   448 		else if (StrEqual(cvarname, "sv_password") && (GetUserFlagBits(client) & ADMFLAG_PASSWORD))
   449 		{
   450 			allowed = true;
   451 		}
   452 	} 
   453 	/* Do a check for the cheat cvar */
   454 	else if (StrEqual(cvarname, "sv_cheats"))
   455 	{
   456 		if (GetUserFlagBits(client) & ADMFLAG_CHEATS
   457 			|| GetUserFlagBits(client) & ADMFLAG_ROOT)
   458 		{
   459 			allowed = true;
   460 		}
   461 	}
   462 	/* If we drop down to here, it was a normal cvar. */
   463 	else
   464 	{
   465 		allowed = true;
   466 	}
   467 	
   468 	if (!allowed)
   469 	{
   470 		ReplyToCommand(client, "[SM] %t", "No access to cvar");
   471 		return Plugin_Handled;
   472 	}
   473 	
   474 	decl String:value[255];
   475 	if (args < 2)
   476 	{
   477 		GetConVarString(hndl, value, sizeof(value));
   478 		
   479 		ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value);
   480 		return Plugin_Handled;
   481 	}
   482 	
   483 	GetCmdArg(2, value, sizeof(value));
   484 	
   485 	if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED)
   486 	{
   487 		ShowActivity(client, "%t", "Cvar changed", cvarname, value);
   488 	} else {
   489 		ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
   490 	}
   491 	
   492 	LogMessage("\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
   493 	
   494 	SetConVarString(hndl, value, true);
   495 		
   496 	return Plugin_Handled;
   497 }
   498 
   499 public Action:Command_Rcon(client, args)
   500 {
   501 	if (args < 1)
   502 	{
   503 		ReplyToCommand(client, "[SM] Usage: sm_rcon <args>");
   504 		return Plugin_Handled;
   505 	}
   506 	
   507 	decl String:argstring[255];
   508 	GetCmdArgString(argstring, sizeof(argstring));
   509 	
   510 	LogMessage("\"%L\" console command (cmdline \"%s\")", client, argstring);
   511 	
   512 	ServerCommand("%s", argstring);
   513 	
   514 	return Plugin_Handled;
   515 }
   516 
   517 public Action:Command_Map(client, args)
   518 {
   519 	if (args < 1)
   520 	{
   521 		ReplyToCommand(client, "[SM] Usage: sm_map <map>");
   522 		return Plugin_Handled;
   523 	}
   524 	
   525 	decl String:map[64];
   526 	GetCmdArg(1, map, sizeof(map));
   527 	
   528 	if (!IsMapValid(map))
   529 	{
   530 		ReplyToCommand(client, "[SM] %t", "Map was not found", map);
   531 		return Plugin_Handled;
   532 	}
   533 	
   534 	ShowActivity(client, "%t", "Changing map", map);
   535 	
   536 	LogMessage("\"%L\" changed map to \"%s\"", client, map);
   537 	
   538 	new Handle:dp;
   539 	CreateDataTimer(3.0, Timer_ChangeMap, dp);
   540 	WritePackString(dp, map);
   541 	
   542 	return Plugin_Handled;
   543 }
   544 
   545 public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
   546 {
   547 	decl String:map[65];
   548 	
   549 	ResetPack(dp);
   550 	ReadPackString(dp, map, sizeof(map));
   551 	
   552 	ServerCommand("changelevel \"%s\"", map);
   553 	
   554 	return Plugin_Stop;
   555 }
   556 
   557 public Action:Command_Kick(client, args)
   558 {
   559 	if (args < 1)
   560 	{
   561 		ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]");
   562 		return Plugin_Handled;
   563 	}
   564 	
   565 	decl String:arg[65];
   566 	GetCmdArg(1, arg, sizeof(arg));
   567 	
   568 	
   569 	new target = FindTarget(client, arg);
   570 	if (target == -1)
   571 	{
   572 		return Plugin_Handled;
   573 	}
   574 	
   575 	decl String:name[65];
   576 	
   577 	GetClientName(target, name, sizeof(name));
   578 	
   579 	decl String:reason[256];
   580 	if (args < 2)
   581 	{
   582 		/* Safely null terminate */
   583 		reason[0] = '\0';
   584 	} else {
   585 		GetCmdArg(2, reason, sizeof(reason));
   586 	}
   587 	
   588 	ShowActivity(client, "%t", "Kicked player", name);
   589 	
   590 	LogMessage("\"%L\" kicked \"%L\" (reason \"%s\")", client, target, reason);
   591 	
   592 	KickClient(target, "%s", reason);
   593 	
   594 	return Plugin_Handled;
   595 }