diff --git a/docs/3.4-任务流程协议.md b/docs/3.4-任务流程协议.md
index 1f9a2aba12..cb45556f45 100644
--- a/docs/3.4-任务流程协议.md
+++ b/docs/3.4-任务流程协议.md
@@ -15,25 +15,14 @@
// - OcrDetect: 文字识别
// - Hash: 哈希计算
- "template": "xxx.png", // 仅当 algorithm 为 MatchTemplate 时有效;可选项,要匹配的图片文件名
- // 不填时写默认 "任务名.png"
-
- "isAscii": false, // 仅当 algorithm 为 OcrDetect 时有效;可选项,要识别的文字内容是否为 ASCII 码字符
- // 不填写默认 false
-
- "withoutDet": false, // 仅当 algorithm 为 OcrDetect 时有效;可选项,是否不使用检测模型位置
- // 不填写默认 false
-
- "text": [ "接管作战", "代理指挥" ], // 仅当 algorithm 为 OcrDetect 时有效;必选项,要识别的文字内容,只要任一匹配上了即认为识别到了
-
"action": "ClickSelf", // 可选项,表示识别到后的动作
// 不填写时默认为 DoNothing
- // - ClickSelf: 点击识别到的位置(识别到的目标范围内随机点)
- // - ClickRand: 点击整个画面中随机位置
- // - DoNothing: 什么都不做
- // - Stop: 停止当前任务
- // - ClickRect: 点击指定的区域,对应 specificRect 字段,不建议使用该选项
- // - Swipe: 滑动,对应 specificRect 与 rectMove 字段
+ // - ClickSelf: 点击识别到的位置(识别到的目标范围内随机点)
+ // - ClickRand: 点击整个画面中随机位置
+ // - ClickRect: 点击指定的区域,对应 specificRect 字段,不建议使用该选项
+ // - DoNothing: 什么都不做
+ // - Stop: 停止当前任务
+ // - Swipe: 滑动,对应 specificRect 与 rectMove 字段
"sub": [ "SubTaskName1", "SubTaskName2" ],
// 可选项,子任务。会在执行完当前任务后,依次执行每一个子任务
@@ -50,6 +39,7 @@
// 不填写默认执行完当前任务直接停止
// 对于相同任务,第一次识别后第二次就不再识别:
// "next": [ "A", "B", "A", "A" ] -> "next": [ "A", "B" ]
+ // 不允许 JustReturn 型任务位于非最后一项
"maxTimes": 10, // 可选项,表示该任务最大执行次数
// 不填写时默认无穷大
@@ -91,6 +81,9 @@
/* 以下字段仅当 algorithm 为 MatchTemplate 时有效 */
+ "template": "xxx.png", // 可选项,要匹配的图片文件名
+ // 默认 "任务名.png"
+
"templThreshold": 0.8, // 可选项,图片模板匹配得分的阈值,超过阈值才认为识别到了。
// 默认 0.8, 可根据日志查看实际得分是多少
@@ -100,14 +93,22 @@
/* 以下字段仅当 algorithm 为 OcrDetect 时有效 */
- "fullMatch": false, // 可选项,文字识别是否需要全字匹配(不能多字),默认为 false
- // false 时只要是子串即可:例如 text: [ "开始" ],实际识别到了 "开始行动",也算识别成功;
- // true 时则必须识别到了 "开始",多一个字都不行
+ "text": [ "接管作战", "代理指挥" ], // 必选项,要识别的文字内容,只要任一匹配上了即认为识别到了
"ocrReplace": [ // 可选项,针对常见识别错的文字进行替换(支持正则)
[ "千员", "干员" ],
[ ".+击干员", "狙击干员" ]
- ]
+ ],
+
+ "fullMatch": false, // 可选项,文字识别是否需要全字匹配(不能多字),默认为 false
+ // false 时只要是子串即可:例如 text: [ "开始" ],实际识别到了 "开始行动",也算识别成功;
+ // true 时则必须识别到了 "开始",多一个字都不行
+
+ "isAscii": false, // 可选项,要识别的文字内容是否为 ASCII 码字符
+ // 不填写默认 false
+
+ "withoutDet": false // 可选项,是否不使用检测模型
+ // 不填写默认 false
/* 以下字段仅当 algorithm 为 Hash 时有效 */
// 算法不成熟,仅部分特例情况中用到了,暂不推荐使用
@@ -117,82 +118,106 @@
```
-## 任务类型
+## 特殊任务类型
### Template Task(`@` 型任务)
-Template Task 与 Base Task 合称**模板任务**。
+Template task 与 base task 合称**模板任务**。
-允许把某个 task(例如 "A")当作模板,然后 "B@A" 表示由 "A" 生成的任务。
+允许把某个任务 "A" 当作模板,然后 "B@A" 表示由 "A" 生成的任务。
-- 如果 `tasks.json` 中没有定义任务 "B@A",则在 `next`, `onErrorNext`, `exceededNext`, `reduceOtherTimes` 字段中增加 `B@` 前缀,其余参数与 "A" 任务相同。就是说相当于定义了
+- 如果 `tasks.json` 中未显式定义任务 "B@A",则在 `sub`, `next`, `onErrorNext`, `exceededNext`, `reduceOtherTimes` 字段中增加 `B@` 前缀(如遇任务名开头为 `#` 则增加 `B` 前缀),其余参数与 "A" 任务相同。就是说如果任务 "A" 有以下参数:
+ ```jsonc
+ "A": {
+ "template": "A.png",
+ ...,
+ "next": [ "N1", "N2" ]
+ }
+ ```
+ 就相当于同时定义了
```jsonc
"B@A": {
"template": "A.png",
...,
- "next": { "B@N1", "B@N2", "B@N3", "B@N4" }
+ "next": [ "B@N1", "B@N2" ]
}
```
- 如果 `tasks.json` 中定义了任务 "B@A",则:
1. 如果 "B@A" 与 "A" 的 `algorithm` 字段不同,则派生类参数不继承(只继承 `TaskInfo` 定义的参数)
- 2. 如果是图像匹配任务,`template` 若留空则为 `B@A.png`(而不是继承"A"的 `template` 名),其余情况任何派生类参数若留空,直接继承 "A" 任务的参数
+ 2. 如果是图像匹配任务,`template` 若未显式定义则为 `B@A.png`(而不是继承"A"的 `template` 名),其余情况任何派生类参数若未显式定义,直接继承 "A" 任务的参数
3. 对于 `TaskInfo` 基类中定义的参数(任何类型任务都有的参数,例如 `algorithm`, `roi`, `next` 等),若没有在 "B@A" 内显式定义,则除了上面提到的 `sub` 等五个字段在继承时会增加 "B@" 前缀外,其余参数直接继承 "A" 任务的参数
### Base Task
-Base Task 与 Template Task 合称**模板任务**。
+Base task 与 template task 合称**模板任务**。
-除了 `template` 留空时仍为"任务名.png",其余任何参数若留空直接使用 baseTask 的参数。(不加前缀)
+有字段 `baseTask` 的任务即为 base task。
+除了 `template` 未显式定义时仍为 `"任务名.png"`,其余任何参数若未显式定义直接使用 `baseTask` 对应任务的参数。(不加前缀)
-### Sharp Task(`#` 型任务)
+#### 其它相关
+
+- 外服 `tasks.json` 中定义的同名任务直接继承国服 `tasks.json` 的参数,相当于 `"A": { "baseTask": "国服的A" }`
+- 如果国服 `tasks.json` 中定义了任务 "B@A",外服 `tasks.json` 中也定义了 "B@A",那么
+ 1. 如果外服 "B@A" 有字段 `"baseTask": ""`,则不继承国服 "B@A"
+ - 若有定义任务 "A",则以 template task 的逻辑处理 "B@A"
+ - 若未定义任务 "A",则以普通任务的逻辑处理 "B@A"
+ 2. 如果外服 "B@A" 没有 `baseTask`,则直接继承国服 "B@A" 参数
+
+### 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"` 含义相同。_
#### 简单示例
- ```json
- {
- "A": {
- "next": [ "N1", "N2" ]
- },
- "C": {
- "next": [ "B@A#next" ]
- }
- }
- ```
-可以得到 "C" 的 next 是 `[ "B@N1, "B@N2" ]`
+```json
+{
+ "A": { "next": [ "N1", "N2" ] },
+ "C": { "next": [ "B@A#next" ] },
- ```json
"Loading": {
"next": [ "#self", "#next", "#back" ]
},
"B": {
"next": [ "Other", "B@Loading" ]
}
- ```
-可以生成:
-
-`"B@Loading" -> next = [ "B@Loading", "Other", "B" ]`
-
-`"Loading" -> next = [ "Loading" ]`
-
-_Note: 在 `m_raw_all_tasks_info` 中,`"B@Loading" -> next = [ "B@Loading", "B#next", "B#back" ]`_
-
-`#` 后可接参数 `next`, `back`, `self`, `sub`, `on_error_next`, `exceeded_next`, `reduce_other_times`。
+}
+```
+可以得到:
+```cpp
+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@Task4"` 代表依次执行 `Task4`, `Task3`, `Task2`, `Task1`。
+- 当几个任务有 `"next": [ "#back" ]` 时,`"Task1@Task2@Task3"` 代表依次执行 `Task3`, `Task2`, `Task1`。
-## 其它相关
- ```json
- "B@A1": { "next": [ "B@A2#next" ] },
- "B@A2": { "next": [ "N0" ] },
- "C@B@A2": { "next": [ "N1" ] }
- ```
-以上这种情况, `Task.get("C@B@A1") -> next` 应该为 `[ "N1" ]` 而不是 `[ "C@N0" ]`.
+#### 其它相关
+
+```json
+{
+ "A": { "next": [ "N0" ] },
+ "B": { "next": [ "A#next" ] },
+ "C@A": { "next": [ "N1" ] }
+}
+```
+以上这种情况, `"C@B" -> next`(即 `C@A#next`)为 `[ "N1" ]` 而不是 `[ "C@N0" ]`.
## Schema 检验