diff --git a/iw4/Components/FastFiles.cpp b/iw4/Components/FastFiles.cpp index 380459eb..fe747b3b 100644 --- a/iw4/Components/FastFiles.cpp +++ b/iw4/Components/FastFiles.cpp @@ -33,7 +33,7 @@ namespace Components std::string absoluteFile = Utils::VA("%s\\%s%s", dir, path.data(), file); // No ".ff" appended, append it manually - if (strstr(file, ".ff") != (file + strlen(file) - 3)) + if (!Utils::EndsWith(file, ".ff")) { absoluteFile.append(".ff"); } diff --git a/iw4/Components/Menus.cpp b/iw4/Components/Menus.cpp index 1f30d238..fff46b96 100644 --- a/iw4/Components/Menus.cpp +++ b/iw4/Components/Menus.cpp @@ -321,13 +321,17 @@ namespace Components { // Do i need to free expressions and strings? // Or does the game take care of it? + // Seems like it does... if (menudef->items) { - for (int i = 0; i < menudef->itemCount; i++) - { - Game::Menu_FreeItemMemory(menudef->items[i]); - } + // Seems like this is obsolete as well, + // as the game handles the memory + + //for (int i = 0; i < menudef->itemCount; i++) + //{ + // Game::Menu_FreeItemMemory(menudef->items[i]); + //} free(menudef->items); } @@ -353,6 +357,39 @@ namespace Components } } + void Menus::RemoveMenu(Game::menuDef_t* menudef) + { + for (auto i = Menus::MenuList.begin(); i != Menus::MenuList.end(); i++) + { + if ((*i) == menudef) + { + Menus::FreeMenu(menudef); + Menus::MenuList.erase(i); + break; + } + } + } + + void Menus::RemoveMenuList(Game::MenuList* menuList) + { + if (!menuList) return; + + for (auto i = Menus::MenuListList.begin(); i != Menus::MenuListList.end(); i++) + { + if ((*i)->name == menuList->name) + { + for (auto j = 0; j < menuList->menuCount; j++) + { + Menus::RemoveMenu(menuList->menus[j]); + } + + Menus::FreeMenuList(menuList); + Menus::MenuListList.erase(i); + break; + } + } + } + void Menus::FreeEverything() { for (auto menu : Menus::MenuList) @@ -377,10 +414,14 @@ namespace Components // Check if we already loaded it for (auto menuList : Menus::MenuListList) { - if (!strcmp(menuList->name, filename)) + if (!_stricmp(menuList->name, filename)) { - header.menuList = menuList; - return header; + // Free it! + // Seems like the game deallocated half of it :P + Menus::RemoveMenuList(menuList); + break; + //header.menuList = menuList; + //return header; } } @@ -389,7 +430,11 @@ namespace Components if (menuList) { - header.menuList = Menus::LoadMenuList(menuList); + // Don't parse scriptmenus for now! + if (!Utils::EndsWith(filename, ".menu")) + { + header.menuList = Menus::LoadMenuList(menuList); + } } return header; @@ -398,6 +443,7 @@ namespace Components Menus::Menus() { AssetHandler::On(Game::XAssetType::ASSET_TYPE_MENUFILE, Menus::MenuFileLoad); + //Utils::Hook(0x63FE80, Menus::MenuFileLoad, HOOK_JUMP).Install()->Quick(); // disable the 2 new tokens in ItemParse_rect Utils::Hook::Set(0x640693, 0xEB); @@ -418,23 +464,25 @@ namespace Components Command::Add("reloadmenus", [] (Command::Params params) { - if (Game::CL_IsCgameInitialized()) - { - Logger::Print("Realoading menus in-game is not allowed!\n"); - return; - } - // Close all menus Game::Menus_CloseAll(0x62E2858); // Free custom menus Menus::FreeEverything(); - // Reinitialize ui context - ((void(*)())0x401700)(); + // Only disconnect if in-game, context is updated automatically! + if (Game::CL_IsCgameInitialized()) + { + Game::Cbuf_AddText(0, "disconnect\n"); + } + else + { + // Reinitialize ui context + ((void(*)())0x401700)(); - // Reopen main menu - Game::Menus_OpenByName(0x62E2858, "main_text"); + // Reopen main menu + Game::Menus_OpenByName(0x62E2858, "main_text"); + } }); } diff --git a/iw4/Components/Menus.hpp b/iw4/Components/Menus.hpp index 1d22072b..4df89f9c 100644 --- a/iw4/Components/Menus.hpp +++ b/iw4/Components/Menus.hpp @@ -32,6 +32,9 @@ namespace Components static void FreeMenuList(Game::MenuList* menuList); static void FreeMenu(Game::menuDef_t* menudef); + static void RemoveMenu(Game::menuDef_t* menudef); + static void RemoveMenuList(Game::MenuList* menuList); + static void FreeEverything(); // Ugly! diff --git a/iw4/Utils/Utils.cpp b/iw4/Utils/Utils.cpp index 5dcce60d..d7f6c535 100644 --- a/iw4/Utils/Utils.cpp +++ b/iw4/Utils/Utils.cpp @@ -24,4 +24,9 @@ namespace Utils std::transform(input.begin(), input.end(), input.begin(), ::tolower); return input; } + + bool EndsWith(const char* heystack, const char* needle) + { + return (strstr(heystack, needle) == (heystack + strlen(heystack) - strlen(needle))); + } } \ No newline at end of file diff --git a/iw4/Utils/Utils.hpp b/iw4/Utils/Utils.hpp index 8cd9bfa4..de95b9db 100644 --- a/iw4/Utils/Utils.hpp +++ b/iw4/Utils/Utils.hpp @@ -2,4 +2,5 @@ namespace Utils { const char *VA(const char *fmt, ...); std::string StrToLower(std::string input); + bool EndsWith(const char* heystack, const char* needle); }