Самостоятельный хостинг ресурс-пака
ResourcePackManager поставляется с собственным небольшим HTTP-сервером. Когда autoHost: true (по умолчанию) и preferSelfHost: true (по умолчанию), плагин пытается хостить собранный пак из той же JVM, что и сам Minecraft-сервер — без внешнего файлового хоста, без отдельного веб-сервера, без ручной вставки URL.
Эта страница описывает, как работает этот путь самостоятельного хостинга, что делают проверки исправности, как выбирается порт и hostname, и что настраивать, когда значения по умолчанию вам не подходят.
Если вместо этого вы хотите хостить zip через свой собственный существующий веб-сервер вне RSPM, см. раздел про autoHost: false на странице устранения неполадок.
Дерево решений по доставке
Когда игрок подключается, RSPM выбирает URL для доставки по такому приоритету:
selfHostForce: true— прямой self-host, без проверок, без удалённой загрузки. Главным образом для тестирования self-host пути. Обходит все остальные флаги.preferSelfHost: trueИselfHostEnabled: trueИ не в сетевом режиме — попробовать self-host с тремя проверками исправности (см. ниже). Если все проходят, фиксируется self-host. Если хоть одна не прошла, откат на удалённый путь.- Иначе — загрузить пак на
https://magmaguy.com/rsp/и анонсировать этот URL. Если загрузка не удалась или проверка SHA1 сообщаетSESSION_NOT_FOUND, откат на self-host (при условииselfHostEnabled: true).
Как только URL получен, RSPM использует multi-pack API Minecraft на 1.20.3+ (чтобы сосуществовать с другими паками, отправляемыми сервером) и старый метод одиночного пака на более старых версиях.
Три проверки исправности
Когда preferSelfHost: true, RSPM выполняет эти проверки по порядку перед тем, как зафиксировать self-host:
Уровень 1 — эвристическая проверка разрешённого внешнего хоста
Если разрешённый хост (см. «Определение внешнего хоста» ниже) — это RFC1918 (10.*, 172.16-31.*, 192.168.*), loopback (127.*), link-local (169.254.*) или unspecified (0.0.0.0), self-host никак не сможет работать для интернет-клиентов. Сразу пропустить и использовать удалённый хостинг.
Это ловит очень распространённый сценарий «ipify-запрос не удался, откатился на LAN-IP».
Уровень 2 — локальная самопроверка
Открывается HEAD-запрос на http://127.0.0.1:<port>/rspm.zip, проверяется HTTP 200 и непустое тело. Ловит:
- коллизии при привязке порта (что-то другое уже на выбранном порту)
- отсутствующий файл пака (маршрут зарегистрирован, но zip ещё не на диске)
- баги регистрации маршрутов
Агрессивный таймаут (3 с), чтобы медленная проверка не затягивала загрузку.
Уровень 3 — проверка внешней доступности
POST анонсированного URL на POST /rsp/probe на хостере magmaguy.com. Хостер скачивает URL с публичной vantage point (с SSRF-защитой и жёстким таймаутом) и отчитывается, доступен ли он.
Ловит наиболее распространённую боевую проблему: у сервера есть публичный IP, но HTTP-порт не проброшен на роутере или файрволе. Уровень 2 проходит (сервер отвечает на 127.0.0.1), но ни один реальный клиент никогда не сможет скачать пак.
Политика принятия решений по результатам проверки:
- reachable=true → внешние клиенты могут достучаться до нашего URL. Фиксируется self-host.
- reachable=false → внешние клиенты не могут. Сворачивается self-host, используется удалённый хостинг (который универсально доступен с magmaguy.com).
- сама связь проверки не удалась (IOException) → не удалось проверить никак. По умолчанию оставляется self-host: отказывать из-за невозможности проверки было бы парадоксально, потому что удалённому пути magmaguy.com тоже нужен.
Что проверки всё ещё не обнаруживают
Граничный случай NAT-hairpin, когда порт открыт в публичный интернет (Уровень 3 проходит), но собственный роутер оператора не делает loopback трафика обратно изнутри LAN. Внешние клиенты работают, но оператор, тестирующий с той же машины, получает отказ.
Обходной путь на сейчас: при тестировании с хост-машины со сломанным hairpin на роутере выставьте preferSelfHost: false ЛИБО selfHostExternalHost: 127.0.0.1.
Разрешение порта
Две настройки взаимодействуют:
selfHostPort— явный порт (любое положительное целое) или-1(по умолчанию) для авто-вывода.networkHttpOffset-v2— учитывается только когдаselfHostPort = -1. Прибавляется к порту Minecraft-сервера. По умолчанию1.
По умолчанию selfHostPort: -1 + networkHttpOffset-v2: 1, поэтому:
- MC порт 25565 → HTTP порт 25566
- MC порт 25584 → HTTP порт 25585
Это автоматически разводит HTTP-порты по бэкендам в одноузловой сети без какой-либо административной настройки — у каждого бэкенда уже есть уникальный MC-порт, поэтому каждый получает уникальный HTTP-порт.
Почему смещение 1?
Большинство shared / managed Minecraft-хостингов (панели на базе Pterodactyl и т. п.) выделяют узкий диапазон портов на контейнер (часто всего 4–10 портов). Большие смещения уходят за границы диапазона, и файрвол хостинга молча блокирует HTTP-порт. Смещение 1 помещается даже в самые узкие выделения.
Самостоятельные администраторы с полным контролем над портами могут увеличить это до любого значения, но если вы держите прокси-сеть, вы обязаны также изменить network-http-offset-v2 прокси, чтобы совпадало.
Осторожно: коллизия с RCON
Если ваш хостинг включает RCON по умолчанию на MC port + 1, выберите смещение 2 или 3 во избежание коллизии портов. Проверьте server.properties на rcon.port=.
Версионированный ключ конфига
Настройка в config.yml буквально называется networkHttpOffset-v2. Ключ v1 был networkHttpOffset с дефолтом 100 — этот дефолт ломался на shared / managed-хостингах, где каждый игровой контейнер получает всего ~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()— bind-адрес сервера, когда непустой и не0.0.0.0. Обычно LAN-адрес.InetAddress.getLocalHost()— best-effort.localhost— последний резерв. Клиенты вне коробки сюда не достучатся.
Если авто-определение приводит к не-маршрутизируемому адресу и preferSelfHost: true, эвристическая проверка Уровня 1 проваливается, и плагин переключается на удалённый хостинг.
Для максимально надёжной настройки self-host выставьте selfHostExternalHost явно на ваше публичное имя хоста (например, play.example.com). Это полностью пропускает определение через ipify/AWS, и проверка запускается против явного значения.
Справочник по конфигурации
# Можно ли вообще использовать встроенный HTTP-сервер как путь доставки.
# Когда false, self-host никогда не пробуется независимо от других флагов.
selfHostEnabled: true
# Порт для self-host HTTP-сервера.
# -1 (по умолчанию) = авто-вывод: HTTP порт = порт Minecraft-сервера + networkHttpOffset-v2.
# Установите любое положительное значение, чтобы принудительно задать порт.
selfHostPort: -1
# Прибавляется к порту Minecraft-сервера, когда selfHostPort = -1.
# По умолчанию 1 (MC 25565 -> HTTP 25566). Должно совпадать с network-http-offset-v2 прокси
# в прокси-сетях.
networkHttpOffset-v2: 1
# Публичное имя хоста или IP, которые клиенты используют для доступа к self-host серверу.
# Оставьте пустым для авто-определения (api.ipify.org / checkip.amazonaws.com).
selfHostExternalHost: ""
# Пробовать self-host СНАЧАЛА с тремя проверками исправности, откатываться на удалённый при отказе.
# Когда false, использовать старый порядок: сначала удалённая загрузка, self-host только при её отказе.
preferSelfHost: true
# Пропустить ВСЕ другие пути доставки и принудительно использовать self-host.
# Обходит проверки исправности И удалённую загрузку. Главным образом для тестирования.
selfHostForce: false
Маршруты бэкенд-HTTP-сервера
Встроенный HTTP-сервер всегда раздаёт zip пака по адресу:
http://<host>:<port>/rspm.zip
В сетевом режиме (RSPM находится за Velocity / BungeeCord / Waterfall прокси) регистрируются два дополнительных маршрута для опроса прокси-плагином:
http://<host>:<port>/bedrock.zip # Bedrock-преобразованный пак
http://<host>:<port>/mappings.json # JSON кастомных маппингов Geyser
Все три маршрута file-backed: маршрут читает файл свежим при каждом запросе, поэтому пересборка, переписывающая тот же путь zip, подхватывается автоматически без перезапуска HTTP-сервера. Bedrock-маршруты поддерживают If-Modified-Since, поэтому опросчик прокси платит примерно нулевой трафик, когда ничего не изменилось. Все маршруты корректно возвращают 404, когда подлежащий файл отсутствует (например, до завершения первой сборки).
Проверка, что self-host активен
/rspm status показывает:
Active delivery: SELF-HOSTED— self-host используетсяActive delivery: REMOTE (magmaguy.com)— удалённый авто-хостинг используетсяURL: ...— фактический URL, который увидят клиентыResolved external host— во что разрешилосьselfHostExternalHostPublic IP (auto-detected)— что вернули ipify/AWS, если что-тоselfHostPort— авто vs явный, и разрешённое значение
Если вы ожидали self-host, но видите удалённый, лог загрузки объясняет, какая проверка исправности не прошла и почему.
Типичные ошибки
- Установка
selfHostPortв произвольное значение и забывание про это на прокси — в сетевом режиме прокси используетmcPort + network-http-offset-v2для вычисления HTTP-порта каждого бэкенда. ЯвныйselfHostPortпереопределяет авто-вывод, но прокси про это не знает, поэтому всё равно будет опрашиватьmcPort + offset. ОставьтеselfHostPort: -1в сетевом режиме, если только не готовы координировать. - Доверять проверке Уровня 3 при сломанном hairpin на роутере — проверка идёт с vantage point magmaguy.com, поэтому она не может поймать случай, когда внешние клиенты работают, но собственная LAN оператора не делает loopback. Тестируйте с телефона по сотовой, если не уверены.
- Увеличение
networkHttpOffset-v2за пределы диапазона портов вашего хостинг-провайдера — симптом — молчаливый CONNECT_FAILED навсегда на стороне прокси. Проверьте, чтоmcPort + offsetнаходится в выделенной полосе портов вашего контейнера, прежде чем увеличивать смещение.