feat(maafw): 启动模拟器时按项目包名一并拉起游戏 - #638
Merged
qiyinxi merged 3 commits intoSep 9, 2026
Merged
Conversation
MaaFW 用 Adb controller 时只开模拟器,游戏要等脚本自己那套流程冷启动。模拟器侧 其实早有 open(idx, package_name),缺的是「这个项目要开哪个包」。 包名不在 interface.json 里——MaaFramework 的 ProjectInterface 规格没有这一项, 实测两个真实项目也都没有。真正的包名写在 pipeline 节点的 StartApp 动作参数里, 而且两种放法都存在:M9A 的九个服各自在 resource/<服>/pipeline/startup.json 里 覆盖同一个节点 Start1999,靠 interface 的 resource[].path 顺序叠加;MaaEnd 则放在 option 的 pipeline_override 里,取决于用户选的 ClientVersion。 所以 game_package.py 按同一套顺序推断:先按 resource[].path 顺序扫 pipeline,再把 已选任务的 pipelineOverride 按节点名盖上去,最后看还剩几个互不相同的包名。剩一个 才用,一个都没有或剩多个都不猜——挑错了会去启动另一个游戏,比不启动更糟,两种情况 都会在运行日志里说清楚原因并回落到手填。 配置只加 Game.PackageName 一项而不是「开关 + 输入框」两项:填了就是手动覆盖, 留空就是自动识别,同一个概念不让用户选两次。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
前脚本原先在重试循环里,一个用户重试三次就跑三遍;后脚本在每次尝试的 finally 里, 同样跑三遍。用户期望的口径是「第一次启动跑一次,完全结束时跑一次」,取消也算完全结束。 对照其余十个专项:MAA 与 HSR 是「每用户一次」,其余七个和 MaaFW 一样在重试循环里; 而「取消时跑收尾」全仓只有 MaaFW 一家做到(它用了 finally)。所以本次只把次数改对, 保留 finally——取消、重试全败、成功三条路都要跑到收尾脚本。 前脚本挪进同一个 try 的开头,与 finally 里的后脚本严格配对:跑过前脚本就一定跑后脚本。 实测(本地驱动 main_task):重试三次全失败由「前 3 次 / 后 3 次」变为「前 1 次 / 后 1 次」; 第一次成功与中途取消都是各 1 次,CancelledError 仍正常外抛。 其余十个专项的口径不一致,不在本次范围内。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
审查者指南该 PR 为 MFW ADB controller 引入了从项目 pipeline 自动推断 Android 游戏包名的机制,并允许手动覆盖;解析遵循 resource 顺序和任务 pipeline override 的覆盖语义,对不确定结果安全回落为仅启动模拟器。同时将任务前后脚本调整为每用户各执行一次,并完善前端配置、日志提示、测试和文档更新。 MFW 模拟器和游戏启动时序图sequenceDiagram
participant Runner as MaaFWRunner
participant Resolver as resolve_game_package
participant Project as ProjectPipelines
participant Emulator as EmulatorManager
Runner->>Runner: Read Game.PackageName
alt Manual package name configured
Runner->>Emulator: open(emulator_index, package_name)
else Automatic detection
Runner->>Resolver: resolve_game_package(resource_paths, task_overrides)
Resolver->>Project: Read resource pipeline files in order
Resolver->>Project: Apply task pipelineOverride values
alt One package candidate
Resolver-->>Runner: PackageResolution resolved
Runner->>Emulator: open(emulator_index, package)
else None or conflicting candidates
Resolver-->>Runner: not-found or ambiguous
Runner->>Emulator: open(emulator_index, empty package)
end
end
MFW 每用户任务脚本时序图sequenceDiagram
participant Runner as main_task
participant Before as execute_script_task
participant Tasks as MFWTaskLoop
participant After as execute_script_task
Runner->>Before: execute_script_task(ScriptBeforeTask, 脚本前任务)
Runner->>Tasks: _run_pretasks()
loop Retry attempts
Runner->>Tasks: Run one attempt
end
alt Success, all retries failed, or cancellation
Runner->>After: execute_script_task(ScriptAfterTask, 脚本后任务)
end
Runner-->>Runner: Propagate CancelledError when cancelled
MFW 游戏包解析流程图flowchart TD
A["MFW ADB controller starts"] --> B{"Game.PackageName filled?"}
B -->|Yes| C["Use manual package name"]
B -->|No| D["Scan resource pipeline files in resource path order"]
D --> E["Apply task pipelineOverride"]
E --> F{"Remaining package names"}
F -->|Exactly one| G["Use detected package name"]
F -->|None| H["Log not-found; launch emulator only"]
F -->|Multiple| I["Log ambiguous candidates; launch emulator only"]
C --> J["emulator_manager.open with package name"]
G --> J
H --> K["emulator_manager.open without game package"]
I --> K
文件级变更
提示和命令与 Sourcery 交互
自定义使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's Guide该 PR 为 MFW ADB controller 引入了从项目 pipeline 自动推断 Android 游戏包名的机制,并允许手动覆盖;解析遵循 resource 顺序和任务 pipeline override 的覆盖语义,对不确定结果安全回落为仅启动模拟器。同时将任务前后脚本调整为每用户各执行一次,并完善前端配置、日志提示、测试和文档更新。 Sequence diagram for MFW emulator and game startupsequenceDiagram
participant Runner as MaaFWRunner
participant Resolver as resolve_game_package
participant Project as ProjectPipelines
participant Emulator as EmulatorManager
Runner->>Runner: Read Game.PackageName
alt Manual package name configured
Runner->>Emulator: open(emulator_index, package_name)
else Automatic detection
Runner->>Resolver: resolve_game_package(resource_paths, task_overrides)
Resolver->>Project: Read resource pipeline files in order
Resolver->>Project: Apply task pipelineOverride values
alt One package candidate
Resolver-->>Runner: PackageResolution resolved
Runner->>Emulator: open(emulator_index, package)
else None or conflicting candidates
Resolver-->>Runner: not-found or ambiguous
Runner->>Emulator: open(emulator_index, empty package)
end
end
Sequence diagram for per-user MFW task scriptssequenceDiagram
participant Runner as main_task
participant Before as execute_script_task
participant Tasks as MFWTaskLoop
participant After as execute_script_task
Runner->>Before: execute_script_task(ScriptBeforeTask, 脚本前任务)
Runner->>Tasks: _run_pretasks()
loop Retry attempts
Runner->>Tasks: Run one attempt
end
alt Success, all retries failed, or cancellation
Runner->>After: execute_script_task(ScriptAfterTask, 脚本后任务)
end
Runner-->>Runner: Propagate CancelledError when cancelled
Flow diagram for MFW game package resolutionflowchart TD
A["MFW ADB controller starts"] --> B{"Game.PackageName filled?"}
B -->|Yes| C["Use manual package name"]
B -->|No| D["Scan resource pipeline files in resource path order"]
D --> E["Apply task pipelineOverride"]
E --> F{"Remaining package names"}
F -->|Exactly one| G["Use detected package name"]
F -->|None| H["Log not-found; launch emulator only"]
F -->|Multiple| I["Log ambiguous candidates; launch emulator only"]
C --> J["emulator_manager.open with package name"]
G --> J
H --> K["emulator_manager.open without game package"]
I --> K
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
…afw-game-package-20260909 # Conflicts: # frontend/src/i18n/locales/en-US.ts # frontend/src/i18n/locales/ja-JP.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
interface.json中并没有包名字段(ProjectInterface 规格里就没有这一项),真正的包名写在 pipeline 节点的StartApp动作参数里。M9A 的九个服各自在resource/<服>/pipeline/startup.json覆盖同一个节点,靠resource[].path顺序叠加;MaaEnd 则放在 option 的pipeline_override里、取决于所选ClientVersion。两种放法都已覆盖。Game.PackageName一项:填了即手动覆盖,留空即自动识别,同一概念不让用户选两次。finally内,一个用户重试三次就各跑三遍;现改为每用户各一次。后脚本仍保留在finally,成功、重试全败与中途取消都会跑到。本地验证
包名识别对着两个真实项目逐项实跑:
base + global_jp + global_en这类三层叠加resource[].path顺序会得到上一层的包名,符合覆盖语义ambiguous(附候选列表)与not-found,均不猜测前后脚本改动实跑
main_task三条路径对照:CancelledError仍正常外抛自动化:
python -m pytest tests744 passed / 3 skipped(新增 13 个纯逻辑用例 + 8 subtests,并更新既有test_maafw_config的字段数量断言);收集门槛--collect-only747 条退出码 0;ruff format --check与ruff check对改动文件无问题;python scripts/changelog.py check退出码 0。前端yarn typecheck、yarn lint无问题,OpenAPI 由生成器更新(生成物为 CRLF,已按仓库行尾归一化,净差异仅MaaFWConfig_Game.ts一个文件)。已知问题(均非本 PR 引入)
frontend/electron/services/backendService.test.ts有一个用例稳定超时失败;本 PR 未改动frontend/electron/下任何文件。tests/task/test_maafw_embedded_prepare_cancel.py的三个用例在仅按uv sync --group dev建立的环境下失败,原因是dev依赖组未包含pytest-asyncio;补装后全部通过,上述 744 即为补装后的结果。🤖 Generated with Claude Code
Sourcery 摘要
允许 MFW 模拟器运行自动启动已配置的游戏,并执行按用户划分的生命周期脚本,同时避免重试导致脚本重复执行。
新功能:
Game.PackageName设置及相应的界面、API 模型和本地化说明,以支持手动覆盖或在必要时回退到自动检测。错误修复:
增强功能:
文档:
测试:
Original summary in English
Sourcery 摘要
允许 MFW 模拟器会话自动启动游戏,同时使生命周期脚本按每位用户执行一次,而不是每次重试执行一次。
新功能:
Game.PackageName设置。错误修复:
增强功能:
文档:
测试:
Original summary in English
Summary by Sourcery
Allow MFW emulator sessions to launch their game automatically while making lifecycle scripts execute once per user rather than once per retry.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests: