Files
BlueArchiveToolkit/docs/guides/official-resource-test-pull.md
T
nyaKazuha 5bae90cb14
bat-rust / Build and test Rust (push) Canceled after 0s
bat-rust / Build and test Go API (push) Canceled after 0s
fix(release): 完成分发身份与 CAS legacy ownership 收尾
2026-09-13 10:44:24 +08:00

29 KiB
Raw Blame History

官方资源拉取用户指南

本文档描述当前可用的官方日服资源拉取流程。

默认平台:

  • Windows
  • Android

不包含:

  • iOS
  • macOS
  • bluearchive.cafe 或其他镜像域名
  • 任何本地客户端目录
  • 任何已安装的官方启动器或 Windows 客户端

0. 快速入口

查看命令参数:

cargo run -p bat-infrastructure --bin bat -- --help

构建生产 binary

cargo build --release -p bat-infrastructure --bin bat

使用 release binary 做一次 dry-run

target/release/bat \
  --auto-discover \
  --dry-run

常驻自动更新:

target/release/bat \
  --auto-discover \
  --watch

默认官方原版资源输出目录是 ./bat-resources,默认汉化产物目录是 ./bat-localized,默认后台状态目录是 /tmp/bat-pid。官方资源输出目录是发布根目录:非 dry-run 同步先写 <output>/.staging/<id>,校验完成后移动到 <output>/versions/<id>,再原子切换 <output>/current symlink;生产读取方应读取 current。后台状态目录会保存 bat.sockbat.pidbat-status.jsonbat-daemon.logbat-events.jsonl 和短生命周期的 bat-control.lock;其中 bat.sock 是 live daemon 的 Unix socket JSON-RPC 控制通道,bat-events.jsonl 是带轮转的结构化 JSONL 事件日志,bat-status.json 保存最后成功时间、下次检查时间、最后错误摘要和当前下载进度,bat-control.lock 串行化 status/stop/restart/reload/logs/refresh/repair 等控制命令。生产官方资源目录和汉化产物目录都必须是独立目录;需要覆盖官方目录时用 --output <资源目录>,需要覆盖汉化目录时用 --localized-output <目录>BAT_LOCALIZED_OUTPUT,不要使用已有游戏客户端目录、官方启动器安装目录、人工维护资源目录,或开发机上的 /home/wanye/D/BlueArchive

同步流程会拒绝危险输出目录、路径逃逸和现有 symlink 路径组件;下载目标、.part、manifest、snapshot、PID、status、log 和控制锁文件不会跟随 symlink,daemon 状态类文件默认以 0600 权限创建。

0.1 本地代理

bat 默认会自动读取当前进程环境中的 curl 代理变量:HTTPS_PROXYhttps_proxyALL_PROXYall_proxyHTTP_PROXYhttp_proxy,并保留 NO_PROXY / no_proxy。同步开始时会输出一条 proxy 进度日志;bat doctor 也会显示当前代理解析结果。

推荐:带凭据的代理优先用环境变量。 如果代理 URL 里含有用户名/密码,优先通过标准代理环境变量配置,而不是命令行参数:

HTTPS_PROXY=http://user:pass@127.0.0.1:7890 target/release/bat --auto-discover

生产环境用 systemd 时,把该变量写进 EnvironmentFile=(建议 0600),凭据就不会进入 shell 历史、ps、进程 argv 或任何状态文件。这是配置带凭据代理最简单也最安全的方式。

也可以用 --proxy 参数手动指定(无凭据的本地代理用这个最方便):

target/release/bat \
  --auto-discover \
  --proxy http://127.0.0.1:7890

明确关闭代理并直连:

target/release/bat \
  --auto-discover \
  --no-proxy

确认当前代理配置:

target/release/bat doctor --proxy http://127.0.0.1:7890

--proxy auto 会恢复默认环境变量自动检测;--proxy none--proxy direct--proxy off--proxy disabled 等价于 --no-proxy

凭据处理:无论用环境变量还是 --proxy 参数,代理凭据都不会以明文出现在世界可读的位置——日志和 status 输出中会脱敏;传给 curl 子进程时经 ALL_PROXY 环境变量而非 --proxy 参数,因此不落 curl 的 /proc/<pid>/cmdline--daemon 模式下代理凭据经环境变量下传后台子进程,不进入子进程 argv 或 bat-status.json,复用所需的凭据单独存于后台状态目录下的 bat-proxy.secret0600),clean-stable 会在后台停止后清除它。后续 restart / reload 会复用同一代理配置;若该凭据文件已被清除,复用型 restart 会明确报错要求重新传入代理。

代理只影响 curl 传输层,资源 URL 仍必须是官方域名;不要把代理配置成镜像、转写或非官方资源来源。

1. 当前流程

Linux 生产运行时链路只走官方日服 HTTP 资源,不安装、不启动、不依赖官方启动器二进制:

  1. 显式执行 --auto-discover,通过官方 HTTP metadata 自动发现 app-versionserver-info URL 和默认 connection-group
  2. 请求官方 server-info
  3. 生成 Windows + Android 的官方资源 discovery 端点。
  4. 拉取 seed catalog,生成完整官方 pull plan。
  5. dry-run 只输出 URL;非 dry-run 下载全部官方 URL 到 staging,验收完成后原子发布到 current,并在 release 中写入 official-launcher-bootstrap.json

--auto-discover 会下载官方 metadata,记录 launcher API 返回的 game config、CDN config、remote manifest 文件列表和选中的 resources.assets 来源,并按官方 manifest 临时获取 resources.assets 解析 GameMainConfig;旧 ZIP manifest 才会下载临时 game zip。该流程不会安装官方启动器,也不会执行官方启动器进程。--launcher-bootstrap 只是旧命名兼容别名,新流程不要再推荐使用。

2. 可选 metadata 审计

如需单独审计官方 metadata API 和官方 ZIP 链路,可以手动运行:

cargo run -p bat-infrastructure --example official_launcher_bootstrap -- \
  --launcher-version 1.7.2 \
  --manifest

这一步会输出:

  • game_latest_version
  • game_latest_file_path
  • primary_cdn
  • backup_cdn
  • manifest_url
  • manifest_source
  • manifest_file_count

所有 URL 都应来自官方域名。

3. 先做 dry-run

推荐开发和生产自动化的默认流程是显式打开 --auto-discover

cargo run -p bat-infrastructure --example official_pull_plan -- \
  --auto-discover \
  --output /tmp/bat-official-pull \
  --dry-run

如果你要复现某次已审计的 metadata snapshot,也可以显式传入官方 server-info 文件名:

cargo run -p bat-infrastructure --example official_pull_plan -- \
  --server-info-file r93_70_xxxxxxxxxxxxxxxxxxxx.json \
  --connection-group Prod-Audit \
  --app-version 1.70.0 \
  --output /tmp/bat-official-pull \
  --dry-run

如果你已经把官方 server-info JSON 存成只读本地文件,也可以使用:

cargo run -p bat-infrastructure --example official_pull_plan -- \
  --server-info-path /path/to/server-info.json \
  --connection-group Prod-Audit \
  --app-version 1.70.0 \
  --output /tmp/bat-official-pull \
  --dry-run

检查输出时,重点看:

  • platforms=[Windows, Android]
  • discovery_url_count 大于 0
  • content_url_count 大于 0
  • 不出现 bluearchive.cafe

4. 执行真实拉取

确认 dry-run 正常后,去掉 --dry-run

cargo run -p bat-infrastructure --example official_pull_plan -- \
  --auto-discover \
  --output /tmp/bat-official-pull

