diff --git a/Metal Gear Solid Delta/dllmain.cpp b/Metal Gear Solid Delta/dllmain.cpp index 0cd5045..d450d8a 100644 --- a/Metal Gear Solid Delta/dllmain.cpp +++ b/Metal Gear Solid Delta/dllmain.cpp @@ -1,5 +1,6 @@ #include "Memory.hpp"; #include "Maths.hpp"; +#include "UEngine.hpp"; #include "ObfuscateString.h" #include #include @@ -7,7 +8,6 @@ #include #include #include -//#include "SDK/Basic.hpp" #include "SDK/Engine_classes.hpp" using namespace SDK; @@ -50,6 +50,7 @@ static int g_AdditionalFOVValue = 0; static float g_FOV_In = 0; static float g_Compensated_FOV = 0; static float g_FOV_Out = 0; +static bool g_Console_Enabled = false; // AOB Scan pointers static uint8_t* FOVaddress = nullptr; @@ -63,6 +64,13 @@ static uint8_t* CAaddress = nullptr; static uint8_t* Vignettingaddress = nullptr; static uint8_t* Fogaddress = nullptr; +// AOB Unreal Engine offsets addresses +static uint8_t* GObjectsaddress = nullptr; +static uint8_t* GNamesaddress = nullptr; +static uint8_t* GetNameEntryaddress = nullptr; +static uint8_t* AppendStringaddress = nullptr; +static uint8_t* ProcessEventaddress = nullptr; + // Hooking static SafetyHookMid FOVHook{}; static SafetyHookMid FPSHook{}; @@ -238,7 +246,7 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled, bool init) else { logger->info("Fog signature found at address: 0x{:X}.", reinterpret_cast(Fogaddress)); Fogaddress += 0xd; - } + } } if (FOVaddress && Resolutionaddress_1 && FPSaddress && Aspectaddress && AspectMenuaddress && @@ -246,8 +254,57 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled, bool init) logger->info("All AOB signatures found. Ready to patch..."); AOBScanDone = true; } + // Unreal Engine Offsets updates (needed when the game reveives an update and to prevent the fix from crashing the game) + if (!GObjectsaddress || !AppendStringaddress || !ProcessEventaddress) { + logger->info("------------ UEngine offsets search ------------"); - logger->info("--------------- AOB scan finished ---------------"); + constexpr auto GObjetcsStringObfuscated = make_obfuscated<0x4A>("48 8B ?? ?? ?? ?? ?? 48 8B ?? ?? 48 8D ?? ?? EB ?? 33"); + GObjectsaddress = Memory::AOBScan(gameExecutable, GObjetcsStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + constexpr auto GNamesStringObfuscated = make_obfuscated<0x4A>("8B 05 ?? ?? ?? ?? 0F B7 ?? ?? FF ?? 3B ?? 73"); + GNamesaddress = Memory::AOBScan(gameExecutable, GNamesStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + constexpr auto AppendStringStringObfuscated = make_obfuscated<0x4A>("48 89 ?? ?? ?? ?? ?? ?? 48 81 ?? ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 48 ?? ?? 48 89 ?? ?? ?? ?? ?? ?? 0F ?? ?? 48 8B"); + AppendStringaddress = Memory::AOBScan(gameExecutable, AppendStringStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + constexpr auto ProcessEventStringObfuscated = make_obfuscated<0x4A>("40 ?? 56 57 41 ?? 41 ?? 41 ?? 41 ?? 48 81 ?? ?? ?? ?? ?? 48 8D ?? ?? ?? 48 89 ?? ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 48 33 ?? 48 89 ?? ?? ?? ?? ?? 4D ?? ?? 48"); + ProcessEventaddress = Memory::AOBScan(gameExecutable, ProcessEventStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + + if (!GObjectsaddress) + logger->warn("GObjects signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else { + uint32_t gObjectsOffset = static_cast(Memory::GetOffsetFromOpcode(GObjectsaddress + 0x3) - + reinterpret_cast(GetModuleHandleA(gameExecutable.c_str()))); + logger->info("GObjects offset is: 0x{:X}.", gObjectsOffset); + Offsets::GObjects = static_cast(gObjectsOffset); // Update GObjects offset + } + + if (!GNamesaddress) + logger->warn("GNames signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else { + uint32_t gNamesOffset = static_cast(Memory::GetOffsetFromOpcode(GNamesaddress + 0x2) - + reinterpret_cast(GetModuleHandleA(gameExecutable.c_str()))); + logger->info("GNames offset is: 0x{:X}.", gNamesOffset); + Offsets::GNames = static_cast(gNamesOffset); // Update GNames offset + } + + if (!AppendStringaddress) + logger->warn("AppendString signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else { + std::optional gAppendStringOffsetOpt = UE::CalculateOffset(gameExecutable, AppendStringaddress); // Get Offset from opcode + uint32_t gAppendStringOffset = *gAppendStringOffsetOpt; + logger->info("AppendString offset is: 0x{:X}.", gAppendStringOffset); + Offsets::AppendString = static_cast(gAppendStringOffset); // Update AppendString offset + } + + if (!ProcessEventaddress) + logger->warn("Process Event signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else { + std::optional gProcessEventOffsetOpt = UE::CalculateOffset(gameExecutable, ProcessEventaddress); + uint32_t gProcessEventOffset = *gProcessEventOffsetOpt; + logger->info("Process Event offset is: 0x{:X}.", gProcessEventOffset); + Offsets::ProcessEvent = static_cast(gProcessEventOffset);// Update ProcessEvent offset + } + } + + logger->info("-------------- Fixes initialisation -------------"); } if (g_fix_enabled) { if (FOVaddress) FOVFixEnabled(g_fov_fix_enabled || g_aspect_fix_enabled); @@ -270,7 +327,7 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled, bool init) if (Fogaddress) FogFixEnabled(false); logger->info("All fixes disabled."); } - if (AOBScanDone) + if (!g_Console_Enabled && GObjectsaddress && GNamesaddress && AppendStringaddress && ProcessEventaddress) EnableConsole(); } @@ -341,6 +398,10 @@ extern "C" __declspec(dllexport) float GetFOVOut() { return g_FOV_Out; } +extern "C" __declspec(dllexport) bool GetConsoleEnabled() { + return g_Console_Enabled; +} + // Code injection functions static void FOVFixEnabled(bool fix_enabled) { if (g_fix_enabled && fix_enabled && FOVaddress) { @@ -488,7 +549,15 @@ static void FogFixEnabled(bool fix_enabled) { // UE Console creation static void EnableConsole() { + logger->info("-------------- Console re-enabling --------------"); + if (!GObjectsaddress || !GNamesaddress || !AppendStringaddress || !ProcessEventaddress) { + logger->warn("Could not re-enable console"); + logger->info("------------------ User inputs ------------------"); + return; + } + std::thread([&]() { + auto start = std::chrono::high_resolution_clock::now(); // Measure the time to renable console UEngine* Engine = nullptr; for (int i = 0; i < 100; ++i) { // gives 10 seconds to find UE Engine @@ -498,20 +567,30 @@ static void EnableConsole() if (Engine && Engine->ConsoleClass && Engine->GameViewport) break; } - if (!Engine || !Engine->ConsoleClass || !Engine->GameViewport) + + if (!Engine || !Engine->ConsoleClass || !Engine->GameViewport) { + logger->error("Console could not be found in engine."); return; + } + logger->info("Console found in engine"); /* Creates a new UObject of class-type specified by Engine->ConsoleClass */ UObject* NewObject = UGameplayStatics::SpawnObject(Engine->ConsoleClass, Engine->GameViewport); if (NewObject) { + logger->info("Successfully spawned console object"); // Set the console viewport so that it will be displayed Engine->GameViewport->ViewportConsole = static_cast(NewObject); - // Set the all the console shortkey to F8 - for (int i = 0; i < UInputSettings::GetDefaultObj()->ConsoleKeys.Num(); i++) - { - UInputSettings::GetDefaultObj()->ConsoleKeys[i].KeyName = UKismetStringLibrary::Conv_StringToName(L"F8"); - } + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = end - start; + + logger->info("Console fully reactivated in {:.3f}s and bound to key Tilde", elapsed.count()); + logger->info("------------------ User inputs ------------------"); + + g_Console_Enabled = true; + } + else { + logger->error("Could not spawn console object"); } }).detach(); }