feat: harden official sync scheduling and integrity

This commit is contained in:
2026-07-11 01:06:02 +08:00
parent 2bdc55a1be
commit 264e78c440
11 changed files with 474 additions and 99 deletions
+1 -1
View File
@@ -116,7 +116,7 @@ official-sync-snapshot.json + official-download-manifest.json
- 不安装、不执行官方 launcher。
- 默认平台 `Windows + Android`
- `--auto-discover` 自动获取 `app-version``connection-group``server-info`
- `--watch` 常驻检查,正常检查默认 1 小时,失败重试默认 60 秒。
- `--watch` 常驻检查,正常检查默认 1 小时,失败重试默认 60 秒,每天北京时间(UTC+8`03:00``16:00``18:00` 强制刷新一次
- 远端 marker 无变化且本地 manifest clean 时不下载。
- 本地文件损坏时 repair。
- 官方 seed `.hash` 强校验;Addressables `catalog_*.hash` 作为变更 marker。
+12 -9
View File
@@ -126,11 +126,12 @@
5. 缺少清单、清单不匹配或文件损坏时重新下载。
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. 存在 `.part` 临时文件时通过 `curl --continue-at -` 尝试断点续传
9. 新下载写入 `.part`,成功后原子 rename 到最终路径
10. 成功下载后更新本地下载清单
11. 记录最终文件大小、本次传输字节数、官方 hash 校验数和执行状态
12. 非官方 URL 直接拒绝
8. 官方 seed `.hash` 校验失败会让当前下载失败,并移除对应 data/hash URL 的本地 manifest 条目,避免失败产物在下一轮被本地 BLAKE3 audit 误判为健康缓存
9. 存在 `.part` 临时文件时通过 `curl --continue-at -` 尝试断点续传
10. 新下载写入 `.part`,成功后原子 rename 到最终路径
11. 成功下载后更新本地下载清单
12. 记录最终文件大小、本次传输字节数、官方 hash 校验数和执行状态
13. 非官方 URL 直接拒绝。
路径映射时会做分段清理,避免把不安全路径写进输出目录。
@@ -186,11 +187,13 @@
3. 生成当前 v2 snapshot,记录 `app_version``connection_group``bundle_version``addressables_root`、endpoint URL、seed `.hash` 内容、`catalog_*.hash` marker、launcher metadata 摘要和 `GameMainConfig` 摘要。
4. 读取上一次成功同步写出的 snapshot。
5. 使用 `OfficialSyncPlan` 和扩展 snapshot diff 判断是否需要下载;URL 未变但 `.hash` / marker 内容变化也会触发更新。
6. 远端无变化时执行本地 download manifest audit,检查路径、size 和 BLAKE3
7. 远端变化或本地 audit 发现 repair_needed 时生成 pull plan,下载并校验官方 URL
8. 下载成功后写回新的 snapshot
6. 每轮都会基于最新 seed catalog 构建当前 pull plan,并检查输出目录是否已有当前 plan 的 manifest 条目或目标文件
7. 如果远端 snapshot 未变化但输出目录没有任何当前 plan 的本地资源,仍按首次运行处理并执行全量拉取
8. 远端无变化且本地已有资源时执行 download manifest audit,检查路径、size 和 BLAKE3
9. 远端变化、本地 audit 发现 repair_needed,或首次空目录运行时,下载并校验官方 URL。
10. 下载成功后写回新的 snapshot。
该入口不安装、不执行官方启动器,也不读取生产外的本地客户端目录。Rust 正式 binary 支持 `--watch` 常驻模式,正常情况下默认每 1 小时执行一次检查;远端和本地一致时静默等待下次检查,不一致时自动下载或 repair。下载、发现或校验失败时不等待完整正常周期,默认 60 秒后重试,可用 `--error-retry``--error-retry-seconds` 调整。单次运行仍保留为核心幂等路径,systemd service、容器或 Go 进程可以只负责守护该常驻进程;cron/systemd timer 调单次模式只是可选集成方式。项目是否热更新、热重载或重启进程,由上层业务集成决定。
该入口不安装、不执行官方启动器,也不读取生产外的本地客户端目录。Rust 正式 binary 支持 `--watch` 常驻模式,正常情况下默认每 1 小时执行一次检查;每天北京时间(UTC+8`03:00``16:00``18:00` 会中断普通 sleep 并强制执行一次自动刷新,该轮注入 `force=true`远端和本地一致时静默等待下次检查,不一致时自动下载或 repair。下载、发现或校验失败时不等待完整正常周期,默认 60 秒后重试;如果固定时间强制刷新失败,会保留 pending force 并按失败重试周期继续重试,可用 `--error-retry``--error-retry-seconds` 调整。单次运行仍保留为核心幂等路径,systemd service、容器或 Go 进程可以只负责守护该常驻进程;cron/systemd timer 调单次模式只是可选集成方式。项目是否热更新、热重载或重启进程,由上层业务集成决定。
对应实现主要在: