@joebao/maa-pipeline-generate
v1.2.2
Published
Batch-generate MAA pipeline JSON from templates and data (CLI + browser GUI).
Readme
MAA Pipeline Generate
English | 中文
基于模板和数据源批量生成 MAA pipeline JSON,适用于需要大批量制作、仅有细微差异的 pipeline 场景。
图形界面(推荐)
不想用命令行时,使用 本机浏览器 + 小型 HTTP 服务(无需 Electron):
- 在本仓库 Releases 中查找以
maa-generate-v*发布的版本。 - 下载对应平台的 便携 zip(文件名形如
maa-pipeline-generate-x.x.x-win-x64.zip/darwin-arm64/linux-x64),解压到任意目录;zip 内为单层文件夹(与 zip 同名、无扩展名),请进入该文件夹后再运行下方脚本。 - 需已安装 Node.js(与 zip 同平台
node_modules一致):在上述文件夹内双击start.bat(Windows)或执行chmod +x start.sh && ./start.sh(macOS / Linux)。脚本会启动node server.mjs,并自动打开系统浏览器访问本机页面(默认http://127.0.0.1:48765/)。 - 在网页中选择模板、数据文件,填写输出目录等选项后点击生成。结束服务:在运行窗口按 Ctrl+C。
可选:自带 Node 的绿色包(解压即可用,无需全局 Node):在已安装 Node 的机器上进入解压后的程序文件夹(zip 内的那一层目录),执行:
node scripts/download-portable-node.mjs win-x64 # 或 linux-x64 / darwin-x64 / darwin-arm64将把官方便携 Node 解压到目录下的 node/,之后 start.bat / start.sh 会优先使用 node\node.exe 或 node/bin/node。
npm / npx(需本机已装 Node)
与便携 zip 二选一即可;包名为 @joebao/maa-pipeline-generate(发布前请确认 npm 作用域与账号一致)。
- 全局安装:
npm i -g @joebao/maa-pipeline-generate- 命令行生成:
maa-pipeline-generate --help - 打开浏览器 GUI:
maa-pipeline-generate-gui(可加--no-open仅监听端口不自动开浏览器)
- 命令行生成:
- 临时运行(不全局安装)(多
bin时需指定命令名):npx -p @joebao/maa-pipeline-generate maa-pipeline-generate -- --helpnpx -p @joebao/maa-pipeline-generate maa-pipeline-generate-gui
首次发布:在包目录执行 npm login 后 npm publish(已配置 publishConfig.access: public)。
若仓库 Release 命名或链接与上述不一致,请以实际仓库的 Tags / Releases 为准。
Release 与自动构建
在本工具 独立仓库 推送 Git tag maa-generate-v主版本号(例如 maa-generate-v1.0.0)会触发 GitHub Actions(本仓库根目录下 .github/workflows/maa-pipeline-generate-release.yml),在 Windows / macOS / Linux 上分别 npm ci --omit=dev 并打 便携 zip(含生产依赖 node_modules),上传到 同一 Tag 的 GitHub Release。此工作流属于本仓库,不挂在 VS Code 扩展(maa-support-extension)主仓库上。
手动触发:在本仓库 Actions 中选择 MAA Pipeline Generate (Portable zip),使用 Run workflow(仅生成 Artifact,不创建 Release)。
特性
- 模板驱动:用
${Var}占位符编写模板,自动填充数据 - 类型感知:
"${Var}"作为整值时自动替换为数组、对象等原始类型 - 注释保留:模板中的
//和/* */注释会保留到输出文件 - 可选语义校验:需要时在生成后用
@nekosu/maa-pipeline-manager的parseTask对输出做诊断(CLI--semantic-check、configsemanticCheck或 Web 勾选项,默认不启用) - 独立文件输出:每条数据生成独立文件,文件名支持变量(如
${Id}.json) - 支持 JSON / JSONC(含注释和尾逗号)
- 输出 JSON 会自动格式化:所有
[...]数组都会强制换行输出,不会生成同一行内联数组 - AutoCollect 路线生成:从结构化参数一键生成完整的自动采集路线 pipeline,支持 MapNavigate / MapTracker 两种导航模式
- Task 增量批量生成:独立命令把 task 片段批量合并进单个目标文件,适合
SellProduct.json这类高重复结构 - 浏览器 GUI:
server.mjs提供静态页与/api/generate,与 CLI 共用lib/runGenerate.mjs;GUI 内含"模板生成"和"AutoCollect 路线"两个标签页
快速开始(命令行)
# 安装依赖
npm install
# 运行(使用默认的 template.jsonc + data.json)
node generate.mjs
# 或
npm run generate
# task 增量批量模式(独立命令,层级可读的 jsonc 模板)
node generate-task.mjs --template ./examples/task/template.smart.jsonc --data ./examples/task/data.smart.mjs
# 或
npm run generate:task -- --template ./examples/task/template.smart.jsonc --data ./examples/task/data.smart.mjs生成结果在 output/ 目录下。
config.json(可选)
默认情况下,程序会读取当前工作目录下的 config.json;如果不存在,则使用 npm 包内置的 config.json。你可以用它控制模板/数据/输出目录,以及输出行为:
template、data:模板与数据路径(pipeline / task 通用)outputDir:输出目录(pipeline / task 通用,默认output/)outputFile:单文件输出名(pipeline merged / task 通用;pipeline 默认pipeline.json)- task 与共用 config:数据源里的
target/outputFile(以及 CLI--target/--output-file)优先于config.json的outputFile,避免与 pipeline 共用同一config.json时把任务结果误写到pipeline.json outputPattern:pipeline 非 merged 时的逐条文件名模式(如${Id}.json)merged:pipeline 是否合并为单文件(true时输出outputDir/outputFile)task/taskGenerate/generateTask(与generate.mjs):在config.json中设task: true(或taskGenerate/generateTask)时,直接运行node generate.mjs即走 task 生成(等价于generate-task.mjs);若只生成 pipeline 则不要写这些字段,或设pipeline: true/task: falseformat:默认true(会把[...]数组强制为多行,不生成同一行内联数组)- 兼容旧字段:task 模式仍读取
taskTemplate/taskData/taskTarget/target - 数值保真:当模板中使用
"${Var}"作为整值占位符时,来自data.json的数字字面(例如5.0)会保持原样,不会被折叠成5
若要指定自定义配置文件:
node generate.mjs --config ./config.json本地快速验证
- 默认运行:
node generate.mjs - 检查数组格式:确认输出里的
expected/next/roi/...等数组不再出现在同一行内联[...] - 检查
5.0保真:把你的data.json中某个数字改成5.0(或类似带小数结尾的数),再运行,确认输出中仍显示5.0(尤其是当占位符以"${Var}"作为整值替换时)
从源码运行 GUI
npm install
npm run start:gui不自动打开浏览器(例如在无图形界面环境):
npm run start:gui:no-open
# 或
node server.mjs --no-open文件说明
| 文件 / 目录 | 作用 |
|-------------|------|
| generate.mjs | 命令行入口(模板生成 + --auto-collect 路线生成) |
| generate-task.mjs | task 增量批量模式命令行入口 |
| lib/runGenerate.mjs | 模板生成核心(CLI 与浏览器 GUI 共用) |
| lib/generateAutoCollect.mjs | AutoCollect 路线生成核心 |
| lib/runTaskGenerate.mjs | task 增量批量生成核心(按 key 覆盖合并) |
| server.mjs | 本机 HTTP 服务 + 自动打开浏览器 |
| public/ | 浏览器界面(HTML / CSS / JS) |
| start.bat / start.sh | 一键启动(优先使用目录内便携 node/) |
| scripts/download-portable-node.mjs | 可选:下载官方便携 Node 到 node/ |
| template.jsonc | 模板文件,用 ${Var} 作为占位符 |
| data.json | 数据源,包含每条数据的变量值 |
| examples/pipeline/ | pipeline 示例模板与示例数据(统一示例入口) |
| examples/task/ | task 智能模板与示例数据(统一示例入口) |
| output/ | 生成结果输出目录 |
| .maa-gen-tmp/ | 浏览器生成时的临时文件目录(自动创建,已 gitignore) |
AutoCollect 路线生成
针对 MaaEnd 自动采集场景,从结构化参数直接生成完整的路线 pipeline JSON(无需编写模板)。支持 MapNavigate(地图导航)和 MapTracker(路径追踪)两种导航模式。
输入参数
必填参数
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| Map_way | string | 导航方式 | "MapNavigate" 或 "MapTracker" |
| route_id | number | 路线编号,用于生成节点名前缀和文件名 | 4 |
| teleport_name | string | 传送点名称(万能跳转) | "WulingWulingCity5" |
| map_name | string | 地图名 | "map02_lv002" |
| zone_id | string | 导航区域 ID(MapNavigate 必填) | "Wuling_Base" |
| assert_target | [x, y] | 传送落点校验坐标,自动补成 [x-10, y-10, 20, 20] | [663, 733] |
| initial_path | array | 从传送点到第一个采集点的完整导航路径 | [[654, 723], [656, 723], [645, 650, true]] |
| collect_points | array | 后续采集点坐标列表 | [[647, 648], [647, 646], [643, 642]] |
可选参数
| 参数名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| collect_action_entry | string | "AutoCollectClickStart" | 每个采集点执行后的跳转入口 |
命令行用法
准备一个 JSON 参数文件(如 route_input.json):
{
"Map_way": "MapNavigate",
"route_id": 1,
"teleport_name": "WulingWulingCity5",
"map_name": "map02_lv002",
"zone_id": "Wuling_Base",
"assert_target": [663, 733],
"initial_path": [
[654, 723],
[656, 723],
[645, 650, true]
],
"collect_points": [
[647, 648],
[647, 646],
[643, 642]
]
}运行:
node generate.mjs --auto-collect route_input.json
node generate.mjs --auto-collect route_input.json --output-dir ./pipeline生成的文件名为 AutoCollectRoute{route_id}.json(如 AutoCollectRoute1.json)。
浏览器 GUI 用法
启动 GUI 后,点击顶部的 "AutoCollect 路线" 标签页,填写各参数后点击 "生成路线 Pipeline"。生成结果会在预览区域显示,同时写入输出目录。
生成结果说明
以 route_id = 1、3 个采集点为例,生成的 pipeline 包含以下节点:
| 节点名 | 作用 |
|--------|------|
| AutoCollectRoute1Start | 入口节点,跳转到位置校验和传送 |
| AutoCollectRoute1End | 路线结束节点 |
| AutoCollectRoute1AssertLocation | 校验传送落点坐标 |
| AutoCollectRoute1GotoFind1 | 沿 initial_path 前往第一个采集点 |
| AutoCollectRoute1GotoFind2 | 前往第二个采集点 |
| AutoCollectRoute1GotoFind3 | 前往第三个采集点 |
| AutoCollectRoute1GotoFind4 | 前往第四个采集点(最后一个,链接到 End) |
两种导航模式的区别
| 方面 | MapNavigate | MapTracker |
|------|-------------|------------|
| 自定义动作 | MapNavigateAction | MapTrackerMove |
| 路径前缀 | 每段 path 首元素为 { "action": "ZONE", "zone_id": "..." } | 无 |
| 额外参数 | 无 | "fine_approach": "AllTargets" |
| zone_id | 必填 | 不需要 |
MapTracker 示例
{
"Map_way": "MapTracker",
"route_id": 4,
"teleport_name": "WulingWulingCity2",
"map_name": "map02_lv002",
"assert_target": [632, 535],
"initial_path": [
[635.0, 537.0],
[630.0, 533.3],
[586.3, 533.2],
[532.5, 472.0]
],
"collect_points": [
[530.1, 465.7],
[528.8, 469.6],
[523.8, 473.1]
]
}Task 增量批量生成
适合 SellProduct.json 这种在同一文件内大量重复、只需要增量维护局部片段的场景。
task 生成与 pipeline 使用统一配置体系;多条数据合并固定为深度增量(旧式浅合并已移除)。
命令行用法
# 位置参数
node generate-task.mjs task_template.jsonc task_data.jsonc target_task.json
# 或显式参数
node generate-task.mjs --template task_template.jsonc --data task_data.jsonc --output-dir output --output-file task.json全部选项
node generate-task.mjs [模板文件] [数据文件] [目标文件] [选项]
位置参数:
第一个参数 task 模板文件路径
第二个参数 task 数据源文件路径
第三个参数 目标 task 文件路径
选项:
--template <path> task 模板文件路径
--data <path> task 数据源文件路径
--output-dir <path> 输出目录(默认: output/)
--output-file <name> 输出文件名(推荐,与 pipeline 保持一致)
--target <path> 旧字段别名:完整目标路径(兼容)
--config <path> 配置文件路径(支持 outputDir/outputFile,也兼容 task* 与 target)
--no-format 关闭输出格式化
--dry-run 仅计算与预览,不写入目标文件
--help 显示帮助信息数据源格式
.json/.jsonc:数组[{...}],或对象{ "outputFile": "...", "data": [...] }.mjs:export default [...]或export const data = [...]- 单条数据可设置
"enabled": false(或"Enabled": false)跳过生成
模板格式
.json/.jsonc:占位符模板(${Var}),适合展示清晰层级结构(推荐 task 场景).mjs:代码模板,导出default/render/buildTaskFragment- 签名:
(entry, helpers) => ({ task, option }) - 适合
SellProduct这类高重复结构(可在模板中用循环和函数生成)
- 签名:
合并规则(固定深度增量)
task数组:按task.name合并,option/group字符串数组自动去重追加option对象:按option[key]深度合并(同 key 递归覆盖+续写)- 对象数组(如
cases):按name主键合并;同名递归合并,不同名追加
示例(统一结构)
- pipeline 示例模板:
examples/pipeline/template.default.jsonc - pipeline 示例数据:
examples/pipeline/data.default.json - task 智能模板:
examples/task/template.smart.jsonc - task 智能数据:
examples/task/data.smart.mjs - 运行:
node generate-task.mjs --template ./examples/task/template.smart.jsonc --data ./examples/task/data.smart.mjs据点交易表(settlement_trade_outposts.json)经中间层 data.mjs 加工后,有两种接法:
- smart 模板:
task-data.settlement.mjs→examples/task/template.smart.jsonc,输出默认SellProduct.from-settlement.json - 根目录
task-template.jsonc(ItemCases*为整段数组):task-data.flat-settlement.mjs,输出SellProduct.task-template.json
node generate-task.mjs --template ./task-template.jsonc --data ./task-data.flat-settlement.mjsconfig.json 示例(据点 → task-template 成品):复制仓库内 config.task-settlement.example.json 为当前目录的 config.json,或:
{
"task": true,
"template": "task-template.jsonc",
"data": "task-data.flat-settlement.mjs",
"outputDir": "output",
"format": true
}然后执行 node generate.mjs 即可(与上面一条 generate-task 等价)。输出文件名默认以 task-data.flat-settlement.mjs 里 export const config 的 outputFile 为准(当前为 SellProduct.task-template.json);若与根 config.json 的 outputFile 同时存在,数据文件里的优先。
与成品结构对齐:仓库里若有一份参考成品(例如 SellProduct copy.json),其形态应为「静态 task + 静态大区开关 + 每条据点数据展开出的 ${RegionPrefix}${LocationId} / Attempt / Item 节点」。现有语法已足够:settlement_trade_outposts.json → data.mjs(SETTLEMENT_MAP、ITEM_META、buildItemCases)→ 多行 default 数据 → task-template.jsonc 占位符替换 → runTaskGenerate 深度合并为单文件。换游戏表时主要改 data.mjs(映射与物品表);task-template.jsonc 仅在任务层级结构变化时改。
这个示例会保留 Region -> Location -> Attempt -> Item 层级在 template 中:
- 区域开关
- 点位开关
- Attempt1~4
- Item1~4 的 select cases(含
pipeline_override.expected)
分层建议(已在示例中实践):
template.smart.jsonc:保留可读层级结构(让人一眼看出生成后的结构)data.smart.mjs:放业务数据与重复数据展开(locations、items、expected 等)- 当业务文本/物品池更新时,优先改
data.smart.mjs;当层级结构变更时再改 template
模板编写
模板是一个标准的 JSONC 文件,在键名和值中使用 ${变量名} 作为占位符:
{
// 任务入口
"${Id}Job": {
"desc": "${Name}任务",
"recognition": "And",
"all_of": ["Check${Id}Text"],
"next": ["Accept${Id}"]
},
"Check${Id}Text": {
"desc": "检查是否有${Name}文本",
"recognition": "OCR",
"expected": "${ExpectedText}", // 整值替换 → 自动变成数组
"order_by": "Expected"
}
}替换规则
| 模板写法 | 数据 | 输出 |
|----------|------|------|
| "${Id}Job" | "Id": "AncientTree" | "AncientTreeJob" |
| "${Name}任务" | "Name": "古树" | "古树任务" |
| "${ExpectedText}" | "ExpectedText": ["古树", "Ancient Tree"] | ["古树", "Ancient Tree"] |
| "${MapTarget}" | "MapTarget": [280, 580, 15, 15] | [280, 580, 15, 15] |
关键: 当 "${Var}" 是唯一值(整个引号内只有占位符)时,会被替换为数据中的原始类型(数组、对象、数字等),而不是字符串。
注释
模板中的注释会原样保留到输出文件中:
{
// 这个注释会出现在每个生成的文件中
"${Id}Job": { ... }
}数据源
格式一:纯 JSON 数组
[
{
"Id": "AncientTree",
"Name": "古树",
"ExpectedText": ["古树", "Ancient Tree"]
},
{
"Id": "EternalSunset",
"Name": "栖霞驻影",
"ExpectedText": ["栖霞驻影", "Eternal Sunset"]
}
]格式二:带配置的 JSON 对象
{
"outputPattern": "${Id}.json",
"outputDir": "output",
"data": [
{ "Id": "AncientTree", "Name": "古树", ... },
{ "Id": "EternalSunset", "Name": "栖霞驻影", ... }
]
}支持的配置字段:
| 字段 | 说明 | 默认值 |
|------|------|--------|
| outputPattern | 输出文件名模式,支持 ${Var} | 合并为 pipeline.json |
| outputDir | 输出目录 | output |
格式三:JS 模块(.mjs)
export default [
{ Id: "AncientTree", Name: "古树", ExpectedText: ["古树", "Ancient Tree"] }
]命令行
# 基本用法
node generate.mjs
# 指定模板和数据文件(位置参数)
node generate.mjs my_template.jsonc my_data.json
# 指定参数
node generate.mjs --template my_template.jsonc --data my_data.json
# 合并输出为单文件
node generate.mjs --merged --output-file merged-pipeline.json
# 指定输出目录
node generate.mjs --output-dir ./pipeline
# 与 config 中 task: true 等价:一条命令走 task 生成(无需单独运行 generate-task)
node generate.mjs --task --template task-template.jsonc --data task-data.sample.jsonc全部选项
node generate.mjs [模板文件] [数据文件] [选项]
位置参数:
第一个参数 模板文件路径
第二个参数 数据源文件路径
选项:
--template <path> 模板文件路径
--data <path> 数据源文件路径
--output-dir <path> 输出目录 (默认: output/)
--output-pattern <pat> 输出文件名模式
--output-file <name> 合并输出文件名 (仅 --merged 生效,默认: pipeline.json)
--task 强制走 task 生成(runTaskGenerate);也可在 config 中写 task: true
--merged 合并输出为单个文件(默认 pipeline.json)
--semantic-check 生成后做 MAA 语义/引用诊断(默认关闭;也可在 config 或 data 根设 `semanticCheck: true`)
--auto-collect <path> 从 JSON 参数文件生成 AutoCollect 路线 pipeline
--help 显示帮助信息语义校验(可选)
在启用时(见上)会对输出进行 MAA pipeline 语义校验,报告:
- 未指定 recognition 类型的任务
- 引用了未定义任务的 next / target / reco
这些是警告而非错误,因为被引用的任务可能定义在项目的其他文件中。
输出示例
运行后输出:
[generate] 共 8 条数据,开始生成...
→ AncientTree.json (14 个任务节点)
→ BeaconDamagedInBlightTide.json (14 个任务节点)
→ CisternOriginiumSlugs.json (14 个任务节点)
...
[generate] 完成! 共生成 112 个任务节点,56 个诊断问题