リソースパックのセルフホスト
ResourcePackManagerは自前の小さなHTTPサーバーを同梱しています。autoHost: true(既定)と preferSelfHost: true(既定)の場合、プラグインはマージされたパックをMinecraftサーバーと同じJVMからホストしようとします — 外部ファイルホストも、別のWebサーバーも、手動でのURL貼り付けも不要です。
このページでは、そのセルフホスト経路がどう動くか、健全性チェックが何をするか、ポートとホスト名がどう選ばれるか、既定では合わないセットアップのときに何を設定すればよいかを説明します。
RSPMの前にHTTPSリバースプロキシを置き、配信を自動化したままにする場合は、後述の selfHostExternalUrl を使います。autoHost: false は、別のシステムがホスティングとプレイヤーへの配信の両方を担当する場合にのみ使ってください。
配信判定ツリー
プレイヤーが参加したとき、RSPMは次の優先順位で配信URLを選びます:
通常の自動配信には autoHost: true が必要です。autoHost: false の場合、明示的に selfHostForce: true を指定したときだけURLを送信します。
selfHostForce: true— プローブやリモートアップロードを行わず、セルフホストを直接試します。主にこの経路のテスト用です。autoHostとselfHostEnabledを上書きしますが、URL検証とHTTPリスナーの起動には成功する必要があります。preferSelfHost: trueかつselfHostEnabled: true: プロキシのバックエンドも含め、以下の確認を行ってセルフホストを試します。確認に失敗するとリモートホストへ切り替えます。- それ以外 —
https://magmaguy.com/rsp/のパックを再利用するかアップロードし、そのURLを通知します。初期化、SHA1検証、アップロードのいずれかが失敗すると、selfHostEnabled: trueであれば検証付きセルフホストを試します。SESSION_NOT_FOUNDはリモートセッションも消去し、後の試行で再初期化できるようにします。自動フォールバックでもセルフホスト優先時と同じ検証を行い、両経路が失敗した場合は新しい配信URLを通知しません。
リモートホストが受け付けるJavaパックは50,000 KiB(51,200,000バイト)までです。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以降を要求します。
3つの健全性チェック
RSPMは自動セルフホストを選択する前に、次のチェックを順番に実行します。リモートホストの失敗後のフォールバックも対象です。省略できるのは selfHostForce: true の場合だけです。
Layer 1 — 解決された外部ホストのヒューリスティックチェック
解決されたホスト(後述の「外部ホスト検出」を参照)がRFC1918(10.*、172.16-31.*、192.168.*)、ループバック(127.* または localhost)、リンクローカル(169.254.*)、未指定(0.0.0.0)の場合はセルフホストを除外します。IPv6の未指定、ループバック、リンクローカル、サイトローカル、ユニークローカルも拒否します。これはホスト文字列のヒューリスティック検査であり、ホスト名は以下のダウンロード検証にも合格する必要があります。
これはとてもよくある「ipify検索に失敗して、LAN IPにフォールバックした」失敗モードを捕捉します。
Layer 2 — ローカルと通知URLのダウンロード
RSPMはバイト範囲を指定したGETを、まず http://127.0.0.1:<port>/rspm.zip、次にプレイヤーへ渡す正確なURLに送信します。先頭の最大1 KiBをローカルパックと比較します。HTTP 200または206を受け付け、報告された長さが一致し、206応答では期待した Content-Range が必要です。リダイレクトは拒否します。以下を検出します:
- ポートバインドの衝突(選んだポートに他のものがいる)
- パックファイルの欠落(ルートは登録されているがzipがまだディスクにない)
- 間違ったルート、HTMLエラーページ、異なるパックのバイト
- NATループバックの障害など、サーバー自身が通知URLからダウンロードできない状態
各接続と読み取りのタイムアウトは3秒で、サンプルの読み取りには別途3秒の期限があります。限定されたサンプルの検証であり、クライアントによる完全なダウンロードではありません。
Layer 3 — 外部到達性プローブ
通知されたURLを magmaguy.com ホスターの POST /rsp/probe にPOSTします。ホスターは公開された視点からそのURLを取得し(SSRFガードとタイトなタイムアウト付き)、到達可能だったかを報告します。
これは本番で最もよくある失敗モードを捕捉します:サーバーは公開IPを持っているが、HTTPポートがルーターやファイアウォールで転送されていない、というケースです。Layer 2は通る(サーバーは 127.0.0.1 で応答する)が、本当のクライアントはパックをダウンロードできません。
プローブ結果に対する判定ポリシー:
- reachable=trueかつHTTP 200または206 → 公開ネットワーク上のプローブからURLに到達できました。セルフホストを選択します。
- reachable=falseまたは別のHTTPステータス → 検証失敗です。候補のJava URLを取り下げ、magmaguy.comでのリモートホストを試します。ネットワークモードでは、プロキシが成果物を取得できるようバックエンドのHTTPリスナーを維持します。
- プローブ通信自体が失敗(IOException)、またはプローブクライアントを利用できない → 到達性は未検証です。リモートホストを試します。プローブへの接続失敗はアップロードも失敗する証拠ではありません。自動フォールバックでもこの検証を省略できません。
チェックの限界
通知URLからのダウンロードにより、サーバー自身のネットワークからのNATループバック障害を検出するようになりました。ただし、すべてのプレイヤーのネットワークからの到達性や、Minecraftクライアントでの完全なダウンロード成功までは証明できません。実際のクライアントで全体のダウンロードとパックの受け入れを確認し、公開アクセスの確認には別の外部ネットワークを使ってください。
ホストマシンから手早くテストしたい場合は、preferSelfHost: false にしてリモートフォールバックを使うか、携帯回線などの外部ネットワークから公開URLをテストしてください。恒久的なセルフホスト構成にするなら、スプリットホライズンDNS(同じ公開ホスト名が、ネットワーク内部ではサーバーのLANアドレスに解決される)を使ってください。selfHostExternalHost を 127.0.0.1 に設定してはいけません:ループバックやプライベートホストは公開ホストの健全性チェックで拒否され、外部クライアントには配信できません。
ポート解決
2つの設定が相互作用します:
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との衝突
ホスティングが既定でRCONを MCポート + 1 で有効化している場合、ポート衝突を避けるためオフセット2または3を選んでください。server.properties の rcon.port= を確認してください。
バージョン管理された設定キー
config.yml のキー名は正確に networkHttpOffset-v2 です。v1は networkHttpOffset で既定値100だったため、ホストの割り当て外にリスナーが設定される場合がありました。v2の既定値は 1 ですが、そのポートも利用可能で到達できる必要があります。
v1からアップグレードする場合、死んだv1キーは手動でクリーンアップするまで設定ファイルに無害な遺物として残ります — RSPMは意図的にそれを読みません。
外部ホスト検出
selfHostExternalHost はクライアントがURLで見るホスト名を制御します。空(既定)のままにすると、次の優先順位で自動検出します:
- api.ipify.org / checkip.amazonaws.com — このホストの公開IPv4を返します。
/rspm reloadごとに1回キャッシュされるので、IPサービスを叩きすぎることはありません。 Bukkit.getIp()— サーバーのバインドアドレス。非空かつ0.0.0.0でない場合に使用されます。通常はLANアドレスです。InetAddress.getLocalHost()— ベストエフォート。localhost— 最終フォールバック。ボックスの外のクライアントはここに到達できません。
自動検出がルーティング不可なアドレスに着地し、preferSelfHost: true の場合、Layer 1のヒューリスティックチェックが失敗し、プラグインはリモートホスティングに切り替えます。
最も信頼できるセルフホストセットアップのためには、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リスナーを実行します。この設定は証明書のインストールやWebサーバーの構成を行いません。
指定した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は通常の起動時、ホスティングについて意図的に1行だけを出力します — 経緯ではなく結果です:
[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>
この行は、配信経路が新たに初期化されるたびに1回出力されます。プレイヤーの再試行やキープアライブのティックでは出力されません。パックが変わっていないリロードでは、新しい結果を出力する代わりに既存のホスティング登録を再利用できます。
到達性チェックの失敗は詳細レベルで記録されます。 例:Self-host check: local pack link is not public. This is OK.。ホストとlocalhostのチェックは This is OK. で終わります。通知URLからのダウンロードと外部検証は、この末尾の文を付けずに失敗を通知します。無効なURL設定、リスナー起動失敗、リモート通信失敗では警告が出ることがあります。チェックの失敗だけではリモートへの切り替え成功を示しません。最終的な配信状態を確認してください。
判断の連鎖全体 — どのチェックが失敗したか、プローブURL、理由コード、ステージングされた各パックとマージされた各クラスター — を見るには、次を実行します:
/rspm verbose on
そして /rspm reload を実行します。ホスティングに関するバグ報告を出す前に入れるべきスイッチです。このコマンドは config.yml に verboseLogging: true を書き込み、設定は再起動をまたいで保持されるため、終わったら /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 を返せます。アップデート用ルートは共有ネットワークキーから導出したベアラートークンで別途保護され、有効なアップデートjarを提供できる場合にのみ利用できます。
セルフホストが有効か確認する
/rspm status には次が表示されます:
Active delivery: SELF-HOSTED— セルフホストが使用中Active delivery: REMOTE (magmaguy.com)— リモート自動ホストが使用中URL: ...— クライアントが実際に見るURLResolved external host—selfHostExternalHostが何に解決されたかPublic IP (auto-detected)— ipify/AWS が何を返したか(あれば)selfHostPort— 自動か明示か、および解決された値
セルフホストを期待していたのにリモートになっている場合は、/rspm status を見てください — 起動ログは設計上、自己修復されたプローブ失敗について沈黙します。どの健全性チェックがなぜ失敗したかを見るには、/rspm verbose on と /rspm reload を実行してください。
よくある間違い
- プローブ成功を完全なクライアントテストとみなす — ローカルサンプルと公開プローブが確認するのは特定のネットワーク経路です。実際のプレイヤーで全体のダウンロードとパックの受け入れを確認してください。強制セルフホストはこれらの検証をすべて省略します。
networkHttpOffset-v2をホスティングプロバイダーのポート範囲を超えてバンプする — 症状は、プロキシ側でサイレントなCONNECT_FAILEDが永遠に続く、というものです。バックエンドは実際にバインドしたポートをプロキシに通知しますが、HTTPサーバーは依然として到達可能なポートにバインドする必要があり、プロキシも依然としてそこに到達できる必要があります。mcPort + offsetがコンテナの割り当てポート帯域の外に着地すると、通知の有無にかかわらずバインド/ファイアウォールが失敗します。オフセットを上げる前に、そのポートがコンテナの割り当て帯域内にあることを確認してください。