Files
BlueArchiveToolkit/CURRENT_STATUS.md
T
nyaKazuhaandClaude Fable 5 0ab3f3b953 feat(download): 多线程下载 + 重试指数退避(issue #17)
下载主循环由串行改为「并发下载 + 串行簿记」三段式:
- Phase A:无网络前置校验(官方性/目标路径/建目录)+ 判定跳过/需下载,
  非官方 URL 在任何下载前 fail-fast
- Phase B:need-download 项经 scoped 线程池并发下载(默认并发 4,
  可配 1..=256)。worker 只做只读 &self 的 pull_one(各 URL 独立
  .part/目标文件),经 mpsc 把结果送回主线程;manifest/quarantine
  簿记与进度回调全在主线程串行执行,无需加锁。首个失败或 should_cancel
  置 cancel 标志,其余 worker 在任务边界停止
- Phase C:按 plan 顺序串行收尾——seed .hash 校验(顺序相关、可
  fail-fast)+ 构建有序结果

fail-fast 与「不发布不完整资源」不变量保留;进度事件按 URL 配对但
顺序不再单调(并发下天然如此)。

curl 重试加指数退避(网络类 200ms→400ms→800ms…上限 5s;ETXTBSY 仍走
极短退避),并发下对官方 CDN 更礼貌;退避基值 cfg(test) 下为 0 不拖慢
单测。

并发度经 OfficialUpdateConfig.download_concurrency 贯通,CLI
--download-concurrency 与 BAT_DOWNLOAD_CONCURRENCY 可配,.env 模板
与 USERGUIDE/CURRENT_STATUS/CHANGELOG 同步。

验证:新增并发正确性测试(并发 8:每 URL 恰一次 started+finished、
全部落盘)、并发度钳制、退避时长计算、CLI/env 解析单测;progress
排序测试改为顺序无关不变量;workspace 全测试(20 套件) + fmt +
clippy --all-targets -D warnings 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 03:25:04 -07:00

295 lines
17 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.
# BlueArchiveToolkit 当前工作区状态
- **更新时间**2026-07-15
- **状态来源**:本地工作区盘点、代码验证和最新提交
- **状态分支**`experiment`
- **最新已推送功能提交**:以当前 `git log --oneline -1` 为准
- **权威计划**`PROJECT_PLAN.md`
---
## 1. 总体判断
当前项目处于 **稳定基线完成、CAS V1 已落地、Rust 官方资源同步链路已具备最小生产运行形态、Go CLI/API/Web 仍未落地** 阶段。
Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
1. 首次运行可以通过 `--auto-discover` 从官方 HTTP metadata 解析 `GameMainConfig`,自动获得 `app-version``connection-group``server-info`;解密出的 `GameMainConfig` JSON 会校验已知字段,避免把错误解密结果当成成功。
2. 不安装、不启动、不依赖已安装官方启动器。
3. 默认平台为 `Windows + Android`
4. 能生成官方全量 pull plan,执行真实下载,维护 release 内的 `official-download-manifest.json`
5. 下载后使用本地 manifest 的 size + BLAKE3 校验复用文件;所有 `.zip` 在下载验收、复用、本地 audit/verify 时做 ZIP 结构校验;官方 seed `.hash` 使用标准 `xxHash32(seed=0)` 强校验(早期实现的非标准 avalanche 常量已修正)。
6. 支持 `.part` 断点续传、失败后 clean retry、本地 manifest audit/repair、失败 staging 恢复复用、403/404/5xx 分类重试(重试带指数退避)、下载 quarantine 诊断,以及旧 launcher 包官方 primary/backup CDN 切换。下载支持多线程:并行仅作用于实际网络下载(默认并发 4,可经 `--download-concurrency`/`BAT_DOWNLOAD_CONCURRENCY` 配置为 `1..=256`),manifest/quarantine 簿记与 seed `.hash` 校验保持串行,`fail-fast` 与「不发布不完整资源」不变量不变。
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 会阻止前台写命令直接修改它正在管理的同一目录。
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、403/404、hash mismatch 均有离线回归 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`)。
仍需明确:这不是完整产品完成。Go CLI 最小入口、完整 AssetBundle 解析、Patch、翻译系统、API Server 和 Web 仍是后续工作;真实官方网络全量拉取 smoke 已固化为可重复脚本和 runbook(G-018 已关闭),当前正在进行长期运行测试,运行报告将在后续提供;真实大文件产物与运行报告默认保存在 `/tmp` 隔离目录,不纳入 Git。
---
## 2. 权威文档入口
- `README.md`:项目概览、当前可用能力和快速验证。
- `PROJECT_PLAN.md`:最终目标、里程碑和近期任务。
- `DOCS_INDEX.md`:文档阅读顺序和索引。
- `docs/guides/official-resource-test-pull.md`:官方资源拉取与自动更新用户指南。
- `docs/guides/official-full-pull-smoke.md`:真实官方全量拉取 smoke runbook 和可重复命令。
- `docs/architecture/official-resource-backend.md`:官方资源后端设计和审核说明。
- `docs/reports/CURRENT_GAPS.md`:当前缺口和关闭顺序。
历史 Week 2/Week 3 报告只作追溯,不再代表当前状态。
---
## 3. 当前模块状态
### Rust workspace
已显式纳入 workspace
- `core`
- `adapters`
- `infrastructure`
- `crates/bat-assetbundle`
- `crates/bat-cas-engine`
- `crates/bat-ffi`
- `crates/bat-patch`
### `bat-core`
状态:**领域模型和仓储接口骨架可用**
已包含:
- `GameClient`
- `GameVersion`
- `Resource`
- `Translation`
- `CasRepository`
- `ResourceRepository`
- `TranslationRepository`
待完成:
- 领域服务模块仍为空。
- Glossary、Provider、Patch、Manifest 等后续仓储/服务接口需要补齐。
- 公共错误模型需要与 CLI/API 错误码统一。
### `bat-adapters`
状态:**适配器框架可用,官方日服规则和 Addressables 当前样本解析已推进**
已包含:
- Unity adapter trait、注册表、Unity 2021.3 adapter 骨架。
- Manifest driver trait、Addressables driver、注册表。
- Addressables JSON catalog 的 path、hash、size、address、dependencies、metadata 解析。
- 真实形态 Addressables fixture/golden 测试。
- 当前 catalog、上一个版本 catalog、结构变化 catalog 的离线回归 fixture。
- 官方日服 `server-info`、URL 规则、平台 discovery 和 inventory 枚举。
待完成:
- Unity bundle serialize 仍是后续阶段能力。
- Addressables parser 仍需继续覆盖二进制/压缩字段组合和更细失败诊断。
- 客户端发现、备份、应用补丁流程尚未连接真实实现。
### `bat-cas-engine`
状态:**CAS V1 已完成**
已包含:
- BLAKE3 Hash。
- 原子文件写入:临时文件、fsync、rename、目录 sync。
- 文件系统对象存储:put/get/exists/delete/list/stats。
- SQLite 对象元数据和引用计数。
- 引用计数增加、减少、查询。
- GC 候选查询和 GC 删除。
- 并发写入相同内容测试。
- 损坏对象 Hash mismatch 检测。
- infrastructure 仓储适配层。
待完成:
- 更复杂的跨进程压力测试。
- 未来需要时扩展流式大文件写入。
- 未来需要时扩展非 SQLite 元数据后端。
### `bat-infrastructure`
状态:**CAS 适配层、ResourceRepository 和官方资源同步入口可用**
已包含:
- `FileSystemCasRepository` 作为 `bat-core::CasRepository` 适配层。
- `InMemoryResourceRepository`
- `SqliteResourceRepository`
- 官方 pull plan 构建。
- `OfficialResourcePullService`:官方 URL 拒绝策略、目标路径映射、下载 manifest、下载 quarantine、`.part` 续传、curl 代理配置、403/404/5xx 分类重试、ZIP 结构校验、官方 seed `.hash` 校验、本地全量 verify。
- `OfficialUpdateService`:官方 metadata auto-discover、bootstrap cache、snapshot diff、marker diff、本地 audit/repair、失败 staging 恢复。
- `bat`:正式 CLI binary,支持 one-shot、`--proxy` / `--no-proxy``--watch``--daemon``status``stop``restart``reload``refresh``logs``verify``repair``doctor``clean-stable`
待完成:
- 将官方同步下载结果作为用户级流程自动导入 CAS + ResourceRepository。
- 真实线上全量下载 smoke 已固化为 `scripts/official-full-pull-smoke.sh``make official-smoke`;实际运行报告由脚本写入隔离输出目录。
- 增加更多权限和极端文件系统场景测试。
### `bat-assetbundle`
状态:**占位**
当前只有:
- Parser trait 占位。
- AssetType 占位。
- 错误类型骨架。
待完成:
- UnityFS header、block、directory、metadata、object table。
- LZ4/LZMA 解压。
- TypeTree 解析。
- TextAsset、MonoBehaviour、ScriptableObject 解析入口。
### `bat-patch`
状态:**占位**
当前 Binary Patch 和 JSON Patch 函数返回空结果,不具备真实补丁能力。
待完成:
- Binary diff/apply。
- JSON Patch apply/validate。
- Patch manifest。
- Integrity check。
- Rollback。
### `bat-ffi`
状态:**可选无状态兼容层,非主集成边界**
已包含:
- `bat_version`
- `bat_manifest_inspect_json`:解析 Addressables manifest 并返回 JSON summary。
- `bat_sync_plan_json`:根据 current/previous snapshot 生成官方同步计划 JSON。
- `internal/ffi/ffi.go` 提供可选 CGO 兼容包装骨架。
定位约束:
- `bat-ffi` 只暴露粗粒度、无状态、一次调用一次 JSON 输入输出的 C ABI helper。
- 它不持有 downloader、daemon、CAS handle、资源目录锁或长生命周期状态。
- Go CLI 和生产运维默认应调用 `bat --json` 进程边界;未来稳定 SDK 也优先于 FFI。
- FFI 仅用于需要嵌入 C ABI 的兼容场景,不能作为官方同步控制面或主集成边界。
待完成:
- 错误码与结构化响应约定。
- 如确有兼容需求,再补发布用头文件、构建脚本和跨平台产物。
### Go / API / Web
状态:**CLI/API/Web 仍未实现,仅有可选 CGO 兼容包装**
当前情况:
- `internal/ffi/ffi.go` 已存在。
- Go CLI 默认集成方向是调用 Rust `bat --json` 并转发结构化 report,而不是依赖 FFI。
- `cmd/``pkg/``api/``web/` 仍无可用产品入口。
- `go test ./...` 在没有 Go package 时可能无测试可运行;Makefile 会清晰跳过空 Go 阶段。
---
## 4. 已验证结果
最新功能提交前已运行并通过:
```bash
cargo test -p bat-adapters -- --nocapture
cargo test -p bat-ffi -- --nocapture
cargo test -p bat-infrastructure -- --nocapture
cargo test -p bat-infrastructure --bin bat -- --nocapture
cargo run -p bat-infrastructure --bin bat -- --help
git diff --cached --check
```
提交后确认:
```bash
git status --short
```
结果:工作区干净。
未执行:
- 本次状态更新未执行一次性真实官方网络全量下载 smoke;该流程已由 `docs/guides/official-full-pull-smoke.md``scripts/official-full-pull-smoke.sh` 固化并关闭(G-018),当前处于长期运行测试阶段,运行报告将在后续提供。
- Go CLI 端到端测试,因为 Go CLI 尚未实现。
- Web/API 测试,因为 Web/API 尚未实现。
---
## 5. 当前生产运行边界
当前唯一可作为 Linux 生产资源同步任务运行的入口是 Rust binary
```bash
cargo run -p bat-infrastructure --bin bat -- \
--auto-discover \
--output /var/lib/bluearchive-toolkit/official \
--watch
```
生产要求:
1. 使用独立输出目录,例如 `/var/lib/bluearchive-toolkit/official`
2. 不要指向已有游戏客户端目录。
3. 不要指向 `/home/wanye/D/BlueArchive` 这类开发或人工维护资源目录。
4. `--auto-discover` 可以下载官方 metadata,并按官方 manifest 临时获取 `resources.assets` 以解析 `GameMainConfig`;旧 ZIP manifest 才会下载临时 game zip。该流程不会安装或启动官方 launcher。
5. 推荐生产形态是 systemd 直接托管前台 `bat --watch`unit 模板位于 `deployments/systemd/bluearchive-toolkit-official-sync.service`,稳定 binary 路径为 `/opt/bluearchive-toolkit/bin/bat`,资源发布根目录为 `/var/lib/bluearchive-toolkit/official`,生产读取方读取 `/var/lib/bluearchive-toolkit/official/current`,日志通过 `journalctl -u bluearchive-toolkit-official-sync.service` 查看;不使用 systemd 时也可用 `bat --daemon` 自托管,daemon 状态、`bat-daemon.log``bat-events.jsonl` 建议放在 `/var/lib/bluearchive-toolkit/daemon-state`。定时检查逻辑已经在 Rust 内部,正常检查默认 1 小时,失败重试默认 60 秒,每天北京时间(UTC+8)`03:00``16:00``18:00` 会强制执行一次自动刷新。
详细运行说明见 `docs/guides/deployment.md``docs/guides/official-resource-test-pull.md`
---
## 6. 当前阻塞项
GitHub issue 状态:#4#16 已全部关闭(#16 为 daemon status 版本失败输出与重复堆积 bug,已由失败版本去重和状态输出优化修复),当前 open 的是 #1P1)、#2P2)、#3P2)。
下一阶段必须优先完成:
1. Issue #1P1,主体已实现):`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)、`resource.*`state/sync/verify/manifest)、`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.*`(被引擎阻塞)、`resource.repair`(待引擎独立修复模式)、`task.create`(按设计由语义方法创建)、Redis 任务后端(`.env` 已预留配置键,接入时机另议)。Go 层通过 RPC 调用 Rust backend,不走 FFIFFI 降级说明见 `docs/architecture/official-resource-backend.md` §7)。
2. Go CLI 最小可用入口:`bat doctor`、稳定的 `bat --help` 命令结构,默认通过上述 RPC 或 `bat --json` 进程边界获取同步 report。
3. 官方同步结果接入 CAS + ResourceRepository 的用户级工作流(G-011 剩余部分:自动导入触发、schema 迁移、CLI 查询)。
4. Issue #3P2):AssetBundle UnityFS 基础解析校验。
5. Issue #2P2):继续逆向 Addressables catalog,提取 bundle hash/size/CRC 等可校验字段。
6. Patch 和翻译系统仍应后置。
非阻塞跟踪项:官方同步长期运行测试正在进行,运行报告将在后续提供。
---
## 7. 下一步建议
立即任务:
1. Issue #1 收尾:协议基础设施、最小方法集及 `catalog.*`/`task.*` 全量、错误码模型与文档(USERGUIDE §5/§6、架构文档 §7)均已完成;剩余 `patch.*`/`unityfs.*`(待引擎)与任务持久化按后续里程碑推进。
2. 实现 Go CLI 最小框架和 `doctor`,通过 RPC 或 `bat --json` 边界对接 Rust backend。
3. 跟进官方同步长期运行测试,收集并归档运行报告。
4. 开始 AssetBundle parser 的 UnityFS header/block/directoryissue #3),并继续扩展 Addressables catalog 可校验字段(issue #2)。
---
- **当前总体完成度**:约 22%
- **当前基线状态**:Rust 官方资源同步链路已具备可运行闭环;产品级 CLI/API/Web 仍未完成。
- **下一工程里程碑**Rust Resource Backend RPC API 最小方法集(issue #1)+ Go CLI 最小可用 + 官方同步结果接入 CAS/ResourceRepository + AssetBundle 解析起步。