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

View File

@@ -1,7 +1,7 @@
import json
import math
import time
import pydirectinput
from hardware_control import hw_ctrl
# 修理商所在位置(游戏坐标),按实际位置修改
VENDOR_POS = (30.08, 71.51)
@@ -34,21 +34,61 @@ class LogisticsManager:
else:
self.is_returning = False
def use_hearthstone_and_stop(self):
"""按炉石按键并等待施法完成,返回 True 表示已执行(调用方应随后结束循环)"""
print(f">>> [后勤] 包满,使用炉石({self.hearthstone_key})回城,等待 {self.hearthstone_cast_sec:.0f}s...")
pydirectinput.press(self.hearthstone_key)
time.sleep(self.hearthstone_cast_sec)
print(">>> [后勤] 炉石施法完成,停止所有动作。")
def use_hearthstone_and_stop(self, get_state=None):
"""按炉石按键并等待施法完成,带有坐标校验的重试机制"""
max_retries = 3
success = False
for i in range(max_retries):
start_pos = None
if get_state:
st = get_state()
if st:
start_pos = (st.get('x'), st.get('y'))
print(f">>> [后勤] 第 {i+1} 次尝试使用炉石(按键: {self.hearthstone_key}...")
# 先按一下 S 确保停止移动,防止移动中按炉石失败
hw_ctrl.press('s')
time.sleep(0.5)
hw_ctrl.press(self.hearthstone_key)
# 等待施法过程
print(f">>> [后勤] 正在等待施法 {self.hearthstone_cast_sec}s...")
time.sleep(self.hearthstone_cast_sec + 2.0) # 多等 2 秒保险
if get_state and start_pos and start_pos[0] is not None:
st_now = get_state()
if st_now:
end_pos = (st_now.get('x'), st_now.get('y'))
dist = math.dist(start_pos, end_pos)
# 如果坐标发生了明显跳变(大于 2.0),证明回城成功
if dist > 2.0:
print(f">>> [后勤] 炉石回城成功!位置跳变距离: {dist:.2f}")
success = True
break
else:
print(f">>> [后勤] 炉石似乎失败(位置未变化),准备重试...")
else:
# 获取不到状态可能已经卡死或窗口关闭,默认成功以退出循环
success = True
break
else:
# 如果没法校验坐标,就只执行一次
success = True
break
if not success:
print(">>> [后勤] 警告:多次尝试炉石回城均未检测到位置跳变!")
self.is_returning = False
return True
return success
def return_home(self):
"""执行回城动作"""
# 1. 停止当前巡逻
# 2. 寻找安全点或直接使用炉石
print(">>> 正在释放炉石...")
pydirectinput.press('7') # 假设炉石在 7 号键
hw_ctrl.press('7') # 假设炉石在 7 号键
time.sleep(15) # 等待炉石施法
def handle_town_visit(self, state, patrol):
@@ -64,9 +104,9 @@ class LogisticsManager:
def _do_vendor_interact(self):
"""执行与修理商/背包的交互按键8、4"""
pydirectinput.press("8")
hw_ctrl.press("8")
time.sleep(0.5)
pydirectinput.press("4")
hw_ctrl.press("4")
time.sleep(2)
def run_route1_round(self, get_state, patrol, route_file=None):
@@ -94,4 +134,4 @@ class LogisticsManager:
if not ok:
print(">>> [后勤] 反向未完成")
return
print(">>> [后勤] route1 往返结束")
print(">>> [后勤] route1 往返结束")