跳至主要內容

代理網路(BungeeCord / Waterfall / Velocity)

ResourcePackManager 可在代理網路上運作。只有一個 jar——ResourcePackManager.jar——你會在每個後端以及代理上安裝同一個 jar。在後端上它以後端角色執行(合併、託管、推送、轉換);在 Velocity 或 BungeeCord/Waterfall 代理上,同一個 jar 會自動偵測平台載入器並以代理角色執行(網路端 Bedrock 交付)。這兩種角色會自行建立連結:代理持有網路金鑰,並在玩家首次連線到某個後端時把金鑰推送給它——沒有各平台分開的代理 jar,也沒有需要貼上的金鑰。

本頁通篇的「代理外掛」一詞,是指同一個 ResourcePackManager.jar 以代理角色執行的簡稱。

代理外掛的作用

代理外掛的工作是Bedrock 資源包的合併與交付。在擁有多個後端的網路中,每個後端會產出自己的 Bedrock 資源包(其合併後 Java 資源包的轉換版本)。代理外掛會:

  1. 每 5 秒輪詢一次每個後端的小型 HTTP 伺服器以取得 /bedrock.zip/mappings.json,優先使用搭配 If-None-Match 的強 ETag,同時保留對舊版後端的 If-Modified-Since 相容性。未變更的檔案會回傳 304,因此幾乎不耗頻寬。每個後端都會通報它實際綁定的確切 HTTP 連接埠,因此代理通常會自動連到正確的連接埠(請參閱後端 HTTP 連接埠解析)。
  2. 等待 inbox 狀態穩定——一旦相鄰兩次輪詢觀察到相同的檔案雜湊集合,就立即合併。
  3. 將每個後端的 Bedrock 資源包合併為單一的網路級資源包。
  4. 當存在物品對應時,將合併後的 Geyser 自訂對應檔複製到代理的 plugins/Geyser-*/custom_mappings/
  5. 在 Bedrock 用戶端連線時,透過 Geyser 的 SessionLoadResourcePacksEvent 提供合併後的資源包。

代理外掛只對 Bedrock 玩家有用。 網路上的 Java 資源包交付仍由各後端透過一般的 setResourcePack / addResourcePack API 處理——Java 用戶端會看到所在後端所選擇發送的資源包。若你的網路為純 Java,則不需要代理外掛。

設定——只有一個步驟(若你想要 Bedrock,再加上 Floodgate)

Floodgate

Bedrock 玩家要在代理上完成認證,就需要 Floodgate。但 RSPM 要把代理與其後端連結起來則需要它——純 Java 的網路完全可以在沒有 Floodgate 的情況下執行代理外掛。

如果 RSPM 首次在代理上啟動的當下,Floodgate 確實已安裝在該代理上,RSPM 會從 plugins/floodgate/key.pem 一次性地衍生出它的網路金鑰種子,讓原本就正常運作的既有網路在升級後仍保有相同的身份識別。在首次啟動之後,金鑰會存放在 RSPM 自己的 network-key 檔案中,key.pem 不會再被讀取。

ResourcePackManager.jar 複製到代理

只有一個 jar。你安裝在 Bukkit/Paper 後端上的 ResourcePackManager.jar,同時也是代理外掛——它在單一 shaded jar 中一併打包了 Velocity 與 BungeeCord/Waterfall 的實作,並會自動偵測它正在哪個平台上執行。沒有各平台分開的代理 jar 需要解壓。

如果你已經先啟動了後端、卻還沒把 RSPM 放上代理,你不必去翻找下載連結:每個位於代理之後、尚未取得金鑰的後端,都會在 plugins/ResourcePackManager/proxy-extension/ResourcePackManager.jar 預備一份與自身位元組完全相同的 jar 副本,並在主控台印出該確切路徑。複製那個檔案可以保證代理與後端絕不會處於不同版本。

將同一個 ResourcePackManager.jar 複製到代理的 plugins/ 資料夾:

