2323 sys .path .insert (0 , _ROOT )
2424
2525from custom .core .timing import calibration # noqa: E402
26+ from custom .maa .reco .click_stage import get_attempt_count , reset_attempt_count # noqa: E402
2627from custom .maa .registry import register_all # noqa: E402
2728from custom .utils .jsonc import load as load_jsonc # noqa: E402
2829from custom .utils .logger import setup_logging # noqa: E402
2930from custom .utils .runtime_paths import configure_paths # noqa: E402
3031
3132logger = logging .getLogger (__name__ )
3233
33- # 每轮估时 (秒),用于 max-retries 超时估算
34- _EST_SECONDS_PER_ROUND = 120
34+ # 次数监控线程的轮询间隔 (秒)
35+ _POLL_INTERVAL = 2.0
3536
3637
3738def main () -> int :
@@ -48,7 +49,10 @@ def main() -> int:
4849 help = "难度:normal=普通 | sand=沙盘推演" ,
4950 )
5051 parser .add_argument (
51- "--max-retries" , type = int , default = 50 , help = "最大重试次数(0=无限,靠 Ctrl+C 停)"
52+ "--max-retries" ,
53+ type = int ,
54+ default = 50 ,
55+ help = "最大凹图次数(0=无限,靠 Ctrl+C 停)。按实际尝试计数,不再用估时" ,
5256 )
5357 parser .add_argument (
5458 "--profile" , default = None , help = "校准文件名(可选,默认 config.DEFAULT_CALIBRATION)"
@@ -72,6 +76,7 @@ def main() -> int:
7276
7377 if args .profile :
7478 calibration .load (args .profile ) # 校验可加载
79+ reset_attempt_count () # 每次运行从 0 计数
7580 logger .info ("时间轴: %s(map_code 从文件读取)" , args .timeline )
7681
7782 wins = Toolkit .find_desktop_windows ()
@@ -115,23 +120,29 @@ def main() -> int:
115120 pipeline ["Farm" ]["anchor" ] = {"Farm@SwitchDifficulty" : anchor_target }
116121 logger .info ("难度:%s" , "沙盘推演" if args .difficulty == "sand" else "普通" )
117122
118- # max-retries 超时定时器(到点 post_stop)
123+ # max-retries 次数监控线程:累计凹图尝试达上限则 post_stop
124+ # 用 > 而非 >=:count 在 ClickStage 识别成功时自增(约每轮一次),
125+ # 故 count > max_retries 意味着已发起 max_retries 次完整尝试、第 N+1 次刚开始,此时停。
119126 if args .max_retries :
120- deadline = args .max_retries * _EST_SECONDS_PER_ROUND
121127
122- def _timeout_stop () -> None :
123- time .sleep (deadline )
124- if not tasker .stopping :
125- logger .warning ("已达 max-retries %d(≈%ds),停止" , args .max_retries , deadline )
126- tasker .post_stop ()
127-
128- threading .Thread (target = _timeout_stop , daemon = True ).start ()
128+ def _count_stop () -> None :
129+ while not tasker .stopping :
130+ time .sleep (_POLL_INTERVAL )
131+ if get_attempt_count () > args .max_retries :
132+ if not tasker .stopping :
133+ logger .warning (
134+ "已达 max-retries %d 次(实际 %d 次),停止" ,
135+ args .max_retries ,
136+ get_attempt_count (),
137+ )
138+ tasker .post_stop ()
139+ return
140+
141+ threading .Thread (target = _count_stop , daemon = True ).start ()
129142
130143 logger .info (
131144 "开始凹图%s。请在关卡列表页等待..." ,
132- f"(最多 { args .max_retries } 次,≈{ args .max_retries * _EST_SECONDS_PER_ROUND } s)"
133- if args .max_retries
134- else "(无限,Ctrl+C 停)" ,
145+ f"(最多 { args .max_retries } 次凹图)" if args .max_retries else "(无限,Ctrl+C 停)" ,
135146 )
136147
137148 t_start = time .time ()
0 commit comments