跳至主要內容

自我託管資源包

ResourcePackManager 內建一個小型 HTTP 伺服器。當 autoHost: true(預設)且 preferSelfHost: true(預設)時,外掛會嘗試以與 Minecraft 伺服器相同的 JVM 來託管合併後的資源包——無需外部檔案託管、無需獨立網頁伺服器、也無需手動貼上 URL。

本頁說明這條自我託管路徑如何運作、健全性檢查負責什麼、連接埠與主機名稱如何選擇,以及在預設值不適用時要設定哪些內容。

若要在 RSPM 前部署 HTTPS 反向代理並保留自動交付,請使用下文的 selfHostExternalUrl。只有當其他系統同時負責託管和向玩家交付時,才使用 autoHost: false。

交付決策樹​

當玩家加入時,RSPM 會依照下列優先順序選擇交付 URL:

一般自動交付要求 autoHost: true。當 autoHost: false 時,只有明確設定 selfHostForce: true 才會傳送 URL。

  1. selfHostForce: true — 直接嘗試自我託管,不進行探測或遠端上傳,主要用於測試這條路徑。覆寫 autoHost 和 selfHostEnabled,但 URL 驗證與 HTTP 監聽器啟動仍須成功。
  2. preferSelfHost: true 且 selfHostEnabled: true:執行下列檢查並嘗試自行託管,代理後端也適用。檢查失敗時退回遠端託管。
  3. 否則 — 重用或上傳資源包至 https://magmaguy.com/rsp/,並公告該 URL。若初始化、SHA1 檢查或上傳失敗,則在 selfHostEnabled: true 時嘗試經過驗證的自我託管。SESSION_NOT_FOUND 也會清除遠端工作階段,讓後續嘗試能重新初始化。自動後備採用與優先自我託管相同的檢查;兩條路徑皆失敗時,不會公告新的交付 URL。

遠端主機接受最大 50,000 KiB(51,200,000 位元組)的 Java 資源包。RSPM 會在上傳前檢查大小。較大的資源包絕不會被上傳:主控台會印出 Automatic hosting skipped: resource pack is <size> bytes; the limit is 51200000 bytes.。之後 RSPM 會停止對該資源包使用遠端託管,並持續重試經過驗證的自我託管(當 selfHostEnabled: true 時),直到託管因新的資源包或重新載入而重新開始。請縮小資源包大小或讓自我託管可被連線,然後執行 /rspm reload。

取得 URL 後,RSPM 會使用 Minecraft 的多重資源包 API,因此它的 Java 資源包能與其他伺服器發送的資源包共存。目前的 Bukkit 外掛描述檔要求 Minecraft 1.21.4 或更新版本。

三項健全性檢查​

RSPM 在選擇自動自我託管前會依序執行這些檢查,包含遠端託管失敗後的後備路徑。只有 selfHostForce: true 可以略過:

第 1 層 — 對解析後外部主機進行 heuristic 檢查​

若解析後的主機(見下方「外部主機偵測」)為 RFC1918(10.*、172.16-31.*、192.168.*)、loopback(127.* 或 localhost)、link-local(169.254.*)或未指定位址(0.0.0.0),便略過自我託管。IPv6 未指定、loopback、link-local、site-local 和 unique-local 位址也會被拒絕。這只是對主機字串的啟發式檢查;主機名稱仍須通過下述下載檢查。

這可揪出非常常見的「ipify 查詢失敗、回退到 LAN IP」失敗模式。

第 2 層 — 本機與公告 URL 下載​

RSPM 先向 http://127.0.0.1:<port>/rspm.zip,再向玩家將收到的確切 URL 傳送指定位元組範圍的 GET 請求,將開頭最多 1 KiB 與本機資源包比較。接受 HTTP 200 或 206;回報的長度必須相符,206 回應還須包含預期的 Content-Range。重新導向會被拒絕。可偵測:

  • 連接埠綁定衝突(其他程式佔用了所選的連接埠)
  • 資源包檔案缺失(路由已註冊但 zip 尚未在磁碟上)
  • 錯誤路由、HTML 錯誤頁或不一致的資源包位元組
  • 伺服器本身無法下載公告 URL 的情況,包括 NAT loopback 故障

每次連線與讀取的逾時為 3 秒,讀取樣本另有獨立的 3 秒期限。這些是有限樣本檢查,不是完整的用戶端下載。

第 3 層 — 外部可達性探測​

將公告的 URL 以 POST 方式送往 magmaguy.com 託管端的 POST /rsp/probe。託管端會從公開觀測點擷取該 URL(搭配 SSRF 防護與緊湊的逾時設定),並回報是否可達。

可揪出最常見的生產環境失敗模式:伺服器有公開 IP,但 HTTP 連接埠未在路由器或防火牆上轉送。第 2 層通過(伺服器在 127.0.0.1 有回應),但真實用戶端永遠下載不到資源包。