代理軟體使用此 jar
VelocityResourcePackManager.jar
BungeeCordResourcePackManager.jar
Waterfall(Bungee 分支)ResourcePackManager.jar

你隨時可以在後端執行 /rspm status 來確認這一點;Proxy deployment 區段會印出 Network proxy jar: ResourcePackManager.jar 以及 Use the same jar on Bukkit/Paper, Velocity, and BungeeCord/Waterfall.

重新啟動代理。就這樣。

沒有必須編輯的設定,也沒有金鑰需要貼上。代理會在啟動時自行建立網路金鑰,並自動把它佈建給每個後端——請參閱下方的代理與後端如何建立連結。產生出來的代理 config.yml 只包含兩個選用設定,兩者都會在後文說明。

代理的第一次輪詢約在啟動後 2 秒觸發,之後每 5 秒一次。結合單一週期的穩定性閘門,當代理能看到至少一個已在產出內容的後端後,首次合併約在 7 秒後發佈。

代理與後端如何建立連結

以下所有流程都不需要任何設定。之所以記錄在此,是因為當網路沒有成功連結時,了解這個順序就等同於完成了整個診斷。

1. 代理建立金鑰。 啟動時它會依下列順序解析出唯一一個值:

  1. 位於代理外掛自身資料夾中、已儲存的 network-key 檔案——這是首次啟動之後每次啟動的穩定狀態;
  2. 若代理上存在 plugins/floodgate/key.pem,則從該檔案衍生出的一次性種子;
  3. 全新產生的隨機金鑰。

不論走到哪一個分支,結果都會寫入 network-key 並從此永久沿用。代理主控台會說明發生的是哪一種情況(Network key loaded ✓adopted from Floodgate key.pemNew network key generated)。若該檔案無法被寫入,代理會以 [ERROR] 等級記錄錯誤——這個狀態對當次啟動並不致命,但下次重啟會產生一把不同的金鑰,並悄無聲息地讓每個後端失去連結,所以請修正資料夾權限。

2. 代理把金鑰推送給每個後端。 只要有玩家連線到某個後端,代理就會透過 rspm:network 外掛頻道把金鑰送過去。方向是刻意如此的:後端在物理上無法主動索取,因為代理不會轉發玩家自己的用戶端從未註冊過的頻道上的外掛訊息。

3. 後端採用並保存它。 後端會把金鑰存入自己的 data.yml,並回報 Network key received from the proxy; this backend is now linked.。只有在後端尚未持有金鑰時才會接受授予——已建立連結的後端會記錄一則警告並保留現有金鑰,而不會讓某則訊息把它重新指向另一個網路。

使用現代轉發的 Velocity 上,授予會以代理 forwarding.secret 為金鑰的 HMAC 簽章,而設定為現代轉發的後端要求該簽章。在 BungeeCord、Waterfall 以及舊版轉發上,並沒有可用來簽章的共享密鑰,因此授予是未簽章的,並會以未簽章的形式被接受。

若某個後端走到了步驟 2 卻始終沒到步驟 3,它的金鑰來源會維持在 not set。這正是觸發 proxy-extension/ 預備機制與 Bedrock 專屬警告橫幅的狀態。

驗證是否運作

代理主控台

重啟後約 10 秒內(假設後端正在運行),你應該會看到:

[ResourcePackManager] Network key loaded ✓
[ResourcePackManager] Network key provisioning ready on rspm:network; backends are keyed as players connect.
[ResourcePackManager] NetworkSync starting (poll interval 5000 ms, network-http-offset 1 - endpoint announcements preferred, fallback HTTP port = mcPort + offset)
[ResourcePackManager] NetworkSync: inbox stabilized — merging 2 Bedrock zip(s) and 2 mappings file(s) across 2 backend(s).
[ResourcePackManager] Merged Bedrock pack published at .../merged/Bedrock.zip (sha1=...).
[ResourcePackManager] ✔ Network resource pack is now ready (... KB, sha1 ABCD1234)

在代理上執行 /rspm status

