Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/ProtoInput/ProtoInputHooks/AdjustWindowRectHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ namespace Proto
void AdjustWindowRectHook::ShowGuiStatus()
{
int pos[2] = { posx, posy };
ImGui::SliderInt2("Position", &pos[0], -5000, 5000);
ImGui::InputInt2("Position", &pos[0]);
posx = pos[0];
posy = pos[1];

int size[2] = { width, height };
ImGui::SliderInt2("Size", &size[0], 0, 5000);
ImGui::InputInt2("Size", &size[0]);
width = size[0];
height = size[1];
}
Expand Down
110 changes: 97 additions & 13 deletions src/ProtoInput/ProtoInputHooks/FakeCursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@ namespace Proto
{

FakeCursor FakeCursor::state{};
#define WM_MOVE_pointerWindow (WM_APP + 1)

LRESULT WINAPI FakeCursorWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_MOVE_pointerWindow:
{
FakeCursor::state.GetWindowDimensions(hWnd);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
Expand All @@ -24,6 +30,29 @@ LRESULT WINAPI FakeCursorWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
return DefWindowProc(hWnd, msg, wParam, lParam);
}

void FakeCursor::GetWindowDimensions(HWND pointerWindow)
{
HWND tHwnd = (HWND)HwndSelector::GetSelectedHwnd();
if (pointerWindow == tHwnd)
return;

if (IsWindow(tHwnd))
{
RECT cRect;
GetClientRect(tHwnd, &cRect);

POINT topLeft = { cRect.left, cRect.top };
ClientToScreen(tHwnd, &topLeft);

SetWindowPos(pointerWindow, HWND_TOPMOST,
topLeft.x,
topLeft.y,
cRect.right - cRect.left,
cRect.bottom - cRect.top,
SWP_NOACTIVATE);
}
}

LONG fakeCursorMinX = 0, fakeCursorMaxX = 0, fakeCursorMinY = 0, fakeCursorMaxY = 0;

BOOL CALLBACK EnumWindowsProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
Expand Down Expand Up @@ -139,6 +168,31 @@ DWORD WINAPI FakeCursorDrawLoopThread(LPVOID lpParameter)
return 0;
}

DWORD WINAPI PointerWindowLoopThread(LPVOID lpParameter)
{
printf("Pointer window loop thread start\n");
Proto::AddThreadToACL(GetCurrentThreadId());
FakeCursor::state.UpdatePointerWindowLoopInternal();

return 0;
}

void FakeCursor::UpdatePointerWindowLoopInternal()
{
while (true)
{
HWND tHwnd = (HWND)HwndSelector::GetSelectedHwnd();
if (!IsWindow(tHwnd))
{
Sleep(2000);
continue;
}
PostMessage(pointerWindow, WM_MOVE_pointerWindow, 0, 0);

Sleep(5000);
}
}

void FakeCursor::StartDrawLoopInternal()
{
int tick = 0;
Expand All @@ -153,11 +207,15 @@ void FakeCursor::StartDrawLoopInternal()
//TODO: is this ok? (might eat cpu)
Sleep(drawingEnabled ? 12 : 500);

tick = (tick + 1) % 200;
if (!FakeMouseKeyboard::PutMouseInsideWindow)
{

if (tick == 0)
// Nucleus can put the game window above the pointer without this
SetWindowPos(pointerWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);
tick = (tick + 1) % 200;

if (tick == 0)
// Nucleus can put the game window above the pointer without this
SetWindowPos(pointerWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);
}
}
}

Expand All @@ -182,19 +240,33 @@ void FakeCursor::StartInternal()
wc.lpszClassName = className;
wc.style = CS_OWNDC | CS_NOCLOSE;

Sleep(1000);

if (!RegisterClass(&wc))
{
fprintf(stderr, "Failed to open fake cursor window\n");
}
else
{
pointerWindow = CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_NOINHERITLAYOUT | WS_EX_NOPARENTNOTIFY |
WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_LAYERED,
wc.lpszClassName, classNameStr.c_str(), 0,
0, 0, 200, 200,
nullptr, nullptr, hInstance, nullptr);
if (FakeMouseKeyboard::PutMouseInsideWindow)
{
pointerWindow = CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_NOINHERITLAYOUT | WS_EX_NOPARENTNOTIFY |
WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_LAYERED,
wc.lpszClassName, classNameStr.c_str(),
WS_POPUP | WS_VISIBLE,
0, 0, HwndSelector::windowWidth, HwndSelector::windowHeight,
nullptr, nullptr, hInstance, nullptr);
}
else
{
pointerWindow = CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_NOINHERITLAYOUT | WS_EX_NOPARENTNOTIFY |
WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_LAYERED,
wc.lpszClassName, classNameStr.c_str(), 0,
0, 0, 200, 200,
nullptr, nullptr, hInstance, nullptr);

SetWindowLongW(pointerWindow, GWL_STYLE, WS_VISIBLE | WS_DISABLED);
SetWindowLongW(pointerWindow, GWL_STYLE, WS_VISIBLE | WS_DISABLED);
}
SetLayeredWindowAttributes(pointerWindow, transparencyKey, 0, LWA_COLORKEY);

// Nucleus can put the game window above the pointer without this
Expand All @@ -204,9 +276,12 @@ void FakeCursor::StartInternal()
// UpdateWindow(pointerWindow);
EnableDisableFakeCursor(drawingEnabled);

// Over every screen
EnumDisplayMonitors(nullptr, nullptr, &EnumWindowsProc, 0);
MoveWindow(pointerWindow, fakeCursorMinX, fakeCursorMinY, fakeCursorMaxX - fakeCursorMinX, fakeCursorMaxY - fakeCursorMinY, TRUE);
if (!FakeMouseKeyboard::PutMouseInsideWindow)
{
// Over every screen
EnumDisplayMonitors(nullptr, nullptr, &EnumWindowsProc, 0);
MoveWindow(pointerWindow, fakeCursorMinX, fakeCursorMinY, fakeCursorMaxX - fakeCursorMinX, fakeCursorMaxY - fakeCursorMinY, TRUE);
}

hdc = GetDC(pointerWindow);

Expand All @@ -219,6 +294,15 @@ void FakeCursor::StartInternal()
if (threadHandle != nullptr)
CloseHandle(threadHandle);

if (FakeMouseKeyboard::PutMouseInsideWindow)
{
const auto pointerThreadHandle = CreateThread(nullptr, 0,
(LPTHREAD_START_ROUTINE)PointerWindowLoopThread, GetModuleHandle(0), 0, 0);

if (pointerThreadHandle != nullptr)
CloseHandle(pointerThreadHandle);
}

// Want to avoid doing anything in the message loop that might cause it to not respond, as the entire screen will say not responding...
MSG msg;
ZeroMemory(&msg, sizeof(msg));
Expand Down
2 changes: 2 additions & 0 deletions src/ProtoInput/ProtoInputHooks/FakeCursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class FakeCursor
bool DrawFakeCursorFix;
void StartInternal();
void StartDrawLoopInternal();
void UpdatePointerWindowLoopInternal(); // Checks the selected window dimensions.
void GetWindowDimensions(HWND hWnd); // For pointerWindow

static bool& GetToggleVisilbityShorcutEnabled()
{
Expand Down
31 changes: 27 additions & 4 deletions src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ void FakeMouseKeyboard::AddMouseDelta(int dx, int dy)
{
if (!DefaultBottomRightMouseBounds)
{
if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x > max)
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)
if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y >= max)
mouseState.y = max - 1;
}
else if (DefaultBottomRightMouseBounds)
Expand Down Expand Up @@ -137,9 +137,9 @@ void FakeMouseKeyboard::SetMousePos(int x, int y)
{
if (!DefaultBottomRightMouseBounds)
{
if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x > max)
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)
if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y >= max)
mouseState.y = max - 1;
}
else if (DefaultBottomRightMouseBounds)
Expand Down Expand Up @@ -213,6 +213,29 @@ void FakeMouseKeyboard::ClearAsyncKeyState(int vkey)
}
}

bool FakeMouseKeyboard::IsExtendedKey(int vkey)
{
switch (vkey)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
case VK_HOME:
case VK_END:
case VK_PRIOR:
case VK_NEXT:
case VK_INSERT:
case VK_DELETE:
case VK_RCONTROL:
case VK_RMENU:
case VK_SEPARATOR:
return true;
default:
return false;
}
}

bool FakeMouseKeyboard::IsKeyStatePressed(int vkey)
{
if (vkey >= 0 && vkey < keyboardState.keysState.size())
Expand Down
2 changes: 2 additions & 0 deletions src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class FakeMouseKeyboard
static void ClearAsyncKeyState(int vkey);
static bool IsKeyStatePressed(int vkey);
static bool IsAsyncKeyStatePressed(int vkey);
//To use the exteended key flag (like arrow keys)
static bool IsExtendedKey(int vkey);

// Some games must use the exact window rect to determine the edge of the window.
static bool PutMouseInsideWindow;
Expand Down
1 change: 1 addition & 0 deletions src/ProtoInput/ProtoInputHooks/Gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Proto
extern unsigned long GuiThreadID;
extern intptr_t ConsoleHwnd;
extern HWND ProtoGuiHwnd;
extern bool DisableGuiWindow;

int ShowGuiImpl();

Expand Down
4 changes: 4 additions & 0 deletions src/ProtoInput/ProtoInputHooks/GuiImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//TODO: default to hidden
constexpr bool defaultGuiToHidden = true;
constexpr bool defaultConsoleToHidden = true;
bool Proto::DisableGuiWindow = false;

HGLRC g_GLRenderContext;
HDC g_HDCDeviceContext;
Expand Down Expand Up @@ -139,6 +140,9 @@ void Proto::SetConsoleVisible(bool visible)

int Proto::ShowGuiImpl()
{
if (Proto::DisableGuiWindow)
return 0;

auto hInstance = GetModuleHandle(NULL);

WNDCLASS wc = { 0 };
Expand Down
15 changes: 13 additions & 2 deletions src/ProtoInput/ProtoInputHooks/MoveWindowHook.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "MoveWindowHook.h"
#include <imgui.h>
#include "HwndSelector.h"

namespace Proto
{
Expand All @@ -25,14 +26,24 @@ namespace Proto
void MoveWindowHook::ShowGuiStatus()
{
int pos[2] = { posx, posy };
ImGui::SliderInt2("Position", &pos[0], -5000, 5000);
ImGui::InputInt2("Position", &pos[0]);
posx = pos[0];
posy = pos[1];

int size[2] = { width, height };
ImGui::SliderInt2("Size", &size[0], 0, 5000);
ImGui::InputInt2("Size", &size[0]);
width = size[0];
height = size[1];

ImGui::Separator();

if (ImGui::Button("Apply Changes"))
{
if ((HWND)HwndSelector::GetSelectedHwnd() != NULL)
{
::MoveWindow((HWND)HwndSelector::GetSelectedHwnd(), posx, posy, width, height, TRUE);
}
}
}

void MoveWindowHook::InstallImpl()
Expand Down
2 changes: 1 addition & 1 deletion src/ProtoInput/ProtoInputHooks/MoveWindowHook.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace Proto
return
"When the game tries to reposition/resize its game window, this hook forces it to a fixed position and size. ";
}
bool HasGuiStatus() const override { return false; }
bool HasGuiStatus() const override { return true; }
void ShowGuiStatus() override;
void InstallImpl() override;
void UninstallImpl() override;
Expand Down
11 changes: 11 additions & 0 deletions src/ProtoInput/ProtoInputHooks/PipeCommunication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "PipeCommunication.h"
#include <iostream>
#include "HookManager.h"
#include "Gui.h"

#include "pipeinclude/pipeinclude.h"
#include <imgui.h>
Expand Down Expand Up @@ -576,6 +577,16 @@ DWORD WINAPI PipeThread(LPVOID lpParameter)

break;
}
case ProtoPipe::PipeMessageType::DisableGuiWindow:
{
const auto body = reinterpret_cast<ProtoPipe::PipeMessageDisableGuiWindow*>(messageBuffer);

printf("Received DisableGuiWindow, enabled = %d\n", body->DisableGuiWindow);

Proto::DisableGuiWindow = body->DisableGuiWindow;

break;
}
default:
{
fprintf(stderr, "Unrecongnised message type, exiting pipe\n");
Expand Down
18 changes: 14 additions & 4 deletions src/ProtoInput/ProtoInputHooks/RawInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,14 @@ void RawInput::ProcessMouseInput(const RAWMOUSE& data, HANDLE deviceHandle)
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_RBUTTONUP, mouseMkFlags | MouseButtonFilter::signature, mousePointLparam);

if ((data.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) != 0)
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, mouseMkFlags | (XBUTTON1 << 4) | MouseButtonFilter::signature, mousePointLparam);
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, (mouseMkFlags | MK_XBUTTON1) | (XBUTTON1 << 16) | MouseButtonFilter::signature, mousePointLparam);
if ((data.usButtonFlags & RI_MOUSE_BUTTON_4_UP) != 0)
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, mouseMkFlags | (XBUTTON1 << 4) | MouseButtonFilter::signature, mousePointLparam);
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, (mouseMkFlags | MK_XBUTTON1) | (XBUTTON1 << 16) | MouseButtonFilter::signature, mousePointLparam);

if ((data.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) != 0)
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, mouseMkFlags | (XBUTTON2 << 4) | MouseButtonFilter::signature, mousePointLparam);
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, (mouseMkFlags | MK_XBUTTON2) | (XBUTTON2 << 16) | MouseButtonFilter::signature, mousePointLparam);
if ((data.usButtonFlags & RI_MOUSE_BUTTON_5_UP) != 0)
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, mouseMkFlags | (XBUTTON2 << 4) | MouseButtonFilter::signature, mousePointLparam);
PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, (mouseMkFlags | MK_XBUTTON2) | (XBUTTON2 << 16) | MouseButtonFilter::signature, mousePointLparam);
}


Expand Down Expand Up @@ -233,6 +233,11 @@ void RawInput::ProcessKeyboardInput(const RAWKEYBOARD& data, HANDLE deviceHandle
{
lparam |= (1 << 30);
}

if (FakeMouseKeyboard::IsExtendedKey(data.VKey))
{
lparam |= (1 << 24); // Set the extended-key flag
}

PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_KEYDOWN,
MessageFilterHook::IsKeyboardButtonFilterEnabled() ? data.VKey | KeyboardButtonFilter::signature : data.VKey,
Expand All @@ -256,6 +261,11 @@ void RawInput::ProcessKeyboardInput(const RAWKEYBOARD& data, HANDLE deviceHandle
lparam |= (1 << 30); // Previous key state (always 1 for key up)
lparam |= (1 << 31); // Transition state (always 1 for key up)

if (FakeMouseKeyboard::IsExtendedKey(data.VKey))
{
lparam |= (1 << 24); // Set the extended-key flag
}

PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_KEYUP,
MessageFilterHook::IsKeyboardButtonFilterEnabled() ? data.VKey | KeyboardButtonFilter::signature : data.VKey,
lparam);
Expand Down
Loading