程序会:

  • 只接受官方 URL
  • 下载完整官方资源集合
  • 下载成功后在 release 目录维护 official-download-manifest.json
  • 已存在目标文件只有在本地下载清单中的 size 和 BLAKE3 校验通过时才会跳过;.zip 文件还必须通过 ZIP central directory / local header 结构校验
  • TableCatalog.bytesBundlePackingInfo.bytesMediaCatalog.bytes 会用官方 .hash 做强校验;该 .hashxxHash32(seed=0) 的十进制文本
  • catalog_*.hash 是 Unity Addressables/SBP 写出的 catalog 变更标记,来源是 HashingMethods.Calculate(json/bin catalog) 生成的 Hash128 文本;它不是 seed catalog 的 xxHash32 规则,目前不作为 zip/JSON 内容强校验
  • 存在 .part 临时文件时会尝试断点续传
  • 新下载先写 .part,成功并通过必要校验后再替换为最终文件;如果断点续传后的 .zip 结构校验失败,会删除 .part 并重新全量下载
  • 如果上一轮非 dry-run 已进入 staging 但未发布成功,下一轮会优先查找 <output>/official-version-state.json 中同一 app version、bundle version 和 Addressables root 的失败版本;只有对应 <output>/.staging/<id> 仍存在、路径安全且 versions/<id> 尚未发布时,才复用该 staging,并继续按 manifest 校验复用或重下单个 URL
  • 新 release 的 staging 在访问网络前会扫描已发布 release 的 official-download-manifest.json。候选必须同时满足 manifest 记录的 destination、size、BLAKE3 和适用的 ZIP 结构校验;URL、CDN 根和 release ID 的变化本身不会阻止复用。命中后优先用硬链接,跨文件系统时回退为临时文件复制并原子 rename,旧 release 不会被修改
  • 历史 release 候选失效时,如果配置的 CAS 根已有对应 BLAKE3 对象,会先通过 CAS 读取完整性和元数据,再增加当前 release 的引用并原子物化;当前 release 会写带持久化 ownership_idofficial-cas-reuse-references.json,清理孤儿 staging 或显式清理 release 时按 ownership 和 ordinal 递减这些引用;旧无 identity 清单保留 legacy cleanup key。CAS 损坏、缺对象或元数据不一致会写入复用诊断并继续走网络下载,不会静默使用缓存
  • 把结果发布到 --output/current

5. 自动更新检查

