30 KiB
官方资源后端说明
本文档说明 BlueArchiveToolkit 中“官方资源后端”的职责、数据流和工作原理,供审核使用。
1. 范围
这个后端只处理 日服官方资源,只接受官方 .jp/.com 域名下的资源链路。
Release 布局、URL→磁盘映射、seed 模板与 bat-api 分发 path 的冻结契约见:
docs/architecture/resource-release-layout.md
明确排除:
bluearchive.cafe- 任何镜像层、转写层、二次代理层
- 人工拼接出来的样例 URL
- Linux 生产环境安装或执行官方启动器
- 把已安装客户端目录或官方启动器安装目录当作生产输入
本地 HTTP/SOCKS 代理只允许作为 curl 传输层配置使用,不改变资源来源判定。无论是否配置代理,下载器仍只接受官方 URL,并拒绝镜像、转写或非官方资源域名。
当前默认平台集合是:
WindowsAndroid
iOS 和 macOS 已从默认支持中移除。
2. 后端负责什么
| 层 | 任务 | 结果 |
|---|---|---|
| 发现层 | 读取官方 server-info,选择 connection group 和版本覆盖 |
得到官方资源根和种子端点 |
| 清单层 | 解析 BundlePackingInfo.bytes、TableCatalog.bytes、MediaCatalog.bytes |
得到完整文件清单 |
| 计划层 | 合并 discovery + inventory,去重并保序 | 得到全量 pull plan |
| 下载层 | 校验官方 URL,调用下载器,落盘并记录字节数 | 得到本地资源副本 |
| 导入层 | 可配置将已校验官方 release 写入 CAS 和 ResourceRepository | 得到可查询的资源索引 |
| 同步层 | 比较当前快照和历史快照 | 决定下载、校验、发布 |
| 更新层 | 保存上次官方 snapshot,定期执行 discovery + diff + pull | 形成自动更新闭环 |
3. 工作原理
3.0 Linux 生产约束
生产环境目标是 Linux 后端任务,不是 Windows 桌面客户端环境。
因此生产同步入口必须满足:
- 不要求安装官方启动器。
- 不要求启动官方启动器进程。
- 不要求把生产环境当作客户端安装目录。
- 可以显式执行 official metadata discovery 自动发现
server-infoURL、connection-group和app-version。 - 也可以通过配置、调度状态或已审计 metadata snapshot 显式提供这些值。
--auto-discover只允许通过官方 HTTP metadata 和临时目录解析GameMainConfig;launcher metadata 与 remote manifest 文件列表 digest 均未变时必须复用缓存,任一变化时才按 manifest 重新下载必要resources.assets或旧版官方 game zip。
3.1 发现官方资源根
入口是 YostarJpServerInfo。
流程是:
- 读取官方
server-infoJSON。 - 按
connection_group + app_version规则选择版本覆盖。 - 从
AddressablesCatalogUrlRoot提取root token。 - 校验该 root 只能落在官方
prod-clientpatch.bluearchiveyostar.com之下。 - 基于 root token 生成 discovery 端点。
对应实现主要在:
adapters/src/official/yostar_jp.rs
3.2 枚举完整资源清单
资源清单不是“猜几个文件”,而是从官方 catalog 字节里提取完整文件名或相对路径列表。
当前做法:
- 读取
BundlePackingInfo.bytes。 - 提取所有
FullPatch_*.zip包名。 - 读取
TableCatalog.bytes。 - 提取所有表资源名,例如
ExcelDB.db。 - 读取
MediaCatalog.bytes。 - 提取所有媒体下载相对路径,例如
GameData/Audio/VOC_JP/JP_Airi.zip、Prologue/Scenario/Event/10000_Title_Sound.ogg。
然后对 verified platforms 生成完整 URL 集:
- Windows patch pack
- Android patch pack
- TableBundles
- MediaResources-Windows
- MediaResources
对应实现主要在:
adapters/src/official/inventory.rsadapters/src/official/yostar_jp.rs
3.3 组装全量 pull plan
OfficialResourcePullPlan 是这个后端的关键对象。
它做三件事:
- 保存 discovery 端点。
- 保存完整 inventory。
- 用默认平台集或指定平台集生成最终 URL 列表。
all_urls() 是执行层的权威输入:
- 先放 discovery URLs
- 再放 content URLs
- 统一去重
- 保持顺序
这意味着后端拉取的是 完整资源包集合,不是抽样下载。
对应实现主要在:
infrastructure/src/official_pull.rs
3.4 执行下载
OfficialResourcePullService 负责真正下载。
工作方式:
- 检查 URL 是否属于官方 host。
- 把 URL 映射到当前工作根目录下的本地输出路径;在自动更新服务中,读侧根目录是
current指向的 versioned 目录,写侧根目录是 staging。 - 读取工作根目录下的
official-download-manifest.json。 - 已存在目标文件只有在本地清单中的相对路径、size、BLAKE3 都匹配时才跳过;
.zip文件还必须通过 ZIP central directory / local header 结构校验。 - 缺少清单、清单不匹配、ZIP 结构无效或文件损坏时重新下载。
TableCatalog.bytes、BundlePackingInfo.bytes、MediaCatalog.bytes总是刷新并用官方.hash强校验;该.hash是xxHash32(seed=0)的十进制文本。catalog_*.hash当前只作为 Addressables catalog 变更标记,不作为 zip/JSON 内容校验算法;Unity Addressables/SBP builder 对 JSON/bin catalog 使用HashingMethods.Calculate生成Hash128文本,运行时用它判断 remote catalog cache 是否过期,它不能套用 seed catalog 的xxHash32规则。- 官方 seed
.hash校验失败会让当前下载失败,并移除对应 data/hash URL 的本地 manifest 条目,避免失败产物在下一轮被本地 BLAKE3 audit 误判为健康缓存。 - 官方启动器/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状态按错误重试间隔继续探测。 - 存在
.part临时文件时通过curl --continue-at -尝试断点续传。 - 新下载写入
.part,成功并通过必要校验后原子 rename 到 staging 内最终路径;断点续传后的.zip如果结构无效,会删除.part并重新全量下载。 - 成功下载后更新本地下载清单。
- 上一轮失败或中断留下的 staging 只有在
official-version-state.json中存在同一 app version、bundle version 和 Addressables root 的失败记录,且<output>/.staging/<id>仍安全存在、versions/<id>尚未发布时才会复用;复用后仍按 manifest、BLAKE3、ZIP 结构和官方.hash逐 URL 校验,不信任散落文件。 - 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会在后台停止后清除。 - curl 失败按 HTTP/网络类型分类:403/404/普通 4xx 不重试,5xx、429、DNS、连接、超时、中断和网络类错误按尝试次数重试。
- 单个 URL 最终失败时写入
official-download-quarantine.json,发出 Failed progress,并阻止发布不完整资源。 - 旧 launcher 包或
resources.assets下载使用官方 launcher CDN 配置,primary CDN 失败后切换 official backup CDN;资源 patch host 不猜测非官方镜像。 - 记录最终文件大小、本次传输字节数、官方 hash 校验数和执行状态。
- 非官方 URL 直接拒绝。
- 下载调度默认并发数为
8,允许范围是1..=256,由--download-concurrency/BAT_DOWNLOAD_CONCURRENCY配置。worker 从共享 plan 队列逐项领取任务,单个任务完成后立即领取下一个,不等待其他 worker 的当前任务;完成结果在协调线程即时更新 manifest、hash 事件和进度计数。 最终OfficialResourcePullReport.items仍按OfficialResourcePullPlan顺序排列,避免并发完成顺序泄露到发布和 API 读侧。
路径映射时会做分段清理,并在写入前做输出目录安全校验、相对路径归属校验和现有路径组件 symlink 检查,避免把不安全路径写进输出目录或通过 symlink 跳出输出目录。
对应实现主要在:
infrastructure/src/official_download.rs
3.5 导入到 CAS 和资源仓储
官方同步下载、校验并发布 release 后,可以通过 --import-repository 或
config.toml / 环境变量 BAT_IMPORT_REPOSITORY=1 自动触发 CAS + ResourceRepository
导入:
- 读取已发布 release 下的
official-download-manifest.json。 - 逐条按 manifest 的相对路径、size 和 BLAKE3 重新校验本地文件。
- 把已校验字节写入 CAS;默认 CAS 根目录是
<output>/.cas,也可用--import-cas-root/BAT_IMPORT_CAS_ROOT覆盖。 - 将资源条目写入 SQLite
ResourceRepository;默认索引路径是<output>/resources.sqlite,也可用--import-resource-db/BAT_IMPORT_RESOURCE_DB覆盖。 - AssetBundle、TextAsset、TableBundle、Media、Manifest/Other 会按资源类型分类;资源 metadata 会通过
metadata_json保存 release、平台、bundle path、parse status、TextAsset 名称和 TextUnit 数量/格式。 - 当前 release 的单条 TextUnit 明细和解析错误会写入
official-textunit-index.json,可通过parse.text_units/parse.errorsRPC 和parse-text-units/parse-errorsCLI 只读查询。
这层的意义是把“下载到磁盘的文件”变成“可查询、可复用、可去重”的资源对象。
resource.index RPC / CLI 只读查询现有 SQLite 索引;索引不存在时返回
available=false,不会因为查询创建空库。发布后的 TextUnit 队列还会在当前
release 根目录写入 translation-tasks.sqlite,由版本化 schema_migrations
管理 queued/running/failed/completed/skipped、provider run、lease、失败分类、
重试计划和 TextUnit 级译文结果。跨 release 的 Translation Memory V1 独立存储在
<output>/translation-memory.sqlite,记录 raw source/hash、完整 context、candidate/
trusted 和 release/TextUnit/provider/run provenance;translation.tasks 优先查询这份状态库,
translation.worker.run 由 Rust worker 回写状态;translation.task.update 仍供外部 provider 流程回写状态;
没有状态库的旧 release 才回退到 immutable JSON 队列。bat doctor cas
已提供只读 CAS 根目录、对象目录、元数据库文件和对象统计诊断;resource.index
已把 release、平台、bundle path 和常用数组 metadata 过滤下推到 SQLite。G-011
剩余工作是更丰富的 TextUnit/TM 查询和通用 Patch 发布所需资源视图。
对应实现主要在:
infrastructure/src/import.rsinfrastructure/src/resources.rs
3.6 同步决策
同步层只做判断,不做重业务。
它比较当前快照和历史快照,关注:
- root token 是否变化
- addressables root 是否变化
- endpoint 是否变化
- bundle version 是否变化
判断结果分三类:
UpToDateDownloadAndVerifyDownloadVerifyAndPublish
对应实现主要在:
infrastructure/src/official_sync.rs
3.7 自动更新闭环
OfficialUpdateService 是当前 Rust 侧的自动更新核心,正式命令入口是 bat。
集成边界:
- 当前生产集成路径是 Rust
bat --watch/bat --daemon持久运行;Gobat-api通过internal/backendrpc调用 daemon RPC,读取已发布 release 和状态,不运行 另一套同步器。bat --json只表示 Rust CLI 的机器输出形态。 - systemd、容器或上层 Go 进程只负责守护
bat --watch/bat --daemon,不直接接管下载器内部状态。 bat-ffi只允许作为可选无状态 C ABI 兼容层,用于 Manifest inspect 和 sync plan 这类一次性 JSON helper;它不是官方同步 daemon、下载器、资源锁、CAS handle 或主控制面的承载位置。
流程是:
- 显式执行
--auto-discover或读取已审计server-info输入。 --auto-discover先抓官方 launcher metadata、launcher CDN config 和 remote manifest;metadata 与 remote manifest 文件列表 digest 均未变时复用official-bootstrap-cache.json中的GameMainConfig摘要,任一变化时按 manifest 临时下载resources.assets或旧版官方 game zip 并重新解析。- 生成当前 v2 snapshot,记录
app_version、connection_group、bundle_version、addressables_root、endpoint URL、seed.hash内容、catalog_*.hashmarker、launcher metadata 摘要、remote manifest 文件列表 digest 和GameMainConfig摘要。 - 读取上一次成功同步写出的 snapshot。
- 使用
OfficialSyncPlan和扩展 snapshot diff 判断是否需要下载;URL 未变但.hash/ marker 内容变化也会触发更新。 - 每轮都会基于最新 seed catalog 构建当前 pull plan,并检查输出目录是否已有当前 plan 的 manifest 条目或目标文件。
- 如果远端 snapshot 未变化但输出目录没有任何当前 plan 的本地资源,仍按首次运行处理并执行全量拉取。
- 远端无变化且本地已有资源时执行 download manifest audit,检查路径、size、BLAKE3 和 ZIP 结构。
- 远端变化、本地 audit 发现 repair_needed,首次空目录运行,或缺少
current原子发布指针时,进入下载/发布流程。 - 下载先写入
<output>/.staging/<id>;若已有 active release,会先 seed staging 以复用已验证文件;若 version-state 中存在同一版本的失败 staging,则优先复用该 staging 并跳过 active seed,避免旧 active 覆盖已下载的新文件。新 staging 还会扫描已发布 release 的下载 manifest,按规范化 destination 查找候选并重新验证 size、BLAKE3 和 ZIP 结构;硬链接失败时回退到临时文件复制和原子 rename,历史 release 保持不可变。 - 下载、manifest、本地 BLAKE3、ZIP 和官方
.hash校验完成后写入新的 snapshot,并在 staging 中写入official-launcher-bootstrap.json(若本轮启用--auto-discover)。 - 将 staging rename 为
<output>/versions/<id>,再原子替换<output>/currentsymlink 指向该 versioned 目录。 - 发布完成后先对比上一完整 release 和当前 release 的
official-download-manifest.json,写出official-resource-changes.json和crowdin-translation-handoff.json。同一 destination 只有 size 或 BLAKE3 变化才算 modified;新增+变更资源进入解析/翻译 handoff,删除资源只进入差异记录。当前只预留 Crowdin 本地 handoff,不发外部 API 请求。 - 随后刷新 active release 下的
official-parse-cache.json和official-textunit-index.json,并从 Added/Modified 资源、parse cache 与 TextUnit 明细索引派生official-textunit-tasks.json、crowdin-textunit-queue.json和版本化的translation-tasks.sqlite;up-to-date 轮询在已有有效解析缓存、TextUnit 明细索引和 TextUnit 队列时只读取摘要,不重复解析,重新同步队列时保留已有 worker 状态。 - 若启用
--import-repository,已校验 release 会被导入 CAS +ResourceRepository,并可经resource.index查询。历史 release 候选失效时,已有 CAS 对象会先经过完整性和元数据校验,再增加 release 引用并原子物化;当前 release 在official-cas-reuse-references.json中记录引用,staging/release 清理时递减,失败则回退网络并保留诊断。 - 官方同步报告默认给出
localized_release_status=not_localized,表示原版资源已发布、汉化资源未发布;UnityFS TextAsset patch 发布成功并通过localized-patch-manifest.json、current symlink 和 release ID 校验后,localized.status才返回localized,表示原版和汉化两套资源都已发布。translation.proofread只会把 workflow 标记成manual_proofreading/translation.manual_proofreading,不会回退已发布汉化 release 的发布状态。
维护期特殊分支:如果官方 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、restart、logs、reload、默认形态的 refresh 和默认形态的 repair 优先走 RPC;reload 会唤醒或排队 watch 循环重新自动发现并强制刷新,默认 repair 会通过 resource.repair 入队本地 manifest 审计+修复任务,live RPC restart 会启动 Rust lifecycle controller 并复用 CLI 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 调单次模式只是可选集成方式。项目是否热更新、热重载或重启进程,由上层业务集成决定。
对应实现主要在:
infrastructure/src/official_update.rsinfrastructure/src/bin/bat_official_sync.rs(薄入口)infrastructure/src/bin/bat/app.rs(控制面组合)infrastructure/src/bin/bat/report_output.rs、terminal_output.rs(前台报告和终端输出)infrastructure/src/bin/bat/task_registry.rs(任务注册表、持久化和 worker)infrastructure/src/bin/bat/readonly_query.rs、translation_query.rs(只读查询)infrastructure/src/bin/bat/patch_commands.rs(patch 命令)infrastructure/examples/official_update_check.rs(历史/开发入口)
4. 官方 bootstrap 与用户流程
当前已经提供的官方用户流程分两类。
Linux 生产路径:
- 显式执行
--auto-discover,或提供已审计的官方 metadata snapshot。 official_pull_plan依据官方server-info、catalog 和 verified platforms 生成全量拉取计划。bat对比上次 snapshot 和远端.hashmarker;远端无变化时 audit 本地清单,有变化或本地损坏时下载、校验并落盘官方资源。
开发/审计辅助路径:
official_launcher_bootstrap获取官方 launcher 信息。official_game_main_config按官方 manifest 获取resources.assets(旧 ZIP manifest 则先解出)并解密GameMainConfig。- 手动确认最新 PC metadata、
server-infoURL 和默认 connection group。
自动发现路径和开发/审计辅助路径都只使用官方 HTTP 和临时目录,不安装或启动官方 launcher。
这些入口都只接受官方域名,不走 bluearchive.cafe 镜像链。
5. 已验证行为
当前代码已经验证:
- 默认平台是
Windows + Android iOS和macOS不再进入默认官方流程- verified inventory 会产出完整内容 URL 集
- pull plan 会同时包含 discovery URLs 和 content URLs
- 全量样本下是
2个 discovery URL +5个内容 URL =7个 URL OfficialUpdateService能持久化 v2 snapshot,并在远端 marker 内容变化时触发下载决策bat默认向 stderr 输出BlueArchiveToolkitASCII banner 和 progress log,stdout 默认输出人类可读摘要;progress log 覆盖代理决策、下载已完成计数、单文件开始/完成状态、下载中断失败分类和校验结果摘要;支持--proxy/--no-proxy控制 curl 传输代理,支持--json输出稳定 JSON,支持--no-progress关闭进度日志,支持--no-banner只关闭横幅,支持--watch --interval 1h --error-retry 60s常驻运行,支持--daemonUnix socket JSON-RPC live control/backend(daemon.status/logs/stop/restart/reload/refresh/doctor、resource.sync/verify/repair/state/manifest/list/index、parse.status/text_units/errors、translation.tasks/handoff/task.update、localized.status、catalog.*、task.*、文件级patch.apply/unityfs.patch_*);restart通过 Rust lifecycle controller 复用 CLI 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索引、metadata_jsonrelease/平台/bundle/TextAsset/TextUnit 摘要,以及 TextAsset/Table/Media 分类;resource.index可只读查询现有索引,常用 metadata 过滤已下推到 SQLite,bat doctor cas可只读诊断既有 CAS 目录和对象统计 - 官方 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/repairCLI 行为- 下载层能在本地文件 size/BLAKE3/path、ZIP 结构或 manifest 不匹配时重新下载
- 官方 seed
.hashmismatch 会导致下载失败,而不是降级为本地 BLAKE3 猜测 - 非官方 URL 会在 fetch/download 入口被拒绝
- 真实官方网络全量下载 smoke 已固化为
scripts/official-full-pull-smoke.sh、make official-smoke和docs/guides/official-full-pull-smoke.md;大型资源文件和运行报告默认保留在/tmp隔离目录,不纳入 Git
相关验证主要来自:
cargo test -p bat-adapters -- --nocapturecargo test -p bat-ffi -- --nocapturecargo test -p bat-infrastructure -- --nocapturecargo test -p bat-infrastructure --bin bat -- --nocapturecargo run -p bat-infrastructure --bin bat -- --help
6. 审核重点
请重点检查这几件事:
- 是否只接受官方 host。
- 是否默认只走 Windows + Android。
- 是否把完整 content URL 集都纳入
all_urls()。 - 是否拒绝镜像域名和手工拼接样例。
- 是否在下载前做了 URL 和路径安全校验。
- 是否能在官方客户端变动时只改适配层。
7. RPC Backend API 与 Go 调用边界
daemon(bat --daemon)在 <state-dir>/bat.sock 上提供 Unix socket
JSON-RPC 2.0 服务,是面向上层服务(Go 层)的主要跨语言边界。
稳定方法、schema 和错误语义以 docs/reference/rpc-backend-api.md 为准。
7.1 协议契约
- 应用层统一 envelope(装入 JSON-RPC
result):ok/status/data/error/request_id;传输层解析失败走 JSON-RPC 顶层error(-32700)。 error为统一ApiError:code(BAT-ERR-<6 位>)、kind、domain、location、message、retryable。码表以core/src/error_code.rs为准。- 长任务(
resource.sync/resource.verify/resource.repair/catalog.refresh) 入队即返回task_id,经task.status/task.list/task.logs轮询,task.cancel协作式取消。任务执行器是单 worker FIFO,与 watch 循环经进程内锁互斥。任务历史持久化于<state-dir>/bat-tasks.json(版本化、0600原子写,生命周期转换时落盘),daemon 重启后历史任务 仍可经task.*查询,中断任务标记task_interrupted(700005)。 - 方法命名空间与实现状态、请求/响应示例见
docs/reference/rpc-backend-api.md:daemon.status/logs/stop/restart/reload/refresh/doctor、resource.state/sync/verify/repair/manifest/list/index、parse.status/text_units/errors、translation.tasks/handoff/task.update/proofread、localized.status、catalog.*与task.status/list/cancel/logs已实现;文件级patch.apply/unityfs.patch_*已实现,发布级 patch 与复杂 UnityFS 语义编辑待引擎;task.create按设计暂不开放通用任务入口;daemon.restart通过 Rust lifecycle controller 复用 CLI restart 路径;daemon.clean-stable仍由 CLI 侧按进程生命周期显式执行。
7.2 Go 层职责边界
- Rust
bat/ daemon 是资源生产者和状态拥有者;Gobat-api是资源读侧、 bootstrap 和 HTTP 分发入口。二者之间的稳定边界是bat.sockRPC 和resource_root中已发布的只读文件。 - Go 层负责:资源 bootstrap、资源内容分发(
cmd/bat-api)、HTTP API 进程配置、 以及通过internal/backendrpc作为 RPC client 调用本机 daemon(连接bat.sock,每行一个 JSON-RPC 请求/响应)。cmd/bat仍是试验骨架,不是产品级用户 CLI。 bat-api(资源分发):- 提供
/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 和 RPC 刷新周期,并预留 database/redis 键供后续 API 持久化;不负责资源自动拉取。 - 可选改写 server-info 中的
AddressablesCatalogUrlRoot指向自身;不伪装 完整游戏业务 API。启动前资源 metadata 兼容属于资源 bootstrap;账号、登录、 Gateway、游戏业务ApiUrl和鉴权全链非本服务关闭条件。
- 提供
- Rust
bat/ daemon 负责:官方资源自动发现与拉取、校验、catalog 更新检查、 版本状态与发布、任务队列/日志/错误/进度管理等长期状态型工作。 - Go 层不直接嵌入 Rust FFI,不直接读写 daemon 的状态文件;跨语言控制面
只经 RPC 契约。生产文件字节从 RPC 给出的
resource_root读取,bat-api与 daemon 同服务器、同容器或同一共享文件系统部署;显式--resource-root只用于 fixture、本地开发或 RPC 不可用时的应急只读诊断。
7.3 FFI 的定位(降级说明)
bat-ffi crate(cgo 头文件 + 静态/动态库链接,见 Makefile 的
build-ffi / build-go)降级为可选的历史兼容边界:保留用于既有
cgo 试验路径与本地工具,不再作为 Go 服务层的主要集成方式,也不会按
RPC 契约的节奏扩展。新能力一律先落 RPC 方法。