Project Interface V2 协议
注意: 本文档是关于
ProjectInterface的编写和使用文中将使用 PI 代指
ProjectInterface,Client 代指可以处理 PI 的工具
简介
所谓 ProjectInterface,即 MaaFramework 的一个标准化的项目结构声明,该声明目前包含 interface.json 一个文件。通过定义 PI,你可以使用 MaaFramework 的各种衍生工具。因此,即使你打算纯粹依靠通用编程语言集成,也建议定义包含基础信息的 PI。
UI 支持
- MFAAvalonia
- MaaPiCli
- MFW-CFA
interface.json
该文件可以通过 schema 文件获得提示和校验功能
使用 VSCode 打开 项目模板 文件夹,可自动关联 schema 和文件
整体结构
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
stringMirrorChyan 资源包标识符,用于资源管理和分发。
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'控制器类型,取值为
Adb和Win32。display_short_side
number默认缩放分辨率的短边长度,用于屏幕适配。可选,默认720。与
display_long_side和display_raw互斥。display_long_side
number默认缩放分辨率的长边长度,用于屏幕适配。可选。与
display_short_side和display_raw互斥。display_raw
boolean是否使用原始分辨率进行截图,不进行缩放。可选,默认false。与缩放分辨率设置互斥。
adb
objectAdb控制器的具体配置。注意: V2 协议中。Adb 控制器的 input/screencap 由 MaaFramework 自动检测和选择最优方式,无需手动配置。
win32
objectWin32控制器的具体配置。
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字段对应。若不指定,则表示支持所有控制器类型。当用户选择了某个控制器时,只有支持该控制器的资源包才会显示在用户界面中供选择。这允许为不同控制器类型提供专门优化的资源包。
jsonc"resource": [ { "name": "Android专用资源", "label": "$Android专用资源", "controller": ["Android"], "path": ["resource_android"] }, { "name": "通用资源", "label": "$通用资源", "path": ["resource"] } ]
agent
object代理配置,为一个对象,含有子进程(AgentServer)的信息。
child_exec
string子进程路径,为系统路径中可执行文件。如在环境变量(系统变量、用户变量)中存在 Python 路径,可直接写
"python"。
CWD 为 interface.json 所在目录。child_args
string[]可选。子进程参数数组。
jsonc"agent": { "child_exec": "python", "child_args": [ "./agent/main.py", // 注意 cwd 为 interface.json 所在目录 "--test-mode" // 固定字符串,原样传递 ] }identifier
string可选。连接标识符,被用来创建一个通信套接字。填写则会被使用,否则自动创建。
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字段对应。若不指定,则表示该任务在所有资源包中都可用。当用户选择了某个资源包时,只有支持该资源包的任务才会显示在用户界面中供选择。这允许为不同资源包提供专门的任务配置,比如活动任务只在特定资源包中可用。
jsonc"task": [ { "name": "活动任务", "label": "$活动任务", "entry": "ActivityTask", "resource": ["Official"], "description": "仅在官服资源包中可用的活动任务" }, { "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": 下拉选项框,用户从预定义的选项中选择"input": 用户输入框,允许用户手动输入内容"switch": 选择框,Yes or No
label
string配置项显示标签,用于在用户界面中展示。支持国际化字符串(以
$开头)。可选。description
string配置项详细描述信息,帮助用户理解配置项的作用。支持文件路径、URL或直接文本,内容支持Markdown格式。可选。支持国际化(以
$开头)。icon
string配置项图标文件路径,相对于项目根目录。可选。支持国际化(以
$开头)。cases
object[]仅在
type为"select"/"switch"时使用。可选项,为一个对象数组,含有各个可选项的信息。注意: 当
type为"switch"时,仅支持两个 cases,且需遵循以下规则:- 如果
case.name为"Yes"、"yes"、"Y"或"y"之一,该 case 会被识别为 Yes 选项 - 其他
case.name会被识别为 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默认选项名称,仅在
type为"select"时使用。Client 可以使用该值作为选项的初始选中值。可选。
配置项示例
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": "{超时时间}"
}
}
}
}
}国际化支持
对于所有支持国际化的字符串字段,如果字符串以 $ 开头,则表示该字符串是国际化字符串,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 字段配置消息模板。Client 收到回调后,应根据模板进行占位符替换并展示给用户。
Pipeline 中的配置示例:
{
"NodeA": {
"focus": {
"Node.Recognition.Succeeded": "{name} 识别命中,准备开始执行",
"Node.Action.Starting": "{name} 开始执行,任务 ID: {task_id}"
}
}
}回调函数收到的参数示例:
// message 参数:
"Node.Action.Starting"
// details_json 参数(解析后):
{
"task_id": 12345,
"action_id": 11111,
"name": "NodeA",
"focus": {
"Node.Recognition.Succeeded": "{name} 识别命中,准备开始执行",
"Node.Action.Starting": "{name} 开始执行,任务 ID: {task_id}"
}
}Client 处理流程
- 在回调函数中解析
details_json参数 - 检查解析后的对象中是否存在
focus字段 - 若存在,根据
message参数在focus中查找对应的模板字符串 - 使用
details_json中的数据替换模板中的占位符(如{name}、{task_id}) - 将处理后的文本展示给用户
以上述示例为例,最终应展示:NodeA 开始执行,任务 ID: 12345
