From 8f4f401763c63ed60fcc08df7e692eda138ab6c7 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 14 Jan 2016 14:26:29 +0100 Subject: [PATCH] Partial connect menu loading. --- src/Components/Modules/Menus.cpp | 106 ++++++++++++++++++++----------- src/Components/Modules/Menus.hpp | 10 ++- src/Game/Functions.cpp | 2 + src/Game/Functions.hpp | 6 ++ 4 files changed, 83 insertions(+), 41 deletions(-) diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index 00a7c4fc..322e099d 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -3,8 +3,8 @@ namespace Components { std::vector Menus::CustomMenus; - std::vector Menus::MenuList; - std::vector Menus::MenuListList; + std::map Menus::MenuList; + std::map Menus::MenuListList; int Menus::ReserveSourceHandle() { @@ -125,14 +125,14 @@ namespace Components return nullptr; } - Menus::MenuList.push_back(menu); - Game::pc_token_t token; Game::keywordHash_t *key; if (!Game::PC_ReadTokenHandle(handle, &token) || token.string[0] != '{') { - return menu; + Utils::Memory::Free(menu->items); + Utils::Memory::Free(menu); + return nullptr; } while (true) @@ -167,6 +167,9 @@ namespace Components } } + Menus::RemoveMenu(menu->window.name); + Menus::MenuList[menu->window.name] = menu; + return menu; } @@ -246,7 +249,8 @@ namespace Components // Copy new menus memcpy(newList->menus, menus.data(), menus.size() * sizeof(Game::menuDef_t *)); - Menus::MenuListList.push_back(newList); + Menus::RemoveMenuList(newList->name); + Menus::MenuListList[newList->name] = newList; return newList; } @@ -291,7 +295,8 @@ namespace Components // Copy new menus memcpy(newList->menus, menus.data(), menus.size() * sizeof(Game::menuDef_t *)); - Menus::MenuListList.push_back(newList); + Menus::RemoveMenuList(newList->name); + Menus::MenuListList[newList->name] = newList; return newList; } @@ -383,11 +388,21 @@ namespace Components Utils::Memory::Free(menuList); } + void Menus::RemoveMenu(std::string menu) + { + auto i = Menus::MenuList.find(menu); + if(i != Menus::MenuList.end()) + { + if (i->second) Menus::FreeMenu(i->second); + Menus::MenuList.erase(i); + } + } + void Menus::RemoveMenu(Game::menuDef_t* menudef) { for (auto i = Menus::MenuList.begin(); i != Menus::MenuList.end(); i++) { - if ((*i) == menudef) + if (i->second == menudef) { Menus::FreeMenu(menudef); Menus::MenuList.erase(i); @@ -396,57 +411,68 @@ namespace Components } } - void Menus::RemoveMenuList(Game::MenuList* menuList) + void Menus::RemoveMenuList(std::string menuList) { - if (!menuList) return; - - for (auto i = Menus::MenuListList.begin(); i != Menus::MenuListList.end(); i++) + auto i = Menus::MenuListList.find(menuList); + if (i != Menus::MenuListList.end()) { - if ((*i)->name == menuList->name) + if (i->second) { - for (auto j = 0; j < menuList->menuCount; j++) + for (auto j = 0; j < i->second->menuCount; j++) { - Menus::RemoveMenu(menuList->menus[j]); + Menus::RemoveMenu(i->second->menus[j]); } - Menus::FreeMenuList(menuList); - Menus::MenuListList.erase(i); - break; + Menus::FreeMenuList(i->second); } + + Menus::MenuListList.erase(i); } } + void Menus::RemoveMenuList(Game::MenuList* menuList) + { + if (!menuList || !menuList->name) return; + Menus::RemoveMenuList(menuList->name); + } + void Menus::FreeEverything() { - for (auto menu : Menus::MenuList) + for (auto i = Menus::MenuListList.begin(); i != Menus::MenuListList.end(); i++) { - Menus::FreeMenu(menu); - } - - Menus::MenuList.clear(); - - for (auto menuList : Menus::MenuListList) - { - Menus::FreeMenuList(menuList); + Menus::FreeMenuList(i->second); } Menus::MenuListList.clear(); + + for (auto i = Menus::MenuList.begin(); i != Menus::MenuList.end(); i++) + { + Menus::FreeMenu(i->second); + } + + Menus::MenuList.clear(); + } + + Game::XAssetHeader Menus::MenuLoad(Game::XAssetType type, const char* filename) + { + Game::XAssetHeader header = { 0 }; + + header.menu = Menus::FindMenuByName(Game::uiContext, filename); + + if (!header.menu) + { + OutputDebugStringA("Oh snap!"); + } + + return header; } Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, const char* filename) { Game::XAssetHeader header = { 0 }; - // Check if we already loaded it - for (auto menuList : Menus::MenuListList) - { - if (!_stricmp(menuList->name, filename)) - { - // Free it, seems like the game deallocated it - Menus::RemoveMenuList(menuList); - break; - } - } + // Check if we already loaded it and free it, seems like the game deallocated it + Menus::RemoveMenuList(Menus::MenuListList[filename]); Game::MenuList* menuList = Game::DB_FindXAssetHeader(type, filename).menuList; header.menuList = menuList; @@ -514,8 +540,12 @@ namespace Components { if (Dedicated::IsDedicated()) return; + // Ensure everything is zero'ed + Menus::FreeEverything(); + + // Intercept asset finding + AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENU, Menus::MenuLoad); AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENUFILE, Menus::MenuFileLoad); - //Utils::Hook(0x63FE80, Menus::MenuFileLoad, HOOK_JUMP).Install()->Quick(); // Custom Menus_FindByName Utils::Hook(0x487240, Menus::FindMenuByName, HOOK_JUMP).Install()->Quick(); diff --git a/src/Components/Modules/Menus.hpp b/src/Components/Modules/Menus.hpp index ed89b555..0db681e7 100644 --- a/src/Components/Modules/Menus.hpp +++ b/src/Components/Modules/Menus.hpp @@ -14,11 +14,13 @@ namespace Components static void Add(std::string menu); private: - static std::vector MenuList; - static std::vector MenuListList; + static std::map MenuList; + static std::map MenuListList; static std::vector CustomMenus; - static Game::XAssetHeader MenuFileLoad(Game::XAssetType type, const char* filename); + static Game::XAssetHeader MenuLoad(Game::XAssetType type, const char* filename); + static Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, const char* filename); + static Game::MenuList* LoadMenuList(Game::MenuList* menuList); static Game::MenuList* LoadScriptMenu(const char* menu); static std::vector LoadMenu(Game::menuDef_t* menudef); @@ -37,7 +39,9 @@ namespace Components static void FreeMenuList(Game::MenuList* menuList); static void FreeMenu(Game::menuDef_t* menudef); + static void RemoveMenu(std::string menu); static void RemoveMenu(Game::menuDef_t* menudef); + static void RemoveMenuList(std::string menuList); static void RemoveMenuList(Game::MenuList* menuList); static void AddMenuListHook(Game::UiContext *dc, Game::MenuList *menuList, int close); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 1c45a949..e4765e97 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -63,6 +63,8 @@ namespace Game Menus_CloseAll_t Menus_CloseAll = (Menus_CloseAll_t)0x4BA5B0; Menus_OpenByName_t Menus_OpenByName = (Menus_OpenByName_t)0x4CCE60; + Menu_IsVisible_t Menu_IsVisible = (Menu_IsVisible_t)0x4D77D0; + Menus_MenuIsInStack_t Menus_MenuIsInStack = (Menus_MenuIsInStack_t)0x47ACB0; MSG_Init_t MSG_Init = (MSG_Init_t)0x45FCA0; MSG_ReadData_t MSG_ReadData = (MSG_ReadData_t)0x4527C0; diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index fc8e442a..def955c3 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -148,6 +148,12 @@ namespace Game typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p); extern Menus_OpenByName_t Menus_OpenByName; + typedef int(__cdecl * Menu_IsVisible_t)(UiContext *dc, menuDef_t *menu); + extern Menu_IsVisible_t Menu_IsVisible; + + typedef int(__cdecl * Menus_MenuIsInStack_t)(UiContext *dc, menuDef_t *menu); + extern Menus_MenuIsInStack_t Menus_MenuIsInStack; + typedef void(__cdecl * MSG_Init_t)(void* msg, void* data, int maxsize); extern MSG_Init_t MSG_Init;