diff --git a/overlay_experimental/linux/X11_Hook.cpp b/overlay_experimental/linux/X11_Hook.cpp index 5ed6721b..ff795cbf 100644 --- a/overlay_experimental/linux/X11_Hook.cpp +++ b/overlay_experimental/linux/X11_Hook.cpp @@ -101,14 +101,25 @@ bool X11_Hook::StartHook(std::function& _key_combination_callback, s return false; } - XEventsQueued = libX11.GetSymbol("XEventsQueued"); - XPending = libX11.GetSymbol("XPending"); + struct { + void** func_ptr; + void* hook_ptr; + const char* func_name; + } hook_array[] = { + { (void**)&XEventsQueued, &X11_Hook::MyXEventsQueued, "XEventsQueued" }, + { (void**)&XPending , &X11_Hook::MyXPending , "XPending" }, + }; - if (XPending == nullptr || XEventsQueued == nullptr) + for (auto& entry : hook_array) { - SPDLOG_WARN("Failed to hook X11: Cannot load functions.({}, {})", DLL_NAME, (void*)XEventsQueued, (void*)XPending); - return false; + *entry.func_ptr = libX11.GetSymbol(entry.func_name); + if (entry.func_ptr == nullptr) + { + SPDLOG_ERROR("Failed to hook X11: Event function {} missing.", entry.func_name); + return false; + } } + SPDLOG_INFO("Hooked X11"); _KeyCombinationCallback = std::move(_key_combination_callback); @@ -124,12 +135,13 @@ bool X11_Hook::StartHook(std::function& _key_combination_callback, s _Hooked = true; - UnhookAll(); BeginHook(); - HookFuncs( - std::make_pair(&(void*&)XEventsQueued, (void*)&X11_Hook::MyXEventsQueued), - std::make_pair(&(void*&)XPending, (void*)&X11_Hook::MyXPending) - ); + + for (auto& entry : hook_array) + { + HookFunc(std::make_pair(entry.func_ptr, entry.hook_ptr)); + } + EndHook(); } return true; diff --git a/overlay_experimental/windows/Windows_Hook.cpp b/overlay_experimental/windows/Windows_Hook.cpp index 9ae55df4..3ac976bb 100644 --- a/overlay_experimental/windows/Windows_Hook.cpp +++ b/overlay_experimental/windows/Windows_Hook.cpp @@ -93,24 +93,30 @@ bool Windows_Hook::StartHook(std::function& _key_combination_callbac return false; } - GetRawInputBuffer = libUser32.GetSymbol("GetRawInputBuffer"); - GetRawInputData = libUser32.GetSymbol("GetRawInputData"); - GetKeyState = libUser32.GetSymbol("GetKeyState"); - GetAsyncKeyState = libUser32.GetSymbol("GetAsyncKeyState"); - GetKeyboardState = libUser32.GetSymbol("GetKeyboardState"); - GetCursorPos = libUser32.GetSymbol("GetCursorPos"); - SetCursorPos = libUser32.GetSymbol("SetCursorPos"); + struct { + void** func_ptr; + void* hook_ptr; + const char* func_name; + } hook_array[] = { + { (void**)&GetRawInputBuffer, &Windows_Hook::MyGetRawInputBuffer, "GetRawInputBuffer" }, + { (void**)&GetRawInputData , &Windows_Hook::MyGetRawInputData , "GetRawInputData" }, + { (void**)&GetKeyState , &Windows_Hook::MyGetKeyState , "GetKeyState" }, + { (void**)&GetAsyncKeyState , &Windows_Hook::MyGetAsyncKeyState , "GetAsyncKeyState" }, + { (void**)&GetKeyboardState , &Windows_Hook::MyGetKeyboardState , "GetKeyboardState" }, + { (void**)&GetCursorPos , &Windows_Hook::MyGetCursorPos , "GetCursorPos" }, + { (void**)&SetCursorPos , &Windows_Hook::MySetCursorPos , "SetCursorPos" }, + { (void**)&GetClipCursor , &Windows_Hook::MyGetClipCursor , "GetClipCursor" }, + { (void**)&ClipCursor , &Windows_Hook::MyClipCursor , "ClipCursor" }, + }; - if(GetRawInputBuffer == nullptr || - GetRawInputData == nullptr || - GetKeyState == nullptr || - GetAsyncKeyState == nullptr || - GetKeyboardState == nullptr || - GetCursorPos == nullptr || - SetCursorPos == nullptr) + for (auto& entry : hook_array) { - SPDLOG_ERROR("Failed to hook Windows: Events functions missing."); - return false; + *entry.func_ptr = libUser32.GetSymbol(entry.func_name); + if (entry.func_ptr == nullptr) + { + SPDLOG_ERROR("Failed to hook Windows: Events function {} missing.", entry.func_name); + return false; + } } SPDLOG_INFO("Hooked Windows"); @@ -126,15 +132,12 @@ bool Windows_Hook::StartHook(std::function& _key_combination_callbac } BeginHook(); - HookFuncs( - std::make_pair(&(PVOID&)GetRawInputBuffer, &Windows_Hook::MyGetRawInputBuffer), - std::make_pair(&(PVOID&)GetRawInputData , &Windows_Hook::MyGetRawInputData), - std::make_pair(&(PVOID&)GetKeyState , &Windows_Hook::MyGetKeyState), - std::make_pair(&(PVOID&)GetAsyncKeyState , &Windows_Hook::MyGetAsyncKeyState), - std::make_pair(&(PVOID&)GetKeyboardState , &Windows_Hook::MyGetKeyboardState), - std::make_pair(&(PVOID&)GetCursorPos , &Windows_Hook::MyGetCursorPos), - std::make_pair(&(PVOID&)SetCursorPos , &Windows_Hook::MySetCursorPos) - ); + + for (auto& entry : hook_array) + { + HookFunc(std::make_pair(entry.func_ptr, entry.hook_ptr)); + } + EndHook(); _Hooked = true; @@ -289,6 +292,11 @@ LRESULT CALLBACK Windows_Hook::HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, // Save the last known cursor pos when opening the overlay // so we can spoof the GetCursorPos return value. inst->GetCursorPos(&inst->_SavedCursorPos); + inst->GetClipCursor(&inst->_SavedClipCursor); + } + else + { + inst->ClipCursor(&inst->_SavedClipCursor); } inst->_KeyCombinationPushed = true; } @@ -407,16 +415,33 @@ BOOL WINAPI Windows_Hook::MySetCursorPos(int X, int Y) { Windows_Hook* inst = Windows_Hook::Inst(); - if (inst->_Initialized && inst->_KeyCombinationCallback(false)) - {// That way, it will fail only if the real API fails. - // Hides error messages on some Unity debug builds. - POINT pos; - inst->GetCursorPos(&pos); - X = pos.x; - Y = pos.y; - } + if (!inst->_Initialized || !inst->_KeyCombinationCallback(false)) + return inst->SetCursorPos(X, Y); - return inst->SetCursorPos(X, Y); + return TRUE; +} + +BOOL WINAPI Windows_Hook::MyGetClipCursor(RECT* lpRect) +{ + Windows_Hook* inst = Windows_Hook::Inst(); + if (lpRect == nullptr || !inst->_Initialized || !inst->_KeyCombinationCallback(false)) + return inst->GetClipCursor(lpRect); + + *lpRect = inst->_SavedClipCursor; + return TRUE; +} + +BOOL WINAPI Windows_Hook::MyClipCursor(CONST RECT* lpRect) +{ + Windows_Hook* inst = Windows_Hook::Inst(); + CONST RECT* v = lpRect == nullptr ? &inst->_DefaultClipCursor : lpRect; + + inst->_SavedClipCursor = *v; + + if (!inst->_Initialized || !inst->_KeyCombinationCallback(false)) + return inst->ClipCursor(v); + + return inst->ClipCursor(&inst->_DefaultClipCursor); } ///////////////////////////////////////////////////////////////////////////////////// @@ -427,12 +452,8 @@ Windows_Hook::Windows_Hook() : _RecurseCallCount(0), _GameHwnd(nullptr), _GameWndProc(nullptr), - _KeyCombinationPushed(false), - GetRawInputBuffer(nullptr), - GetRawInputData(nullptr), - GetKeyState(nullptr), - GetAsyncKeyState(nullptr), - GetKeyboardState(nullptr) + _DefaultClipCursor{ LONG(0xFFFF8000), LONG(0xFFFF8000), LONG(0x00007FFF), LONG(0x00007FFF) }, + _KeyCombinationPushed(false) { } diff --git a/overlay_experimental/windows/Windows_Hook.h b/overlay_experimental/windows/Windows_Hook.h index c25a176b..1f11fdba 100644 --- a/overlay_experimental/windows/Windows_Hook.h +++ b/overlay_experimental/windows/Windows_Hook.h @@ -37,6 +37,8 @@ private: HWND _GameHwnd; WNDPROC _GameWndProc; POINT _SavedCursorPos; + RECT _SavedClipCursor; + CONST RECT _DefaultClipCursor; // In (bool): Is toggle wanted // Out(bool): Is the overlay visible, if true, inputs will be disabled @@ -55,6 +57,8 @@ private: decltype(::GetKeyboardState) *GetKeyboardState; decltype(::GetCursorPos) *GetCursorPos; decltype(::SetCursorPos) *SetCursorPos; + decltype(::GetClipCursor) *GetClipCursor; + decltype(::ClipCursor) *ClipCursor; static LRESULT CALLBACK HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static UINT WINAPI MyGetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader); @@ -64,6 +68,8 @@ private: static BOOL WINAPI MyGetKeyboardState(PBYTE lpKeyState); static BOOL WINAPI MyGetCursorPos(LPPOINT lpPoint); static BOOL WINAPI MySetCursorPos(int X, int Y); + static BOOL WINAPI MyGetClipCursor(RECT* lpRect); + static BOOL WINAPI MyClipCursor(CONST RECT* lpRect); public: std::string LibraryName;