Pular para o conteúdo principal

Self-hosting do Resource Pack

O ResourcePackManager inclui seu próprio pequeno servidor HTTP. Quando autoHost: true (o padrão) e preferSelfHost: true (o padrão), o plugin tenta hospedar o pack unificado a partir da mesma JVM do próprio servidor Minecraft — sem host de arquivos externo, sem servidor web separado, sem colar URL manualmente.

Esta página cobre como esse caminho de self-host funciona, o que as checagens de sanidade fazem, como a porta e o hostname são escolhidos, e o que configurar quando os padrões não servirem para a sua configuração.

Se, em vez disso, você quiser hospedar o zip por meio do seu próprio servidor web existente, fora do RSPM, consulte a seção sobre autoHost: false na página de Solução de Problemas.

Árvore de Decisão de Entrega

Quando um jogador entra, o RSPM escolhe uma URL de entrega usando esta precedência:

  1. selfHostForce: true — direto para o self-host, sem probes, sem upload remoto. Principalmente para testar o caminho de self-host. Ignora todas as outras flags.
  2. preferSelfHost: true E selfHostEnabled: true E não está em modo de rede — tenta o self-host com três checagens de sanidade (veja abaixo). Se todas passarem, compromete-se com o self-host. Se alguma falhar, recorre ao caminho remoto.
  3. Caso contrário — faz upload do pack para https://magmaguy.com/rsp/ e anuncia essa URL. Se o upload falhar ou a checagem de SHA1 reportar SESSION_NOT_FOUND, recorre ao self-host (assumindo selfHostEnabled: true).

Uma vez de posse de uma URL, o RSPM usa a API de múltiplos packs do Minecraft no 1.20.3+ (podendo coexistir com outros packs enviados pelo servidor) e o método antigo de pack único em versões anteriores.

As Três Checagens de Sanidade

Quando preferSelfHost: true, o RSPM executa estas checagens em ordem antes de se comprometer com o self-host:

Camada 1 — Checagem heurística no host externo resolvido

Se o host resolvido (veja "Detecção de Host Externo" abaixo) for RFC1918 (10.*, 172.16-31.*, 192.168.*), loopback (127.*), link-local (169.254.*) ou não especificado (0.0.0.0), o self-host não tem como funcionar para clientes da internet. Pula imediatamente e usa a hospedagem remota.

Isso captura o modo de falha muito comum de "a busca pelo ipify falhou e recorreu ao IP de LAN".

Camada 2 — Self-probe em localhost

Abre uma requisição HEAD para http://127.0.0.1:<port>/rspm.zip, verifica HTTP 200 e corpo não vazio. Captura:

  • colisões de bind de porta (algo mais está na porta escolhida)
  • arquivo de pack ausente (a rota está registrada mas o zip ainda não está no disco)
  • bugs de registro de rota

Tem timeout agressivo (3 s) para que um probe lento não arraste o boot.

Camada 3 — Probe de alcançabilidade externa

Faz POST da URL anunciada para POST /rsp/probe no hoster do magmaguy.com. O hoster busca a URL a partir de um ponto de observação público (com proteções contra SSRF e um timeout apertado) e reporta de volta se ela está acessível.

Captura o modo de falha de produção mais comum: o servidor tem um IP público mas a porta HTTP não está encaminhada no roteador ou firewall. A Camada 2 passa (o servidor responde em 127.0.0.1), mas nenhum cliente real conseguiria baixar o pack.

Política de decisão sobre os resultados do probe:

  • reachable=true → clientes externos conseguem alcançar nossa URL. Compromete-se com o self-host.
  • reachable=false → clientes externos não conseguem. Desmonta o self-host e usa a hospedagem remota (que é universalmente acessível a partir do magmaguy.com).
  • a própria comunicação do probe falha (IOException) → não foi possível verificar em nenhum sentido. Por padrão, mantém o self-host: recusá-lo por incapacidade de fazer o probe seria paradoxal, pois o caminho remoto também precisa do magmaguy.com.

O que as checagens ainda não detectam

