Cómo Restaurar Personaje Corrompido o con Datos Inválidos en MU
Guía avanzada para diagnosticar y restaurar personajes con datos corruptos en la base de datos SQL de MU Online, incluyendo inventario, posición y stats.
Visión General del Problema
Los personajes corrompidos son uno de los incidentes más críticos en la administración de un servidor MU Online. La corrupción puede producirse por corte de energía durante el guardado, fallo del GameServer, edición manual incorrecta de la base de datos, ataque externo o un bug de versión. El resultado práctico es un personaje que hace crash al GameServer en el momento de cargar, bloqueando con frecuencia el acceso a toda la cuenta.
Esta guía cubre el diagnóstico completo y el procedimiento de restauración para servidores Season 6 (MuServer S6 EP3) con SQL Server 2008, 2012, 2014 o 2019.
BACKUP DATABASE MuOnline TO DISK = 'C:\Backups\MuOnline_antes_restaurar.bak' WITH COMPRESSION, STATS = 10Paso 1 — Identificar el Personaje con Problema
1.1 Abre el log de errores del GameServer. La ruta predeterminada es:
GameServer\Logs\Error\Error_YYYYMMDD.log
GameServer\Logs\GMCommand\GMCommand_YYYYMMDD.log
1.2 Filtra por palabras clave de error crítico:
[Error] Character Load Failed - CharName: Jugador01
[Error] Invalid Map Position - Map:255 X:0 Y:0
[Error] Inventory data corrupted - AccountID: cuenta01
[Error] Exception in CharacterLoad() - Overflow or invalid data
1.3 Confirma en SQL Server Management Studio (SSMS) que el registro del personaje existe:
USE MuOnline;
SELECT Name, AccountID, Class, cLevel, MapNumber, MapPosX, MapPosY, ConnectStat
FROM Character
WHERE Name = 'Jugador01';
ConnectStat debe ser 0 cuando el personaje está desconectado. Si aparece en 1 con el servidor corriendo y sin nadie conectado, el personaje quedó como "online" de forma incorrecta — esto por sí solo puede bloquear el login.Paso 2 — Restablecer el Estado de Conexión Bloqueado
Antes de cualquier intervención más profunda, resuelve cualquier estado de conexión pendiente:
USE MuOnline;
-- Forzar personaje a offline
UPDATE Character
SET ConnectStat = 0,
ChatLimitTime = 0
WHERE Name = 'Jugador01';
-- Forzar cuenta a offline
UPDATE MEMB_STAT
SET ConnectStat = 0,
ServerName = '',
IP = ''
WHERE memb__id = 'cuenta01';
Reinicia el GameServer y prueba el login. Si el problema persiste, avanza al Paso 3.
Paso 3 — Corregir una Posición de Mapa Inválida
Un mapa o posición inválida (p. ej., MapNumber=255, coordenadas X=0 Y=0 o un ID de mapa inexistente) es la causa más frecuente de crash al cargar el personaje.
Lorencia es el destino más seguro para la teletransportación: MapNumber=0, X=125, Y=125.
USE MuOnline;
UPDATE Character
SET MapNumber = 0,
MapPosX = 125,
MapPosY = 125,
Dir = 1
WHERE Name = 'Jugador01';
Referencia rápida de mapas válidos en Season 6:
| MapNumber | Nombre del Mapa | X seguro | Y seguro |
|---|---|---|---|
| 0 | Lorencia | 125 | 125 |
| 1 | Dungeon | 107 | 247 |
| 2 | Devias | 197 | 35 |
| 3 | Noria | 171 | 99 |
| 7 | Atlans | 15 | 15 |
| 10 | Crywolf Fortress | 87 | 90 |
| 56 | Kanturu Relics | 39 | 27 |
GameServer\Data\World\WorldSetting.xml o en la tabla WZ_WORLD, según la versión de MuServer que utilices.Paso 4 — Diagnosticar y Limpiar el Inventario Corrompido
El inventario se almacena como datos binarios (BLOB/Image) en la columna Inventory de la tabla Character. Un solo byte fuera de rango puede hacer crash a toda la rutina de carga.
4.1 Verifica el tamaño de los datos del inventario:
USE MuOnline;
SELECT Name,
DATALENGTH(Inventory) AS TamanioInventario,
DATALENGTH(MagicList) AS TamanioMagicList,
DATALENGTH(Quest) AS TamanioQuest
FROM Character
WHERE Name = 'Jugador01';
Tamaños esperados para Season 6:
Inventory: exactamente 7168 bytes (112 slots x 64 bytes por ítem)MagicList: típicamente entre 256 y 2048 bytesQuest: típicamente 4096 bytes
4.2 Si el tamaño es incorrecto, limpia el inventario con un blob zerado del tamaño correcto:
USE MuOnline;
-- Zerear el inventario (pierde ítems pero restaura el acceso al login)
UPDATE Character
SET Inventory = CAST(REPLICATE(CHAR(0xFF), 7168) AS VARBINARY(7168))
WHERE Name = 'Jugador01';
0xFF representa un slot vacío en el protocolo de MuServer Season 6. Usa 0x00 solo si tu versión del servidor emplea otra convención — consulta la documentación de protocolo de tu versión específica.4.3 Para limpiar también una lista de skills corrompida:
USE MuOnline;
UPDATE Character
SET MagicList = CAST(REPLICATE(CHAR(0xFF), 1152) AS VARBINARY(1152))
WHERE Name = 'Jugador01';
Paso 5 — Restaurar Stats Inválidos
Stats con valores fuera del rango permitido causan desbordamiento de entero (overflow) en la lógica del servidor.
5.1 Verifica los stats actuales:
USE MuOnline;
SELECT Name, Class, cLevel,
Strength, Dexterity, Vitality, Energy, Leadership,
LevelUpPoint, Life, MaxLife, Mana, MaxMana
FROM Character
WHERE Name = 'Jugador01';
5.2 Si algún valor es negativo o absurdamente alto (p. ej., Strength=65535 o -1), corrígelo a los valores base de la clase:
USE MuOnline;
-- Ejemplo para Dark Knight (Class=0) corregido a base de nivel 1
UPDATE Character
SET Strength = 28,
Dexterity = 20,
Vitality = 25,
Energy = 10,
Leadership = 0,
LevelUpPoint = 0,
Life = 110,
MaxLife = 110,
Mana = 40,
MaxMana = 40,
cLevel = 1,
Experience = 0
WHERE Name = 'Jugador01';
Stats base por clase (valores predeterminados Season 6):
| Clase | Class | STR | DEX | VIT | ENE |
|---|---|---|---|---|---|
| Dark Knight | 0 | 28 | 20 | 25 | 10 |
| Dark Wizard | 1 | 18 | 18 | 15 | 30 |
| Fairy Elf | 2 | 22 | 25 | 20 | 15 |
| Magic Gladiator | 3 | 26 | 26 | 26 | 16 |
| Dark Lord | 4 | 26 | 20 | 20 | 15 |
| Summoner | 5 | 18 | 18 | 18 | 23 |
| Rage Fighter | 6 | 32 | 27 | 25 | 10 |
Paso 6 — Verificar y Corregir Datos Auxiliares
Más allá de la tabla Character, otros registros relacionados pueden estar también corrompidos:
6.1 Limpiar un warehouse corrompido:
USE MuOnline;
-- Verificar tamaño del warehouse
SELECT StoreName, DATALENGTH(Items) AS TamanioWarehouse
FROM warehouse
WHERE StoreName = 'cuenta01';
-- Zerear el warehouse si está corrompido (pierde ítems del baúl)
UPDATE warehouse
SET Items = CAST(REPLICATE(CHAR(0xFF), 7680) AS VARBINARY(7680)),
Money = 0
WHERE StoreName = 'cuenta01';
6.2 Eliminar registros huérfanos de Blood Castle / Devil Square que puedan bloquear al personaje:
USE MuOnline;
DELETE FROM BC_UserData WHERE Name = 'Jugador01';
DELETE FROM DS_UserData WHERE Name = 'Jugador01';
DELETE FROM CC_UserData WHERE Name = 'Jugador01';
DELETE FROM T_OfflineStore WHERE CharName = 'Jugador01';
6.3 Verificar y corregir el registro de guild si es necesario:
USE MuOnline;
-- Remover personaje de entrada de guild corrompida
UPDATE GuildMember
SET G_Name = '',
G_Level = 0,
G_Status = 0
WHERE Name = 'Jugador01';
Paso 7 — Restaurar Desde un Backup
Si la corrupción es severa, la mejor solución es restaurar únicamente los datos del personaje afectado a partir de un backup reciente.
7.1 Restaura el backup en una base de datos temporal:
RESTORE DATABASE MuOnline_Backup
FROM DISK = 'C:\Backups\MuOnline_20240115_0600.bak'
WITH MOVE 'MuOnline' TO 'C:\SQL\MuOnline_Backup.mdf',
MOVE 'MuOnline_log' TO 'C:\SQL\MuOnline_Backup_log.ldf',
NORECOVERY, STATS = 10;
RESTORE DATABASE MuOnline_Backup WITH RECOVERY;
7.2 Copia únicamente los datos del personaje específico desde la base restaurada:
-- Restaurar fila de Character
UPDATE MuOnline..Character
SET Inventory = B.Inventory,
MagicList = B.MagicList,
MapNumber = B.MapNumber,
MapPosX = B.MapPosX,
MapPosY = B.MapPosY,
Strength = B.Strength,
Dexterity = B.Dexterity,
Vitality = B.Vitality,
Energy = B.Energy,
cLevel = B.cLevel,
Experience = B.Experience,
LevelUpPoint = B.LevelUpPoint
FROM MuOnline..Character A
JOIN MuOnline_Backup..Character B ON A.Name = B.Name
WHERE A.Name = 'Jugador01';
-- Restaurar warehouse
UPDATE MuOnline..warehouse
SET Items = B.Items,
Money = B.Money
FROM MuOnline..warehouse A
JOIN MuOnline_Backup..warehouse B ON A.StoreName = B.StoreName
WHERE A.StoreName = 'cuenta01';
Paso 8 — Validación Final
Después de todas las correcciones, ejecuta esta lista de verificación antes de reiniciar el GameServer:
USE MuOnline;
-- Lista de validacion final
SELECT
Name,
ConnectStat,
MapNumber,
MapPosX,
MapPosY,
cLevel,
Strength,
Dexterity,
Vitality,
Energy,
DATALENGTH(Inventory) AS InventarioBytes,
DATALENGTH(MagicList) AS MagicListBytes
FROM Character
WHERE Name = 'Jugador01';
Confirma que:
ConnectStat= 0MapNumberentre 0 y 255 con un valor reconocido por el servidorMapPosXyMapPosYambos > 0DATALENGTH(Inventory)= 7168 (Season 6)- Todos los stats son positivos y dentro del rango 0–65534
Reinicia el GameServer y monitorea GameServer\Logs\Error\ durante 5 minutos después del login del personaje restaurado para confirmar que no aparecen nuevos errores relacionados.
Perguntas frequentes
¿Cómo identificar si un personaje está corrompido?
Señales comunes: crash al intentar cargar ese personaje, mensaje 'Character load failed', personaje invisible en el servidor, error 'Invalid map position' en los logs del GameServer, o inventario que no carga. Revisa GameServer/Logs/Error/ para identificar el CharName específico que genera errores.
¿Qué tabla SQL almacena los datos del personaje en Season 6?
La tabla principal es Character en la base de datos MuOnline. Contiene columnas como Name, AccountID, Class, cLevel, LevelUpPoint, Strength, Dexterity, Vitality, Energy, Leadership, MapNumber, MapPosX, MapPosY, Inventory, MagicList y Life.
¿Puedo restaurar el inventario de un personaje sin backup?
Sin un backup completo es imposible recuperar los ítems originales. Sin embargo, puedes limpiar el inventario corrompido definiendo la columna Inventory como un blob de ceros, lo que permite el login nuevamente, aunque los ítems se perderán.
El personaje queda atascado en un mapa inválido tras restaurar. ¿Qué hago?
Ejecuta UPDATE MuOnline..Character SET MapNumber=0, MapPosX=125, MapPosY=125 WHERE Name='NombrePersonaje' para teletransportarlo a Lorencia (MapNumber=0). Si el problema persiste, verifica que el ID de mapa configurado exista en GameServer/Data/World/.
¿Cómo evitar la corrupción de datos en el futuro?
Configura backups automáticos con el Agente de SQL Server programando un job que ejecute BACKUP DATABASE MuOnline TO DISK cada 6 horas. También activa el modo de recuperación FULL en la base MuOnline y conserva los transaction logs para recuperación point-in-time.