正式自动更新入口是 bat。它会保存上一次成功同步的 snapshot,下次运行时先自动发现当前官方 metadata,再和 snapshot 对比:

  • 每轮都会先拉取轻量官方 metadata 和 .hash marker。
  • URL 没变但 .hash / marker 内容变更时,也会判定为需要更新。
  • 即使远端 snapshot 未变化,只要 active release 没有任何当前 pull plan 的本地 manifest 条目或目标文件,也会按首次运行处理并执行全量拉取。
  • 远端无变化时,默认执行 active release 中的 official-download-manifest.json audit。
  • 本地文件缺失、路径不一致、size 不一致、BLAKE3 不一致或 ZIP 结构无效时,默认进入 repair 并重下必要文件。
  • 官方 seed .hash 校验失败会让本轮失败,并清理对应本地 manifest 条目;下一轮会继续把这类文件视为需要 repair,而不是把失败产物当作健康缓存复用。
  • curl 默认自动检测本地代理环境;也可以用 --proxy <URL> 显式指定代理,或用 --no-proxy 强制直连。代理决策会进入 progress log、daemon log 和 doctor 诊断输出。
  • curl 失败会按类型分类:403/404/普通 4xx 不重试,5xx、429、DNS、连接、超时、中断和网络类错误按尝试次数重试。
  • 官方维护或大版本发布窗口可能出现启动器/server-info 已经给出新版本和新 AddressablesCatalogUrlRoot,但 client-patch CDN 的 seed marker 或必需 seed catalog 尚未开放的状态。此时单次运行会输出 update_status=waiting_for_official_resourceswaiting_for_official_resources=trueunavailable_endpoints;不会进入 staging、不会写入 failed_versions、不会切换 current。watch/daemon 会把状态置为 waiting,按 --error-retry / BAT_ERROR_RETRY_SECONDS(默认 60 秒)继续探测。
  • 单个 URL 最终失败后会写入 official-download-quarantine.jsonprogress log、daemon status 和 bat-events.jsonl 会记录失败类型、HTTP 状态、是否可重试、尝试次数和 quarantine 状态。
  • quarantine 项会跳过本轮发布并让同步失败,避免把不完整 staging 发布到 current;下一轮 repair/refresh 成功后会清理对应 quarantine 条目。
  • 失败或中断后的 staging 不会无条件丢弃:如果 version-state 记录的失败版本和本轮远端元数据匹配,且 staging 目录仍安全存在,下一轮会复用该 staging;已通过 manifest 校验的文件会跳过,缺失、损坏、无 manifest 或官方 seed .hash 需要刷新的 URL 会重新下载。
  • 旧 launcher 包或 resources.assets 下载路径使用官方 launcher CDN 配置,primary CDN 失败后会切换官方 backup CDN;资源 patch host 当前只使用 server-info 返回的官方 client-patch host,不猜测非官方镜像。
  • 远端和本地都一致:单次模式输出 update_status=up_to_date,watch 模式默认静默并等待下次检查。
  • 远端 metadata 已更新但资源端尚未开放:单次模式输出 update_status=waiting_for_official_resourceswatch/daemon 模式保留现有资源并短间隔重试。
  • 有远端变化或本地 repair:生成 pull plan,下载完整官方资源到 staging,成功后更新 snapshot 并原子发布到 current
  • 非 dry-run 会维护 <output>/official-version-state.json:开始下载后写入 in_progress_version,发布成功后写入 current_completed_versionprevious_available_version,失败或中断后写入 failed_versions。同一 app version、bundle version 和 Addressables root 的失败只保留最新一条;同一版本开始重新拉取或后续发布成功时会清理对应失败记录。重新拉取同一失败版本时会复用安全存在的失败 staging,不会因为 publish_id 变化从空目录重新开始。
  • --dry-run:只报告本次是否会下载,不写 snapshot;如果 cache miss,也不会写入新的 bootstrap cache。
  • --dry-run --plan:除更新判断外,还会解析 seed catalog 并打印完整下载 URL。
  • 真实更新会输出 downloaded_countresumed_countskipped_counttransferred_bytesofficial_seed_hash_verified_count
  • 复用统计还包括 release_reused_countcas_reused_countreused_bytesreuse_warnings;单文件 progress 状态区分 release_reusedcas_reuseddownloadedtransferred_bytes 不包含复用文件。
  • 校验报告分层输出 official_seed_hash_verified_countlocal_manifest_verified_countaddressables_marker_checked_countunverified_marker_count
  • 下载阶段复用同一套本地清单、ZIP 结构校验和 .part 续传逻辑;没有清单或校验不匹配的文件会重新下载。
  • 非 dry-run 且启用 --auto-discover 时,成功发布的 release 会包含 official-launcher-bootstrap.jsonup-to-date 轮询发现当前 release 缺少该文件时会补写。官方 launcher/server-info 已更新但 client-patch 资源尚未开放时,不切换 current,只在输出根写入 official-launcher-bootstrap.pending.json 作为维护期证据。
  • 校验和发布完成后会先对比上一完整 release 与当前 release 的 official-download-manifest.json,写出 <output>/current/official-resource-changes.json<output>/current/crowdin-translation-handoff.json。同一 destination 只有 size 或 BLAKE3 改变才算 modified;仅 URL/CDN 根变化但内容一致不会触发解析/翻译候选。新增+变更资源进入解析和 Crowdin 翻译 handoff,删除资源只进入差异记录;当前不会直接调用 Crowdin API。
  • 随后会刷新 <output>/current/official-parse-cache.json。解析缓存从 official-download-manifest.json 的全部条目出发,处理直接 UnityFS bundle 和 zip 内 UnityFS 条目;catalog、hash、媒体等非 UnityFS 文件记录为不支持,不视为同步失败。新 release 会刷新解析缓存;远端和本地都 up-to-date 且已有有效解析缓存时只读取摘要,不重复解析。
  • 需要将已校验官方 release 导入 CAS + SQLite ResourceRepository 时,使用 --import-repositoryconfig.toml / 环境变量 BAT_IMPORT_REPOSITORY=1;默认 CAS 为 <output>/.cas,默认索引为 <output>/resources.sqlite,可用 --import-cas-root / BAT_IMPORT_CAS_ROOT--import-resource-db / BAT_IMPORT_RESOURCE_DB 覆盖。resource.index RPC 可查询现有索引,索引不存在时返回 available=false,不会创建空库;bat doctor cas --output <output>bat doctor cas --import-cas-root <path> 可只读检查既有 CAS 根目录、对象目录、元数据库文件和对象统计。
  • 官方同步报告中的 localized_release_status=not_localized 表示原版资源已发布、汉化资源未发布,这是当前官方同步阶段的正常完成状态;后续 Patch 发布完成后才应切换为 localized,表示原版和汉化两套资源都已发布。

