Cómo auditar la economía de tu servidor de MU Online con SQL
Usa consultas SQL para detectar ítems duplicados, Zen inflado y cuentas anómalas en tu servidor de MU Online, generando reportes periódicos que protegen la integridad de la economía.
La economía de un servidor de MU Online es un organismo vivo: el Zen entra por el drop de monstruos y sale por tasas y upgrades; los ítems raros son impresos por bosses y destruidos en fallos de refinamiento. Cuando ese flujo está sano, el servidor prospera. Cuando un bug de duplicación (dupe), un e
La economía de un servidor de MU Online es un organismo vivo: el Zen entra por el drop de monstruos y sale por tasas y upgrades; los ítems raros son impresos por bosses y destruidos en fallos de refinamiento. Cuando ese flujo está sano, el servidor prospera. Cuando un bug de duplicación (dupe), un exploit de drop o una cuenta comprometida inyecta valor artificial, la economía se infla, los precios se disparan y los jugadores honestos abandonan el servidor. Auditar la economía con SQL es la forma más directa y confiable de ver lo que está pasando por debajo del juego, sin depender de denuncias ni de la suerte. Este tutorial muestra, a nivel avanzado, cómo escribir consultas para detectar ítems duplicados, Zen inflado y cuentas anómalas, y cómo convertir eso en reportes periódicos.
El principio que guía toda auditoría económica es el de conservación: en una economía sana, lo que existe debe ser explicable por lo que se generó menos lo que se destruyó. Cuando un valor aparece sin origen —Zen que nadie farmeó, un ítem raro en una cantidad mayor de la que ha caído— tienes un síntoma. Las consultas a continuación existen para encontrar esos valores inexplicables rápidamente.
Requisitos previos
- Acceso de lectura a la base de datos del servidor (SQL Server, MySQL o el SGBD que use tu emulador).
- Herramienta de consulta: SQL Server Management Studio, HeidiSQL, DBeaver o similar.
- Idealmente, una réplica o un backup restaurado para ejecutar consultas pesadas sin impactar producción.
- Conocimiento del esquema de tu emulador: nombres de las tablas de cuenta, personaje, inventario y warehouse.
- Permiso para crear objetos (views, tablas de snapshot) si quieres automatizar reportes.
> Aviso: todos los nombres de tabla y columna de abajo (AccountCharacter, Character, warehouse, Money, Serial) son ejemplos de la línea Season 6 y derivados. El esquema real varía por emulador. Siempre revisa el mapeo antes de ejecutar cualquier comando, especialmente los que alteran datos.
Si aún estás montando la infraestructura de base de datos desde cero, la guía de cómo crear un servidor de MU Online cubre la instalación base del SGBD antes de que llegues a la parte de auditoría.
Regla de oro: nunca audites con UPDATE o DELETE
La auditoría es una actividad de lectura. Toda consulta de este tutorial es SELECT. Investigas, exportas evidencias y solo actúas después, y hasta la acción debe preferir congelar/aislar antes que borrar. Ejecutar DELETE o UPDATE durante una investigación destruye la misma traza que estás intentando reconstruir. Si necesitas corregir algo, hazlo en una etapa separada, documentada, y siempre con un backup inmediatamente anterior.
Paso 1: mapear el Zen en circulación
El primer indicador de salud económica es la distribución de Zen. Comienza midiendo el total y la concentración. Si pocas cuentas poseen la mayor parte del Zen del servidor, o si el total crece más rápido que la base de jugadores, algo está mal.
-- Total de Zen en el servidor (personajes + warehouse)
-- Nombres de columna de ejemplo: Money en el personaje, Money en el baúl
SELECT
(SELECT SUM(CAST(Money AS BIGINT)) FROM Character) AS zen_personajes,
(SELECT SUM(CAST(Money AS BIGINT)) FROM warehouse) AS zen_baules;
A continuación, mira quién concentra el Zen. Una cola larga y suave es normal; un escalón abrupto (una cuenta con órdenes de magnitud más que la segunda) es sospechoso.
-- Top 20 personajes por Zen
SELECT TOP 20
Name,
AccountID,
Money AS zen,
cLevel AS nivel,
ResetCount AS resets
FROM Character
ORDER BY CAST(Money AS BIGINT) DESC;
> Interpretación: compara la cima con el esfuerzo. Un personaje con Zen altísimo, pero nivel y resets bajos, no farmeó eso: lo recibió, lo compró de un dupe o explotó un bug. El desfase entre riqueza y progresión es una de las señales más confiables de anomalía.
Paso 2: detectar Zen inflado a lo largo del tiempo
Un número absoluto dice poco sin historial. La forma robusta de detectar inflación es comparar snapshots. Crea una tabla de snapshot y aliméntala periódicamente (idealmente con un job programado).
-- Tabla de historial económico (créala una vez)
CREATE TABLE EconomySnapshot (
snapshot_date DATETIME NOT NULL DEFAULT GETDATE(),
total_zen BIGINT NOT NULL,
total_contas INT NOT NULL,
contas_ativas INT NOT NULL
);
-- Inserción periódica (ejecuta vía job diario)
INSERT INTO EconomySnapshot (total_zen, total_contas, contas_ativas)
SELECT
(SELECT SUM(CAST(Money AS BIGINT)) FROM Character),
(SELECT COUNT(*) FROM MEMB_INFO),
(SELECT COUNT(*) FROM MEMB_INFO WHERE ConnectStat = 1);
Con los snapshots acumulados, calcula la variación. Lo que importa no es el Zen total, sino el Zen por cuenta activa: si sube consistentemente, hay más dinero persiguiendo los mismos ítems, es decir, inflación.
-- Evolución del Zen por cuenta activa (detecta inflación)
SELECT
snapshot_date,
total_zen,
contas_ativas,
total_zen / NULLIF(contas_ativas, 0) AS zen_por_conta_ativa
FROM EconomySnapshot
ORDER BY snapshot_date DESC;
Un salto abrupto de zen_por_conta_ativa entre dos días consecutivos, sin que haya habido un evento oficial de bono, es la señal clásica de un dupe de Zen o un exploit de drop. Prioriza la investigación de la ventana de tiempo en que ocurrió el salto.
Paso 3: detectar ítems duplicados
La detección de dupes depende de cómo el emulador almacena los ítems. Hay dos escenarios:
Escenario A — el emulador tiene serial único por ítem. Es el caso ideal. Un serial repetido en lugares diferentes es prueba directa de duplicación.
-- Ítems con el mismo serial apareciendo más de una vez (dupe directo)
-- Asume una tabla normalizada de ítems con columna Serial
SELECT Serial, COUNT(*) AS ocorrencias
FROM ItemInstance
GROUP BY Serial
HAVING COUNT(*) > 1
ORDER BY ocorrencias DESC;
Escenario B — los ítems son blobs en el inventario/baúl (sin serial). Es el caso más común en emuladores clásicos: el inventario es un campo binario/hexadecimal. Aquí no detectas por serial, sino por exceso de volumen y patrones. La idea es comparar cuántos ejemplares de un ítem raro existen contra cuántos podrían haber caído de forma plausible.
-- Conteo de un ítem raro específico en el baúl de todos los jugadores
-- Busca la firma hex del ítem dentro del blob del warehouse (ejemplo)
SELECT COUNT(*) AS total_encontrado
FROM warehouse
WHERE Items LIKE '%<FIRMA_HEX_DEL_ITEM>%';
Si un ala de nivel 3 que solo cae de un boss semanal, dropeada quizás 10 veces en la historia del servidor, aparece en 60 baúles, tienes duplicación, independientemente de que haya serial. El volumen no cuadra con la emisión. Registra la firma hex de cada ítem raro en un catálogo propio para hacer esa verificación rápida y repetible.
Paso 4: cazar cuentas anómalas
Las cuentas problemáticas suelen destacarse en al menos una dimensión fuera de la curva. Cruza la edad de la cuenta, la riqueza, el tiempo de juego y la progresión.
-- Cuentas nuevas con riqueza desproporcionada (posible receptor de dupe)
SELECT
m.memb___id AS conta,
m.RegDate AS criada_em,
c.Name AS personaje,
c.Money AS zen,
c.ResetCount AS resets
FROM MEMB_INFO m
JOIN AccountCharacter a ON a.Id = m.memb___id
JOIN Character c ON c.AccountID = m.memb___id
WHERE m.RegDate > DATEADD(DAY, -7, GETDATE()) -- cuenta con menos de 7 días
AND CAST(c.Money AS BIGINT) > 1000000000 -- umbral de ejemplo: 1 mil millones
ORDER BY CAST(c.Money AS BIGINT) DESC;
Otro patrón útil: varias cuentas con la misma IP o creadas en el mismo intervalo corto, concentrando ítems raros, típico de una red de dupe o de cuentas mula.
-- Múltiples cuentas compartiendo la misma IP de registro (ejemplo)
SELECT IP AS ip_registro, COUNT(*) AS qtde_contas
FROM MEMB_INFO
GROUP BY IP
HAVING COUNT(*) > 5
ORDER BY qtde_contas DESC;
> Cuidado con los falsos positivos: los cibercafés, las familias y el NAT de operadora comparten IP legítimamente. Una IP repetida es un indicio, no una condena. Siempre corrobóralo con otra señal (riqueza, ítems raros, horarios) antes de actuar.
Tabla de indicadores y umbrales
Usa la tabla de abajo como panel mental. Los umbrales son ejemplos y deben calibrarse al tamaño de tu servidor.
| Indicador | Cómo medir | Señal de alerta | Acción inicial |
|---|---|---|---|
| Zen por cuenta activa | Snapshot diario | Salto abrupto sin evento oficial | Investigar la ventana del salto |
| Concentración de Zen | Top 20 vs. mediana | Cima con órdenes de magnitud más | Auditar las cuentas de la cima |
| Riqueza vs. progresión | Zen alto + resets bajos | Desfase fuerte | Revisar el historial de la cuenta |
| Volumen de ítem raro | Conteo vs. emisión conocida | Volumen por encima de lo ya dropeado | Investigar dupe |
| Serial duplicado | GROUP BY serial | Cualquier ocurrencia > 1 | Congelar los ítems involucrados |
| Cuentas por IP | GROUP BY IP | Muchas cuentas ricas en la misma IP | Corroborar con otras señales |
Paso 5: convertir la auditoría en un reporte periódico
Auditar una vez no protege a nadie; el valor está en la repetición. Consolida las principales consultas en una view y programa la recolección de snapshots. Así, cada día genera una línea de historial que puedes comparar.
-- View de resumen económico diario (lectura rápida)
CREATE VIEW vw_ResumoEconomico AS
SELECT
CAST(GETDATE() AS DATE) AS data_ref,
(SELECT SUM(CAST(Money AS BIGINT)) FROM Character) AS zen_total,
(SELECT COUNT(*) FROM MEMB_INFO) AS contas,
(SELECT MAX(CAST(Money AS BIGINT)) FROM Character) AS maior_zen_individual;
Programa la inserción diaria de snapshot vía job del SGBD (SQL Server Agent, evento de MySQL o tarea externa — varía por emulador y SO). Con el historial en mano, un simple gráfico del zen_por_conta_ativa a lo largo de las semanas revela tendencias que ninguna inspección puntual mostraría.
Errores comunes y soluciones
| Problema | Causa probable | Solución |
|---|---|---|
| La consulta de auditoría cuelga el servidor | Full scan en tabla grande en hora pico | Ejecutar contra réplica/backup, filtrar por fecha, crear índices |
| Los nombres de tabla/columna no existen | El esquema difiere del ejemplo (otro emulador) | Mapear el esquema real antes de ejecutar |
| Falsos positivos por IP compartida | Cibercafé, familia, NAT de operadora | Corroborar con riqueza, ítems raros y horarios |
| Dupe no detectado por serial | El emulador almacena ítems como blob sin serial | Detectar por volumen vs. emisión y por firma hex |
| Overflow al sumar Zen | Columna sumada como INT | Usar CAST(... AS BIGINT) en las agregaciones |
| Evidencia perdida tras el castigo | DELETE/UPDATE hecho antes de exportar los datos | Congelar la cuenta, exportar todo, solo entonces actuar |
Lista de verificación de auditoría
- Backup o réplica disponible para ejecutar consultas pesadas con seguridad
- Esquema real del emulador mapeado (tablas de cuenta, personaje, baúl)
- Todas las consultas de investigación son solo de lectura (SELECT)
- Snapshot de economía siendo recolectado diariamente y almacenado
- Catálogo de firmas hex de los ítems raros creado y actualizado
- Top de Zen y volumen de raros revisados y comparados con la emisión esperada
- Cuentas anómalas identificadas y congeladas antes de cualquier castigo
- Evidencias (saldos, ítems, logs, IPs) exportadas y documentadas
- Revisión manual profunda programada semanalmente
- Auditoría extra planificada tras eventos y actualizaciones grandes
Preguntas frecuentes
¿Con qué frecuencia debo auditar la economía del servidor?
Para servidores activos, una auditoría automática diaria de indicadores clave (top de Zen, nuevos ítems raros, duplicados) y una revisión manual semanal más profunda. Después de grandes eventos o actualizaciones, ejecuta una auditoría extra, pues es cuando suelen surgir los dupes.
¿Cómo detectar ítems duplicados si cada ítem no tiene un ID único?
Depende del emulador. Muchos almacenan los ítems como blobs hexadecimales en el inventario, sin serial. En esos casos detectas los dupes por patrones: la misma firma de ítem raro en cuentas diferentes surgiendo en el mismo intervalo, o un volumen de un ítem por encima del total que ya se ha dropeado. Si el emulador tiene serial de ítem, la detección es directa por serial repetido.
¿Ejecutar consultas pesadas de auditoría puede colgar el servidor?
Puede, si se ejecuta en producción en hora pico sin cuidado. Prefiere ejecutarlas contra una réplica o un backup restaurado, usa índices adecuados y limita el alcance con filtros de fecha. Evita los escaneos completos de tablas grandes en horario de movimiento.
¿Qué hacer al encontrar una cuenta claramente anómala?
No borres nada de inmediato. Congela la cuenta, exporta las evidencias (saldos, ítems, logs), y solo entonces decide la acción. Borrar datos destruye la traza de auditoría y puede castigar a un inocente. Documenta todo antes de cualquier castigo.
¿Las consultas de este tutorial funcionan en cualquier servidor de MU?
Los conceptos sí, pero los nombres de tablas y columnas varían por emulador. Los ejemplos usan nombres comunes de la línea Season 6; adapta AccountCharacter, Character, warehouse y las columnas de Zen al esquema de tu servidor antes de ejecutar.