El mayor portal de MU Online de Brasil — desde 2003
Tutorial Avanzado Tutoriais

Sistema de Log de Jugadores Avanzado: Monitoreo Completo en MU

Configura un sistema completo de logs para monitorear acciones de jugadores en MU Online: SQL, archivos de log, alertas automáticas y panel admin.

EQ Equipo ViciadosMU · Actualizado el 3 jul 2026 · ⏱ 12 min de lectura

Por Qué un Sistema de Log Avanzado es Esencial

En servidores privados de MU Online, la ausencia de logs detallados hace imposible investigar dupes de ítems, acusaciones entre jugadores y exploits. El sistema por defecto de MuServer registra eventos básicos, pero con la configuración correcta es posible rastrear cada acción relevante — desde el drop de un ítem Excellent hasta intentos de speed hack — con timestamp preciso y la IP del jugador.

Este tutorial cubre el stack completo: configuración del GameServer, creación de tablas SQL dedicadas, stored procedures de logging, SQL Jobs para alertas automáticas y buenas prácticas de retención de datos.


Paso 1: Habilitar Logs Nativos del GameServer

El archivo central de configuración se encuentra en GameServer/Data/GS_Config.ini. Ábrelo con cualquier editor de texto y localiza o agrega las siguientes claves en la sección [GameServer]:

[GameServer]
; --- Logging ---
LogEnable=1
LogLevel=3
; 1=básico | 2=medio | 3=completo (recomendado para admin)

TradeLog=1
TradeLogLevel=2

DropLog=1
DropLogLevel=2

ChatLog=1
ChatLogLevel=1
; Nivel 1 = solo chat público, 2 = incluye whisper

HackLog=1
PKLog=1

; Directorio de salida de los logs en texto
LogPath=./Log/
Atenção: LogLevel=3 incrementa el volumen de I/O en disco. En un VPS con disco HDD, monitorea el uso de I/O después de habilitarlo. En SSD no hay impacto perceptible para servidores con hasta 500 jugadores simultáneos.

Después de guardar, reinicia el GameServer. Los archivos de log se generarán en GameServer/Log/ con la siguiente nomenclatura:

  • GS_YYYYMMDD.log — log general
  • Trade_YYYYMMDD.log — intercambios entre jugadores
  • Drop_YYYYMMDD.log — drops de ítems en el suelo
  • Hack_YYYYMMDD.log — eventos de seguridad

Paso 2: Crear Tablas SQL para Log Estructurado

Los logs en archivos de texto son difíciles de consultar. La solución es reflejar los eventos críticos en tablas SQL. Conéctate a la base MuOnline en SQL Server Management Studio y ejecuta:

USE MuOnline;
GO

-- Tabla de log de drops de ítems
CREATE TABLE Log_ItemDrop (
    LogID        BIGINT IDENTITY(1,1) PRIMARY KEY,
    LogDate      DATETIME DEFAULT GETDATE(),
    CharName     VARCHAR(10) NOT NULL,
    AccountID    VARCHAR(10) NOT NULL,
    MapNumber    TINYINT NOT NULL,
    MapX         SMALLINT NOT NULL,
    MapY         SMALLINT NOT NULL,
    ItemIndex    SMALLINT NOT NULL,
    ItemLevel    TINYINT NOT NULL,
    ItemOption   TINYINT NOT NULL,   -- 0=normal, 4=excellent
    ItemSerial   BIGINT NOT NULL,
    DropType     TINYINT NOT NULL,   -- 1=suelo, 2=trade, 3=warehouse
    PlayerIP     VARCHAR(20)
);
GO

-- Tabla de log de trades
CREATE TABLE Log_Trade (
    LogID        BIGINT IDENTITY(1,1) PRIMARY KEY,
    LogDate      DATETIME DEFAULT GETDATE(),
    CharGive     VARCHAR(10) NOT NULL,
    CharReceive  VARCHAR(10) NOT NULL,
    ItemIndex    SMALLINT NOT NULL,
    ItemLevel    TINYINT NOT NULL,
    ItemOption   TINYINT NOT NULL,
    ItemSerial   BIGINT NOT NULL,
    ZenAmount    INT DEFAULT 0
);
GO

-- Tabla de alertas para el panel admin
CREATE TABLE T_AdminAlerts (
    AlertID      INT IDENTITY(1,1) PRIMARY KEY,
    AlertDate    DATETIME DEFAULT GETDATE(),
    AlertType    VARCHAR(30) NOT NULL,
    CharName     VARCHAR(10),
    Description  VARCHAR(500),
    IsRead       BIT DEFAULT 0
);
GO
Nota: Los nombres de tablas y columnas siguen la convención de MuServer Season 6 EP3. En versiones Season 9+ algunos nombres de columna pueden diferir — verifica las tablas MEMB_INFO y Character de tu base de datos para confirmar el schema.

Paso 3: Stored Procedures para Inserción de Logs

Crea procedures que el GameServer invoca vía ODBC (en versiones que soportan extensión SQL) o que puedes ejecutar vía triggers. Para servidores que usan extensión de log SQL nativa:

USE MuOnline;
GO

CREATE PROCEDURE WZ_InsertItemDropLog
    @CharName    VARCHAR(10),
    @AccountID   VARCHAR(10),
    @MapNumber   TINYINT,
    @MapX        SMALLINT,
    @MapY        SMALLINT,
    @ItemIndex   SMALLINT,
    @ItemLevel   TINYINT,
    @ItemOption  TINYINT,
    @ItemSerial  BIGINT,
    @DropType    TINYINT,
    @PlayerIP    VARCHAR(20)
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Log_ItemDrop
        (CharName, AccountID, MapNumber, MapX, MapY,
         ItemIndex, ItemLevel, ItemOption, ItemSerial, DropType, PlayerIP)
    VALUES
        (@CharName, @AccountID, @MapNumber, @MapX, @MapY,
         @ItemIndex, @ItemLevel, @ItemOption, @ItemSerial, @DropType, @PlayerIP);
END;
GO

CREATE PROCEDURE WZ_InsertTradeLog
    @CharGive    VARCHAR(10),
    @CharReceive VARCHAR(10),
    @ItemIndex   SMALLINT,
    @ItemLevel   TINYINT,
    @ItemOption  TINYINT,
    @ItemSerial  BIGINT,
    @ZenAmount   INT = 0
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Log_Trade
        (CharGive, CharReceive, ItemIndex, ItemLevel, ItemOption, ItemSerial, ZenAmount)
    VALUES
        (@CharGive, @CharReceive, @ItemIndex, @ItemLevel, @ItemOption, @ItemSerial, @ZenAmount);
END;
GO

Paso 4: SQL Job para Detección de Ítems Sospechosos

Configura un SQL Server Agent Job que se ejecute cada 5 minutos y detecte automáticamente drops de ítems con nivel alto u opciones raras:

  1. Abre SQL Server Management Studio
  2. Expande SQL Server Agent → clic derecho en JobsNew Job
  3. Nombre: MU_DetectarDropsSospechosos
  4. En StepsNew Step, pega el siguiente script:
USE MuOnline;
GO

-- Detectar drops de ítems Level 13+ o Excellent en los últimos 5 minutos
INSERT INTO T_AdminAlerts (AlertType, CharName, Description)
SELECT
    'DROP_SOSPECHOSO',
    d.CharName,
    'Drop: Item=' + CAST(d.ItemIndex AS VARCHAR) +
    ' Lv=' + CAST(d.ItemLevel AS VARCHAR) +
    ' Opt=' + CAST(d.ItemOption AS VARCHAR) +
    ' Map=' + CAST(d.MapNumber AS VARCHAR) +
    ' Pos=(' + CAST(d.MapX AS VARCHAR) + ',' + CAST(d.MapY AS VARCHAR) + ')' +
    ' IP=' + ISNULL(d.PlayerIP, 'N/A')
FROM Log_ItemDrop d
WHERE d.LogDate >= DATEADD(MINUTE, -5, GETDATE())
  AND (d.ItemLevel >= 13 OR d.ItemOption >= 4);

-- Detectar trades con ítems Level 15+ (posible dupe)
INSERT INTO T_AdminAlerts (AlertType, CharName, Description)
SELECT
    'TRADE_LEVEL15',
    t.CharGive,
    'Trade: ' + t.CharGive + ' -> ' + t.CharReceive +
    ' Item=' + CAST(t.ItemIndex AS VARCHAR) +
    ' Lv=' + CAST(t.ItemLevel AS VARCHAR)
FROM Log_Trade t
WHERE t.LogDate >= DATEADD(MINUTE, -5, GETDATE())
  AND t.ItemLevel >= 15;
  1. En SchedulesNew Schedule: Frequency = Daily, Recurs every 5 minutes
  2. Haz clic en OK para guardar el Job
Dica: Para recibir estas alertas por correo electrónico, configura Database Mail en SQL Server y agrega un step al Job que ejecute msdb.dbo.sp_send_dbmail con el contenido de los registros no leídos de T_AdminAlerts.

Paso 5: Script Batch para Archivar Logs Antiguos

Los logs se acumulan rápidamente. Crea el archivo GameServer/LogArchive.bat para comprimir y mover logs con más de 30 días:

@echo off
REM Archivo: GameServer/LogArchive.bat
REM Programar en el Programador de tareas de Windows - diariamente a las 03:00

set LOG_DIR=C:\MuServer\GameServer\Log
set ARCHIVE_DIR=C:\MuServer\GameServer\Log\Archive
set DAYS_OLD=30

if not exist "%ARCHIVE_DIR%" mkdir "%ARCHIVE_DIR%"

REM Mover logs antiguos a la carpeta de archivo
forfiles /p "%LOG_DIR%" /s /m *.log /d -%DAYS_OLD% /c "cmd /c move @path %ARCHIVE_DIR%\"

