Python C++ 模拟键鼠输入,键鼠监听,英雄联盟优化

文章目录

  • 一、windll 输入
  • 二、Interception
  • 三、鼠标键盘监听
  • 联盟优化首先要解决的是输入问题,这里首选语言是 Python,为什么要使用 Python 而不是使用 C++ ,原因如下:

    1. C++ 如果使用注入的方式来操作的话,效果是最好的,但是这样容易被检查进而封号;
    2. 如果不使用 C++ 的注入方式,使用 windll 中的 user32 来操作的话,Python 使用 ctypes 得到的效果和 C++ 基本一致;
    3. Python 是胶水语言,我们可以发挥想象力很方便的添加其他的功能;

    一、windll 输入

    在 Python 中使用 windll 输入主要是靠模拟 C++ 程序使用 ctypes 实现的,鼠标键盘的输入有两种方式,一种是 sendinput ,一种是 mouse_event 和 keybd_event;其中 mouse_event 和 keybd_event 已经被取代,因此这里只能使用 sendinput 函数来执行发送操作;

    构建 sendinput 函数的结构参数如下:

    from ctypes import (windll, byref, Union, POINTER, sizeof,  
                        Structure, c_ulong, pointer, c_long, wintypes)  
      
      
    class POINT(Structure):  
        _fields_ = [("x", c_ulong),  
                    ("y", c_ulong)]  
      
      
    class MOUSEINPUT(Structure):  
        _fields_ = [("dx", c_long),  
                    ("dy", c_long),  
                    ("mouseData", wintypes.DWORD),  
                    ("dwFlags", wintypes.DWORD),  
                    ("time", wintypes.DWORD),  
                    ("dwExtraInfo", POINTER(c_ulong))]  
      
      
    class KEYBDINPUT(Structure):  
        _fields_ = [("wVk", wintypes.WORD),  
                    ("wScan", wintypes.WORD),  
                    ("dwFlags", wintypes.DWORD),  
                    ("time", wintypes.DWORD),  
                    ("dwExtraInfo", POINTER(c_ulong))]  
      
      
    class HARDWAREINPUT(Structure):  
        _fields_ = [("uMsg", wintypes.DWORD),  
                    ("wParamL", wintypes.WORD),  
                    ("wParamH", wintypes.WORD)]  
      
      
    class Input_UNION(Union):  
        _fields_ = [("mi", MOUSEINPUT),  
                    ("ki", KEYBDINPUT),  
                    ("hi", HARDWAREINPUT)]  
      
      
    class INPUT(Structure):  
        _fields_ = [("type", c_ulong),  
                    ("DUMMYUNIONNAME", Input_UNION)]  
    

    接着实现鼠标控制和键盘控制函数如下:

    def get_mouse_pos():
    	"""获取鼠标当前位置"""
        orig = POINT()  
        windll.user32.GetCursorPos(byref(orig))  
        return int(orig.x), int(orig.y)  
      
      
    def set_mouse_pos(x, y):
    	"""设置鼠标当前位置"""
        windll.user32.SetCursorPos(x, y)  
      
      
    def mouse_click(right=False):
    	"""执行鼠标点击"""
        # down up 的值  
        down = 0x02 if not right else 0x08  
        up = 0x04 if not right else 0x10  
      
        extra_info = c_ulong()  
        windll.user32.GetMessageExtraInfo(byref(extra_info))  
      
        # 创建输入  
        INPUTS = INPUT * 2  
        union_1 = Input_UNION()  
        union_2 = Input_UNION()  
        union_1.mi = MOUSEINPUT(0, 0, 0, down | 0x0001, 0, pointer(extra_info))  
        union_2.mi = MOUSEINPUT(0, 0, 0, up | 0x0001, 0, pointer(extra_info))  
        inputs = INPUTS((0, union_1), (0, union_2))  
        windll.user32.SendInput(2, pointer(inputs), sizeof(inputs[0]))  
      
    def keyboard_click(keyname):
    	"""执行键盘点击"""
    	# 在游戏中可能只接受 directinput
    	# http://www.flint.jp/misc/?q=dik&lang=en
        dic = {  
            'q' : 0x10,  
            'w' : 0x11,  
            'e' : 0x12,  
            'r' : 0x13,  
            's' : 0x1F,  
        }  
        value = dic.setdefault(keyname, None)  
        extra_info = c_ulong()  
        windll.user32.GetMessageExtraInfo(byref(extra_info))  
        if value:  
            INPUTS = INPUT * 2  
            union_1 = Input_UNION()  
            union_1.ki = KEYBDINPUT(0, value, 0x0008, 0, pointer(extra_info))  
            union_2 = Input_UNION()  
            union_2.ki = KEYBDINPUT(0, value, 0x0008 | 0x0002, 0, pointer(extra_info))
            inputs = INPUTS((1, union_1), (2, union_2))  
            windll.user32.SendInput(2, pointer(inputs), sizeof(inputs[0]))  
    

    这里可以看下面文档进行修改和操作:

    1. sendInput 函数 (winuser.h) – Win32 apps | Microsoft Learn
    2. INPUT (winuser.h) – Win32 apps | Microsoft Learn
    3. MOUSEINPUT (winuser.h) – Win32 apps | Microsoft Learn
    4. KEYBDINPUT (winuser.h) – Win32 apps | Microsoft Learn
    5. HARDWAREINPUT (winuser.h) – Win32 apps | Microsoft Learn
    6. DirectInput Key Code Table (flint.jp)

    二、Interception

    如果你目前发送输入的东西工作正常,而且你不担心被某种反作弊软件标记,那么,你完全可以继续使用pyautogui/pydirectinput。此时值得注意的是,许多更高级的反作弊软件,包括Vanguard和一些版本的EAC,在驱动程序加载到你的系统上时将不会启动,毕竟,这是一个众所周知的软件。如果你问我如何绕过这种检测——那就自己编写驱动程序吧。

    官网:GitHub – kennyhml/pyinterception: Modern Python port & wrapper for the interception device driver

    Interception 是一个用于拦截的低级输入设备驱动程序,主要用于解决尝试向应用程序发送输入,但什么也没发生的情况;这是由于通过 windows API 发送输入时,windows 能够区分假的输入和真实的输入;

    使用方法如下:

    1. 首先到官网GitHub – oblitum/Interception.下载 Interception 的驱动程序;
    2. 打开 command line installer 文件夹,在该文件夹目录下以管理员的方式打开命令提示符即 cmd 窗口,然后输入代码:install-interception /install
    3. 重新启动电脑,完毕后观察 C:\Windows\System32\drivers 是否存在 mouse.sys keyboard.sys 两个文件,如果有说明驱动安装完毕;
    4. 安装 Python 的调用包,pip install interception-python
    5. 处理完毕后就可以导入包了,import interception

    驱动如果下载不了,百度云网盘如下:

    链接:https://pan.baidu.com/s/1tb0hxx0SKXApvGzOBlau6Q?pwd=zynb
    提取码:zynb

    Interception-python 的使用非常简单,和 pyautogui 或 pydirectinput 差不多,实例如下:

    import interception
    
    interception.auto_capture_devices(keyboard=True, mouse=True, verbose=True)
    interception.move_to(960, 540)
    
    with interception.hold_key("shift"):
        interception.press("a")
    
    interception.click(120, 160, button="right", delay=1)
    

    三、鼠标键盘监听

    鼠标键盘监听这里使用的是 Pynput ,全平台的 Python 包;

    官网如下:Handling the keyboard — pynput 1.7.6 documentation

    其操作使用也是十分简单,锐雯 wsq 和 rsq 连招实例如下:

    import interception  
    from pynput import mouse, keyboard  
      
      
    key_state = {  
        'q' : False,  
        'w' : False,  
        'e' : False,  
        'r' : False,  
        's' : False,  
        'space' : False,  
    }  
    interception.auto_capture_devices(keyboard=True, mouse=True, verbose=True)  
      
    def on_press(key):  
        global key_state  
        if key == keyboard.Key.space:  
            key_state['space'] = True  
      
        if key_state['space']:  
            if key == keyboard.KeyCode(char='w') and key_state['w'] == False:  
                key_state['w'] = True  
                print("wsq 连招")  
                interception.press('s')  
                interception.press('q')  
      
      
            if key == keyboard.KeyCode(char='r') and key_state['r'] == False:  
                key_state['r'] = True  
                print("rsq 连招")  
                interception.press('q')  
      
      
    def on_release(key):  
        global key_state  
        if key == keyboard.Key.space:  
            key_state['space'] = False  
      
        if key == keyboard.KeyCode(char='w'):  
            key_state['w'] = False  
      
        if key == keyboard.KeyCode(char='r'):  
            key_state['r'] = False  
      
      
    with keyboard.Listener(on_release=on_release, on_press=on_press) as listener:  
        listener.join()
    

    还可以添加其他功能,例如和神经网络结合…

    作者:Bigcrab__

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python C++ 模拟键鼠输入,键鼠监听,英雄联盟优化

    发表回复