El mayor portal de MU Online de Brasil — desde 2003
Tutorial Intermedio Admin

Scripts útiles para Game Master en lote en el servidor de MU Online

Automatiza tareas repetitivas de Game Master en tu servidor de MU Online con scripts en lote: distribución de ítems, baneos, resets masivos, limpieza de cuentas inactivas y anuncios programados.

BR Bruno · Actualizado el 11 feb 2026 · ⏱ 15 min de lectura
Respuesta rápida

Administrar un servidor de MU Online con cientos o miles de cuentas activas hace inviable ejecutar cada acción de moderación, evento o mantenimiento manualmente, una cuenta a la vez. Los scripts de GM en lote resuelven este cuello de botella, permitiendo distribuir premios de evento a una lista de g

Administrar un servidor de MU Online con cientos o miles de cuentas activas hace inviable ejecutar cada acción de moderación, evento o mantenimiento manualmente, una cuenta a la vez. Los scripts de GM en lote resuelven este cuello de botella, permitiendo distribuir premios de evento a una lista de ganadores, banear cuentas por patrón de comportamiento, resetear personajes en masa o limpiar cuentas inactivas con un único comando revisado y auditable. Este tutorial reúne los scripts más útiles para el día a día de la administración, con el cuidado que las acciones en lote exigen —porque un UPDATE sin WHERE correcto puede destruir la economía del servidor en segundos.

Por qué centralizar las acciones de GM en scripts

Las acciones hechas manualmente, comando por comando, tienen tres problemas: son lentas a escala, no dejan rastro de auditoría confiable y son inconsistentes entre distintos GMs. Un script versionado resuelve los tres: corre en segundos sobre miles de filas, registra un log de cada acción, y cualquier GM autorizado lo ejecuta de la misma forma. La regla de oro es siempre correr la versión SELECT del filtro antes de la versión UPDATE/DELETE, confirmando el número de filas afectadas.

Requisitos previos

  • Acceso de lectura y escritura a la base de datos del servidor (MSSQL o MySQL, según el emulador).
  • Backup reciente de la base de datos antes de cualquier ejecución en lote.
  • Una tabla de auditoría (GMActionLog o equivalente) para registrar quién ejecutó qué y cuándo.
  • Ambiente de prueba/staging con una copia de la base de datos para validar scripts nuevos antes de correrlos en producción.

Estructura de log de auditoría

Antes de cualquier script en lote, asegúrate de que exista una tabla para registrar las acciones administrativas:

CREATE TABLE GMActionLog (
    LogId INT IDENTITY(1,1) PRIMARY KEY,
    GMAccount VARCHAR(50) NOT NULL,
    ActionType VARCHAR(50) NOT NULL,
    TargetAccount VARCHAR(50) NULL,
    Details VARCHAR(500) NULL,
    ExecutedAt DATETIME DEFAULT GETDATE()
);

Toda acción en lote descrita abajo debe terminar con un INSERT en esa tabla, aunque el resto del script sea simple.

Script 1 — Distribución de ítems en lote (premio de evento)

Para entregar un ítem a una lista de ganadores de evento sin repetir comando por comando:

-- Verificación antes de ejecutar
SELECT AccountID, CharacterName FROM Character
WHERE CharacterName IN ('Jogador1','Jogador2','Jogador3');

-- Distribución (ejemplo MuEMU/IGCN, ajusta la tabla según el emulador)
INSERT INTO WarehouseItems (AccountID, ItemIndex, ItemLevel, ItemOptions, Durability)
SELECT AccountID, 168, 15, 0, 255
FROM Character
WHERE CharacterName IN ('Jogador1','Jogador2','Jogador3');

INSERT INTO GMActionLog (GMAccount, ActionType, Details)
VALUES ('admin_root', 'ITEM_DISTRIBUTION', 'Premio evento verano - 3 cuentas');

Evita entregar ítems directamente al inventario del personaje en línea —prefiere el warehouse (baúl), que no exige que el jugador esté desconectado.

Script 2 — Prevención de entrega duplicada

Para eventos recurrentes, controla quién ya recibió el premio con una tabla de log dedicada:

CREATE TABLE ItemDistributionLog (
    AccountID VARCHAR(50),
    EventCode VARCHAR(50),
    DistributedAt DATETIME DEFAULT GETDATE(),
    PRIMARY KEY (AccountID, EventCode)
);

-- Entrega solo a quien todavía no recibió
INSERT INTO WarehouseItems (AccountID, ItemIndex, ItemLevel)
SELECT c.AccountID, 168, 15
FROM Character c
WHERE c.CharacterName IN ('Jogador1','Jogador2')
AND NOT EXISTS (
    SELECT 1 FROM ItemDistributionLog d
    WHERE d.AccountID = c.AccountID AND d.EventCode = 'VERAO2026'
);

Este patrón evita el error clásico de correr el script dos veces por accidente y duplicar premios valiosos.

Script 3 — Baneo en lote por patrón de comportamiento

Para banear cuentas que comparten características sospechosas (ej. la misma IP con múltiples cuentas farmeando con bot):

-- Verificación: cuántas cuentas serán afectadas
SELECT AccountID, LastIP, LastLoginDate FROM Account
WHERE LastIP IN ('203.0.113.10','203.0.113.11') AND BanStatus = 0;

-- Baneo
UPDATE Account
SET BanStatus = 1, BanReason = 'Uso de bot - IP compartida sospechosa'
WHERE LastIP IN ('203.0.113.10','203.0.113.11') AND BanStatus = 0;

INSERT INTO GMActionLog (GMAccount, ActionType, Details)
VALUES ('admin_root', 'BAN_BATCH', 'Ban por IP sospechosa - 2 IPs, ver SELECT anterior');

Siempre filtra por BanStatus = 0 para no reprocesar cuentas ya baneadas y ensuciar el log.

Script 4 — Reset masivo de personajes (evento de reset gratuito)

Para un evento de reset gratuito limitado a personajes por encima de determinado nivel:

-- Verificación
SELECT Name, cLevel, ResetCount FROM Character WHERE cLevel >= 400;

-- Reset masivo
UPDATE Character
SET cLevel = 1, Experience = 0, LevelUpPoint = 0,
    ResetCount = ResetCount + 1,
    Strength = 30, Dexterity = 30, Vitality = 30, Energy = 30
WHERE cLevel >= 400;

INSERT INTO GMActionLog (GMAccount, ActionType, Details)
VALUES ('admin_root', 'MASS_RESET', 'Evento reset gratuito - cLevel >= 400');

Los valores base de atributo (Strength, Dexterity, etc.) varían según la clase —ajusta la consulta con un CASE por clase si tu servidor no usa atributos base uniformes.

Script 5 — Limpieza de cuentas inactivas

Para identificar y opcionalmente archivar cuentas sin inicio de sesión desde hace mucho tiempo, liberando nombres de personaje y espacio en la base de datos:

-- Identificar cuentas inactivas hace más de 365 días
SELECT AccountID, LastLoginDate FROM Account
WHERE LastLoginDate < DATEADD(DAY, -365, GETDATE());

-- Marcar (no eliminar directamente) para archivado
UPDATE Account
SET AccountStatus = 'ARCHIVED_CANDIDATE'
WHERE LastLoginDate < DATEADD(DAY, -365, GETDATE()) AND AccountStatus = 'ACTIVE';

Nunca hagas DELETE directo de cuentas antiguas en un solo paso —márcalas para archivado, espera un período de gracia (30-60 días) anunciado públicamente, y solo entonces elimínalas o muévelas a una tabla de historial.

Script 6 — Anuncios programados en el servidor

Para notificar a los jugadores sobre mantenimiento o eventos sin depender de un GM escribiendo justo a tiempo, usa una tabla de anuncios leída por un servicio programado:

CREATE TABLE ScheduledAnnouncements (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Message VARCHAR(500),
    ScheduledTime DATETIME,
    Sent BIT DEFAULT 0
);

INSERT INTO ScheduledAnnouncements (Message, ScheduledTime)
VALUES ('Mantenimiento en 30 minutos - guarda tu progreso', DATEADD(MINUTE, 30, GETDATE()));

Un servicio externo (job programado) consulta esa tabla cada minuto y envía el mensaje vía pipe de comando del GameServer cuando llega ScheduledTime, marcando Sent = 1 para no repetirlo.

Buenas prácticas al correr scripts en lote

PrácticaPor qué
Siempre correr SELECT antes del UPDATE/DELETEConfirma el número de filas afectadas antes de comprometer datos
Correr primero en staging/copia de la base de datosEvita descubrir un error de lógica directamente en producción
Registrar toda acción en la tabla de auditoríaPermite investigar reclamos y revertir decisiones con contexto
Usar transacciones (BEGIN TRAN/COMMIT)Permite un ROLLBACK inmediato si el resultado no coincide con lo esperado
Nunca dar acceso de ejecución a todos los GMsReduce el riesgo de error o abuso; centraliza los scripts sensibles en pocos administradores

Usando transacciones para reducir el riesgo

Envolver el script en una transacción permite confirmar el resultado antes de comprometerlo:

BEGIN TRAN;

UPDATE Account SET BanStatus = 1 WHERE LastIP = '203.0.113.10';

-- Verifica el resultado
SELECT * FROM Account WHERE LastIP = '203.0.113.10';

-- Si está correcto:
COMMIT;
-- Si algo está mal:
-- ROLLBACK;

Este patrón es especialmente valioso para acciones irreversibles como el baneo y el reset masivo, donde un error de filtro sale caro.

Organizando los scripts en un repositorio

Al igual que el código del servidor, los scripts de GM deben estar versionados. Una estructura simple:

gm-scripts/
├── eventos/
│   ├── reset-gratuito-2026-07.sql
│   └── premio-verano.sql
├── moderacion/
│   ├── ban-por-ip.sql
│   └── limpieza-inactivos.sql
└── README.md

Cada archivo debe contener, en un comentario, la fecha de uso, el GM responsable y el resultado esperado (cuántas filas afectadas). Esto transforma scripts sueltos en un historial auditable de la administración del servidor.

Errores comunes y soluciones

SíntomaCausa probableSolución
Ítem entregado por duplicadoScript ejecutado dos veces sin verificación de logAgrega una tabla de control de distribución (Script 2)
Cuentas equivocadas baneadasFiltro del WHERE más amplio de lo previstoSiempre corre el SELECT de verificación antes del UPDATE
El reset afectó personajes que no debíaRango de nivel o clase mal filtradoAjusta el WHERE y valida con SELECT en staging primero
Pérdida de datos tras DELETE masivoAusencia de backup inmediatamente anteriorSiempre haz backup y prefiere marcar para archivado en vez de eliminar directo
El anuncio programado no se disparóEl servicio programado no está corriendo o la tabla no se leeVerifica el job/cron responsable y el pipe de comando del GameServer

Lista de verificación antes de correr un script de GM en lote

  • Backup de la base de datos hecho inmediatamente antes de la ejecución.
  • Versión SELECT del filtro corrida y verificada.
  • Script probado en staging o copia de la base de datos.
  • Transacción (BEGIN TRAN) usada para acciones irreversibles.
  • Acción registrada en la tabla de auditoría (GMActionLog).
  • Script versionado en el repositorio de scripts de GM.
  • Acceso de ejecución restringido a administradores autorizados.

Con estos scripts organizados y auditables, el siguiente paso natural es integrarlos al pipeline de mantenimiento del servidor como un todo —consulta el tutorial de creación de servidor de MU Online para entender cómo este flujo administrativo encaja en la operación completa.

Preguntas frecuentes

¿Es seguro correr scripts SQL directamente en producción para acciones de GM?

Solo con un backup inmediatamente anterior y una prueba previa en staging o en una copia de la base de datos. Las acciones en lote (UPDATE/DELETE sin WHERE preciso) son la causa más común de accidentes graves en servidores de MU —siempre corre primero un SELECT con los mismos filtros para confirmar cuántas filas serán afectadas.

¿Estos scripts reemplazan los comandos de GM in-game?

No del todo. Los comandos in-game (como /additem o /ban) son mejores para acciones puntuales y para GMs sin acceso técnico a la base de datos. Los scripts en lote tienen sentido cuando la acción afecta a decenas o cientos de cuentas a la vez, lo cual sería inviable comando por comando.

¿Cómo evitar que un script de distribución de ítems duplique entregas?

Registra cada entrega en una tabla de log (ej. ItemDistributionLog) con el ID de la cuenta y el ID del evento, y haz que el script verifique esa tabla antes de insertar el ítem nuevamente. Esto también sirve como auditoría en caso de que un jugador reclame que no recibió el premio.

¿Puedo programar estos scripts para que corran solos?

Sí, usando el SQL Server Agent (MSSQL) o un cron job que llame a un script que ejecute la consulta. Es común para tareas como la limpieza de cuentas inactivas o el reseteo de eventos diarios, pero las acciones sensibles (baneo, remoción de ítem) deben mantener aprobación manual antes de ejecutarse.

¿Cuál es el riesgo de dar reset masivo a todos los personajes?

Si la consulta no filtra correctamente por nivel mínimo o clase, puedes resetear personajes que no debían, causando pérdida de builds y reclamos masivos. Siempre corre el SELECT de verificación antes y avisa a la comunidad con anticipación sobre la ventana de mantenimiento.

BR
Editor de eventos, mapas e ítems

Bruno es especialista en eventos, mapas, bosses y economía de ítems de MU Online. Documenta cada detalle basándose en el juego real.

Sigue leyendo

Artículos relacionados