资源同步状态文件默认分布如下:

  • <output>/current/official-sync-snapshot.json:上一次成功同步的 v2 snapshot,包含 app version、connection group、bundle version、addressables root、endpoint URL、官方 seed .hash 内容、Addressables catalog_*.hash marker、launcher metadata 摘要和 GameMainConfig 摘要;launcher metadata 额外包含 remote manifest 文件列表 digest,用于发现同文件数但内容变化的 launcher manifest。
  • <output>/current/official-launcher-bootstrap.json:随已发布 release versioned 保存的官方 launcher bootstrap 产物,包含 launcher metadata、launcher CDN config、remote manifest 文件列表、选中的 resources.assets 来源、GameMainConfig 摘要和当前资源上下文。
  • <output>/official-launcher-bootstrap.pending.json:官方 launcher/server-info 已前进但 client-patch seed marker 或必需 seed catalog 尚未开放时写入的待处理 bootstrap 证据;它不代表资源已发布,也不会改变 current
  • <output>/official-bootstrap-cache.json--auto-discoverGameMainConfig 解析缓存。launcher metadata 与 remote manifest 文件列表 digest 都未变时复用缓存;任一变化时才通过官方 HTTP 按 manifest 下载必要 resources.assets 或旧版 game zip 到临时目录解析。
  • <output>/official-version-state.json:资源发布根目录的持久版本状态,包含当前已完成版本、正在拉取版本、上一个可用版本和失败版本。
  • <output>/current/official-download-manifest.json:本地下载强校验清单,记录 URL、相对路径、size、BLAKE3、deterministic distribution mapping identity 和 destination index。
  • <output>/current/official-cas-reuse-references.json:当前 release 获取的 CAS 引用清单,首次创建时包含持久化 ownership_id;每个复用项占一条记录,release 清理或孤儿 staging GC 时据此按 ownership/ordinal 递减引用。旧无 identity 清单使用 output-root 的 .cas-owner-scope 完成 generation-aware legacy cleanup;该文件不会被复制到新 release。
  • <output>/current/official-resource-changes.json:当前 release 相对上一完整 release 的资源差异,记录新增、变更、删除以及解析/翻译候选计数。
  • <output>/current/crowdin-translation-handoff.json:为后续 Crowdin worker 预留的本地队列,只包含新增+变更资源;它不是 Crowdin API 调用结果。
  • <output>/current/official-parse-cache.json:官方资源发布后的派生解析缓存,记录 bundle/zip 条目解析摘要和缓存复用情况;它不是汉化产物。
  • <output>/current/official-download-quarantine.json 或当前 staging 下同名文件:下载最终失败的 URL 诊断记录,包含失败类型、HTTP 状态、是否可重试、尝试次数和最后错误。

先 dry-run

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover \
  --dry-run

如果需要在 dry-run 阶段审阅完整下载 URL,加 --plan

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover \
  --dry-run \
  --plan

确认后执行真实更新:

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover

Rust 常驻更新模式默认每 1 小时执行一次检查,符合则静默,不符合则自动拉取/repair 并输出人类可读摘要;需要稳定 JSON report 时加 --json

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover \
  --watch

后台自动运行使用 --daemon。它会启动一个脱离终端的 watch 子进程,官方原版资源默认写入 ./bat-resources,汉化产物默认写入 ./bat-localized,后台控制和状态默认写入 /tmp/bat-pid

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover \
  --daemon

cargo run -p bat-infrastructure --bin bat -- status
cargo run -p bat-infrastructure --bin bat -- logs
cargo run -p bat-infrastructure --bin bat -- restart
cargo run -p bat-infrastructure --bin bat -- reload
cargo run -p bat-infrastructure --bin bat -- stop

