#40 Experiments.
This commit is contained in:
parent
32088789ef
commit
6fa0a743d8
@ -167,6 +167,7 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
Menus::OverrideMenu(menu);
|
||||
Menus::RemoveMenu(menu->window.name);
|
||||
Menus::MenuList[menu->window.name] = menu;
|
||||
|
||||
@ -223,9 +224,19 @@ namespace Components
|
||||
std::vector<Game::menuDef_t*> menus = Menus::LoadMenu(Utils::VA("ui_mp\\%s.menu", menudef->window.name));
|
||||
|
||||
if (!menus.size())
|
||||
{
|
||||
// Try loading the original menu, if we can't load our custom one
|
||||
Game::menuDef_t* originalMenu = AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_MENU, menudef->window.name).menu;
|
||||
|
||||
if (originalMenu)
|
||||
{
|
||||
menus.push_back(originalMenu);
|
||||
}
|
||||
else
|
||||
{
|
||||
menus.push_back(menudef);
|
||||
}
|
||||
}
|
||||
|
||||
return menus;
|
||||
}
|
||||
@ -285,7 +296,8 @@ namespace Components
|
||||
Game::MenuList* newList = Utils::Memory::AllocateArray<Game::MenuList>(1);
|
||||
if (!newList) return menuList;
|
||||
|
||||
newList->menus = Utils::Memory::AllocateArray<Game::menuDef_t*>(menus.size());
|
||||
size_t size = menus.size();
|
||||
newList->menus = Utils::Memory::AllocateArray<Game::menuDef_t*>(size);
|
||||
if (!newList->menus)
|
||||
{
|
||||
Utils::Memory::Free(newList);
|
||||
@ -293,10 +305,10 @@ namespace Components
|
||||
}
|
||||
|
||||
newList->name = Utils::Memory::DuplicateString(menuList->name);
|
||||
newList->menuCount = menus.size();
|
||||
newList->menuCount = size;
|
||||
|
||||
// Copy new menus
|
||||
memcpy(newList->menus, menus.data(), menus.size() * sizeof(Game::menuDef_t *));
|
||||
memcpy(newList->menus, menus.data(), size * sizeof(Game::menuDef_t *));
|
||||
|
||||
Menus::RemoveMenuList(newList->name);
|
||||
Menus::MenuListList[newList->name] = newList;
|
||||
@ -433,6 +445,52 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
// This is actually a really important function
|
||||
// It checks if we have already loaded the menu we passed and replaces its instances in memory
|
||||
// Due to deallocating the old menu, the game might crash on not being able to handle its old instance
|
||||
// So we need to override it in our menu lists and the game's ui context
|
||||
// EDIT: We might also remove the old instances inside RemoveMenu
|
||||
// EDIT2: Removing old instances without having a menu to replace them with might leave a nullptr
|
||||
void Menus::OverrideMenu(Game::menuDef_t *menu)
|
||||
{
|
||||
if (!menu || !menu->window.name) return;
|
||||
std::string name = menu->window.name;
|
||||
|
||||
// Find the old menu
|
||||
auto i = Menus::MenuList.find(name);
|
||||
if (i != Menus::MenuList.end())
|
||||
{
|
||||
// We have found it, *yay*
|
||||
Game::menuDef_t* oldMenu = i->second;
|
||||
|
||||
// Replace every old instance with our new one in the ui context
|
||||
for (int i = 0; i < Game::uiContext->menuCount; i++)
|
||||
{
|
||||
if (Game::uiContext->menus[i] == oldMenu)
|
||||
{
|
||||
Game::uiContext->menus[i] = menu;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace every old instance with our new one in our menu lists
|
||||
for (auto i = Menus::MenuListList.begin(); i != Menus::MenuListList.end(); i++)
|
||||
{
|
||||
Game::MenuList* list = i->second;
|
||||
|
||||
if (list && list->menus)
|
||||
{
|
||||
for (int i = 0; i < list->menuCount; i++)
|
||||
{
|
||||
if (list->menus[i] == oldMenu)
|
||||
{
|
||||
list->menus[i] = menu;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Menus::RemoveMenuList(Game::MenuList* menuList)
|
||||
{
|
||||
if (!menuList || !menuList->name) return;
|
||||
@ -503,6 +561,13 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < header.menuList->menuCount; i++)
|
||||
{
|
||||
OutputDebugString(Utils::VA("Menu: %d\t%X\t%s",i + Game::uiContext->menuCount, header.menuList->menus[i], header.menuList->menus[i]->window.name));
|
||||
}
|
||||
|
||||
OutputDebugString(Utils::VA("Loaded menus: %d", header.menuList->menuCount));
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
@ -570,6 +635,29 @@ namespace Components
|
||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENU, Menus::MenuLoad);
|
||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENUFILE, Menus::MenuFileLoad);
|
||||
|
||||
// Reinitialize ui
|
||||
Utils::Hook(0x4BA5C8, static_cast<void(*)(Game::UiContext*, Game::menuDef_t*)>([] (Game::UiContext* context, Game::menuDef_t* menu)
|
||||
{
|
||||
if (menu->window.name == (char*)0xDDDDDDDD)
|
||||
{
|
||||
OutputDebugString("Going to crash!");
|
||||
for (int i = 0; i < context->menuCount; i++)
|
||||
{
|
||||
if(menu == context->menus[i]) OutputDebugString(Utils::VA("Menu crash: %d %X", i, menu));
|
||||
}
|
||||
|
||||
//return;
|
||||
}
|
||||
static bool displayed = false;
|
||||
if (!displayed)
|
||||
{
|
||||
displayed = true;
|
||||
OutputDebugString(Utils::VA("Current menus: %d", context->menuCount));
|
||||
}
|
||||
|
||||
Utils::Hook::Call<void(Game::UiContext*, Game::menuDef_t*)>(0x430D50)(context, menu);
|
||||
}), HOOK_CALL).Install()->Quick();
|
||||
|
||||
// Don't open connect menu
|
||||
Utils::Hook::Nop(0x428E48, 5);
|
||||
|
||||
@ -612,7 +700,7 @@ namespace Components
|
||||
else
|
||||
{
|
||||
// Reinitialize ui context
|
||||
((void(*)())0x401700)();
|
||||
Utils::Hook::Call<void()>(0x401700)();
|
||||
|
||||
// Reopen main menu
|
||||
Game::Menus_OpenByName(Game::uiContext, "main_text");
|
||||
|
@ -20,7 +20,7 @@ namespace Components
|
||||
static std::vector<std::string> CustomMenus;
|
||||
|
||||
static Game::XAssetHeader MenuLoad(Game::XAssetType type, const char* filename);
|
||||
static Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, const char* filename);
|
||||
static Game::XAssetHeader MenuFileLoad(Game::XAssetType type, const char* filename);
|
||||
|
||||
static Game::MenuList* LoadMenuList(Game::MenuList* menuList);
|
||||
static Game::MenuList* LoadScriptMenu(const char* menu);
|
||||
@ -45,6 +45,8 @@ namespace Components
|
||||
static void RemoveMenuList(std::string menuList);
|
||||
static void RemoveMenuList(Game::MenuList* menuList);
|
||||
|
||||
static void OverrideMenu(Game::menuDef_t *menu);
|
||||
|
||||
static bool IsMenuVisible(Game::UiContext *dc, Game::menuDef_t *menu);
|
||||
|
||||
static void RemoveMenuFromContext(Game::UiContext *dc, Game::menuDef_t *menu);
|
||||
|
@ -27,9 +27,9 @@ namespace Game
|
||||
|
||||
Dvar_RegisterBool_t Dvar_RegisterBool = (Dvar_RegisterBool_t)0x4CE1A0;
|
||||
Dvar_RegisterFloat_t Dvar_RegisterFloat = (Dvar_RegisterFloat_t)0x648440;
|
||||
Dvar_RegisterFloat2_t Dvar_RegisterFloat2 = (Dvar_RegisterFloat2_t)0x4F6070;
|
||||
Dvar_RegisterFloat3_t Dvar_RegisterFloat3 = (Dvar_RegisterFloat3_t)0x4EF8E0;
|
||||
Dvar_RegisterFloat4_t Dvar_RegisterFloat4 = (Dvar_RegisterFloat4_t)0x4F28E0;
|
||||
Dvar_RegisterVec2_t Dvar_RegisterVec2 = (Dvar_RegisterVec2_t)0x4F6070;
|
||||
Dvar_RegisterVec3_t Dvar_RegisterVec3 = (Dvar_RegisterVec3_t)0x4EF8E0;
|
||||
Dvar_RegisterVec4_t Dvar_RegisterVec4 = (Dvar_RegisterVec4_t)0x4F28E0;
|
||||
Dvar_RegisterInt_t Dvar_RegisterInt = (Dvar_RegisterInt_t)0x479830;
|
||||
Dvar_RegisterEnum_t Dvar_RegisterEnum = (Dvar_RegisterEnum_t)0x412E40;
|
||||
Dvar_RegisterString_t Dvar_RegisterString = (Dvar_RegisterString_t)0x4FC7E0;
|
||||
|
@ -57,14 +57,14 @@ namespace Game
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat_t)(const char* name, float default, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat_t Dvar_RegisterFloat;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat2_t)(const char* name, float defx, float defy, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat2_t Dvar_RegisterFloat2;
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterVec2_t)(const char* name, float defx, float defy, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterVec2_t Dvar_RegisterVec2;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat3_t)(const char* name, float defx, float defy, float defz, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat3_t Dvar_RegisterFloat3;
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterVec3_t)(const char* name, float defx, float defy, float defz, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterVec3_t Dvar_RegisterVec3;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat4_t)(const char* name, float defx, float defy, float defz, float defw, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat4_t Dvar_RegisterFloat4;
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterVec4_t)(const char* name, float defx, float defy, float defz, float defw, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterVec4_t Dvar_RegisterVec4;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterInt_t)(const char* name, int default, int min, int max, int flags, const char* description);
|
||||
extern Dvar_RegisterInt_t Dvar_RegisterInt;
|
||||
|
@ -1,7 +1,11 @@
|
||||
#define PROTOCOL 0x92
|
||||
|
||||
// This allows us to compile our structures in IDA, for easier reversing :3
|
||||
#ifdef __cplusplus
|
||||
namespace Game
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ASSET_TYPE_PHYSPRESET = 0,
|
||||
@ -115,7 +119,7 @@ namespace Game
|
||||
char pad2[3]; //13:15
|
||||
dvar_value_t current; //16:31
|
||||
dvar_value_t latched; //32:47
|
||||
dvar_value_t default; //48:64
|
||||
dvar_value_t _default; //48:64
|
||||
dvar_maxmin_t min; //65:67
|
||||
dvar_maxmin_t max; //68:72 woooo
|
||||
} dvar_t;
|
||||
@ -270,7 +274,7 @@ namespace Game
|
||||
|
||||
union entryInternalData
|
||||
{
|
||||
operationEnum op;
|
||||
//operationEnum op;
|
||||
Operand operand;
|
||||
};
|
||||
|
||||
@ -1079,7 +1083,7 @@ namespace Game
|
||||
unsigned __int16 usageFrame;
|
||||
};
|
||||
|
||||
enum XFileLanguage : uint8_t
|
||||
enum XFileLanguage : unsigned char
|
||||
{
|
||||
XLANG_NONE = 0x00,
|
||||
XLANG_ENGLISH = 0x01,
|
||||
@ -1102,8 +1106,8 @@ namespace Game
|
||||
#pragma pack(push, 1)
|
||||
struct XFileHeader
|
||||
{
|
||||
uint64_t magic;
|
||||
uint32_t version;
|
||||
unsigned __int64 magic;
|
||||
unsigned int version;
|
||||
XFileLanguage language;
|
||||
DWORD highDateTime;
|
||||
DWORD lowDateTime;
|
||||
@ -1145,7 +1149,7 @@ namespace Game
|
||||
{
|
||||
ScriptStringList stringList;
|
||||
int assetCount;
|
||||
Game::XAsset *assets;
|
||||
XAsset *assets;
|
||||
};
|
||||
|
||||
struct ZoneHeader
|
||||
@ -1204,4 +1208,7 @@ namespace Game
|
||||
{
|
||||
DWORD unk;
|
||||
} PartyData_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -32,7 +32,7 @@
|
||||
#define ZLIB_CONST
|
||||
#define ASIO_STANDALONE
|
||||
#include <zlib.h>
|
||||
#include <asio.hpp>
|
||||
//#include <asio.hpp>
|
||||
#include <json11.hpp>
|
||||
|
||||
// Version number
|
||||
|
Loading…
Reference in New Issue
Block a user