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