From db47a296d0f9021aeebe22db2f46b3865b49b2ec Mon Sep 17 00:00:00 2001 From: Indra Date: Sat, 20 Jan 2024 04:23:14 +0100 Subject: [PATCH] Add patterns for showing menu in all games --- src/Hook.cpp | 42 ++++++++++++++++++-- src/Hook.h | 1 + src/cdc/render/PCDeviceManager.cpp | 9 ++++- src/game/Game.cpp | 9 +++-- src/game/Game.h | 6 +-- src/modules/Module.h | 8 ++++ src/render/Font.cpp | 62 ++++++++++++++++++++++++++++++ src/render/Font.h | 20 ++++++++++ src/render/RenderContext.cpp | 10 ++++- src/util/Hooking.h | 16 +++++++- 10 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 src/render/Font.cpp create mode 100644 src/render/Font.h diff --git a/src/Hook.cpp b/src/Hook.cpp index 3dec70c..9e573a3 100644 --- a/src/Hook.cpp +++ b/src/Hook.cpp @@ -1,13 +1,19 @@ #include +#include #include "Hook.h" #include "input/MessageHook.h" #include "instance/Instances.h" #include "game/Game.h" +#include "render/Font.h" // Modules +#include "modules/MainMenu.h" #include "modules/InstanceViewer.h" #include "modules/Skew.h" +#include "modules/Render.h" +#include "modules/Draw.h" +#include "modules/Log.h" #include "cdc/render/PCDeviceManager.h" @@ -15,6 +21,9 @@ using namespace std::placeholders; static bool(*s_D3D_Init)(); +// Pointer to the cdc::DeviceManager::s_pInstance pointer +static void* s_deviceManager; + static bool D3D_Init() { // Initialize the device @@ -32,12 +41,19 @@ Hook::Hook() : m_menu(nullptr), m_modules() void Hook::Initialize() { - Game::Init(); - RegisterModules(); +#ifndef TR8 + auto match = hook::pattern("A1 ? ? ? ? 8B 0D ? ? ? ? 68 ? ? ? ? 50 E8").count(1); + s_deviceManager = *match.get_first(7); +#else + auto match = hook::pattern("8B 0D ? ? ? ? 8B 01 8B 15 ? ? ? ? 8B 00 68").count(1); + s_deviceManager = *match.get_first(2); +#endif + + // Create the initial hook MH_Initialize(); - MH_CreateHook((void*)0x4153E0, D3D_Init, (void**)&s_D3D_Init); + MH_CreateHook(match.get_first(), D3D_Init, (void**)&s_D3D_Init); MH_EnableHook(MH_ALL_HOOKS); } @@ -48,6 +64,10 @@ void Hook::PostInitialize() // Register the message hook MessageHook::OnMessage(std::bind(&Hook::OnMessage, this, _1, _2, _3, _4)); + +#ifndef TR8 + Font::OnFlush(std::bind(&Hook::OnFrame, this)); +#endif } void Hook::OnMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -60,10 +80,18 @@ void Hook::OnMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } } +void Hook::OnFrame() +{ + for (auto& mod : m_modules) + { + mod->OnFrame(); + } +} + void Hook::OnDevice() { // Assign the DeviceManager instance - cdc::PCDeviceManager::s_pInstance = *(cdc::PCDeviceManager**)0xA6669C; + cdc::PCDeviceManager::s_pInstance = *(cdc::PCDeviceManager**)s_deviceManager; // Initialize the hook PostInitialize(); @@ -79,8 +107,14 @@ void Hook::RegisterModule() void Hook::RegisterModules() { + RegisterModule(); RegisterModule(); RegisterModule(); +#ifndef TR8 + RegisterModule(); + RegisterModule(); + RegisterModule(); +#endif } Hook& Hook::GetInstance() diff --git a/src/Hook.h b/src/Hook.h index a053ef1..fee81fa 100644 --- a/src/Hook.h +++ b/src/Hook.h @@ -20,6 +20,7 @@ class Hook void RegisterModules(); void OnMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + void OnFrame(); public: Hook(); diff --git a/src/cdc/render/PCDeviceManager.cpp b/src/cdc/render/PCDeviceManager.cpp index ed595e5..27efc8a 100644 --- a/src/cdc/render/PCDeviceManager.cpp +++ b/src/cdc/render/PCDeviceManager.cpp @@ -1,3 +1,5 @@ +#include + #include "PCDeviceManager.h" cdc::PCDeviceManager* cdc::PCDeviceManager::s_pInstance = nullptr; @@ -24,7 +26,12 @@ HWND cdc::PCDeviceManager::GetWindow() void cdc::PCDeviceManager::AddDeviceResource(PCInternalResource* resource) { - auto func = reinterpret_cast(0x00616F10); +#ifndef TR8 + auto match = hook::pattern("8B 41 08 33 D2 3B C2 8B 44 24 04").count(1); +#else + auto match = hook::pattern("8B 44 24 04 33 D2 39 51 08 89 50").count(1); +#endif + auto func = (void(__thiscall*)(PCDeviceManager*, PCInternalResource*))match.get_first(); func(this, resource); } \ No newline at end of file diff --git a/src/game/Game.cpp b/src/game/Game.cpp index 78a087a..bb5f7f2 100644 --- a/src/game/Game.cpp +++ b/src/game/Game.cpp @@ -1,8 +1,6 @@ #include "Game.h" -void Game::Init() -{ -} +#include "util/Hooking.h" Instance* Game::GetPlayerInstance() { @@ -12,4 +10,9 @@ Instance* Game::GetPlayerInstance() GameTracker* Game::GetGameTracker() { return (GameTracker*)0x838330; +} + +void GAMELOOP_ExitGame(char* name, GameTracker* gameTracker, int doneType) +{ + Hooking::Call(0xC61CFA, name, gameTracker, doneType); } \ No newline at end of file diff --git a/src/game/Game.h b/src/game/Game.h index 9e0b187..6721d52 100644 --- a/src/game/Game.h +++ b/src/game/Game.h @@ -54,8 +54,8 @@ struct GameTracker class Game { public: - static void Init(); - static Instance* GetPlayerInstance(); static GameTracker* GetGameTracker(); -}; \ No newline at end of file +}; + +void GAMELOOP_ExitGame(char* name, GameTracker* gameTracker, int doneType); \ No newline at end of file diff --git a/src/modules/Module.h b/src/modules/Module.h index e2a8d95..b34c737 100644 --- a/src/modules/Module.h +++ b/src/modules/Module.h @@ -5,7 +5,15 @@ class Module { public: + // Called during drawing of the main menu bar, can be used to add menu items virtual void OnMenu() { }; + + // Called during menu drawing, used for ImGui draw code virtual void OnDraw() { }; + + // Called just before a frame ends, Font::Flush to be specific + virtual void OnFrame() { }; + + // Called when a message is processed by the window procedure virtual void OnInput(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { }; }; \ No newline at end of file diff --git a/src/render/Font.cpp b/src/render/Font.cpp new file mode 100644 index 0000000..d059d26 --- /dev/null +++ b/src/render/Font.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include + +#include "Font.h" +#include "util/Hooking.h" + +static std::function s_callback; + +// Font::Flush +static void(* s_Flush)(); + +static void Flush() +{ + s_callback(); + s_Flush(); +} + +char Font::s_formatted[1024]; + +Font* Font::GetMainFont() +{ + return *(Font**)0x7D1800; +} + +void Font::SetCursor(float x, float y) +{ + Hooking::Call(0x433C70, x, y); +} + +void Font::SetScale(float scaleX, float scaleY) +{ + Hooking::Call(0x433E60, scaleX, scaleY); +} + +void Font::Print(const char* fmt, ...) +{ + va_list va; + + va_start(va, fmt); + vsprintf_s(s_formatted, fmt, va); + va_end(va); + + PrintFormatted(s_formatted); +} + +void Font::PrintFormatted(const char* formatted, int backdrop) +{ + Hooking::ThisCall(0x434A70, this, formatted, backdrop); +} + +void Font::OnFlush(std::function callback) +{ + if (!s_callback) + { + MH_CreateHook((void*)0x434C40, Flush, (void**)&s_Flush); + MH_EnableHook(MH_ALL_HOOKS); + } + + s_callback = callback; +} \ No newline at end of file diff --git a/src/render/Font.h b/src/render/Font.h new file mode 100644 index 0000000..b9a0ab5 --- /dev/null +++ b/src/render/Font.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class Font +{ +private: + static char s_formatted[1024]; + +public: + static Font* GetMainFont(); + + static void SetCursor(float x, float y); + static void SetScale(float scaleX, float scaleY); + + void Print(const char* fmt, ...); + void PrintFormatted(const char* formatted, int backdrop = 0); + + static void OnFlush(std::function callback); +}; \ No newline at end of file diff --git a/src/render/RenderContext.cpp b/src/render/RenderContext.cpp index 721c051..d3a0700 100644 --- a/src/render/RenderContext.cpp +++ b/src/render/RenderContext.cpp @@ -1,5 +1,5 @@ #include - +#include #include #include "RenderContext.h" @@ -19,7 +19,13 @@ void RenderContext::OnPresent(std::function callback) { if (!s_callback) { - MH_CreateHook((void*)0x61BB80, Present, (void**)&s_Present); +#ifndef TR8 + auto match = hook::pattern("8B 41 14 85 C0 74 19 8B 54 24 0C").count(1); +#else + auto match = hook::pattern("A1 ? ? ? ? 83 78 10 00 75 39 80 B8").count(1); +#endif + + MH_CreateHook(match.get_first(), Present, (void**)&s_Present); MH_EnableHook(MH_ALL_HOOKS); } diff --git a/src/util/Hooking.h b/src/util/Hooking.h index 824ca3c..67aa738 100644 --- a/src/util/Hooking.h +++ b/src/util/Hooking.h @@ -17,4 +17,18 @@ class Hooking { reinterpret_cast(address)(args...); } -}; \ No newline at end of file + + // Calls a class function + template + static inline void ThisCall(unsigned int address, Args... args) + { + reinterpret_cast(address)(args...); + } + + // Calls a class function with a return value + template + static inline T ThisCallReturn(unsigned int address, Args... args) + { + reinterpret_cast(address)(args...); + } +};