會印出一份快照:網路金鑰指紋、後端清單、各後端各路徑對 /bedrock.zip/mappings.json/rspm-update.jar 的擷取結果(200 / 304 / 404 / CONNECT_FAILED)、它已收到的端點通報、它能看見的中繼條目、連續空輪詢計數、合併後的 Bedrock 資源包與合併後的對應檔是否存在於磁碟上(含其大小)以及目前合併資源包的 SHA-1 前綴、network-http-offset 後備值、偵測到的 Geyser 外掛資料夾與已佈署的對應檔,還有代理上 Floodgate / Geyser 的存在狀態。Velocity 接受 resourcepackmanager.command.statusresourcepackmanager.*;BungeeCord 註冊的是確切的 resourcepackmanager.command.status 節點,權限外掛可透過萬用字元展開來滿足它。主控台可以執行此指令。輸出不會揭露任何機密(網路金鑰只會以簡短的單向雜湊指紋呈現,且不會印出任何認證 token),因此放寬授權是安全的。

在後端執行 /rspm status

Deploy mode 行應顯示 network-backendNetwork key fingerprint 應顯示一段簡短的雜湊——它必須與代理印出的指紋相符。Network key source 則告訴你這個後端是如何取得金鑰的:

來源行意義
provided by the proxy正常的已連結狀態。代理在玩家連線時授予了金鑰。
saved on this server在先前的啟動中就已取得金鑰(或是自行產生金鑰的獨立伺服器)。
adopted from Floodgate's key曾一次性地從此後端本機的 plugins/floodgate/key.pem 衍生。
not set — the proxy sends one when a player next connects here未連結。 可能是代理啟動後還沒有玩家連線過,也可能是代理上缺少 RSPM/該代理不受支援。

Bedrock 用戶端

透過 Bedrock 連線。應該會在進入世界前看到資源包下載提示。自訂物品會以其原本設計的模型顯示,而非顯示為單純的盔甲架。

設定參考

後端 plugins/ResourcePackManager/config.yml

網路模式為自動偵測——沒有 networkMode: true 旗標需要設定。偵測訊號(滿足任一即可):

  1. Floodgate 存在、Geyser-Spigot 不存在 — Bedrock-via-proxy 情境的最強訊號。
  2. spigot.yml: settings.bungeecord: true — 舊版 BungeeCord / Waterfall IP 轉發開關。
  3. paper-global.yml: proxies.velocity.enabled: true — 現代的 Velocity 轉發。

專為網路模式而言唯一重要的選項是 networkHttpOffset-v2,它控制代理會在每個後端輪詢的後備 HTTP 連接埠(即在後端通報其實際綁定的連接埠之前,代理所猜測的連接埠)。預設 1 幾乎適用於所有託管。完整的連接埠解析說明請參閱自我託管

正常運作下,每個後端會自動向代理通報其真實的 HTTP 連接埠(透過 magmaguy.com 端點註冊表),因此偏移量只會在啟動 / 失敗時作為後備被參考。請參閱下方的後端 HTTP 連接埠解析

代理 config.yml

代理外掛會在首次啟動時寫入一份最小化的預設設定。資料夾會因平台而異,因為每個代理都是從自己的外掛識別碼推導出該路徑:

代理軟體設定路徑
Velocityplugins/resourcepackmanager/config.yml
BungeeCord / Waterfallplugins/ResourcePackManager/config.yml

其中恰好包含兩個設定,兩者皆為選用:

# FALLBACK offset added to each backend's Minecraft port to derive the HTTP
# port this proxy will hit for /bedrock.zip and /mappings.json BEFORE that
# backend has announced its real ResourcePackManager HTTP port. Default 1.
# In normal operation the backend announces the exact port it bound, so this
# value is only used at startup or if announcement fails — but if it IS used,
# it should match each backend's networkHttpOffset-v2.
network-http-offset-v2: 1

# Installs and updates this universal ResourcePackManager.jar in the proxy's
# Geyser extensions folder, which is what makes custom Bedrock ENTITIES render.
# Default true. Setting it to false stops future installation and update
# staging; it does not delete an extension jar that is already installed —
# remove that by hand while Geyser is stopped.
geyser-extension-auto-install: true