statusstoprestartlogsreload、默认形态的 refresh 和默认形态的 repair 会优先连接 bat.sock,通过 Unix socket JSON-RPC 和 live daemon 通信;socket 不可用时,statusstop 会回退到 PID/状态文件兼容路径。status 会显示最后成功时间、下次检查时间、最后错误摘要、当前阶段、当前下载 URL 进度、版本状态摘要、最近历史失败版本和原因、文本日志路径、结构化日志路径和轮转日志路径;正在重新拉取同一版本时,对应旧失败不会作为当前历史失败摘要展示;人类输出不会把完整 official-version-state.json 内联打印成 JSON。控制命令会通过 bat-control.lock 做跨进程互斥,失效或损坏的控制锁会在下次控制命令或 clean-stable 时恢复。restart 会通过 Rust lifecycle controller 复用 CLI restart 路径停止旧后台进程并按保存参数或显式参数重新启动;reload 在未显式传入同步参数时不会重启进程,而是唤醒或排队 watch 循环重新执行自动发现和强制刷新:空闲睡眠时立即执行,正在同步时等当前轮结束;如果显式传入 --proxy--no-proxy,会按新代理配置重启后台进程。所有命令默认输出人类可读摘要,脚本集成时加 --json

如果要把后台状态目录改到其他位置,使用 --state-dir <目录>

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover \
  --daemon \
  --state-dir /tmp/bat-prod-pid

cargo run -p bat-infrastructure --bin bat -- status --state-dir /tmp/bat-prod-pid
cargo run -p bat-infrastructure --bin bat -- logs --state-dir /tmp/bat-prod-pid --tail 200
cargo run -p bat-infrastructure --bin bat -- stop --state-dir /tmp/bat-prod-pid

常用手动维护命令:

cargo run -p bat-infrastructure --bin bat -- refresh
cargo run -p bat-infrastructure --bin bat -- refresh --force
cargo run -p bat-infrastructure --bin bat -- verify
cargo run -p bat-infrastructure --bin bat -- repair
cargo run -p bat-infrastructure --bin bat -- doctor
cargo run -p bat-infrastructure --bin bat -- clean-stable
  • refresh 执行一次同步检查;refresh --force 强制刷新并重新匹配当前官方资源。
  • 如果后台 daemon 正在运行,并且 refresh 没有显式指定另一套资源目录、server-info、connection-group、app-version、platforms、snapshot、curl、proxy 或 unzip 参数,refresh / refresh --force 会通过 RPC 唤醒或排队后台进程执行;否则作为一次性前台同步运行。一次性前台 run/watch/refresh/repair 如果要写入 live daemon 正在管理的同一资源目录,会返回 locked 错误;需要先 stop 或改用默认 refresh 走 RPC。
  • verify 只读验证当前官方计划、本地 manifest size+BLAKE3、ZIP 结构,以及本地已有官方 seed .bytes/.hash 对的 xxHash32;资源缺失、远端变化或本地损坏时返回非 0。
  • repair 在有异常资源时尝试重新下载并修复,成功后重新写 manifest 和 snapshot。
  • doctor 检查输出目录、后台状态目录、curl/unzip、代理解析、后台 PID、RPC socket、资源锁和 daemon 控制锁。
  • clean-stable 只能在后台未运行且 RPC socket 不可连接时清理 .part.tmp、失效或损坏的 PID、socket、资源锁和 daemon 控制锁,不删除正式资源文件。

如需调整间隔:

cargo run -p bat-infrastructure --bin bat -- \
  --auto-discover \
  --watch \
  --interval 30m \
  --error-retry 60s

