Fixed AskPluginLoad would still allowed plugin to load even if it returned false.
3 * Implements basic admin commands.
4 * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
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.
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.
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.
27 public Plugin:myinfo =
29 name = "Basic Commands",
30 author = "AlliedModders LLC",
31 description = "Basic Admin Commands",
32 version = SOURCEMOD_VERSION,
33 url = "http://www.sourcemod.net/"
36 new Handle:hBanForward = INVALID_HANDLE;
37 new Handle:hAddBanForward = INVALID_HANDLE;
38 new Handle:hBanRemoved = INVALID_HANDLE;
40 public OnPluginStart()
42 LoadTranslations("common.phrases");
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");
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);
61 public Action:Command_ReloadAdmins(client, args)
64 DumpAdminCache(AdminCache_Groups, true);
65 DumpAdminCache(AdminCache_Overrides, true);
67 LogMessage("\"%L\" refreshed the admin cache.", client);
68 ReplyToCommand(client, "[SM] %t", "Admin cache refreshed");
70 return Plugin_Handled;
73 public Action:Command_BanIp(client, args)
77 ReplyToCommand(client, "[SM] Usage: sm_banip <time> <ip> [reason]");
78 return Plugin_Handled;
81 decl String:arg[50], String:time[20];
82 GetCmdArg(1, time, sizeof(time));
83 GetCmdArg(2, arg, sizeof(arg));
85 new minutes = StringToInt(time);
87 decl String:reason[128];
90 GetCmdArg(3, reason, sizeof(reason));
93 new Action:act = Plugin_Continue;
94 Call_StartForward(hAddBanForward);
95 Call_PushCell(client);
97 Call_PushCell(minutes);
98 Call_PushString(reason);
101 if (act < Plugin_Handled)
103 LogMessage("\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")", client, minutes, arg, reason);
104 ReplyToCommand(client, "[SM] %t", "Ban added");
107 if (act < Plugin_Stop)
109 ServerCommand("banip %d %s", minutes, arg);
110 ServerCommand("writeip");
113 return Plugin_Handled;
116 public Action:Command_AddBan(client, args)
120 ReplyToCommand(client, "[SM] Usage: sm_addban <time> <steamid> [reason]");
121 return Plugin_Handled;
124 decl String:arg[50], String:time[20];
125 GetCmdArg(1, time, sizeof(time));
126 GetCmdArg(2, arg, sizeof(arg));
128 new minutes = StringToInt(time);
130 decl String:reason[128];
133 GetCmdArg(3, reason, sizeof(reason));
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);
144 if (act < Plugin_Handled)
146 LogMessage("\"%L\" added ban (minutes \"%d\") (id \"%s\") (reason \"%s\")", client, minutes, arg, reason);
147 ReplyToCommand(client, "[SM] %t", "Ban added");
150 if (act < Plugin_Stop)
152 ServerCommand("banid %d %s", minutes, arg);
153 ServerCommand("writeid");
156 return Plugin_Handled;
159 public Action:Command_Unban(client, args)
163 ReplyToCommand(client, "[SM] Usage: sm_unban <steamid>");
164 return Plugin_Handled;
169 decl String:new_arg[50];
170 GetCmdArgString(arg, sizeof(arg));
172 if (strncmp(arg, "STEAM_0:", 8) == 0)
175 } else if (strncmp(arg, "0:1:", 4) == 0 || strncmp(arg, "0:0:", 4) == 0)
180 Format(new_arg, sizeof(new_arg), "STEAM_0:%s", arg[start]);
182 new Action:act = Plugin_Continue;
183 Call_StartForward(hBanRemoved);
184 Call_PushCell(client);
185 Call_PushString(new_arg);
188 if (act < Plugin_Handled)
190 LogMessage("\"%L\" removed ban (filter \"%s\")", client, arg[start]);
191 ReplyToCommand(client, "[SM] %t", "Removed bans matching", arg);
194 if (act < Plugin_Stop)
196 ServerCommand("removeid \"%s\"", arg[start]);
197 ServerCommand("writeid");
200 return Plugin_Handled;
203 public Action:Command_Ban(client, args)
207 ReplyToCommand(client, "[SM] Usage: sm_ban <#userid|name> <minutes|0> [reason]");
208 return Plugin_Handled;
212 GetCmdArg(1, arg, sizeof(arg));
214 new target = FindTarget(client, arg, true);
217 return Plugin_Handled;
220 decl String:s_time[12];
221 GetCmdArg(2, s_time, sizeof(s_time));
223 new time = StringToInt(s_time);
225 decl String:reason[128];
228 GetCmdArg(3, reason, sizeof(reason));
233 decl String:authid[64];
234 GetClientAuthString(target, authid, sizeof(authid));
235 GetClientName(target, arg, sizeof(arg));
237 /* Fire the ban forward */
238 new Action:act = Plugin_Continue;
239 Call_StartForward(hBanForward);
240 Call_PushCell(client);
241 Call_PushCell(target);
243 Call_PushString(reason);
246 if (act < Plugin_Handled)
250 if (reason[0] == '\0')
252 ShowActivity(client, "%t", "Permabanned player", arg);
254 ShowActivity(client, "%t", "Permabanned player reason", arg, reason);
257 if (reason[0] == '\0')
259 ShowActivity(client, "%t", "Banned player", arg, time);
261 ShowActivity(client, "%t", "Banned player reason", arg, time, reason);
264 LogMessage("\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason);
267 if (act < Plugin_Stop)
269 if (reason[0] == '\0')
271 strcopy(reason, sizeof(reason), "Banned");
274 ServerCommand("banid %d %s", time, authid);
275 KickClient(target, "%s", reason);
279 ServerCommand("writeid");
283 return Plugin_Handled;
286 #define FLAG_STRINGS 14
287 new String:g_FlagNames[FLAG_STRINGS][20] =
305 FlagsToString(String:buffer[], maxlength, flags)
307 decl String:joins[FLAG_STRINGS][20];
310 for (new i=0; i<FLAG_STRINGS; i++)
314 strcopy(joins[total++], 20, g_FlagNames[i]);
318 ImplodeStrings(joins, total, ", ", buffer, maxlength);
321 public Action:Command_Who(client, args)
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);
330 PrintToConsole(client, "%-24.23s %s", t_name, t_access);
332 /* List all players */
333 new maxClients = GetMaxClients();
334 decl String:flagstring[255];
336 for (new i=1; i<=maxClients; i++)
338 if (!IsClientInGame(i))
342 new flags = GetUserFlagBits(i);
345 strcopy(flagstring, sizeof(flagstring), "none");
346 } else if (flags & ADMFLAG_ROOT) {
347 strcopy(flagstring, sizeof(flagstring), "root");
349 FlagsToString(flagstring, sizeof(flagstring), flags);
351 decl String:name[65];
352 GetClientName(i, name, sizeof(name));
353 PrintToConsole(client, "%d. %-24.23s %s", i, name, flagstring);
356 if (GetCmdReplySource() == SM_REPLY_TO_CHAT)
358 ReplyToCommand(client, "[SM] %t", "See console for output");
361 return Plugin_Handled;
365 GetCmdArg(1, arg, sizeof(arg));
368 new numClients = SearchForClients(arg, clients, 2);
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;
379 new flags = GetUserFlagBits(clients[0]);
380 decl String:flagstring[255];
383 strcopy(flagstring, sizeof(flagstring), "none");
384 } else if (flags & ADMFLAG_ROOT) {
385 strcopy(flagstring, sizeof(flagstring), "root");
387 FlagsToString(flagstring, sizeof(flagstring), flags);
390 ReplyToCommand(client, "[SM] %t: %s", "Access", flagstring);
392 return Plugin_Handled;
395 public Action:Command_ExecCfg(client, args)
399 ReplyToCommand(client, "[SM] Usage: sm_execcfg <filename>");
400 return Plugin_Handled;
403 new String:path[64] = "cfg/";
404 GetCmdArg(1, path[4], sizeof(path)-4);
406 if (!FileExists(path))
408 ReplyToCommand(client, "[SM] %t", "Config not found", path[4]);
409 return Plugin_Handled;
412 ShowActivity(client, "%t", "Executed config", path[4]);
414 LogMessage("\"%L\" executed config (file \"%s\")", client, path[4]);
416 ServerCommand("exec \"%s\"", path[4]);
418 return Plugin_Handled;
421 public Action:Command_Cvar(client, args)
425 ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar> [value]");
426 return Plugin_Handled;
429 decl String:cvarname[33];
430 GetCmdArg(1, cvarname, sizeof(cvarname));
432 new Handle:hndl = FindConVar(cvarname);
433 if (hndl == INVALID_HANDLE)
435 ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname);
436 return Plugin_Handled;
439 new bool:allowed = false;
440 if (GetConVarFlags(hndl) & FCVAR_PROTECTED)
442 /* If they're root, allow anything */
443 if ((GetUserFlagBits(client) & ADMFLAG_ROOT) == ADMFLAG_ROOT)
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))
453 /* Do a check for the cheat cvar */
454 else if (StrEqual(cvarname, "sv_cheats"))
456 if (GetUserFlagBits(client) & ADMFLAG_CHEATS
457 || GetUserFlagBits(client) & ADMFLAG_ROOT)
462 /* If we drop down to here, it was a normal cvar. */
470 ReplyToCommand(client, "[SM] %t", "No access to cvar");
471 return Plugin_Handled;
474 decl String:value[255];
477 GetConVarString(hndl, value, sizeof(value));
479 ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value);
480 return Plugin_Handled;
483 GetCmdArg(2, value, sizeof(value));
485 if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED)
487 ShowActivity(client, "%t", "Cvar changed", cvarname, value);
489 ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
492 LogMessage("\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
494 SetConVarString(hndl, value, true);
496 return Plugin_Handled;
499 public Action:Command_Rcon(client, args)
503 ReplyToCommand(client, "[SM] Usage: sm_rcon <args>");
504 return Plugin_Handled;
507 decl String:argstring[255];
508 GetCmdArgString(argstring, sizeof(argstring));
510 LogMessage("\"%L\" console command (cmdline \"%s\")", client, argstring);
512 ServerCommand("%s", argstring);
514 return Plugin_Handled;
517 public Action:Command_Map(client, args)
521 ReplyToCommand(client, "[SM] Usage: sm_map <map>");
522 return Plugin_Handled;
526 GetCmdArg(1, map, sizeof(map));
528 if (!IsMapValid(map))
530 ReplyToCommand(client, "[SM] %t", "Map was not found", map);
531 return Plugin_Handled;
534 ShowActivity(client, "%t", "Changing map", map);
536 LogMessage("\"%L\" changed map to \"%s\"", client, map);
539 CreateDataTimer(3.0, Timer_ChangeMap, dp);
540 WritePackString(dp, map);
542 return Plugin_Handled;
545 public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
550 ReadPackString(dp, map, sizeof(map));
552 ServerCommand("changelevel \"%s\"", map);
557 public Action:Command_Kick(client, args)
561 ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]");
562 return Plugin_Handled;
566 GetCmdArg(1, arg, sizeof(arg));
569 new target = FindTarget(client, arg);
572 return Plugin_Handled;
575 decl String:name[65];
577 GetClientName(target, name, sizeof(name));
579 decl String:reason[256];
582 /* Safely null terminate */
585 GetCmdArg(2, reason, sizeof(reason));
588 ShowActivity(client, "%t", "Kicked player", name);
590 LogMessage("\"%L\" kicked \"%L\" (reason \"%s\")", client, target, reason);
592 KickClient(target, "%s", reason);
594 return Plugin_Handled;