diff --git a/plugins/pluginmenu.sma b/plugins/pluginmenu.sma new file mode 100644 index 00000000..24a967a2 --- /dev/null +++ b/plugins/pluginmenu.sma @@ -0,0 +1,964 @@ +/* AMX Mod X +* Plugin Cvar and Command Menu +* +* by the AMX Mod X Development Team +* +* This file is part of AMX Mod X. +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* 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, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ + +#include +#include + +// Temporary define for having users test on their core. +// This will ensure that the build will work on 1.76. +#define BUILD_FOR_176 + + +new DisabledCallback; +new EnabledCallback; + +// pcvar that the client is currently modifying +new CurrentCvar[33]; + +// Name of the cvar being modified +new CurrentCvarName[33][32]; + +// Plugin ID that the client is modifying +new CurrentPlid[33]; + +// Page that the client is currently on +new CurrentPage[33]; + +// Menu function ID that the client is in +new CurrentMenuFunction[33] = { -1,... }; + +new CurrentCommand[33][32]; + + +new ExplicitPlugin[33]; + +public plugin_init() +{ + register_plugin("Plugin Menu",AMXX_VERSION_STR,"AMXX Dev Team"); + + register_dictionary("common.txt"); + register_dictionary("pausecfg.txt"); // Needed for PAUSE_COULDNT_FIND + + register_clcmd("amx_plugincvarmenu", "CvarMenuCommand", ADMIN_CVAR, " - displays the plugin cvar menu"); + register_clcmd("amx_plugincmdmenu", "CommandMenuCommand", ADMIN_MENU, " - displays the plugin command menu"); + + register_clcmd("amx_changecvar","CommandChangeCvar"); + register_clcmd("amx_executecmd","CommandExecuteCommand"); + + // Register global menu callbacks. + DisabledCallback=menu_makecallback("AlwaysDisableCallback"); + EnabledCallback=menu_makecallback("AlwaysEnableCallback"); +} + +// Add these menus to the amxmodmenu +public plugin_cfg() +{ + new PluginName[64]; + + get_plugin(-1,"",0,PluginName,sizeof(PluginName)-1); + AddMenuItem("Plugin Cvars", "amx_plugincvarmenu", ADMIN_CVAR, PluginName); + AddMenuItem("Plugin Commands", "amx_plugincmdmenu", ADMIN_MENU, PluginName); +} + +// Reset all fields for each client as they connect. +public client_connect(id) +{ + CurrentCvar[id]=0; + CurrentPlid[id]=0; + CurrentMenuFunction[id]=-1; + CurrentCvarName[id][0]=0; + CurrentCommand[id][0]=0; + ExplicitPlugin[id]=-1; + +} + +/** + * Creates a plugin list menu. + * + * @param MenuText The text to display as the title. + * @param Handler The function to call when an item is selected. + * @param Command The function to pass to the handler. It will be passed as "PLID Command". + * @param Callback Function to call for each plugin to be listed. Displays a number next to it (how many cvars, etc.) + */ +stock DisplayPluginMenu(id,const MenuText[], const Handler[], const Command[], const Callback[]) +{ + new Menu=menu_create(MenuText,Handler); + + + new PluginState[32]; + new PluginName[64]; + new func=get_func_id(Callback); + new tally; + new PluginCmd[64]; + new MenuText[64]; + for (new i=0, max=get_pluginsnum(); + i0) + { + get_plugin(i,"",0,PluginName,sizeof(PluginName)-1,"",0,"",0,PluginState,sizeof(PluginState)-1); + + // Command syntax is: "# Function", # being plugin ID, function being public function to call. + formatex(PluginCmd,sizeof(PluginCmd)-1,"%d %s",i,Command); + formatex(MenuText,sizeof(MenuText)-1,"%s - %d",PluginName,tally); + // If the plugin is running, add this as an activated menu item. + if (strcmp(PluginState,"running",true)==0 || + strcmp(PluginState,"debug", true)==0) + { + menu_additem(Menu,MenuText,PluginCmd,EnabledCallback); + } + else + { + menu_additem(Menu,MenuText,"",_,DisabledCallback); + } + } + } + } +#if !defined BUILD_FOR_176 + menu_setprop(Menu,MPROP_NUMBER_COLOR,"\y"); +#endif + menu_setprop(Menu,MPROP_EXIT,MEXIT_ALL); + menu_display(id,Menu,0); + +} + +/** + * Byrefs the plugin id of a target plugin (passed by argv(1)), but only if it's valid. + * + * @param id id of the display messages to upon failure. + * @param plid Variable to byref the plugin id. + * @return True on successful lookup, false on failure. + */ +stock bool:GetPlidForValidPlugins(id, &plid) +{ + // If arguments have been passed, then we were given + // a specific plugin to examine. + if (read_argc()>1) + { + // Yes, we were provided a plugin. + new TargetPlugin[64]; + read_argv(1,TargetPlugin,sizeof(TargetPlugin)-1); + + new BufferName[64]; + new BufferFile[64]; + new BufferState[64]; + // Scan for the plugin ID. + for (new i=0, max=get_pluginsnum(); + i<%s><>^" set cvar (name ^"%s^") (value ^"%s^")", Name, get_user_userid(id), AuthID, CurrentCvarName[id], Args); + + + new activity = get_cvar_num("amx_show_activity"); + + if (activity != 0) + { + new players[32], pnum, admin[64], cvar_val[64], len; + get_players(players, pnum, "c"); + + for (new i = 0; i < pnum; i++) + { + len = format(admin, 255, "%L", players[i], "ADMIN"); + + if (activity == 1) + { + len += copy(admin[len], 255-len, ":"); + } + else + { + len += format(admin[len], 255-len, " %s:", Name); + } + + if (get_pcvar_flags(pointer) & FCVAR_PROTECTED || + equali(CurrentCvarName[id],"rcon_password") || + equali(CurrentCvarName[id],"amx_sql_",8)) + { + format(cvar_val, 63, "*** %L ***", players[i], "PROTECTED"); + } + else + { + copy(cvar_val, 63, Args); + } + + client_print(players[i], print_chat, "%L", players[i], "SET_CVAR_TO", admin, CurrentCvarName[id], cvar_val); + } + } + console_print(id, "[AMXX] %L", id, "CVAR_CHANGED", CurrentCvarName[id], Args); + + } + + // Now redraw the menu for the client + if (CurrentMenuFunction[id]!=-1 && callfunc_begin_i(CurrentMenuFunction[id])==1) + { + callfunc_push_int(id); + callfunc_push_int(CurrentPlid[id]); + callfunc_push_int(CurrentPage[id]); + callfunc_end(); + } + + return PLUGIN_HANDLED; +} + +/** + * Process a selection from the cvar menu. + * + * @param id The client who chose an item. + * @param menu The menu handle. + * @param item The item that has been selected. + */ +public CvarMenuSelection(id, menu, item) +{ + + if (item==MENU_EXIT) + { + menu_destroy(menu); + + if (ExplicitPlugin[id]==-1) + { + client_cmd(id,"amx_plugincvarmenu"); + } + return PLUGIN_HANDLED; + } + else if (item==MENU_BACK) + { + --CurrentPage[id]; + client_print(id,print_chat,"MENU_BACK"); + return PLUGIN_HANDLED; + } + else if (item==MENU_MORE) + { + ++CurrentPage[id]; + client_print(id,print_chat,"MENU_MORE"); + return PLUGIN_HANDLED; + } + else + { + new CvarName[64]; + new Command[32]; + new Dummy[1]; + // pcvar pointer is stored in command, extract the name of the cvar from the name field. + menu_item_getinfo(menu, item, Dummy[0], Command, sizeof(Command)-1,CvarName,sizeof(CvarName)-1,Dummy[0]); + + CurrentCvar[id]=str_to_num(Command); + + if (CurrentCvar[id]==0) // This should never happen, but just incase.. + { + client_print(id,print_chat,"[AMXX] There was an error extracting the cvar pointer. (Name=^"%s^")",CvarName); + return PLUGIN_HANDLED; + } + // TODO: ML this + + // Scan up "CvarName" and stop at the first space + for (new i=0;i) should be filtered out already. + * + * @param Command The command that is being checked. + */ +stock bool:IsDisplayableCmd(const Command[]) +{ + // Block "say" and "say_team" + if (equal(Command,"say",3)) + { + return false; + } + + return true; +} +/** + * Displays a command list for the specified plugin. + * + * @param id Id of the client that's being displayed to. + * @param plid Plugin ID of the plugin that is to be displayed. + * @param page The page to start at. + */ +public DisplayCmdMenu(id, plid, page) +{ + new PluginName[32]; + new MenuTitle[64]; + get_plugin(plid,"",0,PluginName,sizeof(PluginName)-1,"",0,"",0,"",0); + + formatex(MenuTitle,sizeof(MenuTitle)-1,"%s Commands:",PluginName); + + new Menu=menu_create(MenuTitle,"CommandMenuSelection"); + + new Command[64]; + new CidString[32]; + new CommandAccess; + new userflags=get_user_flags(id); + new bool:isadmin=bool:is_user_admin(id); + + + for (new i=0, max=get_concmdsnum(-1,-1); + i