Skip to content

feat(MAA): 支持按服务器在队列前后管理明日方舟安装 - #330

Open
Taimer0721 wants to merge 1 commit into
AUTO-MAS-Project:devfrom
Taimer0721:Taimer
Open

feat(MAA): 支持按服务器在队列前后管理明日方舟安装#330
Taimer0721 wants to merge 1 commit into
AUTO-MAS-Project:devfrom
Taimer0721:Taimer

Conversation

@Taimer0721

@Taimer0721 Taimer0721 commented Aug 3, 2026

Copy link
Copy Markdown

实现思路

  • 在 MAA 运行配置中增加“运行队列前自动卸载”和“运行队列后自动安装”两个独立开关。
  • 队列启动时读取当前启用用户的服务器配置并形成快照,按“模拟器实例 + 服务器”去重,保证同一资源只处理一次。
  • 为 Official、Bilibili、YoStarEN、YoStarJP、YoStarKR、txwy 六种服务器分别映射正确的 Android 包名和下载资源。
  • 官服复用 6.0 游戏中心的鹰角 APK 入口;B 服从哔哩哔哩游戏中心动态获取当前 APK;国际服、日服、韩服和繁中服按各自包名获取最新 XAPK,并处理 split APK 与 OBB。
  • 单个服务器卸载或安装失败时记录错误并继续队列流程,避免影响其他脚本和服务器。

Summary by Sourcery

为围绕 MAA 脚本队列的每个服务器添加明日方舟的队列级自动卸载和重装功能。

New Features:

  • 允许为每个脚本配置选项,根据启用的用户服务器和模拟器实例,在队列运行前自动卸载明日方舟,并在运行后自动重新安装。

Enhancements:

  • 引入后端明日方舟包管理服务,用于管理特定服务器的安装包发现与下载(包括 APK/XAPK 处理),以及基于 ADB 的安装/卸载操作,并提供健壮的日志记录和错误隔离能力。
  • 扩展 MAA 脚本配置模型和前端编辑视图,以支持新的运行时自动化标志,同时保持行为为可选启用并向后兼容。
Original summary in English

Summary by Sourcery

Add queue-level automation for uninstalling and reinstalling Arknights per server around MAA script queues.

New Features:

  • Allow configuring per-script options to automatically uninstall Arknights before a queue run and reinstall it after, based on enabled user servers and emulator instances.

Enhancements:

  • Introduce a backend Arknights package service to manage server-specific package discovery, download (including APK/XAPK handling), and ADB-based install/uninstall, with robust logging and error isolation.
  • Extend MAA script config models and frontend edit view to support the new run-time automation flags, keeping behavior opt-in and backwards compatible.

@sourcery-ai

sourcery-ai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

为每个已启用的服务器和模拟器实例新增可配置的队列前/后自动化流程,用于卸载/安装明日方舟(Arknights),包括一个新的 ArknightsPackage 服务,用于管理基于服务器的包映射、下载以及基于 ADB 的安装/卸载,并配套相应的后端配置与前端选项接线。

基于队列的明日方舟卸载/安装自动化时序图

sequenceDiagram
    participant TaskRunner as TaskExecuteBase_main_task
    participant Config as Config
    participant EmulatorManager as EmulatorManager
    participant ArknightsPackage as ArknightsPackage
    participant Emulator as DeviceBase

    TaskRunner->>TaskRunner: prepare()
    TaskRunner->>TaskRunner: _collect_arknights_package_automations()
    TaskRunner->>TaskRunner: _run_arknights_package_action(uninstall)
    loop per automation
        TaskRunner->>EmulatorManager: get_emulator_instance(emulator_id)
        EmulatorsManager-->>TaskRunner: emulator
        TaskRunner->>Config: EmulatorConfig[emulator_uid]
        TaskRunner->>ArknightsPackage: get_resource(server)
        TaskRunner->>ArknightsPackage: uninstall(emulator, server, emulator_type, emulator_path, emulator_index)
        ArknightsPackage->>ArknightsPackage: _prepare_device(emulator, emulator_type, emulator_path, emulator_index)
        ArknightsPackage->>Emulator: getStatus(emulator_index)
        alt [emulator offline]
            ArknightsPackage->>Emulator: open(emulator_index)
        end
        ArknightsPackage->>ArknightsPackage: _ensure_connected(adb_path, serial)
        ArknightsPackage->>ProcessRunner: run_process(adb_path, -s, serial, uninstall, package_name)
        ProcessRunner-->>ArknightsPackage: result
        ArknightsPackage-->>TaskRunner: uninstall completed
    end

    TaskRunner->>TaskRunner: run scripts in queue

    TaskRunner->>TaskRunner: final_task()
    TaskRunner->>TaskRunner: _run_arknights_package_action(install)
    loop per automation
        TaskRunner->>ArknightsPackage: get_resource(server)
        TaskRunner->>ArknightsPackage: install(emulator, server, emulator_type, emulator_path, emulator_index, proxy)
        ArknightsPackage->>ArknightsPackage: _prepare_device(emulator, emulator_type, emulator_path, emulator_index)
        ArknightsPackage->>ArknightsPackage: _download_package(resource, proxy)
        alt [package_format == apk]
            ArknightsPackage->>ArknightsPackage: _install_apks(adb_path, serial, [apk])
        else [package_format == xapk]
            ArknightsPackage->>ArknightsPackage: _install_xapk(adb_path, serial, resource, xapk_path)
        end
        ArknightsPackage-->>TaskRunner: install completed
    end
Loading

文件级变更

Change Details Files
在任务管理器中基于 server/emulator 快照,为每个队列添加明日方舟卸载/安装自动化。
  • 引入 ArknightsPackageAutomation 数据类,并在每个任务中从 MaaConfig 收集已启用服务器的快照
  • 为启用了自动化标记的脚本,收集唯一的 (emulator_id, emulator_index, server) 组合
  • 实现 _run_arknights_package_action,用于按目标调用 ArknightsPackage.install/uninstall,并进行错误隔离和 WebSocket 报告
  • 当存在 queue_id 时,在队列开始时触发卸载自动化,在队列结束时触发安装自动化
app/core/task_manager.py
在后端配置/模式与前端类型中,为 MAA 脚本新增运行级别的自动化开关。
  • 在 MaaConfig 的 Run 部分添加 IfAutoUninstallBeforeQueue 和 IfAutoInstallAfterQueue,使用 BoolValidator 默认值
  • 扩展 MaaConfig_Run Pydantic 模式,加入这两个可选开关
  • 更新 MAAScriptConfig TypeScript 接口以包含新字段
app/models/config.py
app/models/schema.py
frontend/src/types/script.ts
在 MAA 脚本编辑器中添加 UI 控件,用于配置队列前卸载和队列后安装明日方舟自动化。
  • 在 MAAScriptEdit 表单中添加两个带 tooltip 标签的开关,用于队列前卸载和队列后安装
  • 将开关接线到 maaConfig.Run.IfAutoUninstallBeforeQueue/IfAutoInstallAfterQueue 并通过 handleChange 处理
  • 在响应式 MAAScriptConfig 默认值中初始化新的 Run 标志
frontend/src/views/EditView/Script/MAAScriptEdit.vue
引入 ArknightsPackage 服务,用于管理基于服务器的包元数据、下载,以及针对不同明日方舟服务器的基于 ADB 的安装/卸载。
  • 定义 ArknightsPackageResource 映射,覆盖 Official、Bilibili、YoStarEN/JP/KR 和 txwy 服务器的包名与下载 URL
  • 实现通过 adb uninstall 进行卸载,并解析结果与记录日志;通过 adb install/install-multiple 进行安装,包括 XAPK 处理
  • 解析模拟器特定的 adb 路径,确保 ADB 连通性,并通过 EmulatorManager 和 DeviceBase 管理设备生命周期
  • 实现 XAPK 解压,带安全路径检查、拆分 APK 顺序控制,以及将 OBB 推送到 /sdcard/Android/obb/package
  • 通过 asyncio 锁管理每个服务器的并发下载,采用流式 HTTP 下载(包括 Bilibili 动态 URL 解析和 APKPure 镜像),并进行原子化缓存替换
