dvander@910: /** ds@1330: * vim: set ts=4 : ds@1330: * ============================================================================= ds@1330: * SourceMod Basic Commands Plugin ds@913: * Implements basic admin commands. ds@1330: * ds@1947: * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. ds@1330: * ============================================================================= dvander@910: * ds@1330: * This program is free software; you can redistribute it and/or modify it under ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the ds@1330: * Free Software Foundation. ds@1330: * ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ds@1330: * details. dvander@910: * ds@1330: * You should have received a copy of the GNU General Public License along with ds@1330: * this program. If not, see . teame06@1211: * ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the dvander@1624: * code of this program (as well as its derivative 1works) to "Half-Life 2," the ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants ds@1330: * this exception to all derivative works. AlliedModders LLC defines further ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), ds@1330: * or . ds@913: * ds@913: * Version: $Id$ dvander@910: */ dvander@910: ds@989: #pragma semicolon 1 dvander@910: ds@989: #include dvander@1510: #undef REQUIRE_PLUGIN dvander@1510: #include ds@913: teame06@1211: public Plugin:myinfo = dvander@910: { dvander@910: name = "Basic Commands", dvander@910: author = "AlliedModders LLC", dvander@910: description = "Basic Admin Commands", dvander@910: version = SOURCEMOD_VERSION, dvander@910: url = "http://www.sourcemod.net/" dvander@910: }; dvander@910: dvander@1510: new Handle:hTopMenu = INVALID_HANDLE; dvander@1510: pred@1536: new Handle:g_MapList; dvander@1839: new Handle:g_ProtectedVars; pred@1536: dvander@1510: #include "basecommands/kick.sp" dvander@1518: #include "basecommands/reloadadmins.sp" dvander@1523: #include "basecommands/cancelvote.sp" pred@1536: #include "basecommands/who.sp" pred@1536: #include "basecommands/map.sp" pred@1536: #include "basecommands/execcfg.sp" dvander@1510: dvander@910: public OnPluginStart() dvander@910: { dvander@1027: LoadTranslations("common.phrases"); dvander@1521: LoadTranslations("plugin.basecommands"); teame06@1211: dvander@910: RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]"); dvander@917: RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map "); dvander@918: RegAdminCmd("sm_rcon", Command_Rcon, ADMFLAG_RCON, "sm_rcon "); dvander@920: RegAdminCmd("sm_cvar", Command_Cvar, ADMFLAG_CONVARS, "sm_cvar [value]"); downtown1@2775: RegAdminCmd("sm_resetcvar", Command_ResetCvar, ADMFLAG_CONVARS, "sm_resetcvar "); dvander@921: RegAdminCmd("sm_execcfg", Command_ExecCfg, ADMFLAG_CONFIG, "sm_execcfg "); dvander@923: RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]"); dvander@1162: RegAdminCmd("sm_reloadadmins", Command_ReloadAdmins, ADMFLAG_BAN, "sm_reloadadmins"); ferret99gt@1276: RegAdminCmd("sm_cancelvote", Command_CancelVote, ADMFLAG_VOTE, "sm_cancelvote"); dvander@2068: RegConsoleCmd("sm_revote", Command_ReVote); dvander@1510: dvander@1510: /* Account for late loading */ dvander@1510: new Handle:topmenu; dvander@1510: if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE)) dvander@1510: { dvander@1510: OnAdminMenuReady(topmenu); dvander@1510: } pred@1536: pred@1536: g_MapList = CreateMenu(MenuHandler_ChangeMap); pred@1536: SetMenuTitle(g_MapList, "Please select a map"); pred@1536: SetMenuExitBackButton(g_MapList, true); dvander@1738: dvander@1738: decl String:mapListPath[PLATFORM_MAX_PATH]; dvander@1738: BuildPath(Path_SM, mapListPath, sizeof(mapListPath), "configs/adminmenu_maplist.ini"); pred@1740: SetMapListCompatBind("sm_map menu", mapListPath); dvander@1839: dvander@1839: g_ProtectedVars = CreateTrie(); dvander@1839: ProtectVar("rcon_password"); dvander@1839: ProtectVar("sm_show_activity"); dvander@1839: ProtectVar("sm_immunity_mode"); pred@1536: } pred@1536: pred@1536: public OnMapStart() pred@1536: { pred@1740: ParseConfigs(); pred@1740: } pred@1740: pred@1740: public OnConfigsExecuted() pred@1740: { ferret99gt@1606: LoadMapList(g_MapList); pred@1536: } pred@1536: dvander@1839: ProtectVar(const String:cvar[]) dvander@1839: { dvander@1839: SetTrieValue(g_ProtectedVars, cvar, 1); dvander@1839: } dvander@1839: dvander@1839: bool:IsVarProtected(const String:cvar[]) dvander@1839: { dvander@1839: decl dummy_value; dvander@1839: return GetTrieValue(g_ProtectedVars, cvar, dummy_value); dvander@1839: } dvander@1839: downtown1@2775: bool:IsClientAllowedToChangeCvar(client, const String:cvarname[]) downtown1@2775: { downtown1@2775: new Handle:hndl = FindConVar(cvarname); downtown1@2775: downtown1@2775: new bool:allowed = false; downtown1@2775: new client_flags = client == 0 ? ADMFLAG_ROOT : GetUserFlagBits(client); downtown1@2775: downtown1@2775: if (client_flags & ADMFLAG_ROOT) downtown1@2775: { downtown1@2775: allowed = true; downtown1@2775: } downtown1@2775: else downtown1@2775: { downtown1@2775: if (GetConVarFlags(hndl) & FCVAR_PROTECTED) downtown1@2775: { downtown1@2775: allowed = ((client_flags & ADMFLAG_PASSWORD) == ADMFLAG_PASSWORD); downtown1@2775: } downtown1@2775: else if (StrEqual(cvarname, "sv_cheats")) downtown1@2775: { downtown1@2775: allowed = ((client_flags & ADMFLAG_CHEATS) == ADMFLAG_CHEATS); downtown1@2775: } downtown1@2775: else if (!IsVarProtected(cvarname)) downtown1@2775: { downtown1@2775: allowed = true; downtown1@2775: } downtown1@2775: } downtown1@2775: downtown1@2775: return allowed; downtown1@2775: } downtown1@2775: dvander@1510: public OnAdminMenuReady(Handle:topmenu) dvander@1510: { dvander@1510: /* Block us from being called twice */ dvander@1510: if (topmenu == hTopMenu) dvander@1510: { dvander@1510: return; dvander@1510: } dvander@1510: dvander@1510: /* Save the Handle */ dvander@1510: hTopMenu = topmenu; dvander@1510: dvander@1510: /* Build the "Player Commands" category */ dvander@1510: new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS); dvander@1510: dvander@1510: if (player_commands != INVALID_TOPMENUOBJECT) dvander@1510: { dvander@1510: AddToTopMenu(hTopMenu, dvander@1600: "sm_kick", dvander@1510: TopMenuObject_Item, dvander@1510: AdminMenu_Kick, dvander@1510: player_commands, dvander@1510: "sm_kick", dvander@1510: ADMFLAG_KICK); pred@1536: pred@1536: AddToTopMenu(hTopMenu, dvander@1600: "sm_who", pred@1536: TopMenuObject_Item, pred@1536: AdminMenu_Who, pred@1536: player_commands, pred@1536: "sm_who", pred@1536: ADMFLAG_GENERIC); dvander@1510: } dvander@1518: dvander@1518: new TopMenuObject:server_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_SERVERCOMMANDS); dvander@1518: dvander@1518: if (server_commands != INVALID_TOPMENUOBJECT) dvander@1518: { dvander@1518: AddToTopMenu(hTopMenu, dvander@1600: "sm_reloadadmins", dvander@1518: TopMenuObject_Item, dvander@1518: AdminMenu_ReloadAdmins, dvander@1518: server_commands, dvander@1518: "sm_reloadadmins", dvander@1518: ADMFLAG_BAN); pred@1536: pred@1536: AddToTopMenu(hTopMenu, dvander@1600: "sm_map", pred@1536: TopMenuObject_Item, pred@1536: AdminMenu_Map, pred@1536: server_commands, pred@1536: "sm_map", pred@1536: ADMFLAG_CHANGEMAP); pred@1536: pred@1536: AddToTopMenu(hTopMenu, dvander@1600: "sm_execcfg", pred@1536: TopMenuObject_Item, pred@1536: AdminMenu_ExecCFG, pred@1536: server_commands, pred@1536: "sm_execcfg", pred@1536: ADMFLAG_CONFIG); dvander@1518: } dvander@1523: dvander@1523: new TopMenuObject:voting_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_VOTINGCOMMANDS); dvander@1523: dvander@1523: if (voting_commands != INVALID_TOPMENUOBJECT) dvander@1523: { dvander@1523: AddToTopMenu(hTopMenu, dvander@1600: "sm_cancelvote", dvander@1523: TopMenuObject_Item, dvander@1523: AdminMenu_CancelVote, dvander@1523: voting_commands, dvander@1523: "sm_cancelvote", dvander@1523: ADMFLAG_VOTE); dvander@1523: } dvander@1510: } dvander@1510: dvander@1510: public OnLibraryRemoved(const String:name[]) dvander@1510: { dvander@1510: if (strcmp(name, "adminmenu") == 0) dvander@1510: { dvander@1510: hTopMenu = INVALID_HANDLE; dvander@1510: } dvander@927: } dvander@927: dvander@923: #define FLAG_STRINGS 14 dvander@923: new String:g_FlagNames[FLAG_STRINGS][20] = dvander@923: { dvander@1376: "res", dvander@923: "admin", dvander@923: "kick", dvander@923: "ban", dvander@923: "unban", dvander@923: "slay", dvander@923: "map", dvander@923: "cvars", dvander@923: "cfg", dvander@923: "chat", dvander@923: "vote", dvander@923: "pass", dvander@923: "rcon", dvander@923: "cheat" dvander@923: }; dvander@923: dvander@1376: CustomFlagsToString(String:buffer[], maxlength, flags) dvander@1376: { dvander@1376: decl String:joins[6][6]; dvander@1376: new total; dvander@1376: dvander@1376: for (new i=_:Admin_Custom1; i<=_:Admin_Custom6; i++) dvander@1376: { dvander@1376: if (flags & (1< [value]"); dvander@1839: } dvander@1839: else dvander@1839: { dvander@1839: ReplyToCommand(client, "[SM] Usage: sm_cvar [value]"); dvander@1839: } dvander@920: return Plugin_Handled; dvander@920: } teame06@1211: dvander@1671: decl String:cvarname[64]; dvander@920: GetCmdArg(1, cvarname, sizeof(cvarname)); dvander@1839: dvander@1839: if (client == 0 && StrEqual(cvarname, "protect")) dvander@1839: { dvander@1839: if (args < 2) dvander@1839: { dvander@1839: ReplyToCommand(client, "[SM] Usage: sm_cvar "); dvander@1839: return Plugin_Handled; dvander@1839: } dvander@1839: GetCmdArg(2, cvarname, sizeof(cvarname)); dvander@1839: ProtectVar(cvarname); dvander@1839: ReplyToCommand(client, "[SM] %t", "Cvar is now protected", cvarname); dvander@1839: return Plugin_Handled; dvander@1839: } teame06@1211: dvander@920: new Handle:hndl = FindConVar(cvarname); dvander@920: if (hndl == INVALID_HANDLE) dvander@920: { dvander@920: ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname); dvander@920: return Plugin_Handled; dvander@920: } downtown1@2775: downtown1@2775: if (!IsClientAllowedToChangeCvar(client, cvarname)) dvander@920: { dvander@920: ReplyToCommand(client, "[SM] %t", "No access to cvar"); dvander@920: return Plugin_Handled; dvander@920: } teame06@1211: dvander@920: decl String:value[255]; dvander@920: if (args < 2) dvander@920: { dvander@920: GetConVarString(hndl, value, sizeof(value)); teame06@1211: dvander@920: ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value); dvander@920: return Plugin_Handled; dvander@920: } teame06@1211: dvander@920: GetCmdArg(2, value, sizeof(value)); teame06@1211: dvander@920: if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED) dvander@920: { dvander@1623: ShowActivity2(client, "[SM] ", "%t", "Cvar changed", cvarname, value); dvander@1623: } dvander@1623: else dvander@1623: { dvander@924: ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value); dvander@920: } teame06@1211: dvander@1378: LogAction(client, -1, "\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value); teame06@1211: ds@937: SetConVarString(hndl, value, true); teame06@1211: dvander@920: return Plugin_Handled; dvander@918: } dvander@918: downtown1@2775: public Action:Command_ResetCvar(client, args) downtown1@2775: { downtown1@2775: if (args < 1) downtown1@2775: { downtown1@2775: ReplyToCommand(client, "[SM] Usage: sm_resetcvar "); downtown1@2775: downtown1@2775: return Plugin_Handled; downtown1@2775: } downtown1@2775: downtown1@2775: decl String:cvarname[64]; downtown1@2775: GetCmdArg(1, cvarname, sizeof(cvarname)); downtown1@2775: downtown1@2775: new Handle:hndl = FindConVar(cvarname); downtown1@2775: if (hndl == INVALID_HANDLE) downtown1@2775: { downtown1@2775: ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname); downtown1@2775: return Plugin_Handled; downtown1@2775: } downtown1@2775: downtown1@2775: if (!IsClientAllowedToChangeCvar(client, cvarname)) downtown1@2775: { downtown1@2775: ReplyToCommand(client, "[SM] %t", "No access to cvar"); downtown1@2775: return Plugin_Handled; downtown1@2775: } downtown1@2775: downtown1@2775: ResetConVar(hndl); downtown1@2775: downtown1@2775: decl String:value[255]; downtown1@2775: GetConVarString(hndl, value, sizeof(value)); downtown1@2775: downtown1@2775: if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED) downtown1@2775: { downtown1@2775: ShowActivity2(client, "[SM] ", "%t", "Cvar changed", cvarname, value); downtown1@2775: } downtown1@2775: else downtown1@2775: { downtown1@2775: ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value); downtown1@2775: } downtown1@2775: downtown1@2775: LogAction(client, -1, "\"%L\" reset cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value); downtown1@2775: downtown1@2775: return Plugin_Handled; downtown1@2775: } downtown1@2775: dvander@918: public Action:Command_Rcon(client, args) dvander@918: { dvander@918: if (args < 1) dvander@918: { dvander@918: ReplyToCommand(client, "[SM] Usage: sm_rcon "); dvander@918: return Plugin_Handled; dvander@918: } teame06@1211: dvander@918: decl String:argstring[255]; dvander@918: GetCmdArgString(argstring, sizeof(argstring)); teame06@1211: dvander@1378: LogAction(client, -1, "\"%L\" console command (cmdline \"%s\")", client, argstring); teame06@1211: dvander@918: ServerCommand("%s", argstring); teame06@1211: dvander@918: return Plugin_Handled; dvander@917: } dvander@2068: dvander@2068: public Action:Command_ReVote(client, args) dvander@2068: { dvander@2068: if (client == 0) dvander@2068: { dvander@2068: ReplyToCommand(client, "[SM] %t", "Command is in-game only"); dvander@2068: return Plugin_Handled; dvander@2068: } dvander@2068: dvander@2068: if (!IsVoteInProgress()) dvander@2068: { dvander@2068: ReplyToCommand(client, "[SM] %t", "Vote Not In Progress"); dvander@2068: return Plugin_Handled; dvander@2068: } dvander@2068: dvander@2068: if (!IsClientInVotePool(client)) dvander@2068: { dvander@2068: ReplyToCommand(client, "[SM] %t", "Cannot participate in vote"); dvander@2068: return Plugin_Handled; dvander@2068: } dvander@2068: dvander@2068: if (!RedrawClientVoteMenu(client)) dvander@2068: { dvander@2068: ReplyToCommand(client, "[SM] %t", "Cannot change vote"); dvander@2068: } dvander@2068: dvander@2068: return Plugin_Handled; dvander@2068: }