Skip to content

Commit b6b16cb

Browse files
提高系统的稳定性,优化系统的流畅度 (#516)
* feat: 更新 azur_lane 模型文件至 v6.6 * feat: 添加多语言OCR模型版本配置和相关功能 * refactor(log): 统一中文日志格式,为所有中文日志添加 [模块名] 前缀 - 游戏功能模块 (campaign/commission/research/island等) 使用 i18n 中文名作为前缀 - 大功能子模块使用 [功能-子功能] 格式 (如 [大世界-智能调度], [岛屿-经营]) - 基础设施模块 (device/handler/ui/ocr等) 使用英文名如 [Device]/[Handler]/[UI] - 根入口文件使用 [Alas]/[GUI]/[MCP] - 保留已有英文子标签 (如 [Story]/[装置处理]), 前缀加在最前面 - 移除消息文本中的中文标签 (如 【智能调度】), 整合进前缀 - 共 90+ 文件, ~1276 条日志消息 * feat: 添加 AlOCR 850K 模型及相关配置,更新多语言支持 * Refactor Windows command execution and fix MuMu12 recognition issues (#514) * refactor(platform_windows): 优化Windows平台命令执行与MuMu12启停逻辑 1. 为execute方法添加同步执行参数与超时支持 2. 将MuMu12关闭操作改为同步执行避免实例查找失败 3. 为模拟器启动流程添加MuMu12的进程稳定等待机制 * fix(emulator): 修复MuMu12模拟器重启后无法识别的问题 1. 新增从Windows卸载注册表读取MuMu12安装路径的逻辑,补充枚举模拟器实例的来源 2. 当未枚举到目标模拟器实例时,尝试使用配置中保存的信息回退构造模拟器实例 3. 兼容基类无法识别模拟器类型的情况,信任配置中的模拟器类型 * fix(device): 修复MuMu12序列号匹配逻辑并新增错误弹窗检测 调整MuMu12实例匹配的代码位置,将漂移修复逻辑移到枚举失败分支前,同时新增MuMu错误弹窗检测和残留进程清理,提升模拟器启动稳定性 * feat(i18n): 更新 OCR 英文模型版本为 900K --------- Co-authored-by: wess09 <> Co-authored-by: Beatrice-betty <168128195+Beatrice-betty@users.noreply.github.com>
1 parent fd48b0f commit b6b16cb

103 files changed

Lines changed: 1805 additions & 1338 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

alas.py

Lines changed: 72 additions & 72 deletions
Large diffs are not rendered by default.
3.29 MB
Binary file not shown.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"checkpoint": "checkpoints_fast_se_850k_w768\\best.pt",
3+
"onnx": "checkpoints_fast_se_850k_w768\\best.onnx",
4+
"opset": 17,
5+
"num_classes": 66,
6+
"charset": [
7+
"0",
8+
"1",
9+
"2",
10+
"3",
11+
"4",
12+
"5",
13+
"6",
14+
"7",
15+
"8",
16+
"9",
17+
":",
18+
"-",
19+
"/",
20+
"A",
21+
"B",
22+
"C",
23+
"D",
24+
"E",
25+
"F",
26+
"G",
27+
"H",
28+
"I",
29+
"J",
30+
"K",
31+
"L",
32+
"M",
33+
"N",
34+
"O",
35+
"P",
36+
"Q",
37+
"R",
38+
"S",
39+
"T",
40+
"U",
41+
"V",
42+
"W",
43+
"X",
44+
"Y",
45+
"Z",
46+
"a",
47+
"b",
48+
"c",
49+
"d",
50+
"e",
51+
"f",
52+
"g",
53+
"h",
54+
"i",
55+
"j",
56+
"k",
57+
"l",
58+
"m",
59+
"n",
60+
"o",
61+
"p",
62+
"q",
63+
"r",
64+
"s",
65+
"t",
66+
"u",
67+
"v",
68+
"w",
69+
"x",
70+
"y",
71+
"z"
72+
],
73+
"blank_id": 0,
74+
"image_height": 48,
75+
"max_width": 768,
76+
"output_layout": "batch,time,classes",
77+
"output_kind": "scores",
78+
"model_arch": "fast_se_ctc"
79+
}

campaign/campaign_war_archives/campaign_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def ui_goto_archives_campaign(self, mode='ex'):
123123
self.ui_click(entrance, appear_button=WAR_ARCHIVES_CHECK, check_button=WAR_ARCHIVES_CAMPAIGN_CHECK,
124124
skip_first_screenshot=True)
125125
else:
126-
logger.critical('当前服务器可能不支持该活动,请稍后再试')
126+
logger.critical('[战役] 当前服务器可能不支持该活动,请稍后再试')
127127
raise RequestHumanTakeover
128128

129129
# Subsequent runs all set False

gui.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ def func(ev: Optional[Event]):
9797
# Electron客户端特定处理
9898
if State.electron:
9999
# https://github.com/LmeSzinc/AzurLaneAutoScript/issues/2051
100-
logger.info("检测到 Electron,移除标准输出日志处理器")
100+
logger.info("[GUI] 检测到 Electron,移除标准输出日志处理器")
101101
from module.logger import console_hdlr
102102
logger.removeHandler(console_hdlr)
103103

104104
# 验证SSL配置
105105
if ssl_cert is None and ssl_key is not None:
106-
logger.error("提供了SSL密钥但未提供证书。请同时提供SSL密钥和证书。")
106+
logger.error("[GUI] 提供了SSL密钥但未提供证书。请同时提供SSL密钥和证书。")
107107
elif ssl_key is None and ssl_cert is not None:
108-
logger.error("提供了SSL证书但未提供密钥。请同时提供SSL密钥和证书。")
108+
logger.error("[GUI] 提供了SSL证书但未提供密钥。请同时提供SSL密钥和证书。")
109109

110110
# 启动uvicorn服务器
111111
try:
@@ -121,7 +121,7 @@ def func(ev: Optional[Event]):
121121
else:
122122
uvicorn.run("module.webui.app:app", host=host, port=port, factory=True)
123123
except Exception as e:
124-
logger.error(f"Uvicorn服务崩溃: {str(e)}")
124+
logger.error(f"[GUI] Uvicorn服务崩溃: {str(e)}")
125125
raise
126126
def _stop_process(process, timeout=5):
127127
"""
@@ -136,12 +136,12 @@ def _stop_process(process, timeout=5):
136136
if not process or not process.is_alive():
137137
return
138138

139-
logger.info(f"正在停止服务进程 (PID: {process.pid})...")
139+
logger.info(f"[GUI] 正在停止服务进程 (PID: {process.pid})...")
140140
process.terminate()
141141
process.join(timeout=timeout)
142142

143143
if process.is_alive():
144-
logger.warning(f"服务进程 (PID: {process.pid}) 超时未退出,强制终止...")
144+
logger.warning(f"[GUI] 服务进程 (PID: {process.pid}) 超时未退出,强制终止...")
145145
process.kill()
146146
process.join(timeout=3)
147147

@@ -154,7 +154,7 @@ def _stop_process(process, timeout=5):
154154
if os.name == "posix" and sys.platform == "darwin":
155155
os.environ["OBJC_DISABLE_INITIALIZE_FORK_SAFETY"] = "YES"
156156
except RuntimeError:
157-
logger.warning("无法设置spawn启动方式,可能使用fork(macOS上不推荐)")
157+
logger.warning("[GUI] 无法设置spawn启动方式,可能使用fork(macOS上不推荐)")
158158

159159
# 启用热重载模式
160160
if State.deploy_config.EnableReload:
@@ -163,35 +163,35 @@ def _stop_process(process, timeout=5):
163163
event = Event()
164164
process = Process(target=func, args=(event,), name="gui")
165165
process.start()
166-
logger.info(f"启动AzurPilot Web服务 (PID: {process.pid})")
166+
logger.info(f"[GUI] 启动AzurPilot Web服务 (PID: {process.pid})")
167167

168168
while not should_exit:
169169
try:
170170
# 等待重启事件,超时1秒
171171
restart_triggered = event.wait(1)
172172
except KeyboardInterrupt:
173-
logger.info("收到KeyboardInterrupt,退出中...")
173+
logger.info("[GUI] 收到KeyboardInterrupt,退出中...")
174174
should_exit = True
175175
break
176176
except Exception as e:
177-
logger.error(f"等待重启事件时出错: {str(e)}")
177+
logger.error(f"[GUI] 等待重启事件时出错: {str(e)}")
178178
should_exit = True
179179
break
180180

181181
if restart_triggered:
182-
logger.info("重启事件触发,终止当前服务...")
182+
logger.info("[GUI] 重启事件触发,终止当前服务...")
183183
_stop_process(process)
184184
break
185185
elif not process.is_alive():
186-
logger.error("AzurPilot Web服务意外退出")
186+
logger.error("[GUI] AzurPilot Web服务意外退出")
187187
should_exit = True
188188

189189
# 确保子进程完全退出
190190
_stop_process(process)
191191

192192
# 最终清理(预防性)
193193
_stop_process(process)
194-
logger.info("AzurPilot Web服务已成功退出")
194+
logger.info("[GUI] AzurPilot Web服务已成功退出")
195195
else:
196196
# 非重载模式:直接运行
197197
func(None)

mcp_server_sse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,5 +511,5 @@ async def mcp_asgi_app(scope, receive, send):
511511

512512
if __name__ == "__main__":
513513
import uvicorn
514-
logger.info("启动 AzurPilot MCP 服务 (Port: 22268)")
514+
logger.info("[MCP] 启动 AzurPilot MCP 服务 (Port: 22268)")
515515
uvicorn.run(app, host="0.0.0.0", port=22268)

module/base/api_client.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def _request_with_fallback(cls, method: str, path: str, params: Dict[str, Any] =
7979
for i, endpoint in enumerate(endpoints):
8080
try:
8181
domain_type = "主域名" if i == 0 else "备用域名"
82-
logger.debug(f'尝试使用{domain_type}: {endpoint}')
82+
logger.debug(f'[Base] 尝试使用{domain_type}: {endpoint}')
8383

8484
if method == 'GET':
8585
response = requests.get(
@@ -101,20 +101,20 @@ def _request_with_fallback(cls, method: str, path: str, params: Dict[str, Any] =
101101

102102
if response.status_code in success_codes:
103103
if i > 0:
104-
logger.info(f'✓ 使用{domain_type}请求成功')
104+
logger.info(f'[Base] ✓ 使用{domain_type}请求成功')
105105
return True, response.status_code, response.text
106106
else:
107-
logger.warning(f'{domain_type}返回错误状态: {response.status_code}')
107+
logger.warning(f'[Base] {domain_type}返回错误状态: {response.status_code}')
108108
last_error = f'HTTP {response.status_code}'
109109

110110
except requests.exceptions.Timeout:
111-
logger.warning(f'{domain_type if i > 0 else "主域名"}请求超时')
111+
logger.warning(f'[Base] {domain_type if i > 0 else "主域名"}请求超时')
112112
last_error = 'Timeout'
113113
except requests.exceptions.RequestException as e:
114-
logger.warning(f'{domain_type if i > 0 else "主域名"}请求失败: {e}')
114+
logger.warning(f'[Base] {domain_type if i > 0 else "主域名"}请求失败: {e}')
115115
last_error = str(e)
116116
except Exception as e:
117-
logger.warning(f'{domain_type if i > 0 else "主域名"}发生异常: {e}')
117+
logger.warning(f'[Base] {domain_type if i > 0 else "主域名"}发生异常: {e}')
118118
last_error = str(e)
119119

120120
return False, 0, last_error or 'Unknown error'
@@ -249,7 +249,7 @@ def get_announcement(cls, timeout: int = 1, current_id: int = None) -> Optional[
249249

250250
# 如果返回空字典或无ID,也视为无更新
251251
if not data or not data.get('announcementId'):
252-
logger.info('公告数据为空或无ID')
252+
logger.info('[Base] 公告数据为空或无ID')
253253
return None
254254

255255
# 只要有标题,且有内容 OR 链接,就是有效公告
@@ -258,13 +258,13 @@ def get_announcement(cls, timeout: int = 1, current_id: int = None) -> Optional[
258258
else:
259259
return None
260260
except json.JSONDecodeError as e:
261-
logger.warning(f'解析公告JSON失败: {e}, response={response_text[:100]}')
261+
logger.warning(f'[Base] 解析公告JSON失败: {e}, response={response_text[:100]}')
262262
return None
263263
else:
264-
logger.warning(f'获取公告失败: {response_text}')
264+
logger.warning(f'[Base] 获取公告失败: {response_text}')
265265
return None
266266

267267
except Exception as e:
268-
logger.warning(f'获取公告异常: {e}')
268+
logger.warning(f'[Base] 获取公告异常: {e}')
269269
return None
270270

module/campaign/campaign_ocr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def _extract_stage_name(image):
279279
x_color = np.convolve(np.mean(image, axis=0), np.ones(interval), 'valid') / interval
280280
x_list = np.where(x_color[x_skip:] > 245)[0]
281281
if x_list is None or len(x_list) == 0:
282-
logger.warning('数字与文本之间未找到间隔。')
282+
logger.warning('[战役] 数字与文本之间未找到间隔。')
283283
area = (0, 0, image.shape[1], image.shape[0])
284284
else:
285285
area = (0, 0, x_list[0] + 1 + x_skip, image.shape[0])
@@ -302,7 +302,7 @@ def _get_stage_name(self, image):
302302
del_cached_property(self, '_stage_image')
303303
del_cached_property(self, '_stage_image_gray')
304304
if len(buttons) == 0:
305-
logger.info('未找到关卡。')
305+
logger.info('[战役] 未找到关卡。')
306306
raise CampaignNameError
307307

308308
ocr = Ocr(buttons, name='campaign', letter=(255, 255, 255), threshold=128,

module/campaign/campaign_ui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ def ensure_campaign_ui(self, name, mode='normal', skip_first_screenshot=True):
492492
if self.handle_campaign_ui_additional():
493493
continue
494494

495-
logger.warning('战役名称错误')
495+
logger.warning('[战役] 战役名称错误')
496496
raise ScriptEnd('Campaign name error')
497497

498498
def commission_notice_show_at_campaign(self):

0 commit comments

Comments
 (0)