8.5 KiB
资源分发接口与三端接入约定
本文件位于 farm_service 项目。服务端接口及准备工具已实现,
素材发布文件位于本仓库根目录 assets/。当前文件只完成本地准备,
尚未提交或发布到 GitHub/Gitea,不能据此认定远端直链已经可用。
活动接口尚未实施,不因为预留服务地址就返回虚构的活动数据。
已确认的客户端配置约定
两个配置项始终同时存在,不根据选项隐藏:
| 配置 | 约定 |
|---|---|
| 资源获取地址 | 选项 Github、Gitea、farm_service;默认 Github |
| farm_service 地址 | 独立的服务基础地址,供资源、活动等功能共同使用 |
选择 Github 或 Gitea 时,farm_service 地址仍保留,未来活动查询仍可使用。
选择 farm_service 获取资源时,该地址必须有效。客户端根据此配置构造
/v1/assets/{sha256}/assets.zip 请求,不依赖清单中服务地址的占位值。
三端接入状态及具体配置字段以插件实现为准,不能把此文档当作线上验证。
Farm当前本地已接入共享启动校验/下载器,三端插件包不再包含assets.zip。
NoneBot字段为FARM_RESOURCE_SOURCE、FARM_SERVICE_URL;AstrBot字段为
resource_source、farm_service_url;真寻配置名为「资源获取地址」、
「farm_service 地址」。均默认Github,服务地址默认空,修改后重载。
源码及离线测试已适配不代表真实公网下载或宿主验证已完成。
仓库文件与发布位置
assets/
manifest.json
assets.zip
assets/manifest.json 和 assets/assets.zip 是实际发布文件;
docs/assets.manifest.example.json 与实际清单保持一致,仅用于阅读示例。
ZIP 从现有农场素材复制,源文件不由准备工具删除。
后续素材发布只更新并提交 farm_service 仓库内的这组文件,
不要把 ZIP 加回 NoneBot、真寻或 AstrBot 的插件仓库、生成目录或发布包。
插件可以携带绑定版本的轻量清单,但不携带 assets.zip。
发布到 main 分支后,公开静态清单直链为:
- GitHub:
https://raw.githubusercontent.com/Shu-Ying/farm_service/main/assets/manifest.json - Gitea:
https://gitea.diuse.work/Diuse/farm_service/raw/branch/main/assets/manifest.json
对应 ZIP 位于相同目录,文件名为 assets.zip。选择 GitHub/Gitea 时
可独立访问公开静态清单和 ZIP,无需 farm_service 在线。
本轮没有提交、推送或验证这些远端文件。
服务端部署文件
服务不从用户输入下载ZIP,也不代理任意URL。管理员准备本地发布文件;
FARM_ASSET_MANIFEST指向JSON,其同目录固定文件名为assets.zip。
启动读取并检查schema、版本、URL、大小、整个ZIP的SHA256及ZIP文件头。
校验失败拒绝启动,不对外提供损坏素材。未设置该环境变量时,其余服务
正常启动,资源接口返回503。现有用户资料接口仍需要Bearer鉴权。
ZIP不解压。启用后保留最多64 MiB的单份只读内存快照,请求共享这份内容; 不会每个请求重复读取磁盘和计算SHA。运行中修改磁盘不会改变当前返回内容, 更新清单或ZIP需先准备一套完整目录,再修改配置并重启服务。 当前仅托管一个活动资源版本;请求其他SHA返回404,历史版本仍需保留在 GitHub/Gitea中,或以后扩展多版本服务。资源版本不必等于插件版本。
用Rust工具生成清单
不手填SHA。工具从现有ZIP计算SHA256与字节数,并复制文件、输出JSON; 输出目录必须不存在,不覆盖旧发布目录,不上传、不访问远端。
实际清单及完整JSON示例
已使用当前农场 ZIP 生成真实 SHA 与大小。生成根目录 assets/ 的示例如下;
已存在时请选择新的临时输出目录,检查后再替换一整套发布文件。
cargo run --locked --bin prepare_assets -- `
D:\Work\farm\src\farm_render\data\assets.zip `
.\assets `
farm-assets-v1 `
https://raw.githubusercontent.com/Shu-Ying/farm_service/main/assets/assets.zip `
https://gitea.diuse.work/Diuse/farm_service/raw/branch/main/assets/assets.zip `
https://farm.example
https://farm.example 是明确的占位域名(placeholder),不是已部署服务。
目前未提供公网地址,所以实际清单及示例暂保留该值;客户端使用独立的
「farm_service 地址」配置构造请求,不请求该占位地址。
部署时应通过准备工具改为真实公网基础地址,支持反向代理路径前缀。
公网访问由部署者配置HTTPS代理,
服务仍默认监听127.0.0.1:8080。不要使用GitHub/Gitea仓库网页URL替代raw文件URL。
准备完成后设置环境变量(PowerShell示例):
$env:FARM_ASSET_MANIFEST = (Resolve-Path .\assets\manifest.json).Path
# FARM_API_TOKEN等原有必填配置沿用原部署方式,不在本文放入真实令牌。
cargo run --locked --bin farm_service
此时依旧需要原有用户服务的FARM_API_TOKEN;公开资源下载不使用它。 不要将资料API令牌打包进插件或写入资源JSON。
JSON协议
schema固定为1;工具实际生成有效64位小写SHA256,下面仅解释字段:
| 字段 | 类型 | 含义 |
|---|---|---|
| schema | 整数 | 清单协议版本1 |
| version | 字符串 | 资源发布标签,1~64个字母、数字、点、下划线或连字符 |
| sha256 | 字符串 | 整个ZIP的64位小写SHA256 |
| size_bytes | 整数 | ZIP字节数,1~67,108,864 |
| sources.github | 字符串 | GitHub绝对HTTPS下载URL |
| sources.gitea | 字符串 | Gitea绝对HTTPS下载URL |
| sources.farm_service | 字符串 | 服务绝对HTTPS下载URL,包含相同SHA256 |
JSON不接受未知字段;URL不允许凭据、查询参数或fragment。 清单大小限制16 KiB。服务端校验本地ZIP,不会主动探测两个镜像是否一致; 发布者须确保三源文件字节相同。主分支raw文件可能变更,长期建议采用 固定提交、标签或Release附件直链。SHA固定而raw发生变化时,客户端必须 拒绝新字节,不能通过重新获取任意清单来跳过版本兼容性检查。
HTTP接口
GET /v1/assets/manifest.json
公开,无需资料API令牌;200返回上述JSON,Cache-Control为no-cache。
未启用资源服务时503,错误码assets_unavailable。
GET /v1/assets/{sha256}/assets.zip
公开,只有SHA与当前校验资源一致时返回200,Content-Type为application/zip。
下载内容与清单的SHA及大小一致;ETag为带双引号的完整SHA。
支持If-None-Match条件请求,命中返回304;返回不可变长期缓存标记。
未知或旧SHA返回404及asset_not_found。不支持任意路径访问,也不执行解压。
不是活动接口,不读取玩家库。未启用资源服务时返回503。
三端下载器接入约定
- 启动时计算本地ZIP的SHA256;符合插件绑定的资源版本和摘要则直接复用。
- 缺失或不匹配才按「资源获取地址」选择源下载;网络不可用不应损坏旧文件。
- 将内容下载到临时文件,限制字节数和超时,校验大小、SHA及必要ZIP条目, 通过后原子替换,避免并发启动重复下载。
- 只有摘要和布局元数据匹配的ZIP才能参与绘图,不能任意跟随服务的最新版本。
- 清单可以从farm_service接口读取,也可将工具生成的同一JSON发布到镜像, 并随插件保留经过版本绑定的清单,避免选择Github后又强依赖服务在线。
- 三端共用同一实现;无可用素材时保留文字功能并提示管理员,不能使用损坏包。
- 当前按所选源下载,不自动跨源回退;失败保留文字模式,调整配置后重载重试。
- 本地缓存路径为插件数据目录
assets/<sha256>/assets.zip,可手动预置离线包。 同进程并发启动合并下载,跨进程使用独立临时文件与原子替换保证写入完整。 不解压到磁盘,缓存中存在旧版本时不自动删除,便于回滚。
离线验证
cargo fmt --check
cargo test --locked --offline --all-targets
cargo clippy --locked --offline --all-targets -- -D warnings
测试覆盖公开清单、ZIP下载、条件缓存、磁盘变动后快照一致性、损坏/缺失 文件及非法URL拒绝、资源未启用,另保留原用户接口鉴权和持久化测试。 离线验证不代表真实公网部署、镜像发布或三端集成完成。