探測結果的決策政策:

  • reachable=true 且 HTTP 200 或 206 → 探測從其公開網路位置存取到 URL。選擇自我託管。
  • reachable=false 或其他 HTTP 狀態 → 驗證失敗。撤回候選 Java URL,嘗試透過 magmaguy.com 遠端託管。網路模式下保留後端 HTTP 監聽器,讓代理能輪詢成品。
  • 探測通訊本身失敗(IOException),或探測用戶端無法使用 → 可達性尚未驗證。嘗試遠端託管;無法聯絡探測服務並不證明上傳也會失敗。自動後備不能略過這項檢查。

檢查的限制​

從公告 URL 下載現在能偵測伺服器自身網路中的 NAT loopback 故障,但無法證明每位玩家的網路都可存取,也不能證明 Minecraft 用戶端能完成整個下載。請以真實用戶端驗證完整下載和資源包接受情況;檢查公開存取時,使用另一個外部網路。

若只是想在主機機器上快速測試,請設定 preferSelfHost: false 並改用遠端回退,或從行動網路/外部網路測試該公開 URL。若要建立長期的自我託管環境,請使用 split-horizon DNS(讓同一個公開主機名稱在你的網路內部解析到伺服器的 LAN 位址)。請勿將 selfHostExternalHost 設為 127.0.0.1:loopback 與私有主機會被公開主機健全性檢查拒絕,也無法服務外部用戶端。

連接埠解析​

有兩個設定會相互影響:

  • selfHostPort — 1 至 65535 的明確連接埠,或使用 -1(預設)自動計算。計算結果也必須在此範圍內;其他值會阻止監聽器啟動。
  • networkHttpOffset-v2 — 僅在 selfHostPort = -1 時參考。會加到 Minecraft 伺服器連接埠上以衍生 HTTP 連接埠。預設 1。(在代理網路中,此同一值也是代理對後端 HTTP 連接埠的後備猜測——見下文。)

預設值為 selfHostPort: -1 + networkHttpOffset-v2: 1,因此:

  • MC 連接埠 25565 → HTTP 連接埠 25566
  • MC 連接埠 25584 → HTTP 連接埠 25585

不同的 Minecraft 連接埠會得到不同的 HTTP 連接埠,但計算結果仍可能與另一個後端的 Minecraft 連接埠或其他服務衝突。請檢查所有監聽器與供應商分配的連接埠。

為什麼偏移為 1?​

共享或代管服務可能只為每個容器分配少量連接埠。偏移 1 讓計算出的連接埠接近遊戲連接埠,但不會預留它,也不保證供應商已分配或開放它。請在管理面板確認確切的 HTTP 連接埠。

具備完整連接埠控制權的自架管理員可將此值調高至任意值。在代理網路上,後端會自動向代理通報它實際綁定的確切 HTTP 連接埠,因此即使你改變偏移量或設定明確的 selfHostPort,代理也會跟著走。將代理的 network-http-offset-v2 調整為相符的值,只在後端尚未完成通報的短暫期間(或通報無法抵達代理時)作為後備才有意義。

注意:RCON 衝突​

若你的主機預設在 MC port + 1 啟用 RCON,請選擇偏移 2 或 3 以避免連接埠衝突。請檢查 server.properties 中的 rcon.port=。

帶版本的設定鍵​

config.yml 中的鍵名就是 networkHttpOffset-v2。v1 的鍵名為 networkHttpOffset,預設值 100,可能使監聽器超出供應商分配的連接埠範圍。v2 預設值為 1,但該連接埠仍須可用且可存取。

若你從 v1 升級,失效的 v1 鍵會作為無害的殘留留在你的設定中,直到你清理為止——RSPM 刻意不讀取它。

外部主機偵測​

selfHostExternalHost 控制用戶端在 URL 中看到的主機名稱。留空(預設)則會依下列優先順序自動偵測:

  1. api.ipify.org / checkip.amazonaws.com — 回傳此主機的公開 IPv4。每次 /rspm reload 會快取一次,避免反覆敲打 IP 服務。
  2. Bukkit.getIp() — 伺服器的綁定位址,需非空且非 0.0.0.0。通常是 LAN 位址。
  3. InetAddress.getLocalHost() — 盡力而為。
  4. localhost — 最後手段。位於本機之外的用戶端連不上。

若自動偵測落在無法路由的位址,且 preferSelfHost: true,第 1 層 heuristic 檢查會失敗,外掛會切換到遠端託管。

要獲得最可靠的自我託管設定,請將 selfHostExternalHost 明確設為你的公開主機名稱(例如 play.example.com)。這會完全略過 ipify/AWS 偵測,探測會針對該明確值執行。

