diff --git a/src/scripting/LuaVM.h b/src/scripting/LuaVM.h index 356e73d5..8d820399 100644 --- a/src/scripting/LuaVM.h +++ b/src/scripting/LuaVM.h @@ -59,6 +59,7 @@ struct LuaVM static void HookLog(RED4ext::IScriptable*, RED4ext::CStackFrame* apStack, void*, void*); static void HookLogChannel(RED4ext::IScriptable*, RED4ext::CStackFrame* apStack, void*, void*); + static void HookTDBIDToStringDEBUG(RED4ext::IScriptable*, RED4ext::CStackFrame* apStack, void* apResult, void*); static TDBID* HookTDBIDCtorDerive(TDBID* apBase, TDBID* apThis, const char* acpName); static bool HookRunningStateRun(uintptr_t aThis, uintptr_t aApp); static uintptr_t HookSetLoadingState(uintptr_t aThis, int aState); @@ -72,6 +73,7 @@ struct LuaVM RED4ext::OpcodeHandlers::Handler_t m_realLog{ nullptr }; RED4ext::OpcodeHandlers::Handler_t m_realLogChannel{nullptr}; + RED4ext::OpcodeHandlers::Handler_t m_realTDBIDToStringDEBUG{nullptr}; TTDBIDCtorDerive* m_realTDBIDCtorDerive{ nullptr }; TRunningStateRun* m_realRunningStateRun{ nullptr }; TSetLoadingState* m_realSetLoadingState{ nullptr }; diff --git a/src/scripting/LuaVM_Hooks.cpp b/src/scripting/LuaVM_Hooks.cpp index 87024287..30fc14a7 100644 --- a/src/scripting/LuaVM_Hooks.cpp +++ b/src/scripting/LuaVM_Hooks.cpp @@ -98,6 +98,24 @@ TDBID* LuaVM::HookTDBIDCtorDerive(TDBID* apBase, TDBID* apThis, const char* acpN return result; } +void LuaVM::HookTDBIDToStringDEBUG(RED4ext::IScriptable*, RED4ext::CStackFrame* apStack, void* apResult, void*) +{ + TDBID tdbid; + apStack->unk30 = 0; + apStack->unk38 = 0; + apStack->currentParam++; + uint8_t opcode = *(apStack->code++); + RED4ext::OpcodeHandlers::Run(opcode, apStack->context, apStack, &tdbid, nullptr); + apStack->code++; // skip ParamEnd + + if (apResult) + { + std::string name = CET::Get().GetVM().GetTDBIDString(tdbid.value); + RED4ext::CString s(name.c_str()); + *static_cast(apResult) = s; + } +} + bool LuaVM::HookRunningStateRun(uintptr_t aThis, uintptr_t aApp) { auto& luavm = CET::Get().GetVM(); @@ -198,6 +216,32 @@ void LuaVM::Hook(Options& aOptions) } } + { + const mem::pattern cPattern("48 BF 58 D1 78 A0 18 09 BA EC 75 16 48 8D 15 ? ? ? ? 48 8B CF E8 ? ? ? ? C6 05 ?? " + "?? ?? ?? 01 41 8B 06 39 05 ? ? ? ? 7F"); + const mem::default_scanner cScanner(cPattern); + uint8_t* pLocation = cScanner(gameImage.TextRegion).as(); + if (pLocation) + { + pLocation = &pLocation[45] + static_cast(pLocation[44]); + mem::region reg(pLocation, 45); + const mem::pattern cSecondaryPattern( + "48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 3D ?? ?? ?? ?? FF 75 ?? 48 8D 05"); + const mem::default_scanner cSecondaryScanner(cSecondaryPattern); + pLocation = cSecondaryScanner(reg).as(); + if (pLocation) + { + pLocation = &pLocation[28] + *reinterpret_cast(&pLocation[24]); + if (MH_CreateHook(pLocation, &HookTDBIDToStringDEBUG, + reinterpret_cast(&m_realTDBIDToStringDEBUG)) != MH_OK || + MH_EnableHook(pLocation) != MH_OK) + spdlog::error("Could not hook TDBID::ToStringDEBUG function!"); + else + spdlog::info("TDBID::ToStringDEBUG function hook complete!"); + } + } + } + // Disable SetLoadingState hook temporarily and get back to log count workaround // as it introduces major breaking change for onInit handler. //{