Skip to content

Commit

Permalink
docs: 更新用户手册&开发文档 (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
Windsland52 authored Dec 19, 2024
1 parent b8b1c5c commit 959162b
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 114 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
目前已有的功能:

- 启动/关闭游戏
- 切换账号
- 收取荒原、魔精收取生产物品
- 每日心相(意志解析)
- 刷体力、最优材料关卡、活动关卡、吃糖选项
Expand Down
77 changes: 45 additions & 32 deletions docs/zh_cn/develop/Bug 排查.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
# Bug 排查

修 bug 也是开发中重要的一环,如何快速准确地定位、分析、解决 bug 是有技巧的。本文将介绍一些常见的 bug 排查方法。
修 bug 也是开发中重要的一环。
如何快速准确地定位、分析、解决 bug 是有技巧的。
本文将简单介绍排查 bug 的一般流程。

> [!NOTE]
>
> 以下内容仅供参考,注意时效性。
## 前置准备

与 bug 发现者沟通,尽可能的获取 bug 相关的信息,如:
与 bug 提出者沟通,尽可能的获取 bug 相关的信息,如:

- 资源版本
- 系统版本
- 问题的细节(发生的时间、场景等)
- 配置文件、日志、截图等
- 问题的细节描述(发生的时间、场景等)
- 配置文件、日志、截图等必要信息

## 定位问题
## 定位关键 log

### 确认资源版本以及运行方式
1. 确认资源版本以及运行方式

对于 M9A 来说,有两种运行方式:1. MaaPiCli 2. MFAWPF
对于 M9A 来说,有两种运行方式:1. MaaPiCli 2. MFAWPF

根据观察,MaaPiCli运行时有行log为
根据观察,MaaPiCli运行时有行log为

```plaintext
[2024-11-28 19:46:32.571][INF][Px14600][Tx16498][Parser.cpp][L56][MaaNS::ProjectInterfaceNS::Parser::parse_interface] Interface Version: [data.version=v2.4.11]
```
```plaintext
[2024-11-28 19:46:32.571][INF][Px14600][Tx16498][Parser.cpp][L56][MaaNS::ProjectInterfaceNS::Parser::parse_interface] Interface Version: [data.version=v2.4.11]
```

既能看出资源版本,又能看出是以 MaaPiCli 方式运行。
而 MFAWPF 运行时有log为

```plaintext
[2024-11-30 01:46:56.490][INF][Px20060][Tx33876][Parser.cpp][L56][MaaNS::ProjectInterfaceNS::Parser::parse_interface] Interface Version: [data.version=]
```
```plaintext
MFAWPF Version: [mfa.version=v1.2.2.0] Interface Version: [data.version=v2.5.5]
```

`version` 为空时,MaaPiCli log 为以上样式。
由 data.version 可以确定资源版本。以此判断当前问题发生的版本是否已修复当前 bug。
同时确认运行方式。因为不同运行方式,可能影响问题的复刻。

确认资源版本可以了解是否为已修复bug版本,确认运行方式则是因为不同运行方式,config文件不同,同时可能生成的bug也不同。
2. 定位问题所在的 log 位置

### 确定问题 log 范围
分两种情况:
- 任务提前结束
- 任务陷入无限循环

- 根据问题描述发生的时间缩小范围
- 根据问题发生的任务缩小范围
- 根据[ERR]确定错误相关原因
- 根据bug相关的[ERR]处反向查找 `Task Hit` ,以确定出错任务
前者全局搜素 **[ERR]** ,查看报错是与什么有关。
后者全局搜索 **Task Hit** ,查找不正常的匹配情况(如持续匹配一个本不该一直匹配的 node)。

## 分析问题

在这里我将问题大致分为三类:资源加载问题、连接问题以及 pipeline 问题(timeout)
在这里我将问题大致分为三类:资源加载问题、连接问题以及 pipeline 问题。

### 资源加载问题

Expand All @@ -64,19 +65,31 @@
[2024-11-24 23:44:05.539][ERR][Px26056][Tx55883][ControlUnitMgr.cpp][L55][MaaNS::CtrlUnitNs::ControlUnitMgr::connect] failed to connect [adb_path_=D:/MuMu Player 12/shell/adb.exe] [adb_serial_=127.0.0.1:16384]
```

### pipeline 问题
### Pipeline 问题

这类是 M9A 主要需要关注的问题,需要了解原 pipeline 流程以及 log 展示的执行情况,加以分析。

1. 非 pipeline 流程类问题

这种问题本身 pipeline 流程逻辑上没有问题。

根据出问题的 node 分为两种:

第一种是 非 无条件匹配/inverse node。
常见原因是截图截太快了,匹配到 `next` 中 node,但当前画面尚未未稳定。
解决方案是为当前 node 添加合适的 `post_wait_freezes`,等待画面稳定再做判断。

一般来说,是pipeline逻辑有漏洞导致的,需要进一步分析。
第二种是 无条件匹配/inverse node。
这种可能是进到非预期界面,导致判断失误。
解决方案是按需修改。

常用的解决方法有:
2. pipeline 流程类问题

- 增加 `flag` 任务
- 增加 `pre/post_wait_freezes` (注意默认 `target` 是否是你想要的)
- 更改实现逻辑(如更换识别方式以及动作逻辑)
这种是任务流程本身完备性不足,需在分析后修改。

## 解决问题

前两种参考[常见问题](../manual/常见问题.md)解决,pipeline 问题需要进一步分析
前两种参考[常见问题](../manual/常见问题.md)解决,pipeline 问题根据分析结果修改

## 验证修复

Expand Down
114 changes: 87 additions & 27 deletions docs/zh_cn/develop/Pipeline 编写.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,106 @@
#### 资源命名

- 对于图片等文件,采用大驼峰命名法,所有单词的首字母都大写。
- 对于 `pipeline.json` 文件,一般来说,采用蛇形命名法,单词之间用下划线分隔,所有字母小写,
特别地,专有名词的活动采取大驼峰命名法,一般在 `activity`
- 对于 `image` 下文件夹,每个文件夹对应一个 `pipeline.json` 文件,文件夹名采用大驼峰命名法,
特别地,`activity``pipeline.json` 对应的 `image` 放到 `Combat/Activity` 处。
- 对于 `pipeline` 文件夹下的 json 文件名,一般采用蛇形命名法,单词之间用下划线分隔,所有字母小写,
特别地,专有名词的活动采取大驼峰命名法,一般在 `activity` 文件夹内
- 对于 `image` 下文件夹,每个文件夹对应一个 `pipeline` 文件夹下的 json 文件,文件夹名采用大驼峰命名法,
特别地,`activity` 内 json 文件对应的 `image` 放到 `Combat/Activity` 处。

#### Task 命名
#### Node 命名

大多数采用大驼峰命名法,特别地,部分情况下用 `_` 连接前、后缀。
node 的定义为符合任务流水线(Pipeline)协议的一个完整的 `JsonObject`大多数采用大驼峰命名法,特别地,部分情况下用 `_` 连接前、后缀。

前缀一般为 `Sub` 或 当前活动缩写(如 `SOD` 黄昏的音序、`EITM` 山麓的回音)等,其他情况建议不要前缀。
前缀一般为 `Sub` 或 当前活动缩写(如 `SOD` 黄昏的音序、`EITM` 山麓的回音)等。(其他情况建议不要前缀)

后缀一般为 `数字``状态` 等,表示该任务的具体阶段或状态。(建议新写的任务不加后缀
后缀一般为 `数字``状态` 等,表示该 node 的具体阶段或状态。(建议新写的 node 不加后缀

### Task 编写
### Node 编写

参考[Pipeline 协议详细说明](https://github.com/MaaXYZ/MaaFramework/blob/main/docs/zh_cn/3.1-%E4%BB%BB%E5%8A%A1%E6%B5%81%E6%B0%B4%E7%BA%BF%E5%8D%8F%E8%AE%AE.md)
具体内容参见[Pipeline 协议详细说明](https://github.com/MaaXYZ/MaaFramework/blob/main/docs/zh_cn/3.1-%E4%BB%BB%E5%8A%A1%E6%B5%81%E6%B0%B4%E7%BA%BF%E5%8D%8F%E8%AE%AE.md)

> [!NOTE]
>
> - 一般 `next` 放置当前任务的出口任务,`interrupt` 放置当前任务的中断任务。
> - 建议多写些 `Flag` 任务进行判断,以保证任务的稳定性。
> - 部分情况下,可在 `next` 加入自身,以提高任务的稳定性。(存在程序未正确接受动作的情况)
> - `next` 放置当前 node 的出口 node,`interrupt` 放置当前 node 的中断 node。
> - 多将具有 Flag 性质的 node 设为出口 node,作为当前 node 完成的标志。
> - 降低 node 之间的耦合。
> `BackButton` 一般不设置 `next`,而是作为一个“异常处理”放入 `interrupt`,以便保证任务流程的清晰,并方便 interrupt node 被其它任务复用。
> - 部分情况下,可将 node 加入自身 `next` 。(存在动作未被游戏正确接受/尚未在游戏内生效的情况)
> - 在涉及切换页面的 node 中加入 `post_wait_freezes` ,并使用 `object` 作为值,设置合适的 `time``target`
> - 涉及滑动的操作时,在后面加个点击操作,以便确保画面稳定。
> [!WARNING]
>
> - 慎用 `inverse` 字段,这可能会导致任务的不可预测。
> 如必须使用,请保证其有带 `post_wait_freezes` 的前置 node,以保证匹配该 node 时处于预期状态。
> - 慎用“无条件匹配” node。
> node 的 `recognition` 字段默认为 `DirectHit``recognition` 字段为 `DirectHit` 的 node 即为“无条件匹配” node。
> 使用“无条件匹配” node,可能导致任务运行到非预期状态时,程序未能正常报错,而是循环匹配该 node,造成任务卡死。
> 如非必要,请选择其它实现逻辑完成任务。
#### Node 连接

Node 间主要通过 `next``interrupt` 字段连接。

`next`完成 node 间的串联,`interrupt`实现执行以当前 interrupt node为 entry 的新任务链,并在该任务链完成后返回当前 node。

简单表示如下:

```mermaid
graph LR
A(Task Entry<br>Node A) --> |next| B(Node B)
A --> |interrupt| C(Node C)
C --> |return| A
```

将 interrupt node 变复杂点:

```mermaid
graph LR
A(Task Entry<br>Node A) --> |next| B(Node B)
A --> |interrupt| C(Node C)
C --> |next| D(Node D)
C --> |interrupt| E(Node E)
D --> |return| A
E --> |return| C
```

为保证任务链有一个较好的结构,请按以下原则进行 node 连接:

1. 标志完成阶段性任务的 node 应放在 `next` 中。
2. 为达到匹配 `next` 中 node 而处理其他状况的 node 应放在 `interrupt` 中。

如 活动刷取任务、位于活动主界面、进入活动主界面 三者关系如下:

```mermaid
graph LR
A(活动刷取任务) --> |next| B(位于活动主界面)
A --> |interrupt| C(进入活动主界面)
C --> |return| A
```

这里“进入活动主界面”就不会放在 `next` ,而是放入 `interrupt`

### next & interrupt 任务顺序
#### Next & Interrupt Node 排序

总体上,`interrupt` 第一个任务 `next` 最后一个任务低一优先级
总体上,`interrupt` 第一个 node `next` 最后一个 node 低一优先级

`next``interrupt` 内部,统一先按照优先级由高到低顺序排列,不能出现优先级倒挂的情况。举例:

```plaintext
现有判断一个小弹窗的任务B,和判断跳出弹窗前界面的任务A
如果弹窗出现时依旧能匹配到任务A,则任务B的优先级应该高于任务A,否则会出现无法处理B而卡死于A的情况
现有判断一个小弹窗的 node B,和判断跳出弹窗前界面的 node A
如果弹窗出现时依旧能匹配到A,则B的优先级应该高于A,否则会出现无法处理B而卡死于A的情况
```

同一优先级内的任务,可按照匹配频率由高到低顺序排列,以便提高命中率,降低资源消耗。
同一优先级内的 node,可按照匹配频率由高到低顺序排列,以便提高 node 命中率,降低资源消耗。

### 注释规范
#### 注释规范

`pipeline.json` 文件中,注释共两种属性字段:

1. `.*_doc$|^doc$`: 以 _doc 结尾的字符串或者正好是 doc 的字符串。
2. `.*_code$|^code$`:以 _code 结尾的字符串或者正好是 code 的字符串。

前者为对当前 task(或某字段)的说明,后者为对必填字段的占位。举例:
前者为对当前 node(或某字段)的说明,后者为对必填字段的占位。举例:

```json
{
Expand All @@ -67,16 +123,20 @@
183
],
"action": "Click",
"post_wait_freezes": 300,
"next": [
"ActivityMainFlag",
"EnterTheActivityMain"
]
"post_wait_freezes": {
"time": 500,
"target": [
0,
179,
190,
541
]
}
}
}
```

`doc` 为当前 task 说明。
`doc` 为当前 node 说明。

`template_code` 为必填字段占位,
原因是 `recognition``TemplateMatch` 时, "template" 字段必填,但我们想在 `interface.json` 中修改,故用 `template_code` 占位。
原因是 `recognition``TemplateMatch` 时, "template" 字段必填,但我们想在 `interface.json` 中修改,而不是该 json 文件中。故用 `template_code` 占位。
48 changes: 31 additions & 17 deletions docs/zh_cn/develop/interface.json 编写.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# interface.json 编写

[参考资料——interface.schema.json](https://github.com/MaaXYZ/MaaFramework/blob/main/tools/interface.schema.json)
> [!TIP]
>
> 参考资料:
> [interface.schema.json](https://github.com/MaaXYZ/MaaFramework/blob/main/tools/interface.schema.json)
> [ProjectInterface协议.md](https://github.com/MaaXYZ/MaaFramework/blob/main/docs/zh_cn/3.2-ProjectInterface%E5%8D%8F%E8%AE%AE.md)
`interface.json` 旨在提供菜单配置。

Expand Down Expand Up @@ -36,7 +40,7 @@

任务列表。任务列表包含多个任务,而每个任务又有任务名 `name`、任务入口 `entry`、任务参数 `pipeline_override`、以及任务选项 `option`,其中 `name` `entry` 必填。

`pipeline_override` 中应为 pipeline task,并带有覆写参数,例如:
`pipeline_override` 中应为 pipeline node,并带有覆写参数,例如:

```json
{
Expand All @@ -51,31 +55,35 @@
}
```

这里原task为
这里原 node 为

```json
{
"EnterTheActivityMain": {
"doc": "进入当期活动主界面",
"template_code": "在interface.json中修改template",
"recognition": "TemplateMatch",
"template_code": "在interface.json中修改template",
"roi": [
885,
123,
340,
183
],
"action": "Click",
"post_wait_freezes": 300,
"next": [
"ActivityMainFlag",
"EnterTheActivityMain"
]
"post_wait_freezes": {
"time": 500,
"target": [
0,
179,
190,
541
]
}
}
}
```

经过覆写,该 task 在执行“轶事派遣(角色故事请自行阅读)”任务时,实际执行效果等同于:
经过覆写,该 node 在执行“轶事派遣(角色故事请自行阅读)”任务时,实际执行效果等同于:

```json
{
Expand All @@ -89,18 +97,22 @@
183
],
"action": "Click",
"post_wait_freezes": 300,
"next": [
"ActivityMainFlag",
"EnterTheActivityMain"
]
"post_wait_freezes": {
"time": 500,
"target": [
0,
179,
190,
541
]
}
}
}
```

执行“轶事派遣(角色故事请自行阅读)”任务后,task 便会恢复原状。
执行“轶事派遣(角色故事请自行阅读)”任务后,node 便会恢复原状。

`option` 则是根据你下面的具体设置来决定如何覆写 pipeline task
`option` 则是根据你下面的具体设置来决定如何覆写 pipeline node

## option

Expand Down Expand Up @@ -147,6 +159,8 @@
}
```

`defaul_case` 为默认选项,从 `cases` 中选择一个。

## version

版本。不必填写,ci install 时会自动生成。
Expand Down
Loading

0 comments on commit 959162b

Please sign in to comment.