默认平台是 Windows,Android,无需显式传 --platforms;只有要覆盖默认平台时才传。--interval 是正常检查周期,默认 1hwatch/daemon 模式还会在每天北京时间(UTC+8)03:0016:0018:00 强制执行一次自动刷新,该轮会注入 force=true,并且会中断普通 interval 的 sleep。--error-retry 是下载、发现或校验失败后的重试周期,默认 60s,也可以用 --error-retry-seconds 60。CLI 默认启动时向 stderr 打印 BlueArchiveToolkit ASCII banner,并把阶段进度日志写到 stderr,包括自动发现、proxy、server-info、marker、catalog、audit、download、snapshot 和 publish 阶段;download 阶段会输出已完成计数和单文件开始/完成状态,worker 从共享队列独立领取任务并在完成后立即领取下一项,完成计数保持单调不倒退,最终 report 的 items 仍按 pull plan 顺序排列,audit 阶段会输出官方 .hash、本地 BLAKE3、需修复项和 ZIP 结构校验结果摘要。daemon 还会写 bat-events.jsonl 结构化日志并按大小轮转。命令结果默认以人类可读摘要写到 stdout。需要纯机器输出时加 --json --no-progress,需要显式开启进度日志则用 --progress;只想关闭横幅但保留日志时可加 --no-banner。错误时 stderr 输出 JSON errorwatch 模式下错误 JSON 的 next_retry_seconds 使用失败重试周期;如果未关闭 progress,错误 JSON 前可能已有 banner 和进度日志。普通错误 exit 1,资源目录锁冲突 exit 75verifydoctor 发现问题也返回非 0。

生产可以直接运行 --watch,也可以用 --daemon 后台运行,或者用 systemd service、容器或 Go 进程守护它。cron/systemd timer 仍可调用单次模式,但不再是 Rust 自动更新的唯一方式。下载默认并发 8,可用 --download-concurrency / BAT_DOWNLOAD_CONCURRENCY 配置为 1..=256worker 动态领取共享 plan,finished 进度即时按完成数统计,发布 report 仍按 plan 顺序。项目是否热更新、热重载或重启进程,由上层业务集成决定。生产官方资源目录应使用独立输出目录,不要指向现有客户端或人工维护的资源目录;上层读取原版资源时应读取 --output/current,不要读取 .stagingversions 中未切换的目录。汉化 Patch/导出应写入 --localized-output,并保留官方相对目录结构,不能写回 --output/current。发布状态分两档:not_localized 只发布原版资源、不发布汉化资源;localized 发布原版和汉化两套资源。非 dry-run 每轮会创建 --output/.official-sync.lock,防止并发写同一官方资源目录;release.cleanup execute 使用同一个锁并在锁内重新生成/校验 plan_idlocalized cleanup 使用 .localized-release.locklive daemon 还会阻止前台写命令直接修改它正在管理的同一目录。

需要只做探测时可以加 --dry-run。需要关闭本地 audit 或 repair 时可以显式使用 --no-audit-local--no-repair,但生产同步默认应保持开启。

6. 真实全量 smoke

真实官方网络全量拉取 smoke 已固化为 runbook 和脚本:

scripts/official-full-pull-smoke.sh

# 或
make official-smoke

默认输出在 /tmp/bat-official-smoke-<UTC timestamp>/,脚本会执行 dry-run plan、首次全量拉取、二次 up_to_date、本地文件破坏后的 repair、repair 后 verify,并检查 stderr progress log 中存在下载已完成计数、单文件进度和校验结果摘要。完整说明见 docs/guides/official-full-pull-smoke.md

7. 输入模式

可接受的 server-info 输入是:

  • --auto-discover
  • --server-info-url <官方 URL>
  • --server-info-file <官方文件名>
  • --server-info-path <本地官方 JSON>

如果没有显式 server-info 输入,必须手动加 --auto-discover 才会走官方 metadata / GameMainConfig 辅助发现链路。不要在 Linux 生产任务里依赖已安装启动器或本地客户端目录。

8. 代码入口

当前可用的用户入口:

  • infrastructure/examples/official_launcher_bootstrap.rs
  • infrastructure/examples/official_pull_plan.rs
  • infrastructure/src/bin/bat_official_sync.rs(薄入口;控制面实现位于同目录 bat/
  • infrastructure/examples/official_update_check.rs(历史/开发入口;生产优先使用 bat
  • adapters/examples/yostar_jp_client_bootstrap.rs
  • adapters/examples/yostar_jp_discovery.rs
  • adapters/examples/yostar_jp_inventory.rs

9. 验证

推荐验证命令:

cargo test -p bat-adapters
cargo test -p bat-infrastructure
cargo test -p bat-infrastructure --example official_launcher_bootstrap -- --nocapture
cargo test -p bat-infrastructure --example official_pull_plan -- --nocapture
cargo test -p bat-infrastructure --bin bat -- --nocapture