You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python读取原始鼠标输入?适配Minecraft宏录制场景

读取原始鼠标输入实现Minecraft宏录制

问题分析

你提到PyAutoGUI和Pynput的常规方法只能获取屏幕坐标,但Minecraft会锁定鼠标在屏幕中心,导致坐标变化无法反映真实的鼠标移动输入。你之前的代码存在几个关键问题:

  • 计算change_y时错误地减去了base_position_x,正确应为base_position_y
  • 回放代码里zip(x_coords, x_coords)是笔误,应该是zip(x_coords, y_coords)
  • PyAutoGUI的move()默认是绝对坐标移动,而非相对偏移,需改用moveRel()
  • 依赖屏幕坐标的方案本身不适用于鼠标被锁定的场景,必须读取原始鼠标输入事件才能解决问题

解决方案:读取原始鼠标输入

Windows平台(使用pywin32监听原始输入)

通过Windows原始输入API捕获鼠标的原始移动数据,不受屏幕坐标限制:

import win32api
import win32con
import win32gui
import time

# 注册原始输入设备
def register_raw_input(hwnd):
    rid = win32gui.RAWINPUTDEVICE()
    rid.usUsagePage = 0x01
    rid.usUsage = 0x02  # 指定鼠标设备
    rid.dwFlags = win32con.RIDEV_INPUTSINK
    rid.hwndTarget = hwnd
    win32gui.RegisterRawInputDevices([rid])

# 解析原始输入消息,提取鼠标偏移量
def process_raw_input(msg):
    data = win32gui.GetRawInputData(msg.lParam, win32con.RID_INPUT)
    if data:
        raw_input = data[1]
        if raw_input.header.dwType == win32con.RIM_TYPEMOUSE:
            mouse_data = raw_input.data.mouse
            dx = mouse_data.lLastX
            dy = mouse_data.lLastY
            return dx, dy
    return 0, 0

# 创建隐藏窗口接收原始输入消息
hwnd = win32gui.CreateWindowEx(0, win32gui.WNDCLASS(), "RawInputWindow", 0, 0, 0, 0, 0, 0, 0, None)
register_raw_input(hwnd)

# 录制原始鼠标移动(包含时间戳)
recorded_moves = []
start_time = time.time()

print("开始录制,按Ctrl+C停止")
try:
    while True:
        msg = win32gui.GetMessage(None, 0, 0)
        if msg.message == win32con.WM_INPUT:
            dx, dy = process_raw_input(msg)
            if dx != 0 or dy != 0:
                recorded_moves.append((dx, dy, time.time() - start_time))
        win32gui.TranslateMessage(msg)
        win32gui.DispatchMessage(msg)
        time.sleep(0.001)
except KeyboardInterrupt:
    print("录制结束")

# 回放原始鼠标移动
print("开始回放")
start_time = time.time()
for dx, dy, timestamp in recorded_moves:
    # 同步时间戳
    while time.time() - start_time < timestamp:
        time.sleep(0.001)
    # 模拟原始鼠标移动
    win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, dx, dy, 0, 0)

Linux平台(使用evdev)

通过evdev直接读取输入设备的原始事件,需要先安装依赖:pip install evdev

from evdev import InputDevice, categorize, ecodes
import time

# 替换为你的鼠标设备路径,可通过`ls /dev/input/event*`查找
mouse_device = InputDevice('/dev/input/event5')

recorded_moves = []
start_time = time.time()

print("开始录制,按Ctrl+C停止")
try:
    for event in mouse_device.read_loop():
        if event.type == ecodes.EV_REL:
            rel_event = categorize(event)
            if rel_event.event.code == ecodes.REL_X:
                recorded_moves.append(('x', rel_event.event.value, time.time() - start_time))
            elif rel_event.event.code == ecodes.REL_Y:
                recorded_moves.append(('y', rel_event.event.value, time.time() - start_time))
except KeyboardInterrupt:
    print("录制结束")

# 回放原始移动(需root权限或用户加入input组)
print("开始回放")
start_time = time.time()
for axis, value, timestamp in recorded_moves:
    while time.time() - start_time < timestamp:
        time.sleep(0.001)
    if axis == 'x':
        mouse_device.write(ecodes.EV_REL, ecodes.REL_X, value)
    elif axis == 'y':
        mouse_device.write(ecodes.EV_REL, ecodes.REL_Y, value)
    mouse_device.syn()  # 同步事件,确保系统接收

注意事项

  • Windows下运行需管理员权限,否则无法捕获原始输入
  • Linux下需将用户加入input组(sudo usermod -aG input 你的用户名)或用root权限运行
  • Minecraft的反作弊机制可能检测模拟输入,建议在单机模式测试,避免账号风险

内容的提问来源于stack exchange,提问作者user24963864

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:53:16