feat(MAA): 从模拟器层面接管明日方舟游戏更新 - #418
Conversation
MAA 自带的开始唤醒任务会原地轮询等待游戏内资源热更新,但对客户端 APK 版本 落后导致的强制更新门没有任何任务,只会一直卡到超时并按重试次数反复失败, 无人值守场景下这段时间是纯浪费。 补足 MAA 缺失的这一层:启动 MAA 前比对服务端与模拟器内的客户端版本,官服 可自动下载安装包并经 adb 安装;其余服务器无可靠安装包来源,改为快速失败并 给出可执行提示。同时用服务端 resVersion 识别待下载的资源热更新,在那一次 运行放宽超时,避免把正常更新误判成卡死。
审查者指南本 PR 在不重复实现 MAA 内置资源热更新的前提下,在启动前增加可选的客户端版本检查和官服 APK 自动更新链路,并通过 resVersion 记录识别资源热更新、动态放宽单次代理超时;同时补充模拟器 adb 路径适配、脚本配置、前端设置项和分支测试。 启动前游戏版本检查与更新时序图sequenceDiagram
participant AutoProxy
participant GameUpdate as ensure_game_updated
participant VersionAPI
participant Emulator
participant APK as OfficialAPK
participant ADB
participant User
AutoProxy->>GameUpdate: ensure_game_updated()
GameUpdate->>VersionAPI: fetch_game_version()
VersionAPI-->>GameUpdate: clientVersion, resVersion
GameUpdate->>Emulator: get_installed_client_version()
Emulator->>ADB: dumpsys package
ADB-->>Emulator: installed version
Emulator-->>GameUpdate: installed version
alt client version is current
GameUpdate-->>AutoProxy: UpToDate
else Official and auto install enabled
GameUpdate->>APK: download_official_apk()
APK-->>GameUpdate: APK file
GameUpdate->>ADB: install_apk()
ADB-->>GameUpdate: Success
GameUpdate->>Emulator: get_installed_client_version()
Emulator-->>GameUpdate: updated version
GameUpdate-->>AutoProxy: Updated
else unsupported server or manual update required
GameUpdate-->>AutoProxy: NeedManualUpdate
AutoProxy->>User: push notification and stop retry
end
资源热更新超时处理流程图flowchart TD
A[Start MAA run] --> B[ensure_game_updated]
B --> C{resVersion differs from LastResVersion?}
C -- No --> D[Use normal task timeout]
C -- Yes --> E[Mark resource hot update pending]
E --> F[Use max task timeout and GameUpdateTimeLimit]
F --> G[MAA performs its built-in resource hot update]
G --> H{Proxy succeeds?}
H -- Yes --> I[Save pending resVersion as LastResVersion]
H -- No --> J[Keep previous LastResVersion]
D --> K[Run normal MAA flow]
I --> K
J --> K
文件级变更
可能关联的 issue
提示与命令与 Sourcery 交互
自定义使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's Guide本 PR 在不重复实现 MAA 内置资源热更新的前提下,在启动前增加可选的客户端版本检查和官服 APK 自动更新链路,并通过 resVersion 记录识别资源热更新、动态放宽单次代理超时;同时补充模拟器 adb 路径适配、脚本配置、前端设置项和分支测试。 Sequence diagram for pre-launch game version check and updatesequenceDiagram
participant AutoProxy
participant GameUpdate as ensure_game_updated
participant VersionAPI
participant Emulator
participant APK as OfficialAPK
participant ADB
participant User
AutoProxy->>GameUpdate: ensure_game_updated()
GameUpdate->>VersionAPI: fetch_game_version()
VersionAPI-->>GameUpdate: clientVersion, resVersion
GameUpdate->>Emulator: get_installed_client_version()
Emulator->>ADB: dumpsys package
ADB-->>Emulator: installed version
Emulator-->>GameUpdate: installed version
alt client version is current
GameUpdate-->>AutoProxy: UpToDate
else Official and auto install enabled
GameUpdate->>APK: download_official_apk()
APK-->>GameUpdate: APK file
GameUpdate->>ADB: install_apk()
ADB-->>GameUpdate: Success
GameUpdate->>Emulator: get_installed_client_version()
Emulator-->>GameUpdate: updated version
GameUpdate-->>AutoProxy: Updated
else unsupported server or manual update required
GameUpdate-->>AutoProxy: NeedManualUpdate
AutoProxy->>User: push notification and stop retry
end
Flow diagram for resource hot-update timeout handlingflowchart TD
A[Start MAA run] --> B[ensure_game_updated]
B --> C{resVersion differs from LastResVersion?}
C -- No --> D[Use normal task timeout]
C -- Yes --> E[Mark resource hot update pending]
E --> F[Use max task timeout and GameUpdateTimeLimit]
F --> G[MAA performs its built-in resource hot update]
G --> H{Proxy succeeds?}
H -- Yes --> I[Save pending resVersion as LastResVersion]
H -- No --> J[Keep previous LastResVersion]
D --> K[Run normal MAA flow]
I --> K
J --> K
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
嘿——我发现了 1 个问题
给 AI 代理的提示
请处理此次代码审查中的评论:
## 个别评论
### 评论 1
<location path="app/task/MAA/tools/game_update.py" line_range="221-225" />
<code_context>
+ async def report(text: str) -> None:
+ self.script_info.log = text
+
+ try:
+ result = await ensure_game_updated(
+ adb_path=self.emulator_manager.get_adb_path(),
</code_context>
<issue_to_address>
**issue (bug_risk):** 配置的 `time_limit` 从未应用于 APK 下载:`download_official_apk` 使用固定的 60 秒 HTTP 超时,而调用方调用它时没有设置任何截止时间。一个持续产生下载进度的 2 GB 下载可能无限期运行,因此 `GameUpdateTimeLimit` 并未像其配置和文档字符串所声称的那样限制下载时间。
**触发条件:** CDN 下载速度缓慢或停滞,但产生数据的频率仍高于 HTTP 非活动超时时间。
**建议修复:** 将配置的截止时间传入 `download_official_apk`,并在完整下载过程外层强制执行该截止时间,例如使用总体的 `asyncio.timeout(time_limit * 60)`,或采用等效的总时间限制。
</issue_to_address>Sourcery 评估
需要人工审查。 首先需要处理 1 个发现的问题;此外,启用该功能后,它会从外部端点下载 APK,并通过 ADB 安装该 APK。因此,错误的版本响应、重定向或软件包可能会永久修改模拟器,而仅回滚此 PR 并不能撤销该安装。其他方面,存储的资源版本和超时变更均处于受控范围内,并且可以在后续运行中修正。
阻塞性发现:app/task/MAA/tools/game_update.py:225
请帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用这些反馈来改进审查结果。
Original comment in English
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="app/task/MAA/tools/game_update.py" line_range="221-225" />
<code_context>
+ async def report(text: str) -> None:
+ self.script_info.log = text
+
+ try:
+ result = await ensure_game_updated(
+ adb_path=self.emulator_manager.get_adb_path(),
</code_context>
<issue_to_address>
**issue (bug_risk):** The configured `time_limit` is never applied to APK downloading: `download_official_apk` uses a fixed 60-second HTTP timeout, and the caller invokes it without any deadline. A 2 GB download that continues making progress can run indefinitely, so `GameUpdateTimeLimit` does not limit the download as its configuration and docstring claim.
**Triggers:** When the CDN download is slow or stalls while still producing data more frequently than the HTTP inactivity timeout.
**Suggested fix:** Pass the configured deadline into `download_official_apk` and enforce it around the complete download, for example with an overall `asyncio.timeout(time_limit * 60)` or an equivalent total-time limit.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and when enabled, the feature downloads an APK from an external endpoint and installs it through ADB, so a bad version response, redirect, or package can alter the emulator persistently and reverting the PR will not undo that installation. The stored resource version and timeout change are otherwise bounded and can be corrected on a later run.
Blocking findings: app/task/MAA/tools/game_update.py:225
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| try: | ||
| async with httpx.AsyncClient(follow_redirects=True) as client: | ||
| async with client.stream( | ||
| "GET", ARKNIGHTS_OFFICIAL_APK_URL, timeout=60.0 | ||
| ) as response: |
There was a problem hiding this comment.
issue (bug_risk): 配置的 time_limit 从未应用于 APK 下载:download_official_apk 使用固定的 60 秒 HTTP 超时,而调用方调用它时没有设置任何截止时间。一个持续产生下载进度的 2 GB 下载可能无限期运行,因此 GameUpdateTimeLimit 并未像其配置和文档字符串所声称的那样限制下载时间。
触发条件: CDN 下载速度缓慢或停滞,但产生数据的频率仍高于 HTTP 非活动超时时间。
建议修复: 将配置的截止时间传入 download_official_apk,并在完整下载过程外层强制执行该截止时间,例如使用总体的 asyncio.timeout(time_limit * 60),或采用等效的总时间限制。
Original comment in English
issue (bug_risk): The configured time_limit is never applied to APK downloading: download_official_apk uses a fixed 60-second HTTP timeout, and the caller invokes it without any deadline. A 2 GB download that continues making progress can run indefinitely, so GameUpdateTimeLimit does not limit the download as its configuration and docstring claim.
Triggers: When the CDN download is slow or stalls while still producing data more frequently than the HTTP inactivity timeout.
Suggested fix: Pass the configured deadline into download_official_apk and enforce it around the complete download, for example with an overall asyncio.timeout(time_limit * 60) or an equivalent total-time limit.
摘要
GameStartUpdateOCR/GameStartCheckResourceOCR自循环),但对客户端 APK 版本落后导致的强制更新门没有任何任务,只会一直卡到超时并按重试次数反复失败。本 PR 只补 MAA 缺失的这一层,不重复实现热更新。resVersion识别待下载的资源热更新,仅在该次运行把超时放宽到「游戏更新超时限制」,代理成功后记录版本供下次比对,避免把正常大版本热更误判成卡死。实现要点
DeviceBase.get_adb_path()为非抽象方法、默认返回None(回退系统 adb),MuMu 与雷电各自覆写返回自带adb.exe,不破坏现有实现。ak-conf.hypergryph.com/config/prod/{official,b}/Android/version实测可用;外服与台服未找到稳定公开接口,不在映射表中的服务器直接跳过检查。.downloading临时文件,体积明显偏小判定为未取到真实安装包,无论成败都清理不长期占用磁盘。测试
python -m pytest tests/ -q:206 passed / 7 failed。7 项失败在未改动的origin/dev上完全一致(199 passed / 同样 7 failed),与本 PR 无关;新增 7 项测试全部通过。tests/task/test_maa_game_update.py覆盖版本比较(含段数不等、无法解析时不下判断)与编排层各分支判定。待办与已知限制
yarn openapi重新生成前端 API 代码(frontend/src/api/models/MaaConfig_Run.ts、MaaUserConfig_Data.ts)。按规范未手改生成文件;updateScript入参为any,不阻塞当前功能。LogMonitor.update_latest_timestamp仅在日志行内容变化时推进latest_time),放宽超时是保守兜底而非依赖该行为。Sourcery 摘要
接管明日方舟客户端版本检查与官服自动更新,并为资源热更新放宽本次 MAA 代理超时。
新功能:
错误修复:
改进:
测试:
Original summary in English
Summary by Sourcery
接管明日方舟客户端版本检查与官服自动更新,并为资源热更新放宽本次 MAA 代理超时。
New Features:
Bug Fixes:
Enhancements:
Tests: