add 硬件控制模块 (hardware_control.py) 并修复游戏状态扫描区域宽度

- 新增 wyhkm.dll 硬件盒子 COM 接口封装,支持键盘鼠标控制
- 修复 game_state_config.json 中 scan_region_width 过小导致截图越界的问题
- 添加鼠标路径录制器、硬件测试脚本等工具
- 更新多项配置默认值

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
王鹏
2026-04-15 12:15:00 +08:00
parent b4de5278ed
commit 33dc741fd9
203 changed files with 12197 additions and 247 deletions

152
hardware_control.py Normal file
View File

@@ -0,0 +1,152 @@
import os
import sys
import ctypes
from ctypes import *
import time
import win32com.client
import pythoncom
class HardwareController:
"""
接入 wyhkm.dll 硬件盒子的 COM 接口封装类。
经过实测验证Index 0 配合 SetMode(2, 1) 可同时支持键盘与鼠标。
"""
_instance = None
_wyhkm = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(HardwareController, cls).__new__(cls)
return cls._instance
def __init__(self, dll_path="ddl/wyhkm.dll"):
if self._wyhkm:
return
self.dll_path = os.path.abspath(dll_path)
if not os.path.exists(self.dll_path):
print(f">>> [硬件控制] 错误:找不到 DLL 文件 {self.dll_path}")
return
try:
# 1. 进程内注册 (标准 64 位注册方式)
hkmdll = windll.LoadLibrary(self.dll_path)
hkmdll.DllInstall.argtypes = (c_long, c_longlong)
if hkmdll.DllInstall(1, 2) < 0:
print(">>> [硬件控制] 注册失败!")
return
else:
print(">>> [硬件控制] 进程内注册 wyhkm.dll 成功")
# 2. 创建对象
pythoncom.CoInitialize()
try:
self._wyhkm = win32com.client.Dispatch("wyp.hkm")
except Exception as e:
print(f">>> [硬件控制] 创建对象失败: {e}")
return
# 3. 查找并打开设备 (Index 0 已验证支持键盘鼠标)
dev_id = self._wyhkm.SearchDevice(0x2612, 0x1701, 0)
if dev_id == -1:
print(">>> [硬件控制] 未找到无涯键鼠盒子 (Index 0)")
return
if not self._wyhkm.Open(dev_id, 0):
print(">>> [硬件控制] 打开设备失败")
return
# 4. 关键初始化设置 (实测鼠标移动必须开启模式 2, 1)
# 开启键盘增强模拟
self._wyhkm.SetMode(1, 1)
# 开启鼠标仿真移动 (解决鼠标不动的问题)
self._wyhkm.SetMode(2, 1)
# 设置推荐的按键/鼠标间隔 (与 test_hw.py 一致30-50ms 更稳定)
self._wyhkm.SetKeyInterval(30, 50)
self._wyhkm.SetMouseInterval(30, 50)
print(f">>> [硬件控制] 成功打开设备并完成初始化配置")
except Exception as e:
print(f">>> [硬件控制] 初始化异常: {e}")
self._wyhkm = None
def is_available(self):
if not self._wyhkm:
return False
try:
# 修正IsOpen 需要参数 (0:全模式, 1:键盘, 2:鼠标)
# 之前漏传参数会导致 COM 报错,进而导致 key_down 等所有操作被 skip
return self._wyhkm.IsOpen(0)
except:
return False
def delay_rnd(self, min_ms, max_ms):
"""随机延时"""
if self.is_available():
try: self._wyhkm.DelayRnd(int(min_ms), int(max_ms))
except: pass
# --- 键盘操作 (均使用大写字符串) ---
def key_down(self, key_str):
if self.is_available():
try: self._wyhkm.KeyDown(str(key_str).upper())
except: pass
def key_up(self, key_str):
if self.is_available():
try: self._wyhkm.KeyUp(str(key_str).upper())
except: pass
def key_press(self, key_str):
if self.is_available():
try: self._wyhkm.KeyPress(str(key_str).upper())
except: pass
# 兼容性别名
def keyDown(self, key_str): self.key_down(key_str)
def keyUp(self, key_str): self.key_up(key_str)
def press(self, key_str): self.key_press(key_str)
# --- 鼠标操作 ---
def move_to(self, x, y):
"""绝对移动"""
if self.is_available():
try: self._wyhkm.MoveTo(int(x), int(y))
except: pass
def move_r(self, dx, dy):
"""相对移动"""
if self.is_available():
try: self._wyhkm.MoveR(int(dx), int(dy))
except: pass
def MoveR(self, dx, dy): # 兼容写法
self.move_r(dx, dy)
def left_click(self):
if self.is_available():
try: self._wyhkm.LeftClick()
except: pass
def right_click(self):
if self.is_available():
try: self._wyhkm.RightClick()
except: pass
def left_down(self):
if self.is_available():
try: self._wyhkm.LeftDown()
except: pass
def left_up(self):
if self.is_available():
try: self._wyhkm.LeftUp()
except: pass
# 全局实例
hw_ctrl = HardwareController()