Files
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

73 lines
7.2 KiB
Markdown
Raw Permalink 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.
# 变更日志
所有重要的项目变更都将记录在此文件中。
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
## [未发布]
### 新增
- Addressables catalog 提取 `m_Crc`bundle IEEE CRC-32):`ResourceEntry` 新增 `crc` 字段(compact/expanded 两种形态均解析),SQLite 持久化并对旧库幂等迁移补列;core 新增 `crc32_ieee``ResourceEntry::verify_downloaded_bytes`(按声明的 size/CRC 校验字节)(issue #2
- UnityFS 解析新增目录条目越界校验:directory 的 `offset+size` 必须落在解压数据区内,截断/损坏 bundle 的越界目录条目不再被静默接受(issue #3
- 官方资源下载支持多线程:并行仅作用于实际网络下载(默认并发 4,可经 `--download-concurrency` / `BAT_DOWNLOAD_CONCURRENCY` 配置为 `1..=256`),manifest/quarantine 簿记与 seed `.hash` 校验保持串行,`fail-fast` 与「不发布不完整资源」不变量不变(issue #17
### 修复
- 官方下载失败重试之间加入指数退避(网络类失败 200ms→400ms→800ms…,上限 5s),并发下载时对官方 CDN 更礼貌
### 计划
- [ ] 实现 `bat-api`:仿 BlueArchive 官方 API 的 Go HTTP 服务(含鉴权/签名验签,issue #19
- [ ] 官方同步结果接入 CAS + ResourceRepository 的用户级工作流
- [ ] 官方下载/导入路径接入 CRC/size 校验(复用 `verify_downloaded_bytes`
- [ ] 实现翻译系统
- [ ] 实现 Patch 引擎
- [ ] 实现 Web 管理后台
## [0.2.0] - 2026-07-17
### 新增
- 引入统一 `BAT-ERR` 错误码模型(`ErrorCode` / `ApiError`:数字码、kind、域、位置、可重试标记),接入下载、launcher/metadata、server-info/marker 与配置校验路径;新增 `USERGUIDE.md` 用户指南(命令、选项、退出码、错误码参考、RPC 接口)
- daemon 的 `bat.sock` Unix socket JSON-RPC 扩展为面向 Go 服务层的 Rust Resource Backend API:统一应用层 envelope`ok`/`status`/`data`/`error`/`request_id`),方法覆盖 `daemon.*`status/logs/stop/reload/refresh)、`resource.*`state/sync/verify/manifest)、`catalog.*`status/versions/diff/refresh)、`task.*`status/list/cancel/logs
- 新增异步任务执行器:`resource.sync` / `resource.verify` / `catalog.refresh` 入队即返回 `task_id`,单 worker FIFO 串行执行并与 watch 循环互斥,支持进度日志与协作式取消
- 任务历史文件态持久化 `<state-dir>/bat-tasks.json`(版本化、`0600` 原子写):daemon 重启后任务历史仍可查,中断任务标记 `task_interrupted``BAT-ERR-700005`
- 新增 `.env` 无参启动:`bat` 首次启动在二进制所在目录释放配置模板(`0600`)并自动加载,优先级为命令行参数 > 进程环境变量 > `.env` > 内置默认值,Redis 配置键预留
- 初始化 Monorepo 项目结构
- 创建 Rust workspace (bat-cas-engine, bat-assetbundle, bat-patch, bat-ffi)
- 创建 Go module 结构
- 配置 Docker Compose 支持本地和远程数据库
- 添加 Makefile 统一构建入口
- 创建架构文档和开发指南
- 完成 CAS V1:原子写入、BLAKE3 校验、SQLite 引用计数、GC、并发写入测试和损坏检测
- 新增官方日服资源同步链路:auto-discover、pull plan、snapshot、marker diff、本地 manifest audit/repair
- 新增 Rust 官方同步 binary,当前正式入口为 `bat`,支持 one-shot、`--watch`、默认 1 小时间隔、人类可读默认输出和 `--json` 结构化 report
- 官方同步正式入口统一为 `bat`,新增 `--daemon` 后台模式和基于 `bat.sock` 的 Unix socket JSON-RPC 控制面,管理命令覆盖 `status``stop``restart``reload``refresh``logs``verify``repair``doctor``clean-stable`
- 新增 daemon 控制锁 `bat-control.lock`、daemon 与前台同资源目录写入互斥,以及失效/损坏 PID 和锁文件恢复逻辑
- 新增官方同步路径安全边界:拒绝危险输出目录和 snapshot 路径逃逸,下载目标、manifest、daemon PID/status/log/control 文件不跟随 symlinkdaemon 状态文件默认使用 `0600` 权限
- 新增官方资源原子发布布局:非 dry-run 下载先进入 `.staging/<id>`,校验和 manifest/snapshot 写入完成后发布到 `versions/<id>`,再原子切换 `current` symlink
- 新增 daemon 可观测性:`bat-events.jsonl` 结构化 JSONL 日志、日志轮转、status 中的当前下载进度、最后成功时间、下次检查时间和最后错误摘要
- 新增运行时下载与校验 progress log:总体下载进度、单文件开始/完成状态、官方 `.hash`、本地 BLAKE3、需修复项和 ZIP 结构校验摘要
- 新增官方资源同步生产部署模板:release binary symlink 路径、systemd unit、运行用户、日志位置、升级和回滚流程
- 新增真实官方网络全量拉取 smoke:`scripts/official-full-pull-smoke.sh``make official-smoke``docs/guides/official-full-pull-smoke.md`
- 新增官方资源下载校验:官方 URL 拒绝、`.part` 续传、重试、本地 size+BLAKE3、官方 seed `.hash` 校验
- 新增下载失败分类与 quarantine403/404/普通 4xx 不重试,5xx/429/网络类错误重试,最终失败写入 `official-download-quarantine.json` 并阻止发布不完整资源;旧 launcher 包支持官方 primary/backup CDN 切换
- 新增官方版本状态管理:`official-version-state.json` 持久化当前已完成版本、正在拉取版本、上一个可用版本和失败版本,并在 `bat status` 中暴露状态摘要
- 优化资源导入链路:CAS 导入会写入 `ResourceRepository`AssetBundle 记录 UnityFS 摘要,TextAsset/Table/Media 按资源类型分类并可被索引
- 新增离线回归 fixture:当前 catalog、上一个版本 catalog、catalog 结构变化、403、404 和官方 seed hash mismatch 样本
- 新增 Addressables 当前真实形态 fixture/golden 测试
- 新增 SQLite Resource Repository 和粗粒度 FFI JSON 接口
- 补齐官方资源运行、架构、状态、缺口和交接文档
### 修复
- 修正 Unity 版本范围比较:改为按 `(major, minor, patch)` 数值比较,`2021.3.9f1` 等带发布后缀的正式版本号不再被字典序误判越界
- 将 curl 进程启动时的 `ETXTBSY`(可执行文件忙)归为可重试的瞬时竞态并加短退避,消除多线程测试环境下的偶发失败
- 修正对抗性审查发现的 launcher 链错误码误归类:非官方 CDN 根归 `non_official_url`、远端 manifest/包内容缺陷归 `launcher_response_invalid`、解压失败归完整性域
- 串行化 `bat-status.json` 的读-改-写,消除 daemon 状态文件并发写竞态
### 安全
- 代理凭据不再落入世界可读位置:传给 curl 子进程时经 `ALL_PROXY` 环境变量而非 `--proxy` 参数,不进 curl 的 `/proc/<pid>/cmdline``--daemon` 模式下代理凭据经环境变量下传后台子进程,不进子进程 argv 或 `bat-status.json`,复用凭据单独存于 `0600``bat-proxy.secret` 并在 `clean-stable` 后台停止后清除;日志与 `status` 输出对带凭据代理 URL 脱敏(含无 `scheme` 形式);推荐带凭据代理用 `HTTPS_PROXY` 等环境变量配置
## [0.1.0] - 2026-06-27
### 新增
- 项目初始化
- 基础架构搭建