Blogue ·
Escolher um painel de jogos pela API que automatiza
Seis painéis de jogos, medidos pelo que as suas APIs deixam mesmo fazer. A pergunta decisiva não são as funcionalidades, mas se o painel impõe a suspensão.
Por Provibr
A maioria das comparações de painéis de servidores de jogos é escrita para quem vai andar aos cliques dentro de um. Se vai vender servidores de jogos, não é essa pessoa. Vai ver o painel umas duas vezes por ano, e o seu sistema de faturação vai vê-lo de poucos em poucos minutos, para sempre.
Portanto a comparação útil é outra: o que é que a API deixa fazer, o que é que ela se recusa a dizer, e qual das promessas da interface é que o painel impõe mesmo quando um cliente deixa de pagar.
Tudo o que se segue foi medido ao construir integrações contra o Pterodactyl 1.11, o Pelican 1.0.0-beta38, o WISP 3.7.5, o PufferPanel 3.0.9, o GameAP 4.4.2 e o MCSManager 10.18.2, em agosto de 2026.
Há um painel que está deliberadamente fora da tabela. O AMP não está aqui porque não o medimos. É um produto razoável com uma API a sério, e escrever uma linha de comparação a partir da sua documentação em vez das suas respostas seria exatamente o tipo de enchimento com ar de confiança contra o qual este texto argumenta.
Entrar: seis painéis, cinco modelos de credenciais
| Painel | Credencial | Notas |
|---|---|---|
| Pterodactyl | Duas chaves estáticas, ptla_ e ptlc_ | As duas são precisas |
| Pelican | Duas chaves estáticas, papp_ e pacc_ | As duas são precisas |
| WISP | Uma chave, sem prefixo | Nada para validar antes da primeira chamada |
| PufferPanel | Credenciais de cliente OAuth2 | Token opaco, uma hora, âmbito admin |
| GameAP | Um token bearer do Sanctum | Sem coluna de validade no esquema do painel |
| MCSManager | Uma chave, cabeçalho x-request-api-key | O acesso à API vem desligado |
Três deles precisam de um aviso.
O Pterodactyl e o Pelican precisam das duas chaves, e a razão é estrutural: não existe na Application API um ponto de acesso para as ações de energia. Uma integração montada só com uma chave de aplicação consegue criar servidores que o seu dono não consegue iniciar.
O Pelican aceita uma chave de cliente na Application API. O GET /api/application/servers, o /nodes e o /users devolvem todos 200 com a chave errada, e o engano só aparece numa escrita, como um erro de validação sobre um campo de utilizador em falta. O Pterodactyl responde 403 ao mesmo pedido. No Pelican, verificar o prefixo da chave é a única maneira de apanhar um par trocado antes de se tornar uma falha confusa na altura do aprovisionamento. No WISP, que não tem prefixo nenhum, não há maneira de o apanhar.
O MCSManager vem com a API desligada. Uma instalação de raiz tem o enableApiKey a falso e, até alguém o ligar, todas as chamadas devolvem 403 «Insufficient Permissions», incluindo chamadas feitas com uma chave válida de um administrador válido. Isso é um pedido de suporte logo no primeiro dia para quem não saiba onde olhar. Já que lá está: o MCSManager também limita o débito a oito pedidos por segundo por cookie de sessão, pelo que um cliente que guarda cookies é travado onde um cliente que os deita fora não é.
A pergunta que decide: o suspend faz alguma coisa?
Todos estes painéis podem receber a ordem de suspender um servidor. Não é essa a pergunta. A pergunta é se um cliente que continua a ter credenciais do painel consegue desfazê-la.
| Painel | Mecanismo | O painel impõe? |
|---|---|---|
| Pterodactyl | suspend / unsuspend na Application API | Sim |
| Pelican | O mesmo | Sim |
| WISP | O mesmo | Sim |
| MCSManager | Pôr o fim da instância no passado e matar | Sim |
| PufferPanel | Parar e depois matar | Não |
| GameAP | Parar e depois marcar blocked | Não |
Os três painéis da família Pterodactyl têm uma primitiva a sério e não há nada a discutir.
O MCSManager é a surpresa. Também não tem ponto de acesso de suspensão, mas tem uma validade: ponha a data de fim de uma instância no passado e o daemon recusa-se a iniciá-la. Verificámos isso contra o painel e não contra a nossa própria guarda, com um pedido em bruto, e obtivemos 500 Instance expired. Unable to start the instance. Isso é imposição. Duas ressalvas: também tem de matar a instância, porque de outro modo um servidor a correr continua a correr até a verificação horária de validade lhe pegar, o que pode demorar até sessenta minutos. E se um cliente tiver definido a sua própria data de validade, cabe-lhe a si repô-la ao reativar; a nossa integração ainda não o faz.
O PufferPanel não tem nada. Não há ponto de acesso de suspensão nem coluna de suspensão no seu modelo de dados; o vocabulário de estado é running e installing. A melhor ação disponível é parar o servidor e matá-lo se não parar. Um cliente com acesso ao painel pode carregar em iniciar.
O GameAP tem um indicador que não faz nada. Existe um campo blocked, e defini-lo é apenas administrativo. Definimo-lo num servidor SA-MP em funcionamento e o servidor ficou online, a responder a consultas de jogo em direto, e pôde ser iniciado outra vez a partir do painel depois disso.
Vale a pena construir essa distinção no seu próprio modelo de dados em vez de a limar. Nos dois painéis que não a impõem, a descrição honesta do que aconteceu é «o servidor foi parado e bloqueado no painel, mas uma sessão direta pode voltar a iniciá-lo», e isso pertence ao registo de auditoria da ação. Registar seis painéis como «suspenso» quando dois deles apenas desejam estar é a forma de um sistema de faturação deixar de cobrar em silêncio.
Criar um servidor: quatro formas diferentes
Aqui não há terreno comum nenhum. Quatro destes painéis modelam um servidor de jogos de maneira fundamentalmente diferente, e a forma da chamada de criação vem atrás.
O Pterodactyl e o Pelican querem tudo de uma vez. Nome, dono, egg, imagem docker, comando de arranque, o conjunto completo de variáveis de ambiente incluindo as que o cliente nunca vê, limits, feature_limits e uma alocação. Não há criação parcial; um campo em falta é uma recusa por campo. Um valor que vale a pena conhecer: o limits.io é validado com between:10,1000, pelo que enviar 0 para «ilimitado» é um 422 num campo de que nenhum cliente vai ouvir falar. O Pelican inverteu essa regra: ali o 0 serve e é omitir o campo que é o erro.
O PufferPanel está do avesso. É você que cunha o identificador do servidor, com oito caracteres, e depois faz PUT da definição completa do template em linha, porque a lista de templates não traz as variáveis. Criar não instala: isso é uma segunda chamada. E apagar exige parar primeiro, ou recebe um 500.
O GameAP cria uma linha na base de dados e mais nada. O POST /api/servers dá-lhe um servidor com installed: 0; a instalação é uma segunda chamada cujo desfecho aterra numa tarefa do daemon e não na resposta HTTP, por isso consulta-se. Não há identificador externo nem chave de idempotência, e os nomes não são únicos, o que em conjunto significa que uma criação repetida produz um duplicado em silêncio. O identificador devolvido é a única identidade que recebe, por isso guarde-o antes que outra coisa possa correr mal.
O MCSManager não tem conceito de template nenhum. Uma instância é um comando de arranque, e é essa toda a abstração. Há uma lista de predefinições de instalação rápida, sessenta e três, mas nenhuma traz identificador: o painel compara pelo título mais a descrição, cinquenta dos sessenta e três títulos não são únicos, e os valores dependem do idioma. Tudo o que dependa deles parte quando o cliente muda o idioma do painel.
O que se consegue ver depois
| Painel | Números de uso | Capacidade do nó | Consola em direto |
|---|---|---|---|
| Pterodactyl | CPU, memória, disco, rede, uptime | Do nó | Sim |
| Pelican | O mesmo | Do nó | Sim |
| WISP | O mesmo, sem uptime | Capacidade sim, ocupação não | Sim |
| PufferPanel | Só CPU e memória | Nada reportado | Por consulta, sem fluxo |
| GameAP | Nenhuns | Não legível, 403 | Protocolo à parte |
| MCSManager | CPU e memória; disco sempre 0 | Por daemon | Socket.io, não WebSocket |
Duas entradas aí são piores do que parecem. O GameAP devolve 403 em /api/nodes para um token de API, pelo que um motor de colocação não consegue ver capacidade nenhuma e tem de ser instruído sobre onde pôr as coisas. E o número de disco do MCSManager não é apenas pouco fiável: o campo é declarado a zero no daemon e nunca é atribuído, pelo que é sempre zero, em todas as instâncias, para sempre.
O ponto de acesso /resources do Pterodactyl guarda em cache durante vinte segundos, o que conta mais do que parece: consulte mais depressa do que isso e recebe os mesmos bytes de volta, e um cálculo ingénuo de débito de rede transforma contadores idênticos numa quebra que nunca aconteceu. O Pelican herdou o mesmo comportamento. O WISP não guarda isso em cache, mas o WISP não tem campo de uptime, que é o campo que usaria para distinguir uma leitura fresca de uma leitura repetida.
Como escolher de facto
- Precisa de suspensão imponível e de uma API a sério. Pterodactyl, ou Pelican se quiser o fork em desenvolvimento ativo. É esta a resposta aborrecida e correta para a maioria de quem vende alojamento de jogos.
- Quer alojamento sem Docker em máquinas pequenas. MCSManager, e assenta melhor do que a sua reputação sugere, porque a validade lhe dá imposição a sério. Aceite que vai ter duas métricas de uso e nenhuma integração de consola.
- Já explora PufferPanel ou GameAP. Muito bem, mas construa a suspensão por cima: a plataforma tem de bloquear o acesso ao painel, porque o painel não o faz.
- Está a escolher hoje sem legado. A API do painel vai ser a restrição da sua automatização durante anos, e dois destes seis não conseguem impor a única operação de que o seu sistema de faturação mais depende.
O que não está medido aqui
O AMP, como já foi dito. As versões do Pterodactyl abaixo da 1.11, num painel onde este é exatamente o tipo de comportamento que muda em versões menores. Os limites de débito do Pterodactyl e do Pelican, que exigiriam centenas de pedidos contra um painel em funcionamento para serem estabelecidos com honestidade. O MCSManager com Docker ativo, onde deveriam existir mais métricas mas onde nunca vimos um campo preenchido. E o GameAP clássico em PHP, já que o painel que medimos é a reescrita em Go, que difere pelo menos na camada de autenticação.
O Provibr integra estes seis painéis através de um agente que corre dentro da sua própria rede; as notas de configuração estão em Pterodactyl, Pelican, PufferPanel, GameAP e MCSManager.