docs(project): 同步维护冻结与运行文档
bat-rust / Build and test Rust (push) Canceled after 0s

补齐解析模块维护冻结规则,并同步 CURRENT_STATUS、CURRENT_GAPS、PROJECT_PLAN、RPC 参考、部署指南、用户指南和官方资源运行说明。

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

验证:未运行新命令;本轮已按要求停止重复构建/测试。
This commit is contained in:
2026-07-31 00:45:46 +08:00
parent 3f78f8f880
commit 03021ad649
16 changed files with 946 additions and 225 deletions
+49 -42
View File
@@ -1,6 +1,6 @@
# AssetBundle 与资源解析路线图
- **更新时间**2026-07-25
- **更新时间**2026-07-26
- **适用范围**:Rust 解析引擎、官方同步后的解析缓存、CAS/ResourceRepository 接入、后续文本提取和 Patch 发布。
- **权威关联**`PROJECT_PLAN.md` Milestone 3/4/5/8`docs/reports/CURRENT_GAPS.md` G-005/G-007/G-011/G-011D。
@@ -13,10 +13,10 @@
1. 官方资源同步负责拉取、校验和发布原版资源。
2. 解析器只读取已发布或 staging 中已校验的资源,不修改原始文件。
3. 解析结果写入派生缓存、CAS 索引或后续文本提取索引。
4. 汉化产物只能由 Patch/发布阶段写入 `localized-output`,不能写回官方资源目录。
4. 汉化产物只能由 Patch/发布阶段写入 `--localized-output` / `BAT_LOCALIZED_OUTPUT` 指定的汉化发布根,不能写回官方资源目录。
5. 解析器必须与 CLI、daemon、Go API、Patch 业务流程解耦。
当前官方同步完成后会维护 `official-parse-cache.json`。它是官方 release 的派生索引,不是汉化产物;本地 URL、相对路径、size 和 BLAKE3 未变化时应复用旧解析结果并跳过重复解析。
当前官方同步在新 release 发布后会先维护 `official-resource-changes.json``crowdin-translation-handoff.json`,再维护 `official-parse-cache.json``official-textunit-index.json``official-textunit-tasks.json``crowdin-textunit-queue.json`。这些都是官方 release 的派生索引,不是汉化产物;up-to-date 轮询在已有有效解析缓存、TextUnit 明细索引和 TextUnit 队列时只读取摘要,不重复解析。
---
@@ -30,8 +30,8 @@
| Addressables catalog | `catalog_*.zip` 内 JSON/bin catalog、`catalog_*.hash` | asset path、provider、dependencies、size、CRC、bundle name | JSON/compact 当前样本已覆盖,仍需更多真实结构变体 |
| UnityFS container | `.bundle`、zip 内 bundle | header、block、directory、解压文件、基础摘要 | 已支持基础解包、LZ4/LZMA、边界校验 |
| Serialized file | UnityFS directory 文件 | header、type table、TypeTree node、object table、TextAsset bytes | 已支持基础表结构和 TextAsset bytes |
| Unity 对象字段 | TextAsset、MonoBehaviour、ScriptableObject | 可翻译文本单元、上下文、资源定位 | TextAsset bytes 已有入口,字段级反序列化未完成 |
| Patch 发布前解析 | 已翻译文本、中间格式、原版资源 | 可验证 patch manifest、汉化 release 目录 | 未完成 |
| Unity 对象字段 | TextAsset、MonoBehaviour、ScriptableObject | 可翻译文本单元、上下文、资源定位 | TypeTree 基础字段读取、`SerializedReference` / prefixed managed-reference metadata alias、payload 提取和字符串提取已落地,真实结构覆盖继续扩大 |
| Patch 发布前解析 | 已翻译文本、中间格式、原版资源 | 可验证 patch manifest、汉化 release 目录 | UnityFS TextAsset 前置已落地,通用 Binary/JSON/Text Patch 与文件级 patch / UnityFS 写入入口可用,发布级 build/rollback 未开放 |
---
@@ -45,16 +45,17 @@
4. 能从 UnityFS directory 提取文件 bytes。
5. `serialized` 模块能读取 Unity serialized file header、type table、TypeTree node 元数据、object table。
6. 能提取 TextAsset 的 name 和原始 bytes。
7. `ResourceImportService` 能把 AssetBundle 摘要、TextAsset/Table/Media 分类写入导入报告
8. 官方同步后 `OfficialParseCacheService` 能从 `official-download-manifest.json` 遍历所有资源,解析直接 bundle 和 zip 内条目,非候选资源记录为 unsupported
7. TypeTree field reader 已支持基础标量、string、bytes、array、vector/staticvector 嵌套 `Array` 形态、`List<T>` / `HashSet<T>` 集合 alias、map、PPtr、enum `value__` backing field、`LayerMask` / `BitField``m_Bits` backing field、嵌套对象、常见固定 Unity float/int/hash 值类型的 leaf 和 direct child TypeTree 形态、unknown fixed-size raw bytes 保留和同长度替换、TypeTree-covered managed reference、TypeTree-covered managed reference registry 记录、`m_ManagedReferences` / `RefIds` / `m_RefIds` / verbose type 字段等 registry 命名变体、`id` / `typeInfo` 等 metadata 命名变体、`data` / `value` / `payload` / `object` / `managedReferencePayload` / `referencePayload` / `serializedReferencePayload` / `managedReferenceValue` / `referenceValue` / `serializedReferenceValue` / `managedReferenceObject` / `referenceObject` / `serializedReferenceObject` / `managedReferenceData` / `referenceData` / `serializedData` 等 payload 命名变体、managed-reference full typename 拆解和字段 offset/size 诊断
8. `TextUnitExtractor` 已把 JSON/CSV/TSV/plain TextAsset、TypeTree 字符串字段和 TypeTree-covered managed reference payload 字符串输出为可序列化 TextUnit/JSONLzip 场景保留 archive entryTextUnit 明细包含 serialized file、path id、class id、field path、字段 offset/byte size、format、asset name 和上下文。managed-reference 类型元数据保留为 payload context,不进入翻译文本队列;即使 registry 暂时只能走 fallback 字段遍历,`RefIds``className``namespaceName``asmName` 等元数据别名也会被跳过,payload/value/object 家族和 `managedReferenceData` / `referenceData` / `serializedData` 仍按 payload 处理,并按 `RefIds[n]` 等记录前缀或子字段推导 metadata,避免多条 fallback record 混用 managed-reference context
9. `ResourceImportService` 能把 AssetBundle 摘要、TextAsset/Table/Media 分类和 TextUnit 摘要写入导入报告。
10. 官方同步后 `OfficialParseCacheService` 能从 `official-download-manifest.json` 遍历所有资源,解析直接 bundle 和 zip 内条目,非候选资源记录为 unsupported,并缓存 TextUnit 数量/格式/诊断摘要,同时写出 `official-textunit-index.json``parse.text_units` / `parse.errors` 查询。
当前还不能宣称完整:
1. MonoBehaviour/ScriptableObject 的 TypeTree 字段级反序列化未完成
2. Unity managed reference、PPtr、array/map、string alignment 等复杂字段未完整覆盖
3. Addressables bin/compact catalog 结构变体仍需真实样本驱动补齐
4. 解析结果尚未自动进入用户级 CAS + ResourceRepository 查询流程
5. 不能重写 AssetBundle,也不能生成可发布汉化 patch。
1. TypeTree-covered managed reference 字段和 registry 记录已可结构化解码并参与文本提取,常见 registry 命名别名(含 `m_ManagedReferences``RefIds``m_RefIds`、verbose type 字段)、metadata 命名别名(含 `id``typeInfo`)、payload 命名别名(含 `data``value``payload``object``managedReferencePayload``referencePayload``serializedReferencePayload``managedReferenceValue``referenceValue``serializedReferenceValue``managedReferenceObject``referenceObject``serializedReferenceObject``managedReferenceData``referenceData``serializedData`)、full typename 拆解和 payload-only TextUnit 提取已有回归覆盖,多记录 registry 聚合也已有单元回归;fallback 字段遍历会跳过常见 registry 元数据字符串,避免误入翻译队列,并按记录前缀或子字段可推导 metadata 保留 managed-reference TextUnit context。enum `value__` backing field 和 `LayerMask` / `BitField``m_Bits` backing field 已可语义化解码和替换;`Vector2f/3f/4f``Quaternionf``ColorRGBA``Rectf``AABB/Bounds/Ray``Matrix4x4f``Vector2Int/Vector3Int``RectInt``BoundsInt``RangeInt``GUID``Hash128` 等固定 Unity 值类型的 leaf 和 direct child TypeTree 形态已可结构化解码和语义替换;array/vector/staticvector/List/HashSet/map 元素与 registry payload 字段已保留独立 field path、offset 和 byte size,可用于字符串元素 patchmanaged-reference registry payload 字符串、enum、bit_field、unknown fixed-size raw bytes、object 字段组合和 TypeTree schema 支撑的 array/vector/List/HashSet/map 已可整体变长替换,`first/second``key/value` map entry schema 已有 serialized 和 UnityFS 重建回归,ScriptableObject `key/value` map 解析、变长替换和 UnityFS 重建已有专门回归,且嵌套 vector `Array``List<T>` / `HashSet<T>` 集合 alias、enum、bit_field、unknown fixed-size raw bytes 与 managed-reference payload 字段已有重建回归覆盖;解析模块当前处于维护冻结,未见样本驱动的完整 managed reference registry / map entry 变体、unknown 字段结构语义和版本差异冻结后再推进
2. Addressables bin/compact catalog 结构变体仍需真实样本驱动补齐
3. 官方 release 已可配置导入 CAS + ResourceRepository,并可通过 `resource.index` 查询现有资源索引;Resource metadata 已记录 release、平台、bundle path、parse status、TextAsset 名称和 TextUnit 摘要
4. 不能完成复杂对象字段重打包,也不能从真实 Crowdin 结果自动生成完整汉化文件集合
---
@@ -66,17 +67,23 @@
交付:
1. `official-parse-cache.json` 记录 manifest entry、zip entry、解析状态、Unity 版本、文件数、TextAsset 数、错误摘要和缓存复用状态
2. 解析直接 `.bundle` / `.unity3d` 和 zip 内全部文件条目,不能只假设 `FullPatch_*.zip`
3. 非候选资源记录为 unsupported,不影响官方同步发布
4. 缺失、损坏或无法解析的 bundle 记录 failed,但不回滚已经完成校验的官方原版 release
5. 用合成 fixture、隔离真实样本和回归 fixture 覆盖缓存复用、zip 内条目、非候选资源、解析失败
1. `official-resource-changes.json` 记录当前 release 相对上一完整 release 的新增、变更、删除资源,以及解析/翻译候选计数
2. `crowdin-translation-handoff.json` 只包含新增+变更资源,作为后续 Crowdin worker 的本地队列输入;当前解析阶段不直接调用 Crowdin API
3. `official-parse-cache.json` 记录 manifest entry、zip entry、解析状态、Unity 版本、文件数、TextAsset 数、TextUnit 数/格式、错误摘要和缓存复用状态
4. `official-textunit-index.json` 持久化单条 TextUnit 和解析错误,保留 destination、archive entry、serialized file、path id、class id、field path、offset 和 format 等定位信息
5. `official-textunit-tasks.json` 只从 Added/Modified 资源、parse cache 和 TextUnit 明细索引派生,记录可翻译 TextUnit 任务和跳过原因
6. `crowdin-textunit-queue.json` 只包含已经产生 TextUnit 的离线任务,当前不调用 Crowdin 网络 API。
7. 解析直接 `.bundle` / `.unity3d` 和 zip 内全部文件条目,不能只假设 `FullPatch_*.zip`
8. 非候选资源记录为 unsupported,不影响官方同步发布。
9. 缺失、损坏或无法解析的 bundle 记录 failed,但不回滚已经完成校验的官方原版 release。
10. 用合成 fixture、隔离真实样本和回归 fixture 覆盖资源变更集、Crowdin handoff、TextUnit 队列、缓存复用、zip 内条目、非候选资源、解析失败。
验收:
1. 第二次运行同一 release 时能看到解析缓存复用计数
2. 修改任意 manifest entry 的 size/BLAKE3 后,只重新解析对应资源
3. 解析缓存不会写入 `localized-output`
1. release 发布时能生成资源变更集,新增+变更资源进入解析/翻译候选,删除资源不进入翻译队列
2. 第二次 up-to-date 轮询不会重复解析已有有效缓存和 TextUnit 明细索引
3. 修改任意 manifest entry 的 size/BLAKE3 后,变更集能标记对应资源并让后续解析/翻译只消费候选
4. 解析缓存、handoff 和 TextUnit 队列不会写入汉化发布根。
### P1Addressables catalog 完整化
@@ -103,10 +110,10 @@
交付:
1. TypeTree schema 内部表示稳定化:node path、type、name、size、flags、array 信息。
2. 实现基础字段 readerbool、integer、float、string、bytes、array、map、PPtr、managed reference 占位
3. 支持 TextAsset script/name 的结构化读取,而不只保留 raw bytes
4. 支持 MonoBehaviour 和 ScriptableObject 的 TypeTree 字段遍历。
5. 对缺 TypeTree 或 stripped 类型返回可诊断错误,保留 raw object bytes 作为后备。
2. 基础字段 reader 已支持 bool、integer、float、string、bytes、array、vector/staticvector 嵌套 `Array``List<T>` / `HashSet<T>` 集合 alias、map、PPtr、enum `value__` backing field、`LayerMask` / `BitField``m_Bits` backing field、常见固定 Unity 值类型的 leaf/direct-child 形态,以及 unknown fixed-size raw bytes 保留和同长度替换
3. TextAsset 已有专用 name/bytes 读取,避免和字段级遍历重复报错
4. MonoBehaviour 和 ScriptableObject 的 TypeTree 字段遍历入口已落地,复杂版本差异继续补 fixture
5. 对缺 TypeTree 或 stripped 类型返回可诊断结果,保留 raw object bytes 作为后备。
验收:
@@ -120,11 +127,11 @@
交付:
1. 定义 `TextUnit`source text、resource path、archive entry、object path id、field path、语言、版本、上下文。
2. TextAsset 支持 JSON/CSV/TSV/plain text 的可配置探测。
3. MonoBehaviour/ScriptableObject 按字段路径和类型策略提取字符串。
1. 定义 `TextUnit`source text、bundle path、archive entry、serialized file、object path id、class id、field path、字段 offset/byte size、版本和上下文;managed-reference payload 会额外写入 reference id、full type name、assembly、namespace 和 class 上下文。
2. TextAsset 支持 JSON/CSV/TSV/plain text 探测,二进制 payload 单独计数
3. MonoBehaviour/ScriptableObject 按字段路径提取字符串。
4. 保留重复文本和上下文,不在解析阶段做会丢定位的合并。
5. 导出 JSONL 作为第一稳定格式,CSV/XLIFF 可后置。
5. 已提供 JSONL 第一稳定格式,CSV/XLIFF 可后置。
验收:
@@ -138,15 +145,15 @@
交付:
1. 官方同步完成后可配置触发导入 CAS + ResourceRepository。
2. ResourceRepository 保存版本、平台、资源类型、bundle path、TextAsset 名称、TextUnit 索引摘要
3. 支持 CLI/RPC 查询资源、bundle、TextAsset、解析错误和缓存状态。
4. schema 迁移版本化,旧库可重复升级
1. 官方同步完成后可配置触发导入 CAS + ResourceRepository(已具备 `--import-repository` / `BAT_IMPORT_REPOSITORY=1`
2. ResourceRepository 保存官方 manifest 资源类型、路径、hash、size 和 metadatametadata 包含 release、平台、bundle path、parse status、TextAsset 名称、TextUnit 数量/格式
3. 支持 RPC/CLI 查询资源、bundle、TextAsset、解析错误和缓存状态;当前 `resource.index` 会返回资源 metadata`parse-status` 会返回 TextUnit 索引和队列摘要,`parse-text-units` / `parse-errors` 会按当前 release 查询明细,`localized-status` 会校验 patch manifest
4. schema 迁移可重复执行;当前 SQLite 已有 `crc``metadata_json` 兼容迁移
验收:
1. 可以按版本、路径、类型、hash、TextAsset 名称查询
2. 解析缓存和 repository 数据能从同一 manifest fingerprint 追溯。
1. 可以按版本、路径、类型、hash 查询,并在结果 metadata 中看到 TextAsset / TextUnit 摘要
2. 解析缓存、资源变更集和 repository 数据能从同一 manifest fingerprint 追溯。
3. CAS 对象跨版本复用,不重复存储相同文件。
### P5Patch 发布前置解析
@@ -155,17 +162,17 @@
交付:
1. 定义 patch manifest:目标官方版本、输入 TextUnit 版本、输出文件、hash、回滚信息。
2. 支持 TextAsset raw bytes 替换的最小 patch 路径。
1. 定义 `localized-patch-manifest.json`:目标官方版本、localized release、输出文件、hash、size、byte delta、TextAsset 操作和回滚信息。
2. 支持 UnityFS TextAsset raw bytes 替换的最小 patch 路径。
3. MonoBehaviour/ScriptableObject 字段替换必须依赖 P2 字段级解析结果。
4. Patch 产物写入 `localized-output/.staging/<id>`,校验通过后发布到 `localized-output/versions/<id>` 并切换 `current`
5. 成功后发布状态从 `not_localized` 切到 `localized`
4. Patch 产物写入配置化汉化发布根下的 `.staging/<id>`,校验通过后发布到 `versions/<id>` 并切换 `current`
5. 成功后发布状态从 `not_localized` 切到 `localized``localized.status` 要求 state、current symlink 和 patch manifest 同时匹配当前官方 release
验收:
1. Patch 失败不影响 `bat-resources/current`
2. 汉化 release 保留官方相对目录结构。
3. `localized` 状态能证明原版和汉化两套资源都已发布。
3. `localized` 状态能证明原版和汉化两套资源都已发布,且 patch manifest 可验证
---
@@ -194,6 +201,6 @@
1. 完成 Addressables Windows/Android 当前版本 catalog 样本集合,关闭 G-007 当前阶段。
2. 完成 TypeTree 字段 reader 和 MonoBehaviour/ScriptableObject 遍历,推进 G-005。
3.`official-parse-cache.json` 摘要接入 CAS/ResourceRepository 用户级导入,推进 G-011
4. 定义 TextUnit JSONL 和最小 TextAsset 提取命令,衔接 Milestone 5
5. Patch 引擎落地后实现 `localized` 发布状态切换,关闭 G-011D 的核心发布缺口
3.`crowdin-textunit-queue.json` 接入真实 Crowdin worker、翻译记忆和 Patch 构建
4. 将翻译任务状态接入 CAS/ResourceRepository 查询面,推进 G-011
5.通用 Binary/JSON/Text Patch 基础上继续扩展复杂 AssetBundle 重打包和发布流程统一,保留当前 UnityFS TextAsset patch 发布前置链路
+66 -38
View File
@@ -37,7 +37,7 @@
| 清单层 | 解析 `BundlePackingInfo.bytes``TableCatalog.bytes``MediaCatalog.bytes` | 得到完整文件清单 |
| 计划层 | 合并 discovery + inventory,去重并保序 | 得到全量 pull plan |
| 下载层 | 校验官方 URL,调用下载器,落盘并记录字节数 | 得到本地资源副本 |
| 导入层 | 将 bundle 写入 CAS 和 ResourceRepository | 得到可查询的资源索引 |
| 导入层 | 可配置将已校验官方 release 写入 CAS 和 ResourceRepository | 得到可查询的资源索引 |
| 同步层 | 比较当前快照和历史快照 | 决定下载、校验、发布 |
| 更新层 | 保存上次官方 snapshot,定期执行 discovery + diff + pull | 形成自动更新闭环 |
@@ -54,7 +54,7 @@
3. 不要求把生产环境当作客户端安装目录。
4. 可以显式执行 official metadata discovery 自动发现 `server-info` URL、`connection-group``app-version`
5. 也可以通过配置、调度状态或已审计 metadata snapshot 显式提供这些值。
6. `--auto-discover` 只允许通过官方 HTTP metadata 和临时目录解析 `GameMainConfig`launcher metadata 未变时必须复用缓存,metadata 变化时才按 manifest 重新下载必要 `resources.assets` 或旧版官方 game zip。
6. `--auto-discover` 只允许通过官方 HTTP metadata 和临时目录解析 `GameMainConfig`launcher metadata 与 remote manifest 文件列表 digest 均未变时必须复用缓存,任一变化时才按 manifest 重新下载必要 `resources.assets` 或旧版官方 game zip。
### 3.1 发现官方资源根
@@ -135,16 +135,17 @@
6. `TableCatalog.bytes``BundlePackingInfo.bytes``MediaCatalog.bytes` 总是刷新并用官方 `.hash` 强校验;该 `.hash``xxHash32(seed=0)` 的十进制文本。
7. `catalog_*.hash` 当前只作为 Addressables catalog 变更标记,不作为 zip/JSON 内容校验算法;Unity Addressables/SBP builder 对 JSON/bin catalog 使用 `HashingMethods.Calculate` 生成 `Hash128` 文本,运行时用它判断 remote catalog cache 是否过期,它不能套用 seed catalog 的 `xxHash32` 规则。
8. 官方 seed `.hash` 校验失败会让当前下载失败,并移除对应 data/hash URL 的本地 manifest 条目,避免失败产物在下一轮被本地 BLAKE3 audit 误判为健康缓存。
9. 存在 `.part` 临时文件时通过 `curl --continue-at -` 尝试断点续传
10. 新下载写入 `.part`,成功并通过必要校验后原子 rename 到 staging 内最终路径;断点续传后的 `.zip` 如果结构无效,会删除 `.part` 并重新全量下载
11. 成功下载后更新本地下载清单
12. 上一轮失败或中断留下的 staging 只有在 `official-version-state.json` 中存在同一 app version、bundle version 和 Addressables root 的失败记录,且 `<output>/.staging/<id>` 仍安全存在、`versions/<id>` 尚未发布时才会复用;复用后仍按 manifest、BLAKE3、ZIP 结构和官方 `.hash` 逐 URL 校验,不信任散落文件
13. curl 默认自动检测 `HTTPS_PROXY` / `ALL_PROXY` / `HTTP_PROXY` 及小写环境变量,保留 `NO_PROXY`;带凭据的代理推荐用这些环境变量配置。CLI 也可用 `--proxy <URL>` 显式指定代理,或用 `--no-proxy` 强制直连。代理决策会进入 progress log、daemon log 和 `doctor` 诊断输出。代理凭据全程不落世界可读位置:日志与 `status` 输出脱敏;传给 curl 子进程时经 `ALL_PROXY` 环境变量而非 `--proxy` 参数,不进 curl 的 `/proc/<pid>/cmdline``--daemon` 模式下经环境变量下传后台子进程,不进子进程 argv 或 `bat-status.json`,复用凭据单独存于 `bat-proxy.secret``0600`),`clean-stable` 会在后台停止后清除
14. curl 失败按 HTTP/网络类型分类:403/404/普通 4xx 不重试,5xx、429、DNS、连接、超时、中断和网络类错误按尝试次数重试
15. 单个 URL 最终失败时写入 `official-download-quarantine.json`,发出 Failed progress,并阻止发布不完整资源
16. 旧 launcher 包或 `resources.assets` 下载使用官方 launcher CDN 配置,primary CDN 失败后切换 official backup CDN;资源 patch host 不猜测非官方镜像
17. 记录最终文件大小、本次传输字节数、官方 hash 校验数和执行状态
18. 非官方 URL 直接拒绝
9. 官方启动器/server-info 先于 client-patch CDN 开放是合法上游状态。若 seed marker 或必需 seed catalog 在进入 staging 前返回 403/404/普通 4xx,更新服务返回 `waiting_for_official_resources``unavailable_endpoints`,保留现有 `current`,不创建失败 staging,不写入 `failed_versions`watch/daemon 使用 `waiting` 状态按错误重试间隔继续探测
10. 存在 `.part` 临时文件时通过 `curl --continue-at -` 尝试断点续传
11. 新下载写入 `.part`,成功并通过必要校验后原子 rename 到 staging 内最终路径;断点续传后的 `.zip` 如果结构无效,会删除 `.part` 并重新全量下载
12. 成功下载后更新本地下载清单
13. 上一轮失败或中断留下的 staging 只有在 `official-version-state.json` 中存在同一 app version、bundle version 和 Addressables root 的失败记录,且 `<output>/.staging/<id>` 仍安全存在、`versions/<id>` 尚未发布时才会复用;复用后仍按 manifest、BLAKE3、ZIP 结构和官方 `.hash` 逐 URL 校验,不信任散落文件
14. curl 默认自动检测 `HTTPS_PROXY` / `ALL_PROXY` / `HTTP_PROXY` 及小写环境变量,保留 `NO_PROXY`;带凭据的代理推荐用这些环境变量配置。CLI 也可用 `--proxy <URL>` 显式指定代理,或用 `--no-proxy` 强制直连。代理决策会进入 progress log、daemon log 和 `doctor` 诊断输出。代理凭据全程不落世界可读位置:日志与 `status` 输出脱敏;传给 curl 子进程时经 `ALL_PROXY` 环境变量而非 `--proxy` 参数,不进 curl 的 `/proc/<pid>/cmdline``--daemon` 模式下经环境变量下传后台子进程,不进子进程 argv 或 `bat-status.json`,复用凭据单独存于 `bat-proxy.secret``0600`),`clean-stable` 会在后台停止后清除
15. curl 失败按 HTTP/网络类型分类:403/404/普通 4xx 不重试,5xx、429、DNS、连接、超时、中断和网络类错误按尝试次数重试
16. 单个 URL 最终失败时写入 `official-download-quarantine.json`,发出 Failed progress,并阻止发布不完整资源
17. 旧 launcher 包或 `resources.assets` 下载使用官方 launcher CDN 配置,primary CDN 失败后切换 official backup CDN;资源 patch host 不猜测非官方镜像
18. 记录最终文件大小、本次传输字节数、官方 hash 校验数和执行状态
19. 非官方 URL 直接拒绝。
路径映射时会做分段清理,并在写入前做输出目录安全校验、相对路径归属校验和现有路径组件 symlink 检查,避免把不安全路径写进输出目录或通过 symlink 跳出输出目录。
@@ -154,14 +155,24 @@
### 3.5 导入到 CAS 和资源仓储
当前实现已经提供资源导入能力,但官方同步下载完成后尚未自动作为用户级流程触发导入。手动或上层流程调用导入层时,它会:
官方同步下载、校验并发布 release 后,可以通过 `--import-repository`
`.env``BAT_IMPORT_REPOSITORY=1` 自动触发 CAS + `ResourceRepository`
导入:
1. 把 bundle 原始字节写入 CAS
2. 解析 UnityFS 基础摘要
3.资源条目写入 `ResourceRepository`
4. 记录资源路径、hash、大小和解析摘要
1. 读取已发布 release 下的 `official-download-manifest.json`
2. 逐条按 manifest 的相对路径、size 和 BLAKE3 重新校验本地文件
3.已校验字节写入 CAS;默认 CAS 根目录是 `<output>/.cas`,也可用
`--import-cas-root` / `BAT_IMPORT_CAS_ROOT` 覆盖
4. 将资源条目写入 SQLite `ResourceRepository`;默认索引路径是
`<output>/resources.sqlite`,也可用 `--import-resource-db` /
`BAT_IMPORT_RESOURCE_DB` 覆盖。
5. AssetBundle、TextAsset、TableBundle、Media、Manifest/Other 会按资源类型分类;资源 metadata 会通过 `metadata_json` 保存 release、平台、bundle path、parse status、TextAsset 名称和 TextUnit 数量/格式。
6. 当前 release 的单条 TextUnit 明细和解析错误会写入 `official-textunit-index.json`,可通过 `parse.text_units` / `parse.errors` RPC 和 `parse-text-units` / `parse-errors` CLI 只读查询。
这层的意义是把“下载到磁盘的文件”变成“可查询、可复用、可去重”的资源对象。把官方同步结果自动接入 CAS + `ResourceRepository` 仍属于 G-011 剩余工作。
这层的意义是把“下载到磁盘的文件”变成“可查询、可复用、可去重”的资源对象。
`resource.index` RPC / CLI 只读查询现有 SQLite 索引;索引不存在时返回
`available=false`,不会因为查询创建空库。G-011 剩余工作是翻译任务状态、
CAS 诊断入口和更丰富查询。
对应实现主要在:
@@ -202,8 +213,8 @@
流程是:
1. 显式执行 `--auto-discover` 或读取已审计 `server-info` 输入。
2. `--auto-discover` 先抓官方 launcher metadatametadata 未变时复用 `official-bootstrap-cache.json` 中的 `GameMainConfig` 摘要,metadata 变化时按 manifest 临时下载 `resources.assets` 或旧版官方 game zip 并重新解析。
3. 生成当前 v2 snapshot,记录 `app_version``connection_group``bundle_version``addressables_root`、endpoint URL、seed `.hash` 内容、`catalog_*.hash` marker、launcher metadata 摘要和 `GameMainConfig` 摘要。
2. `--auto-discover` 先抓官方 launcher metadata、launcher CDN config 和 remote manifestmetadata 与 remote manifest 文件列表 digest 均未变时复用 `official-bootstrap-cache.json` 中的 `GameMainConfig` 摘要,任一变化时按 manifest 临时下载 `resources.assets` 或旧版官方 game zip 并重新解析。
3. 生成当前 v2 snapshot,记录 `app_version``connection_group``bundle_version``addressables_root`、endpoint URL、seed `.hash` 内容、`catalog_*.hash` marker、launcher metadata 摘要、remote manifest 文件列表 digest `GameMainConfig` 摘要。
4. 读取上一次成功同步写出的 snapshot。
5. 使用 `OfficialSyncPlan` 和扩展 snapshot diff 判断是否需要下载;URL 未变但 `.hash` / marker 内容变化也会触发更新。
6. 每轮都会基于最新 seed catalog 构建当前 pull plan,并检查输出目录是否已有当前 plan 的 manifest 条目或目标文件。
@@ -211,10 +222,14 @@
8. 远端无变化且本地已有资源时执行 download manifest audit,检查路径、size、BLAKE3 和 ZIP 结构。
9. 远端变化、本地 audit 发现 repair_needed,首次空目录运行,或缺少 `current` 原子发布指针时,进入下载/发布流程。
10. 下载先写入 `<output>/.staging/<id>`;若已有 active release,会先 seed staging 以复用已验证文件;若 version-state 中存在同一版本的失败 staging,则优先复用该 staging 并跳过 active seed,避免旧 active 覆盖已下载的新文件。
11. 下载、manifest、本地 BLAKE3、ZIP 和官方 `.hash` 校验完成后写入新的 snapshot。
11. 下载、manifest、本地 BLAKE3、ZIP 和官方 `.hash` 校验完成后写入新的 snapshot,并在 staging 中写入 `official-launcher-bootstrap.json`(若本轮启用 `--auto-discover`
12. 将 staging rename 为 `<output>/versions/<id>`,再原子替换 `<output>/current` symlink 指向该 versioned 目录。
13. 发布完成后刷新 active release `official-parse-cache.json`;未变化文件按 manifest 的 URL、相对路径、size BLAKE3 复用旧解析结果
14. 官方同步报告默认给出 `localized_release_status=not_localized`,表示原版资源已发布、汉化资源未发布;后续 Patch 发布阶段完成后才切换为 `localized`,表示原版和汉化两套资源都已发布
13. 发布完成后先对比上一完整 release 和当前 release 的 `official-download-manifest.json`,写出 `official-resource-changes.json``crowdin-translation-handoff.json`。同一 destination 只有 size BLAKE3 变化才算 modified;新增+变更资源进入解析/翻译 handoff,删除资源只进入差异记录。当前只预留 Crowdin 本地 handoff,不发外部 API 请求
14. 随后刷新 active release 下的 `official-parse-cache.json``official-textunit-index.json`,并从 Added/Modified 资源、parse cache 与 TextUnit 明细索引派生 `official-textunit-tasks.json``crowdin-textunit-queue.json`up-to-date 轮询在已有有效解析缓存、TextUnit 明细索引和 TextUnit 队列时只读取摘要,不重复解析
15. 若启用 `--import-repository`,已校验 release 会被导入 CAS + `ResourceRepository`,并可经 `resource.index` 查询。
16. 官方同步报告默认给出 `localized_release_status=not_localized`,表示原版资源已发布、汉化资源未发布;UnityFS TextAsset patch 发布成功并通过 `localized-patch-manifest.json`、current symlink 和 release ID 校验后,`localized.status` 才返回 `localized`,表示原版和汉化两套资源都已发布。
维护期特殊分支:如果官方 launcher/server-info 已经指向新资源根,但 client-patch seed marker 或必需 seed catalog 仍返回 403/404 等未开放状态,`bat` 返回 `waiting_for_official_resources`,保留现有 `current`,不创建失败 staging;若本轮启用 `--auto-discover`,会在 `<output>/official-launcher-bootstrap.pending.json` 写入待处理 launcher bootstrap 证据,供后续排障和自研客户端开发使用。
该入口不安装、不执行官方启动器,也不读取生产外的本地客户端目录。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;`bat-events.jsonl` 是带轮转的结构化 JSONL 事件日志;`bat-control.lock` 串行化控制命令,并在 stale/corrupt 时由下一次控制命令或 `clean-stable` 恢复。`bat-status.json``status` 子命令包含最后成功时间、下次检查时间、最后错误摘要、当前阶段和当前下载 URL 进度。PID、status、log 和控制锁文件创建时使用私有权限,读取和写入时不跟随 symlink。`status``stop``logs``reload`、默认形态的 `refresh` 和默认形态的 `repair` 优先走 RPC`reload` 会唤醒或排队 watch 循环重新自动发现并强制刷新,默认 `repair` 会通过 `resource.repair` 入队本地 manifest 审计+修复任务,`restart` 才负责重启进程或替换启动参数;显式 `--proxy` / `--no-proxy` 会作为启动参数保存并在后台重启时复用。后台 daemon 管理某个资源目录时,前台 `run/watch/refresh/repair` 不允许直接写入同一目录;默认形态 `refresh` 会通过 RPC 触发后台刷新,默认形态 `repair` 会通过 RPC 入队任务。正常情况下默认每 1 小时执行一次检查;每天北京时间(UTC+8)`03:00``16:00``18:00` 会中断普通 sleep 并强制执行一次自动刷新,该轮注入 `force=true`。远端和本地一致时静默等待下次检查,不一致时自动下载或 repair。下载、发现或校验失败时不等待完整正常周期,默认 60 秒后重试;如果固定时间强制刷新失败,会保留 pending force 并按失败重试周期继续重试,可用 `--error-retry``--error-retry-seconds` 调整。默认官方原版资源输出目录是 `./bat-resources`,默认汉化产物目录是 `./bat-localized`,默认后台状态目录是 `/tmp/bat-pid`,三者分别通过 `--output``--localized-output``--state-dir` 配置;官方目录和汉化目录不能相同或互相嵌套。单次运行仍保留为核心幂等路径,systemd service、容器或 Go 进程可以只负责守护该常驻进程;cron/systemd timer 调单次模式只是可选集成方式。项目是否热更新、热重载或重启进程,由上层业务集成决定。
@@ -254,10 +269,11 @@ Linux 生产路径:
- pull plan 会同时包含 discovery URLs 和 content URLs
- 全量样本下是 `2` 个 discovery URL + `5` 个内容 URL = `7` 个 URL
- `OfficialUpdateService` 能持久化 v2 snapshot,并在远端 marker 内容变化时触发下载决策
- `bat` 默认向 stderr 输出 `BlueArchiveToolkit` ASCII banner 和 progress logstdout 默认输出人类可读摘要;progress log 覆盖代理决策、下载已完成计数、单文件开始/完成状态、下载中断失败分类和校验结果摘要;支持 `--proxy` / `--no-proxy` 控制 curl 传输代理,支持 `--json` 输出稳定 JSON,支持 `--no-progress` 关闭进度日志,支持 `--no-banner` 只关闭横幅,支持 `--watch --interval 1h --error-retry 60s` 常驻运行,支持 `--daemon` Unix socket JSON-RPC live control/backend`daemon.status/logs/stop/reload/refresh/doctor``resource.sync/verify/repair/state/manifest/list``catalog.*``task.*`);`restart``clean-stable` 仍由 CLI 侧按进程生命周期显式执行,非 dry-run 使用 `.official-sync.lock` 防止并发写资源目录,控制命令使用 `bat-control.lock` 防止并发状态修改,资源发布使用 `.staging``versions``current` 原子切换,daemon 写 `bat-events.jsonl` 结构化日志并在 `status` 中暴露下载进度、失败类型、HTTP 状态和调度状态
- `bat` 默认向 stderr 输出 `BlueArchiveToolkit` ASCII banner 和 progress logstdout 默认输出人类可读摘要;progress log 覆盖代理决策、下载已完成计数、单文件开始/完成状态、下载中断失败分类和校验结果摘要;支持 `--proxy` / `--no-proxy` 控制 curl 传输代理,支持 `--json` 输出稳定 JSON,支持 `--no-progress` 关闭进度日志,支持 `--no-banner` 只关闭横幅,支持 `--watch --interval 1h --error-retry 60s` 常驻运行,支持 `--daemon` Unix socket JSON-RPC live control/backend`daemon.status/logs/stop/reload/refresh/doctor``resource.sync/verify/repair/state/manifest/list/index``parse.status/text_units/errors``localized.status``catalog.*``task.*`);`restart``clean-stable` 仍由 CLI 侧按进程生命周期显式执行,非 dry-run 使用 `.official-sync.lock` 防止并发写资源目录,控制命令使用 `bat-control.lock` 防止并发状态修改,资源发布使用 `.staging``versions``current` 原子切换,daemon 写 `bat-events.jsonl` 结构化日志并在 `status` 中暴露下载进度、失败类型、HTTP 状态和调度状态
- curl 失败分类和重试策略已覆盖 404 不重试、5xx 重试耗尽后 quarantine、launcher primary CDN 失败后切换 official backup CDN
- `official-version-state.json` 已覆盖当前完成版本、正在拉取版本、上一个可用版本和失败版本;同一 app version、bundle version 和 Addressables root 的失败只保留最新一条,重新拉取或成功发布后清理同版本失败记录,同版本失败 staging 会在路径安全且未发布时复用,`bat status` 会暴露版本状态摘要和最近历史失败原因
- 资源导入链路已覆盖 CAS 写入、`ResourceRepository` 索引、AssetBundle UnityFS 摘要,以及 TextAsset/Table/Media 分类
- 资源导入链路已覆盖可配置 CAS 写入、`ResourceRepository` 索引、`metadata_json` release/平台/bundle/TextAsset/TextUnit 摘要,以及 TextAsset/Table/Media 分类`resource.index` 可只读查询现有索引
- 官方 release 发布后会生成 `official-resource-changes.json``crowdin-translation-handoff.json``official-parse-cache.json``official-textunit-index.json``official-textunit-tasks.json``crowdin-textunit-queue.json`,为后续增量解析和 Crowdin worker 预留稳定输入
- 离线回归样本已覆盖当前 catalog、上一个版本 catalog、catalog 结构变化、403、404 和 seed hash mismatch
- `OfficialUpdateService` 能读写 `official-bootstrap-cache.json`,并支持默认开启的 `audit_local` / `repair` CLI 行为
- 下载层能在本地文件 size/BLAKE3/path、ZIP 结构或 manifest 不匹配时重新下载
@@ -304,30 +320,42 @@ JSON-RPC 2.0 服务,是面向上层服务(Go 层)的**主要跨语言边
watch 循环经进程内锁互斥。任务历史持久化于 `<state-dir>/bat-tasks.json`
(版本化、`0600` 原子写,生命周期转换时落盘),daemon 重启后历史任务
仍可经 `task.*` 查询,中断任务标记 `task_interrupted`700005)。
- 方法命名空间与实现状态、请求/响应示例见 `USERGUIDE.md` §6
`daemon.status/logs/stop/reload/refresh/doctor``resource.state/sync/verify/repair/manifest/list`
`catalog.*``task.status/list/cancel/logs` 已实现;`patch.*` / `unityfs.*`
待引擎;`task.create` 按设计暂不开放通用任务入口;`daemon.restart` /
`daemon.clean-stable` 仍由 CLI 侧按进程生命周期显式执行。
- 方法命名空间与实现状态、请求/响应示例见
`docs/reference/rpc-backend-api.md``daemon.status/logs/stop/reload/refresh/doctor`
`resource.state/sync/verify/repair/manifest/list/index``parse.status/text_units/errors`
`localized.status``catalog.*``task.status/list/cancel/logs` 已实现;
`patch.*` / `unityfs.*` 待引擎;`task.create` 按设计暂不开放通用任务入口;
`daemon.restart` / `daemon.clean-stable` 仍由 CLI 侧按进程生命周期显式执行。
### 7.2 Go 层职责边界
- Go 层负责:资源内容分发(`cmd/bat-api`)、HTTP API 进程配置、以及通过
`internal/backendrpc` 作为 RPC client 调用本机 daemon(连接 `bat.sock`
每行一个 JSON-RPC 请求/响应)。`cmd/bat` 仍是试验骨架,不是产品级用户 CLI
- Rust `bat` / daemon 是资源生产者和状态拥有者;Go `bat-api` 是资源读侧、
bootstrap 和 HTTP 分发入口。二者之间的稳定边界是 `bat.sock` RPC 和
`resource_root` 中已发布的只读文件
- Go 层负责:资源 bootstrap、资源内容分发(`cmd/bat-api`)、HTTP API 进程配置、
以及通过 `internal/backendrpc` 作为 RPC client 调用本机 daemon(连接
`bat.sock`,每行一个 JSON-RPC 请求/响应)。`cmd/bat` 仍是试验骨架,不是产品级用户 CLI。
- **`bat-api`(资源分发,issue #19**
- 提供 `/v1/bootstrap`,把 `bat` 的 RPC 健康、release 摘要、server-info URL、
client-patch base 和改写后的 Addressables root 组织成启动前资源发现响应。
- 提供 `/healthz` 作为 liveness + 最近一次 RPC refresh 诊断,提供 `/readyz`
作为 release readiness;当前无可分发 release 时 `/readyz` 返回 `503`
- 只读提供 Rust `bat` 已发布 release 中的资源字节(官方 CDN host/path 形态)。
- CDN path 支持 `GET` / `HEAD` / Range / 条件请求;ETag 优先使用 download
manifest 中的 BLAKE3,响应包含 Last-Modified、Accept-Ranges 和长期缓存头。
- 版本/清单发现优先走 RPC:先 `daemon.status`,再 `daemon.doctor`,再
`catalog.status` / `resource.manifest`(可用 `--socket` 指定 socket 文件)。
- 支持 `.env` / 环境变量配置监听端口、public base URL、RPC socket,并预留
database/redis 键供后续 API 持久化;**不**负责资源自动拉取。
- 支持 `.env` / 环境变量配置监听端口、public base URL、RPC socket 和 RPC
刷新周期,并预留 database/redis 键供后续 API 持久化;**不**负责资源自动拉取。
- 可选改写 server-info 中的 `AddressablesCatalogUrlRoot` 指向自身;不伪装
完整游戏业务 API,launcher 全链非本服务关闭条件。
完整游戏业务 API。启动前资源 metadata 兼容属于资源 bootstrap;账号、登录、
Gateway、游戏业务 `ApiUrl` 和鉴权全链非本服务关闭条件。
- Rust `bat` / daemon 负责:官方资源自动发现与拉取、校验、catalog 更新检查、
版本状态与发布、任务队列/日志/错误/进度管理等长期状态型工作。
- Go 层**不**直接嵌入 Rust FFI,不直接读写 daemon 的状态文件;跨语言控制面
只经 RPC 契约。文件字节从 RPC 给出的 `resource_root`(或显式
`--resource-root`)读取,与 daemon 同机或共享文件系统部署。
只经 RPC 契约。生产文件字节从 RPC 给出的 `resource_root` 读取,`bat-api`
与 daemon 同服务器、同容器或同一共享文件系统部署;显式 `--resource-root`
只用于 fixture、本地开发或 RPC 不可用时的应急只读诊断。
### 7.3 FFI 的定位(降级说明)
+58 -10
View File
@@ -1,7 +1,7 @@
# 官方资源 Release 布局与资源侧契约
- **更新时间**2026-07-24
- **用途**:冻结日服官方资源在本地发布根上的布局、URL 映射、seed 规则,以及 `bat-api` 分发 path 的 1:1 对应关系。
- **更新时间**2026-07-27
- **用途**:冻结日服官方资源在本地发布根上的布局、URL 映射、seed 规则`bat`/`bat-api` 关系,以及 `bat-api` 分发 path 的 1:1 对应关系。
- **范围**:资源发现 / 清单 / 落盘 / 只读分发(**不是**完整游戏业务 API)。
- **权威代码**
- URL / 平台 / seed`adapters/src/official/yostar_jp.rs`
@@ -17,7 +17,7 @@
| 角色 | 组件 | 职责 |
|---|---|---|
| 同步 / 运维(近乎全自动) | Rust `bat` | auto-discover、拉取、校验、发布、watch/daemon、RPC 后端 |
| 资源只读分发 | Go `bat-api` | 按官方 CDN path 提供已发布字节;经 `bat.sock` 发现版本 |
| 资源 bootstrap / 只读分发 | Go `bat-api` | 同环境经 `bat.sock` 发现已发布版本和 `resource_root`,提供 `/v1/bootstrap`、server-info 改写和官方 CDN path 字节 |
| 试验 CLI | Go `cmd/bat``bin/bat-go` | 非产品;禁止与 Rust `bat` 重名 |
**禁止**:把已安装客户端目录或 `/home/wanye/D/BlueArchive` 当作生产输入;真实全量样本优先服务器 release 或 `/tmp` 隔离目录。
@@ -32,7 +32,11 @@
versions/<id>/ # 已发布 versioned release= resource_root
official-download-manifest.json
official-parse-cache.json # 校验后派生解析缓存,不是汉化产物
official-sync-snapshot.json # 常在 active root / current 下
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/
@@ -65,6 +69,7 @@
.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> # 已汉化后才切换;未汉化状态不发布
@@ -83,7 +88,7 @@
|---|---|
| 下载写入 | `<output>/.staging/<id>` |
| 发布完成 | rename 到 `versions/<id>`,再切换 `current` |
| 生产读取 / bat-api | `current` 解析后的 versioned 目录,或 RPC 给出的 `version.resource_root` |
| 生产读取 / bat-api | RPC 给出的 `version.resource_root`;通常等价于 `current` 解析后的 versioned 目录 |
---
@@ -110,7 +115,7 @@ https://{host}/{path...} → <resource_root>/{host}/{path...}
| `prod-clientpatch.bluearchiveyostar.com` | Addressables / Table / Media / PatchPack 内容 |
| `yostar-serverinfo.bluearchiveyostar.com` | server-info JSON |
launcher 包 CDN 属于启动器链,**不是**默认资源 release 主体。)
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
@@ -121,6 +126,45 @@ GET {public-base-url}/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.json``manifest.json``BlueArchive_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`
@@ -226,10 +270,14 @@ https://prod-clientpatch.bluearchiveyostar.com/<root_token>
| 面 | 假设(当前工程) | bat-api 行为 |
|---|---|---|
| client-patch 内容 | GET 官方 path;无业务鉴权头(资源 CDN) | `GET/HEAD /prod-clientpatch.../...` 原样字节 |
| 启动前资源发现 | 客户端/补丁器需要知道当前资源版本、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;字段 PascalCase`ConnectionGroups` 等) | 可选加载并**只改** `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 / 断点 | 官方客户端下载器用 Range;bat 用 curl `.part` | **本轮 bat-api 可不实现 Range**;记入后续 |
| Range / 断点 | 官方客户端下载器用 Range;bat 用 curl `.part` | `ServeContent` 支持 Range / `206` / `416` / `If-Range` |
| 缓存 / 条件请求 | 资源位于 versioned rootmanifest 有 BLAKE3 | ETag 优先使用 manifest BLAKE3;返回 Last-Modified、Accept-Ranges、长期 Cache-Control |
| 业务 ApiUrl/Gateway | 游戏协议 | **不改写、不仿造** |
Addressables 改写后客户端拼接:
@@ -245,7 +293,7 @@ Addressables 改写后客户端拼接:
## 8. RPC 与分发发现顺序
`bat-api`(及任何 Go 服务层)发现当前 release
`bat-api`(及任何 Go 服务层)发现当前 release,并由 `/v1/bootstrap` 组织为启动前资源入口
1. `daemon.status`
2. `daemon.doctor`
@@ -255,7 +303,7 @@ Addressables 改写后客户端拼接:
**不读** `bat-status.json` / `bat-tasks.json` 作为常规路径。
配置:`--socket` / `BAT_API_SOCKET`;应急 `--resource-root`。见 `cmd/bat-api/.env.example`
生产配置:`--socket` / `BAT_API_SOCKET``bat-api``bat` 在同服务器、同容器或同共享文件系统环境内运行。`--resource-root` 只用于本地 fixture 或应急只读诊断,不作为生产资源根配置。`BAT_API_REFRESH_INTERVAL` 控制 bat-api 周期重读 RPC,以跟随 Rust `bat` 发布新 release。见 `cmd/bat-api/.env.example`
---