diff --git a/BG3Updater/BG3Updater.vcxproj b/BG3Updater/BG3Updater.vcxproj index fbd58849..321af672 100644 --- a/BG3Updater/BG3Updater.vcxproj +++ b/BG3Updater/BG3Updater.vcxproj @@ -93,14 +93,14 @@ true stdcpplatest MultiThreadedDebugDLL - $(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm + $(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm;$(SolutionDir)External\SDL2-2.30.1\include;$(SolutionDir)External\Detours\include Windows true - CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + detours.lib;SDL2.lib;CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) Exports.def - $(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Debug;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Debug + $(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Debug;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Debug;$(SolutionDir)\External\SDL2-2.30.1\lib\x64;$(SolutionDir)\External\Detours\lib.X64 copy /Y "$(TargetPath)" "D:\SteamLibrary\steamapps\common\Baldurs Gate 3\bin\DWrite.dll" @@ -154,7 +154,7 @@ MultiThreaded Size false - $(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm + $(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm;$(SolutionDir)External\SDL2-2.30.1\include;$(SolutionDir)External\Detours\include Windows @@ -162,8 +162,8 @@ true true Exports.def - CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Release;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Release + detours.lib;SDL2.lib;CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Release;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Release;$(SolutionDir)\External\SDL2-2.30.1\lib\x64;$(SolutionDir)\External\Detours\lib.X64 copy /Y "$(TargetPath)" "D:\SteamLibrary\steamapps\common\Baldurs Gate 3\bin\DWrite.dll" diff --git a/BG3Updater/Resources.rc b/BG3Updater/Resources.rc index b9fd90c3..0c462359 100644 Binary files a/BG3Updater/Resources.rc and b/BG3Updater/Resources.rc differ diff --git a/BG3Updater/Updater.cpp b/BG3Updater/Updater.cpp index 9d133393..8c02ddb5 100644 --- a/BG3Updater/Updater.cpp +++ b/BG3Updater/Updater.cpp @@ -3,11 +3,16 @@ #include "HttpFetcher.h" #include #include +#include #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") BEGIN_SE() +std::unordered_set gRegisteredTrampolines; + +WrappableFunction* WrappableFunction::gHook; + ManifestFetcher::ManifestFetcher(HttpFetcher& fetcher, UpdaterConfig const& config) : fetcher_(fetcher), config_(config) {} @@ -322,6 +327,7 @@ void ScriptExtenderUpdater::Initialize(char const* exeDirOverride) UpdateExeDir(exeDirOverride); LoadConfig(); LoadGameVersion(); + HookSDL(); } void ScriptExtenderUpdater::UpdateExeDir(char const* exeDirOverride) @@ -377,6 +383,32 @@ void ScriptExtenderUpdater::LoadGameVersion() } } +void ScriptExtenderUpdater::HookSDL() +{ + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + SDLInitHook.Wrap(ResolveFunctionTrampoline(&SDL_Init)); + SDLInitHook.SetPostHook(&ScriptExtenderUpdater::OnSDLInit, this); + DetourTransactionCommit(); +} + +void ScriptExtenderUpdater::UnhookSDL() +{ + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + SDLInitHook.Unwrap(); + DetourTransactionCommit(); +} + +void ScriptExtenderUpdater::OnSDLInit(Uint32, int) +{ + while (needsClientSuspend_) { + Sleep(10); + } + + UnhookSDL(); +} + void ScriptExtenderUpdater::UpdatePaths() { auto cacheDir = config_.CachePath; @@ -481,28 +513,13 @@ HRESULT UpdaterUI::UICallback(HWND hwnd, UINT uNotification, WPARAM wParam, LPAR return S_OK; } -volatile bool NeedsClientSuspend{ false }; - -DWORD WINAPI DelayedClientSuspenderThread(LPVOID param) -{ - Sleep(1000); - if (NeedsClientSuspend) { - DEBUG("Suspending client thread"); - gGameHelpers->SuspendClientThread(); - } - return 0; -} - DWORD WINAPI UpdaterThread(LPVOID param) { gUpdater->InitConsole(); gUpdater->InitUI(); DEBUG("Launch loader"); - NeedsClientSuspend = true; - CreateThread(NULL, 0, &DelayedClientSuspenderThread, NULL, 0, NULL); gUpdater->Run(); - NeedsClientSuspend = false; - gGameHelpers->ResumeClientThread(); + gUpdater->RequestClientSuspend(false); DEBUG("Extender launcher thread exiting"); return 0; } @@ -518,6 +535,7 @@ void StartUpdaterThread() gUpdater = std::make_unique(); gUpdater->Initialize(nullptr); + gUpdater->RequestClientSuspend(true); CreateThread(NULL, 0, &UpdaterThread, NULL, 0, NULL); } diff --git a/BG3Updater/Updater.h b/BG3Updater/Updater.h index 040e2b53..2801e8fa 100644 --- a/BG3Updater/Updater.h +++ b/BG3Updater/Updater.h @@ -2,6 +2,8 @@ #include "Cache.h" #include "HttpFetcher.h" #include +#include +#include BEGIN_SE() @@ -125,12 +127,19 @@ class ScriptExtenderUpdater return cancellingUpdate_; } + void RequestClientSuspend(bool suspend) + { + needsClientSuspend_ = suspend; + } + void Initialize(char const* exeDirOverride); void Run(); void LoadCaches(); bool FetchUpdates(); bool LoadExtender(); + enum class SDLInitTag {}; + private: VersionNumber gameVersion_; UpdaterConfig config_; @@ -145,11 +154,17 @@ class ScriptExtenderUpdater bool completed_{ false }; bool cancellingUpdate_{ false }; std::string log_; + volatile bool needsClientSuspend_{ false }; + + WrappableFunction SDLInitHook; void UpdatePaths(); void UpdateExeDir(char const* exeDirOverride); void LoadConfig(); void LoadGameVersion(); + void HookSDL(); + void UnhookSDL(); + void OnSDLInit(Uint32, int); }; void StartUpdaterThread(); diff --git a/BG3Updater/resource.h b/BG3Updater/resource.h index 48487869..b30d83ed 100644 --- a/BG3Updater/resource.h +++ b/BG3Updater/resource.h @@ -2,8 +2,8 @@ // Microsoft Visual C++ generated include file. // Used by Resources.rc -#define UPDATER_DLL_MAJOR_VERSION 1 -#define UPDATER_DLL_VERSION_STRING "1.0.0.0" +#define UPDATER_DLL_MAJOR_VERSION 5 +#define UPDATER_DLL_VERSION_STRING "5.0.0.0" #define IDR_BINARY_MAPPINGS 101