/* * CSB CVar Menu * Copyright (C) 2026 counter-strike-boost.com * * A menu of the cvars server admins change most often (friendly fire, gravity, * freeze time, round time, buy time, auto team balance, start money, C4 timer). * Each entry shows its current value and cycles through a preset list when * selected, applying it immediately with set_cvar_string. * * Inspired by the AMX Mod X CVar menu (AMX Mod X Development Team). Independent * GPL re-implementation. * * 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 3 of the License, or (at your option) any later * version. It 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 for details. */ #include #include new const PLUGIN[] = "CSB CVar Menu" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" /* cvar name, friendly label and a pipe-separated list of preset values */ new const g_cvarName[][] = { "mp_friendlyfire", "sv_gravity", "mp_freezetime", "mp_roundtime", "mp_buytime", "mp_autoteambalance", "mp_startmoney", "mp_c4timer" } new const g_cvarLabel[][] = { "Friendly Fire", "Gravity", "Freeze Time", "Round Time", "Buy Time", "Auto Team Balance", "Start Money", "C4 Timer" } new const g_cvarPreset[][] = { "0|1", "400|600|800|1000", "0|3|6", "1.75|3|5|9", "0.25|0.5|1", "0|1", "800|1600|8000|16000", "30|35|45|60" } #define ENTRIES sizeof(g_cvarName) public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) register_concmd("amx_cvarmenu", "cmdCvarMenu", ADMIN_CVAR, "- open the quick cvar menu") register_clcmd("say /cvars", "sayCvarMenu") } public sayCvarMenu(id) { if (get_user_flags(id) & ADMIN_CVAR) showMenu(id) return PLUGIN_HANDLED } public cmdCvarMenu(id, level, cid) { if (!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED showMenu(id) return PLUGIN_HANDLED } showMenu(id) { new title[64] formatex(title, charsmax(title), "\yCSB CVar Menu^n\wPick a cvar to cycle its value") new menu = menu_create(title, "menuHandler") new line[96], cur[24], info[4] for (new i = 0; i < ENTRIES; i++) { get_cvar_string(g_cvarName[i], cur, charsmax(cur)) formatex(line, charsmax(line), "%s: \y%s", g_cvarLabel[i], cur) num_to_str(i, info, charsmax(info)) menu_additem(menu, line, info, 0) } menu_display(id, menu, 0) } public menuHandler(id, menu, item) { if (item == MENU_EXIT || item < 0) { menu_destroy(menu) return PLUGIN_HANDLED } new info[4], name[2], access, callback menu_item_getinfo(menu, item, access, info, charsmax(info), name, charsmax(name), callback) menu_destroy(menu) new idx = str_to_num(info) if (idx < 0 || idx >= ENTRIES) return PLUGIN_HANDLED cycleCvar(id, idx) showMenu(id) return PLUGIN_HANDLED } cycleCvar(id, idx) { new presets[64] copy(presets, charsmax(presets), g_cvarPreset[idx]) new cur[24] get_cvar_string(g_cvarName[idx], cur, charsmax(cur)) /* split the preset list on '|' and find the current value, then take next */ new values[6][24], count = 0 new start = 0, len = strlen(presets) for (new i = 0; i <= len && count < sizeof(values); i++) { if (presets[i] == '|' || presets[i] == 0) { new sub = i - start if (sub > 0) { if (sub > charsmax(values[])) sub = charsmax(values[]) copy(values[count], sub, presets[start]) count++ } start = i + 1 } } if (!count) return new nextIdx = 0 for (new i = 0; i < count; i++) { if (equal(values[i], cur)) { nextIdx = (i + 1) % count break } } set_cvar_string(g_cvarName[idx], values[nextIdx]) new aname[32] get_user_name(id, aname, charsmax(aname)) log_amx("[CSB CVar] %s set %s to %s", aname, g_cvarName[idx], values[nextIdx]) client_print(id, print_chat, "[CSB] %s = %s", g_cvarLabel[idx], values[nextIdx]) }