diff --git a/amxmodx/CMisc.cpp b/amxmodx/CMisc.cpp index 4047d613..f8f066cf 100755 --- a/amxmodx/CMisc.cpp +++ b/amxmodx/CMisc.cpp @@ -29,6 +29,7 @@ * version. */ #include "amxmodx.h" +#include "newmenus.h" // ***************************************************** // class CPlayer // ***************************************************** @@ -49,6 +50,7 @@ void CPlayer::Init(edict_t* e, int i) menu = 0; keys = 0; menuexpire = 0.0; + newmenu = -1; death_weapon.clear(); name.clear(); @@ -62,6 +64,21 @@ void CPlayer::Disconnect() initialized = false; authorized = false; + if (newmenu != -1) + { + Menu *pMenu = g_NewMenus[newmenu]; + if (pMenu) + { + //prevent recursion + newmenu = -1; + menu = 0; + executeForwards(pMenu->func, + static_cast(ENTINDEX(pEdict)), + static_cast(pMenu->thisId), + static_cast(MENU_EXIT)); + } + } + List::iterator iter, end=queries.end(); for (iter=queries.begin(); iter!=end; iter++) { @@ -72,6 +89,8 @@ void CPlayer::Disconnect() queries.clear(); bot = 0; + menu = 0; + newmenu = -1; } void CPlayer::PutInServer() @@ -101,6 +120,7 @@ bool CPlayer::Connect(const char* connectname, const char* ipaddress) bot = IsBot(); death_killer = 0; menu = 0; + newmenu = -1; memset(flags, 0, sizeof(flags)); memset(weapons, 0, sizeof(weapons)); diff --git a/amxmodx/newmenus.cpp b/amxmodx/newmenus.cpp index b7ea41a7..f34da949 100755 --- a/amxmodx/newmenus.cpp +++ b/amxmodx/newmenus.cpp @@ -32,6 +32,7 @@ #include "newmenus.h" CVector g_NewMenus; +CStack g_MenuFreeStack; void ClearMenus() { @@ -39,6 +40,8 @@ void ClearMenus() delete g_NewMenus[i]; g_NewMenus.clear(); + while (!g_MenuFreeStack.empty()) + g_MenuFreeStack.pop(); } void validate_menu_text(char *str) @@ -90,6 +93,7 @@ Menu::Menu(const char *title, int mid, int tid) items_per_page = 7; func = 0; padding = 0; + isDestroying = false; } Menu::~Menu() @@ -393,7 +397,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys) } #define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p]) { \ - LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \ + LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \ return 0; } \ Menu *pMenu = g_NewMenus[p]; @@ -417,13 +421,22 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params) int id = g_menucmds.registerMenuId(title, amx); g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func); - Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size()); + Menu *pMenu = new Menu(title, id, 0); pMenu->func = func; - g_NewMenus.push_back(pMenu); - - return (int)g_NewMenus.size() - 1; + if (g_MenuFreeStack.empty()) + { + g_NewMenus.push_back(pMenu); + pMenu->thisId = (int)g_NewMenus.size() - 1; + return (int)g_NewMenus.size() - 1; + } else { + int pos = g_MenuFreeStack.front(); + g_MenuFreeStack.pop(); + g_NewMenus[pos] = pMenu; + pMenu->thisId = pos; + return pos; + } } static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params) @@ -724,6 +737,10 @@ static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params) { GETMENU(params[1]); + if (pMenu->isDestroying) + return 0; //prevent infinite recursion + + pMenu->isDestroying = true; g_NewMenus[params[1]] = NULL; g_menucmds.removeMenuId(pMenu->menuId); CPlayer *player; @@ -741,6 +758,7 @@ static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params) } } delete pMenu; + g_MenuFreeStack.push(params[1]); return 1; } diff --git a/amxmodx/newmenus.h b/amxmodx/newmenus.h index fd6c8986..f53563ef 100755 --- a/amxmodx/newmenus.h +++ b/amxmodx/newmenus.h @@ -102,6 +102,7 @@ public: int thisId; int func; int padding; + bool isDestroying; public: unsigned int items_per_page; };