// vim: set ts=4 sw=4 tw=99 noet: // // AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). // Copyright (C) The AMX Mod X Development Team. // // This software is licensed under the GNU General Public License, version 3 or higher. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://alliedmods.net/amxmodx-license // // Plugin Cvar and Command Menu // #include #include new DisabledCallback; new EnabledCallback; // pcvar that the client is currently modifying new CurrentCvar[MAX_PLAYERS + 1]; // Name of the cvar being modified new CurrentCvarName[MAX_PLAYERS + 1][32]; // Plugin ID that the client is modifying new CurrentPlid[MAX_PLAYERS + 1]; // Page that the client is currently on new CurrentPage[MAX_PLAYERS + 1]; // Menu function ID that the client is in new CurrentMenuFunction[MAX_PLAYERS + 1] = { -1,... }; new CurrentCommand[MAX_PLAYERS + 1][32]; new cvarmenu_cmdid; new cmdmenu_cmdid; new ExplicitPlugin[MAX_PLAYERS + 1]; 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 cvarmenu_cmdid=register_clcmd("amx_plugincvarmenu", "CvarMenuCommand", ADMIN_CVAR, " - displays the plugin cvar menu"); cmdmenu_cmdid=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() { set_task(0.1, "addToMenuFront"); } public addToMenuFront() { new PluginFileName[64]; get_plugin(-1, PluginFileName, charsmax(PluginFileName)); new cvarflags; new cmdflags; new garbage[1]; new cmd[32]; get_concmd(cmdmenu_cmdid, cmd, charsmax(cmd), cmdflags, garbage, charsmax(garbage), -1); if (strcmp(cmd, "amx_plugincmdmenu") != 0) { // this should never happen, but just incase! cmdflags = ADMIN_MENU; } get_concmd(cvarmenu_cmdid, cmd, charsmax(cmd), cvarflags, garbage, charsmax(garbage), -1); if (strcmp(cmd, "amx_plugincvarmenu") != 0) { // this should never happen, but just incase! cvarflags = ADMIN_CVAR; } AddMenuItem("Plugin Cvars", "amx_plugincvarmenu", cvarflags, PluginFileName); AddMenuItem("Plugin Commands", "amx_plugincmdmenu", cmdflags, PluginFileName); } // 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,charsmax(PluginName),"",0,"",0,PluginState,charsmax(PluginState)); // Command syntax is: "# Function", # being plugin ID, function being public function to call. formatex(PluginCmd,charsmax(PluginCmd),"%d %s",i,Command); formatex(MenuText,charsmax(MenuText),"%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); } } } } menu_setprop(Menu,MPROP_BACKNAME,fmt("%L", id, "BACK")); menu_setprop(Menu,MPROP_NEXTNAME,fmt("%L", id, "MORE")); menu_setprop(Menu,MPROP_EXITNAME,fmt("%L", id, "EXIT")); menu_setprop(Menu,MPROP_NUMBER_COLOR,"\y"); 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,charsmax(TargetPlugin)); 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 cvar_val[64]; for (new i = 1; i <= MaxClients; i++) { if (is_user_connected(i) && !is_user_bot(i)) { if (get_pcvar_flags(pointer) & FCVAR_PROTECTED || equali(Args, "rcon_password")) { formatex(cvar_val, charsmax(cvar_val), "*** %L ***", i, "PROTECTED"); } else { copy(cvar_val, charsmax(cvar_val), Args); } show_activity_id(i, id, Name, "%L", i, "SET_CVAR_TO", "", 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) { DisplayPluginMenu(id,"Plugin Cvar Menu:", "PluginMenuSelection","DisplayCvarMenu","GetNumberOfCvarsForPlid"); } } else if (item==MENU_BACK) { --CurrentPage[id]; client_print(id,print_chat,"MENU_BACK"); } else if (item==MENU_MORE) { ++CurrentPage[id]; client_print(id,print_chat,"MENU_MORE"); } 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, charsmax(Command),CvarName,charsmax(CvarName),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,charsmax(PluginName),"",0,"",0,"",0); formatex(MenuTitle,charsmax(MenuTitle),"%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