Skip to content

RFC: Config v2 (欢迎有兴趣的朋友提出意见) #529

Description

@wangl-cc

Config V2 设计规范

概述

  • Profileprofiles/*.toml):定义如何连接——连接方式、客户端与可选的行为/进阶配置
  • Tasktasks/*.yaml):定义做什么——带条件和覆盖的任务列表

在下面的例子里面,由于 Profile 更扁平,适合 TOML;Task 嵌套很深,更适合 YAML。但是,新版本依然支持 TOML,YAML,JSON 三种格式混合使用,你可以选择你喜欢的格式。

设计目标

V2 的目标有两个:

  • 对用户更直观:Profile 负责描述“如何连接”,Task 负责描述“做什么”,同时不再直接对接 MaaCore API。client_type 等运行上下文不再散落在任务参数中;任务文件也不再依赖多种隐式变换和不一致的规则,尤其体现在生命周期处理、参数传播,以及 variants 的激活逻辑上。
  • 对实现更直接:配置边界更清晰,client_type 的来源唯一,自动生命周期与手写生命周期的语义分离,单 Session 与多 Session 也分别建模。这样可以避免在运行时反复提取、合并、回填和兜底,减少隐式规则和特殊分支。

兼容性

Profile 和 Task 都有一个顶层字段 version

version = 2 
  • version = 2 → 按 V2 解析
  • version = 1 → 按 V1 解析,不警告 (如果你暂时不想迁移的话,但是后续 V1 会删除,所以最终还是要迁移)
  • version → 按 V1 解析 + 弃用警告

Profile 和 Task 必须同时升级,不保证交叉兼容,必须是 Profile V1 + Task V1 或者 Profile V2 + Task V2.


Profile 配置

顶层字段

version = 2              # 必填,标识配置格式版本
inherits = "default"     # 可选,继承另一个 Profile,深度合并(子字段覆盖父字段)
client_type = "Official" # 可选

继承示例

inherits 字段用来继承另一个 Profile,可以方便的实现配置复用:

# profiles/default.toml
version = 2

[connection]
type = "General"
address = "emulator-5554"
touch_mode = "MaaTouch"
# profiles/yostar-en.toml
version = 2
inherits = "default"
client_type = "YoStarEN"   # 只改这一个字段,其余全部继承

游戏客户端类型

client_type 是一个横跨多个作用域的配置,决定:

  • 加载哪个全局资源包(如 YoStarEN → EN 资源)
  • 部分 Preset 使用的游戏包名 / Bundle ID(如 PlayCover)
  • 任务条件判断需要的 client_type
  • 部分任务需要注入的 client_type

[connection]

type 选择连接类型,除了 General 以外提供了一系列默认值,且决定哪些字段合法。此外,对于部分类型 (类如 Waydroid) 也负责确定如何管理外部环境。

[connection]
type = "General"               # General / PlayCover / Waydroid / AVD / MuMuPro

General(通用模式,直接对标原始的 MaaCore API)

类似于旧版本,但是部分选项的位置和名字发生了变化。

[connection]
type = "General"
address = "emulator-5554"   # 可选,缺省时从 `adb devices` 自动检测
adb_path = "adb"            # 可选
touch_mode = "MaaTouch"     # 可选:MaaTouch / MiniTouch / Adb
adb_lite = false            # 可选
kill_adb_on_exit = false    # 可选
config = "General"          # 可选,连接时使用的配置,可能影响部分行为

PlayCover(macOS 通过 PlayCover 原生运行 iOS App)

touch_mode 内部固定为 MacPlayTools,平台差异资源 iOS 自动加载。

[connection]
type = "PlayCover"
address = "127.0.0.1:1717"  # 可选,默认 127.0.0.1:1717
screencap_mod = "Default"  

Playcover 支持多种截图模式:

  • Default:默认兼容模式
  • BGR:速度更快,使用目前没发现兼容性问题
  • SCK:使用 macOS ScreenCaptureKit 速度最快,但是需要 cli 的宿主 (终端),被授予了截图权限

Waydroid(Linux Continer)

支持自动启动,连接地址在运行时从 waydroid status 获取:

[connection]
type = "Waydroid"
adb_path = "adb"           # 可选
touch_mode = "MaaTouch"    # 可选
adb_lite = false           # 可选

MuMuPro(macOS)

类似于通用 ADB,但是有已知的 adb_path 和 address

[connection]
type = "MuMuPro"
address = "127.0.0.1:16384"  # 可选
touch_mode = "MaaTouch"      # 可选
adb_lite = false             # 可选
kill_adb_on_exit = false     # 可选

后续可以扩展更多类型,比如 AVD (自动启动),实体设备 (自动调节分辨率),以及 Windows 上面的 Mumu / 雷电(截图增强):

AVD(Android 虚拟设备)

sdk_path 必填,adb_path 和模拟器命令从中推导。

理论上支持截图增强,见 MaaAssistantArknights/MaaAssistantArknights#15608,有待实际实现

[connection]
type = "AVD"
sdk_path = "/home/user/Android/Sdk"   # 必填
avd_name = "Pixel_6_API_33"           # 可选,用于启动指定模拟器
touch_mode = "MaaTouch"               # 可选
adb_lite = false                      # 可选
kill_adb_on_exit = false              # 可选

[behavior]

运行时行为偏好,所有字段可选。

[behavior]
auto_reconnect = true          # 掉线后自动重连,默认 true
deployment_with_pause = false  # 部署时暂停,默认 false

[advanced]

进阶技术配置,大多数用户无需关注。所有字段可选。

[advanced]
inference_engine = "cpu"       # cpu / gpu:0 / gpu:1 / ...,默认 cpu
user_resource = false          # 从配置目录加载自定义资源,默认 false

完整示例

最简配置(PlayCover):

version = 2

[connection]
type = "PlayCover"

完整配置(General):

version = 2
client_type = "YoStarEN"

[connection]
type = "General"
address = "127.0.0.1:5555"
adb_path = "/usr/bin/adb"
touch_mode = "MaaTouch"
adb_lite = false
kill_adb_on_exit = false

[behavior]
auto_reconnect = true

[advanced]
inference_engine = "gpu:0"
user_resource = true

Task 配置(tasks/*.yaml

结构

生命周期管理

两个标志控制自动启停:

  • manage_environment_lifecycle(默认 true):是否自动管理外部环境(如 Waydroid session、AVD)。由 Profile 的 connection.type 决定是否实际生效——General / PlayCover 等无外部环境的类型忽略此标志。
  • manage_game_lifecycle(默认 true):是否自动管理游戏启停流程。
    • 启用时,运行时会自动执行 StartUp / CloseDown,client_typeaccount_name 会自动注入给 StartUp。
    • 禁用时,用户可以自己在 tasks 中手写 StartUp / CloseDown task。Runtime 仍会将 Profile 的 client_type 注入到这些 task 的 params 中,但不会从中提取 client_typeclient_type 的唯一来源始终是 Profile,同时不再保证中间任务出错后依然执行 CloseDown。

任务

Task 文件支持两种模式,两者不能同时存在:

  • tasks:任务列表模式,通常对于单账号任务;
  • sessions:编排模式,主要用于多个账号按顺序轮跑;

任务列表模式

version = 2
manage_environment_lifecycle: true  # 可选,默认 true
manage_game_lifecycle: true         # 可选,默认 true
account_name: main                  # 可选,注入给 StartUp

tasks:
  - type: Fight
    # ...

编排模式

所有 Session 共享 Profile 中的 client_type,只有 account_name 不同。实际按顺序串行执行。

manage_environment_lifecycle 只执行一次,(环境只启停一次)。
manage_game_lifecycle 每个 session 执行一次:

  • true 时,运行时会在各 Session 之间自动执行 CloseDown → StartUp
  • false 时,运行时仅按书写顺序执行,不做额外检查或兜底;如需切账号,需用户自己手写 StartUp / CloseDown

sessions 模式下:

  • 顶层不能再出现 account_name
  • 每个 Session 只描述该账号自己的 tasks
  • Session 按顺序执行;当前 Session 未完成时,不会进入下一个 Session
  • manage_game_lifecycle = false 时,Session 内允许手写 StartUp / CloseDown,但运行时不额外保证切换正确性

编排模式下的失败处理规则:

  • 用户主动中断时,立即停止整个运行,不进入后续 Session
  • 当前 Session 运行报错或掉线时,将该 Session 标记为失败,但继续执行后续 Session
  • 如果启用了自动游戏生命周期,当前 Session 在报错或掉线后仍会先自动执行 CloseDown,再进入下一个 Session
  • 最终结果需要反映所有失败的 Session,不能因为后续 Session 成功而吞掉前面的错误
version = 2
manage_environment_lifecycle: true  # 可选,默认 true,全局一次

sessions:
  - account_name: main
    tasks:
      - type: Fight
        params:
          stage: "1-7"

  - account_name: alt
    tasks:
      - type: Fight
        params:
          stage: CE-6

一个可能的痛点是,多 session 模式可能会存在大量的重复,所以后续可能会加上 template,允许复用。
现阶段主要使用可以利用 YAML 的锚点,一定程度进行复用。

Task 定义

每个 Task 包含:

  • type(必填):MaaCore 任务类型
  • name(可选):控制最终显示在 Summary 里面的名字
  • if(可选):控制该任务是否执行的条件;缺省表示始终执行
  • params(可选):任务执行时始终传给 MaaCore 的基础参数
  • override_strategy(可选):多个 override 同时命中时的处理策略,firstmerge,默认 first
  • overrides(可选):条件性参数覆盖列表,叠加在 params 之上

除非显式说明,V2 中的 type 都直接对应 MaaCore task 类型。V2 不额外引入新的“生命周期 task 类型”;自动启停由 manage_*_lifecycle 控制。

tasks:
  - type: Fight
    name: Fight Daily
    override_strategy: first
    if:
      weekdays: [Mon, Wed, Fri]
    params:
      stage: "1-7"
      report_to_penguin: true
    overrides:
      - if: OnSideStory
        params:
          stage: ""
      - if:
          weekdays: [Tue, Thu, Sat]
        params:
          stage: CE-6

overrides 的应用策略由 override_strategy 决定:

  • first(默认):按顺序找到第一个命中的 override,应用后停止
  • merge:按顺序应用所有命中的 override,后者覆盖前者

无匹配时使用原始 params,任务照常执行 (注意,V1 版本则会静默跳过)。

执行语义

自动游戏生命周期

manage_game_lifecycle = true 时:

  • 单 Session 模式会在任务列表前后自动执行 StartUp / CloseDown
  • account_name 会自动注入给 StartUp
  • client_type 会自动注入给需要的任务参数

自动执行的 CloseDown 只在以下情况执行:

  • 正常结束
  • 运行报错
  • 掉线停止

用户主动中断 (Ctrl-C) 时,不自动执行 CloseDown。后续可能添加配置/命令行参数,在报错的情况下,依然不关闭。

手写生命周期

manage_game_lifecycle = false 时:

  • tasks 中可以手写 StartUp / CloseDown,并允许任意穿插
  • 运行时严格按书写顺序执行
  • 不再根据 CloseDown 做任何额外兜底
  • 失败或中断后的行为与普通任务一致

条件系统

条件出现在两处:

  • task.if——决定任务是否执行
  • override.if——决定该 override 是否应用

字符串形式(无参数条件)

if: Always       # 始终激活(缺省 if 时的默认行为)
if: OnSideStory  # SideStory 期间激活(使用 Profile 中的 client_type)

其中:

  • OnSideStory(字符串)表示检查当前 Profile 的 client_type
  • on_side_story: Xxx(对象)表示显式检查指定客户端

Weekday(星期)

唯一字段:weekdays

if:
  weekdays: [Mon, Wed, Fri]
  timezone: Official   # 可选:Local(默认)/ Official / YoStarEN / ... / UTC 偏移整数

timezone 为客户端名称时,以服务器时间 04:00 作为换天边界。

DayMod(天数取模)

唯一字段:divisor。满足 num_days_from_ce % divisor == remainder 时激活。

if:
  divisor: 2
  remainder: 0   # 可选,默认 0
  timezone: 8    # 可选,UTC 偏移整数

Time(每日时间段,循环)

唯一字段:time_after 和/或 time_before

if:
  time_after: "16:00:00"
  time_before: "23:59:59"
  timezone: Official   # 可选

仅设 time_after:从该时刻到午夜激活。仅设 time_before:从午夜到该时刻激活。支持跨午夜的时间段(如 23:00–01:00)。

DateTime(日期范围,一次性)

唯一字段:start_date 和/或 end_date

if:
  start_date: "2024-08-01T00:00:00"
  end_date: "2024-08-21T04:00:00"
  timezone: 8   # 可选,UTC 偏移整数

OnSideStory(指定客户端)

if:
  on_side_story: Txwy   # 检查指定客户端的限时活动状态

这里的 Txwy 是显式目标客户端,与 Profile 当前使用的 client_type 无关。

组合条件

# AND——所有子条件满足
if:
  all:
    - weekdays: [Mon, Wed, Fri]
    - time_after: "16:00:00"

# OR——任一子条件满足
if:
  any:
    - weekdays: [Sat]
    - weekdays: [Sun]

# NOT——取反
if:
  not:
    weekdays: [Sun]

完整 Task 示例

manage_game_lifecycle: true

tasks:
  # Fight:始终执行,但根据条件覆盖关卡
  - type: Fight
    params:
      stage: "1-7"
      report_to_penguin: true
      penguin_id: "00000000"
    overrides:
      - if: OnSideStory
        params:
          stage: ""
      - if:
          weekdays: [Tue, Thu, Sat]
        params:
          stage: CE-6

  # Mall:仅在 16:00 后执行
  - type: Mall
    if:
      time_after: "16:00:00"
    params:
      shopping: true
      credit_fight: true
      buy_first: [招聘许可, 龙门币]
      blacklist: [碳, 家具, 加急许可]

  # Recruit:始终执行
  - type: Recruit
    params:
      refresh: true
      select: [4, 5]
      confirm: [3, 4, 5]

V1 → V2 迁移

Profile 迁移

V1

[connection]
type = "ADB"
adb_path = "adb"
device = "emulator-5554"
config = "CompatMac"

[resource]
global_resource = "YoStarEN"
user_resource = true

[static_options]
cpu_ocr = true

[instance_options]
touch_mode = "MaaTouch"
deployment_with_pause = false
adb_lite_enabled = false
kill_adb_on_exit = false

V2

version = 2
client_type = "YoStarEN"       # resource.global_resource 不再需要手动设,由 client_type 自动推导

[connection]
type = "General"               # "ADB" → "General"
address = "emulator-5554"      # "device" → "address"
adb_path = "adb"
touch_mode = "MaaTouch"        # 原 instance_options.touch_mode
adb_lite = false               # 原 instance_options.adb_lite_enabled
kill_adb_on_exit = false
config = "CompatMac"

[behavior]
deployment_with_pause = false  # 原 instance_options.deployment_with_pause

[advanced]
inference_engine = "cpu"       # 原 static_options.cpu_ocr = true → "cpu"
user_resource = true           # 原 resource.user_resource

主要变化:

  • 添加 version = 2
  • connection.typeADBGeneral
  • connection.deviceconnection.address
  • resource.global_resource / platform_diff_resource → 由 client_typeconnection.type 自动推导,不再需要手动设
  • static_options / instance_options → 拆分到 [connection][behavior][advanced]

Task 迁移

V1

tasks:
  - type: StartUp
    params:
      start_game_enabled: true
      client_type: Official

  - type: Fight
    params:
      stage: "1-7"
    variants:
      - condition:
          type: Weekday
          weekdays: [Tue, Thu, Sat]
        params:
          stage: CE-6
      - condition:
          type: Always
        params: {}

  - type: CloseDown

V2

manage_game_lifecycle: true    # 替代手写 StartUp / CloseDown task

tasks:
  - type: Fight
    params:
      stage: "1-7"             # base params,始终使用
    overrides:                 # variants → overrides
      - if:
          weekdays: [Tue, Thu, Sat]   # condition → if,无需 type 标签
        params:
          stage: CE-6          # 不再需要 Always variant 保底

主要变化:

  • StartUp / CloseDown task → manage_game_lifecycle: true(默认值),自动管理游戏启停
  • client_type 不再在 task params 中设置,由 Profile 注入
  • 用户仍可手写 StartUp / CloseDown(设 manage_game_lifecycle: false),但 client_type 只注入不提取,且运行时完全按书写顺序执行
  • variantsoverrides,仅覆盖参数,不影响任务是否执行
  • conditionif,通过唯一字段推断类型,无需 type 标签
  • 不再需要 Always variant 作为保底

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions