如果无法识别,如何在游戏中模拟硬件鼠标点击?

Posted

技术标签:

【中文标题】如果无法识别,如何在游戏中模拟硬件鼠标点击?【英文标题】:How to simulate a hardware mouse click in game if it is not recognized? 【发布时间】:2021-10-21 19:44:16 【问题描述】:

我想点击一个游戏的按钮。我尝试了几种方法,SendInputMouseEvent 就是其中的一些。尽管如此,我总是得到相同的结果,但它不起作用。

这是原始按钮。

当我用SendInputMouseEvent点击它时,这就是按钮

颜色改变了,但它根本不起作用。 (我还尝试了leftClickdouble LeftClickleftClickUp/Down。)我的猜测是,如果点击不是虚拟的,它应该可以工作?我完全不确定,因为我对此不太了解。

有什么想法吗?

小更新:正如我所提到的,我尝试过使用SendInputMouseEventInputSimulator 等等,问题总是一样的,虽然它在那个游戏中有效,但它没有那个按钮。我很确定这可能是因为游戏检测到它是虚拟点击模拟。

因为有些人要求提供代码。 (我再重复一遍,这在代码中看起来不是问题......)

这个是给InputSimulator的。


InputSimulator sim = new InputSimulator();
sim.Mouse.LeftButtonDoubleClick();

这个使用MouseEvent


[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

private const int MOUSEEVENT_LEFTDOWN = 0x02;
private const int MOUSEEVENT_LEFTUP = 0x04;
private const int MOUSEEVENT_MIDDLEDOWN = 0x20;
private const int MOUSEEVENT_MIDDLEUP = 0x40;
private const int MOUSEEVENT_RIGHTDOWN = 0x08;
private const int MOUSEEVENT_RIGHTUP = 0x10;

static void Click()
   mouse_event(MOUSEEVENT_LEFTDOWN, 0, 0, 0, 0);
   mouse_event(MOUSEEVENT_LEFTUP, 0, 0, 0, 0);


private void timer1_Tick(object sender, EventArgs e) 
   Click();

这个使用SendInput。 (MouseSimulator 是一个使用 SendInput 的静态类。)


MouseSimulator.ClickLeftMouseButton();

这是 MouseSimulator 的类。

using System;
using System.Runtime.InteropServices;

public class MouseSimulator

    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

    [StructLayout(LayoutKind.Sequential)]
    struct INPUT
    
        public SendInputEventType type;
        public MouseKeybdhardwareInputUnion mkhi;
    
    [StructLayout(LayoutKind.Explicit)]
    struct MouseKeybdhardwareInputUnion
    
        [FieldOffset(0)]
        public MouseInputData mi;

        [FieldOffset(0)]
        public KEYBDINPUT ki;

        [FieldOffset(0)]
        public HARDWAREINPUT hi;
    
    [StructLayout(LayoutKind.Sequential)]
    struct KEYBDINPUT
    
        public ushort wVk;
        public ushort wScan;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    
    [StructLayout(LayoutKind.Sequential)]
    struct HARDWAREINPUT
    
        public int uMsg;
        public short wParamL;
        public short wParamH;
    
    struct MouseInputData
    
        public int dx;
        public int dy;
        public uint mouseData;
        public MouseEventFlags dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    
    [Flags]
    enum MouseEventFlags : uint
    
        MOUSEEVENTF_MOVE = 0x0001,
        MOUSEEVENTF_LEFTDOWN = 0x0002,
        MOUSEEVENTF_LEFTUP = 0x0004,
        MOUSEEVENTF_RIGHTDOWN = 0x0008,
        MOUSEEVENTF_RIGHTUP = 0x0010,
        MOUSEEVENTF_MIDDLEDOWN = 0x0020,
        MOUSEEVENTF_MIDDLEUP = 0x0040,
        MOUSEEVENTF_XDOWN = 0x0080,
        MOUSEEVENTF_XUP = 0x0100,
        MOUSEEVENTF_WHEEL = 0x0800,
        MOUSEEVENTF_VIRTUALDESK = 0x4000,
        MOUSEEVENTF_ABSOLUTE = 0x8000
    
    enum SendInputEventType : int
    
        InputMouse,
        InputKeyboard,
        InputHardware
    

    public static void ClickLeftMouseButton()
    
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));

        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    
    public static void ClickRightMouseButton()
    
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));

        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    


它们在游戏之外都运行良好,在内部它们就像我上面描述的那样运行。

由于游戏中的所有按钮都会发生这种情况,因此这是一个 gif,显示正在发生的事情与预期发生的事情。

这是预期的行为。

https://gyazo.com/ffd6af281414c5b0b10e19cf7a27823d

尽管如此,这就是正在发生的事情。 (您可以看到颜色发生了变化,看起来像是被按下但显然没有)

https://gyazo.com/20ebb3bc360a4a5bccbe3ea5207d201b

【问题讨论】:

这能回答你的问题吗? Directing mouse events [DllImport("user32.dll")] click, double click @OlivierRogier 是的,我也尝试过 InputSimulator 并遇到了同样的问题。 InputSimulator sim = new InputSimulator(); sim.Mouse.LeftButtonDoubleClick(); 代码本身没有任何错误,它可以完美地在其他应用程序上运行,但它没有那个按钮。 (.Net 框架 WinForms) @OlivierRogier 我已经添加了一些代码。 @OlivierRogier 更新了,我希望现在看起来有点清楚了。 最后我解决了使用 Interception 的包装问题,使用驱动程序使游戏相信是真实鼠标而不是虚拟鼠标。这是包装器链接。 github.com/jasonpang/Interceptor 【参考方案1】:

您的问题质量非常低。按钮的设计不相关,您的代码将是。不过我还是猜一猜。

嗯。看起来点击已注册。可能是您的脚本按下了鼠标按钮并且从不释放它吗?许多 UI 不会在按下按钮时触发,而是在释放按钮时触发。我对 C# 了解不多,但在 Powershell 中,您需要告诉脚本分别按下和释放按钮。

【讨论】:

以上是关于如果无法识别,如何在游戏中模拟硬件鼠标点击?的主要内容,如果未能解决你的问题,请参考以下文章

FPS游戏实战数据集|yolov8训练模型导出|C/C++项目|驱动鼠标模拟人工|加密狗USB硬件虚拟化

win10无法识别usb设备怎么办

“游戏中心无法识别此游戏”错误

windows 10 中用mklink 无法识别

二维码无法识别的原因

关于微信网页/H5游戏开发中二维码无法识别的解决方法