Como migrar de emulador de MU Online sem perder o banco de dados
Troque de emulador de MU Online (IGCN, MuEMU, X-Team, Season 6 → nova season) preservando contas, personagens, inventário e Warehouse: backup do SQL Server, mapeamento de tabelas, ajuste de schema e testes antes de abrir para os jogadores.
Trocar de emulador é um dos passos mais delicados na vida de um servidor de MU Online: você quer os recursos do emulador novo (melhor anti-cheat, novos sistemas, mais estabilidade), mas não pode perder as contas, personagens, inventários e Warehouses que os jogadores construíram. Uma migração malfei
Trocar de emulador é um dos passos mais delicados na vida de um servidor de MU Online: você quer os recursos do emulador novo (melhor anti-cheat, novos sistemas, mais estabilidade), mas não pode perder as contas, personagens, inventários e Warehouses que os jogadores construíram. Uma migração malfeita apaga meses de progresso e mata o servidor em um dia. Uma migração bem-feita é invisível para o jogador: ele faz login e está tudo lá. Este tutorial percorre o processo completo — backup, mapeamento de tabelas, conversão de schema e testes — sempre trabalhando sobre cópias e nunca no banco de produção.
Por que a migração dá errado (e como evitar)
A maioria dos desastres de migração vem de três erros: mexer no banco de produção direto, assumir que os schemas são idênticos entre emuladores, e abrir o servidor sem testar. O MU Online, na esmagadora maioria dos emuladores (IGCN, MuEMU, X-Team, entre outros), usa Microsoft SQL Server como banco. Isso é uma boa notícia: as tabelas centrais têm nomes e estruturas parecidas entre emuladores, porque todos descendem dos mesmos arquivos originais. A má notícia é que "parecidas" não é "iguais" — nomes de colunas, tamanhos de campo e o formato binário do inventário variam. A migração segura sempre trata o banco antigo como fonte de leitura e constrói o novo em paralelo.
Pré-requisitos
- O servidor antigo ainda funcional, com acesso ao SQL Server (usuário
saou equivalente). - O novo emulador já instalado e testado com um banco limpo (veja o tutorial de criação de servidor).
- SQL Server Management Studio (SSMS) para backup, restore e queries.
- Espaço em disco para pelo menos duas cópias completas do banco.
- Uma janela de manutenção com o servidor offline (nada de migrar ao vivo).
- Backup validado antes de qualquer alteração — este é inegociável.
Entenda as tabelas centrais do MU
Antes de mover qualquer dado, saiba o que precisa sobreviver. Os nomes variam por emulador, mas o núcleo é sempre este:
| Tabela | O que guarda | Criticidade |
|---|---|---|
MEMB_INFO | Contas (login, senha, email) | Máxima |
AccountCharacter | Quais personagens pertencem a cada conta | Máxima |
Character | Personagens: nível, stats, classe, posição | Máxima |
warehouse | Baú/Vault e Zen guardado | Máxima |
Guild / GuildMember | Guildas e membros | Alta |
MEMB_STAT | Status online/offline da conta | Baixa (regenerável) |
O inventário do personagem normalmente não é uma tabela separada: ele vive dentro de um campo binário (Inventory) na tabela Character. Esse detalhe é o coração da migração — voltaremos a ele no Passo 4.
Passo 1 — Backup completo do banco antigo
Com o GameServer e o ConnectServer parados, faça um backup full pelo SSMS ou por T-SQL. Nunca comece nada sem esta etapa concluída e verificada:
-- Backup completo do banco de produção antigo
BACKUP DATABASE [MuOnline]
TO DISK = N'D:\Backups\MuOnline_pre_migracao.bak'
WITH FORMAT, INIT,
NAME = N'MuOnline - backup pre-migracao',
STATS = 10;
GO
-- Verifique a integridade do arquivo de backup
RESTORE VERIFYONLY
FROM DISK = N'D:\Backups\MuOnline_pre_migracao.bak';
GO
O RESTORE VERIFYONLY confirma que o arquivo .bak está íntegro e restaurável. Se ele falhar, pare tudo — seu backup não presta e você não pode arriscar a migração.
Passo 2 — Restaurar uma cópia de trabalho
Nunca migre no banco original. Restaure o backup com um nome novo, que será seu ambiente de conversão. Assim, o banco de produção continua intocado se algo der errado:
-- Restaura como banco de trabalho separado (MuOnline_MIGRACAO)
RESTORE DATABASE [MuOnline_MIGRACAO]
FROM DISK = N'D:\Backups\MuOnline_pre_migracao.bak'
WITH MOVE 'MuOnline' TO N'D:\SQLData\MuOnline_MIGRACAO.mdf',
MOVE 'MuOnline_log' TO N'D:\SQLData\MuOnline_MIGRACAO_log.ldf',
RECOVERY, STATS = 10;
GO
Os nomes lógicos (MuOnline, MuOnline_log) você obtém com RESTORE FILELISTONLY FROM DISK = '...'. A partir daqui, todo trabalho acontece em MuOnline_MIGRACAO.
Passo 3 — Mapear o schema: antigo vs. novo
Aqui está o trabalho intelectual da migração. Instale o novo emulador com seu banco limpo e compare a estrutura de cada tabela central entre os dois. Para listar colunas de uma tabela:
-- Rode nos dois bancos e compare coluna a coluna
SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Character'
ORDER BY ORDINAL_POSITION;
Monte um mapa de diferenças. As três categorias de divergência que você vai encontrar:
| Tipo de diferença | Exemplo (varia por emulador) | Ação |
|---|---|---|
| Coluna renomeada | cLevel vs Level | Mapear na cópia (INSERT/UPDATE) |
| Coluna nova no emulador novo | MasterLevel, PkCount | Preencher com valor default |
| Formato binário diferente | Inventory com layout distinto | Converter byte a byte (Passo 4) |
Colunas novas no emulador destino que não existiam no antigo devem receber um valor padrão coerente (0 para nível de master, NULL onde permitido). Colunas que existiam no antigo e sumiram no novo são simplesmente descartadas.
Passo 4 — O inventário e o Warehouse (o campo binário)
Este é o ponto onde a maioria das migrações falha silenciosamente. O inventário e o Warehouse são armazenados como um blob hexadecimal, onde cada item ocupa um bloco fixo de bytes (tipicamente 16 bytes por slot em muitas seasons: código do item, nível, opções, serial, socket, etc.). Se os dois emuladores usam o mesmo layout de bytes, o campo é copiado como está e tudo se preserva. Se o novo emulador mudou o layout (por exemplo, ampliou o bloco para suportar novos sockets ou harmony), você precisa converter cada bloco.
Regra prática: antes de confiar, pegue um personagem de teste com itens conhecidos, olhe o hex do inventário nos dois formatos e confirme que os campos batem. Nunca assuma compatibilidade de blob binário — valide com um caso real. Se o layout divergir, escreva um script de conversão que leia o blob antigo, reorganize cada bloco de item para o novo tamanho e grave de volta.
Passo 5 — Migrar as contas e personagens
Com o schema mapeado, mova os dados na ordem de dependência: contas primeiro, depois personagens, depois vínculos e Warehouse. Se o schema for compatível, um INSERT direto entre bancos resolve; se houver renomeação de colunas, você lista as colunas explicitamente:
-- Exemplo: copiar contas para o banco do novo emulador
-- (nomes de colunas variam por emulador — ajuste ao seu schema)
INSERT INTO [MuOnline_NOVO].dbo.MEMB_INFO
(memb___id, memb__pwd, mail_addr, appl_days, bloc_code, ctl1_code)
SELECT
memb___id, memb__pwd, mail_addr, appl_days, bloc_code, ctl1_code
FROM [MuOnline_MIGRACAO].dbo.MEMB_INFO;
GO
Repita o padrão para Character, AccountCharacter, warehouse, Guild e GuildMember, sempre respeitando a ordem para não violar chaves estrangeiras. Migre primeiro um lote pequeno (10–20 contas de teste) antes de rodar a base inteira.
Passo 6 — Ajustar identidades, seeds e constraints
Depois de inserir os dados, arrume o que o INSERT não cuida: colunas IDENTITY precisam ter o seed reajustado, senão o próximo personagem criado colide com um ID existente. Verifique também que não há personagens órfãos (em Character sem entrada em AccountCharacter) nem duplicidade de nomes:
-- Reajusta o contador de identidade após a carga em massa
DBCC CHECKIDENT ('Character', RESEED);
GO
-- Personagens orfaos (existem mas nao pertencem a nenhuma conta)
SELECT c.Name
FROM Character c
LEFT JOIN AccountCharacter ac ON c.Name = ac.GameID1 OR c.Name = ac.GameID2
WHERE ac.Id IS NULL;
GO
A query de órfãos varia conforme o emulador guarde os personagens em colunas (GameID1..5) ou em linhas — adapte à sua estrutura. Qualquer órfão encontrado é um personagem que o jogador não vai enxergar no login.
Passo 7 — Apontar o novo emulador e subir
Configure a connection string do novo GameServer/ConnectServer para o banco migrado (arquivo de config do emulador — .ini, .xml ou .dat, varia por emulador). Suba os serviços um de cada vez e acompanhe os logs. Um erro comum aqui é o emulador não subir porque uma tabela auxiliar que ele espera (config de eventos, ranking, cash shop) não existe no banco migrado — nesse caso, crie a tabela vazia a partir do script do banco limpo do novo emulador.
Passo 8 — Testar em jogo antes de abrir
Nunca abra para os jogadores sem esta bateria de testes com contas reais migradas:
- Login: entre com uma conta antiga migrada e confirme que autentica.
- Seleção de personagem: todos os personagens aparecem, com nível, classe e resets corretos.
- Stats: força, agilidade, vida e mana batem com o valor antigo.
- Inventário e Warehouse: itens presentes, com opções e sockets íntegros.
- Zen: o Zen do personagem e do Warehouse está correto.
- Guild: guildas, marcas e membros preservados; ranking coerente.
- Criar personagem novo: confirme que não colide com IDs migrados (valida o Passo 6).
Só depois que todos os itens passarem você aponta o servidor de produção para o banco novo e comunica os jogadores.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| GameServer não conecta ao banco | Connection string ou tabela ausente | Confira config e crie tabelas auxiliares faltantes |
| Login OK mas nenhum personagem aparece | AccountCharacter não migrado ou órfão | Verifique o vínculo conta↔personagem |
| Itens sumidos ou trocados | Layout do blob de inventário divergente | Converta o campo binário (Passo 4) |
| Erro de chave duplicada ao criar char | IDENTITY não reajustado | Rode DBCC CHECKIDENT ... RESEED |
| Stats ou nível zerados | Coluna renomeada não mapeada | Corrija o mapeamento no INSERT |
| Backup não restaura | Arquivo .bak corrompido | Refaça o backup e valide com VERIFYONLY |
Checklist de migração
- Servidor antigo offline (GameServer e ConnectServer parados).
- Backup full feito e validado com
RESTORE VERIFYONLY. - Cópia de trabalho restaurada com nome separado.
- Schema das tabelas centrais comparado (antigo vs. novo).
- Formato do inventário/Warehouse verificado com caso real.
- Lote pequeno de contas migrado e testado antes da base inteira.
- IDENTITY reajustado e órfãos verificados.
- Novo emulador apontando para o banco migrado e subindo limpo.
- Bateria completa de testes em jogo aprovada.
- Banco de produção original preservado até a virada final.
Com a migração validada, guarde o .bak pré-migração por semanas: se algum jogador reportar perda de item que passou despercebida nos testes, você tem a fonte original para conferir e corrigir. Uma migração de emulador bem-documentada vira um roteiro reutilizável — na próxima troca de versão, você repete os mesmos passos com muito menos risco.
Perguntas frequentes
Preciso apagar o banco antigo para migrar de emulador?
Não, e você nunca deve fazer isso. A migração correta parte de uma cópia (restore) do banco antigo em outra instância/nome, e só depois adapta o schema para o novo emulador. O banco de produção original fica intocado até você validar tudo em ambiente de teste.
Migrar de emulador muda a estrutura das tabelas?
Depende do quanto os dois emuladores divergem. Tabelas centrais como Character, AccountCharacter e Warehouse costumam ter colunas parecidas, mas nomes, tamanhos de campo e a codificação do inventário variam por emulador. Sempre compare o schema das duas versões antes de mover dados.
O inventário do personagem vai sobreviver à migração?
Sim, se o formato do campo de inventário for compatível. O inventário é um blob/hex com a lista de itens; se o novo emulador usa o mesmo layout de 16 bytes por item (padrão em muitas seasons), ele é preservado. Se o layout mudou (ex.: suporte a sockets/harmony novo), é preciso converter.
Posso migrar entre versões diferentes de Season?
Pode, mas quanto maior o salto de season, maior a chance de o schema divergir. Migrar dentro da mesma season (só trocando de emulador) é o cenário mais seguro. Saltar várias seasons exige scripts de conversão e testes redobrados, especialmente em itens, sockets e master level.
Como sei se a migração deu certo antes de abrir o servidor?
Você valida em ambiente de teste: login funciona, personagens aparecem com nível/stats corretos, inventário e Warehouse íntegros, Guild e ranking preservados. Só depois de todos esses testes passarem você aponta o servidor de produção para o banco novo.
Devo mexer no banco com o GameServer ligado?
Nunca. Qualquer backup ou alteração de schema deve ser feito com o servidor offline (GameServer e ConnectServer parados). Alterar tabelas com o jogo rodando corrompe dados em trânsito e pode travar contas de jogadores logados.