後端上的對應項目是後端 config.yml 中的 networkHttpOffset-v2geyserExtensionAutoInstall。兩側是各自獨立的設定——在代理上關閉擴充功能安裝並不會同時關閉後端上的設定,反之亦然。

除了 config.yml 之外,代理外掛也會在同一個資料夾中寫入一個 network-key 檔案。那是產生出來的狀態,不是設定:請勿編輯它,也不要在不同的網路之間複製它。刪除它會讓代理在下次啟動時產生一把全新的金鑰,這會讓每個已佈建過的後端失去連結(每個後端都會保留舊金鑰,且不會採用替代金鑰)。只有在一種情況下複製它才是正確做法:兩個代理位於同一組後端之前,此時它們必須共用同一把金鑰。

代理端沒有 force-resource-pack 設定。強制接受資源包是後端側的決定(後端 config.yml 中的 forceResourcePack),因為代理外掛只處理 Bedrock 資源包交付——它從不發送 Java 資源包。若舊的代理 config.yml 中仍留有 force-resource-pack 行,它會直接被忽略,可以刪除。

刻意沒有 network-key 設定條目——可貼上的金鑰在預發行階段就已被淘汰,因為錯字會悄無聲息地破壞代理↔後端的連結,而且任何地方都不會出現錯誤訊息。金鑰是由代理建立、並自動佈建給後端的,詳見代理與後端如何建立連結

後端 HTTP 連接埠解析

代理需要知道要在每個後端的哪個 HTTP 連接埠上輪詢 /bedrock.zip/mappings.json。它會依下列順序解析該連接埠:

  1. 後端通報的端點(優先)。 每個後端會將它實際綁定的確切 HTTP 連接埠上傳到 magmaguy.com 端點註冊表,並以網路金鑰為鍵。在每次輪詢時,代理會刷新此清單,並依 Minecraft 連接埠(在可用時也含主機)將後端通報的連接埠與伺服器清單條目比對。這表示無論管理員在後端設定了明確的 selfHostPort,或其後端自動落在 mcPort + 1,都會以相同方式處理——代理會使用後端實際綁定的任何連接埠。
  2. mcPort + network-http-offset-v2(後備)。 僅在沒有可比對的通報時使用(例如在任何後端通報之前的首次輪詢,或端點註冊表短暫無法連線時)。這就是為什麼若你倚賴後備,兩邊的偏移量仍應一致。

代理刻意會以連接埠掃描後端作為後備——這在主機看來像是濫用行為。當直接擷取完全無法運作時,中繼路徑(見下文)才是根本的答案。

代理上的 /rspm status 會逐後端顯示所選的連接埠,以及它是來自通報或偏移量後備。

穩定性與合併節奏

代理會等待 inbox 狀態穩定後才進行合併:首次輪詢設定基準的檔案雜湊集合,下一次觀察到相同集合的輪詢便會觸發合併(單一週期的穩定性閘門)。在約 2 秒的初始延遲與 5 秒的輪詢間隔下,這表示首次合併會在代理能看到至少一個後端產出內容的約 7 秒後發生。後續合併僅在 inbox 檔案的 SHA-1 集合變更時才會重新壓縮,因此長時間的靜置期幾乎不耗成本。

後端會將其 bedrock.zip 寫入暫存檔後再原子化重新命名,因此 /bedrock.zip 路由一律提供完整的 zip——代理永遠不必防範讀到寫到一半的內容,這也是閘門只需單一週期而非兩個週期的原因。

直接擷取 vs 中繼回退

預設路徑是直接擷取:代理對每個後端發出 http://<backend-host>:<mcPort + offset><path> 的 HTTP GET 請求。

若代理無法直接連到後端的 HTTP 連接埠(在共享 / 代管 Minecraft 託管環境中常見,MC 連接埠對外開放但相鄰埠被防火牆擋掉),後端會將其 bedrock.zipmappings.json 推送到 magmaguy.com 上、以該網路命名空間(從網路金鑰衍生)區分的中繼端點。當直接擷取硬性失敗時,代理會從中繼端點列出並下載。

