Files
BlueArchiveToolkit/USERGUIDE.md
T
nyaKazuhaandClaude Fable 5 1a25ea58dd feat(core): 引入统一错误码模型并新增 USERGUIDE
为 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>
2026-07-17 03:57:17 -07:00

223 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 hashdry-run + 审计当前 release |
| `repair` | 重新下载本地校验失败的资源 |
| `status` | 显示 daemon 状态 |
| `stop` | 停止 daemon |
| `restart` | 重启 daemon;未显式传参时复用保存的参数 |
| `reload` | 请求 daemon 重新自动发现并强制刷新 |
| `logs` | 显示 daemon 日志尾部(配合 `--tail` |
| `doctor` | 运行时诊断(输出目录、状态目录、curl/unzip、代理、PID、socket、锁) |
| `clean-stable` | 清理 `.part`/`.tmp`/失效锁、PID、socketdaemon 运行中会拒绝执行) |
`status`/`stop`/`logs`/`reload` 和默认形态的 `refresh` 优先走 `bat.sock` JSON-RPCsocket 不可用时 `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` 的码表登记后,同步更新本表。