Files
MaaAssistantArknights/docs/zh-tw/protocol/task-schema.md
Lucien Shaw e461208bf9 chore: 完善容器配置及依赖安装 (#14208)
格式化工具部分:
1. pre-commit 引入 python 的格式化工具,包括 black(代码格式化)和 isort(对“包导入顺序”的规范)
2. 允许 prettier 对文档站的 markdown 文件格式化
3. 不允许 prettier 对 markdown 文件中的代码块的代码本身进行格式化
4. 升级了 pre-commit 的各个 hook 的版本
5. 优化了 pre-commit 的日志文本显示

容器总览部分:
1. 由原来的单一轻量环境转为区分空环境、轻量环境和全量环境
2. 空环境是裸 Linux 镜像(Ubuntu),为默认环境
3. 轻量环境适合开发文档站前端
4. 全量环境适合开发 MaaCore
5. 目前,全量环境完整包含了轻量环境,轻量环境完整包含了空环境
6. 在仓库 README.md 中更新了三个环境的描述,并将链接分别设置为对应环境的创建链接
   **注意:没有修改文档站中的对应文件**
7. 在各个语言的开发指南的最后,移除了 Codespace 部分的“安装额外依赖”相关描述,且将链接设置为全量环境的创建链接
   **注意:没有添加“开发文档站”的指南和对应 codespace 的使用方式**

容器的轻量环境和全量环境共有部分:
1. 安装 black 和 isort 包
2. 调整 VS Code 设置,取消先前(对 markdown 文件单独指定 markdownlint 扩展作为格式化工具)的错误设置,现在 markdown 文件仍然使用默认的 prettier 扩展作为格式化工具
3. 引入 markdown-all-in-one 扩展作为语法提示工具
4. 将 node_modules 和 3rdparty 排除在 VS Code 的文本的搜索路径之外

容器的全量环境部分:
1. 为 tools 下的所有 python 脚本安装依赖
2. 使用 tools/maadeps-download.py 下载 maadeps,且将必要二进制文件软链接到 /usr/local/bin/
3. 使用 apt 安装 cmake 和 clangd-20,将后者通过 update-alternatives 设置为系统 clangd 的默认版本
4. 使用 cmake tools 扩展,并按照 Linux 编译方法进行配置
5. 使用 clang-format 作为 c/cpp 的格式化工具,clang-format 程序主体来自 maadeps(已经软链接到 /usr/local/bin/)
6. 使用 clangd 作为 c/cpp 的语法提示工具
7. 将 MaaDeps、install 和 build 排除在 VS Code 的文本搜索路径之外

其它手动调整:
1. 更新文档站的 package.json,指定 pnpm 包管理器的版本
2. 手动保证 markdown 文件中的列表前后有空行(注意到 MarkdownLint 官方规则不一定能精准定位所有“列表前后空行”的问题,详见:https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md032---lists-should-be-surrounded-by-blank-lines )
3. 修改了部分 markdown 文件中的 json 代码块的语法问题
   **注意:相同的问题并未全部发现,仅修改了两处**
4. 在 tools 目录中,一处 python 脚本的包名误用(本地包名和某个 pip 包重名),这里修改了相应代码
5. 在 tools 目录中,一处 python 脚本使用了弃用的包 cchardet 的问题,这里更换了推荐使用的功能相近的包并修改了相应代码

自动化脚本提交的修改:
1. 自动格式化了大量 tools 中的 python 脚本
2. 自动格式化了大量 docs 中的 markdown 文件

Commits:

* chore: pre-commit引入black和isort规范py文件

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: devcontainer添加isort扩展,排序python导入

* chore: pre-commit任务命名及更名

* style: isort fix

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: 更新pre-commit的hook版本

* fix: 模块名与第三方库重名,大忌

* chore: 容器构建时额外安装isort

* docs: md -> markdown

* chore: 容器安装python包和maadeps

* fix: 修复过时python包

* chore: 指定pnpm版本

* chore: container支持选择轻量环境

* chore: 去掉rust

* chore: add plain env

* chore: 使用clangd语言服务器

* chore: 无需单独设置markdown的格式化工具

* chore: 更新安装的clangd版本

* docs: 简易文档适配

* docs: 在仓库README中重新编排codespaces相关指引

* chore: Auto update by pre-commit hooks [skip changelog]

* style: 调整缩进

* chore: 格式化工具不用特意排除被gitignore忽略的文件

* chore: sh文件在gitattributes中单列一类

* chore: 格式化docs下的markdown文件

* chore: 暂时不修改md文件中的代码块

* style: 人为明确markdown中的部分列表相关格式

* docs: 补上部分markdown的json代码块中缺失的逗号

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 补上tools的服务器排序相关代码中缺失的逗号

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: 使用maadeps的clangd

* build: 更新maadeps工具链版本

* style: prettier fix

* revert: 还原maadeps版本

* revert: 取消使用maadeps的clangd依赖,改用系统apt安装

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-30 19:39:48 +08:00

20 KiB
Raw Blame History

order, icon
order icon
4 material-symbols:task

任務流程協議

resource/tasks 的使用方法及各欄位說明

::: tip 推薦使用 Visual Studio Code 並安裝 Maa Pipeline Support 擴展以實現高效編輯,詳情請查閱擴展首頁和文件 :::

::: warning JSON 文件是不支持注釋的,文本中的注釋僅用於示範,請勿直接複製使用 :::

完整欄位一覽

{
    "TaskName" : {                          // 任務名

        "baseTask": "xxx",                  // 以 xxx 任務為範本產生任務,詳細見下方特殊任務類型中的 Base Task

        "algorithm": "MatchTemplate",       // 可選項,表示辨識演算法的類型
                                            // 不填寫時預設為 MatchTemplate
                                            //      - JustReturn:       不進行辨識,直接執行 action
                                            //      - MatchTemplate:    匹配圖片
                                            //      - OcrDetect:        文字辨識
                                            //      - Hash:             哈希計算

        "action": "ClickSelf",              // 可選項,表示辨識到後的動作
                                            // 不填寫時預設為 DoNothing
                                            //      - ClickSelf:        點擊辨識到的位置(辨識到的目標範圍內隨機點)
                                            //      - ClickRand:        點擊整個畫面中隨機位置
                                            //      - ClickRect:        點擊指定的區域,對應 specificRect 欄位,不建議使用該選項
                                            //      - DoNothing:        什麼都不做
                                            //      - Stop:             停止目前任務
                                            //      - Swipe:            滑動,對應 specificRect 與 rectMove 欄位

        "sub": [ "SubTaskName1", "SubTaskName2" ],
                                            // 可選項,子任務。會在執行完目前任務後,依次執行每一個子任務
                                            // 可以套娃,子任務再套子任務。但要注意不要寫出了死迴圈

        "subErrorIgnored": true,            // 可選項,是否忽略子任務的錯誤。
                                            // 不填寫預設 false
                                            // 為 false 時,若某個子任務出錯,則不繼續執行後續任務(相當於本任務出錯了)
                                            // 為 true 時,子任務是否出錯沒有影響

        "next": [ "OtherTaskName1", "OtherTaskName2" ],
                                            // 可選項,表示執行完目前任務和 sub 任務後,下一個要執行的任務
                                            // 會從前往後依次去辨識,去執行第一個匹配上的
                                            // 不填寫預設執行完目前任務直接停止
                                            // 對於相同任務,第一次辨識後第二次就不再辨識:
                                            //     "next": [ "A", "B", "A", "A" ] -> "next": [ "A", "B" ]
                                            // 不允許 JustReturn 型任務位於非最後一項

        "maxTimes": 10,                     // 可選項,表示該任務最大執行次數
                                            // 不填寫時預設無限大
                                            // 達到最大次數後,若存在 exceededNext 欄位,則執行 exceededNext否則直接任務停止

        "exceededNext": [ "OtherTaskName1", "OtherTaskName2" ],
                                            // 可選項,表示達到了最大執行次數後要執行的任務
                                            // 不填寫時,達到了最大執行次數則停止,填寫後就執行這裡的,而不是 next 裡的
        "onErrorNext": [ "OtherTaskName1", "OtherTaskName2" ],
                                            // 可選項,表示執行出錯時,後續要執行的任務

        "preDelay": 1000,                   // 可選項,表示辨識到後延遲多久才執行 action單位毫秒不填寫時預設 0
        "postDelay": 1000,                  // 可選項,表示 action 執行完後延遲多久才去辨識 next單位毫秒不填寫時預設 0

        "roi": [ 0, 0, 1280, 720 ],         // 可選項,表示辨識的範圍,格式為 [ x, y, width, height ]
                                            // 以 1280 * 720 為基準自動縮放,不填寫時預設 [ 0, 0, 1280, 720 ]
                                            // 儘量填寫,減小辨識範圍可以減少性能消耗,加快辨識速度

        "cache": false,                      // 可選項,表示該任務是否使用快取,預設為 false
                                            // 第一次辨識到後,以後永遠只在第一次辨識到的位置進行辨識,開啟可大幅節省性能
                                            // 但僅適用於待辨識目標位置完全不會變的任務,若待辨識目標位置會變請設為 false

        "rectMove": [ 0, 0, 0, 0 ],         // 可選項,辨識後的目標移動,不建議使用該選項。以 1280 * 720 為基準自動縮放
                                            // 例如辨識到了 A ,但實際要點擊的是 A 下方 10 像素 5 * 2 區域的某個位置,
                                            // 則可填寫 [ 0, 10, 5, 2 ],可以的話儘量直接辨識要點擊的位置,不建議使用該選項
                                            // 額外的,當 action 為 Swipe 時有效且必選,表示滑動終點。

        "reduceOtherTimes": [ "OtherTaskName1", "OtherTaskName2" ],
                                            // 可選項,執行後減少其他任務的執行計數。
                                            // 例如執行了吃理智藥,則說明上一次點擊藍色開始行動按鈕沒生效,所以藍色開始行動要 -1

        "specificRect": [ 100, 100, 50, 50 ],
                                            // 當 action 為 ClickRect 時有效且必選,表示指定的點擊位置(範圍內隨機一點)。
                                            // 當 action 為 Swipe 時有效且必選,表示滑動起點。
                                            // 以 1280 * 720 為基準自動縮放
                                            // 當 algorithm 為 "OcrDetect" 時specificRect[0] 和 specificRect[1] 表示灰度上下限閾值。

        "specialParams": [ int, ... ],      // 某些特殊辨識器需要的參數
                                            // 額外的,當 action 為 Swipe 時可選,[0] 表示 duration[1] 表示 是否啟用額外滑動

        "highResolutionSwipeFix": false,    // 可選項,是否啟用高解析度滑動修正,目前應該只有關卡導航未使用 Unity 滑動方式所以需要開啟
                                            // 預設為 false

        /* 以下欄位僅當 algorithm  MatchTemplate 時有效 */

        "template": "xxx.png",              // 可選項,要匹配的圖片檔案名稱
                                            // 預設 "任務名稱.png"

        "templThreshold": 0.8,              // 可選項,圖片範本匹配得分的閾值,超過閾值才認為辨識到了。
                                            // 預設 0.8,可根據日誌查看實際得分是多少

        "maskRange": [ 1, 255 ],            // 可選項,灰階遮罩範圍。
                                            // 例如將圖片不需要辨識的部分塗成黑色(灰階值為 0
                                            // 然後設定 "maskRange" 的範圍為 [ 1, 255 ],匹配的時候立刻忽略塗黑的部分

        "colorScales": [                    // 當 method 為 HSVCount 或 RGBCount 時有效且必選,數色掩碼範圍。
            [                               // list<array<array<int, 3>, 2>> / list<array<int, 2>>
                [23, 150, 40],              // 結構為 [[lower1, upper1], [lower2, upper2], ...]
                [25, 230, 150]              //     內層為 int 時是灰度,
            ],                              //       為 array<int, 3> 時是三通道顏色method 決定其是 RGB 或 HSV
            ...                             //     中間一層的 array<*, 2> 是顏色(或灰度)下限與上限:
        ],                                  //     最外層代表不同的顏色範圍,待識別區域為它們對應在模板圖片上掩碼的併集。

        "colorWithClose": true,             // 可選項,當 method 為 HSVCount 或 RGBCount 時有效,默認為 true
                                            // 數色時是否先用閉運算處理掩碼範圍。
                                            // 閉運算可以填補小黑點,一般會提高數色匹配效果,但若圖片中包含文字建議設為 false

        "method": "Ccoeff",                 // 可選項,模板匹配算法,可以是列表
                                            // 不填寫時默認為 Ccoeff
                                            //      - Ccoeff:       對顏色不敏感的模板匹配算法,對應 cv::TM_CCOEFF_NORMED
                                            //      - RGBCount:     對顏色敏感的模板匹配算法,
                                            //                      先將待匹配區域和模板圖片依據 colorScales 二值化,
                                            //                      以 F1-score 為指標計算 RGB 顏色空間內的相似度,
                                            //                      再將結果與 Ccoeff 的結果點積
                                            //      - HSVCount:     類似 RGBCount顏色空間換為 HSV

        /* 以下欄位僅當 algorithm  OcrDetect 時有效 */

        "text": [ "接管作戰", "代理指揮" ],  // 必選項,要辨識的文字內容,只要任一匹配上了即認為辨識到了

        "ocrReplace": [                     // 可選項,針對常見辨識錯的文字進行替換(支援正則)
            [ "千員", "幹員" ],
            [ ".+擊幹員", "狙擊幹員" ]
        ],

        "fullMatch": false,                 // 可選項,文字辨識是否需要完全匹配(不能多字),預設為 false
                                            // false 時只要是子串即可:例如 text: [ "開始" ],實際辨識到了 "開始行動",也算辨識成功
                                            // true 時則必須辨識到了 "開始",多一個字都不行

        "isAscii": false,                   // 可選項,要辨識的文字內容是否為 ASCII 碼字元
                                            // 不填寫預設 false

        "withoutDet": false,                // 可選項,是否不使用檢測模型
                                            // 不填寫預設 false

        /* 以下欄位僅當 algorithm  OcrDetect  withoutDet  true 時有效 */

        "useRaw": true,                     // 可選項,是否使用原圖匹配
                                            // 不填寫預設 truefalse 時為灰階匹配

        "binThreshold": [140, 255],         // 可選項,灰階二值化閾值(預設為 [140, 255]
                                            // 灰階值不在範圍的像素會被視為背景,排除在文字區域之外
                                            // 最終僅保留 [lower, upper] 區間的像素作為文字前景

        /* 以下欄位僅當 algorithm  JustReturn  action  Input 時有效 */

        "inputText": "A string text.",      // 必選項,要輸入的文字內容,為字串格式

        /* 以下欄位僅當 algorithm  FeatureMatch 時有效 */

        "template": "xxx.png",              // 可選項,要符合的圖片檔案名,可以是字串或字串列表
                                            // 預設 "任務名稱.png"

        "count": 4,                         // 匹配的特徵點的數量要求 (閾值), 預設值 = 4

        "ratio": 0.6,                       // KNN 匹配演算法的距離比值, [0 - 1.0], 越大則匹配越寬鬆, 更容易連線. 預設0.6

        "detector": "SIFT",                 // 特徵點偵測器類型, 可選值為 SIFT, ORB, BRISK, KAZE, AKAZE, SURF; 預設值 = SIFT
                                            // SIFT: 計算複雜度高,具有尺度不變性、旋轉不變性。效果最好。
                                            // ORB: 計算速度非常快,具有旋轉不變性。但不具有尺度不變性。
                                            // BRISK: 計算速度非常快,具有尺度不變性、旋轉不變性。
                                            // KAZE: 適用於2D和3D影像具有尺度不變性、旋轉不變性。
                                            // AKAZE: 計算速度較快,具有尺度不變性、旋轉不變性。
    }
}

特殊任務類型

Template Task@ 型任務)