設定參考​

HTTPS 與反向代理​

將 selfHostExternalUrl 設為完整的公開下載 URL:

autoHost: true
selfHostEnabled: true
preferSelfHost: true
selfHostPort: 25566
selfHostExternalUrl: "https://packs.example.com/rspm.zip"

設定反向代理,將此公開路徑轉送到 RSPM 內部的 http://<server>:25566/rspm.zip 路由並終止 TLS。RSPM 仍執行 HTTP 監聽器;此設定不會安裝憑證或設定網頁伺服器。

確切 URL 會傳送給 Java 玩家,並用於外部可達性探測,不會附加 /rspm.zip。它在 Java 交付中覆寫 selfHostExternalHost 和公開 IP 偵測;selfHostPort 仍控制內部監聽器。代理輪詢 Bedrock 成品仍使用後端 HTTP 端點。

只接受帶主機名稱的完整 HTTP 或 HTTPS URL,不得包含內嵌認證資料或片段。URL 中的明確連接埠須在 1 至 65535 之間。無效 URL 會阻止自我託管。一般自動託管可以退回遠端服務,強制自我託管則不能。留空以使用主機和連接埠偵測。

設定項目​

# 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 a value from 1 to 65535 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: ""

# Optional complete public Java-pack URL, including the path.
# Your reverse proxy supplies HTTPS and forwards to the internal /rspm.zip route.
selfHostExternalUrl: ""

# 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

主控台實際會印出什麼​

Java 遠端託管和 Bedrock 中繼失敗後,會採用帶隨機變化的指數退避。每個流程同時只允許一次嘗試,最多重試五次,然後等待 15–30 分鐘再開始下一輪。成功後重設重試額度;HTTP 用戶端不會另行自動重試。Java 託管會先檢查遠端 SHA-1,再決定是否上傳。Bedrock 重試會在最多 20 分鐘內重用已成功上傳且沒有變更的檔案。一般的每 25 分鐘中繼續期仍會上傳檔案,以延長伺服器上的有效期限。

在正常啟動時,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 而重印。若某次重新載入的資源包內容未變更,則可沿用既有的託管註冊,而不會印出新的結果行。

可達性檢查失敗會記錄在詳細日誌層級。 例如:Self-host check: local pack link is not public. This is OK.。主機與 localhost 檢查會以 This is OK. 結尾;公告 URL 的下載檢查與外部驗證則會回報失敗,不帶此後綴。無效 URL 設定、監聽器啟動失敗和遠端通訊失敗仍可能產生警告。單次檢查失敗不能證明遠端後備已成功;請檢查最終交付狀態。

若要看到完整的決策鏈——哪一項檢查失敗、探測 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 代理後方),會額外註冊數個路由供代理外掛拉取:

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 伺服器即可使用;僅替換磁碟檔案不會授權交付。若沒有目前獲准的成品、檔案缺失,或位元組與發布摘要不符,路由會回傳 404。Bedrock 路由還要求轉換保持啟用。強 ETag 支援 If-None-Match,優先於相容性的 If-Modified-Since 檢查;未變更的輪詢可收到無主體的 304。更新路由由共享網路金鑰衍生的 bearer token 單獨保護,且只有能提供有效更新 jar 時才可用。

驗證自我託管是否啟用​

/rspm status 會顯示:

  • Active delivery: SELF-HOSTED — 目前使用自我託管
  • Active delivery: REMOTE (magmaguy.com) — 目前使用遠端自動託管
  • URL: ... — 用戶端實際會看到的 URL
  • Resolved external host — selfHostExternalHost 解析後的結果
  • Public IP (auto-detected) — ipify/AWS 回報的內容(若有)
  • selfHostPort — 自動 vs 明確指定,以及解析後的值

若你預期使用自我託管但實際是遠端,請查看 /rspm status——啟動日誌刻意對自我修復的探測失敗保持安靜。請執行 /rspm verbose on 再執行 /rspm reload,即可看到是哪一項健全性檢查失敗以及原因。

常見錯誤​

  • 把探測成功視為完整的用戶端測試 — 本機樣本與公開探測僅涵蓋特定網路路徑。請以真實玩家驗證完整下載和資源包接受情況;強制自我託管會完全略過這些檢查。
  • 將 networkHttpOffset-v2 調整超過你的託管供應商連接埠範圍 — 症狀是代理端永遠收到無聲的 CONNECT_FAILED。後端會向代理通報它實際綁定的連接埠,但 HTTP 伺服器仍必須綁定到一個可達的連接埠,代理也仍必須能連到它;若 mcPort + offset 落在你容器分配的連接埠範圍之外,無論是否有通報,綁定 / 防火牆都會失敗。提高偏移之前,請檢查該連接埠是否落在你容器分配的連接埠範圍內。