feat(assetbundle): 完善官方资源解析与双目录发布

This commit is contained in:
2026-07-25 20:51:01 +08:00
parent 102b49b666
commit 3e9bb20d79
37 changed files with 4663 additions and 1333 deletions
+48 -50
View File
@@ -1,16 +1,17 @@
# BlueArchiveToolkit 当前工作区状态
- **更新时间**2026-07-20
- **更新时间**2026-07-24
- **状态来源**:本地工作区盘点、代码验证和最新提交
- **状态分支**`experiment`
- **最新已推送功能提交**:以当前 `git log --oneline -1` 为准
- **权威计划**`PROJECT_PLAN.md`
- **Go 进度权威**`docs/reports/GO_STATUS.md`
---
## 1. 总体判断
当前项目处于 **稳定基线完成、CAS V1 已落地、Rust 官方资源同步链路已具备可持续生产运行形态、Go `bat-api` 已有 Rust daemon RPC client 但 CLI/API/Web 仍未形成产品入口** 阶段。
当前项目处于 **稳定基线完成、CAS V1 已落地、Rust 官方资源同步链路已具备可持续生产运行形态、Go 侧以 `bat-api` 资源分发 MVP + `backendrpc` 为正式服务入口(同步/运维命令行仍为近乎全自动的 Rust `bat`)** 阶段。
Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
@@ -23,13 +24,13 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
7. 支持 curl 传输层本地代理:默认自动检测 `HTTPS_PROXY` / `ALL_PROXY` / `HTTP_PROXY` 及小写环境变量(带凭据的代理推荐用环境变量配置),也可用 `--proxy <URL>` 显式指定或 `--no-proxy` 强制直连;代理决策会写入 progress log、daemon log 和 `bat doctor` 诊断输出。代理凭据不落世界可读位置:日志/`status` 脱敏,传给 curl 经 `ALL_PROXY` 环境变量而非 argv`--daemon` 下经环境变量下传后台子进程、不进子进程 argv 或 `bat-status.json`,复用凭据存于 `bat-proxy.secret``0600`)且 `clean-stable` 会清除。
8. `bat --watch` 可常驻运行,`bat --daemon` 可后台运行并用 `bat status` / `bat stop` / `bat restart` / `bat reload` / `bat logs` 管理;daemon 使用 `bat.sock` Unix socket JSON-RPC 作为 live 控制通道,PID/状态/日志文件作为快照和 fallback,`bat-events.jsonl` 记录带轮转的结构化事件日志,`bat-control.lock` 串行化控制命令;正常检查默认每 1 小时一次;远端和本地一致时默认静默,失败后默认 60 秒快速重试;CLI 默认向 stdout 输出人类可读摘要,向 stderr 输出 ASCII banner、progress log、失败分类和 quarantine 状态,需要机器输出时使用 `--json --no-progress`
9. 远端 snapshot 未变化但输出目录为空时,会按首次运行执行全量拉取;官方 seed `.hash` 校验失败时会清理对应 manifest 条目,避免失败产物被后续本地 audit 误判为可复用。
10. 默认资源目录是 `./bat-resources`,默认后台状态目录是 `/tmp/bat-pid`;资源目录是发布根目录,包含 `current` symlink、`versions/<id>``.staging/<id>`,非 dry-run 会先写 staging,校验完成后发布 versioned 目录并原子切换 `current`;如果上一轮同一 app version、bundle version 和 Addressables root 的 staging 失败但目录仍安全存在,下一轮会复用该 staging 并按 manifest 逐文件校验/补下载;后台状态目录包含 `bat.sock``bat.pid``bat-status.json``bat-daemon.log``bat-events.jsonl`、任务历史 `bat-tasks.json` 和短生命周期 `bat-control.lock`;非 dry-run 使用 `--output/.official-sync.lock` 防止并发写同一资源目录,live daemon 会阻止前台写命令直接修改它正在管理的同一目录。
10. 默认官方原版资源目录是 `./bat-resources`,默认汉化产物目录是 `./bat-localized`,默认后台状态目录是 `/tmp/bat-pid`官方资源目录是发布根目录,包含 `current` symlink、`versions/<id>``.staging/<id>`,非 dry-run 会先写 staging,校验完成后发布 versioned 目录并原子切换 `current`;如果上一轮同一 app version、bundle version 和 Addressables root 的 staging 失败但目录仍安全存在,下一轮会复用该 staging 并按 manifest 逐文件校验/补下载;后台状态目录包含 `bat.sock``bat.pid``bat-status.json``bat-daemon.log``bat-events.jsonl`、任务历史 `bat-tasks.json` 和短生命周期 `bat-control.lock`;非 dry-run 使用 `--output/.official-sync.lock` 防止并发写同一资源目录,live daemon 会阻止前台写命令直接修改它正在管理的同一目录。
11. 官方同步会拒绝危险输出目录、路径逃逸和现有 symlink 路径组件;下载目标、`.part`、manifest、snapshot、PID、status、log 和控制锁文件不会跟随 symlink,daemon 状态类文件默认以 `0600` 权限创建。
12. `<output>/official-version-state.json` 会明确保存当前已完成版本、正在拉取版本、上一个可用版本和失败版本;同一 app version、bundle version 和 Addressables root 的失败只保留最新一条,同一版本开始重新拉取或后续发布成功时会清理对应失败记录;`bat status` 会显示最后成功时间、下次检查时间、最后错误摘要、当前阶段、当前下载 URL 进度、版本状态摘要、最近历史失败版本和原因、结构化日志路径和轮转日志路径,人类可读输出不会把完整版本状态 JSON 内联打印。
13. 资源导入链路已支持 CAS + `ResourceRepository` 索引写入,AssetBundle 导入会记录 UnityFS 摘要,TextAsset/Table/Media 会按类型分类;当前/上一个/结构变化 catalog、失败 staging 复用、403/404、hash mismatch、CRC 与 UnityFS 边界校验均有离线回归 fixture 或单测覆盖。
14. `bat` 首次启动会在二进制所在目录释放 `.env` 配置模板(`0600`),之后每次启动自动加载(不覆盖已存在的环境变量),支持 `BAT_OUTPUT`/`BAT_STATE_DIR`/`BAT_AUTO_DISCOVER`/`BAT_WATCH`/`BAT_DAEMON`/`BAT_PROXY` 等键,实现编辑 `.env` 后无参启动;优先级为命令行参数 > 进程环境变量 > `.env` > 内置默认值,`BAT_SKIP_ENV_FILE=1` 可整体禁用;Redis 键为预留。daemon 任务历史持久化在 `<state-dir>/bat-tasks.json`(版本化、`0600` 原子写),重启后任务经 `task.*` 仍可查,中断任务标记 `task_interrupted``BAT-ERR-700005`)。
14. 非 dry-run 官方同步在校验完成并发布后,会在 active release 下刷新 `official-parse-cache.json`;每轮根据 `official-download-manifest.json` 的 URL、相对路径、size 和 BLAKE3 判断是否复用旧解析结果,本地文件未变化时跳过重复解析。解析入口覆盖下载 manifest 中的全部官方资源:直接 UnityFS bundle、zip 内 UnityFS 条目会进入解析,其它 catalog/hash/media 文件记录为不支持而不是失败。官方同步报告默认 `localized_release_status=not_localized`,含义是原版资源已经发布、汉化资源未发布;后续 Patch 发布完成后才应切换为 `localized`,表示原版和汉化两套资源都可发布。`bat` 首次启动会在二进制所在目录释放 `.env` 配置模板(`0600`),之后每次启动自动加载(不覆盖已存在的环境变量),支持 `BAT_OUTPUT`/`BAT_LOCALIZED_OUTPUT`/`BAT_STATE_DIR`/`BAT_AUTO_DISCOVER`/`BAT_WATCH`/`BAT_DAEMON`/`BAT_PROXY` 等键,实现编辑 `.env` 后无参启动;优先级为命令行参数 > 进程环境变量 > `.env` > 内置默认值,`BAT_SKIP_ENV_FILE=1` 可整体禁用;Redis 键为预留。daemon 任务历史持久化在 `<state-dir>/bat-tasks.json`(版本化、`0600` 原子写),重启后任务经 `task.*` 仍可查,中断任务标记 `task_interrupted``BAT-ERR-700005`)。
仍需明确:这不是完整产品完成。Go 产品入口、完整 AssetBundle 引擎解析、Patch、翻译系统、API Server 和 Web 仍是后续工作;真实官方网络全量拉取 smoke 已固化为可重复脚本和 runbook(G-018 已关闭),当前正在进行长期运行测试,运行报告将在后续提供;真实大文件产物与运行报告默认保存`/tmp` 隔离目录,不纳入 Git。
仍需明确:这不是完整产品完成。完整 AssetBundle 引擎、Patch、翻译、Web、以及 `bat-api` 的服务器联调/可选业务扩展仍是后续工作;G-008(产品级 Go 同步 CLI)已决策关闭。真实官方网络全量拉取 smoke 已固化(G-018 已关闭);真实大文件与运行报告默认在 `/tmp` 隔离目录,不纳入 Git。Go 细节见 `docs/reports/GO_STATUS.md`
---
@@ -41,6 +42,7 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
- `docs/guides/official-resource-test-pull.md`:官方资源拉取与自动更新用户指南。
- `docs/guides/official-full-pull-smoke.md`:真实官方全量拉取 smoke runbook 和可重复命令。
- `docs/architecture/official-resource-backend.md`:官方资源后端设计和审核说明。
- `docs/architecture/assetbundle.md`:解析补全路线图,覆盖 Addressables、UnityFS、Serialized 字段级解析、文本提取、CAS 接入和 Patch 发布前置。
- `docs/reports/CURRENT_GAPS.md`:当前缺口和关闭顺序。
历史 Week 2/Week 3 报告只作追溯,不再代表当前状态。
@@ -96,7 +98,7 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
待完成:
- `crates/bat-assetbundle` 仍是占位 crate,完整 UnityFS/对象表/TypeTree 引擎未实现。
- `crates/bat-assetbundle` 已具备 UnityFS 容器基础解析,完整对象表/TypeTree/TextAsset/MonoBehaviour/ScriptableObject 引擎未实现。
- Addressables parser 已覆盖当前真实形态 fixture/golden 与 `m_Crc`,但仍需继续覆盖二进制/压缩字段组合和更细失败诊断。
- 客户端发现、备份、应用补丁流程尚未连接真实实现。
@@ -144,20 +146,23 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
### `bat-assetbundle`
状态:**占位**
状态:**UnityFS 解包和 TextAsset 提取已起步;MonoBehaviour/ScriptableObject 字段级解析未完成**
当前有:
当前有:
- Parser trait 仍是占位
- AssetType 仍是占位
- 错误类型骨架可用,但没有完整解析引擎
- `UnityFsParser``UnityFsBundle``ParsedAssetBundle``RawAssetBundle` 等正式类型
- UnityFS header、block info、directory 解析
- block info at end、LZ4/LZMA block info 解压、LZ4/LZMA 数据 block 解压、directory 文件提取、压缩/解压数据区大小和 directory 越界诊断
- Unity serialized file header、type table、TypeTree node 元数据、object table 和 TextAsset bytes 提取。
- `ResourceImportService` 的 UnityFS 摘要已包含解包文件数、serialized file 数、TextAsset 数量和名称。
- `bat-adapters` 的 Unity 2021.3 adapter 已改为版本选择薄层,复用 `bat-assetbundle`,避免两套 UnityFS parser。
待完成:
- UnityFS header、block、directory、metadata、object table
- LZ4/LZMA 解压
- TypeTree 解析
- TextAsset、MonoBehaviour、ScriptableObject 解析入口
- MonoBehaviour、ScriptableObject 的 TypeTree 字段级反序列化
- 修改 TextAsset/字段值后的 AssetBundle 重打包或 Patch 生成
- 真实资源 fixture 覆盖对象级解析和文本提取
- 详细补全顺序见 `docs/architecture/assetbundle.md`
### `bat-patch`
@@ -198,15 +203,19 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
### Go / API / Web
状态:**Go 产品入口仍未完成;`bat-api` 已有 typed Rust daemon RPC client、可选 CGO 兼容包装和试验性 `cmd/bat` 骨架**
状态:**边界已冻结;资源分发 MVP 已落地。权威细节见 `docs/reports/GO_STATUS.md`**
当前情况:
| 角色 | 所有者 | 状态 |
|---|---|---|
| 同步/运维命令行(近乎全自动) | Rust `bat` | 产品入口 |
| 资源分发 HTTP | Go `cmd/bat-api` | CDN MVP |
| daemon RPC client | `internal/backendrpc` | 完成 |
| 试验 CLI | `cmd/bat``bin/bat-go` | 非产品 |
| FFI | `internal/ffi` | 可选 |
| 空目录 `api/` `pkg/` 等 | 占位 | 无实现 |
| Web | `web/` | 空(G-010 |
- `internal/backendrpc` 已提供 Go typed Unix socket JSON-RPC client,作为 `bat-api` 调用 Rust daemon 的默认路径
- `internal/ffi/ffi.go` 已存在。
- Go CLI 的稳定集成方向仍应优先通过 Rust daemon RPC 或 Rust `bat --json` one-shot 进程边界;`cmd/bat` 目前只是试验性骨架,不代表产品级 CLI 已完成。
- `cmd/``pkg/``api/``web/` 仍无可用产品入口,`cmd/bat` 目前只覆盖 `doctor``manifest inspect``sync plan` 这类最小演示能力。
- `go test ./...` 目前只有空测试包结果,`go vet ./...` 可作为基础门禁。
默认 Go 门禁:`make test-go-api``make build-go-api`(无 FFI
---
@@ -216,27 +225,16 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
```bash
cargo test --workspace --quiet
cargo clippy --workspace --all-targets -- -D warnings
go test ./...
go vet ./...
go build -o /tmp/bat-go-cli ./cmd/bat
target/debug/bat --help
git diff --check
make test-go-api
make build-go-api
go vet ./internal/api/... ./internal/backendrpc/... ./cmd/bat-api/...
```
同步确认
未执行 / 后置
```bash
git status --short --branch
```
结果:工作区干净。
未执行:
- 本次状态更新未执行一次性真实官方网络全量下载 smoke;该流程已由 `docs/guides/official-full-pull-smoke.md``scripts/official-full-pull-smoke.sh` 固化并关闭(G-018),当前处于长期运行测试阶段,运行报告将在后续提供。
- Go CLI 端到端测试,因为 Go 产品入口尚未完成;`internal/backendrpc` 已有 fake transport 单测覆盖。
- Web/API 测试,因为 Web/API 尚未实现。
- 真实官方全量 smoke 长期运行报告(G-018 命令已固化)。
- `bat-api` 对服务器全量 release 的 SSH 联调(等连接信息)。
- WebG-010)。
---
@@ -265,15 +263,15 @@ cargo run -p bat-infrastructure --bin bat -- \
## 6. 当前阻塞项
GitHub issue 状态:#1升为 P0#17 的实现已合入 HEAD,但 issue 本身尚未关闭,需在验收后再同步关闭。其他 open issue 的实时标签以 GitHub 为准。
GitHub issue 状态:#1关闭#17 已按 wontfix 关闭(多线程下载入口已移除,下载回归顺序执行并保留指数退避与单调进度上报,子 issue #20#23 均已关闭。其他 open issue 的实时标签以 GitHub 为准。
下一阶段必须优先完成:
1. Issue #1P0,主体已实现):`bat.sock` Unix socket JSON-RPC 已扩展为面向 Go 服务层的 Rust Resource Backend API。统一 envelope`ok``status``error``data``request_id`)与 `BAT-ERR` 错误码模型已落地;`daemon.*`status/logs/stop/reload/refresh/doctor)、`resource.*`state/sync/verify/repair/manifest/list)、`catalog.*`status/refresh/diff/versions)、`task.*`status/list/cancel/logs)已实现,长任务返回 `task_id` 可轮询(任务执行器单 worker FIFO,与 watch 循环互斥;任务历史持久化于 `<state-dir>/bat-tasks.json`,daemon 重启后仍可查,中断任务标记 `task_interrupted`);错误码已接入下载、launcher/metadata、server-info/marker 与配置校验路径。剩余:`patch.*` / `unityfs.*`(被引擎阻塞)、`task.create`(按设计由语义方法创建)、`daemon.restart` / `daemon.clean-stable`(由 CLI 侧按进程生命周期显式执行,live RPC 内不做自重启或在线清理)、Redis 任务后端(`.env` 已预留配置键,接入时机另议)。Go 层通过 RPC 调用 Rust backend,不走 FFIFFI 降级说明见 `docs/architecture/official-resource-backend.md` §7)。
2. `bat-api` Go 侧:`internal/backendrpc` typed RPC client 已起步,`cmd/bat` 当前只实现 `doctor``manifest inspect``sync plan` 这类试验性入口,不能视作产品级 CLI;是否继续作为长期产品入口需要单独收敛
2. Go 侧:进度见 `docs/reports/GO_STATUS.md`。G-008 已关闭;`bat-api` 资源分发 MVP 已落地;联调与 USERGUIDE 专章后置
3. 官方同步结果接入 CAS + ResourceRepository 的用户级工作流(G-011 剩余部分:自动导入触发、schema 迁移、CLI 查询)。
4. Issue #3P2):AssetBundle UnityFS 基础解析校验。
5. Issue #2P2):继续逆向 Addressables catalog,提取 bundle hash/size/CRC 等可校验字段。
4. Issue #3P1):AssetBundle UnityFS 基础解析校验已具备离线和隔离真实样本覆盖;对象级解析继续跟踪 G-005
5. Issue #2P1):继续逆向 Addressables catalog,提取 bundle hash/size/CRC 等可校验字段。
6. Patch 和翻译系统仍应后置。
非阻塞跟踪项:官方同步长期运行测试正在进行,运行报告将在后续提供。
@@ -285,12 +283,12 @@ GitHub issue 状态:#1 已升为 P0#17 的实现已合入 HEAD,但 issue
立即任务:
1. Issue #1 收尾:协议基础设施、最小方法集、`catalog.*``task.*``resource.repair`、任务持久化、错误码模型与文档(USERGUIDE §5/§6、架构文档 §7)均已完成;剩余 `patch.*`/`unityfs.*`(待引擎)以及 `task.create``daemon.restart``daemon.clean-stable` 的设计边界确认。
2. 明确 Go 产品入口的边界:是继续推进独立 `bat` CLI,还是保留当前 Rust `bat` 为用户 CLI、Go 只做服务层与 `bat-api`
3. 跟进官方同步长期运行测试,收集并归档运行报告。
4. 开始 AssetBundle parser 的 UnityFS header/block/directoryissue #3),并继续扩展 Addressables catalog 可校验字段(issue #2)。
2. `bat-api` 与全量 release / 服务器 daemon 联调(issue #19 剩余)
3. 跟进官方同步长期运行测试报告。
4. AssetBundle / Addressablesissue #3 / #2);CAS 用户级导入(G-011)。
---
- **当前总体完成度**:不再固定写单一百分比,以各模块状态和 issue 为准。
- **当前基线状态**Rust 官方资源同步链路已具备可运行闭环;Go `bat-api` 已有 Rust daemon RPC client,但产品级 CLI/API、CAS 用户级导入完整 AssetBundle 引擎未完成。
- **下一工程里程碑**Rust Resource Backend RPC API 收尾、Go 产品入口收敛、官方同步结果接入 CAS/ResourceRepository、AssetBundle 解析起步
- **当前总体完成度**:不再固定写单一百分比,以各模块状态`GO_STATUS.md` 和 issue 为准。
- **当前基线状态**Rust `bat` 同步闭环可用;Go `bat-api` 资源分发 MVP + `backendrpc` 可用;CAS 用户级导入完整 AssetBundle 引擎未完成。
- **下一工程里程碑**bat-api 联调、CAS/ResourceRepository 用户流、AssetBundle 解析。