兩條路徑會餵入同一個合併步驟,因此操作員不需要選擇——直接擷取是優先選項(對 magmaguy.com 零頻寬成本),中繼會在需要時透明地接手。

中繼在伺服器端的 TTL 為 30 分鐘。後端每 25 分鐘推送一次以維持條目存活;乾淨關機會立即刪除條目,而非等到 TTL 過期。

常見問題疑難排解

某個後端始終取不到網路金鑰

症狀:後端上的 /rspm status 顯示 Network key source: not set — the proxy sends one when a player next connects here,而且後端主控台不斷重複:

[ResourcePackManager] This backend is behind a proxy but has no network key yet, so it is not linked to the proxy.
[ResourcePackManager] The proxy sends one automatically the first time a player connects to this server.

請依序檢查下列項目:

  1. 代理啟動之後,真的有人連線過那個後端嗎? 授予是搭著玩家連線一起送出的。一個還沒人造訪過的大廳伺服器,沒有金鑰是完全合理的。
  2. 代理上到底有沒有 RSPM? 後端正是為了這個情況,才會在 plugins/ResourcePackManager/proxy-extension/ResourcePackManager.jar 預備一份自身 jar 的副本。把它複製到代理的 plugins/ 資料夾並重新啟動代理。
  3. Velocity 現代轉發:後端的轉發密鑰與代理的一致嗎? 設定為現代轉發的後端會刻意拒絕未簽章或簽章錯誤的授予——這項檢查是唯一能阻止未授權代理為你的後端配發金鑰的機制。後端日誌會指出它遇到的是兩種情況中的哪一種。在兩側修正密鑰後,下一次玩家連線就會自動重試;兩邊都不需要重啟即可重新啟用。
  4. 這個代理是不受支援的代理嗎? 只有 Velocity 與 BungeeCord/Waterfall 會執行代理角色。

請注意 Floodgate 的 key.pem 已不再是這個流程的一部分。代理上沒有 plugins/floodgate/key.pem 是完全受支援的狀態——代理會改為自行產生金鑰。但 Bedrock 玩家若要連上代理,仍然需要 Floodgate。

兩個代理位於同一組後端之前

兩個代理必須提供相同的網路金鑰,否則每個後端只會與最先連上它的那個代理建立連結,並拒絕另一個(並記錄 A proxy offered a network key that differs from the one this backend already uses)。請將主要代理的 RSPM 資料夾中的 network-key 檔案複製到另一個代理的對應資料夾,然後重新啟動它。

約 20 秒後出現「No merged pack content」警告

在連續 4 次空輪詢週期後,代理會記錄一次性的多行警告,列出它輪詢過的每個後端、嘗試過的 URL,以及結果。該警告會說明最常見的修復方式:

  • 每個後端皆顯示 CONNECT_FAILED — 代理完全無法連到後端的 HTTP 連接埠。請檢查 velocity.toml / config.yml 中設定的位址是否為代理實際可達的位址(而非代理網路中無法解析的 Docker 內部名稱),並確認後端的 HTTP 連接埠在代理與後端之間是開放的。該警告會印出它為每個後端嘗試的確切 HTTP host:port,以及該連接埠是來自後端的通報或 mcPort + networkHttpOffset-v2 後備。若你無法開放該連接埠(代管託管),請參閱上方的中繼回退章節——後端應該會自動上傳到中繼。
  • 每個後端皆顯示 NOT_FOUND_404 — 後端正在運作但未產生 Bedrock 資源包。請在每個後端執行 /rspm status;Bedrock Pack 診斷區塊會告訴你原因(最常見:合併後的資源包中沒有可轉換的物品對應或實體套組,或首次混合週期尚未完成)。

該警告在每次「卡住」期間只會觸發一次。當至少一個後端開始重新回傳內容時,會記錄一行 NetworkSync: recovered

