Como implementar autoupdate incremental do cliente no seu servidor de MU Online
Configure um launcher com autoupdate incremental para o cliente do seu servidor de MU Online: manifesto de versão, diff de arquivos, download por patch e verificação de integridade, evitando redownloads completos a cada atualização.
Toda vez que você atualiza o cliente do seu servidor de MU Online — um mapa novo, um item customizado, uma correção de bug — o jogador precisa baixar essa mudança antes de entrar. Sem um sistema de autoupdate incremental, isso normalmente significa baixar o cliente inteiro de novo, o que afasta joga
Toda vez que você atualiza o cliente do seu servidor de MU Online — um mapa novo, um item customizado, uma correção de bug — o jogador precisa baixar essa mudança antes de entrar. Sem um sistema de autoupdate incremental, isso normalmente significa baixar o cliente inteiro de novo, o que afasta jogadores com internet mais lenta e gera picos de tráfego no seu servidor de arquivos. Um autoupdate incremental resolve isso comparando o que o jogador já tem com o que mudou, baixando só a diferença. Este tutorial cobre a arquitetura completa: geração de manifesto, verificação de integridade, download seletivo e tratamento de falhas.
Como funciona o autoupdate incremental
O princípio é simples: o servidor mantém um manifesto — uma lista de todos os arquivos do cliente com seu hash e tamanho atuais. O launcher, ao abrir, baixa esse manifesto e compara com um manifesto local (gerado a partir dos arquivos que o jogador já tem instalados). Qualquer arquivo cujo hash seja diferente (ou que não exista localmente) entra na fila de download. Arquivos idênticos são ignorados. O resultado prático: uma atualização de 50 MB em um cliente de 3 GB baixa só os 50 MB, não os 3 GB inteiros.
Pré-requisitos
- Um launcher já funcional para o seu servidor (custom ou baseado em algum framework de launcher de MU).
- Acesso a um servidor de arquivos (CDN, VPS ou storage) para hospedar o manifesto e os patches.
- Script ou ferramenta para gerar hash de todos os arquivos do cliente (pode ser feito em PHP, Python, ou C#).
- Ambiente de teste separado do cliente de produção, para validar o fluxo sem afetar jogadores reais.
Estrutura do manifesto
O manifesto é normalmente um arquivo JSON hospedado junto com os patches, listando cada arquivo relevante do cliente:
{
"version": "1.42.0",
"generated_at": "2026-07-20T14:00:00Z",
"files": [
{ "path": "Data/Item/Item1.bmd", "sha256": "a1b2c3...", "size": 184320 },
{ "path": "Data/Map/World1.map", "sha256": "d4e5f6...", "size": 942112 },
{ "path": "Main.exe", "sha256": "9f8e7d...", "size": 15728640 }
]
}
Gerar esse manifesto deve ser um passo automatizado sempre que você publica uma atualização — nunca manual, porque um único hash errado invalida a atualização inteira para todos os jogadores.
Gerando o manifesto no servidor (exemplo em script)
#!/bin/bash
# generate_manifest.sh - percorre a pasta do cliente e gera manifest.json
OUTPUT="manifest.json"
echo '{"version":"'$1'","generated_at":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","files":[' > $OUTPUT
find ./client -type f | while read -r file; do
hash=$(sha256sum "$file" | awk '{print $1}')
size=$(stat -c%s "$file")
relpath=$(echo "$file" | sed 's|^./client/||')
echo '{"path":"'$relpath'","sha256":"'$hash'","size":'$size'},' >> $OUTPUT
done
sed -i '$ s/,$//' $OUTPUT
echo ']}' >> $OUTPUT
Rode esse script como parte do seu pipeline de publicação, sempre gerando um manifesto novo antes de subir os patches ao servidor de arquivos.
Lógica do launcher (comparação de hash)
O launcher precisa, na abertura:
- Baixar o
manifest.jsonremoto. - Calcular (ou ler de um cache local) o hash de cada arquivo já instalado.
- Comparar as duas listas e montar a fila de arquivos divergentes ou ausentes.
- Baixar apenas os arquivos da fila, de preferência em paralelo (2-4 conexões simultâneas).
- Validar o hash de cada arquivo baixado antes de sobrescrever o original.
| Etapa | Local recomendado | Observação |
|---|---|---|
| Cache de hash local | Arquivo local_manifest.json ao lado do executável | Evita recalcular hash de tudo a cada abertura |
| Download | Pasta temporária _update_tmp/ | Nunca grava direto na pasta final |
| Validação pós-download | Hash SHA-256 do arquivo baixado | Só move para a pasta final se bater |
| Log de atualização | Arquivo de log com timestamp e lista de arquivos atualizados | Facilita suporte em caso de erro |
Diff binário para arquivos grandes
Para arquivos como o executável principal ou pacotes grandes de mapa, mesmo uma pequena mudança força o re-download do arquivo inteiro no modelo básico. Uma otimização adicional é usar diff binário (ferramentas como bsdiff/bspatch): o servidor gera um patch pequeno contendo só a diferença binária entre a versão antiga e a nova, e o launcher aplica esse patch localmente em vez de baixar o arquivo completo. Isso é mais complexo de implementar, mas vale a pena para arquivos grandes que mudam com frequência moderada.
CDN e distribuição
Hospedar manifesto e patches em uma CDN (em vez de só no VPS do servidor de jogo) reduz a carga no servidor principal durante picos de atualização (por exemplo, logo após o anúncio de uma nova season). Configure cache-control apropriado no manifesto (curto, para refletir mudanças rápido) e nos arquivos de patch (longo, já que um arquivo com hash fixo nunca muda de conteúdo).
Tratamento de falhas de download
Conexões instáveis são comuns entre jogadores de MU Online no Brasil. O launcher deve:
- Tentar novamente automaticamente (2-3 tentativas) um arquivo que falhou, antes de marcar a atualização como falha.
- Permitir retomar de onde parou (download parcial) em vez de reiniciar o arquivo do zero, especialmente para arquivos grandes.
- Nunca aplicar um arquivo parcialmente baixado — a validação de hash pós-download é a proteção final contra isso.
- Exibir uma mensagem clara ao jogador (nome do arquivo, progresso, erro específico) em vez de um "erro genérico de atualização".
Versionamento e rollback
Mantenha os últimos 2-3 manifestos anteriores acessíveis no servidor de arquivos. Se uma atualização causar problema grave (crash generalizado, item quebrado), você precisa conseguir reverter o manifesto ativo para a versão anterior rapidamente, sem depender de reconstruir os patches do zero.
Testes antes de publicar
Sempre teste a atualização em pelo menos três cenários antes de liberar para todos: (1) cliente limpo, sem nenhuma instalação prévia; (2) cliente na versão imediatamente anterior; (3) cliente em uma versão bem antiga (várias atualizações atrás), para garantir que o incremental cobre saltos maiores de versão, não só o patch mais recente.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Launcher baixa tudo mesmo com poucos arquivos alterados | Manifesto local não gerado ou hash calculado errado | Revise a geração e o cache do manifesto local |
| Atualização trava em um arquivo específico | Arquivo grande sem suporte a retomada de download | Implemente download resumível (range requests) |
| Cliente corrompido após atualização | Arquivo aplicado sem validação pós-download | Adicione checagem de hash antes de mover para a pasta final |
| Jogadores antigos não atualizam corretamente | Incremental só cobre a versão anterior, não saltos maiores | Gere o manifesto sempre com a lista completa atual, não só o diff da última versão |
| Pico de erro 503 no servidor de arquivos | Todos os jogadores baixando ao mesmo tempo sem CDN | Distribua patches por CDN com cache adequado |
Checklist de lançamento
- Script de geração de manifesto automatizado no pipeline de publicação.
- Launcher comparando hash local vs. remoto corretamente.
- Download em pasta temporária com validação pós-download.
- Suporte a retomada de download para arquivos grandes.
- CDN configurada para manifesto e patches.
- Rollback de manifesto testado e documentado.
- Testes em cliente limpo, versão anterior e versão antiga realizados.
Com o autoupdate incremental funcionando, publicar novas atualizações deixa de ser um evento arriscado e vira parte natural do ciclo de manutenção do servidor — para revisar como esse cliente se conecta à infraestrutura geral do projeto, veja o guia de como criar um servidor de MU Online.
Perguntas frequentes
Qual a diferença entre autoupdate incremental e download completo?
No download completo, toda atualização baixa o cliente inteiro (vários GB), mesmo que só um arquivo tenha mudado. No incremental, o launcher compara um manifesto de versão e baixa só os arquivos alterados, reduzindo o tempo de atualização de horas para segundos ou minutos na maioria dos casos.
Preciso reescrever meu launcher do zero para ter autoupdate incremental?
Não necessariamente. A maioria dos launchers de MU já tem uma rotina de checagem de versão; o trabalho principal é gerar o manifesto (lista de arquivos com hash) no servidor e ajustar a lógica do launcher para comparar hash local vs. remoto em vez de baixar tudo.
Qual algoritmo de hash usar para comparar arquivos?
SHA-256 é o mais seguro e recomendado atualmente. MD5 ainda é usado por launchers legados por ser mais rápido de calcular, mas tem colisões teóricas conhecidas — para um cliente de MU o risco prático é baixo, mas SHA-256 é a escolha mais robusta para projetos novos.
Como lido com arquivos muito grandes, tipo o executável principal?
Para arquivos grandes que mudam com frequência, considere usar diff binário (bsdiff/bspatch) em vez de reenviar o arquivo inteiro. Isso reduz ainda mais o volume de download quando só uma pequena parte do binário muda entre versões.
O que acontece se a atualização falhar no meio do download?
O launcher deve validar o hash de cada arquivo após o download e, se não bater, re-baixar apenas aquele arquivo (não a atualização inteira). Mantenha os arquivos baixados em uma pasta temporária e só mova para a pasta final após validação, evitando corromper a instalação em caso de queda de conexão.