19 KiB
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>并原子切换currentsymlink。 - 常驻运行(
--watch)或后台化(--daemon),通过bat.sockUnix socket JSON-RPC 控制。
运行形态
# 一次性 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/状态文件):
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) |
--download-concurrency <N> |
并行下载数,1..=256(默认 4)。并行仅作用于实际网络下载;manifest/quarantine 簿记与 seed .hash 校验仍串行,fail-fast 与「不发布不完整资源」不变量保留。可下载失败重试带指数退避以对官方 CDN 礼貌 |
--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-tasks.json、短生命周期bat-control.lock;代理凭据在bat-proxy.secret,0600)。 - 强制刷新:每天北京时间(UTC+8)
03:00、16:00、18:00各一次。 - 状态类文件默认
0600权限,读写不跟随 symlink。
配置文件(.env,无参启动)
bat 首次启动时会在二进制所在目录释放一个 .env 配置模板(0600 权限,已存在则不动)。之后每次启动自动加载该文件,把其中的键作为进程环境变量(不覆盖已存在的环境变量),因此编辑 .env 后直接运行 bat(无参数)即可按配置启动。
- 优先级:命令行参数 > 进程环境变量 >
.env> 内置默认值。 - 语法:每行
KEY=VALUE;#开头为注释;值两侧成对引号会剥除;空值视为未设置。 - 支持的键:
BAT_OUTPUT、BAT_STATE_DIR、BAT_AUTO_DISCOVER、BAT_WATCH、BAT_DAEMON、BAT_PROXY、BAT_NO_PROXY、BAT_INTERVAL_SECONDS、BAT_ERROR_RETRY_SECONDS、BAT_DOWNLOAD_CONCURRENCY、BAT_APP_VERSION、BAT_CONNECTION_GROUP、BAT_LAUNCHER_VERSION、BAT_PLATFORMS、BAT_CURL、BAT_UNZIP、BAT_JSON、BAT_QUIET_UP_TO_DATE;也可以直接写HTTPS_PROXY等通用环境变量(走现有代理自动检测)。布尔值支持1/0/true/false/yes/no/on/off。 BAT_WATCH/BAT_DAEMON只对无子命令的bat生效(两者同时为1时 daemon 优先);命令行显式传入--watch/--daemon/--dry-run时.env的模式开关让位。status/verify等子命令不受它们影响。BAT_REDIS_URL/BAT_REDIS_PASSWORD为预留键:Redis 任务后端尚未接入,当前任务历史持久化在<state-dir>/bat-tasks.json。- 设
BAT_SKIP_ENV_FILE=1可让bat完全跳过.env的生成与加载。
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一致):"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)已建立并作为公共契约;下载、launcher/metadata、server-info/marker、配置校验、任务/RPC 等主要链路已接入该码表。剩余未实现命名空间和后续引擎能力继续按本表扩展。
域一览
| 域 | 区间 | 含义 |
|---|---|---|
| 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-300031 |
launcher_api_rejected | 否 | 官方启动器 API 返回非 200 业务码(版本/鉴权被拒等) |
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-600004 |
launcher_response_invalid | 否 | 官方启动器链内容无效(API 响应、远端 manifest 或包内容无法解析/缺少必需内容) |
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-700005 |
task_interrupted | 否 | 任务因 daemon 停止/重启而中断 |
BAT-ERR-900001 |
internal | 否 | 未归类的内部错误 |
新增错误码在 core/src/error_code.rs 的码表登记后,同步更新本表。
6. Daemon RPC 接口
bat --daemon 在后台状态目录下创建 bat.sock(Unix socket),提供换行分隔的 JSON-RPC 2.0 控制面。CLI 的 status/stop/logs/reload/refresh 优先走它;Go 服务层也应通过这个进程边界调用,而非 FFI。
传输与 envelope
-
请求:一行 JSON-RPC 2.0,
{"jsonrpc":"2.0","id":<n>,"method":"<ns>.<action>","params":{…}}。 -
响应:JSON-RPC 2.0,应用层负载统一装入
result的 envelope:{"jsonrpc":"2.0","id":1,"result":{ "ok": true, "status": "ok", "data": { … }, "request_id": "req-<pid>-<seq>" }}ok:应用层成功与否。失败时ok=false、status="error"、error为 §5 的ApiError结构(含BAT-ERR码)。status:ok|accepted(长任务已入队) |error。request_id:进程内唯一请求 ID。- 请求解析失败(畸形 JSON)走 JSON-RPC 顶层
error(如-32700),不进 envelope。
方法命名空间
方法采用 <namespace>.<action>。bat.* 为兼容别名(解析为 daemon.*)。
| 方法 | 状态 | 说明 |
|---|---|---|
daemon.status |
✅ | 后台状态快照 |
daemon.logs |
✅ | 日志尾部(params.tail,默认 200) |
daemon.stop |
✅ | 请求停止(accepted) |
daemon.reload |
✅ | 请求重新发现并强制刷新(accepted) |
daemon.refresh |
✅ | 请求刷新检查(params.force,accepted) |
resource.state |
✅ | 资源发布根 + 版本状态 + 上次同步结果 |
resource.sync |
✅ | 触发同步任务(params.force),返回 task_id |
resource.verify |
✅ | 触发校验任务(dry-run + audit),返回 task_id |
resource.manifest |
✅ | 当前版本下载 manifest 分页查询(params.offset 默认 0、params.limit 默认 100/上限 1000) |
catalog.status |
✅ | 当前已发布版本的 catalog 概览(app/bundle 版本、addressables 根、端点与 marker 计数、launcher 元数据) |
catalog.versions |
✅ | 版本历史:current / in_progress / previous / failed |
catalog.diff |
✅ | 当前 snapshot 相对上一个可用版本的差异(base_delta + extended_delta + 变更端点 URL) |
catalog.refresh |
✅ | 触发 catalog 更新检查任务(dry-run 计划,不下载;params.force),返回 task_id |
task.status |
✅ | 查询任务(params.task_id) |
task.list |
✅ | 列出全部任务(最新在前) |
task.cancel |
✅ | 请求取消任务(params.task_id);协作式,在同步检查点生效 |
task.logs |
✅ | 返回任务的进度日志(params.task_id,有界) |
resource.repair / patch.* / unityfs.* / task.create |
⏳ | 已规划,返回 BAT-ERR-700003(not implemented);repair 待引擎支持独立修复模式,patch/unityfs 待引擎实现 |
| 未知方法 | — | BAT-ERR-700001(unknown method) |
只读查询(resource.state / resource.manifest / catalog.status / catalog.versions / catalog.diff)在尚无已发布版本或对应文件不存在时返回 ok: true 且 data.available: false(正常状态而非错误,便于调用方直接分支)。
任务模型
resource.sync / resource.verify / catalog.refresh 是异步任务:入队即返回 { "task_id": "task-<pid>-<seq>", "kind": "resource.sync" }(status: "accepted"),实际执行由后台任务 worker 串行完成,通过 task.status / task.list 轮询。任务记录:
{ "id": "task-1234-1", "kind": "resource.sync",
"status": "queued|running|succeeded|failed",
"stage": "download", "message": "…",
"created_at": …, "updated_at": …, "started_at": …, "finished_at": …,
"error": { … }, "result": { … } }
task.cancel请求取消:置任务的取消标志,worker 在下一个同步检查点中止,任务转为cancelled(协作式,不硬杀正在执行的 curl)。- 与后台 watch 循环的定时同步通过进程内锁互斥(任务等待而非失败)。
- 任务历史持久化在
<state-dir>/bat-tasks.json(版本化、0600原子写):生命周期转换(入队/开始/结束)时落盘,进行中任务的stage/message/日志以内存实时值为准、随下一次转换写入。daemon 重启后历史任务经task.status/task.list/task.logs仍可查;重启时仍处于queued/running的任务标记为failed(错误码BAT-ERR-700005task_interrupted)。文件损坏时改名bat-tasks.json.corrupt留证并从空历史开始。历史保留最近 64 条(运行中任务不裁剪)。
示例
# 触发同步任务并取回 task_id(socat 演示)
printf '{"jsonrpc":"2.0","id":1,"method":"resource.sync","params":{"force":true}}\n' \
| socat - UNIX-CONNECT:/tmp/bat-pid/bat.sock
# 轮询任务
printf '{"jsonrpc":"2.0","id":2,"method":"task.status","params":{"task_id":"task-1234-1"}}\n' \
| socat - UNIX-CONNECT:/tmp/bat-pid/bat.sock
# 查询当前 catalog 概览与版本历史
printf '{"jsonrpc":"2.0","id":3,"method":"catalog.status"}\n' \
| socat - UNIX-CONNECT:/tmp/bat-pid/bat.sock
printf '{"jsonrpc":"2.0","id":4,"method":"catalog.versions"}\n' \
| socat - UNIX-CONNECT:/tmp/bat-pid/bat.sock
# 分页读取当前版本的下载 manifest
printf '{"jsonrpc":"2.0","id":5,"method":"resource.manifest","params":{"offset":0,"limit":50}}\n' \
| socat - UNIX-CONNECT:/tmp/bat-pid/bat.sock