diff --git a/src/ProtoInput/ProtoInputHooks/BlockXinputHook.cpp b/src/ProtoInput/ProtoInputHooks/BlockXinputHook.cpp deleted file mode 100644 index ea6df2e..0000000 --- a/src/ProtoInput/ProtoInputHooks/BlockXinputHook.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "BlockXinputHook.h" -#include -#include - -namespace Proto -{ - - DWORD WINAPI Hook_XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState) - { - return ERROR_SUCCESS; - } - DWORD WINAPI Hook_XInputGetStateEx(DWORD dwUserIndex, XINPUT_STATE* pState) - { - return ERROR_SUCCESS; - } - - DWORD WINAPI Hook_XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration) - { - return ERROR_SUCCESS; - } - - - void BlockXinputHook::ShowGuiStatus() - { - - ImGui::Separator(); - ImGui::Text("This hook blocks Xinput Controllers from being discovered by game."); - } - - void BlockXinputHook::InstallImpl() - { - // Some games (e.g. Terraria) haven't loaded the dlls when we inject hooks. So load all XInput dlls. - const wchar_t* xinputNames[] = { - L"xinput1_3.dll", L"xinput1_4.dll", L"xinput1_2.dll", L"xinput1_1.dll", L"xinput9_1_0.dll" - }; - for (const auto xinputName : xinputNames) - { - if (LoadLibraryW(xinputName) == nullptr) - { - fprintf(stderr, "Not hooking %ws as failed to load dll\n", xinputName); - continue; - } - - if (GetModuleHandleW(xinputName) == nullptr) - { - fprintf(stderr, "Not hooking %ws as failed get module\n", xinputName); - continue; - } - - hookInfos.push_back(std::get<1>(InstallNamedHook(xinputName, "XInputGetState", Hook_XInputGetState))); - hookInfos.push_back(std::get<1>(InstallNamedHook(xinputName, "XInputSetState", Hook_XInputSetState))); - } - //XinputGetStateEx (hidden call, ordinal 100). Only present in xinput1_4.dll and xinput1_3.dll. Used by EtG and DoS2 - //DWORD as 1st param and similar structure pointer for 2nd param (with an extra DWORD at the end). Can be treated as a normal XINPUT_STATE. - if (nullptr != LoadLibraryW(L"xinput1_4.dll")) - { - hookInfos.push_back(std::get<1>(InstallNamedHook(L"xinput1_4.dll", (LPCSTR)(100), Hook_XInputGetStateEx, true))); - } - if (nullptr != LoadLibraryW(L"xinput1_3.dll")) - { - hookInfos.push_back(std::get<1>(InstallNamedHook(L"xinput1_3.dll", (LPCSTR)(100), Hook_XInputGetStateEx, true))); - - XInputGetStateExPtr = t_XInputGetStateEx(GetProcAddress(GetModuleHandleW(L"xinput1_3.dll"), (LPCSTR)(100))); - XInputGetStatePtr = t_XInputGetState(GetProcAddress(GetModuleHandleW(L"xinput1_3.dll"), "XInputGetState")); - XInputSetStatePtr = t_XInputSetState(GetProcAddress(GetModuleHandleW(L"xinput1_3.dll"), "XInputSetState")); - - if (XInputGetStateExPtr == nullptr) - MessageBoxA(NULL, "XInputGetStateExPtr is null", "Error", MB_OK); - - if (XInputGetStatePtr == nullptr) - MessageBoxA(NULL, "XInputGetStatePtr is null", "Error", MB_OK); - - if (XInputSetStatePtr == nullptr) - MessageBoxA(NULL, "XInputSetStatePtr is null", "Error", MB_OK); - - if (XInputGetCapabilitiesPtr == nullptr) - MessageBoxA(NULL, "XInputGetCapabilitiesPtr is null", "Error", MB_OK); - } - - void BlockXinputHook::UninstallImpl() - { - UninstallHook(&hookInfoBlockXinput); - } - -} diff --git a/src/ProtoInput/ProtoInputHooks/BlockXinputHook.h b/src/ProtoInput/ProtoInputHooks/BlockXinputHook.h deleted file mode 100644 index b8f786b..0000000 --- a/src/ProtoInput/ProtoInputHooks/BlockXinputHook.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "Hook.h" -#include "InstallHooks.h" - -namespace Proto -{ - - - class BlockXinputHook final : public Hook - { - private: - std::vector hookInfos{}; - - public: - const char* GetHookName() const override { return "Cursor Visibility"; } - const char* GetHookDescription() const override - { - return "Whenever the game calls for the cursor to be shown/hidden, the 'fake' cursor is shown/hidden instead. " - "Also detects when the game tries to set a custom cursor image, so the fake cursor can copy it. "; - } - bool HasGuiStatus() const override { return true; } - void ShowGuiStatus() override; - void InstallImpl() override; - void UninstallImpl() override; - - static bool ShowCursorWhenImageUpdated; - }; - -} \ No newline at end of file diff --git a/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp b/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp index 4350173..1239c54 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp +++ b/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp @@ -31,7 +31,7 @@ void FakeCursor::setmonitorscale(int scale) cursorWidth = 0; cursorHeight = 0; - //25 scale = 10. + //25 scale = 10. // 40 size on 100% scale // 80 size on 200 while (scale >= 25) { @@ -114,7 +114,7 @@ void FakeCursor::GetWindowDimensions(HWND pointerWindow) targetWidth, targetHeight, SWP_NOACTIVATE); - } + } } void DrawRedX(HDC hdc, int x, int y) //blue @@ -135,25 +135,26 @@ void DrawRedX(HDC hdc, int x, int y) //blue void DrawBlueCircle(HDC hdc, int x, int y) //red { // Create a NULL brush (hollow fill) + HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); - HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); + HPEN hOldPen = (HPEN)SelectObject(hdc, hPen); Ellipse(hdc, x - 15, y - 15, x + 15, y + 15); - SelectObject(hdc, hOldBrush); SelectObject(hdc, hOldPen); + SelectObject(hdc, hOldBrush); DeleteObject(hPen); } void DrawGreenTriangle(HDC hdc, int x, int y) { // Use a NULL brush for hollow - HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); - HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); HPEN hPen = CreatePen(PS_SOLID, 3, RGB(0, 255, 0)); + HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); + HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); HPEN hOldPen = (HPEN)SelectObject(hdc, hPen); POINT pts[3]; @@ -163,25 +164,27 @@ void DrawGreenTriangle(HDC hdc, int x, int y) Polygon(hdc, pts, 3); - SelectObject(hdc, hOldBrush); SelectObject(hdc, hOldPen); + SelectObject(hdc, hOldBrush); DeleteObject(hPen); } void DrawPinkSquare(HDC hdc, int x, int y) { // Create a NULL brush (hollow fill) + HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 192, 203)); HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); - HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 192, 203)); + HPEN hOldPen = (HPEN)SelectObject(hdc, hPen); // Draw hollow rectangle (square) 20x20 Rectangle(hdc, x - 15, y - 15, x + 15, y + 15); - SelectObject(hdc, hOldBrush); SelectObject(hdc, hOldPen); + SelectObject(hdc, hOldBrush); + DeleteObject(hPen); } @@ -263,48 +266,67 @@ void FakeCursor::DrawMessage(HDC hdc, HWND window, HBRUSH Brush, int message) oldmessage = message; } -void FakeCursor::DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, POINT spotY,HWND window, HBRUSH Brush) +int teller = 0; +//int tellerto = 0; +POINT OldTestpos = { 0, 0 }; +void FakeCursor::DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, POINT spotY, HWND window, bool redraw) { - bool windowmoved = false; bool erasedA = false; bool erased = false; bool erasedB = false; bool erasedX = false; bool erasedY = false; //detect window change pos - POINT testpos; - ClientToScreen(window, &testpos); - if (testpos.x < OldTestpos.x || testpos.y < OldTestpos.y || testpos.x > OldTestpos.x || testpos.y > OldTestpos.y) + teller++; + POINT testpos = { 0, 0 }; + if (teller > 1000) { - erased = true; + teller = 0; + + ClientToScreen(window, &testpos); + if (testpos.x != OldTestpos.x || testpos.y != OldTestpos.y) + { + erased = true; + } + OldTestpos.x = testpos.x; + OldTestpos.y = testpos.y; + redraw = true; } + //point coordinate changes - if (OldspotA.x != spotA.x || OldspotA.y != spotA.y) + if (OldspotA.x != spotA.x || OldspotA.y != spotA.y || redraw) { + ClientToScreen(window, &OldspotA); RECT fill{ OldspotA.x - 20, OldspotA.y - 20, OldspotA.x + 20, OldspotA.y + 20 }; FillRect(hdc, &fill, transparencyBrush); // Note: window, not screen coordinates! erasedA = true; + ScreenToClient(window, &OldspotA); } - if (OldspotB.x != spotB.x || OldspotB.y != spotB.y) //|| windowmoved) + if (OldspotB.x != spotB.x || OldspotB.y != spotB.y || redraw) //|| windowmoved) { + ClientToScreen(window, &OldspotB); RECT fill{ OldspotB.x - 20, OldspotB.y - 20, OldspotB.x + 20, OldspotB.y + 20 }; FillRect(hdc, &fill, transparencyBrush); // Note: window, not screen coordinates! erasedB = true; + ScreenToClient(window, &OldspotB); } - if (OldspotX.x != spotX.x || OldspotX.y != spotX.y) //|| windowmoved) + if (OldspotX.x != spotX.x || OldspotX.y != spotX.y || redraw) //|| windowmoved) { + ClientToScreen(window, &OldspotX); RECT fill{ OldspotX.x - 20, OldspotX.y - 20, OldspotX.x + 20, OldspotX.y + 20 }; FillRect(hdc, &fill, transparencyBrush); // Note: window, not screen coordinates! erasedX = true; + ScreenToClient(window, &OldspotX); } - if (OldspotY.x != spotY.x || OldspotY.y != spotY.y) //|| windowmoved) + if (OldspotY.x != spotY.x || OldspotY.y != spotY.y || redraw) //|| windowmoved) { + ClientToScreen(window, &OldspotY); RECT fill{ OldspotY.x - 20, OldspotY.y - 20, OldspotY.x + 20, OldspotY.y + 20 }; FillRect(hdc, &fill, transparencyBrush); // Note: window, not screen coordinates! erasedY = true; - + ScreenToClient(window, &OldspotY); } @@ -313,13 +335,13 @@ void FakeCursor::DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, RECT wholewindow; GetClientRect(pointerWindow, &wholewindow); - FillRect(hdc, &wholewindow, Brush); + FillRect(hdc, &wholewindow, transparencyBrush); erasedA = true; erasedB = true; erasedX = true; erasedY = true; - + erased = false; ScreenshotInput::TranslateXtoMKB::RefreshWindow = 1; //redraw cursor } @@ -338,7 +360,7 @@ void FakeCursor::DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, if (spotA.x != 0 && spotA.y != 0 && erasedA == true) - { + { POINT drawthere = spotA; ClientToScreen(window, &drawthere); //A DrawRedX(hdc, drawthere.x, drawthere.y); @@ -358,7 +380,7 @@ void FakeCursor::DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, POINT drawthere = spotX; ClientToScreen(window, &drawthere); //A DrawPinkSquare(hdc, drawthere.x, drawthere.y); - + } @@ -368,10 +390,9 @@ void FakeCursor::DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, ClientToScreen(window, &drawthere); //A DrawGreenTriangle(hdc, drawthere.x, drawthere.y); } - OldTestpos = testpos; } -void FakeCursor::DrawPointsandMessages() //only on Xtranslate +void FakeCursor::DrawPointsandMessages(bool redraw) //only on Xtranslate { if (ScreenshotInput::ScanThread::scanoption) { @@ -382,7 +403,7 @@ void FakeCursor::DrawPointsandMessages() //only on Xtranslate POINT Bpos = { ScreenshotInput::ScanThread::PointB.x, ScreenshotInput::ScanThread::PointB.y }; POINT Xpos = { ScreenshotInput::ScanThread::PointX.x, ScreenshotInput::ScanThread::PointX.y }; POINT Ypos = { ScreenshotInput::ScanThread::PointY.x, ScreenshotInput::ScanThread::PointY.y }; - FakeCursor::DrawFoundSpots(hdc, Apos, Bpos, Xpos, Ypos, selectorhwnd, transparencyBrush); + FakeCursor::DrawFoundSpots(hdc, Apos, Bpos, Xpos, Ypos, selectorhwnd, redraw); FakeCursor::DrawMessage(hdc, selectorhwnd, transparencyBrush, FakeCursor::Showmessage); LeaveCriticalSection(&ScreenshotInput::ScanThread::critical); } @@ -396,18 +417,26 @@ int cursoroffsetx, cursoroffsety; int offsetSET = 0; //0:sizing 1:scanning 2:done, only drawing until cursor change, or nochange bool nochange = false; //if normal offset was found at first then assume all cursors got same offset bool symmetricdetected = false; -bool symmetrysearch = false; +bool symmetrysearch = true; extern "C" void __declspec(dllexport) __stdcall SetCursorOffset(int X, int Y) { - if (X == 543543) //enable symmetry search + symmetricdetected = false; + if (X == 543) //enable symmetry search { symmetrysearch = true; nochange = false; return; } + if (Y == 543) //disable symmetry search + { + symmetrysearch = false; + nochange = false; + return; + } cursoroffsetx = X; cursoroffsety = Y; + nochange = true; } @@ -456,8 +485,22 @@ void FakeCursor::DrawCursor() if (offsetSET == 1 && hCursor != LoadCursorW(NULL, IDC_ARROW) && IsWindowVisible(pointerWindow)) //offset setting { HDC hdcMem = CreateCompatibleDC(hdc); + if (!hdcMem) + return; HBITMAP hbmScreen = CreateCompatibleBitmap(hdc, cursorWidth, cursorHeight); - SelectObject(hdcMem, hbmScreen); + if (!hbmScreen) + { + DeleteDC(hdcMem); + return; + } + + HBITMAP oldBmp = (HBITMAP)SelectObject(hdcMem, hbmScreen); + if (!oldBmp) + { + DeleteObject(hbmScreen); + DeleteDC(hdcMem); + return; + } BitBlt(hdcMem, 0, 0, cursorWidth, cursorHeight, hdc, pos.x, pos.y, SRCCOPY); cursoroffsetx = -1; cursoroffsety = -1; @@ -477,10 +520,10 @@ void FakeCursor::DrawCursor() break; } } - if (leftcursoroffsetx != -1) break; + if (leftcursoroffsety != -1) break; } - if (symmetrysearch) //disabled because it broke constant offset on some games + if (symmetrysearch) { for (int x = cursorWidth - 1; x >= 0; x--) { @@ -495,6 +538,7 @@ void FakeCursor::DrawCursor() //Adjusting possible here if symmetric cursor is not found if (leftcursoroffsetx == rightcursoroffsetx - 1 || leftcursoroffsetx == rightcursoroffsetx + 1 || leftcursoroffsetx == rightcursoroffsetx) //check for symmetric first only if Y offset is small { + //if any symmetric cursor then guess there are also cursors with 0.0 offset cursoroffsety = cursorHeight / 2; cursoroffsetx = cursorWidth / 2; symmetricdetected = true; @@ -503,15 +547,17 @@ void FakeCursor::DrawCursor() { cursoroffsetx = leftcursoroffsetx; cursoroffsety = leftcursoroffsety; - nochange = true; + if (symmetricdetected != true) + nochange = true; } else { //no offsets cursoroffsetx = 0; cursoroffsety = 0; } offsetSET++; //offset set to 2 should do drawing only now - DeleteDC(hdcMem); + SelectObject(hdcMem, oldBmp); DeleteObject(hbmScreen); + DeleteDC(hdcMem); @@ -528,17 +574,12 @@ void FakeCursor::DrawCursor() { cursorWidth = bitmap.bmWidth; if (ii.hbmColor == NULL) - {//For monochrome icons, the hbmMask is twice the height of the icon and hbmColor is NULL - cursorHeight = bitmap.bmHeight / 2; - } + cursorHeight = bitmap.bmHeight / 2; // monochrome cursor else - { cursorHeight = bitmap.bmHeight; - } - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask); } - + if (ii.hbmColor) DeleteObject(ii.hbmColor); + if (ii.hbmMask) DeleteObject(ii.hbmMask); } offsetSET++; //size set, doing offset next run } @@ -591,10 +632,6 @@ void FakeCursor::UpdatePointerWindowLoopInternal() void FakeCursor::StartDrawLoopInternal() { int tick = 1; - - if (Proto::RawInput::TranslateXinputtoMKB) - ScreenshotInput::TranslateXtoMKB::Initialize(GetModuleHandle(NULL)); - while (true) { if (!Proto::RawInput::TranslateXinputtoMKB) @@ -610,10 +647,10 @@ void FakeCursor::StartDrawLoopInternal() } else { - ScreenshotInput::TranslateXtoMKB::ThreadFunction(); + bool redrawpoints = ScreenshotInput::TranslateXtoMKB::ThreadFunction(); if (ScreenshotInput::TranslateXtoMKB::RefreshPoint > 0) { - DrawPointsandMessages(); + DrawPointsandMessages(redrawpoints); ScreenshotInput::TranslateXtoMKB::RefreshPoint--; } if (ScreenshotInput::TranslateXtoMKB::RefreshWindow > 0) @@ -639,7 +676,7 @@ void FakeCursor::StartInternal() { Proto::AddThreadToACL(GetCurrentThreadId()); - Sleep(1000); + Sleep(500); const auto hInstance = GetModuleHandle(NULL); diff --git a/src/ProtoInput/ProtoInputHooks/FakeCursor.h b/src/ProtoInput/ProtoInputHooks/FakeCursor.h index d6835e9..a02b6ed 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeCursor.h +++ b/src/ProtoInput/ProtoInputHooks/FakeCursor.h @@ -24,7 +24,6 @@ namespace Proto // DrawFakeCursorFix. cursor offset scan and cursor size fix HCURSOR oldhCursor = NULL; - POINT OldTestpos = { 0,0 }; // This is either on or off for a given game (ie. it doesn't change) bool drawingEnabled = false; @@ -44,8 +43,8 @@ namespace Proto HWND selectorhwnd = nullptr; //copy of variable in TranslateXtoMKB to avoid accessing it multiple times with critical section in DrawCursor void DrawMessage(HDC hdc, HWND window, HBRUSH Brush, int message); - void DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, POINT spotY, HWND window, HBRUSH Brush); - void DrawPointsandMessages(); + void DrawFoundSpots(HDC hdc, POINT spotA, POINT spotB, POINT spotX, POINT spotY, HWND window, bool redraw); + void DrawPointsandMessages(bool redraw); void DrawCursor(); diff --git a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp index 060fe1b..b71af6e 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp +++ b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp @@ -11,11 +11,19 @@ bool FakeMouseKeyboard::PutMouseInsideWindow = false; bool FakeMouseKeyboard::DefaultTopLeftMouseBounds = false; bool FakeMouseKeyboard::DefaultBottomRightMouseBounds = false; -void FakeMouseKeyboard::AddMouseDelta(int dx, int dy) +void FakeMouseKeyboard::CursorRestriction(int dx, int dy, bool setpos) { - mouseState.x += dx; - mouseState.y += dy; - + if (!setpos) //mousemove + { + mouseState.x += dx; + mouseState.y += dy; + } + else //setcursorpos call + { + mouseState.x = dx; + mouseState.y = dy; + } + if (!mouseState.ignoreMouseBounds) { if (!PutMouseInsideWindow) @@ -72,7 +80,7 @@ void FakeMouseKeyboard::AddMouseDelta(int dx, int dy) mouseState.y = max; } } - + if (mouseState.hasClipCursor) { if (mouseState.x < mouseState.clipClientLeft) @@ -87,6 +95,10 @@ void FakeMouseKeyboard::AddMouseDelta(int dx, int dy) mouseState.y = mouseState.clipClientBottom; } } +} +void FakeMouseKeyboard::AddMouseDelta(int dx, int dy) +{ + FakeMouseKeyboard::CursorRestriction(dx, dy, false); if (SetWindowsHookHook::LLMousehooked && SetWindowsHookHook::gameshookcallLLMouse != nullptr) //directly call HHOOK callback in game? { @@ -96,80 +108,7 @@ void FakeMouseKeyboard::AddMouseDelta(int dx, int dy) void FakeMouseKeyboard::SetMousePos(int x, int y) { - mouseState.x = x; - mouseState.y = y; - - if (!mouseState.ignoreMouseBounds) - { - if (!PutMouseInsideWindow) - { - int min = mouseState.extendMouseBounds ? -100 : -1; - if (mouseState.x < min) - mouseState.x = min; - if (mouseState.y < min) - mouseState.y = min; - } - else if (PutMouseInsideWindow) - { - if (!DefaultTopLeftMouseBounds) - { - int min = mouseState.extendMouseBounds ? -100 : 0; - if (mouseState.x < min) - mouseState.x = min; - if (mouseState.y < min) - mouseState.y = min; - } - else if (DefaultTopLeftMouseBounds) - { - int min = mouseState.extendMouseBounds ? -100 : -1; - if (mouseState.x < min) - mouseState.x = min; - if (mouseState.y < min) - mouseState.y = min; - } - } - - if (!PutMouseInsideWindow) - { - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth + 100 : HwndSelector::windowWidth; mouseState.x > max) - mouseState.x = max; - - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight + 100 : HwndSelector::windowHeight; mouseState.y > max) - mouseState.y = max; - } - else if (PutMouseInsideWindow) - { - if (!DefaultBottomRightMouseBounds) - { - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x >= max) - mouseState.x = max - 1; - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y >= max) - mouseState.y = max - 1; - } - else if (DefaultBottomRightMouseBounds) - { - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x > max) - mouseState.x = max; - - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y > max) - mouseState.y = max; - } - } - - if (mouseState.hasClipCursor) - { - if (mouseState.x < mouseState.clipClientLeft) - mouseState.x = mouseState.clipClientLeft; - if (mouseState.y < mouseState.clipClientTop) - mouseState.y = mouseState.clipClientTop; - - if (mouseState.x > mouseState.clipClientRight) - mouseState.x = mouseState.clipClientRight; - - if (mouseState.y > mouseState.clipClientBottom) - mouseState.y = mouseState.clipClientBottom; - } - } + FakeMouseKeyboard::CursorRestriction(x, y, true); } void FakeMouseKeyboard::SetClipCursor(int clientLeft, int clientTop, int clientRight, int clientBottom) diff --git a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h index f40dd64..657e4ef 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h +++ b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h @@ -39,6 +39,7 @@ class FakeMouseKeyboard { static FakeMouseState mouseState; static FakeKeyboardState keyboardState; + static void CursorRestriction(int dx, int dy, bool setpos); public: static const FakeMouseState& GetMouseState() { return mouseState; } diff --git a/src/ProtoInput/ProtoInputHooks/GetRawInputDataHook.cpp b/src/ProtoInput/ProtoInputHooks/GetRawInputDataHook.cpp index 244ba66..7d0561b 100644 --- a/src/ProtoInput/ProtoInputHooks/GetRawInputDataHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/GetRawInputDataHook.cpp @@ -34,20 +34,13 @@ UINT WINAPI Hook_GetRawInputData( if (RawInput::TranslateXinputtoMKB2) // TranslateXinputtoMKB2 is just a copy of TranslateXinputtoMKB { - UINT handleValue = (UINT)(UINT_PTR)hRawInput; - UINT bufferIndex = handleValue & 0x00FFFFFF; - if (bufferIndex >= 20) { + UINT bufferIndex = ((UINT)(UINT_PTR)hRawInput) & 0x00FFFFFF; + if (bufferIndex >= RawInputBufferSize) return GetRawInputData(hRawInput, uiCommand, pData, pcbSize, cbSizeHeader); - } - - if (pData == NULL) { - *pcbSize = sizeof(RAWINPUT); - return 0; - } - - RAWINPUT* storedData = &RawInput::inputBuffer[RawInput::bufferCounter]; - memcpy(pData, storedData, sizeof(RAWINPUT)); - return sizeof(RAWINPUT); + if (pData == NULL) { *pcbSize = sizeof(RAWINPUT); return 0; } + const UINT copy = min(*pcbSize, (UINT)sizeof(RAWINPUT)); + memcpy(pData, &RawInput::inputBuffer[bufferIndex], copy); + return copy; } // printf("$"); diff --git a/src/ProtoInput/ProtoInputHooks/GtoMnK_RawInput.cpp b/src/ProtoInput/ProtoInputHooks/GtoMnK_RawInput.cpp index 8c6609b..05fe418 100644 --- a/src/ProtoInput/ProtoInputHooks/GtoMnK_RawInput.cpp +++ b/src/ProtoInput/ProtoInputHooks/GtoMnK_RawInput.cpp @@ -1,5 +1,4 @@ #include "GtoMnK_RawInput.h" -#include "GtoMnK_RawInputHooks.h" #include "HwndSelector.h" #include "RawInput.h" diff --git a/src/ProtoInput/ProtoInputHooks/MessageFilterHook.cpp b/src/ProtoInput/ProtoInputHooks/MessageFilterHook.cpp index 753fc50..019f020 100644 --- a/src/ProtoInput/ProtoInputHooks/MessageFilterHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/MessageFilterHook.cpp @@ -186,7 +186,7 @@ void MessageFilterHook::UninstallImpl() bool MessageFilterHook::IsKeyboardButtonFilterEnabled() { - return IsFilterEnabled(); + return *IsFilterEnabled(); } } diff --git a/src/ProtoInput/ProtoInputHooks/MouseButtonFilter.h b/src/ProtoInput/ProtoInputHooks/MouseButtonFilter.h index aea9500..f6cda26 100644 --- a/src/ProtoInput/ProtoInputHooks/MouseButtonFilter.h +++ b/src/ProtoInput/ProtoInputHooks/MouseButtonFilter.h @@ -16,7 +16,7 @@ class MouseButtonFilter : public MessageFilterBase= 0; --i) { if (std::find(rawInputState.mouseHandles.begin(), rawInputState.mouseHandles.end(), rawInputState.selectedMouseHandles[i]) == rawInputState.mouseHandles.end()) @@ -694,11 +700,11 @@ void RawInput::RefreshDevices() if (std::find(rawInputState.mouseHandles.begin(), rawInputState.mouseHandles.end(), rawInputState.deselectedMouseHandles[i]) == rawInputState.mouseHandles.end()) rawInputState.deselectedMouseHandles.erase(rawInputState.deselectedMouseHandles.begin() + i); } - + //keyboard for (int i = rawInputState.selectedKeyboardHandles.size() - 1; i >= 0; --i) { if (std::find(rawInputState.keyboardHandles.begin(), rawInputState.keyboardHandles.end(), rawInputState.selectedKeyboardHandles[i]) == rawInputState.keyboardHandles.end()) - rawInputState.selectedMouseHandles.erase(rawInputState.selectedMouseHandles.begin() + i); + rawInputState.selectedKeyboardHandles.erase(rawInputState.selectedKeyboardHandles.begin() + i); } for (int i = rawInputState.deselectedKeyboardHandles.size() - 1; i >= 0; --i) { diff --git a/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.cpp b/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.cpp index dd93417..d71fd2a 100644 --- a/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.cpp @@ -5,8 +5,7 @@ #include #include "RawInput.h" #include -#include "HwndSelector.h" //GtoMnK_RawInputHooks -#include "GtoMnK_RawInputHooks.h" //GtoMnK_RawInputHooks +#include "HwndSelector.h" namespace Proto { @@ -125,8 +124,6 @@ void RegisterRawInputHook::FindAlreadySubscribedWindows() { printf("Couldn't find a hwnd subscribed to raw input\n"); //assuming main window - if (RegisterRawInputHook::Reregisterinput) - AddWindowToForward((HWND)HwndSelector::GetSelectedHwnd(), usagesToForward); } else { @@ -145,7 +142,7 @@ void RegisterRawInputHook::AddWindowToForward(HWND hwnd, std::bitset<9> usages) RawInput::AddWindowToForward(hwnd); } - +int telleverk = 0; void RegisterRawInputHook::ShowGuiStatus() { //todo //GetWindowTextA was very slow. better make sure its only done once. @@ -167,7 +164,7 @@ void RegisterRawInputHook::ShowGuiStatus() bool gotawindow = false; for (const auto& hwnd : RawInput::forwardingWindows) { - char windowTitleBuffer[60]; //GetWindowTextA was so slow + //char windowTitleBuffer[60]; //GetWindowTextA was so slow //GetWindowTextA((HWND)HwndSelector::GetSelectedHwnd(), windowTitleBuffer, sizeof(windowTitleBuffer)); ImGui::Text("Raw input to window: %X", hwnd); gotawindow = true; @@ -175,14 +172,18 @@ void RegisterRawInputHook::ShowGuiStatus() if (gotawindow == false) ImGui::Text("No rawinput forwarded. "); - char windowTitleBuffer[60]; - GetWindowTextA((HWND)HwndSelector::GetSelectedHwnd(), windowTitleBuffer, sizeof(windowTitleBuffer)); + static char windowTitleBuffer[60]; + telleverk++; + if (telleverk > 100) + { + telleverk = 0; + GetWindowTextA((HWND)HwndSelector::GetSelectedHwnd(), windowTitleBuffer, sizeof(windowTitleBuffer)); + } ImGui::Separator(); ImGui::Text("Main window is: %X %s", HwndSelector::GetSelectedHwnd(), windowTitleBuffer); ImGui::Separator(); if (ImGui::Button("Force Main Window to forward list")) { - RawInput::AddWindowToForward((HWND)HwndSelector::GetSelectedHwnd()); } @@ -238,6 +239,28 @@ void RegisterRawInputHook::ShowGuiStatus() } +void RegisterRawInputHook::ReregisterRawInput() +{ + RAWINPUTDEVICE devs[2]; + + // Mouse + devs[0].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC + devs[0].usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE + devs[0].dwFlags = RIDEV_INPUTSINK; + devs[0].hwndTarget = NULL; + + // Keyboard + devs[1].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC + devs[1].usUsage = 0x06; // HID_USAGE_GENERIC_KEYBOARD + devs[1].dwFlags = RIDEV_INPUTSINK; + devs[1].hwndTarget = NULL; + + if (!Hook_RegisterRawInputDevices(devs, 2, sizeof(RAWINPUTDEVICE))) + { + MessageBoxA(NULL, "Failed to Reregister raw input", "Error", MB_OK | MB_ICONERROR); + } +} + void RegisterRawInputHook::InstallImpl() { std::bitset<9> usages{}; @@ -254,6 +277,10 @@ void RegisterRawInputHook::InstallImpl() FindAlreadySubscribedWindows(); RawInput::UnregisterGameFromRawInput(); RawInput::RegisterProtoForRawInput(); + if (RegisterRawInputHook::Reregisterinput) + { + RegisterRawInputHook::ReregisterRawInput(); + } } void RegisterRawInputHook::UninstallImpl() diff --git a/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.h b/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.h index 194acaf..dcde2b3 100644 --- a/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.h +++ b/src/ProtoInput/ProtoInputHooks/RegisterRawInputHook.h @@ -18,6 +18,7 @@ class RegisterRawInputHook final : public Hook HookInfo hookInfo{}; void FindAlreadySubscribedWindows(); + void ReregisterRawInput(); public: static bool logCallsToRegisterRawInput; diff --git a/src/ProtoInput/ProtoInputHooks/ScanThread.cpp b/src/ProtoInput/ProtoInputHooks/ScanThread.cpp index 2b0f922..665e858 100644 --- a/src/ProtoInput/ProtoInputHooks/ScanThread.cpp +++ b/src/ProtoInput/ProtoInputHooks/ScanThread.cpp @@ -81,20 +81,38 @@ namespace ScreenshotInput { return ((width * 3 + 3) & ~3); } - bool LoadBMP24Bit(std::wstring filename, std::vector& pixels, int& width, int& height, int& stride) { - HBITMAP hbm = (HBITMAP)LoadImageW(NULL, filename.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); - if (!hbm) return false; + bool LoadBMP24Bit(const std::wstring& filename, + std::vector& pixels, + int& width, int& height, int& stride) + { + HBITMAP hbm = (HBITMAP)LoadImageW( + NULL, filename.c_str(), + IMAGE_BITMAP, 0, 0, + LR_LOADFROMFILE | LR_CREATEDIBSECTION); + + if (!hbm) + return false; + + BITMAP bmp{}; + if (!GetObject(hbm, sizeof(bmp), &bmp)) + { + DeleteObject(hbm); + return false; + } + + width = bmp.bmWidth; + height = bmp.bmHeight; - //BITMAP scaledbmp; - BITMAP bmp; - GetObject(hbm, sizeof(BITMAP), &bmp); - width = bmp.bmWidth - 1; - height = bmp.bmHeight - 1; - stride = CalculateStride(width); + if (width <= 0 || height <= 0) + { + DeleteObject(hbm); + return false; + } + stride = ((width * 3 + 3) & ~3); pixels.resize(stride * height); - BITMAPINFO bmi = {}; + BITMAPINFO bmi{}; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; @@ -102,12 +120,22 @@ namespace ScreenshotInput { bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; - BYTE* pBits = nullptr; - HDC hdc = GetDC(NULL); - GetDIBits(hdc, hbm, 0, height, pixels.data(), &bmi, DIB_RGB_COLORS); + HDC hdc = CreateCompatibleDC(NULL); + if (!hdc) + { + DeleteObject(hbm); + return false; + } + + if (!GetDIBits(hdc, hbm, 0, height, pixels.data(), &bmi, DIB_RGB_COLORS)) + { + DeleteDC(hdc); + DeleteObject(hbm); + return false; + } - if (hdc) DeleteDC(hdc); - if (hbm) DeleteObject(hbm); + DeleteDC(hdc); + DeleteObject(hbm); return true; } @@ -115,16 +143,9 @@ namespace ScreenshotInput { void BmpInputAction(int X, int Y, int type) //moveclickorboth { Proto::FakeMouseState muusjn = Proto::FakeMouseKeyboard::GetMouseState(); - int Xhold = muusjn.x; - int Yhold = muusjn.y; - if (Xhold < X) - X = X - Xhold; - else - X = X - Xhold; - if (Yhold < Y) - Y= Y - Yhold; - else - Y = Y - Yhold; + X = X - muusjn.x; + Y = Y - muusjn.y; + if (type == 0) //click and move { @@ -134,10 +155,12 @@ namespace ScreenshotInput { TranslateXtoMKB::SendMouseClick(X, Y, 3); Sleep(5); TranslateXtoMKB::SendMouseClick(X, Y, 4); + TranslateXtoMKB::RefreshWindow++; //refresh cursor } else if (type == 1) //only move { TranslateXtoMKB::SendMouseClick(X, Y, 8); + TranslateXtoMKB::RefreshWindow++;//refresh cursor } else if (type == 2) //only click { @@ -152,6 +175,7 @@ namespace ScreenshotInput { } POINT Aprevious{ 0,0 }, Bprevious{ 0,0 }, Xprevious{ 0,0 }, Yprevious{ 0,0 }; int Awas; int Bwas; int Xwas; int Ywas; + int Anum; int Bnum; int Xnum; int Ynum; void Bmpfound(const char key[3], int X, int Y, int i, bool onlysearch, bool found, int store) { int input = 0; @@ -163,6 +187,7 @@ namespace ScreenshotInput { { if (onlysearch) { + Anum = 0; EnterCriticalSection(&ScanThread::critical); ScanThread::startsearchA = i; input = ScanThread::scanAtype; @@ -191,17 +216,22 @@ namespace ScreenshotInput { } else { - if (onlysearch) + if (onlysearch) //not found { - EnterCriticalSection(&ScanThread::critical); - ScanThread::startsearchA = 0; - ScanThread::PointA.x = 0; - ScanThread::PointA.y = 0; - if (Aprevious.x != X || Aprevious.y != Y) - ScanThread::UpdateWindow = true; - Aprevious.x = X; - Aprevious.y = Y; - LeaveCriticalSection(&ScanThread::critical); + Anum++; + if (Anum >= 2) + { + Anum = 0; + EnterCriticalSection(&ScanThread::critical); + ScanThread::startsearchA = 0; + ScanThread::PointA.x = 0; + ScanThread::PointA.y = 0; + if (Aprevious.x != X || Aprevious.y != Y) + ScanThread::UpdateWindow = true; + Aprevious.x = X; + Aprevious.y = Y; + LeaveCriticalSection(&ScanThread::critical); + } } } } @@ -214,6 +244,7 @@ namespace ScreenshotInput { //LeaveCriticalSection(&critical); if (onlysearch) { + Bnum = 0; EnterCriticalSection(&ScanThread::critical); ScanThread::startsearchB = i; ScanThread::PointB.x = X; @@ -242,15 +273,20 @@ namespace ScreenshotInput { { if (onlysearch) { - EnterCriticalSection(&ScanThread::critical); - ScanThread::startsearchB = 0; - ScanThread::PointB.x = 0; - ScanThread::PointB.y = 0; - if (Bprevious.x != X || Bprevious.y != Y) - ScanThread::UpdateWindow = true; - Bprevious.x = X; - Bprevious.y = Y; - LeaveCriticalSection(&ScanThread::critical); + Bnum++; + if (Bnum >= 2) + { + Bnum = 0; + EnterCriticalSection(&ScanThread::critical); + ScanThread::startsearchB = 0; + ScanThread::PointB.x = 0; + ScanThread::PointB.y = 0; + if (Bprevious.x != X || Bprevious.y != Y) + ScanThread::UpdateWindow = true; + Bprevious.x = X; + Bprevious.y = Y; + LeaveCriticalSection(&ScanThread::critical); + } } } } @@ -263,6 +299,7 @@ namespace ScreenshotInput { //LeaveCriticalSection(&critical); if (onlysearch) { + Xnum = 0; EnterCriticalSection(&ScanThread::critical); ScanThread::startsearchX = i; ScanThread::PointX.x = X; @@ -292,15 +329,20 @@ namespace ScreenshotInput { { if (onlysearch) { - EnterCriticalSection(&ScanThread::critical); - ScanThread::startsearchX = 0; - ScanThread::PointX.x = 0; - ScanThread::PointX.y = 0; - if (Xprevious.x != X || Xprevious.y != Y) - ScanThread::UpdateWindow = true; - Xprevious.x = ScanThread::PointX.x; - Xprevious.y = ScanThread::PointX.y; - LeaveCriticalSection(&ScanThread::critical); + Xnum++; + if (Xnum >= 2) + { + Xnum = 0; + EnterCriticalSection(&ScanThread::critical); + ScanThread::startsearchX = 0; + ScanThread::PointX.x = 0; + ScanThread::PointX.y = 0; + if (Xprevious.x != X || Xprevious.y != Y) + ScanThread::UpdateWindow = true; + Xprevious.x = X; + Xprevious.y = Y; + LeaveCriticalSection(&ScanThread::critical); + } } } } @@ -313,8 +355,9 @@ namespace ScreenshotInput { { if (onlysearch) { + Ynum = 0; EnterCriticalSection(&ScanThread::critical); - ScanThread::startsearchX = i; + ScanThread::startsearchY = i; ScanThread::staticPointY[i].x = X; ScanThread::staticPointY[i].y = Y; ScanThread::PointY.x = X; @@ -342,16 +385,20 @@ namespace ScreenshotInput { { if (onlysearch) { - EnterCriticalSection(&ScanThread::critical); - ScanThread::startsearchY = 0; - //input = scanYtype; - ScanThread::PointY.x = 0; - ScanThread::PointY.y = 0; - if (Yprevious.x != X || Yprevious.y != Y) - ScanThread::UpdateWindow = true; - Yprevious.x = ScanThread::PointY.x; - Yprevious.y = ScanThread::PointY.y; - LeaveCriticalSection(&ScanThread::critical); + Ynum++; + if (Ynum >= 2) + { + Ynum = 0; + EnterCriticalSection(&ScanThread::critical); + ScanThread::startsearchY = 0; + ScanThread::PointY.x = 0; + ScanThread::PointY.y = 0; + if (Yprevious.x != X || Yprevious.y != Y) + ScanThread::UpdateWindow = true; + Yprevious.x = X; + Yprevious.y = Y; + LeaveCriticalSection(&ScanThread::critical); + } } } } @@ -448,18 +495,32 @@ namespace ScreenshotInput { return pp; } - bool CaptureWindow24Bit(HWND hwnd, SIZE& capturedwindow, std::vector& pixels, int& strideOut, bool draw, bool stretchblt) + bool CaptureWindow24Bit(HWND hwnd, SIZE& capturedwindow, std::vector& pixels, + int& strideOut, bool draw, bool stretchblt) { if (PreScanningEnabled) EnterCriticalSection(&ScanThread::critical); + HDC hdcWindow = GetDC(hwnd); - HDC hdcMem = CreateCompatibleDC(hdcWindow); + if (!hdcWindow) + { + if (PreScanningEnabled) LeaveCriticalSection(&ScanThread::critical); + return false; + } + HDC hdcMem = CreateCompatibleDC(hdcWindow); + if (!hdcMem) + { + ReleaseDC(hwnd, hdcWindow); + if (PreScanningEnabled) LeaveCriticalSection(&ScanThread::critical); + return false; + } RECT rcClient; GetClientRect(hwnd, &rcClient); int width = rcClient.right - rcClient.left; int height = rcClient.bottom - rcClient.top; + capturedwindow.cx = width; capturedwindow.cy = height; @@ -470,31 +531,37 @@ namespace ScreenshotInput { BITMAPINFO bmi = {}; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; - bmi.bmiHeader.biHeight = -height; // top-down + bmi.bmiHeader.biHeight = -height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; BYTE* pBits = nullptr; HBITMAP hbm24 = CreateDIBSection(hdcWindow, &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0); + if (hbm24) { HGDIOBJ oldBmp = SelectObject(hdcMem, hbm24); - BitBlt(hdcMem, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY); - GetDIBits(hdcMem, hbm24, 0, height, pixels.data(), &bmi, DIB_RGB_COLORS); - SelectObject(hdcMem, oldBmp); - DeleteObject(hbm24); - // hbm24 = nullptr; + if (oldBmp) + { + BitBlt(hdcMem, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY); + //GdiFlush(); + memcpy(pixels.data(), pBits, stride * height); - } //hbm24 not null + SelectObject(hdcMem, oldBmp); + } - if (hdcMem) DeleteDC(hdcMem); - if (hdcWindow) ReleaseDC(hwnd, hdcWindow); + DeleteObject(hbm24); + } + + DeleteDC(hdcMem); + ReleaseDC(hwnd, hdcWindow); if (PreScanningEnabled) LeaveCriticalSection(&ScanThread::critical); + return true; - } //function end + } POINT CheckStatics(const char abc[3], int numtocheck) { @@ -671,7 +738,7 @@ namespace ScreenshotInput { int inistart = -1; while (x < 50 && inistart == -1) { - std::string iniPath = UGetExecutableFolder() + "\\GtoMnK.ini"; + std::string iniPath = UGetExecutableFolder() + "\\ProtoInput.ini"; std::string iniSettings = "Statics"; std::string name(path.end() - 1, path.end()); @@ -692,7 +759,7 @@ namespace ScreenshotInput { } bool ScanThread::initovector() { - std::string iniPath = UGetExecutableFolder() + "\\GtoMnK.ini"; + std::string iniPath = UGetExecutableFolder() + "\\ProtoInput.ini"; std::string iniSettings = "Statics"; std::string name = "A"; int y = -1; @@ -968,7 +1035,7 @@ namespace ScreenshotInput { return false; } - DWORD WINAPI ScanThreadMain(LPVOID, int Aisstatic, int Bisstatic, int Xisstatic, int Yisstatic) + DWORD WINAPI ScanThreadMain( int Aisstatic, int Bisstatic, int Xisstatic, int Yisstatic) { ScanThread::scanloop = true; int scantick = 0; @@ -1051,7 +1118,7 @@ namespace ScreenshotInput { else Bmpfound("\\Y", ScanThread::staticPointY[startsearchYW].x, ScanThread::staticPointY[startsearchYW].y, startsearchYW, true, true, Ystatic); } - ButtonScanAction("\\Y", 1, ScanThread::numphotoY, startsearchYW, true, PointYW, Ystatic); + else ButtonScanAction("\\Y", 1, ScanThread::numphotoY, startsearchYW, true, PointYW, Ystatic); } Sleep(10); } @@ -1109,8 +1176,8 @@ namespace ScreenshotInput { if (ScanThread::startsearchB < ScanThread::numphotoB - 1) ScanThread::startsearchB++; //dont want it to update before input done else ScanThread::startsearchB = 0; - ScanThread::PointA.x = 0; - ScanThread::PointA.y = 0; + ScanThread::PointB.x = 0; + ScanThread::PointB.y = 0; } BmpInputAction(Cpoint.x, Cpoint.y, ScanThread::scanBtype); returnedvalue = true; @@ -1191,7 +1258,6 @@ namespace ScreenshotInput { } else if (ScanThread::ShoulderNextBMP) { - //MessageBoxA(NULL, "heisann2", "A", MB_OK); EnterCriticalSection(&ScanThread::critical); if (ScanThread::startsearchA < ScanThread::numphotoA - 1) ScanThread::startsearchA++; //dont want it to update before input done @@ -1239,7 +1305,7 @@ namespace ScreenshotInput { if (!PreScanningEnabled) { EnterCriticalSection(&critical); - returnedvalue = ButtonScanAction("\\E", ModeScanThread, ScanThread::numphotoD, ScanThread::startsearchD, false, { 0,0 }, false); //2 save bmps + returnedvalue = ButtonScanAction("\\E", ModeScanThread, ScanThread::numphotoE, ScanThread::startsearchE, false, { 0,0 }, false); //2 save bmps LeaveCriticalSection(&critical); } } @@ -1258,9 +1324,9 @@ namespace ScreenshotInput { } - void ScanThread::StartScanThread(HMODULE hmodule, int Astatic, int Bstatic, int Xstatic, int Ystatic, bool prescan) { + void ScanThread::StartScanThread( int Astatic, int Bstatic, int Xstatic, int Ystatic, bool prescan) { PreScanningEnabled = prescan; - std::thread tree(ScanThreadMain, hmodule, Astatic, Bstatic, Xstatic, Ystatic); + std::thread tree(ScanThreadMain, Astatic, Bstatic, Xstatic, Ystatic); tree.detach(); } diff --git a/src/ProtoInput/ProtoInputHooks/ScanThread.h b/src/ProtoInput/ProtoInputHooks/ScanThread.h index 9803c74..b26d15b 100644 --- a/src/ProtoInput/ProtoInputHooks/ScanThread.h +++ b/src/ProtoInput/ProtoInputHooks/ScanThread.h @@ -22,7 +22,7 @@ namespace ScreenshotInput { static int resize; static int ignorerect; - static void StartScanThread(HMODULE hmodule, int Astatic, int Bstatic, int Xstatic, int Ystatic, bool prescan); + static void StartScanThread(int Astatic, int Bstatic, int Xstatic, int Ystatic, bool prescan); static bool SaveWindow10x10BMP(HWND hwnd, std::wstring filename, int x, int y); static bool enumeratebmps(); //false if no bmps found diff --git a/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.cpp b/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.cpp index e830e8a..29092f7 100644 --- a/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.cpp +++ b/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.cpp @@ -23,7 +23,6 @@ namespace ScreenshotInput { - int InstanceID = 0; //InstanceID copy from stateinfo.h int TranslateXtoMKB::RefreshWindow; int TranslateXtoMKB::RefreshPoint; @@ -67,9 +66,6 @@ namespace ScreenshotInput int startbuttontimer, backbuttontimer; - - HMODULE g_hModule = nullptr; - bool loop = true; //int TranslateXtoMKB::showmessage = 0; //0 = no message, 1 = initializing, 2 = bmp mode, 3 = bmp and cursor mode, 4 = edit mode @@ -82,7 +78,6 @@ namespace ScreenshotInput POINT delta; //hooks - //fake cursor int Xf = 0; int Yf = 0; @@ -142,7 +137,7 @@ namespace ScreenshotInput ScanThread::initovector(); if (ScanThread::scanoption) { //starting bmp continous scanner - ScanThread::StartScanThread(g_hModule, ScanThread::Aisstatic, ScanThread::Bisstatic, ScanThread::Xisstatic, ScanThread::Yisstatic, ScanThread::scanoption); + ScanThread::StartScanThread(ScanThread::Aisstatic, ScanThread::Bisstatic, ScanThread::Xisstatic, ScanThread::Yisstatic, ScanThread::scanoption); // printf("BMP scanner started"); } Sleep(20); //give time for ScanThread::scanloop toggle true @@ -371,9 +366,10 @@ namespace ScreenshotInput return { integerDeltaX, -integerDeltaY }; } - - void TranslateXtoMKB::ThreadFunction() + + bool TranslateXtoMKB::ThreadFunction() { + bool threadreturn = false; if (ScanThread::scanoption && ScanThread::scanloop == false) { //MessageBoxA(NULL, "Starting BMP scanner...", "Info", MB_OK); @@ -395,7 +391,7 @@ namespace ScreenshotInput //GUI if (oldGUIkey) { - if (IsKeyPressed(VK_RCONTROL) && IsKeyPressed(VK_RMENU) && IsKeyPressed(0x30 + InstanceID)) + if (IsKeyPressed(VK_RCONTROL) && IsKeyPressed(VK_RMENU) && IsKeyPressed(0x30 + Proto::StateInfo::info.instanceIndex)) { } else @@ -404,7 +400,7 @@ namespace ScreenshotInput ButtonStateImpulse(VK_HOME, false, 99);//down} } } - else if (IsKeyPressed(VK_RCONTROL) && IsKeyPressed(VK_RMENU) && IsKeyPressed(0x30 + InstanceID))//gui or fake cursor toggle + else if (IsKeyPressed(VK_RCONTROL) && IsKeyPressed(VK_RMENU) && IsKeyPressed(0x30 + Proto::StateInfo::info.instanceIndex))//gui or fake cursor toggle { Proto::ToggleWindow(); oldGUIkey = true; @@ -684,6 +680,7 @@ namespace ScreenshotInput oldC = true; if (ScanThread::scanoption) { + threadreturn = true; bool found = ScanThread::ButtonPressed(4); if (!found) ButtonStateImpulse(TranslateXtoMKB::RSmapping, true, 99); //down @@ -708,6 +705,7 @@ namespace ScreenshotInput oldD = true; if (ScanThread::scanoption) { + threadreturn = true; bool found = ScanThread::ButtonPressed(5); if (!found) ButtonStateImpulse(TranslateXtoMKB::LSmapping, true, 99);//down @@ -930,15 +928,7 @@ namespace ScreenshotInput else Sleep(10); - return; + return threadreturn; } - void TranslateXtoMKB::Initialize(HMODULE hModule) - { - g_hModule = hModule; - InstanceID = Proto::StateInfo::info.instanceIndex; - Proto::AddThreadToACL(GetCurrentThreadId()); - //Sleep(50); - return; - } } \ No newline at end of file diff --git a/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.h b/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.h index 8f07bf4..f54b812 100644 --- a/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.h +++ b/src/ProtoInput/ProtoInputHooks/TranslateXtoMKB.h @@ -11,8 +11,7 @@ namespace ScreenshotInput // static bool usetraqnslation; public: - static void Initialize(HMODULE g_hModule); - static void ThreadFunction(); //polling from idle drawfakecursor thread + static bool ThreadFunction(); //polling from idle drawfakecursor thread static void SendMouseClick(int x, int y, int z); static int RefreshWindow; static int RefreshPoint; diff --git a/src/ProtoInput/ProtoInputHooks/WindowMsgHook.cpp b/src/ProtoInput/ProtoInputHooks/WindowMsgHook.cpp index 8c47049..d33e2c3 100644 --- a/src/ProtoInput/ProtoInputHooks/WindowMsgHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/WindowMsgHook.cpp @@ -335,6 +335,8 @@ namespace Proto } //less cpu usage blocking these here i guess as the wndproc is already hooked + case WM_POINTERUPDATE: + case WM_POINTERDOWN: case WM_POINTERLEAVE: case WM_POINTERCAPTURECHANGED: //POINTERCAPTURECHANGED is not listed in proto yet case WM_MOUSELEAVE: diff --git a/src/ProtoInput/ProtoInputHooks/XinputHook.cpp b/src/ProtoInput/ProtoInputHooks/XinputHook.cpp index 5c830a3..5e9043a 100644 --- a/src/ProtoInput/ProtoInputHooks/XinputHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/XinputHook.cpp @@ -85,7 +85,6 @@ POINT deltaR; bool oldA, oldB, oldX, oldY, oldtriggerleft, oldtriggerright, oldLS, oldRS, oldup, olddown, oldleft, oldright; bool oldstart, oldback, oldstickRB, oldstickLB; bool firstcall = false; -DWORD fakedwpacketnumber = 0; bool changed; SHORT LaxisX, LaxisY, RaxisX, RaxisY; SHORT deadzone = 14000; @@ -225,19 +224,18 @@ inline DWORD WINAPI XInputfromkbm(DWORD dwUserIndex, XINPUT_STATE* pState, bool pState->Gamepad.sThumbLX = 0; pState->Gamepad.sThumbRY = 0; pState->Gamepad.sThumbRX = 0; + pState->dwPacketNumber = 0; firstcall = true; } - RaxisX = axisvaluebutton(RaxisX, IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickleftmapping), IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickrightmapping)); + RaxisX = axisvaluebutton(RaxisX, IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickrightmapping), IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickleftmapping)); RaxisY = axisvaluebutton(RaxisY, IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickupmapping), IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickdownmapping)); POINT mouseaxis = axisvaluemouse(LaxisX, LaxisY); - LaxisX = mouseaxis.x; - LaxisY = mouseaxis.y; + LaxisX = (SHORT)mouseaxis.x; + LaxisY = (SHORT)mouseaxis.y; - - - FillXbuttons(pState); + FillXbuttons(pState); //normal buttons @@ -281,11 +279,13 @@ inline DWORD WINAPI XInputfromkbm(DWORD dwUserIndex, XINPUT_STATE* pState, bool oldright != IsKeyPressed(ScreenshotInput::TranslateXtoMKB::rightmapping); } + static DWORD packetNumberT = 0; if (changed) { - pState->dwPacketNumber++; + packetNumberT++; changed = false; } + pState->dwPacketNumber = packetNumberT; oldA = IsKeyPressed(ScreenshotInput::TranslateXtoMKB::Amapping); oldB = IsKeyPressed(ScreenshotInput::TranslateXtoMKB::Bmapping); @@ -302,7 +302,7 @@ inline DWORD WINAPI XInputfromkbm(DWORD dwUserIndex, XINPUT_STATE* pState, bool oldstart = IsKeyPressed(ScreenshotInput::TranslateXtoMKB::startmapping); oldback = IsKeyPressed(ScreenshotInput::TranslateXtoMKB::optionmapping); oldstickRB = IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickRpressmapping); - oldstickLB != IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickLpressmapping); + oldstickLB = IsKeyPressed(ScreenshotInput::TranslateXtoMKB::stickLpressmapping); oldtriggerleft = IsKeyPressed(VK_RBUTTON); oldtriggerright = IsKeyPressed(VK_LBUTTON); @@ -331,7 +331,7 @@ inline DWORD WINAPI XInputGetStateDinput_Inline(DWORD dwUserIndex, XINPUT_STATE* if (dinputDevice == nullptr) return ERROR_DEVICE_NOT_CONNECTED; - //WORK TODO TO DO is this an error? it is supposed to increase on statechange. doesnt look correct now? + static DWORD packetNumber = 0; pState->dwPacketNumber = packetNumber++; // memset(&(pState->Gamepad), 0, extended ? sizeof(XINPUT_GAMEPAD_EX) : sizeof(XINPUT_GAMEPAD)); @@ -619,7 +619,7 @@ void XinputHook::ShowGuiStatus() ImGui::PushID(123896); ImGui::Checkbox("", &TranslateMKBtoXinput); ImGui::SameLine(); - ImGui::TextWrapped("Enable KBM to Xinput. emulate Xinput gamepad on controllerindex 0"); + ImGui::TextWrapped("Enable KBM to Xinput. emulate Xinput gamepad if controllerindex is 0(no controller)"); ImGui::PopID(); } if (dinputDevice != nullptr) diff --git a/src/ProtoInput/ProtoInputHooks/dllmain.cpp b/src/ProtoInput/ProtoInputHooks/dllmain.cpp index 83d41b6..347e554 100644 --- a/src/ProtoInput/ProtoInputHooks/dllmain.cpp +++ b/src/ProtoInput/ProtoInputHooks/dllmain.cpp @@ -43,9 +43,9 @@ DWORD WINAPI StartThread(LPVOID lpParameter) Proto::FocusMessageLoop::SetupThread(); //setfocus message spamming loop - Proto::FakeCursor::Initialise(Proto::hmodule); //create cursor drawing window. could be possible to create it later on first drawcursor enable + InitializeCriticalSection(&ScreenshotInput::ScanThread::critical);//must be placed before InitialiseRawInput and before FakeCursor::Initialise - InitializeCriticalSection(&ScreenshotInput::ScanThread::critical);//must be placed before InitialiseRawInput + Proto::FakeCursor::Initialise(Proto::hmodule); //create cursor drawing window. could be possible to create it later on first drawcursor enable Proto::RawInput::InitialiseRawInput(); //create raw input listening window diff --git a/src/ProtoInput/ProtoInputHost/Gui.cpp b/src/ProtoInput/ProtoInputHost/Gui.cpp index cc5a298..5d78108 100644 --- a/src/ProtoInput/ProtoInputHost/Gui.cpp +++ b/src/ProtoInput/ProtoInputHost/Gui.cpp @@ -12,7 +12,7 @@ #include "protoloader.h" #include "Profiles.h" #include "MessageList.h" - +#include namespace ProtoHost { @@ -349,6 +349,15 @@ void SelectFirstIndex() } } +std::string WideToUtf8(const wchar_t* w) +{ + if (!w || !*w) return {}; + int size = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); + std::string s(size, '\0'); + WideCharToMultiByte(CP_UTF8, 0, w, -1, s.data(), size, nullptr, nullptr); + return s; +} + void InstancesWindow() { // Current instances @@ -484,57 +493,85 @@ void InstancesWindow() static HWND foregroundWindow = nullptr; static wchar_t windowNameBuffer[260]; static std::wstring processName; - - if (const auto h = GetForegroundWindow(); h != nullptr && h != protoHostHwnd && h != rawInputHwnd) + static HWND oldone = nullptr; + static wchar_t tempBuff[260]; + static bool changed = false; + if (const auto h = GetForegroundWindow(); + h != nullptr && h != protoHostHwnd && h != rawInputHwnd) { - wchar_t tempBuff[260]; - GetWindowTextW(h, tempBuff, sizeof(tempBuff) / sizeof(wchar_t)); - - - if (wcsstr(tempBuff, L"Cortana") == nullptr && - wcsstr(tempBuff, L"Task Switching") == nullptr && - wcsstr(tempBuff, L"Program Manager") == nullptr) + if (h != oldone) { + int len = GetWindowTextW(h, tempBuff, _countof(tempBuff)); - DWORD tmpPid; - GetWindowThreadProcessId(h, &tmpPid); + if (len <= 0) + { + tempBuff[0] = L'\0'; + } + else + { + tempBuff[_countof(tempBuff) - 1] = L'\0'; + } - const auto ph = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, tmpPid); + oldone = h; + changed = true; + - wchar_t processNameBuffer[260]; - DWORD buffSize = sizeof(processNameBuffer) / sizeof(wchar_t); - QueryFullProcessImageNameW(ph, 0, processNameBuffer, &buffSize); + if (wcsstr(tempBuff, L"Cortana") == nullptr && + wcsstr(tempBuff, L"Task Switching") == nullptr && + wcsstr(tempBuff, L"Program Manager") == nullptr) + { - auto tmpProcessName = std::filesystem::path(processNameBuffer).filename().wstring(); + DWORD tmpPid; + GetWindowThreadProcessId(h, &tmpPid); - if (tmpProcessName.find(L"explorer.exe") == std::string::npos && - tmpProcessName.find(L"SearchApp.exe") == std::string::npos) - { - processName = std::move(tmpProcessName); - wcscpy(&windowNameBuffer[0], &tempBuff[0]); + const auto ph = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, tmpPid); + + wchar_t processNameBuffer[260]; + DWORD buffSize = sizeof(processNameBuffer) / sizeof(wchar_t); + QueryFullProcessImageNameW(ph, 0, processNameBuffer, &buffSize); - foregroundWindow = h; - focusedPid = tmpPid; + auto tmpProcessName = std::filesystem::path(processNameBuffer).filename().wstring(); - hasAlreadyAddedFocusedPid = false; - for (const auto& instance : instances) + if (tmpProcessName.find(L"explorer.exe") == std::string::npos && + tmpProcessName.find(L"SearchApp.exe") == std::string::npos) { - if (instance.runtime && instance.pid == focusedPid) + processName = std::move(tmpProcessName); + StringCchCopyW(windowNameBuffer, _countof(windowNameBuffer), tempBuff); + + foregroundWindow = h; + focusedPid = tmpPid; + + hasAlreadyAddedFocusedPid = false; + for (const auto& instance : instances) { - hasAlreadyAddedFocusedPid = true; - break; + if (instance.runtime && instance.pid == focusedPid) + { + hasAlreadyAddedFocusedPid = true; + break; + } } } - } - CloseHandle(ph); + CloseHandle(ph); + } } } if (focusedPid != -1) { - if (wcslen(windowNameBuffer) != 0) - ImGui::TextWrapped(R"(Focused process: "%ws" (PID %d, Window "%ws"))", processName.c_str(), focusedPid, &windowNameBuffer[0]); + static std::string processNameUtf8{}; + static std::string windowNameUtf8{}; + if (changed == true) + { + processNameUtf8 = WideToUtf8(processName.c_str()); + windowNameUtf8 = WideToUtf8(windowNameBuffer); + changed = false; + } + if (!windowNameUtf8.empty()) + { + ImGui::TextWrapped("Focused process: \"%s\" (PID %d, Window \"%s\")", + processNameUtf8.c_str(), focusedPid, windowNameUtf8.c_str()); + } else ImGui::TextWrapped(R"(Focused process: "%ws" (PID %d))", processName.c_str(), focusedPid); diff --git a/src/ProtoInput/ProtoInputHost/Profiles.h b/src/ProtoInput/ProtoInputHost/Profiles.h index 951685b..160c982 100644 --- a/src/ProtoInput/ProtoInputHost/Profiles.h +++ b/src/ProtoInput/ProtoInputHost/Profiles.h @@ -110,13 +110,13 @@ struct Profile //Profile::hooks::ProtoHookIDs::RenameHandlesHookID int XinputtoMKBdownkey = 0x28; int XinputtoMKBstickR = 0x5A; //Z int XinputtoMKBstickL = 0x4D; //M - int XinputtoMKBstickright = 0x41; //A - int XinputtoMKBstickleft = 0x44; //D + int XinputtoMKBstickright = 0x44; //D + int XinputtoMKBstickleft = 0x41; //A int XinputtoMKBstickup = 0x57; //W int XinputtoMKBstickdown = 0x53; //S int XinputtoMKBoption = 0x1B; // int XinputtoMKBstart = 0x0D; - int XinputtoMKBsens = 15; + int XinputtoMKBsens = 4; int XinputtoMKBsensmult = 4; int XinputtoMKBDeadzone = 2; diff --git a/src/ProtoInput/ProtoInputUtil/InputLocker.cpp b/src/ProtoInput/ProtoInputUtil/InputLocker.cpp index f6356bb..c476e3b 100644 --- a/src/ProtoInput/ProtoInputUtil/InputLocker.cpp +++ b/src/ProtoInput/ProtoInputUtil/InputLocker.cpp @@ -1,10 +1,10 @@ #include "framework.h" #include "include/protoinpututil.h" #include - bool isLocked = false; bool installedHooks = false; HANDLE threadHandle = nullptr; +long CursorMaxX, CursorMaxY = 0; LRESULT CALLBACK LowLevelMouseProc( _In_ int nCode, @@ -42,7 +42,7 @@ DWORD WINAPI LoopThread(LPVOID lpParameter) if (isLocked) { SetForegroundWindow(GetDesktopWindow()); - RECT rect{ 0,0,0,0 }; + RECT rect{ CursorMaxX -1,CursorMaxY -1,CursorMaxX,CursorMaxY }; ClipCursor(&rect); // ShowCursor(FALSE); // SetCursor(NULL); @@ -59,6 +59,21 @@ DWORD WINAPI LoopThread(LPVOID lpParameter) return 0; } +BOOL CALLBACK EnumWindowProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +{ + MONITORINFO info = { sizeof(info) }; + if (GetMonitorInfo(hMonitor, &info)) + { + if (info.rcMonitor.right > CursorMaxX) + { + CursorMaxX = info.rcMonitor.right; + CursorMaxY = info.rcMonitor.bottom; + } + + } + return true; +} + extern "C" __declspec(dllexport) unsigned int LockInput(bool lock) { isLocked = lock; @@ -74,7 +89,11 @@ extern "C" __declspec(dllexport) unsigned int LockInput(bool lock) if (lock && !installedHooks) { + // Over every screen + EnumDisplayMonitors(nullptr, nullptr, &EnumWindowProc, 0); + installedHooks = true; + Sleep(4); SetWindowsHookExW(WH_MOUSE_LL, LowLevelMouseProc, GetModuleHandle(0), 0); SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(0), 0); } @@ -91,4 +110,4 @@ extern "C" __declspec(dllexport) unsigned int LockInput(bool lock) } return (threadHandle != nullptr) ? GetThreadId(threadHandle) : 0; -} \ No newline at end of file +}