13 KiB
官方资源后端说明
本文档说明 BlueArchiveToolkit 中“官方资源后端”的职责、数据流和工作原理,供审核使用。
1. 范围
这个后端只处理 日服官方资源,只接受官方 .jp/.com 域名下的资源链路。
明确排除:
bluearchive.cafe- 任何镜像层、转写层、二次代理层
- 人工拼接出来的样例 URL
- Linux 生产环境安装或执行官方启动器
- 把已安装客户端目录或官方启动器安装目录当作生产输入
当前默认平台集合是:
WindowsAndroid
iOS 和 macOS 已从默认支持中移除。
2. 后端负责什么
| 层 | 任务 | 结果 |
|---|---|---|
| 发现层 | 读取官方 server-info,选择 connection group 和版本覆盖 |
得到官方资源根和种子端点 |
| 清单层 | 解析 BundlePackingInfo.bytes、TableCatalog.bytes、MediaCatalog.bytes |
得到完整文件清单 |
| 计划层 | 合并 discovery + inventory,去重并保序 | 得到全量 pull plan |
| 下载层 | 校验官方 URL,调用下载器,落盘并记录字节数 | 得到本地资源副本 |
| 导入层 | 将 bundle 写入 CAS 和 ResourceRepository | 得到可查询的资源索引 |
| 同步层 | 比较当前快照和历史快照 | 决定下载、校验、发布 |
| 更新层 | 保存上次官方 snapshot,定期执行 discovery + diff + pull | 形成自动更新闭环 |
3. 工作原理
3.0 Linux 生产约束
生产环境目标是 Linux 后端任务,不是 Windows 桌面客户端环境。
因此生产同步入口必须满足:
- 不要求安装官方启动器。
- 不要求启动官方启动器进程。
- 不要求把生产环境当作客户端安装目录。
- 可以显式执行 official metadata discovery 自动发现
server-infoURL、connection-group和app-version。 - 也可以通过配置、调度状态或已审计 metadata snapshot 显式提供这些值。
--auto-discover只允许通过官方 HTTP metadata 和临时目录解析GameMainConfig;launcher metadata 未变时必须复用缓存,metadata 变化时才按 manifest 重新下载必要resources.assets或旧版官方 game zip。
3.1 发现官方资源根
入口是 YostarJpServerInfo。
流程是:
- 读取官方
server-infoJSON。 - 按
connection_group + app_version规则选择版本覆盖。 - 从
AddressablesCatalogUrlRoot提取root token。 - 校验该 root 只能落在官方
prod-clientpatch.bluearchiveyostar.com之下。 - 基于 root token 生成 discovery 端点。
对应实现主要在:
adapters/src/official/yostar_jp.rs
3.2 枚举完整资源清单
资源清单不是“猜几个文件”,而是从官方 catalog 字节里提取完整文件名列表。
当前做法:
- 读取
BundlePackingInfo.bytes。 - 提取所有
FullPatch_*.zip包名。 - 读取
TableCatalog.bytes。 - 提取所有表资源名,例如
ExcelDB.db。 - 读取
MediaCatalog.bytes。 - 提取所有媒体资源名,例如
JP_Airi.zip。
然后对 verified platforms 生成完整 URL 集:
- Windows patch pack
- Android patch pack
- TableBundles
- MediaResources-Windows
- MediaResources
对应实现主要在:
adapters/src/official/inventory.rsadapters/src/official/yostar_jp.rs
3.3 组装全量 pull plan
OfficialResourcePullPlan 是这个后端的关键对象。
它做三件事:
- 保存 discovery 端点。
- 保存完整 inventory。
- 用默认平台集或指定平台集生成最终 URL 列表。
all_urls() 是执行层的权威输入:
- 先放 discovery URLs
- 再放 content URLs
- 统一去重
- 保持顺序
这意味着后端拉取的是 完整资源包集合,不是抽样下载。
对应实现主要在:
infrastructure/src/official_pull.rs
3.4 执行下载
OfficialResourcePullService 负责真正下载。
工作方式:
- 检查 URL 是否属于官方 host。
- 把 URL 映射到本地输出路径。
- 读取输出目录下的
official-download-manifest.json。 - 已存在目标文件只有在本地清单中的相对路径、size、BLAKE3 都匹配时才跳过;
.zip文件还必须通过 ZIP central directory / local header 结构校验。 - 缺少清单、清单不匹配、ZIP 结构无效或文件损坏时重新下载。
TableCatalog.bytes、BundlePackingInfo.bytes、MediaCatalog.bytes总是刷新并用官方.hash强校验;该.hash是xxHash32(seed=0)的十进制文本。catalog_*.hash当前只作为 Addressables catalog 变更标记,不作为 zip/JSON 内容校验算法;Unity Addressables/SBP builder 对 JSON/bin catalog 使用HashingMethods.Calculate生成Hash128文本,运行时用它判断 remote catalog cache 是否过期,它不能套用 seed catalog 的xxHash32规则。- 官方 seed
.hash校验失败会让当前下载失败,并移除对应 data/hash URL 的本地 manifest 条目,避免失败产物在下一轮被本地 BLAKE3 audit 误判为健康缓存。 - 存在
.part临时文件时通过curl --continue-at -尝试断点续传。 - 新下载写入
.part,成功并通过必要校验后原子 rename 到最终路径;断点续传后的.zip如果结构无效,会删除.part并重新全量下载。 - 成功下载后更新本地下载清单。
- 记录最终文件大小、本次传输字节数、官方 hash 校验数和执行状态。
- 非官方 URL 直接拒绝。
路径映射时会做分段清理,避免把不安全路径写进输出目录。
对应实现主要在:
infrastructure/src/official_download.rs
3.5 导入到 CAS 和资源仓储
资源下载后,导入层会:
- 把 bundle 原始字节写入 CAS。
- 解析 UnityFS 基础摘要。
- 把资源条目写入
ResourceRepository。 - 记录资源路径、hash、大小和解析摘要。
这层的意义是把“下载到磁盘的文件”变成“可查询、可复用、可去重”的资源对象。
对应实现主要在:
infrastructure/src/import.rsinfrastructure/src/resources.rs
3.6 同步决策
同步层只做判断,不做重业务。
它比较当前快照和历史快照,关注:
- root token 是否变化
- addressables root 是否变化
- endpoint 是否变化
- bundle version 是否变化
判断结果分三类:
UpToDateDownloadAndVerifyDownloadVerifyAndPublish
对应实现主要在:
infrastructure/src/official_sync.rs
3.7 自动更新闭环
OfficialUpdateService 是当前 Rust 侧的自动更新核心,正式命令入口是 bat。
流程是:
- 显式执行
--auto-discover或读取已审计server-info输入。 --auto-discover先抓官方 launcher metadata;metadata 未变时复用official-bootstrap-cache.json中的GameMainConfig摘要,metadata 变化时按 manifest 临时下载resources.assets或旧版官方 game zip 并重新解析。- 生成当前 v2 snapshot,记录
app_version、connection_group、bundle_version、addressables_root、endpoint URL、seed.hash内容、catalog_*.hashmarker、launcher metadata 摘要和GameMainConfig摘要。 - 读取上一次成功同步写出的 snapshot。
- 使用
OfficialSyncPlan和扩展 snapshot diff 判断是否需要下载;URL 未变但.hash/ marker 内容变化也会触发更新。 - 每轮都会基于最新 seed catalog 构建当前 pull plan,并检查输出目录是否已有当前 plan 的 manifest 条目或目标文件。
- 如果远端 snapshot 未变化但输出目录没有任何当前 plan 的本地资源,仍按首次运行处理并执行全量拉取。
- 远端无变化且本地已有资源时执行 download manifest audit,检查路径、size、BLAKE3 和 ZIP 结构。
- 远端变化、本地 audit 发现 repair_needed,或首次空目录运行时,下载并校验官方 URL。
- 下载成功后写回新的 snapshot。
该入口不安装、不执行官方启动器,也不读取生产外的本地客户端目录。Rust 正式 binary bat 支持单次运行、--watch 常驻模式、--daemon 后台模式,以及 status、stop、restart、reload、logs、refresh、verify、repair、doctor、clean-stable 管理命令。--daemon 会在后台状态目录下创建 bat.sock,使用 Unix socket JSON-RPC 作为 live control plane;bat.pid、bat-status.json 和 bat-daemon.log 是快照、诊断和兼容 fallback。status、stop、logs、reload 和默认形态的 refresh 优先走 RPC;reload 会唤醒或排队 watch 循环重新自动发现并强制刷新,restart 才负责重启进程或替换启动参数。正常情况下默认每 1 小时执行一次检查;每天北京时间(UTC+8)03:00、16:00、18:00 会中断普通 sleep 并强制执行一次自动刷新,该轮注入 force=true。远端和本地一致时静默等待下次检查,不一致时自动下载或 repair。下载、发现或校验失败时不等待完整正常周期,默认 60 秒后重试;如果固定时间强制刷新失败,会保留 pending force 并按失败重试周期继续重试,可用 --error-retry 或 --error-retry-seconds 调整。默认资源输出目录是 ./bat-resources,默认后台状态目录是 /tmp/bat-pid,二者通过 --output 和 --state-dir 分别配置。单次运行仍保留为核心幂等路径,systemd service、容器或 Go 进程可以只负责守护该常驻进程;cron/systemd timer 调单次模式只是可选集成方式。项目是否热更新、热重载或重启进程,由上层业务集成决定。
对应实现主要在:
infrastructure/src/official_update.rsinfrastructure/src/bin/bat_official_sync.rsinfrastructure/examples/official_update_check.rs(历史/开发入口)
4. 官方 bootstrap 与用户流程
当前已经提供的官方用户流程分两类。
Linux 生产路径:
- 显式执行
--auto-discover,或提供已审计的官方 metadata snapshot。 official_pull_plan依据官方server-info、catalog 和 verified platforms 生成全量拉取计划。bat对比上次 snapshot 和远端.hashmarker;远端无变化时 audit 本地清单,有变化或本地损坏时下载、校验并落盘官方资源。
开发/审计辅助路径:
official_launcher_bootstrap获取官方 launcher 信息。official_game_main_config按官方 manifest 获取resources.assets(旧 ZIP manifest 则先解出)并解密GameMainConfig。- 手动确认最新 PC metadata、
server-infoURL 和默认 connection group。
自动发现路径和开发/审计辅助路径都只使用官方 HTTP 和临时目录,不安装或启动官方 launcher。
这些入口都只接受官方域名,不走 bluearchive.cafe 镜像链。
5. 已验证行为
当前代码已经验证:
- 默认平台是
Windows + Android iOS和macOS不再进入默认官方流程- verified inventory 会产出完整内容 URL 集
- pull plan 会同时包含 discovery URLs 和 content URLs
- 全量样本下是
2个 discovery URL +5个内容 URL =7个 URL OfficialUpdateService能持久化 v2 snapshot,并在远端 marker 内容变化时触发下载决策bat默认向 stderr 输出BlueArchiveToolkitASCII banner 和 progress log,stdout 默认输出人类可读摘要;支持--json输出稳定 JSON,支持--no-progress关闭进度日志,支持--no-banner只关闭横幅,支持--watch --interval 1h --error-retry 60s常驻运行,支持--daemonUnix socket JSON-RPC 控制、status、stop、restart、reload、logs、refresh --force、verify、repair、doctor、clean-stable,非 dry-run 使用.official-sync.lock防止并发写资源目录OfficialUpdateService能读写official-bootstrap-cache.json,并支持默认开启的audit_local/repairCLI 行为- 下载层能在本地文件 size/BLAKE3/path、ZIP 结构或 manifest 不匹配时重新下载
- 官方 seed
.hashmismatch 会导致下载失败,而不是降级为本地 BLAKE3 猜测 - 非官方 URL 会在 fetch/download 入口被拒绝
- 尚未在仓库中记录真实官方网络全量下载 smoke test
相关验证主要来自:
cargo test -p bat-adapters -- --nocapturecargo test -p bat-ffi -- --nocapturecargo test -p bat-infrastructure -- --nocapturecargo test -p bat-infrastructure --bin bat -- --nocapturecargo run -p bat-infrastructure --bin bat -- --help
6. 审核重点
请重点检查这几件事:
- 是否只接受官方 host。
- 是否默认只走 Windows + Android。
- 是否把完整 content URL 集都纳入
all_urls()。 - 是否拒绝镜像域名和手工拼接样例。
- 是否在下载前做了 URL 和路径安全校验。
- 是否能在官方客户端变动时只改适配层。