Files
BlueArchiveToolkit/docs/guides/official-resource-test-pull.md
T
nyaKazuha 25c2c4d40f feat: add official full pull smoke
Emit runtime download progress and validation summaries for official sync.

Add repeatable real-network full pull smoke runbook and script.

Fixes #4

Fixes #6
2026-07-14 00:48:59 +08:00

314 lines
16 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.
# 官方资源拉取用户指南
本文档描述当前可用的官方日服资源拉取流程。
默认平台:
- `Windows`
- `Android`
不包含:
- `iOS`
- `macOS`
- `bluearchive.cafe` 或其他镜像域名
- 任何本地客户端目录
- 任何已安装的官方启动器或 Windows 客户端
## 0. 快速入口
查看命令参数:
```bash
cargo run -p bat-infrastructure --bin bat -- --help
```
构建生产 binary
```bash
cargo build --release -p bat-infrastructure --bin bat
```
使用 release binary 做一次 dry-run
```bash
target/release/bat \
--auto-discover \
--dry-run
```
常驻自动更新:
```bash
target/release/bat \
--auto-discover \
--watch
```
默认资源输出目录是 `./bat-resources`,默认后台状态目录是 `/tmp/bat-pid`。资源输出目录是发布根目录:非 dry-run 同步先写 `<output>/.staging/<id>`,校验完成后移动到 `<output>/versions/<id>`,再原子切换 `<output>/current` symlink;生产读取方应读取 `current`。后台状态目录会保存 `bat.sock``bat.pid``bat-status.json``bat-daemon.log``bat-events.jsonl` 和短生命周期的 `bat-control.lock`;其中 `bat.sock` 是 live daemon 的 Unix socket JSON-RPC 控制通道,`bat-events.jsonl` 是带轮转的结构化 JSONL 事件日志,`bat-status.json` 保存最后成功时间、下次检查时间、最后错误摘要和当前下载进度,`bat-control.lock` 串行化 `status/stop/restart/reload/logs/refresh` 等控制命令。生产资源输出目录必须是独立目录;需要覆盖时用 `--output <资源目录>`,不要使用已有游戏客户端目录、官方启动器安装目录、人工维护资源目录,或开发机上的 `/home/wanye/D/BlueArchive`
同步流程会拒绝危险输出目录、路径逃逸和现有 symlink 路径组件;下载目标、`.part`、manifest、snapshot、PID、status、log 和控制锁文件不会跟随 symlink,daemon 状态类文件默认以 `0600` 权限创建。
## 1. 当前流程
Linux 生产运行时链路只走官方日服 HTTP 资源,不安装、不启动、不依赖官方启动器二进制:
1. 显式执行 `--auto-discover`,通过官方 HTTP metadata 自动发现 `app-version``server-info` URL 和默认 `connection-group`
2. 请求官方 `server-info`
3. 生成 Windows + Android 的官方资源 discovery 端点。
4. 拉取 seed catalog,生成完整官方 pull plan。
5. dry-run 只输出 URL;非 dry-run 下载全部官方 URL 到 staging,验收完成后原子发布到 `current`
`--auto-discover` 会下载官方 metadata,并按官方 manifest 临时获取 `resources.assets` 解析 `GameMainConfig`;旧 ZIP manifest 才会下载临时 game zip。该流程不会安装官方启动器,也不会执行官方启动器进程。`--launcher-bootstrap` 只是旧命名兼容别名,新流程不要再推荐使用。
## 2. 可选 metadata 审计
如需单独审计官方 metadata API 和官方 ZIP 链路,可以手动运行:
```bash
cargo run -p bat-infrastructure --example official_launcher_bootstrap -- \
--launcher-version 1.7.2 \
--manifest
```
这一步会输出:
- `game_latest_version`
- `game_latest_file_path`
- `primary_cdn`
- `backup_cdn`
- `manifest_url`
- `manifest_source`
- `manifest_file_count`
所有 URL 都应来自官方域名。
## 3. 先做 dry-run
推荐开发和生产自动化的默认流程是显式打开 `--auto-discover`
```bash
cargo run -p bat-infrastructure --example official_pull_plan -- \
--auto-discover \
--output /tmp/bat-official-pull \
--dry-run
```
如果你要复现某次已审计的 metadata snapshot,也可以显式传入官方 `server-info` 文件名:
```bash
cargo run -p bat-infrastructure --example official_pull_plan -- \
--server-info-file r93_70_xxxxxxxxxxxxxxxxxxxx.json \
--connection-group Prod-Audit \
--app-version 1.70.0 \
--output /tmp/bat-official-pull \
--dry-run
```
如果你已经把官方 `server-info` JSON 存成只读本地文件,也可以使用:
```bash
cargo run -p bat-infrastructure --example official_pull_plan -- \
--server-info-path /path/to/server-info.json \
--connection-group Prod-Audit \
--app-version 1.70.0 \
--output /tmp/bat-official-pull \
--dry-run
```
检查输出时,重点看:
- `platforms=[Windows, Android]`
- `discovery_url_count` 大于 0
- `content_url_count` 大于 0
- 不出现 `bluearchive.cafe`
## 4. 执行真实拉取
确认 dry-run 正常后,去掉 `--dry-run`
```bash
cargo run -p bat-infrastructure --example official_pull_plan -- \
--auto-discover \
--output /tmp/bat-official-pull
```
程序会:
- 只接受官方 URL
- 下载完整官方资源集合
- 下载成功后在 release 目录维护 `official-download-manifest.json`
- 已存在目标文件只有在本地下载清单中的 size 和 BLAKE3 校验通过时才会跳过;`.zip` 文件还必须通过 ZIP central directory / local header 结构校验
- `TableCatalog.bytes``BundlePackingInfo.bytes``MediaCatalog.bytes` 会用官方 `.hash` 做强校验;该 `.hash``xxHash32(seed=0)` 的十进制文本
- `catalog_*.hash` 是 Unity Addressables/SBP 写出的 catalog 变更标记,来源是 `HashingMethods.Calculate(json/bin catalog)` 生成的 `Hash128` 文本;它不是 seed catalog 的 `xxHash32` 规则,目前不作为 zip/JSON 内容强校验
- 存在 `.part` 临时文件时会尝试断点续传
- 新下载先写 `.part`,成功并通过必要校验后再替换为最终文件;如果断点续传后的 `.zip` 结构校验失败,会删除 `.part` 并重新全量下载
- 把结果发布到 `--output/current`
## 5. 自动更新检查
正式自动更新入口是 `bat`。它会保存上一次成功同步的 snapshot,下次运行时先自动发现当前官方 metadata,再和 snapshot 对比:
- 每轮都会先拉取轻量官方 metadata 和 `.hash` marker。
- URL 没变但 `.hash` / marker 内容变更时,也会判定为需要更新。
- 即使远端 snapshot 未变化,只要 active release 没有任何当前 pull plan 的本地 manifest 条目或目标文件,也会按首次运行处理并执行全量拉取。
- 远端无变化时,默认执行 active release 中的 `official-download-manifest.json` audit。
- 本地文件缺失、路径不一致、size 不一致、BLAKE3 不一致或 ZIP 结构无效时,默认进入 repair 并重下必要文件。
- 官方 seed `.hash` 校验失败会让本轮失败,并清理对应本地 manifest 条目;下一轮会继续把这类文件视为需要 repair,而不是把失败产物当作健康缓存复用。
- 远端和本地都一致:单次模式输出 `update_status=up_to_date`,watch 模式默认静默并等待下次检查。
- 有远端变化或本地 repair:生成 pull plan,下载完整官方资源到 staging,成功后更新 snapshot 并原子发布到 `current`
- `--dry-run`:只报告本次是否会下载,不写 snapshot;如果 cache miss,也不会写入新的 bootstrap cache。
- `--dry-run --plan`:除更新判断外,还会解析 seed catalog 并打印完整下载 URL。
- 真实更新会输出 `downloaded_count``resumed_count``skipped_count``transferred_bytes``official_seed_hash_verified_count`
- 校验报告分层输出 `official_seed_hash_verified_count``local_manifest_verified_count``addressables_marker_checked_count``unverified_marker_count`
- 下载阶段复用同一套本地清单、ZIP 结构校验和 `.part` 续传逻辑;没有清单或校验不匹配的文件会重新下载。
资源同步状态文件默认分布如下:
- `<output>/current/official-sync-snapshot.json`:上一次成功同步的 v2 snapshot,包含 app version、connection group、bundle version、addressables root、endpoint URL、官方 seed `.hash` 内容、Addressables `catalog_*.hash` marker、launcher metadata 摘要和 `GameMainConfig` 摘要。
- `<output>/official-bootstrap-cache.json``--auto-discover``GameMainConfig` 解析缓存。launcher metadata 未变时复用缓存;metadata 变化时才通过官方 HTTP 按 manifest 下载必要 `resources.assets` 或旧版 game zip 到临时目录解析。
- `<output>/current/official-download-manifest.json`:本地下载强校验清单,记录 URL、相对路径、size 和 BLAKE3。
先 dry-run
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--dry-run
```
如果需要在 dry-run 阶段审阅完整下载 URL,加 `--plan`
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--dry-run \
--plan
```
确认后执行真实更新:
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover
```
Rust 常驻更新模式默认每 1 小时执行一次检查,符合则静默,不符合则自动拉取/repair 并输出人类可读摘要;需要稳定 JSON report 时加 `--json`
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--watch
```
后台自动运行使用 `--daemon`。它会启动一个脱离终端的 watch 子进程,资源默认写入 `./bat-resources`,后台控制和状态默认写入 `/tmp/bat-pid`
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--daemon
cargo run -p bat-infrastructure --bin bat -- status
cargo run -p bat-infrastructure --bin bat -- logs
cargo run -p bat-infrastructure --bin bat -- restart
cargo run -p bat-infrastructure --bin bat -- reload
cargo run -p bat-infrastructure --bin bat -- stop
```
`status``stop``logs``reload` 和默认形态的 `refresh` 会优先连接 `bat.sock`,通过 Unix socket JSON-RPC 和 live daemon 通信;socket 不可用时,`status``stop` 会回退到 PID/状态文件兼容路径。`status` 会显示最后成功时间、下次检查时间、最后错误摘要、当前阶段、当前下载 URL 进度、文本日志路径、结构化日志路径和轮转日志路径。控制命令会通过 `bat-control.lock` 做跨进程互斥,失效或损坏的控制锁会在下次控制命令或 `clean-stable` 时恢复。`restart` 会停止旧后台进程并按保存参数或显式参数重新启动;`reload` 在未显式传入同步参数时不会重启进程,而是唤醒或排队 watch 循环重新执行自动发现和强制刷新:空闲睡眠时立即执行,正在同步时等当前轮结束。所有命令默认输出人类可读摘要,脚本集成时加 `--json`
如果要把后台状态目录改到其他位置,使用 `--state-dir <目录>`
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--daemon \
--state-dir /tmp/bat-prod-pid
cargo run -p bat-infrastructure --bin bat -- status --state-dir /tmp/bat-prod-pid
cargo run -p bat-infrastructure --bin bat -- logs --state-dir /tmp/bat-prod-pid --tail 200
cargo run -p bat-infrastructure --bin bat -- stop --state-dir /tmp/bat-prod-pid
```
常用手动维护命令:
```bash
cargo run -p bat-infrastructure --bin bat -- refresh
cargo run -p bat-infrastructure --bin bat -- refresh --force
cargo run -p bat-infrastructure --bin bat -- verify
cargo run -p bat-infrastructure --bin bat -- repair
cargo run -p bat-infrastructure --bin bat -- doctor
cargo run -p bat-infrastructure --bin bat -- clean-stable
```
- `refresh` 执行一次同步检查;`refresh --force` 强制刷新并重新匹配当前官方资源。
- 如果后台 daemon 正在运行,并且 `refresh` 没有显式指定另一套资源目录、server-info、connection-group、app-version、platforms、snapshot、curl 或 unzip 参数,`refresh` / `refresh --force` 会通过 RPC 唤醒或排队后台进程执行;否则作为一次性前台同步运行。一次性前台 `run/watch/refresh/repair` 如果要写入 live daemon 正在管理的同一资源目录,会返回 locked 错误;需要先 `stop` 或改用默认 `refresh` 走 RPC。
- `verify` 只读验证当前官方计划、本地 manifest size+BLAKE3、ZIP 结构,以及本地已有官方 seed `.bytes/.hash` 对的 xxHash32;资源缺失、远端变化或本地损坏时返回非 0。
- `repair` 在有异常资源时尝试重新下载并修复,成功后重新写 manifest 和 snapshot。
- `doctor` 检查输出目录、后台状态目录、curl/unzip、后台 PID、RPC socket、资源锁和 daemon 控制锁。
- `clean-stable` 只能在后台未运行且 RPC socket 不可连接时清理 `.part``.tmp`、失效或损坏的 PID、socket、资源锁和 daemon 控制锁,不删除正式资源文件。
如需调整间隔:
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--watch \
--interval 30m \
--error-retry 60s
```
默认平台是 `Windows,Android`,无需显式传 `--platforms`;只有要覆盖默认平台时才传。`--interval` 是正常检查周期,默认 `1h`watch/daemon 模式还会在每天北京时间(UTC+8)`03:00``16:00``18:00` 强制执行一次自动刷新,该轮会注入 `force=true`,并且会中断普通 interval 的 sleep。`--error-retry` 是下载、发现或校验失败后的重试周期,默认 `60s`,也可以用 `--error-retry-seconds 60`。CLI 默认启动时向 stderr 打印 `BlueArchiveToolkit` ASCII banner,并把阶段进度日志写到 stderr,包括自动发现、server-info、marker、catalog、audit、download、snapshot 和 publish 阶段;download 阶段会输出总体下载进度和单文件开始/完成状态,audit 阶段会输出官方 `.hash`、本地 BLAKE3、需修复项和 ZIP 结构校验结果摘要。daemon 还会写 `bat-events.jsonl` 结构化日志并按大小轮转。命令结果默认以人类可读摘要写到 stdout。需要纯机器输出时加 `--json --no-progress`,需要显式开启进度日志则用 `--progress`;只想关闭横幅但保留日志时可加 `--no-banner`。错误时 stderr 输出 JSON errorwatch 模式下错误 JSON 的 `next_retry_seconds` 使用失败重试周期;如果未关闭 progress,错误 JSON 前可能已有 banner 和进度日志。普通错误 exit `1`,资源目录锁冲突 exit `75``verify``doctor` 发现问题也返回非 0。
生产可以直接运行 `--watch`,也可以用 `--daemon` 后台运行,或者用 systemd service、容器或 Go 进程守护它。cron/systemd timer 仍可调用单次模式,但不再是 Rust 自动更新的唯一方式。项目是否热更新、热重载或重启进程,由上层业务集成决定。生产资源目录应使用独立输出目录,不要指向现有客户端或人工维护的资源目录;上层读取资源时应读取 `--output/current`,不要读取 `.staging``versions` 中未切换的目录。非 dry-run 每轮会创建 `--output/.official-sync.lock`,防止并发写同一资源目录;live daemon 还会阻止前台写命令直接修改它正在管理的同一目录。
需要只做探测时可以加 `--dry-run`。需要关闭本地 audit 或 repair 时可以显式使用 `--no-audit-local``--no-repair`,但生产同步默认应保持开启。
## 6. 真实全量 smoke
真实官方网络全量拉取 smoke 已固化为 runbook 和脚本:
```bash
scripts/official-full-pull-smoke.sh
# 或
make official-smoke
```
默认输出在 `/tmp/bat-official-smoke-<UTC timestamp>/`,脚本会执行 dry-run plan、首次全量拉取、二次 `up_to_date`、本地文件破坏后的 `repair`、repair 后 `verify`,并检查 stderr progress log 中存在总体下载进度、单文件进度和校验结果摘要。完整说明见 `docs/guides/official-full-pull-smoke.md`
## 7. 例外输入
可接受的 `server-info` 输入是:
- `--auto-discover`
- `--server-info-url <官方 URL>`
- `--server-info-file <官方文件名>`
- `--server-info-path <本地官方 JSON>`
如果没有显式 `server-info` 输入,必须手动加 `--auto-discover` 才会走官方 metadata / `GameMainConfig` 辅助发现链路。不要在 Linux 生产任务里依赖已安装启动器或本地客户端目录。
## 8. 代码入口
当前可用的用户入口:
- `infrastructure/examples/official_launcher_bootstrap.rs`
- `infrastructure/examples/official_pull_plan.rs`
- `infrastructure/src/bin/bat_official_sync.rs`
- `infrastructure/examples/official_update_check.rs`(历史/开发入口;生产优先使用 `bat`
- `adapters/examples/yostar_jp_client_bootstrap.rs`
- `adapters/examples/yostar_jp_discovery.rs`
- `adapters/examples/yostar_jp_inventory.rs`
## 8. 验证
推荐验证命令:
```bash
cargo test -p bat-adapters
cargo test -p bat-infrastructure
cargo test -p bat-infrastructure --example official_launcher_bootstrap -- --nocapture
cargo test -p bat-infrastructure --example official_pull_plan -- --nocapture
cargo test -p bat-infrastructure --bin bat -- --nocapture
```