自我託管資源包
ResourcePackManager 內建一個小型 HTTP 伺服器。當 autoHost: true(預設)且 preferSelfHost: true(預設)時,外掛會嘗試以與 Minecraft 伺服器相同的 JVM 來託管合併後的資源包——無需外部檔案託管、無需獨立網頁伺服器、也無需手動貼上 URL。
本頁說明這條自我託管路徑如何運作、健全性檢查負責什麼、連接埠與主機名稱如何選擇,以及在預設值不適用時要設定哪些內容。
若你想透過 RSPM 之外的、自己現有的網頁伺服器託管 zip,請參閱疑難排解頁面中關於 autoHost: false 的章節。
交付決策樹
當玩家加入時,RSPM 會依照下列優先順序選擇交付 URL:
selfHostForce: true— 直接使用自我託管,無探測、無遠端上傳。主要用於測試自我託管路徑。會繞過所有其他旗標。preferSelfHost: true且selfHostEnabled: true且不在網路模式 — 嘗試自我託管並執行三項健全性檢查(見下文)。若全部通過則確認使用自我託管;若有任何一項失敗,則回退至遠端路徑。- 否則 — 將資源包上傳到
https://magmaguy.com/rsp/並公告該 URL。若上傳失敗或 SHA1 檢查回報SESSION_NOT_FOUND,則回退至自我託管(假設selfHostEnabled: true)。
取得 URL 後,RSPM 會使用 Minecraft 的多重資源包 API,因此它的 Java 資源包能與其他伺服器發送的資源包共存。目前的 Bukkit 外掛描述檔要求 Minecraft 1.21.4 或更新版本。
三項健全性檢查
當 preferSelfHost: true 時,RSPM 會在確認使用自我託管之前,依序執行下列檢查:
第 1 層 — 對解析後外部主機進行 heuristic 檢查
若解析後的主機(見下方「外部主機偵測」)為 RFC1918(10.*、172.16-31.*、192.168.*)、loopback(127.*)、link-local(169.254.*),或未指定(0.0.0.0),自我託管不可能服務外部用戶端。立即略過並改用遠端託管。
這可揪出非常常見的「ipify 查詢失敗、回退到 LAN IP」失敗模式。
第 2 層 — 本機 self-probe
對 http://127.0.0.1:<port>/rspm.zip 發出 HEAD 請求,驗證 HTTP 200 且主體非空。可揪出:
- 連接埠綁定衝突(其他程式佔用了所選的連接埠)
- 資源包檔案缺失(路由已註冊但 zip 尚未在磁碟上)
- 路由註冊的錯誤
逾時設定相當積極(3 秒),以確保慢速探測不會拖累啟動。
第 3 層 — 外部可達性探測
將公告的 URL 以 POST 方式送往 magmaguy.com 託管端的 POST /rsp/probe。託管端會從公開觀測點擷取該 URL(搭配 SSRF 防護與緊湊的逾時設定),並回報是否可達。
可揪出最常見的生產環境失敗模式:伺服器有公開 IP,但 HTTP 連接埠未在路由器或防火牆上轉送。第 2 層通過(伺服器在 127.0.0.1 有回應),但真實用戶端永遠下載不到資源包。
探測結果的決策政策:
- reachable=true → 外部用戶端可連到我們的 URL。確認使用自我託管。
- reachable=false → 外部用戶端連不到。拆除自我託管,改用遠端託管(從 magmaguy.com 普遍可達)。
- 探測通訊本身失敗(IOException) → 無法以任一方式驗證。預設保留自我託管:以無法探測為由拒絕承諾會自相矛盾,因為遠端路徑同樣需要 magmaguy.com。
檢查仍無法偵測的情況
NAT-hairpin 邊緣情況:連接埠對公開網際網路開放(第 3 層通過),但操作員自己的路由器不會將 LAN 內部流量繞回。外部用戶端正常,但操作員從同一台機器測試卻失敗。
若只是想在主機機器上快速測試,請設定 preferSelfHost: false 並改用遠端回退,或從行動網路/外部網路測試該公開 URL。若要建立長期的自我託管環境,請使用 split-horizon DNS(讓同一個公開主機名稱在你的網路內部解析到伺服器的 LAN 位址)。請勿將 selfHostExternalHost 設為 127.0.0.1:loopback 與私有主機會被公開主機健全性檢查拒絕,也無法服務外部用戶端。
連接埠解析
有兩個設定會相互影響:
selfHostPort— 明確的連接埠(任意正整數),或-1(預設)以自動衍生。networkHttpOffset-v2— 僅在selfHostPort = -1時參考。會加到 Minecraft 伺服器連接埠上以衍生 HTTP 連接埠。預設1。(在代理網路中,此同一值也是代理對後端 HTTP 連接埠的後備猜測——見下文。)
預設值為 selfHostPort: -1 + networkHttpOffset-v2: 1,因此:
- MC 連接埠 25565 → HTTP 連接埠 25566
- MC 連接埠 25584 → HTTP 連接埠 25585
這會在單一主機網路上自動為各後端錯開 HTTP 連接埠,無需管理員設定——每個後端本就有唯一的 MC 連接埠,因此每個都會獲得唯一的 HTTP 連接埠。
為什麼偏移為 1?
大多數共享 / 代管 Minecraft 託管(基於 Pterodactyl 的面板等)會為每個容器分配狹窄的連接埠範圍(通常只有 4–10 個埠)。較大的偏移會落在範圍外,主機防火牆會悄無聲息地擋掉 HTTP 連接埠。偏移為 1 即使在很緊的分配下也能容納。
具備完整連接埠控制權的自架管理員可將此值調高至任意值。在代理網路上,後端會自動向代理通報它實際綁定的確切 HTTP 連接埠,因此即使你改變偏移量或設定明確的 selfHostPort,代理也會跟著走。將代理的 network-http-offset-v2 調整為相符的值,只在後端尚未完成通報的短暫期間(或通報無法抵達代理時)作為後備才有意義。
注意:RCON 衝突
若你的主機預設在 MC port + 1 啟用 RCON,請選擇偏移 2 或 3 以避免連接埠衝突。請檢查 server.properties 中的 rcon.port=。
帶版本的設定鍵
config.yml 中的設定字面上就叫做 networkHttpOffset-v2。v1 鍵為 networkHttpOffset,預設為 100——該預設值在共享 / 代管託管環境(每個遊戲容器只獲得 ~4–10 個連續連接埠)會出問題:MC + 100 落在範圍外,HTTP 伺服器在內部能綁定但主機防火牆會擋掉外部流量,導致代理永遠收到無聲的 CONNECT_FAILED。v2 改採預設 1,使 MC + 1 即使在最狹窄的容器分配下也能穩穩落在範圍內。
若你從 v1 升級,失效的 v1 鍵會作為無害的殘留留在你的設定中,直到你清理為止——RSPM 刻意不讀取它。
外部主機偵測
selfHostExternalHost 控制用戶端在 URL 中看到的主機名稱。留空(預設)則會依下列優先順序自動偵測:
- api.ipify.org / checkip.amazonaws.com — 回傳此主機的公開 IPv4。每次
/rspm reload會快取一次,避免反覆敲打 IP 服務。 Bukkit.getIp()— 伺服器的綁定位址,需非空且非0.0.0.0。通常是 LAN 位址。InetAddress.getLocalHost()— 盡力而為。localhost— 最後手段。位於本機之外的用戶端連不上。
若自動偵測落在無法路由的位址,且 preferSelfHost: true,第 1 層 heuristic 檢查會失敗,外掛會切換到遠端託管。
要獲得最可靠的自我託管設定,請將 selfHostExternalHost 明確設為你的公開主機名稱(例如 play.example.com)。這會完全略過 ipify/AWS 偵測,探測會針對該明確值執行。
設定參考
# Whether the built-in HTTP server may be used as a delivery path at all.
# When false, ordinary self-host attempts are disabled. selfHostForce still overrides it.
selfHostEnabled: true
# Port for the self-host HTTP server.
# -1 (default) = auto-derive: HTTP port = Minecraft server port + networkHttpOffset-v2.
# Set to any positive value to force an explicit port.
selfHostPort: -1
# Added to the Minecraft server port when selfHostPort = -1.
# Default 1 (MC 25565 -> HTTP 25566). On a proxy network this is only a FALLBACK:
# the backend announces the exact HTTP port it actually bound to the proxy, so
# you no longer have to match this against the proxy's network-http-offset-v2.
networkHttpOffset-v2: 1
# Public hostname or IP clients use to reach the self-host server.
# Leave empty for auto-detect (api.ipify.org / checkip.amazonaws.com).
selfHostExternalHost: ""
# Try self-host FIRST with three sanity checks, fall back to remote if any fail.
# When false, use the legacy order: remote upload first, self-host only on upload failure.
preferSelfHost: true
# Skip ALL other delivery paths and force self-hosting.
# Bypasses sanity checks AND remote upload. Mainly for testing.
selfHostForce: false
# Print every step of pack preparation and the hosting handshake.
# Default false — see "What the console actually prints" below.
# `/rspm verbose on|off` flips this same key at runtime and saves it here.
verboseLogging: false
主控台實際會印出什麼
在正常啟動時,RSPM 刻意只印出一行關於託管的訊息——只講結果,不講過程:
[ResourcePackManager] Resource pack is live via self-hosting — http://play.example.com:25566/rspm.zip
或在遠端路徑勝出時:
[ResourcePackManager] Resource pack is live via automatic hosting — https://magmaguy.com/rsp/<uuid>
該行只會在每次有交付路徑重新初始化時印出一次,不會為玩家重試或保活 tick 而重印。若某次重新載入的資源包內容未變更,則可沿用既有的託管註冊,而不會印出新的結果行。
失敗的健全性檢查不是警告。 探測失敗是 RSPM 自己就能恢復的狀況,因此它被記錄為細節而非故障,而且每則訊息都會明講這一點(Self-host check: local pack link is not public. This is OK.)。除非你主動要求,否則不會看到它——把外掛已經處理好的事情記為警告,讀起來像是故障,只會讓操作員去追一個不存在的問題。
若要看到完整的決策鏈——哪一項檢查失敗、探測 URL、原因代碼、每個被暫存的資源包與每個被合併的叢集——請執行:
/rspm verbose on
然後執行 /rspm reload。這是你在提出託管相關的錯誤回報之前應該先打開的開關。該指令會把 verboseLogging: true 寫入 config.yml,此設定會在重啟後保留,因此完成後請執行 /rspm verbose off;手動編輯該設定鍵的效果完全相同。
請注意 verboseLogging 涵蓋的是資源包準備與託管。Bedrock 轉換器有它自己獨立的開關 bedrockConverterDebug——請參閱 Bedrock 轉換。
後端 HTTP 伺服器路由
內建 HTTP 伺服器一律在以下位址提供資源包 zip:
http://<host>:<port>/rspm.zip
在網路模式下(RSPM 位於 Velocity / BungeeCord / Waterfall 代理後方),會額外註冊數個路由供代理外掛拉取:
http://<host>:<port>/bedrock.zip # the Bedrock-converted pack
http://<host>:<port>/mappings.json # the Geyser custom-mappings JSON
http://<host>:<port>/rspm-update.jar # the universal RSPM update jar (authenticated)
資源包與 Bedrock 成品路由皆以檔案為基礎:每個路由在每次請求時都會即時讀取其檔案,因此重新混合後若覆寫到同一路徑,無需重啟 HTTP 伺服器即可自動帶入。Bedrock 路由使用強 ETag,並同時支援 If-Modified-Since 以維持相容性,因此未變更的代理輪詢會收到 304,幾乎不耗頻寬。當底層檔案不存在時(例如首次混合完成前),那些路由都會乾淨地回傳 404。更新路由則另外由一個從共享網路金鑰衍生出的 bearer token 保護,且只有在能提供有效的更新 jar 時才可用。
驗證自我託管是否啟用
/rspm status 會顯示:
Active delivery: SELF-HOSTED— 目前使用自我託管Active delivery: REMOTE (magmaguy.com)— 目前使用遠端自動託管URL: ...— 用戶端實際會看到的 URLResolved external host—selfHostExternalHost解析後的結果Public IP (auto-detected)— ipify/AWS 回報的內容(若有)selfHostPort— 自動 vs 明確指定,以及解析後的值
若你預期使用自我託管但實際是遠端,請查看 /rspm status——啟動日誌刻意對自我修復的探測失敗保持安靜。請執行 /rspm verbose on 再執行 /rspm reload,即可看到是哪一項健全性檢查失敗以及原因。
常見錯誤
- 在 hairpin 失效的路由器下信任第 3 層探測 — 探測會從 magmaguy.com 觀測點執行,因此無法揪出「外部用戶端正常但操作員自己的 LAN 不會繞回」的情況。若不確定,請從行動網路上的手機測試。
- 將
networkHttpOffset-v2調整超過你的託管供應商連接埠範圍 — 症狀是代理端永遠收到無聲的 CONNECT_FAILED。後端會向代理通報它實際綁定的連接埠,但 HTTP 伺服器仍必須綁定到一個可達的連接埠,代理也仍必須能連到它;若mcPort + offset落在你容器分配的連接埠範圍之外,無論是否有通報,綁定 / 防火牆都會失敗。提高偏移之前,請檢查該連接埠是否落在你容器分配的連接埠範圍內。