REM Comprimir archivos movidos (requiere 7-Zip instalado en C:\Program Files\7-Zip\)
"C:\Program Files\7-Zip\7z.exe" a "%ARCHIVE_DIR%\logs_%date:~6,4%%date:~3,2%%date:~0,2%.7z" "%ARCHIVE_DIR%\*.log" -sdel

echo Archivado completado: %date% %time%
Atenção: Verifica la ruta de 7-Zip en tu servidor antes de ejecutar este script. Si no tienes 7-Zip instalado, elimina la línea de compresión y conserva solo el comando forfiles.

Paso 6: Consultas SQL Útiles para Investigaciones

Utiliza estas queries en el día a día para investigar reportes de jugadores:

-- Historial completo de un jugador en las últimas 24 horas
SELECT LogDate, DropType, ItemIndex, ItemLevel, ItemOption,
       MapNumber, MapX, MapY, PlayerIP
FROM Log_ItemDrop
WHERE CharName = 'NombreDelJugador'
  AND LogDate >= DATEADD(HOUR, -24, GETDATE())
ORDER BY LogDate DESC;

-- Verificar si un serial de ítem aparece en múltiples jugadores (dupe)
SELECT CharName, LogDate, DropType
FROM Log_ItemDrop
WHERE ItemSerial = 123456789
ORDER BY LogDate;

-- Jugadores con mayor volumen de drops de ítems raros (posible bot farm)
SELECT CharName, COUNT(*) AS TotalDrops
FROM Log_ItemDrop
WHERE ItemLevel >= 10
  AND LogDate >= DATEADD(DAY, -7, GETDATE())
GROUP BY CharName
ORDER BY TotalDrops DESC;

-- Alertas no leídas para el panel admin
SELECT AlertDate, AlertType, CharName, Description
FROM T_AdminAlerts
WHERE IsRead = 0
ORDER BY AlertDate DESC;

-- Marcar alertas como leídas después de revisión
UPDATE T_AdminAlerts SET IsRead = 1
WHERE IsRead = 0 AND AlertDate < DATEADD(HOUR, -1, GETDATE());

Mantenimiento y Retención de Datos

Conservar logs indefinidamente consume espacio en disco y degrada el rendimiento de las consultas. Configura una rutina de limpieza en SQL Server Agent:

-- Job de limpieza mensual: eliminar logs con más de 90 días
DELETE FROM Log_ItemDrop WHERE LogDate < DATEADD(DAY, -90, GETDATE());
DELETE FROM Log_Trade     WHERE LogDate < DATEADD(DAY, -90, GETDATE());
DELETE FROM T_AdminAlerts WHERE AlertDate < DATEADD(DAY, -30, GETDATE()) AND IsRead = 1;
Dica: Antes de eliminar, haz un backup de las tablas de log a una base de datos separada llamada MuOnline_Archive. Esto preserva el historial sin sobrecargar la base de datos principal.

Solución de Problemas Comunes

El GameServer no está escribiendo logs de texto: Verifica que la carpeta GameServer/Log/ exista y que el proceso del GameServer tenga permiso de escritura en ella. En Windows Server, el usuario que ejecuta GameServer.exe necesita permiso de Modificar en la carpeta Log.

La stored procedure no se está invocando: En versiones de MuServer que no soportan extensión SQL nativa para logs, necesitarás middleware o un script que parsee los archivos de texto e inserte nuevas líneas en SQL cada minuto. Crea un script PowerShell que lea GS_YYYYMMDD.log e inserte entradas nuevas en la base de datos como tarea programada.

La tabla Log_ItemDrop ha crecido demasiado: Ejecuta DBCC SHRINKFILE después de la limpieza y reconstruye el índice: ALTER INDEX ALL ON Log_ItemDrop REBUILD. Esto recupera espacio y mantiene el rendimiento de las consultas.

Perguntas frequentes

¿Dónde escribe el GameServer los logs por defecto?

El GameServer escribe logs de texto en la carpeta GameServer/Log/, con archivos separados por fecha en formato GS_YYYYMMDD.log. Cada línea contiene timestamp, tipo de evento y datos del jugador.

¿Cómo habilitar el log de intercambio de ítems entre jugadores?

En GameServer/Data/GS_Config.ini, define TradeLog=1 y TradeLogLevel=2 para registrar todos los ítems intercambiados con código serial, nivel y opciones de cada ítem.

¿Es posible registrar intentos de hack y exploits?

Sí. Define HackLog=1 en GS_Config.ini. Los intentos de packet injection, speed hack y uso de ítems inválidos se registran en la tabla Log_HackCheck de la base MuOnline con la IP del jugador.

¿Cómo crear alertas automáticas cuando un jugador dropea ítems raros?

Crea un SQL Job en SQL Server Agent que se ejecute cada 5 minutos consultando Log_ItemDrop donde ItemLevel >= 13 o ItemOption = 4 (excellent), e inserta alertas en la tabla T_AdminAlerts para mostrarlas en el panel web.

EQ

Equipo ViciadosMU

Equipe editorial do ViciadosMU — portal de MU Online no ar desde 2003.

Sigue leyendo

Artículos relacionados