From ec7df07a8e3dd852f396fa38526821cab0a3adbd Mon Sep 17 00:00:00 2001 From: Laz Date: Mon, 6 Jan 2025 21:37:10 +0000 Subject: [PATCH] feat: allow redirecting of save files to be relative to exe --- FLUF.CrashWalker/Include/FLUF.CrashWalker.hpp | 4 +++- FLUF/Include/Fluf.hpp | 10 +++++--- FLUF/Include/Internal/FlufConfiguration.hpp | 1 + FLUF/Source/Fluf.cpp | 24 ++++++++++++++++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/FLUF.CrashWalker/Include/FLUF.CrashWalker.hpp b/FLUF.CrashWalker/Include/FLUF.CrashWalker.hpp index a9b2c64..9cb265e 100644 --- a/FLUF.CrashWalker/Include/FLUF.CrashWalker.hpp +++ b/FLUF.CrashWalker/Include/FLUF.CrashWalker.hpp @@ -18,11 +18,13 @@ struct ErrorPayload class CrashCatcher; class FlufCrashWalker final : public FlufModule { - void LoadErrorPayloadFromCache(std::string_view path); void OnGameLoad() override; void OnDllLoaded(std::string_view dllName, HMODULE dllPtr) override; void OnDllUnloaded(std::string_view dllName, HMODULE dllPtr) override; + + void LoadErrorPayloadFromCache(std::string_view path); static int __stdcall GlobalExceptionHandler(EXCEPTION_POINTERS* exceptionPointers); + inline static std::unique_ptr crashCatcher; inline static std::unique_ptr config; std::vector possibleErrors; diff --git a/FLUF/Include/Fluf.hpp b/FLUF/Include/Fluf.hpp index 6e70a05..600d1ee 100755 --- a/FLUF/Include/Fluf.hpp +++ b/FLUF/Include/Fluf.hpp @@ -34,6 +34,8 @@ struct CShip; struct SStartupInfo; class Fluf { + using GetUserDataPathSig = bool (*)(char*); + friend ClientSend; friend ClientReceive; friend FlufModule; @@ -45,6 +47,8 @@ class Fluf // FLUF can run on the client or server. This becomes true when the process is 'freelancer.exe' bool runningOnClient = false; inline static FARPROC oldServerStartupFunc; + inline static auto getUserDataPathDetour = + FunctionDetour(reinterpret_cast(GetProcAddress(GetModuleHandleA("common.dll"), "?GetUserDataPath@@YA_NQAD@Z"))); // The serverClient receives data from the server IClientImpl* serverClient = nullptr; @@ -58,12 +62,12 @@ class Fluf static void OnUpdateHook(double delta); static void* OnScriptLoadHook(const char* file); + void OnGameLoad() const; + static bool __thiscall OnServerStart(IServerImpl* server, SStartupInfo& info); static HINSTANCE __stdcall LoadLibraryDetour(LPCSTR libName); static BOOL __stdcall FreeLibraryDetour(HMODULE module); - - void OnGameLoad() const; - static bool __thiscall OnServerStart(IServerImpl* server, SStartupInfo& info); + static bool GetUserDataPathDetour(char* path); template struct ReturnType; diff --git a/FLUF/Include/Internal/FlufConfiguration.hpp b/FLUF/Include/Internal/FlufConfiguration.hpp index 8e1376c..c87bc9e 100755 --- a/FLUF/Include/Internal/FlufConfiguration.hpp +++ b/FLUF/Include/Internal/FlufConfiguration.hpp @@ -17,4 +17,5 @@ class FlufConfiguration LogLevel logLevel = LogLevel::Info; std::unordered_set logSinks; std::unordered_set modules; + bool setSaveDirectoryRelativeToExecutable = false; }; diff --git a/FLUF/Source/Fluf.cpp b/FLUF/Source/Fluf.cpp index 84a140c..887f52b 100755 --- a/FLUF/Source/Fluf.cpp +++ b/FLUF/Source/Fluf.cpp @@ -410,12 +410,12 @@ std::string GetLastErrorAsString() // Ask Win32 to give us the string version of that message ID. // The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be). size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, + nullptr, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&messageBuffer, + reinterpret_cast(&messageBuffer), 0, - NULL); + nullptr); // Copy the error message into a std::string. std::string message(messageBuffer, size); @@ -432,6 +432,11 @@ Fluf::Fluf() config = std::make_shared(); config->Load(); + if (config->setSaveDirectoryRelativeToExecutable) + { + getUserDataPathDetour.Detour(GetUserDataPathDetour); + } + std::array fileNameBuffer{}; GetModuleFileNameA(nullptr, fileNameBuffer.data(), MAX_PATH); std::string_view fileName = fileNameBuffer.data(); @@ -529,6 +534,19 @@ Fluf::~Fluf() { loadedModules.pop_back(); } + + if (config->setSaveDirectoryRelativeToExecutable) + { + getUserDataPathDetour.UnDetour(); + } + loadLibraryDetour.UnDetour(); freeLibraryDetour.UnDetour(); } + +bool Fluf::GetUserDataPathDetour(char* path) +{ + constexpr std::string_view newSavePath = R"(..\SAVES)"; + strcpy_s(path, newSavePath.size(), newSavePath.data()); + return true; +}