首次代理啟動時 Bedrock 玩家看不到自訂模型

Geyser 只在代理啟動時才會註冊其自訂物品表。如果代理在任何後端產出 Bedrock 資源包之前啟動,Geyser 會在空對應表的狀態下運行,並維持整個工作階段不變。

修復方式:在後端記錄了首次的 Merged Bedrock pack published 行之後,重新啟動代理一次。RSPM 會在每次代理啟動時預先佈署前次執行的對應檔,因此這個問題僅會在全新安裝時出現——之後的啟動都會在 Geyser 掃描前就準備好對應內容。

代理啟動時出現「Duplicate bedrock_identifier」警告

兩個後端為同一個基礎物品發出了相同的 Bedrock 識別碼。後寫入者勝出;若只需要其中一個後端提供該物品則無害。若兩個後端都應在同一個基礎物品下託管不同的自訂物品,請重新命名其中一個來源 Java 模型,使自動產生的雜湊值不同。

Bedrock 玩家已連線但看不到資源包

當有 Bedrock 工作階段在 RSPM 沒有可用資源包的情況下載入時,代理會向所有線上 Java 玩家發出一則聊天橫幅:

⚠ [RSPM] Bedrock player Alice connected before the resource pack was ready — they're seeing plain armor stands instead of custom models. Tell them to disconnect and reconnect; the pack will load on their next session. (Cause: ...)

Bedrock 玩家本人也會收到一則彈窗,代理主控台也會收到橫幅。若你需要更深入調查,可啟用除錯串流(Velocity 與 BungeeCord 皆可):

/rspm debug bedrock on

這會開啟 GeyserBinder 發出的詳盡 [RSPM-BedrockDebug] 日誌行。重現問題後,再關閉它:

/rspm debug bedrock off

此設定會在代理重啟時重置為關閉,因此不會意外被遺留為開啟。

在網路上更新 RSPM

每個後端與代理使用的都是同一個 jar,因此請讓所有元件保持在相同版本。

手動的做法是:升級後端 jar,把同一個 ResourcePackManager.jar 重新複製到代理的 plugins/ 資料夾,然後重新啟動代理。

RSPM 也可以自行完成代理那一半的工作。每個後端會透過一條經過認證的路由(/rspm-update.jar,由從共享網路金鑰衍生出的 token 保護——金鑰本身絕不會被傳輸)把它的通用外掛 jar 提供給代理。代理會驗證所提供的檔案確實是一個完整的通用 RSPM jar,其各平台描述檔版本相符且具備預期的進入點,拒絕降級,並在替換任何檔案之前,比對預備好的位元組與所宣告的大小及 SHA-256。它會為代理外掛預備同一個 jar,而在偵測到代理端託管的 Geyser 時,也會預備其內附的 Geyser 擴充功能;這些檔案會在代理關機時套用,先前的檔案則保留為回溯用副本。

這是一道經過認證的網路信任邊界,而不是針對 Nightbreak 的獨立來源驗證:任何已取得共享網路金鑰佈建的後端,都被信任可以提供結構有效、且版本相同或更新的 RSPM jar。請保護好那把金鑰,並將所有共用它的後端都視為受信任的基礎設施。

因此實務上,更新後端再重新啟動代理通常就已足夠——代理應該已經為自己預備好相符的 jar 了。被拒絕的更新會記錄 Rejected backend-offered ResourcePackManager update: ... 並附上原因。

尚未支援的項目

  • 透過代理外掛在網路上提供 Java 資源包。 Java 用戶端會直接透過一般 API 從各後端接收資源包。代理端沒有 Java 資源包混合器。
  • 跨後端的 Java 資源包合併。 每個後端的 Java 資源包是獨立的。若玩家切換後端,會收到新後端的資源包。
  • 網路金鑰的即時輪替。 後端只會採用金鑰一次,且不會接受來自訊息的替代金鑰。若要輪替,必須刪除代理的 network-key 檔案,並從每個後端的 data.yml 中清除 networkKey,然後重新啟動所有元件。