mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-22 03:56:44 +08:00
为 issue #1 的公共错误契约建立错误码模型: - core/src/error_code.rs:ErrorCode(BAT-ERR-<域3位><序号3位>,如 BAT-ERR-300012) + 44 个初始码表(覆盖输入/路径安全/网络下载/校验/发布存储/解析/任务RPC/内部 八域,网络域含代理故障 310001)、ErrorDomain、以及进入 RPC envelope / --json / bat-events.jsonl 的统一 ApiError { code, kind, domain, location, message, retryable }。 location 用稳定的组件·操作标签(不随行号漂移)。 - 新增 USERGUIDE.md:bat 命令、选项(发现/同步/守护/输出)、退出码(含 75=locked)、 运行时默认值,以及从码表同步的错误码参考(含承载结构与域一览)。 命名遵循国际惯例(英文 kind/domain slug)。码表以 error_code.rs 为准,USERGUIDE 错误码表与之逐条一致。后续各链路报错接入该码表在 issue #1 下推进。 对应 issue #1(错误码模型 + 用户指南)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
223 lines
11 KiB
Markdown
223 lines
11 KiB
Markdown
# BlueArchiveToolkit 用户指南
|
||
|
||
本指南面向 `bat` 官方资源同步二进制的使用者,覆盖:命令、选项、退出码、运行时行为,以及统一错误码参考。
|
||
|
||
- 权威运行/部署说明另见 `docs/guides/official-resource-test-pull.md` 和 `docs/guides/deployment.md`。
|
||
- 本文档中的命令、选项以 `bat --help` 为准;错误码以 `core/src/error_code.rs` 的码表为准。
|
||
|
||
---
|
||
|
||
## 1. 概览
|
||
|
||
`bat` 是 Linux 上官方日服(Yostar JP)资源同步的正式入口。它可以:
|
||
|
||
- `--auto-discover` 从官方 HTTP metadata 解析 `GameMainConfig`,自动获得 app-version、连接组和 server-info,不安装、不启动官方启动器。
|
||
- 生成官方全量 pull plan、执行真实下载,维护 release 内的下载 manifest,并做 size + BLAKE3 复用校验、官方 seed `.hash`(标准 xxHash32(seed=0))强校验、ZIP 结构校验。
|
||
- 断点续传、失败分类重试、下载 quarantine、本地 manifest audit/repair。
|
||
- 原子发布:先写 `.staging/<id>`,校验通过后发布 `versions/<id>` 并原子切换 `current` symlink。
|
||
- 常驻运行(`--watch`)或后台化(`--daemon`),通过 `bat.sock` Unix socket JSON-RPC 控制。
|
||
|
||
### 运行形态
|
||
|
||
```bash
|
||
# 一次性 dry-run(不写状态)
|
||
bat --auto-discover --dry-run
|
||
|
||
# 前台常驻
|
||
bat --auto-discover --watch --output /var/lib/bluearchive-toolkit/official
|
||
|
||
# 后台守护
|
||
bat --auto-discover --daemon --output /var/lib/bluearchive-toolkit/official
|
||
```
|
||
|
||
带凭据的代理**推荐用环境变量**(凭据不进命令行/argv/状态文件):
|
||
|
||
```bash
|
||
HTTPS_PROXY=http://user:pass@127.0.0.1:7890 bat --auto-discover --daemon
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 命令
|
||
|
||
无子命令时执行一次性同步(或配合 `--watch`/`--daemon`)。子命令如下:
|
||
|
||
| 命令 | 说明 |
|
||
|---|---|
|
||
| `refresh` | 执行一次更新检查;若有 live daemon,则通过 RPC 请求其刷新 |
|
||
| `verify` | 校验远端计划、本地 manifest 和官方 seed hash(dry-run + 审计当前 release) |
|
||
| `repair` | 重新下载本地校验失败的资源 |
|
||
| `status` | 显示 daemon 状态 |
|
||
| `stop` | 停止 daemon |
|
||
| `restart` | 重启 daemon;未显式传参时复用保存的参数 |
|
||
| `reload` | 请求 daemon 重新自动发现并强制刷新 |
|
||
| `logs` | 显示 daemon 日志尾部(配合 `--tail`) |
|
||
| `doctor` | 运行时诊断(输出目录、状态目录、curl/unzip、代理、PID、socket、锁) |
|
||
| `clean-stable` | 清理 `.part`/`.tmp`/失效锁、PID、socket(daemon 运行中会拒绝执行) |
|
||
|
||
`status`/`stop`/`logs`/`reload` 和默认形态的 `refresh` 优先走 `bat.sock` JSON-RPC;socket 不可用时 `status`/`stop` 回退到 PID/状态文件兼容路径。
|
||
|
||
---
|
||
|
||
## 3. 选项
|
||
|
||
### 发现(Discovery)
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--auto-discover` | 自动发现 app-version、server-info、连接组 |
|
||
| `--server-info-url <URL>` | 使用官方 server-info URL |
|
||
| `--server-info-file <NAME>` | 使用官方 server-info 文件名 |
|
||
| `--server-info-path <PATH>` | 使用本地 server-info JSON 文件 |
|
||
| `--app-version <VERSION>` | 覆盖 app 版本 |
|
||
| `--connection-group <NAME>` | 覆盖连接组 |
|
||
| `--launcher-version <VERSION>` | 启动器 metadata API 版本(默认 `1.7.2`) |
|
||
|
||
### 同步(Sync)
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--platforms <LIST>` | 平台,如 `Windows,Android`(默认 `Windows,Android`) |
|
||
| `--output <DIR>` | 资源发布根目录(默认 `./bat-resources`) |
|
||
| `--snapshot <PATH>` | 覆盖 snapshot 路径(默认 `<output>/current/official-sync-snapshot.json`) |
|
||
| `--curl <PATH>` | curl 可执行文件(默认 `curl`) |
|
||
| `--proxy <URL\|auto\|none>` | curl 代理覆盖(默认 `auto`,从环境变量检测)。scheme 支持 http/https/socks4/socks4a/socks5/socks5h |
|
||
| `--no-proxy` | 强制直连 |
|
||
| `--unzip <PATH>` | unzip 可执行文件(默认 `unzip`) |
|
||
| `--dry-run` | 不写同步状态 |
|
||
| `--plan` | dry-run 时输出计划中的 URL |
|
||
| `--force` | 强制下载/刷新 |
|
||
| `--audit-local` / `--no-audit-local` | 启用/关闭本地 manifest 审计 |
|
||
| `--repair` / `--no-repair` | 启用/关闭自动修复 |
|
||
|
||
### 守护(Daemon)
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--watch` | 前台常驻循环 |
|
||
| `--daemon` | 启动脱离终端的后台 watch 进程 |
|
||
| `--state-dir <DIR>` | 后台状态目录(默认 `/tmp/bat-pid`) |
|
||
| `--interval <DURATION>` | 正常检查周期(默认 `1h`) |
|
||
| `--error-retry <DURATION>` | 失败后重试周期(默认 `60s`) |
|
||
| `--quiet-up-to-date` / `--no-quiet-up-to-date` | 静默/总是打印 up-to-date 报告 |
|
||
| `--tail <N>` | `logs` 命令返回的日志行数(默认 `200`) |
|
||
|
||
### 输出(Output)
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--human` | 人类可读输出(默认) |
|
||
| `--json` | 面向脚本的稳定 JSON 输出 |
|
||
| `--progress` / `--no-progress` | 启用/关闭 stderr 进度日志 |
|
||
| `--banner` / `--no-banner` | 启用/关闭启动横幅 |
|
||
| `-h`, `--help` | 显示帮助 |
|
||
|
||
### 默认值与运行时行为
|
||
|
||
- 平台:`Windows,Android`。
|
||
- 资源输出:`./bat-resources`(`current` → `versions/<id>`、`.staging/<id>`)。
|
||
- 后台状态目录:`/tmp/bat-pid`(`bat.sock`、`bat.pid`、`bat-status.json`、`bat-daemon.log`、`bat-events.jsonl`、短生命周期 `bat-control.lock`;代理凭据在 `bat-proxy.secret`,`0600`)。
|
||
- 强制刷新:每天北京时间(UTC+8)`03:00`、`16:00`、`18:00` 各一次。
|
||
- 状态类文件默认 `0600` 权限,读写不跟随 symlink。
|
||
|
||
---
|
||
|
||
## 4. 退出码
|
||
|
||
| 退出码 | 含义 |
|
||
|---|---|
|
||
| `0` | 成功;`verify`/`doctor` 检查通过 |
|
||
| `1` | 普通错误 |
|
||
| `75` | 资源目录锁冲突(有 live daemon 正在管理同一目录,或 `.official-sync.lock` 被占用) |
|
||
|
||
`verify` 或 `doctor` 发现问题也返回非 0。`--json` 模式下错误以 JSON 写到 stderr。
|
||
|
||
---
|
||
|
||
## 5. 错误码参考
|
||
|
||
`bat` 使用一套稳定的数字错误码,作为 CLI、daemon RPC 和结构化日志的公共错误契约。
|
||
|
||
- **格式**:`BAT-ERR-<域 3 位><序号 3 位>`,共 6 位,例如 `BAT-ERR-300012`。
|
||
- **域**:错误码首位按百位分大类。
|
||
- **承载结构**(RPC envelope 的 `error` 字段、`--json` 输出、`bat-events.jsonl` 一致):
|
||
|
||
```json
|
||
"error": {
|
||
"code": "BAT-ERR-310001",
|
||
"kind": "proxy_failure",
|
||
"domain": "network",
|
||
"location": "official-sync.download.pull_one",
|
||
"message": "代理返回 407 认证失败",
|
||
"retryable": false
|
||
}
|
||
```
|
||
|
||
`location` 是稳定的「组件·操作」标签(跟随语义、不随行号漂移)。`retryable` 是该类错误的默认可重试性。
|
||
|
||
> 说明:错误码模型(`core/src/error_code.rs`)已建立并作为公共契约;将各链路的报错逐步接入到该码表的工作在 issue #1 下推进。下表随码表更新。
|
||
|
||
### 域一览
|
||
|
||
| 域 | 区间 | 含义 |
|
||
|---|---|---|
|
||
| input | `1xxxxx` | 输入/配置:CLI 参数、配置校验、代理配置 |
|
||
| path_security | `2xxxxx` | 路径/安全边界:危险目录、路径逃逸、symlink、权限 |
|
||
| network | `3xxxxx` | 网络/下载:HTTP/网络错误、代理故障、重试耗尽、quarantine |
|
||
| integrity | `4xxxxx` | 校验/完整性:BLAKE3、官方 seed hash、size、ZIP 结构 |
|
||
| publish_storage | `5xxxxx` | 发布/版本状态/存储:staging、原子发布、version-state、锁、CAS |
|
||
| parse | `6xxxxx` | 解析/适配:manifest、UnityFS、GameMainConfig |
|
||
| task_rpc | `7xxxxx` | 任务/RPC:未知方法、参数非法、未实现、任务不存在 |
|
||
| internal | `9xxxxx` | 内部/未知:兜底 |
|
||
|
||
### 码表
|
||
|
||
| 码 | kind | 可重试 | 含义 |
|
||
|---|---|:---:|---|
|
||
| `BAT-ERR-100001` | missing_app_version | 否 | 缺少应用版本(未传 `--app-version` 且未启用 `--auto-discover`) |
|
||
| `BAT-ERR-100002` | missing_connection_group | 否 | 缺少连接组 |
|
||
| `BAT-ERR-100003` | missing_server_info_source | 否 | 缺少服务器信息来源 |
|
||
| `BAT-ERR-100004` | invalid_proxy_scheme | 否 | 代理 URL scheme 不受支持 |
|
||
| `BAT-ERR-100010` | invalid_argument | 否 | 命令行参数无效 |
|
||
| `BAT-ERR-200001` | dangerous_output_root | 否 | 输出目录被判定为危险路径 |
|
||
| `BAT-ERR-200002` | path_escape | 否 | 路径逃逸出允许根目录 |
|
||
| `BAT-ERR-200003` | symlink_rejected | 否 | 目标不允许是 symlink 或路径组件含 symlink |
|
||
| `BAT-ERR-200004` | file_permission | 否 | 文件权限或模式错误 |
|
||
| `BAT-ERR-300001` | http_forbidden | 否 | HTTP 403 |
|
||
| `BAT-ERR-300002` | http_not_found | 否 | HTTP 404 |
|
||
| `BAT-ERR-300003` | http_client_error | 否 | HTTP 其它 4xx |
|
||
| `BAT-ERR-300004` | http_too_many_requests | 是 | HTTP 429 / 请求过多 |
|
||
| `BAT-ERR-300005` | http_server_error | 是 | HTTP 5xx |
|
||
| `BAT-ERR-300010` | network_dns | 是 | DNS 解析失败 |
|
||
| `BAT-ERR-300011` | network_connect | 是 | 连接失败 |
|
||
| `BAT-ERR-300012` | network_timeout | 是 | 超时 |
|
||
| `BAT-ERR-300013` | network_tls | 是 | TLS 失败 |
|
||
| `BAT-ERR-300014` | network_interrupted | 是 | 传输中断 |
|
||
| `BAT-ERR-300015` | network_other | 是 | 其它网络错误 |
|
||
| `BAT-ERR-300020` | retry_exhausted | 否 | 下载重试次数耗尽 |
|
||
| `BAT-ERR-300021` | quarantined | 否 | URL 因反复失败进入 quarantine |
|
||
| `BAT-ERR-300030` | non_official_url | 否 | URL 不是官方 host(被拒绝) |
|
||
| `BAT-ERR-310001` | proxy_failure | 否 | 代理自身故障(认证/解析/连接代理失败) |
|
||
| `BAT-ERR-400001` | blake3_mismatch | 否 | 本地 BLAKE3 与 manifest 不符 |
|
||
| `BAT-ERR-400002` | official_hash_mismatch | 否 | 官方 seed `.hash`(xxHash32)校验不符 |
|
||
| `BAT-ERR-400003` | size_mismatch | 否 | 文件大小与 manifest 不符 |
|
||
| `BAT-ERR-400004` | zip_structure_invalid | 否 | ZIP 结构无效 |
|
||
| `BAT-ERR-500001` | resource_locked | 否 | 资源目录锁冲突(对应退出码 75) |
|
||
| `BAT-ERR-500002` | staging_prepare_failed | 否 | staging 准备失败 |
|
||
| `BAT-ERR-500003` | publish_failed | 否 | 原子发布失败 |
|
||
| `BAT-ERR-500004` | version_state_write_failed | 是 | 版本状态写入失败 |
|
||
| `BAT-ERR-500010` | cas_hash_mismatch | 否 | CAS 对象 Hash 不匹配 |
|
||
| `BAT-ERR-500011` | cas_object_not_found | 否 | CAS 对象不存在 |
|
||
| `BAT-ERR-500012` | cas_reference_underflow | 否 | CAS 引用计数下溢 |
|
||
| `BAT-ERR-500013` | cas_database | 否 | CAS 元数据库错误 |
|
||
| `BAT-ERR-600001` | manifest_parse_failed | 否 | Manifest / Addressables catalog 解析失败 |
|
||
| `BAT-ERR-600002` | unityfs_parse_failed | 否 | UnityFS 解析失败 |
|
||
| `BAT-ERR-600003` | game_main_config_failed | 否 | GameMainConfig 解密/解析失败 |
|
||
| `BAT-ERR-700001` | rpc_unknown_method | 否 | 未知 RPC 方法 |
|
||
| `BAT-ERR-700002` | rpc_invalid_params | 否 | RPC 参数无效 |
|
||
| `BAT-ERR-700003` | rpc_not_implemented | 否 | 方法/命名空间尚未实现 |
|
||
| `BAT-ERR-700004` | task_not_found | 否 | 任务不存在 |
|
||
| `BAT-ERR-900001` | internal | 否 | 未归类的内部错误 |
|
||
|
||
新增错误码在 `core/src/error_code.rs` 的码表登记后,同步更新本表。
|