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

联盟优化首先要解决的是输入问题,这里首选语言是 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()

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值