O caso de borda do NAT-hairpin, em que a porta está aberta para a internet pública (a Camada 3 passa) mas o próprio roteador do operador não faz o tráfego retornar de dentro da LAN. Clientes externos funcionam, mas o operador testando a partir da mesma máquina falha.

Solução temporária por enquanto: ao testar a partir da máquina host com um roteador sem suporte a hairpin, defina preferSelfHost: false OU selfHostExternalHost: 127.0.0.1.

Resolução de Portas

Duas configurações interagem:

  • selfHostPort — porta explícita (qualquer inteiro positivo) ou -1 (padrão) para auto-derivação.
  • networkHttpOffset-v2 — só é consultado quando selfHostPort = -1. Adicionado à porta do servidor Minecraft para derivar a porta HTTP. Padrão 1. (Em redes com proxy, esse mesmo valor também é o palpite de fallback do proxy para a porta HTTP de um backend — veja abaixo.)

O padrão é selfHostPort: -1 + networkHttpOffset-v2: 1, então:

  • porta MC 25565 → porta HTTP 25566
  • porta MC 25584 → porta HTTP 25585

Isso escalona automaticamente as portas HTTP entre backends em uma rede de host único sem nenhuma configuração do admin — cada backend já tem uma porta MC única, então cada um recebe uma porta HTTP única.

Por que offset 1?

A maioria das hospedagens compartilhadas / gerenciadas de Minecraft (painéis baseados em Pterodactyl, etc.) aloca uma faixa estreita de portas por container (geralmente apenas 4 a 10 portas). Offsets maiores caem fora da faixa e o firewall do host bloqueia silenciosamente a porta HTTP. O offset 1 cabe até em alocações bem apertadas.

Admins que fazem self-host com controle total de portas podem aumentar isso para qualquer valor. Em uma rede com proxy, o backend anuncia automaticamente ao proxy a porta HTTP exata em que se vinculou, então o proxy acompanha mesmo que você mude o offset ou defina um selfHostPort explícito. Aumentar o network-http-offset-v2 do proxy para coincidir só importa como fallback para a breve janela antes de um backend ter anunciado (ou se o anúncio não consegue alcançar o proxy).

Atenção: colisão com RCON

Se o seu host habilita RCON por padrão em porta MC + 1, escolha o offset 2 ou 3 para evitar uma colisão de portas. Verifique rcon.port= no server.properties.

Chave de config versionada

A configuração no config.yml se chama literalmente networkHttpOffset-v2. A chave v1 era networkHttpOffset, com padrão 100 — esse padrão quebrava em hospedagens compartilhadas / gerenciadas, onde cada container de jogo recebe apenas ~4 a 10 portas consecutivas; MC + 100 caía fora da faixa, o servidor HTTP se vinculava internamente mas o firewall do host descartava o tráfego externo, e o proxy recebia um CONNECT_FAILED silencioso para sempre. A v2 vem com padrão 1, então MC + 1 fica bem dentro até da alocação de container mais estreita.

Se você atualizar a partir da v1, a chave v1 morta fica na sua config como um artefato inofensivo até você limpá-la — o RSPM intencionalmente não a lê.

Detecção de Host Externo

selfHostExternalHost controla qual hostname os clientes veem na URL. Deixe vazio (padrão) para auto-detecção nesta ordem de prioridade:

  1. api.ipify.org / checkip.amazonaws.com — retorna o IPv4 público deste host. Cacheado uma vez por /rspm reload para que os serviços de IP não sejam sobrecarregados.
  2. Bukkit.getIp() — o endereço de bind do servidor, quando não vazio e não 0.0.0.0. Geralmente um endereço de LAN.
  3. InetAddress.getLocalHost() — melhor esforço.
  4. localhost — fallback de último recurso. Clientes fora da máquina não alcançarão isso.

Se a auto-detecção cair em um endereço não roteável e preferSelfHost: true, a checagem heurística da Camada 1 falha e o plugin muda para a hospedagem remota.

Para a configuração de self-host mais confiável, defina selfHostExternalHost explicitamente com o seu hostname público (por exemplo, play.example.com). Isso pula a detecção via ipify/AWS por completo e o probe roda contra o valor explícito.

