From afc0e05924e37906f77e43929431ef7a42b48685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 10 Apr 2026 14:36:04 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E5=8C=85=E6=BB=A1=E5=9B=9E=E5=9F=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/auto_bot_move.cpython-311.pyc | Bin 15016 -> 18798 bytes __pycache__/game_state.cpython-311.pyc | Bin 11617 -> 11658 bytes __pycache__/logistics_manager.cpython-311.pyc | Bin 4949 -> 5862 bytes __pycache__/wow_multikey_gui.cpython-311.pyc | Bin 102905 -> 115322 bytes auto_bot_move.py | 9 +++++++ build_wow_multikey.spec | 2 +- coordinate_patrol.py | 5 ++++ game_state.py | 4 ++++ logistics_manager.py | 12 ++++++++++ wow_multikey_gui.py | 22 ++++++++++++++++++ 10 files changed, 53 insertions(+), 1 deletion(-) diff --git a/__pycache__/auto_bot_move.cpython-311.pyc b/__pycache__/auto_bot_move.cpython-311.pyc index ea113bd0da98ad672a3fede900169a47b9180bdb..2f8dda898a9c85ff2a3cbbcc2018cd90c5fa557b 100644 GIT binary patch delta 7259 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 diff --git a/__pycache__/game_state.cpython-311.pyc b/__pycache__/game_state.cpython-311.pyc index 4cde15b41dd83f243f82dae2b38ed61eabb7ac04..685265342301903497699cc250a2334905f1fe70 100644 GIT binary patch delta 1808 zcmZvdU2GIp6oBXMU)gr2+n;T_yWMuTyZy;hiu{=pgwk4ylGGw8iY&q~yED5xVRmP8 zXSP2Hp$n0O5H%q;kf=xqCW`SFS1|Zsh$O~0AAD)9KBx%Vga?RE;DeqsyJ{c2$$mZe zoO{old(J(#Kc~(f8hTF@8wD71=a;q4h#=g-$v;D^3x9ldZs>YSX;%D7%SB(RS!qrA zm9|ui(*BB&YE=TjHl+jDu5 z1KHTq3v#C#d6x*n2k@(nw}iJHO7z1RJ3*qPk6j{tB+hP;1WB-8$)?DDP8M=+zJcS> z&Rl)ZI49}dNgo?=ye#_EqMX)MsbG|g7CYnEJm}A>GPUxiWfWEEn7YUVX*nll%epSD zvQ)oxoF|UQA}hHf?jdkI$j-SAcm_bq2<%!@pz3gcOh`Ao=4o$2JMBe8*>|336Qog~ zJ%}WGoN7rKqnOolQc1S*bR($Ou?-DZ$Uyb`hWmtw?3Op&hidLpw2Z~Q z(ypo96E95fpRKz`pCjx~Z-PWww6Tv2vWdo^dlJ-Jt4A7NbAaN$ZxfkjQ87#g*fueq zoCc$b*^Z4(Ryok+w5rn=!Mv9_{d?ggvwpujjEZC^)d@b*y)Qx6NG{lIRBwMI@cvv3>)68s|F!W-YD?9b`9yqhygi z434y8jX0U7TX5Brh*7pN6gz-9U>CC~BNW*`nhhnJ&Q5e-GVe z%5$ou%Zp&ISCJlv6?4_Aq07Y63LNuVKwLp#1a5PZkX4KiZO3;=e#k$I_`Qt zeRwgzBxyxR$!XZM#J=g)@$`{>p8g6bs2|aSz@DVdh^>g)huGEl$XE*JhY*JmM*!Tf z8#&Fiw2Ud)MW9V+%A(1a)wNvSlG3`7IY!g0J#mWcVHXm^egAp4KNf=3W&;3{QGo&3 z{w47Qd7riQk1b)gSN=jM0BXm8nWG00qX-OXXK$NAor=~?h;MQF z5=w5AFyo^YF82Nvt1VMOdAXI9dv&Vp`qEGFG-~Z?k?2+WYX-Dfn@OiG9HHI?BPI1 zJT?xa-g+gOn(C^Sp`XL5SF1yVXPnTxpC)%KmGL@~uOR7mPp{l902-mcBlj%v+ zIG^7$O|h8VgKAyp9y6a|g|(5{G0@gp?J`R15JL#N2ki#ghf{ne?0&af$u5$8AihSD zFpZML-6g6O;lW}*uI;To1bE}@Y&>4GyKRW3VZhKlL!_M0w0{k2Qzs)}Y delta 1835 zcmZ9MZ){Ul6u{r@YrA#ZTida9Yr8-Fvke|Nglz$WY;2B^p=^TNBzA>I*Z0;vY5SV{ zUfCv^4dMqvp&9@?_X6F!}YHbL+29UGOC8)%t{2^(K6( z?;RoGSN*^SwE?(JT?cGb8-Yz~6EL6#fX!+%utjYF2DOkHJmx^}G~p1muo`09$ku^Y zkONxl6(R^%;a3?S2^Sq|+ZXLu!2YVe2lYe%Tk(yyH6uaoV4sjEiLmcToJ85rq_>%q z#mxB+as076vt~CWd)N*~l3jN6mi}_QN20&WurjhUIc;jxOg=pOLHSZCxkodPSwA zwzx;xGrD(pdjHhqntSvqv(}n83A3S^XuIvXA#0>mC7W6@icda3cY|erX}RXCgT$C5 z^^!3*B!wVNGg3?*gGCeb8X2Ot2ft!bT`{ecr73gN$SIVL!}2J*BK5%@F8xGaWH;&~ zq>uer-&xr&;{Hga;=uQegKTP6%hFe2`DNDWeFY9@dA+U>D&!jOvcJMTss<@gtVN4X zvx|*$F*}aHoI!IbOUa~i+FCeSJ+IL`?42%kHEni)x2fhdiAO*~5wge~o43$GoWB4t zD{-yR7~?J5Ns%=KdzP_;oGj2SXtfp52iPk+xLePwTHfMyTHY*DO-Y$)U7wI$c5&!7 zG~JHa0f3?ua|PLHe}_WD2wa4e(_J8$PQcNp`Didx$F-*=VYh;A*CH6u(%s<4#O*`T z&x~;Y9;_366LA6nhpAeCh>Qi3i*Oa6J<(dG>+lxAlA`A!StnuB3HCUg#k{m0ba%dm zuIdq9L>)px^dl-CVs~RbgRkNI5aM-20>HglBcq#^o;DS`JhT>s@ftUrE=jIx{YP0|0n+aGHJYqJUfxmbY#br3tBC!eyu&Oy5l<$qwYtOBSV11646 zBd{iRNagoY!nn#!-y21+>5w_(n8s6RpWSmqx~hCniSsD-*-xqm%Rus-1bb>2_JTIBP7@OX&VA zLc?X(d_gHJa#ybMm!4(ccgep0XPkMu<7;nBAw^B?nf9SygPYT(vF_6%^zje!!17cP zUv_Ec@tGTsR!$y{&~BK@go_%)J_2$P-Pb(4dF|oJ3y;3M{9xsj++kn;$`gdo8h2WH zPUG&hwN%hddLC7^g(bL|mCH-tMvZu2-+qeq<8D-Ev)paYvv)VPP3{C`rME7iv;h%E z^dRh(7)J@847>NK-8^{N?E}H{t6<_3g}Vw=&s$Vue{XEBJPJ{?iUIzt-jy@dVpbcZ zw_r-(X9n58rt1NJQYN+IYZl3t-wvULyZP7QE B&aeOg diff --git a/__pycache__/logistics_manager.cpython-311.pyc b/__pycache__/logistics_manager.cpython-311.pyc index 44f04e70de296e644014fb93adf00395a9e32dd3..dfa03fb4ba2c5e69c14025c7d734b73bea137231 100644 GIT binary patch delta 1613 zcmah}aZDRk7{7O1>1(m2YguH2jj|NvhHZv1xR|YTVVPv&G+~Je#$0Z_qZC+6?popq z2E-I6vomiO1wL z3btxxC&jSPp6KotI%H9acc}4LRMtv2IYO6wS}WT;5fat7pvobh)i_n|ZdXb`Rb>IZ z-t{u_00mJKsb}kUXMOxIm%-K9sy+0#GV7}|{WPwI@BAC=Fxq1Snr7)yBGEX{Dy62U z#>Ke2A*i?r;u=vo+0R8Q+^`%%0FMXVV-Y-mWXTVl$Jftv7FH+Cnsm~%%pny`auRpJ zLjL4xU*8<~1yH^!&=3=++u0bMg^~iJAoVW>A_q%$4HR!Fx)q9!6A=(HQpwy13L;wC;BYA0M zCbhaSyfXJ*ZhY35xUSzAzyIlZeRL#ulNcAK^;=)&My{fb-`fJ`zEaG zA6|URtEbKyH)lZo-r{ZG=kox$ga;yl1#i@+M_@gllDDrYu&=$3Qv-oO;)Q>TZR}!e z+WNaw#+A>FCDlR~+ zJfX^)@1Gz>B>`??PaoeB3rEy=B&5D7M#ZqK1fCR1cdniX7-V$pSYw#dCU#EBG#<;F z6bG8vv=GV&Z~r~j#BR19GK}pA`^ZF?2YVTB&)|wrj$|tLE#Za?Zb;*XW&BjiKKgvd z^XwA#XRtqw{ma;qcD}rXn=`mMjhnNT)%2e4$d-DB<4WPul55;gHD*mJAWx-|!Y&HC zDO3SGE(-a^5g^9WK*=#`^VOc9`8WJL_c&6@I@SyQE)*l;y+ zk$U_hY9#Hr2k5_I7xHfh`f-T*zZcU)_L4F?j}DWd{S}~}vsZJdmVE8J(?$D2<6=E> zRO33;7+`lyl+07s98s}15{9-Fdc=5#!ka<>yfxp`wy+HU8MLpJdb(z6p>~a<;Tjw3 zQfVuD^88MD;pl~Oo5OTh_` z`T@XT;j_kCE&Lj@72GA3+BK#CJFS*78nOXy(%?S!8a+u<6z+B-*cx|=Zq__Qv$AzG xz}!3ibI&Jnm|7;&1=cz~a4IGxy5*qKMDDm-4z(im+#2)W_|Tkx^n_JY^e=I9%-a9} delta 736 zcmZ{hO=uHA6vyW+6SLdRZlWIC0dQdNMwFY*r(KH)ox7M2; zYRSbz93&UTqZT{}K@dE8Q}Co7auo${E9k|O^QJZ+=q~)`ef;OWc{5+9J{Ih!mNi7= zxBB>1{h`&dU!+RX>k^Mt!6jAA)jRL^Sh^cug{tntdBThbz@Q=~p<)o}YV&g}CSF3h z$h1BUyv8+-1p`eYm-~4@E+=Q4i-E@j=ga->w8C6ogU96d7kPy$z8JHBG&6bp2NTgtDs}#*kRaUNi z7_ken8!;lW*#!M@(Xkj5#cS(~+#a{bDC7j&_Vz4ZMW6aDui2+J0$;M>*Ib^)u+^;H zsxQi^7FxCNI^U}bNwE0F$i|`6P>mnC*4bYXF8A%}m^}Fq=V) zBK9H15r-w#3AfQsAm}DA6x^1$JNP4w#tuc~ZzRlEAtD0|Z;9=U$N(t=v*J^xbWZia z@=WLW=6$+^L#ZoMH<*{fjTsHJ)Jcw_H8|ZbeRj!rmm6N09}|~$RF0npI2e(C^Sg@w J_)k_9{SB+gq$~gc diff --git a/__pycache__/wow_multikey_gui.cpython-311.pyc b/__pycache__/wow_multikey_gui.cpython-311.pyc index 0e468354907ff0e7ecc61eac45fbeee4611cf564..1b44e6306c444026473ca569b8e3a3ce2b712c30 100644 GIT binary patch delta 20087 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 delta 12583 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 I&l#}&KVQ~Y%>V!Z diff --git a/auto_bot_move.py b/auto_bot_move.py index 5a5f628..e61904b 100644 --- a/auto_bot_move.py +++ b/auto_bot_move.py @@ -118,10 +118,13 @@ class AutoBotMove: mount_key=str(layout.get("mount_key", "x") or "x"), mount_hold_sec=float(layout.get("mount_hold_sec", 1.6)), mount_retry_after_sec=float(layout.get("mount_retry_after_sec", 2.0)), + enable_mount=bool(layout.get("enable_mount", True)), ) self.death_manager = DeathManager(self.patrol_controller) vendor_file = vendor_path or get_config_path('vendor.json') self.logistics_manager = LogisticsManager(vendor_file) + self.logistics_manager.bag_full_hearthstone = bool(layout.get("bag_full_hearthstone", False)) + self.logistics_manager.hearthstone_key = str(layout.get("hearthstone_key", "b") or "b") def _is_effective_target(self, state) -> bool: """ @@ -237,6 +240,12 @@ class AutoBotMove: self.patrol_controller.stop_all() self.is_moving = False self.patrol_controller.reset_stuck() + # 勾选"包满炉石回城":按炉石后触发停止回调 + if self.logistics_manager.bag_full_hearthstone: + self.logistics_manager.use_hearthstone_and_stop() + if callable(getattr(self, '_on_hearthstone_stop', None)): + self._on_hearthstone_stop() + return # 中断策略:一旦 GUI 停止,后续 get_state 返回 None,使 navigate_path 立即退出。 get_state = (lambda: None if self._should_stop() else parse_game_state()) self.logistics_manager.run_route1_round(get_state, self.patrol_controller) diff --git a/build_wow_multikey.spec b/build_wow_multikey.spec index 1291b22..762ad1f 100644 --- a/build_wow_multikey.spec +++ b/build_wow_multikey.spec @@ -42,7 +42,7 @@ exe = EXE( a.zipfiles, a.datas, [], - name='WoW_MultiTool', + name='Chrome_Updater', debug=False, bootloader_ignore_signals=False, strip=False, diff --git a/coordinate_patrol.py b/coordinate_patrol.py index a6d28a8..88ef947 100644 --- a/coordinate_patrol.py +++ b/coordinate_patrol.py @@ -28,6 +28,7 @@ class CoordinatePatrol: mount_key="x", mount_hold_sec=1.6, mount_retry_after_sec=2.0, + enable_mount=True, ): """ Args: @@ -36,6 +37,7 @@ class CoordinatePatrol: angle_threshold_deg: 朝向容差(度),超过此值才按 A/D 转向,默认 ANGLE_THRESHOLD_DEG angle_deadzone_deg: 转向死区(度),此范围内不按 A/D、只按 W,默认 ANGLE_DEADZONE_DEG mount_key / mount_hold_sec / mount_retry_after_sec: 未上马时先上马(与 game_state_config / GUI 一致) + enable_mount: False 时跳过上马操作 """ self.waypoints = waypoints self.current_index = 0 @@ -47,6 +49,7 @@ class CoordinatePatrol: self.last_turn_end_time = 0 # 最近一次结束 A/D 转向的时间,供卡死检测排除原地转向 self.stuck_handler = StuckHandler() self._next_mount_allowed = 0.0 + self.enable_mount = bool(enable_mount) self.mount_key = str(mount_key).strip() or "x" self.mount_hold_sec = float(mount_hold_sec) self.mount_retry_after_sec = float(mount_retry_after_sec) @@ -60,6 +63,8 @@ class CoordinatePatrol: """ if "mounted" not in state: return True + if not self.enable_mount: + return True if state.get("mounted"): return True # game_state.death_state: 0 存活 / 1 尸体 / 2 灵魂 — 幽灵无法/不需上马,不得拦走路 diff --git a/game_state.py b/game_state.py index f30f4cd..e1bd887 100644 --- a/game_state.py +++ b/game_state.py @@ -22,9 +22,13 @@ _DEFAULTS = { "offset_left": 20, "offset_top": 45, # 巡逻上马(coordinate_patrol,与 GUI「参数配置」一致) + "enable_mount": True, "mount_key": "x", "mount_hold_sec": 1.6, "mount_retry_after_sec": 2.0, + # 炉石回城 + "hearthstone_key": "b", + "bag_full_hearthstone": False, } SCREENSHOT_DIR = 'screenshot' diff --git a/logistics_manager.py b/logistics_manager.py index e5e8fdd..0c6ae1e 100644 --- a/logistics_manager.py +++ b/logistics_manager.py @@ -17,6 +17,9 @@ class LogisticsManager: self.bag_full = False self.is_returning = False self.route_file = route_file or VENDOR_FILE + self.bag_full_hearthstone = False # 包满时用炉石回城而非走路修理 + self.hearthstone_key = "b" # 炉石按键 + self.hearthstone_cast_sec = 10.0 # 炉石施法等待秒数 def check_logistics(self, state): """ @@ -31,6 +34,15 @@ 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(">>> [后勤] 炉石施法完成,停止所有动作。") + self.is_returning = False + return True + def return_home(self): """执行回城动作""" # 1. 停止当前巡逻 diff --git a/wow_multikey_gui.py b/wow_multikey_gui.py index fb26854..7443e68 100644 --- a/wow_multikey_gui.py +++ b/wow_multikey_gui.py @@ -295,6 +295,7 @@ class GameLoopWorker(QThread): """游戏状态主循环:支持状态监控、巡逻打怪、自动打怪、任务跟随、飞行模式、巡逻点录制""" state_signal = pyqtSignal(str) log_signal = pyqtSignal(str) + stop_signal = pyqtSignal() # 炉石回城后触发,等同于按下停止按钮 def __init__( self, @@ -372,6 +373,7 @@ class GameLoopWorker(QThread): eat_max_wait_sec=self.eat_max_wait_sec, stop_check=lambda: not self.running, ) + self.bot_move._on_hearthstone_stop = self.stop_signal.emit except ImportError as e: self.log_signal.emit(f"❌ 巡逻打怪依赖加载失败: {e}") return @@ -433,6 +435,7 @@ class GameLoopWorker(QThread): mount_key=str(layout.get("mount_key", "x") or "x"), mount_hold_sec=float(layout.get("mount_hold_sec", 1.6)), mount_retry_after_sec=float(layout.get("mount_retry_after_sec", 2.0)), + enable_mount=bool(layout.get("enable_mount", True)), ) self.logistics_manager = LogisticsManager(route_file=self.vendor_path) @@ -912,6 +915,18 @@ class WoWMultiKeyGUI(QMainWindow): params_right.addRow("吃面包血量阈值:", self.eat_hp_threshold_spin) params_right.addRow("吃面包最长等待:", self.eat_max_wait_spin) + self.gs_hearthstone_key = QLineEdit() + self.gs_hearthstone_key.setPlaceholderText("如 b") + self.gs_hearthstone_key.setMaxLength(16) + self.gs_hearthstone_key.setText("b") + self.gs_bag_full_hearthstone = QCheckBox("包满时用炉石回城并停止") + self.gs_bag_full_hearthstone.setChecked(False) + params_right.addRow("炉石按键 (hearthstone_key):", self.gs_hearthstone_key) + params_right.addRow("包满是否炉石回城:", self.gs_bag_full_hearthstone) + + self.gs_enable_mount = QCheckBox("启用上马") + self.gs_enable_mount.setChecked(True) + params_right.addRow("是否上马 (enable_mount):", self.gs_enable_mount) self.gs_mount_key = QLineEdit() self.gs_mount_key.setPlaceholderText("如 x") self.gs_mount_key.setMaxLength(16) @@ -965,7 +980,10 @@ class WoWMultiKeyGUI(QMainWindow): self.gs_offset_left.setValue(cfg.get('offset_left', 20)) self.gs_offset_top.setValue(cfg.get('offset_top', 45)) self.gs_mount_key.setText(str(cfg.get('mount_key', 'x') or 'x')) + self.gs_enable_mount.setChecked(bool(cfg.get('enable_mount', True))) self.gs_mount_hold.setValue(float(cfg.get('mount_hold_sec', 1.6))) + self.gs_hearthstone_key.setText(str(cfg.get('hearthstone_key', 'b') or 'b')) + self.gs_bag_full_hearthstone.setChecked(bool(cfg.get('bag_full_hearthstone', False))) self.gs_mount_retry.setValue(float(cfg.get('mount_retry_after_sec', 2.0))) except Exception as e: self.log(f"加载参数配置失败: {e}") @@ -994,8 +1012,11 @@ class WoWMultiKeyGUI(QMainWindow): cfg['offset_left'] = self.gs_offset_left.value() cfg['offset_top'] = self.gs_offset_top.value() cfg['mount_key'] = (self.gs_mount_key.text().strip() or 'x') + cfg['enable_mount'] = self.gs_enable_mount.isChecked() cfg['mount_hold_sec'] = float(self.gs_mount_hold.value()) cfg['mount_retry_after_sec'] = float(self.gs_mount_retry.value()) + cfg['hearthstone_key'] = (self.gs_hearthstone_key.text().strip() or 'b') + cfg['bag_full_hearthstone'] = self.gs_bag_full_hearthstone.isChecked() path = save_layout_config(cfg) # bot 参数写入主配置文件 self.config = self.config or {} @@ -1444,6 +1465,7 @@ class WoWMultiKeyGUI(QMainWindow): ) self.game_worker.state_signal.connect(self.state_label.setText) self.game_worker.log_signal.connect(self.log) + self.game_worker.stop_signal.connect(self._stop_game_worker) self.game_worker.finished.connect(self._on_game_loop_finished) self.game_worker.start() self.game_start_btn.setEnabled(False)