Files
BlueArchiveToolkit/docs/architecture/resource-release-layout.md
T
nyaKazuha 03021ad649
bat-rust / Build and test Rust (push) Canceled after 0s
docs(project): 同步维护冻结与运行文档
补齐解析模块维护冻结规则,并同步 CURRENT_STATUS、CURRENT_GAPS、PROJECT_PLAN、RPC 参考、部署指南、用户指南和官方资源运行说明。

文档同时反映 bat-api 资源 bootstrap/分发边界、官方同步解析缓存、TextUnit 队列、双目录发布和 patch 入口的当前状态。

验证:未运行新命令;本轮已按要求停止重复构建/测试。
2026-07-31 00:45:46 +08:00

16 KiB
Raw Blame History

官方资源 Release 布局与资源侧契约

  • 更新时间2026-07-27
  • 用途:冻结日服官方资源在本地发布根上的布局、URL 映射、seed 规则、bat/bat-api 关系,以及 bat-api 分发 path 的 1:1 对应关系。
  • 范围:资源发现 / 清单 / 落盘 / 只读分发(不是完整游戏业务 API)。
  • 权威代码
    • URL / 平台 / seedadapters/src/official/yostar_jp.rs
    • inventory 抽取:adapters/src/official/inventory.rs
    • 落盘与 manifestinfrastructure/src/official_download.rsdestination_for_url
    • 发布布局:infrastructure/src/official_update.rs
    • 分发:cmd/bat-api + internal/api(见 docs/reports/GO_STATUS.md

1. 产品边界(资源侧)

角色 组件 职责
同步 / 运维(近乎全自动) Rust bat auto-discover、拉取、校验、发布、watch/daemon、RPC 后端
资源 bootstrap / 只读分发 Go bat-api 同环境经 bat.sock 发现已发布版本和 resource_root,提供 /v1/bootstrap、server-info 改写和官方 CDN path 字节
试验 CLI Go cmd/batbin/bat-go 非产品;禁止与 Rust bat 重名

禁止:把已安装客户端目录或 /home/wanye/D/BlueArchive 当作生产输入;真实全量样本优先服务器 release 或 /tmp 隔离目录。


2. 发布根布局(L1

<output>/                          # 官方原版资源发布根(--output / BAT_OUTPUT
  current -> versions/<id>         # 原子 symlink,生产读侧
  versions/<id>/                   # 已发布 versioned release= resource_root
    official-download-manifest.json
    official-parse-cache.json       # 校验后派生解析缓存,不是汉化产物
    official-textunit-index.json    # TextUnit 明细与解析错误索引,不是汉化产物
    official-textunit-tasks.json    # 翻译任务候选派生队列,不发 Crowdin 网络请求
    crowdin-textunit-queue.json     # Crowdin worker 离线输入队列
    official-sync-snapshot.json     # 常在 active root / current 下
    official-launcher-bootstrap.json # 官方 launcher 引导链版本化产物
    prod-clientpatch.bluearchiveyostar.com/
      <root_token>/
        TableBundles/
          TableCatalog.bytes
          TableCatalog.hash
          <table files...>           # e.g. ExcelDB.db, Excel.zip
        Windows_PatchPack/
          BundlePackingInfo.bytes
          BundlePackingInfo.hash
          catalog_StandaloneWindows64.zip
          catalog_StandaloneWindows64.hash
          FullPatch_NNN.zip
        Android_PatchPack/
          BundlePackingInfo.bytes
          BundlePackingInfo.hash
          catalog_Android.zip
          catalog_Android.hash
          FullPatch_NNN.zip
        MediaResources-Windows/
          Catalog/MediaCatalog.bytes
          Catalog/MediaCatalog.hash
          GameData/...
          Prologue/...
        MediaResources/              # Android
          Catalog/MediaCatalog.bytes
          Catalog/MediaCatalog.hash
          ...
    yostar-serverinfo.bluearchiveyostar.com/   # 若曾下载 server-info
      <name>.json
  .staging/<id>/                   # 未发布写侧(失败可复用)
  official-version-state.json      # 发布根级版本状态
  official-bootstrap-cache.json    # auto-discover 缓存
  official-launcher-bootstrap.pending.json # 维护期 launcher 已前进但资源未开放时的待处理证据

<localized-output>/                # 汉化产物发布根(--localized-output / BAT_LOCALIZED_OUTPUT
  current -> versions/<id>         # 已汉化后才切换;未汉化状态不发布
  versions/<id>/                   # 与官方相对路径一致的汉化资源
  localized-version-state.json     # 预留:后续 Patch 发布阶段维护,官方同步阶段不写入

官方资源发布和汉化发布是两个独立状态:

  • not_localized:官方原版资源已经完成下载、校验和发布,汉化资源尚未发布;这是官方同步完成后的默认状态。
  • localized:同一官方版本的原版资源和汉化资源都已发布,生产侧可以同时提供两套资源。

2.1 读侧 vs 写侧

阶段 根目录
下载写入 <output>/.staging/<id>
发布完成 rename 到 versions/<id>,再切换 current
生产读取 / bat-api RPC 给出的 version.resource_root;通常等价于 current 解析后的 versioned 目录

3. URL → 磁盘映射(核心不变量)

实现:OfficialResourcePullService::destination_for_url

https://{host}/{path...}  →  <resource_root>/{host}/{path...}

规则:

  1. https://
  2. host 必须是官方 JP 资源 host(见下节)
  3. path 分段不得为 . / ..
  4. 禁止 query / fragment(否则直接拒绝,避免同路径覆盖)
  5. 分段经 sanitize 后 join;结果必须在 resource_root

3.1 官方 host

Host 用途
prod-clientpatch.bluearchiveyostar.com Addressables / Table / Media / PatchPack 内容
yostar-serverinfo.bluearchiveyostar.com server-info JSON

launcher 包 CDN 属于启动器链,不是默认资源 release 主体。Rust bat 会把启动器链中与资源发现相关的 launcher metadata、CDN config、remote manifest 文件列表、选中的 resources.assets 来源和 GameMainConfig 摘要写入 official-launcher-bootstrap.json,供后续 bat-api / 自研客户端在 Rust 侧完成前继续以 versioned release 为权威来源。)

3.2 bat-api 对外 path1:1

GET {public-base-url}/prod-clientpatch.bluearchiveyostar.com/<root_token>/...
    ≡ 磁盘 <resource_root>/prod-clientpatch.bluearchiveyostar.com/<root_token>/...

默认仅服务 download manifest 索引内且 Present + size 匹配 的文件。

3.3 launcher 资源引导兼容

只读分析本机样本时可见两类启动器形态:

目录形态 说明
AllResources/YostarGames/BlueArchive_JP_Gamelauncher 官方 Electron 启动器目录
Localized / Localized_Official 汉化或改造启动器目录
AllResources/YostarGames/BlueArchive_JP 官方安装后的游戏客户端目录,含 game-launcher-config.jsonmanifest.jsonBlueArchive_Data/StreamingAssets/catalog_Remote.*

这些目录只作为开发期样本;生产链路不得依赖 /home/wanye/D/BlueArchive 或任何已安装客户端目录。

官方启动器样本中与资源发现相关的 HTTP path:

Host / path 资源侧意义
https://api-launcher-jp.yo-star.com/api/launcher/game/config 返回 launcher 观察到的最新客户端版本和包路径
https://api-launcher-jp.yo-star.com/api/launcher/game/config/json?version=...&file_path=... 返回远端 package manifest URL
https://api-launcher-jp.yo-star.com/api/launcher/advanced/game/download/cdn 返回 launcher package CDN primary / backup

bat-api 的兼容范围是资源引导,不是完整启动器更新服务:

bat-api path 行为
/v1/launcher/bootstrap 返回资源引导聚合视图:已发布 release、launcher metadata、GameMainConfig 摘要、server-info URL、client-patch base、改写后的 Addressables root
/api/launcher/game/config 返回 {code,message,data} envelope,字段来自 Rust bat snapshot/RPC 中的 launcher_metadata,并附带 resource_bootstrap_url
/api/launcher/game/config/json 返回指向 /api-launcher-jp.yo-star.com/api/launcher/resource/bootstrap.json 的资源引导 JSON URL,显式标记 package_update_manifest=false
/api/launcher/advanced/game/download/cdn 返回 public-base-url 作为资源引导 CDN 根,显式标记 package_update_manifest=false
/api-launcher-jp.yo-star.com/... 与上面裸 path 等价,便于反向代理或 hosts 映射保持官方 host 形状

数据来源只能是 Rust bat 已发布状态;当前 Go bat-api 仍主要消费 snapshot/RPC 摘要,后续字段统一与联调时应把 versioned launcher artifact 纳入 contract fixture

  1. catalog.status / official-sync-snapshot.json 中的 launcher_metadata
  2. catalog.status / official-sync-snapshot.json 中的 game_main_config_bootstrap
  3. official-launcher-bootstrap.json 中的官方 launcher bootstrap versioned artifact。
  4. resource.manifest 和磁盘 Present/size 检查得到的当前 release 索引。

bat-api 不下载 launcher 包、不生成官方 PC package update manifest、不执行启动器签名/鉴权链、不仿造登录、账号、网关或游戏业务 API。需要真实资源拉取时,仍由 Rust bat --auto-discover 在隔离 staging 中通过官方 HTTP metadata 完成,并把已发布结果通过 RPC 暴露给 bat-api


4. official-download-manifest.json

字段 类型 说明
version u32 当前为 1
entries map URL → entry 按完整官方 URL 为键(有序 BTreeMap

每条 entry

字段 说明
url 官方 https URL
destination 相对 resource_root 的路径(host/path...
bytes 文件大小
blake3 本地 BLAKE3 hex

权威清单:拉取闭环写入的 manifestbat-api / RPC resource.manifest 以此为应有集合,再以磁盘校验 Present。


5. 发现与 seed URL 规则(L2

常量根:

  • server-infohttps://yostar-serverinfo.bluearchiveyostar.com
  • client-patchhttps://prod-clientpatch.bluearchiveyostar.com

AddressablesCatalogUrlRoot 形如:

https://prod-clientpatch.bluearchiveyostar.com/<root_token>

默认平台:Windows + Android

5.1 平台目录名

平台 Patch 目录 Media 目录 Addressables catalog zip
Windows Windows_PatchPack MediaResources-Windows catalog_StandaloneWindows64.zip
Android Android_PatchPack MediaResources catalog_Android.zip

5.2 Seed 端点模板

共享(非平台):

{CLIENT_PATCH}/{token}/TableBundles/TableCatalog.bytes
{CLIENT_PATCH}/{token}/TableBundles/TableCatalog.hash

每平台:

{CLIENT_PATCH}/{token}/{PatchDir}/BundlePackingInfo.bytes
{CLIENT_PATCH}/{token}/{PatchDir}/BundlePackingInfo.hash
{CLIENT_PATCH}/{token}/{PatchDir}/{catalog_zip}
{CLIENT_PATCH}/{token}/{PatchDir}/{catalog_base}.hash
{CLIENT_PATCH}/{token}/{MediaDir}/Catalog/MediaCatalog.bytes
{CLIENT_PATCH}/{token}/{MediaDir}/Catalog/MediaCatalog.hash

5.3 Content URL 模板

类型 模板
Table 文件 {CLIENT_PATCH}/{token}/TableBundles/{Name}
Patch pack {CLIENT_PATCH}/{token}/{PatchDir}/{FullPatch_NNN.zip}
Media 文件 {CLIENT_PATCH}/{token}/{MediaDir}/{relative_path}

relative_path 示例:GameData/Audio/VOC_JP/JP_Airi.zipPrologue/Scenario/Event/10000_Title_Sound.ogg

5.4 校验分层

对象 算法 / 规则
seed .bytes + .hash 官方 .hashxxHash32(seed=0) 的十进制文本;强校验
一般已下载文件 本地 manifest size + BLAKE3
.zip 另加 ZIP central/local 结构校验
catalog_*.hash Addressables/SBP Hash128 文本标记不是 seed 的 xxHash32 规则

6. Inventory 抽取规则(L3,当前实现)

实现:adapters/src/official/inventory.rs可打印串启发式,非完整 schema 反序列化)。

Catalog 抽取逻辑 风险
BundlePackingInfo.bytes 可打印串中扩展名为 zip 且匹配 FullPatch_NNN.zip(总长 17,中间 3 位数字) 漏抽非 FullPatch 包名(当前有意只 FullPatch
TableCatalog.bytes 可打印串中 .db/.zip 文件名;出现次数 ≥ 2 才收录 依赖「双份列表」启发式;形态变化会漏/多
MediaCatalog.bytes 可打印串中相对路径,扩展名 zip/mp4/png/jpg/jpeg/ogg/wav 路径须 is_plausible_relative_path

R2 待真机核对:用服务器全量 seed 字节跑抽取,与 manifest 中 content URL 集合 diff;有未解释差异再改 inventory + fixture。

仓库内已有:adapters/tests/fixturesinfrastructure/tests/fixtures/official_regression不能替代全量 release 实勘。


7. 客户端资源请求假设(R3,服务 bat-api)

假设(当前工程) bat-api 行为
启动前资源发现 客户端/补丁器需要知道当前资源版本、server-info 和 client-patch 根 GET /v1/bootstrap 返回 bat RPC 健康、release 摘要、server-info URL、client-patch base 和改写后的 Addressables root
服务就绪 运维需要区分进程存活和 release 是否可分发 GET /healthz 返回 liveness + RPC refresh 诊断;GET/HEAD /readyz 无可分发 release 时返回 503
client-patch 内容 GET 官方 path;无业务鉴权头(资源 CDN) GET/HEAD /prod-clientpatch.../... 原样字节,支持 Range
server-info GET JSON;字段 PascalCaseConnectionGroups 等) 可选加载并只改 AddressablesCatalogUrlRoot 指向 {public-base}/prod-clientpatch.../{token}
launcher bootstrap 启动器链会先查 launcher metadata,再找到 server-info / Addressables root /v1/launcher/bootstrap/api/launcher/... 只输出资源引导兼容信息,来源是 Rust snapshot/RPC
seed .hash 纯文本十进制(可含空白) 原样分发
Range / 断点 官方客户端下载器用 Rangebat 用 curl .part ServeContent 支持 Range / 206 / 416 / If-Range
缓存 / 条件请求 资源位于 versioned rootmanifest 有 BLAKE3 ETag 优先使用 manifest BLAKE3;返回 Last-Modified、Accept-Ranges、长期 Cache-Control
业务 ApiUrl/Gateway 游戏协议 不改写、不仿造

Addressables 改写后客户端拼接:

{rewritten_root}/TableBundles/TableCatalog.bytes
≡ {public-base}/prod-clientpatch.../{token}/TableBundles/TableCatalog.bytes

与磁盘映射一致。


8. RPC 与分发发现顺序

bat-api(及任何 Go 服务层)发现当前 release,并由 /v1/bootstrap 组织为启动前资源入口:

  1. daemon.status
  2. daemon.doctor
  3. catalog.statusversion.resource_rootaddressables_root、app/bundle
  4. resource.manifest 分页(url / destination / bytes / blake3
  5. resource_root 上 Lstat 校验 Present / size

不读 bat-status.json / bat-tasks.json 作为常规路径。

生产配置:--socket / BAT_API_SOCKETbat-apibat 在同服务器、同容器或同共享文件系统环境内运行。--resource-root 只用于本地 fixture 或应急只读诊断,不作为生产资源根配置。BAT_API_REFRESH_INTERVAL 控制 bat-api 周期重读 RPC,以跟随 Rust bat 发布新 release。见 cmd/bat-api/.env.example


9. issue #2 / #3 样本索引(R4/R5 预置)

在服务器 release 上优先采集到 /tmp 隔离目录(不入库大文件):

用途 建议路径模式
Addressables#2 {PatchDir}/catalog_*.zip 解压后的 JSON/bin + 旁路 .hash
UnityFS#3 FullPatch_*.zip 内抽样 .bundle,或已解包 bundle
seed 加固(R2 各平台 TableCatalog / BundlePackingInfo / MediaCatalog.bytes+.hash

字段目标(#2,已有 m_Crc 部分):继续扩大 hash/size/CRC/依赖等可校验字段覆盖。 结构目标(#3):header / block / directory / metadata / object table 引擎级解析。


10. 服务器实勘清单(R1,等 SSH)

连接信息到位后只读执行:

  1. readlink current → version id
  2. 顶层是否仅有官方 host 目录 + manifest/snapshot
  3. manifest 条目数 vs 磁盘抽样 size
  4. RPC 四步(status → doctor → catalog.status → manifest 首页)
  5. 将结论写入 docs/reports/resource-server-survey-YYYYMMDD.md(无凭据)

所需:

SSH: user@host -p PORT
资源目录: .../official
bat.sock 或 state-dir: ...

11. 相关文档

  • docs/reports/GO_STATUS.md — Go 边界与进度
  • docs/architecture/official-resource-backend.md — 拉取后端总览
  • docs/reference/rpc-backend-api.md — RPC 契约
  • docs/guides/official-resource-test-pull.md — 用户向运行说明
  • docs/reports/CURRENT_GAPS.md — G-009 / #2 / #3

12. 变更纪律

  1. 改 URL 模板或落盘规则 → 必须同步本文 + 相关单测。
  2. 改 inventory 启发式 → 说明覆盖的真实风险并补 fixture。
  3. 真机实勘若发现与本文冲突 → 以真机为准 修代码与本文,禁止静默分叉。