3.3 Project Interface V2 协议
注意: 本文档是关于
ProjectInterface的编写和使用文中将使用 PI 代指
ProjectInterface,Client 代指可以处理 PI 的工具
简介
所谓 ProjectInterface,即 MaaFramework 的一个标准化的项目结构声明,该声明目前包含 interface.json 一个文件。通过定义 PI,你可以使用 MaaFramework 的各种衍生工具。因此,即使你打算纯粹依靠通用编程语言集成,也建议定义包含基础信息的 PI。
TIP
你可以前往 社区项目 中查找使用 PI 的通用 UI 及其他工具
版本说明
由于业务进度高速迭代,MaaFramework 的发版节奏与 PI 的迭代节奏无法很好对齐。因此,PI 将进行单独的版本控制,PI 的版本号与 MaaFramework release 版本号并不完全同步。
我们将独立版本时(2026-1-30)的版本号定为 v2.1.0,后续新增与修复将会在文档中标注版本号。
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-1-30 | v2.1.0 | 独立版本发布 |
| 2026-1-30 | v2.2.0 | 新增 attach_resource_path 和 import 字段 |
| 2026-2-23 | v2.3.0 | 新增 checkbox 多选类型、option.controller、option.resource、全局/resource/controller 级 option、focus.display 展示渠道标签、preset 预设配置字段、import 支持导入 preset |
| 2026-3-5 | v2.3.1 | 明确 option 适用性过滤规则 |
interface.json
整体结构
interface_version
number
接口版本号,当前为 2,固定且必须设置。用于标识 ProjectInterface 协议版本。languages
object
多语言支持配置,键为语言代码,值为对应的翻译文件路径。若不指定,则默认仅支持中文。
文件相对路径为 interface.json 同目录下的相对路径。jsonc"languages": { "zh_cn": "interface_zh.json", "en_us": "interface_en.json" }name
string
项目唯一标识符,用作项目ID。label
string
项目显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。可选。jsonc{ "name": "MyProject", "label": "$project_name" // 国际化项目名称 }title
string
窗口标题,Client 会直接显示该内容,不添加其他修饰。可选,默认使用name和version拼接生成。支持国际化(以$开头)。icon
string
应用图标文件路径,相对于项目根目录。若不指定,则使用默认图标。支持国际化(以$开头)。mirrorchyan_rid
string
MirrorChyan 资源包标识符,用于资源管理和分发。mirrorchyan_multiplatform
boolean
是否支持多平台,影响资源包的打包和分发策略。github
string
项目GitHub仓库地址,用于版本更新检查和问题反馈。
软件更新约定:经过版本历史的惨痛教训,我们期望通用 UI 仅提供对该 github release 的更新功能,不要提供单独更新 UI 本体 / MaaFW 的功能。
资源作者发版时自行打包其指定的 UI / MaaFW,以实现用户侧的资源版本对应唯一的 UI 和 MaaFW 版本,规避版本混搭带来的各种问题。version
string
项目版本号,Client 可以展示给用户,同时用于版本更新检查。contact
string
联系方式信息,显示在"关于"页面。支持文件路径、URL或直接文本,内容支持Markdown格式。支持国际化(以$开头)。license
string
项目许可证信息,显示在"关于"页面。支持文件路径、URL或直接文本,内容支持Markdown格式。支持国际化(以$开头)。welcome
string
欢迎消息,在用户首次使用时弹窗显示,亦可作为公告使用。支持文件路径、URL或直接文本,内容支持Markdown格式。系统会记录显示内容,当内容更新时会再次弹窗显示。支持国际化(以$开头)。description
string
项目描述信息,显示在"关于"页面。支持文件路径、URL或直接文本,内容支持Markdown格式。支持国际化(以$开头)。controller
object[]
控制器配置,为一个对象数组,含有预设的控制器信息。name
string
唯一名称标识符,用作控制器ID。label
string
显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。description
string
控制器详细描述信息。支持文件路径、URL或直接文本,内容支持Markdown格式。可选。支持国际化(以$开头)。icon
string
控制器图标文件路径,相对于项目根目录。可选。支持国际化(以$开头)。type
'Adb' | 'Win32' | 'PlayCover' | 'Gamepad' | 'WlRoots'
控制器类型,取值为Adb、Win32(仅 Windows)、PlayCover(仅 macOS)、Gamepad(仅 Windows)和WlRoots(仅 Linux)。display_short_side
number
默认缩放分辨率的短边长度,用于屏幕适配。可选,默认720。与display_long_side和display_raw互斥。display_long_side
number
默认缩放分辨率的长边长度,用于屏幕适配。可选。与display_short_side和display_raw互斥。display_raw
boolean
是否使用原始分辨率进行截图,不进行缩放。可选,默认false。与缩放分辨率设置互斥。permission_required
boolean
是否需要管理员权限运行该控制器。可选,默认 false。
在运行任务前,若当前进程不是管理员,会提示并尝试以管理员身份重新启动。attach_resource_path
string[]💡 v2.2.0
可选。附加资源路径数组。将会在resource.path加载完成后,额外加载这些路径下的资源。option
string[]💡 v2.3.0
可选。控制器级的选项配置,为一个字符串数组,数组元素应与外层 option 配置中的键名对应。
该选项生成的参数会参与到所有使用该控制器的任务的 pipeline override 中,起到控制器级参数传递的作用。
若被引用的 option 不支持当前 controller/resource 条件,则该 option 的pipeline_override(含其嵌套option.option)不参与合并。 💡 v2.3.1adb
objectAdb控制器的具体配置。注意: V2 协议中。Adb 控制器的 input/screencap 由 MaaFramework 自动检测和选择最优方式,无需手动配置。
win32
objectWin32控制器的具体配置。playcover
objectPlayCover控制器的具体配置(仅 macOS)。用于控制通过 PlayCover 运行的 iOS 应用。详见 控制方式说明。- uuid
string
可选。目标应用的 Bundle Identifier,不提供则使用默认maa.playcover,仅作为控制器标识符,与被操控应用无关。
- uuid
gamepad
objectGamepad控制器的具体配置(仅 Windows)。用于创建虚拟游戏手柄进行游戏控制。需要安装 ViGEm Bus Driver。详见 控制方式说明。class_regex
string
可选。Win32控制器搜索窗口类名使用的正则表达式。window_regex
string
可选。Win32控制器搜索窗口标题使用的正则表达式。gamepad_type
string
可选。虚拟手柄类型,取值为Xbox360、DualShock4(或DS4)。不提供则默认使用Xbox360。screencap
string
可选。截图方式,不提供则使用默认。仅当配置了窗口正则时有效。详见 控制方式说明。
wlroots
objectwlroots控制器的具体配置(仅 Linux)。用于控制在 wlroots 合成器中运行的应用程序。详见 控制方式说明。
resource
object[]
资源配置,为一个对象数组,含有资源加载的信息。name
string
唯一名称标识符,用作资源包ID。label
string
显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。可选。description
string
资源详细描述信息。支持文件路径、URL或直接文本,内容支持Markdown格式。可选。icon
string
资源图标文件路径,相对于项目根目录。可选。支持国际化(以$开头)。path
string[]
加载的路径数组。如果提供多个路径,会依次加载,后加载的资源会覆盖前加载的资源。
文件相对路径为 interface.json 同目录下的相对路径。
注意: 资源不仅仅是pipeline,也包含image和model,因此不要直接指定pipeline目录。controller
string[]
可选。指定该资源包支持的控制器类型列表。数组元素应与controller配置中的name字段对应。若不指定,则表示支持所有控制器类型。
当用户选择了某个控制器时,只有支持该控制器的资源包才会显示在用户界面中供选择。这允许为不同控制器类型提供专门优化的资源包。option
string[]
可选。资源包级的选项配置,为一个字符串数组,数组元素应与外层 option 配置中的键名对应。
该选项生成的参数会参与到所有任务的 pipeline override 中,起到资源包级参数传递的作用。
若被引用的 option 不支持当前 controller/resource 条件,则该 option 的pipeline_override(含其嵌套option.option)不参与合并。 💡 v2.3.1jsonc"resource": [ { "name": "Android专用资源", "label": "$Android专用资源", "controller": ["Android"], "path": ["resource_android"] }, { "name": "通用资源", "label": "$通用资源", "path": ["resource"] } ]
agent
object | object[]
代理配置,可以是单个对象或对象数组,含有子进程(AgentServer)的信息。支持同时配置多个 Agent 以实现更复杂的自动化场景。child_exec
string
子进程路径,为系统路径中可执行文件。如在环境变量(系统变量、用户变量)中存在 Python 路径,可直接写"python"。
CWD 为 interface.json 所在目录。child_args
string[]
可选。子进程参数数组。identifier
string
可选。连接标识符,被用来创建一个通信套接字。填写则会被使用,否则自动创建。
单个 Agent 示例:
jsonc"agent": { "child_exec": "python", "child_args": [ "./agent/main.py", // 注意 cwd 为 interface.json 所在目录 "--test-mode" // 固定字符串,原样传递 ] }多个 Agent 示例:
jsonc"agent": [ { "child_exec": "python", "child_args": ["./agent/recognition.py"] }, { "child_exec": "python", "child_args": ["./agent/action.py"] } ]task
object[]
任务配置,为一个对象数组,含有可执行任务的信息。name
string
任务唯一标识符,用作任务ID。label
string
任务显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。可选。entry
string
任务入口,为pipeline中Task的名称。default_check
boolean
是否默认选中该任务。可选,默认false。Client 在初始化时会根据该值决定是否默认勾选该任务。description
string
任务详细描述信息,帮助用户理解任务功能。支持文件路径、URL或直接文本,内容支持 Markdown 格式。可选。icon
string
任务图标文件路径,相对于项目根目录。用于在用户界面中显示。可选。支持国际化(以$开头)。resource
string[]
可选。指定该任务支持的资源包列表。数组元素应与resource配置中的name字段对应。若不指定,则表示该任务在所有资源包中都可用。
当用户选择了某个资源包时,Client 可将不支持该资源包的任务隐藏,或以不可用(灰色/禁用)状态展示以提示用户。这允许为不同资源包提供专门的任务配置,比如活动任务只在特定资源包中可用。jsonc"task": [ { "name": "活动任务", "label": "$活动任务", "entry": "ActivityTask", "resource": ["Official"], "description": "仅在官服资源包中可用的活动任务" }, { "name": "通用任务", "label": "$通用任务", "entry": "CommonTask" } ]controller
string[]
可选。指定该任务支持的控制器类型列表。数组元素应与controller配置中的name字段对应。若不指定,则表示该任务在所有控制器类型中都可用。
当用户选择了某个控制器时,Client 可将不支持该控制器的任务隐藏,或以不可用(灰色/禁用)状态展示以提示用户。这允许为不同控制器类型提供专门的任务配置,比如某些任务只适用于 Adb 控制器,某些任务只适用于 Win32 控制器。jsonc"task": [ { "name": "安卓专属任务", "label": "$安卓专属任务", "entry": "AndroidOnlyTask", "controller": ["Android"], "description": "仅在安卓控制器中可用的任务" }, { "name": "PC专属任务", "label": "$PC专属任务", "entry": "Win32OnlyTask", "controller": ["Win32Emulator"], "description": "仅在Win32控制器中可用的任务" }, { "name": "通用任务", "label": "$通用任务", "entry": "CommonTask" } ]pipeline_override
pipeline
可选。任务参数,执行任务时会覆盖已加载的资源。该项结构与pipeline中的json文件完全一致,需要包含 任务名 部分,例如:jsonc"pipeline_override": { "Quit": { "enabled": true } }option
string[]
可选。任务配置项,为一个数组,含有若干后续option对象中的键的值,Client 会根据要求用户进行选择。
Client 可以使用option中的顺序来展示配置项。
option
record<string, object>
配置项定义,为一个对象映射,含有配置项的信息。key
唯一名称标识符,任务会使用该名称进行引用。type
string
配置项类型。可选,默认"select"。可选值:"select": 下拉选项框,用户从预定义的选项中选择一个"checkbox": 多选框,用户从预定义的选项中选择多个 💡 v2.3.0"input": 用户输入框,允许用户手动输入内容"switch": 选择框,Yes or No
controller
string[]💡 v2.3.0
可选。指定该配置项适用的控制器类型列表。数组元素应与controller配置中的name字段对应。若不指定,则表示该配置项在所有控制器类型中都可用。
当用户选择了某个控制器时,Client 可将不适用于该控制器的配置项隐藏,或以不可用(灰色/禁用)状态展示以提示用户。
当当前控制器不在该列表中时,该配置项视为未激活:其自身及其子配置项(option.option)产生的所有pipeline_override均不参与合并。 💡 v2.3.1resource
string[]💡 v2.3.0
可选。指定该配置项适用的资源包列表。数组元素应与resource配置中的name字段对应。若不指定,则表示该配置项在所有资源包中都可用。
当用户选择了某个资源包时,Client 可将不适用于该资源包的配置项隐藏,或以不可用(灰色/禁用)状态展示以提示用户。
当当前资源包不在该列表中时,该配置项视为未激活:其自身及其子配置项(option.option)产生的所有pipeline_override均不参与合并。 💡 v2.3.1label
string
配置项显示标签,用于在用户界面中展示。支持国际化字符串(以$开头)。可选。description
string
配置项详细描述信息,帮助用户理解配置项的作用。支持文件路径、URL或直接文本,内容支持Markdown格式。可选。支持国际化(以$开头)。icon
string
配置项图标文件路径,相对于项目根目录。可选。支持国际化(以$开头)。cases
object[]
仅在type为"select"/"checkbox"/"switch"时使用。可选项,为一个对象数组,含有各个可选项的信息。注意: 当
type为"checkbox"时,用户可以同时选中多个 case,所有被选中的 case 的pipeline_override会按照cases数组中的定义顺序依次合并生效,与用户勾选的先后顺序无关。注意: 当
type为"switch"时,仅支持两个 cases,且需遵循以下规则:- 如果
case.name为"Yes"、"yes"、"Y"或"y"之一,该 case 会被识别为 Yes 选项 - 如果
case.name为"No"、"no"、"N"或"n"之一,该 case 会被识别为 No 选项 - Client 会根据 case 的 name 来匹配用户的 Y/N 输入,其他输入会被要求重新输入
建议使用
"Yes"和"No"作为两个 case 的 name,以保证跨 Client 的一致性。Client 可以使用
cases中的顺序来展示可选项。name
string
选项唯一标识符,用作选项ID。label
string
选项显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。可选。description
string
选项详细描述信息。支持文件路径、URL或直接文本,内容支持Markdown格式。可选。支持国际化(以$开头)。icon
string
选项图标文件路径,相对于项目根目录。可选。支持国际化(以$开头)。option
string[]
子配置项列表。可选。只有当用户选中当前选项时,才会显示这些子配置项。这些子配置项同样放在外层的option中定义,支持无限嵌套。pipeline_override
pipeline
同task中的pipeline_override,在选项激活时生效。
- 如果
inputs
object[]
仅在type为"input"时使用。输入配置,为一个对象数组,定义用户可输入的字段。name
string
输入字段唯一标识符,用作输入字段ID。label
string
输入字段显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。可选。description
string
输入字段详细描述信息,帮助用户理解输入要求。支持文件路径、URL或直接文本,内容支持Markdown格式。可选。支持国际化(以$开头)。default
string
输入字段的默认值。可选。pipeline_type
string
输入字段在 pipeline_override 中的数据类型。可选值:"string","int","bool"。当使用 pipeline_override 中的变量替换时,会根据该类型进行类型转换。verify
string
正则表达式,用于校验用户输入是否合法。可选。pattern_msg
string
正则校验用户输入错误时,显示的信息。可选。支持国际化(以$开头)。
pipeline_override
pipeline
当配置项为"input"类型时使用,作为用户输入内容的替换模板。支持在字符串中使用{名称}格式引用输入字段的值。可选。default_case
string|string[]
默认选项名称。可选。- 当
type为"select"/"switch"时,填写单个字符串,Client 使用该值作为选项的初始选中值。 - 当
type为"checkbox"时,填写字符串数组,Client 使用该值作为多选框的初始选中值。 💡 v2.3.0
- 当
global_option
string[]💡 v2.3.0
可选。全局选项配置,为一个字符串数组,数组元素应与option配置中的键名对应。
该选项生成的参数会参与到所有任务的 pipeline override 中,无论用户选择了什么资源包或控制器。
与resource.option和controller.option不同,全局选项不依赖于任何资源包或控制器的选择。
但global_option引用的 option 仍需满足该 option 自身的resource/controller限制;不满足时不应用任何pipeline_override。 💡 v2.3.1jsonc"global_option": [ "战斗划火柴", "战斗自动闪避" ]import
string[]💡 v2.2.0
可选。导入其他 PI 文件的路径数组。文件相对路径为 interface.json 同目录下的相对路径。
支持导入这些文件中的task、option和preset💡 v2.3.0 字段。
Client 会依次加载这些文件,并将它们的内容与当前文件进行合并,从而实现配置的拆分和复用。preset
object[]💡 v2.3.0
可选。预设配置,为一个对象数组。每个预设是一套预定义的任务勾选状态与选项值的快照,用户可一键应用,快速切换不同使用场景。name
string
唯一标识符,用作预设 ID。label
string
显示名称,用于在用户界面中展示。支持国际化字符串(以$开头)。如果未设置,则显示name字段的值。可选。description
string
预设详细描述信息,帮助用户理解该预设的适用场景。支持文件路径、URL 或直接文本,内容支持 Markdown 格式。可选。支持国际化(以$开头)。icon
string
预设图标文件路径,相对于项目根目录。可选。支持国际化(以$开头)。task
object[]
预设包含的任务配置列表。name
string
必须。与顶层task[].name对应的任务名称。enabled
boolean
可选,默认true。该任务在预设中是否勾选。option
record<string, OptionValue>
可选。该任务各配置项的预设值,键为顶层option中的键名。OptionValue的类型取决于对应option的type:option.type OptionValue 类型 示例 select/switchstring(case.name)"x3"/"Yes"checkboxstring[](case.name数组)["自动战斗", "自动拾取"]inputrecord<string, string>(输入字段 name → 值){ "章节号": "4" }
预设示例:
jsonc"preset": [ { "name": "刷日常", "label": "$刷日常", "description": "每日例行套餐:荒原 + 心相 + 3-9 + 领奖", "icon": "preset_daily.png", "task": [ { "name": "收取荒原", "enabled": true }, { "name": "每日心相(意志解析)", "enabled": true }, { "name": "常规作战", "enabled": true, "option": { "作战关卡": "3-9 厄险(百灵百验鸟)", // select 类型:填 case.name "复现次数": "x3", // select 类型:填 case.name "刷完全部体力": "No", // switch 类型:填 case.name "启用功能": ["自动战斗", "自动拾取"] // checkbox 类型:填 case.name 数组 } }, { "name": "领取奖励", "enabled": true }, { "name": "活动:绿湖噩梦 17 艰难(活动已结束)", "enabled": false } ] }, { "name": "实时辅助", "label": "$实时辅助", "description": "后台挂机辅助,仅执行自动辅助类任务", "task": [ { "name": "常规作战", "enabled": true, "option": { "启用功能": ["自动战斗", "自动拾取", "自动回血"] } } ] } ]通过
import分文件管理预设:预设配置可以通过
import拆分到独立文件中,方便管理和复用。例如:jsonc// interface.json { "import": [ "preset_daily.json", "preset_realtime.json" ], "preset": [ // 也可以在主文件中直接定义预设,会与导入的预设合并 ] }jsonc// preset_daily.json { "preset": [ { "name": "刷日常", "label": "$刷日常", "description": "每日例行套餐", "task": [ { "name": "收取荒原", "enabled": true }, { "name": "领取奖励", "enabled": true } ] } ] }
Option 覆盖顺序 💡 v2.3.0
各级 option 生成的 pipeline_override 会按照以下顺序依次合并,后合并的会覆盖先合并的同名字段:
global_option— 全局选项,最先生效,优先级最低resource.option— 资源包级选项controller.option— 控制器级选项task.option— 任务级选项,最后生效,优先级最高
即:task.option > controller.option > resource.option > global_option。
在进入上述合并顺序前,需先过滤“未激活”的 option。任何不满足当前 controller / resource 条件的 option(包括来自 global_option、resource.option、controller.option、task.option 以及嵌套 option.option)都不得产生 pipeline_override。 💡 v2.3.1
这样设计的理由是:越具体的配置(任务级)应当具有越高的优先级,越通用的配置(全局级)则作为兜底默认值。
示例:
假设 global_option 和某个 task.option 同时引用了同一个 option,且该 option 的某个 case 对同一个 pipeline 节点做了不同的 override,那么任务级的 override 将最终生效。
配置项示例
select 类型选项示例
{
"option": {
"作战关卡": {
"type": "select",
"label": "$选择作战关卡",
"description": "选择要刷的关卡",
"default_case": "3-9 厄险",
"cases": [
{
"name": "3-9 厄险(百灵百验鸟)",
"label": "$3-9厄险",
"description": "刷百灵鸟",
"icon": "百灵鸟.png",
"option": [
"使用理智药",
"刷完xxx"
],
"pipeline_override": {
"EnterTheShow": {
"next": "MainChapter_3"
}
}
}
]
}
}
}input 类型选项示例
{
"option": {
"自定义关卡": {
"type": "input",
"label": "自定义关卡",
"description": "自己选打什么关",
"icon": "扳手.png",
"inputs": [
{
"name": "章节号",
"label": "$章节号",
"description": "关卡章节号,用阿拉伯数字表示",
"default": "4",
"pipeline_type": "string",
"verify": "^\\d+$"
},
{
"name": "超时时间",
"label": "$超时时间",
"description": "等待超时时间",
"default": "20000",
"pipeline_type": "int",
"verify": "^\\d+$"
}
],
"pipeline_override": {
"EnterTheShow": {
"next": "MainChapter_{章节号}",
"timeout": "{超时时间}"
}
}
}
}
}checkbox 类型选项示例 💡 v2.3.0
{
"option": {
"战斗划火柴": {
"type": "checkbox",
"label": "$战斗划火柴",
"description": "选择要启用的划火柴功能,可多选",
"default_case": ["普通划火柴", "蓄力划火柴"],
"cases": [
{
"name": "普通划火柴",
"label": "$普通划火柴",
"description": "启用普通划火柴",
"pipeline_override": {
"NormalMatch": {
"enabled": true
}
}
},
{
"name": "蓄力划火柴",
"label": "$蓄力划火柴",
"description": "启用蓄力划火柴",
"pipeline_override": {
"ChargedMatch": {
"enabled": true
}
}
},
{
"name": "连续划火柴",
"label": "$连续划火柴",
"description": "启用连续划火柴",
"pipeline_override": {
"ComboMatch": {
"enabled": true
}
}
}
]
}
}
}注意: checkbox 类型中,多个被选中 case 的
pipeline_override按照cases数组中的定义顺序依次合并,与用户勾选的先后顺序无关。
国际化支持
对于所有支持国际化的字符串字段,如果字符串以 $ 开头,则表示该字符串是国际化字符串,Client 需要从翻译文件中读取实际值再显示。
例如:
{
"name": "MyDemo3",
"label": "$MyDemo3",
"controller": [
{
"name": "Android",
"label": "$安卓端"
}
]
}对应的翻译文件(如 interface_zh.json):
{
"MyDemo3": "我的演示3",
"安卓端": "安卓设备"
}资源覆盖
后加载的资源中如果发现了和已加载资源同名的任务,会对任务进行合并。通常情况下,可以认为新的任务的顶级键会替换旧任务的。例如:
旧任务
{
"task1": {
"enabled": false,
"recognition": "DirectHit",
"next": [ "T1", "T2" ]
}
}新任务
{
"task1": {
"enabled": true,
"action": "Click",
"next": [ "T2", "T3" ]
}
}合并后的任务
{
"task1": {
"enabled": true,
"recognition": "DirectHit",
"action": "Click",
"next": [ "T2", "T3" ] // 直接替换,内部不会合并
}
}节点通知处理
MaaFramework 在任务执行过程中会通过回调函数发送节点通知,Client 需要实现相应的处理逻辑,以便向用户展示任务执行状态。
回调函数签名
Client 需要注册一个回调函数来接收通知,函数签名参考 MaaDef.h:
typedef void(MAA_CALL* MaaEventCallback)(
void* handle,
const char* message,
const char* details_json,
void* trans_arg
);- message: 消息类型标识(如
Node.Action.Starting、Node.Recognition.Succeeded等) - details_json: 包含具体数据的 JSON 字符串
消息模板机制
资源作者可以在 Pipeline 中通过 focus 字段配置消息模板。focus 是一个字典,键为消息类型,值为模板字符串或模板对象。模板字符串支持文件路径、URL 或直接文本,内容支持 Markdown 格式,支持国际化(以$开头)。Client 收到回调后,应根据模板进行占位符替换并按指定方式展示给用户。
focus 值的两种写法
简写(纯字符串): 等价于 display: "log",内容仅展示在运行日志中。
"focus": {
"Node.Action.Starting": "{name} 开始执行"
}完整写法(对象): 可通过 display 字段指定展示渠道。 💡 v2.3.0
"focus": {
"Node.Action.Starting": {
"content": "{name} 开始执行",
"display": "toast"
}
}display 可选值 💡 v2.3.0
| 值 | 说明 | 行为特征 |
|---|---|---|
"log" | 运行日志(默认) | 追加到日志流,不打断操作 |
"toast" | 应用内轻提示 | 短暂浮现后自动消失,不阻塞 |
"notification" | 系统级通知 | 推送到 OS 通知中心,应用在后台时也可收到 |
"dialog" | 非阻塞式对话框 | 弹出信息框,任务流水线在后台继续执行 |
"modal" | 阻塞式弹窗 | 弹出后任务暂停等待用户确认,适合需要人工干预的场景 |
display 支持数组,同一条消息可同时推送到多个渠道:
"focus": {
"Node.Action.Succeeded": {
"content": "✅ {name} 执行成功",
"display": ["log", "toast"]
},
"Node.Action.Failed": {
"content": "❌ 执行失败,请检查环境",
"display": ["log", "modal"]
}
}Pipeline 中的完整配置示例:
{
"NodeA": {
"focus": {
"Node.Recognition.Succeeded": "{name} 识别命中,准备开始执行",
"Node.Action.Starting": {
"content": "{name} 开始执行,任务 ID: {task_id}",
"display": ["log", "toast"]
},
"Node.Action.Failed": {
"content": "{name} 执行失败",
"display": "modal"
}
}
}
}回调函数收到的参数示例:
// message 参数:
"Node.Action.Starting"
// details_json 参数(解析后):
{
"task_id": 12345,
"action_id": 11111,
"name": "NodeA",
"focus": {
"Node.Recognition.Succeeded": "{name} 识别命中,准备开始执行",
"Node.Action.Starting": {
"content": "{name} 开始执行,任务 ID: {task_id}",
"display": ["log", "toast"]
},
"Node.Action.Failed": {
"content": "{name} 执行失败",
"display": "modal"
}
}
}Client 处理流程
- 在回调函数中解析
details_json参数 - 检查解析后的对象中是否存在
focus字段 - 若存在,根据
message参数在focus中查找对应的模板(字符串或对象) - 若模板为字符串,则
content即为该字符串,display视为["log"];若为对象,则分别读取content和display - 使用
details_json中的数据替换content中的占位符(如{name}、{task_id}) - 根据
display指定的渠道(可多个)将处理后的文本展示给用户 💡 v2.3.0
以上述示例为例,收到 Node.Action.Starting 时,应在日志中追加并弹出 toast:NodeA 开始执行,任务 ID: 12345
