我一直在构建一个需要向游戏发送模拟输入的游戏相关程序(这是屏幕上的顶部窗口并以全屏模式运行)。经过一番挣扎,我终于让鼠标移动(光标拖动)和键盘输入正常工作,但由于某种原因,游戏不会响应模拟鼠标点击。
我尝试了以下方法:
#if TRUE // SendInput works for keyboard simulation and mouse drag, but not clicks:
INPUT mouse = {0};
mouse.type = INPUT_MOUSE;
mouse.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &mouse, sizeof(INPUT));
Sleep(100);
ZeroMemory(&mouse, sizeof INPUT);
mouse.type = INPUT_MOUSE;
mouse.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &mouse, sizeof(INPUT));
#else // tried this, but it did not work:
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
Sleep(75);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
#endif
我面临的第一个难题是一般发送消息,但我意识到这个问题是由游戏进程权限>发送应用程序权限引起的。在此之后,我遇到了另一个问题,按键只能在某些游戏窗口/屏幕上注册,但经过一番搜索,我能够使用扫描码来克服这个问题。例如:
void SendSpacePress(bool bHardwareLevel){
INPUT space = {0};
space.type = INPUT_KEYBOARD;
space.ki.time = 0;
space.ki.dwExtraInfo = 0;
if(!bHardwareLevel){
space.ki.wVk = VK_SPACE;
}else{
space.ki.wScan = 0x39; // physical keyboard scan code
}
space.ki.dwFlags = bHardwareLevel ? KEYEVENTF_SCANCODE : 0;
SendInput(1, &space, sizeof(INPUT));
Sleep(rand()%25 + 25);
space.ki.dwFlags = bHardwareLevel ? KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP : KEYEVENTF_KEYUP;
SendInput(1, &space, sizeof(INPUT));
}
我还能够使用 INPUT 进行鼠标移动,如下所示:
void PanMouse(){
INPUT mouse = {0};
mouse.type = INPUT_MOUSE;
mouse.mi.time = 0;
mouse.mi.mouseData = 0;
mouse.mi.dwExtraInfo = 0;
mouse.mi.dwFlags = MOUSEEVENTF_MOVE;
mouse.mi.dx = rand()%10 -5;
mouse.mi.dy = rand()%10 -5;
SendInput(1, &mouse, sizeof(INPUT));
}
现在最大的问题是游戏拒绝注册我的模拟鼠标点击。我希望有一种无需深入挂钩即可发送鼠标输入的方法。(游戏有多种客户端反作弊机制,所以我大胆猜测任何类型的外部进程挂钩或 DLL 注入都会触发保护。)根据我的阅读,我可能需要编写一个自定义驱动程序一个模拟的硬件鼠标,因此输入来自内核级别。不是一个更好的选择,但如果需要,sobeit
. (如果需要,任何人都可以为此提供有用的信息吗?我从来没有搞砸过编写驱动程序,但我想的一切都是第一次。)
TL;DR:我需要做什么才能让模拟鼠标点击在似乎忽略非硬件输入的游戏中注册?(即,我怎样才能让游戏认为鼠标点击是合法的,类似于KEYEVENTF_SCANCODE
在模拟键盘输入时使用?)