Template task 與 base task 合稱範本任務

允許把某個任務 "A" 當作範本,然後 "B@A" 表示由 "A" 產生的任務。

  • 如果 tasks.json 中未顯式定義任務 "B@A",則在 sub, next, onErrorNext, exceededNext, reduceOtherTimes 欄位中增加 B@ 首碼(如遇任務名開頭為 # 則增加 B 首碼),其餘參數與 "A" 任務相同。就是說如果任務 "A" 有以下參數:

    "A": {
        "template": "A.png",
        ...,
        "next": [ "N1", "N2" ]
    }
    

    就相當於同時定義了

    "B@A": {
        "template": "A.png",
        ...,
        "next": [ "B@N1", "B@N2" ]
    }
    
  • 如果 tasks.json 中定義了任務 "B@A",則:

    1. 如果 "B@A" 與 "A" 的 algorithm 欄位不同,則派生類參數不繼承(只繼承 TaskInfo 定義的參數)
    2. 如果是圖片匹配任務,template 若未顯式定義則為 B@A.png(而不是繼承 "A" 的 template 名),其餘情況任何派生類參數若未顯式定義,直接繼承 "A" 任務的參數
    3. 對於 TaskInfo 基類中定義的參數(任何類型任務都有的參數,例如 algorithm, roi, next 等),若沒有在 "B@A" 內顯式定義,則除了上面提到的 sub 等五個欄位在繼承時會增加 "B@" 首碼外,其餘參數直接繼承 "A" 任務的參數

Base Task

Base task 與 template task 合稱 範本任務

有欄位 baseTask 的任務即為 base task。

Base task 的邏輯優先於 template task。這代表 "B@A": { "baseTask": "C", ... } 與任務 A 沒有任何相關。

任何參數若未顯式定義則不加首碼地直接使用 baseTask 對應任務的參數,除了 template 未顯式定義時仍為 "任務名.png"

多檔任務

如果後載入的任務檔案(例如外服 tasks.json,下稱文件二)中定義的任務在先載入的任務檔案(例如國服 tasks.json,下稱文件一)中也定義了同名任務,那麼:

  • 如果文件二中任務沒有 baseTask 欄位,則直接繼承文件一中同名任務的欄位。
  • 如果文件二中任務有 baseTask 欄位,則不繼承文件一中同名任務的欄位,而是直接取代。

Virtual Task虛任務

Virtual task 也稱 sharp task# 型任務)。

任務名帶 # 的任務即為 virtual task。 # 後可接 next, back, self, sub, on_error_next, exceeded_next, reduce_other_times

虛任務類型 含義 簡單範例
self 父任務名 "A": {"next": "#self"} 中的 "#self" 被解釋為 "A"
"B": {"next": "A@B@C#self"} 中的 "A@B@C#self" 被解釋為 "B"1
back # 前面的任務名 "A@B#back" 被解釋為 "A@B"
"#back" 直接出現則會被跳過
next, sub 等 # 前任務名對應欄位 next 為例:
"A#next" 被解釋為 Task.get("A")->next
"#next" 直接出現則會被跳過

Note1: "XXX#self""#self" 含義相同。

簡單範例

{
    "A": { "next": [ "N1", "N2" ] },
    "C": { "next": [ "B@A#next" ] },

    "Loading": {
        "next": [ "#self", "#next", "#back" ]
    },
    "B": {
        "next": [ "Other", "B@Loading" ]
    }
}

可以得到:

Task.get("C")->next = { "B@N1", "B@N2" };

Task.get("B@Loading")->next = { "B@Loading", "Other", "B" };
Task.get("Loading")->next = { "Loading" };
Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };

一些用途

  • 當幾個任務有 "next": [ "#back" ] 時,"Task1@Task2@Task3" 代表依次執行 Task3, Task2, Task1

其它相關

{
    "A": { "next": [ "N0" ] },
    "B": { "next": [ "A#next" ] },
    "C@A": { "next": [ "N1" ] }
}

以上這種情況,"C@B" -> next(即 C@A#next)為 [ "N1" ] 而不是 [ "C@N0" ].

運行時修改任務

  • Task.lazy_parse() 可以在執行時載入 json 任務設定檔。 lazy_parse 規則與多檔任務相同。
  • Task.set_task_base() 可以修改任務的 baseTask 欄位。

使用範例

假設有任務設定檔如下:

{
     "A": {
         "baseTask": "A_default"
     },
     "A_default": {
         "next": [ "xxx" ]
     },
     "A_mode1": {
         "next": [ "yyy" ]
     },
     "A_mode2": {
         "next": [ "zzz" ]
     }
}

以下程式碼可以實現根據 mode 的值改變任務 "A",同時會改變其它依賴任務 "A" 的任務,如 "B@A":

switch (mode) {
case 1:
     Task.set_task_base("A", "A_mode1"); // 基本上相當於用 A_mode1 的內容直接取代 A下同
     break;
case 2:
     Task.set_task_base("A", "A_mode2");
     break;
default:
     Task.set_task_base("A", "A_default");
     break;
}

運算式計算

符號 含義 實例
@ 範本任務 Fight@ReturnTo
#(單目) 虛任務 #self
#(雙目) 虛任務 StartUpThemes#next
* 重複多個任務 (ClickCornerAfterPRTS+ClickCorner)*5
+ 任務清單合併(在 next 系列屬性中同名任務只保留最靠前者) A+B
^ 任務列表差(在前者但不在後者,順序不變) (A+A+B+C)^(A+B+D)(結果為 C

運算子 @, #, *, +, ^ 有優先順序:#(單目)> @ = #(雙目)> * > + = ^

Schema 檢驗

本項目為 tasks.json 配置了 json schema 檢驗schema 文件為docs/maa_tasks_schema.json

Visual Studio

MaaCore.vcxporj 中已對其進行配置,開箱即用。提示效果較為晦澀,且有部分資訊缺失。

Visual Studio Code

.vscode/settings.json 中已對其進行配置,用 vscode 打開該 專案檔案夾 即可使用。提示效果較好。