app/services/arknights_package.py
app/services/__init__.py

Tips and commands

Interacting with Sourcery

  • 触发新的审查: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 通过回复某条审查评论,让 Sourcery 从该评论创建 issue。你也可以在审查评论下回复 @sourcery-ai issue 来从该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题中的任意位置写上 @sourcery-ai,即可在任意时间生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在任意时间在该位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,可在任意时间(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,以解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 关闭所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,以关闭所有现有的 Sourcery 审查。特别适用于希望从头开始新的审查的情况——别忘了再评论 @sourcery-ai review 来触发新审查!

自定义你的体验

访问你的 dashboard 以:

  • 启用或禁用审查特性,例如 Sourcery 自动生成的 pull request 摘要、审阅者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查指令。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Adds configurable pre/post queue automation to uninstall/install Arknights per enabled server and emulator instance, including a new ArknightsPackage service that manages server-specific package mapping, download, and ADB-based install/uninstall, with corresponding backend config and frontend options wiring.

Sequence diagram for queue-based Arknights uninstall/install automation

sequenceDiagram
    participant TaskRunner as TaskExecuteBase_main_task
    participant Config as Config
    participant EmulatorManager as EmulatorManager
    participant ArknightsPackage as ArknightsPackage
    participant Emulator as DeviceBase

    TaskRunner->>TaskRunner: prepare()
    TaskRunner->>TaskRunner: _collect_arknights_package_automations()
    TaskRunner->>TaskRunner: _run_arknights_package_action(uninstall)
    loop per automation
        TaskRunner->>EmulatorManager: get_emulator_instance(emulator_id)
        EmulatorsManager-->>TaskRunner: emulator
        TaskRunner->>Config: EmulatorConfig[emulator_uid]
        TaskRunner->>ArknightsPackage: get_resource(server)
        TaskRunner->>ArknightsPackage: uninstall(emulator, server, emulator_type, emulator_path, emulator_index)
        ArknightsPackage->>ArknightsPackage: _prepare_device(emulator, emulator_type, emulator_path, emulator_index)
        ArknightsPackage->>Emulator: getStatus(emulator_index)
        alt [emulator offline]
            ArknightsPackage->>Emulator: open(emulator_index)
        end
        ArknightsPackage->>ArknightsPackage: _ensure_connected(adb_path, serial)
        ArknightsPackage->>ProcessRunner: run_process(adb_path, -s, serial, uninstall, package_name)
        ProcessRunner-->>ArknightsPackage: result
        ArknightsPackage-->>TaskRunner: uninstall completed
    end

    TaskRunner->>TaskRunner: run scripts in queue

    TaskRunner->>TaskRunner: final_task()
    TaskRunner->>TaskRunner: _run_arknights_package_action(install)
    loop per automation
        TaskRunner->>ArknightsPackage: get_resource(server)
        TaskRunner->>ArknightsPackage: install(emulator, server, emulator_type, emulator_path, emulator_index, proxy)
        ArknightsPackage->>ArknightsPackage: _prepare_device(emulator, emulator_type, emulator_path, emulator_index)
        ArknightsPackage->>ArknightsPackage: _download_package(resource, proxy)
        alt [package_format == apk]
            ArknightsPackage->>ArknightsPackage: _install_apks(adb_path, serial, [apk])
        else [package_format == xapk]
            ArknightsPackage->>ArknightsPackage: _install_xapk(adb_path, serial, resource, xapk_path)
        end
        ArknightsPackage-->>TaskRunner: install completed
    end
Loading

File-Level Changes

Change Details Files
Add per-queue Arknights uninstall/install automation in the task manager using server/emulator snapshots.
  • Introduce ArknightsPackageAutomation dataclass and per-task snapshot collection of enabled servers from MaaConfig
  • Collect unique (emulator_id, emulator_index, server) combinations for scripts with automation flags enabled
  • Implement _run_arknights_package_action to invoke ArknightsPackage.install/uninstall per target with error isolation and websocket reporting
  • Invoke uninstall automation at queue start and install automation at queue end when queue_id is present
app/core/task_manager.py
Expose new Run-level automation flags for MAA scripts across backend config/schema and frontend types.
  • Add IfAutoUninstallBeforeQueue and IfAutoInstallAfterQueue to MaaConfig Run section with BoolValidator defaults
  • Extend MaaConfig_Run Pydantic schema with the two optional flags
  • Update MAAScriptConfig TypeScript interface to include the new fields
app/models/config.py
app/models/schema.py
frontend/src/types/script.ts
Add UI controls to configure pre-uninstall and post-install Arknights automation in the MAA script editor.
  • Add two switches with tooltipped labels for pre-queue uninstall and post-queue install in MAAScriptEdit form
  • Wire switches to maaConfig.Run.IfAutoUninstallBeforeQueue/IfAutoInstallAfterQueue and handleChange
  • Initialize the new Run flags in the reactive MAAScriptConfig defaults
frontend/src/views/EditView/Script/MAAScriptEdit.vue
Introduce ArknightsPackage service to manage server-specific package metadata, download, and ADB-based install/uninstall for different Arknights servers.
  • Define ArknightsPackageResource mapping for Official, Bilibili, YoStarEN/JP/KR, and txwy servers with package names and download URLs
  • Implement uninstall via adb uninstall with result parsing and logging, and install via adb install/install-multiple including XAPK handling
  • Resolve emulator-specific adb paths, ensure ADB connectivity, and manage device lifecycle via EmulatorManager and DeviceBase
  • Implement XAPK extraction with secure path checks, split APK ordering, and OBB push into /sdcard/Android/obb/package
  • Manage concurrent downloads per server with asyncio locks, streamed HTTP downloads (including bilibili dynamic URL resolution and APKPure mirrors), and atomic cache replacement
app/services/arknights_package.py
app/services/__init__.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我留下了一些整体性的反馈:

  • _resolve_adb_path 中你将 adb.exe 写死了,这在非 Windows 平台上会失败;建议使用与平台无关的方式解析 adb,或者同时检查 adbadb.exe,以保证该功能在不同平台上都能正常工作。
  • _download_package 方法在 _PACKAGE_DIR 中已有缓存文件的情况下仍然会重新下载 APK/XAPK;如果这些文件比较大,你可能需要在已经存在有效文件时提前返回,或者增加一个简单的版本/修改时间检查,以避免不必要的重复下载。
给 AI Agent 的提示
请根据这次代码评审中的评论进行修改:

## 整体评论
-`_resolve_adb_path` 中你将 `adb.exe` 写死了,这在非 Windows 平台上会失败;建议使用与平台无关的方式解析 `adb`,或者同时检查 `adb``adb.exe`,以保证该功能在不同平台上都能正常工作。
- `_download_package` 方法在 `_PACKAGE_DIR` 中已有缓存文件的情况下仍然会重新下载 APK/XAPK;如果这些文件比较大,你可能需要在已经存在有效文件时提前返回,或者增加一个简单的版本/修改时间检查,以避免不必要的重复下载。

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈来改进后续的评审。
Original comment in English

Hey - I've left some high level feedback:

  • In _resolve_adb_path you hardcode adb.exe, which will fail on non‑Windows platforms; consider resolving adb with a platform‑agnostic name or checking both adb and adb.exe to keep this feature working cross‑platform.
  • The _download_package method always re-downloads the APK/XAPK even if a cached file already exists in _PACKAGE_DIR; if these files are large, you might want to short‑circuit when a valid existing file is present or add a simple versioning/mtime check to avoid unnecessary downloads.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_resolve_adb_path` you hardcode `adb.exe`, which will fail on non‑Windows platforms; consider resolving `adb` with a platform‑agnostic name or checking both `adb` and `adb.exe` to keep this feature working cross‑platform.
- The `_download_package` method always re-downloads the APK/XAPK even if a cached file already exists in `_PACKAGE_DIR`; if these files are large, you might want to short‑circuit when a valid existing file is present or add a simple versioning/mtime check to avoid unnecessary downloads.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant