enum _:MenuIndexes { PLAYER, ADMIN };
new g_arrMenuData[128][MenuIndexes][Data], g_iDataSize[MenuIndexes];
enum _:PlayerData { Menu, Pos };
new g_PlayerData[MAX_PLAYERS + 1][PlayerData];
native admin_expired(id);
native cmsapi_service_timeleft(id, szDate[]="", iLen=0, srvName[]="");
native amxbans_get_expired(id);
native adminload_get_expired(id);
public plugin_natives() set_native_filter("native_filter");
public native_filter(const name[], index, trap)
return trap ? PLUGIN_CONTINUE : PLUGIN_HANDLED;
register_plugin(PLUGIN, VERSION, AUTHOR);
register_srvcmd("menu_system_reload", "plugin_cfg");
register_menucmd(register_menuid("Menu System"), 1023, "MenuHandler");
register_dictionary("menu_system.txt");
get_localinfo("amxx_configsdir", szPath, charsmax(szPath));
add(szPath, charsmax(szPath), "/menu_system.ini");
new iFile = fopen(szPath, "rt");
if(!iFile) plugin_print(true, "Файл ^"%s^" не найден.", szPath);
new iState, szBuffer[128], szSetting[8], szValue[128];
arrayset(g_iDataSize, 0, MenuIndexes);
fgets(iFile, szBuffer, charsmax(szBuffer));
parse(szBuffer, szSetting, charsmax(szSetting), szValue, charsmax(szValue));
if(strcmp(szBuffer, "[PLAYER]") == 0)
else if(strcmp(szBuffer, "[ADMIN]") == 0)
case 'a': copy(g_szAccess, charsmax(g_szAccess), szValue);
case 'c': register_clcmd(szValue, (iState == PLAYER) ? "ClCmdMenu" : "ClCmdAdminMenu");
g_arrMenuData[g_iDataSize[iState]][iState][Name], charsmax(g_arrMenuData[][][Name]),
g_arrMenuData[g_iDataSize[iState]][iState][Cmd], charsmax(g_arrMenuData[][][Cmd]),
g_arrMenuData[g_iDataSize[iState]][iState][Access], charsmax(g_arrMenuData[][][Access])
) == 3) g_iDataSize[iState]++;
plugin_print(false, "Настройки плагина загружены.");
if(is_plugin_loaded("Admin Loader") != -1)
else if(is_plugin_loaded("GameCMS_API") != -1)
else if(is_plugin_loaded("AMXBans RBS") != -1)
else if(is_plugin_loaded("Admin Load") != -1)
public ClCmdMenu(const id)
g_PlayerData[id][Menu] = PLAYER;
g_PlayerData[id][Pos] = 0;
public ClCmdAdminMenu(const id)
if(get_user_flags(id) & read_flags(g_szAccess))
g_PlayerData[id][Menu] = ADMIN;
g_PlayerData[id][Pos] = 0;
else client_print_color(id, print_team_default, "%l", "MENU_NOT_ACCESS");
new iMenu = g_PlayerData[id][Menu];
new iSize = g_iDataSize[iMenu];
new iLen = formatex(szMenu, charsmax(szMenu), "%l\R%d/%d^n", (iMenu == PLAYER) ? "MENU_PLAYER_TITLE" : "MENU_ADMIN_TITLE", iPos + 1, (iSize / 8 + ((iSize % 8) ? 1 : 0)));
new iExp, iSysTime = get_systime();
case 1: iExp = admin_expired(id);
case 2: iExp = cmsapi_service_timeleft(id);
case 3: iExp = amxbans_get_expired(id);
case 4: iExp = adminload_get_expired(id);
if((iExp - iSysTime) / 86400 > 0)
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "%l^n^n", "MENU_EXPIRED", ((iExp - iSysTime) / 86400));
else iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "%l^n^n", "MENU_LASTDAY");
else if(iExp == 0) iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "%l^n^n", "MENU_NOLIMIT");
else if(iExp == -1) iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n");
iStart = iPos = g_PlayerData[id][Pos] = 0;
for(new i = iStart, iFlags = get_user_flags(id), a; i < iEnd; ++i)
replace_string(g_arrMenuData[i][iMenu][Name], charsmax(g_arrMenuData[][][Name]), "\n", "^n");
if(!g_arrMenuData[i][iMenu][Access][0] || iFlags & read_flags(g_arrMenuData[i][iMenu][Access]))
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r[\y%d\r] \w%s^n", a, g_arrMenuData[i][iMenu][Name]);
replace_string(g_arrMenuData[i][iMenu][Name], charsmax(g_arrMenuData[][][Name]), "\w", "\d");
replace_string(g_arrMenuData[i][iMenu][Name], charsmax(g_arrMenuData[][][Name]), "\r", "\d");
replace_string(g_arrMenuData[i][iMenu][Name], charsmax(g_arrMenuData[][][Name]), "\y", "\d");
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r[\y%d\r] \d%s^n", ++a, g_arrMenuData[i][iMenu][Name]);
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n%l", iPos ? "MENU_BACK" : "MENU_NEXT");
formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n%l", "MENU_EXIT");
show_menu(id, iKeys, szMenu, -1, "Menu System");
public MenuHandler(const id, iKey)
if(g_PlayerData[id][Pos])
ShowMenu(id, --g_PlayerData[id][Pos]);
else ShowMenu(id, ++g_PlayerData[id][Pos]);
case 9: return PLUGIN_HANDLED;
default:client_cmd(id, "%s", g_arrMenuData[g_PlayerData[id][Pos] * 8 + iKey][g_PlayerData[id][Menu]][Cmd]);
plugin_print(bool:bBlock, const szMessage[], any:...)
vformat(szMsg, charsmax(szMsg), szMessage, 3);
case false: log_amx(szMsg);
case true: set_fail_state(szMsg);