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