Referência de Configuração

# Se o servidor HTTP integrado pode ser usado como caminho de entrega.
# Quando false, o self-host nunca é tentado, independentemente das outras flags.
selfHostEnabled: true

# Porta do servidor HTTP de self-host.
# -1 (padrão) = auto-derivar: porta HTTP = porta do servidor Minecraft + networkHttpOffset-v2.
# Defina qualquer valor positivo para forçar uma porta explícita.
selfHostPort: -1

# Adicionado à porta do servidor Minecraft quando selfHostPort = -1.
# Padrão 1 (MC 25565 -> HTTP 25566). Em uma rede com proxy, isso é apenas um FALLBACK:
# o backend anuncia ao proxy a porta HTTP exata em que efetivamente se vinculou, então
# você não precisa mais fazer isso coincidir com o network-http-offset-v2 do proxy.
networkHttpOffset-v2: 1

# Hostname ou IP público que os clientes usam para alcançar o servidor de self-host.
# Deixe vazio para auto-detecção (api.ipify.org / checkip.amazonaws.com).
selfHostExternalHost: ""

# Tenta o self-host PRIMEIRO com três checagens de sanidade, recorre ao remoto se alguma falhar.
# Quando false, usa a ordem legada: upload remoto primeiro, self-host só em caso de falha de upload.
preferSelfHost: true

# Pula TODOS os outros caminhos de entrega e força o self-hosting.
# Ignora as checagens de sanidade E o upload remoto. Principalmente para testes.
selfHostForce: false

Rotas do Servidor HTTP do Backend

O servidor HTTP integrado sempre serve o zip do pack em:

http://<host>:<port>/rspm.zip

Em modo de rede (o RSPM está por trás de um proxy Velocity / BungeeCord / Waterfall), duas rotas adicionais são registradas para o plugin do proxy buscar:

http://<host>:<port>/bedrock.zip   # o pack convertido para Bedrock
http://<host>:<port>/mappings.json # o JSON de custom-mappings do Geyser

As três rotas são respaldadas por arquivos: a rota lê o arquivo atualizado a cada requisição, então um re-mix que reescreve o mesmo caminho de zip é detectado automaticamente sem reiniciar o servidor HTTP. As rotas Bedrock suportam If-Modified-Since, então o poller do proxy paga praticamente zero de banda quando nada mudou. Todas as rotas retornam 404 de forma limpa quando o arquivo subjacente está ausente (por exemplo, antes da primeira mescla ser concluída).

Verificando se o Self-host Está Ativo

/rspm status mostra:

  • Active delivery: SELF-HOSTED — o self-host está em uso
  • Active delivery: REMOTE (magmaguy.com) — o auto-host remoto está em uso
  • URL: ... — a URL real que os clientes verão
  • Resolved external host — para o que selfHostExternalHost resolveu
  • Public IP (auto-detected) — o que o ipify/AWS reportou, se algo
  • selfHostPort — automático vs explícito, e o valor resolvido

Se você esperava self-host mas vê remoto, o log de boot explica qual checagem de sanidade falhou e por quê.

Erros Comuns

  • Confiar no probe da Camada 3 com um roteador sem suporte a hairpin — o probe roda a partir do ponto de observação do magmaguy.com, então não consegue capturar o caso em que clientes externos funcionam mas a própria LAN do operador não faz o tráfego retornar. Teste a partir de um celular no dados móveis se estiver em dúvida.
  • Aumentar o networkHttpOffset-v2 para além da faixa de portas do seu provedor de hospedagem — o sintoma é um CONNECT_FAILED silencioso para sempre do lado do proxy. Os backends anunciam ao proxy sua porta real vinculada, mas o servidor HTTP ainda precisa se vincular a uma porta acessível e o proxy ainda precisa conseguir alcançá-la; se mcPort + offset cair fora da faixa de portas alocada do seu container, o bind/firewall falha independentemente do anúncio. Verifique se a porta está na faixa alocada do seu container antes de aumentar o offset.