deploy/bootstrap.sh 下载 jar 有两套标准。ViaVersion / ViaBackwards / ViaRewind 三个插件按写死的 sha256 校验,对不上就 die(install_via_plugins:1413-1415);FELIS_VELOCITY_FORK_JAR 也必须带摘要,否则拒装。而从 PaperMC Fill v3 下的两个 jar 一个都不校验,尽管上游在同一个已经被解析过的响应里就把 sha256 交回来了。
deploy/bootstrap.sh
die
install_via_plugins:1413-1415
FELIS_VELOCITY_FORK_JAR
这两个 jar 分别是所有玩家连接经过的代理,和所有游戏后端的服务端本体。目前对它们唯一的检查是 curl -fSL 的 HTTP 状态码。
curl -fSL
#19 合并之后这个不对称会更刺眼:opt-in 的 fork 路径有闸门,默认安装路径没有。
#19
Found by Claude Opus 5 (claude-opus-5) while reviewing the install path after wiring the fork-jar digest gate, on 2026-07-28.
papermc_latest_jar:1258-1267 把 Fill v3 的响应 grep 出一个 URL 就丢掉其余全部:
papermc_latest_jar:1258-1267
urls="$(printf '%s' "$json" | grep -o 'https://fill-data\.papermc\.io/[^"]*\.jar' || true)" url="${urls%%$'\n'*}"
实测今天 GET https://fill.papermc.io/v3/projects/velocity/versions/3.5.1/builds/latest 的 downloads 段:
GET https://fill.papermc.io/v3/projects/velocity/versions/3.5.1/builds/latest
downloads
"server:default": { "name": "velocity-3.5.1-615.jar", "checksums": { "sha256": "b4e3164df5377346854dc6cb9e6a78022b1946ff69e89676313f5f6f1c6f0fb3" }, "size": 18932366, "url": "https://fill-data.papermc.io/v1/objects/b4e3164df5377346854dc6cb9e6a78022b1946ff69e89676313f5f6f1c6f0fb3/velocity-3.5.1-615.jar" }
摘要出现了两次 —— 一次在 checksums.sha256,一次就嵌在 URL 路径里。URL 是内容寻址的,但没有任何一方在客户端比对:CDN 在那个路径下返回什么,curl -fSL 就收什么。
checksums.sha256
两个调用者,两条都没接:
install_velocity:1517-1523
curl -fsSL "$url" -o "$tmp"
atomic_install_file
sha256sum
resolve_game_jars:1224
PAPER_JAR_URL
--build-arg
deploy/lobby/Dockerfile:63
deploy/paper/Dockerfile:39
install_velocity 的默认分支和两个 Dockerfile 在装 jar 之前比对 sha256,不符即失败。喂一个错的摘要进去,安装必须停在下载之后、安装之前。
install_velocity
Paper 那一半比 Velocity 那一半大一点:下载在 Dockerfile 里,所以摘要要跟着 URL 一起作为第二个 --build-arg 传进去。
不要用写死摘要的做法。 install_via_plugins 能钉死是因为那三个插件版本本身就是钉住的;Paper 的版本跟着 MC_VERSION 浮动(MC_VERSION 又来自 Limbo 最新 CI 构建),Velocity 取的是 builds/latest,写死等于每次上游发新构建就装不上。要用的是解析时上游给的那个值。
install_via_plugins
MC_VERSION
builds/latest
另外两个下载不在这条 issue 范围内,它们是另一个问题:Limbo(ci.loohpjames.com Jenkins)和 LuckPerms(metadata.luckperms.net)的元数据里根本没有摘要字段 —— 实测 lastSuccessfulBuild/api/json 和 /data/all 里 sha* / md5 / checksum / digest / fingerprint 一个都搜不到。那两条要么走"人工验一次再钉死"(install_via_plugins 的模式,代价是每次上游更新要手工跟),要么明确接受。混进这条一起改会把一个免费的修复变成一个需要决策的修复。
ci.loohpjames.com
metadata.luckperms.net
lastSuccessfulBuild/api/json
/data/all
sha*
md5
checksum
digest
fingerprint
已修(d9246dd + be0c4c4):papermc_latest_jar 现在返回 <url> <sha256>(Fill v3 的 objects/<sha256>/ 路径段即摘要,此前被 grep 丢掉);Velocity jar 下载后 sha256sum 逐字节校验、不一致即 die;lobby / paper 两个 Dockerfile 把 PAPER_JAR_SHA256 设为必填 build-arg 并在解包处 sha256sum -c。安装器默认路径(bootstrap game stack)的两条 jar 现在都在下载点验签,与 Via 插件/opt-in fork 同一标准。
d9246dd
be0c4c4
papermc_latest_jar
<url> <sha256>
objects/<sha256>/
PAPER_JAR_SHA256
sha256sum -c
No dependencies set.
The note is not visible to the blocked user.
问题
deploy/bootstrap.sh下载 jar 有两套标准。ViaVersion / ViaBackwards / ViaRewind 三个插件按写死的 sha256 校验,对不上就die(install_via_plugins:1413-1415);FELIS_VELOCITY_FORK_JAR也必须带摘要,否则拒装。而从 PaperMC Fill v3 下的两个 jar 一个都不校验,尽管上游在同一个已经被解析过的响应里就把 sha256 交回来了。这两个 jar 分别是所有玩家连接经过的代理,和所有游戏后端的服务端本体。目前对它们唯一的检查是
curl -fSL的 HTTP 状态码。#19合并之后这个不对称会更刺眼:opt-in 的 fork 路径有闸门,默认安装路径没有。证据
Found by Claude Opus 5 (claude-opus-5) while reviewing the install path after wiring the fork-jar digest gate, on 2026-07-28.
papermc_latest_jar:1258-1267把 Fill v3 的响应 grep 出一个 URL 就丢掉其余全部:实测今天
GET https://fill.papermc.io/v3/projects/velocity/versions/3.5.1/builds/latest的downloads段:摘要出现了两次 —— 一次在
checksums.sha256,一次就嵌在 URL 路径里。URL 是内容寻址的,但没有任何一方在客户端比对:CDN 在那个路径下返回什么,curl -fSL就收什么。两个调用者,两条都没接:
install_velocity:1517-1523—curl -fsSL "$url" -o "$tmp"之后直接atomic_install_file,中间没有sha256sum。对照组就在同一个文件往上 100 行。resolve_game_jars:1224—PAPER_JAR_URL只作为--build-arg传进镜像构建,真正的下载发生在deploy/lobby/Dockerfile:63和deploy/paper/Dockerfile:39,两处都是裸curl -fSL。验收
install_velocity的默认分支和两个 Dockerfile 在装 jar 之前比对 sha256,不符即失败。喂一个错的摘要进去,安装必须停在下载之后、安装之前。备注
Paper 那一半比 Velocity 那一半大一点:下载在 Dockerfile 里,所以摘要要跟着 URL 一起作为第二个
--build-arg传进去。不要用写死摘要的做法。
install_via_plugins能钉死是因为那三个插件版本本身就是钉住的;Paper 的版本跟着MC_VERSION浮动(MC_VERSION又来自 Limbo 最新 CI 构建),Velocity 取的是builds/latest,写死等于每次上游发新构建就装不上。要用的是解析时上游给的那个值。另外两个下载不在这条 issue 范围内,它们是另一个问题:Limbo(
ci.loohpjames.comJenkins)和 LuckPerms(metadata.luckperms.net)的元数据里根本没有摘要字段 —— 实测lastSuccessfulBuild/api/json和/data/all里sha*/md5/checksum/digest/fingerprint一个都搜不到。那两条要么走"人工验一次再钉死"(install_via_plugins的模式,代价是每次上游更新要手工跟),要么明确接受。混进这条一起改会把一个免费的修复变成一个需要决策的修复。已修(
d9246dd+be0c4c4):papermc_latest_jar现在返回<url> <sha256>(Fill v3 的objects/<sha256>/路径段即摘要,此前被 grep 丢掉);Velocity jar 下载后sha256sum逐字节校验、不一致即die;lobby / paper 两个 Dockerfile 把PAPER_JAR_SHA256设为必填 build-arg 并在解包处sha256sum -c。安装器默认路径(bootstrap game stack)的两条 jar 现在都在下载点验签,与 Via 插件/opt-in fork 同一标准。