From 863db5fa0ddb6f3591e57261390443602c1b1f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 21 Apr 2026 11:56:55 +0800 Subject: [PATCH] Make turn recovery action configurable --- auto_bot.py | 17 +++++++++++++---- auto_bot_move.py | 9 ++++++--- wow_multikey_gui.py | 43 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/auto_bot.py b/auto_bot.py index 206b289..6a02a36 100644 --- a/auto_bot.py +++ b/auto_bot.py @@ -199,7 +199,15 @@ def load_attack_loop(path): class AutoBot: - def __init__(self, waypoints=None, attack_loop_path=None, skinning_wait_sec=None, enable_mouse_loot=True): + def __init__( + self, + waypoints=None, + attack_loop_path=None, + skinning_wait_sec=None, + enable_mouse_loot=True, + turn_error_key=None, + turn_error_hold_sec=None, + ): self.last_tab_time = 0 self.last_interaction_time = 0 self.last_target_hp = 0 @@ -215,8 +223,9 @@ class AutoBot: self.enable_mouse_loot = enable_mouse_loot self.cursor_mgr = CursorManager() self.last_turn_signal_time = 0.0 + self.turn_error_key = (turn_error_key or 's').strip().lower() or 's' self.combat_signal_retry_sec = 1.0 - self.turn_error_hold_sec = 0.8 + self.turn_error_hold_sec = float(turn_error_hold_sec) if turn_error_hold_sec is not None else 0.8 self._last_mouse_path_scale_signature = None def execute_disengage_loot(self): @@ -525,9 +534,9 @@ class AutoBot: combat_error_signal == 50 and (current_time - self.last_turn_signal_time) >= self.combat_signal_retry_sec ): - hw_ctrl.keyDown('s') + hw_ctrl.keyDown(self.turn_error_key) time.sleep(self.turn_error_hold_sec) - hw_ctrl.keyUp('s') + hw_ctrl.keyUp(self.turn_error_key) self.last_turn_signal_time = current_time self.last_target_hp = target_hp if state['combat']: diff --git a/auto_bot_move.py b/auto_bot_move.py index 5e5f98d..88f6e93 100644 --- a/auto_bot_move.py +++ b/auto_bot_move.py @@ -250,6 +250,8 @@ class AutoBotMove: release_spirit_key=None, resurrect_key=None, enable_mouse_loot=True, + turn_error_key=None, + turn_error_hold_sec=None, ): self.last_tab_time = 0 self.last_interaction_time = 0 # 记录上一次按互动键的时间 @@ -271,7 +273,8 @@ class AutoBotMove: self._eating_started_at = None self.last_turn_signal_time = 0.0 self.combat_signal_retry_sec = 1.0 - self.turn_error_hold_sec = 0.8 + self.turn_error_key = (turn_error_key or 's').strip().lower() or 's' + self.turn_error_hold_sec = float(turn_error_hold_sec) if turn_error_hold_sec is not None else 0.8 self._last_mouse_path_scale_signature = None # stop_check: 返回 True 表示需要立即停止(用于中断阻塞中的后勤/路线导航) self._stop_check = stop_check if callable(stop_check) else (lambda: False) @@ -710,9 +713,9 @@ class AutoBotMove: combat_error_signal == 50 and (now - self.last_turn_signal_time) >= self.combat_signal_retry_sec ): - hw_ctrl.keyDown('s') + hw_ctrl.keyDown(self.turn_error_key) time.sleep(self.turn_error_hold_sec) - hw_ctrl.keyUp('s') + hw_ctrl.keyUp(self.turn_error_key) self.last_turn_signal_time = now self.last_target_hp = target_hp diff --git a/wow_multikey_gui.py b/wow_multikey_gui.py index bca8b0d..c61a627 100644 --- a/wow_multikey_gui.py +++ b/wow_multikey_gui.py @@ -324,6 +324,8 @@ class GameLoopWorker(QThread): resurrect_key=None, enable_mouse_loot=True, use_hardware_input=True, + turn_error_key=None, + turn_error_hold_sec=None, ): super().__init__() self.mode = mode # 'monitor' | 'patrol' | 'combat' | 'quest_follow' | 'flight' | 'record' @@ -364,6 +366,11 @@ class GameLoopWorker(QThread): self.resurrect_key = resurrect_key self.enable_mouse_loot = enable_mouse_loot self.use_hardware_input = bool(use_hardware_input) + self.turn_error_key = (turn_error_key or "s").strip().lower() or "s" + try: + self.turn_error_hold_sec = float(turn_error_hold_sec) + except (TypeError, ValueError): + self.turn_error_hold_sec = 0.8 def run(self): try: @@ -398,6 +405,8 @@ class GameLoopWorker(QThread): release_spirit_key=self.release_spirit_key, resurrect_key=self.resurrect_key, enable_mouse_loot=self.enable_mouse_loot, + turn_error_key=self.turn_error_key, + turn_error_hold_sec=self.turn_error_hold_sec, ) self.bot_move._on_hearthstone_stop = self.stop_signal.emit except ImportError as e: @@ -411,6 +420,8 @@ class GameLoopWorker(QThread): attack_loop_path=self.attack_loop_path, skinning_wait_sec=self.skinning_wait_sec, enable_mouse_loot=self.enable_mouse_loot, + turn_error_key=self.turn_error_key, + turn_error_hold_sec=self.turn_error_hold_sec, ) except ImportError as e: self.log_signal.emit(f"❌ 自动打怪依赖加载失败: {e}") @@ -1056,6 +1067,15 @@ class WoWMultiKeyGUI(QMainWindow): self.eat_max_wait_spin.setSingleStep(1.0) self.eat_max_wait_spin.setValue(30.0) self.eat_max_wait_spin.setSuffix(" 秒") + self.turn_error_key_edit = QLineEdit() + self.turn_error_key_edit.setPlaceholderText("如 s") + self.turn_error_key_edit.setMaxLength(16) + self.turn_error_key_edit.setText("s") + self.turn_error_hold_spin = QDoubleSpinBox() + self.turn_error_hold_spin.setRange(0.1, 10.0) + self.turn_error_hold_spin.setSingleStep(0.1) + self.turn_error_hold_spin.setValue(0.8) + self.turn_error_hold_spin.setSuffix(" 秒") self.gs_hearthstone_key = QLineEdit() self.gs_hearthstone_key.setPlaceholderText("如 b") self.gs_hearthstone_key.setMaxLength(16) @@ -1117,10 +1137,15 @@ class WoWMultiKeyGUI(QMainWindow): game_grid.addWidget(QLabel("释放灵魂按键:"), 4, 2) game_grid.addWidget(self.gs_release_spirit_key, 4, 3) - game_grid.addWidget(self.gs_use_hardware_input, 5, 0, 1, 2) - game_grid.addWidget(QLabel("复活按键:"), 5, 2) - game_grid.addWidget(self.gs_resurrect_key, 5, 3) - game_grid.addWidget(self.gs_bag_full_hearthstone, 6, 1) + game_grid.addWidget(QLabel("需转身按键:"), 5, 0) + game_grid.addWidget(self.turn_error_key_edit, 5, 1) + game_grid.addWidget(QLabel("需转身按住时长:"), 6, 0) + game_grid.addWidget(self.turn_error_hold_spin, 6, 1) + + game_grid.addWidget(self.gs_use_hardware_input, 7, 0, 1, 2) + game_grid.addWidget(QLabel("复活按键:"), 6, 2) + game_grid.addWidget(self.gs_resurrect_key, 6, 3) + game_grid.addWidget(self.gs_bag_full_hearthstone, 8, 1) params_layout.addWidget(game_group) @@ -1172,6 +1197,8 @@ class WoWMultiKeyGUI(QMainWindow): self.food_key_edit.setText(str(bot_cfg.get('food_key', 'f1')).strip() or 'f1') self.eat_hp_threshold_spin.setValue(int(bot_cfg.get('eat_hp_threshold', 30))) self.eat_max_wait_spin.setValue(float(bot_cfg.get('eat_max_wait_sec', 30.0))) + self.turn_error_key_edit.setText(str(bot_cfg.get('turn_error_key', 's')).strip() or 's') + self.turn_error_hold_spin.setValue(float(bot_cfg.get('turn_error_hold_sec', 0.8))) self.gs_enable_mouse_loot.setChecked(bool(bot_cfg.get('enable_mouse_loot', True))) self.gs_use_hardware_input.setChecked(bool(bot_cfg.get('use_hardware_input', True))) except Exception: @@ -1179,6 +1206,8 @@ class WoWMultiKeyGUI(QMainWindow): self.food_key_edit.setText('f1') self.eat_hp_threshold_spin.setValue(30) self.eat_max_wait_spin.setValue(30.0) + self.turn_error_key_edit.setText('s') + self.turn_error_hold_spin.setValue(0.8) self.gs_enable_mouse_loot.setChecked(True) self.gs_use_hardware_input.setChecked(True) @@ -1208,6 +1237,8 @@ class WoWMultiKeyGUI(QMainWindow): self.config['bot']['food_key'] = self.food_key_edit.text().strip() or 'f1' self.config['bot']['eat_hp_threshold'] = int(self.eat_hp_threshold_spin.value()) self.config['bot']['eat_max_wait_sec'] = float(self.eat_max_wait_spin.value()) + self.config['bot']['turn_error_key'] = self.turn_error_key_edit.text().strip() or 's' + self.config['bot']['turn_error_hold_sec'] = float(self.turn_error_hold_spin.value()) self.config['bot']['enable_mouse_loot'] = self.gs_enable_mouse_loot.isChecked() self.config['bot']['use_hardware_input'] = self.gs_use_hardware_input.isChecked() self._save_main_config() @@ -1648,6 +1679,8 @@ class WoWMultiKeyGUI(QMainWindow): eat_max_wait_sec = float(((self.config or {}).get('bot') or {}).get('eat_max_wait_sec', 30.0)) except Exception: eat_max_wait_sec = 30.0 + turn_error_key = self.turn_error_key_edit.text().strip() or 's' + turn_error_hold_sec = float(self.turn_error_hold_spin.value()) # 从 layout_config 读取死亡/复活按键 try: @@ -1682,6 +1715,8 @@ class WoWMultiKeyGUI(QMainWindow): resurrect_key=resurrect_key, enable_mouse_loot=enable_mouse_loot, use_hardware_input=use_hardware_input, + turn_error_key=turn_error_key, + turn_error_hold_sec=turn_error_hold_sec, ) self.game_worker.state_signal.connect(self.state_label.setText) self.game_worker.log_signal.connect(self.log)