Cómo detectar y banear bots automáticamente en MU Online
Monta un pipeline de detección automática de bots en tu servidor de MU Online combinando análisis de patrones en la base de datos, CAPTCHA in-game, telemetría de paquetes y baneo programado, sin inundar a jugadores legítimos con falsos positivos.
Los bots son la plaga silenciosa de los servidores de MU Online. Mientras duermes, un único usuario de bot corre diez clientes en spots de XP, acumula Zen e ítems raros, tira los precios del mercado y desmotiva a los jugadores legítimos que juegan a mano. En 72 horas un servidor sin defensa se convi
Los bots son la plaga silenciosa de los servidores de MU Online. Mientras duermes, un único usuario de bot corre diez clientes en spots de XP, acumula Zen e ítems raros, tira los precios del mercado y desmotiva a los jugadores legítimos que juegan a mano. En 72 horas un servidor sin defensa se convierte en tierra arrasada económicamente. La tentación es activar un baneo automático agresivo — y el resultado suele ser peor: los falsos positivos banean al jugador hardcore que pasa 16 horas farmeando de forma honesta, generan reclamos y queman la reputación del servidor. La salida correcta es un pipeline en capas: recolectar señales de forma automática, puntuar cada cuenta, desafiar a los sospechosos con CAPTCHA y reservar el ban permanente para los casos inequívocos. Esta guía muestra cómo montar ese pipeline. Todos los nombres de tabla, columnas y umbrales son ejemplos que varían por season/emulador — calíbralos con los datos reales de tu servidor.
Requisitos previos
- SQL Server Management Studio (SSMS) conectado a la base de datos
MuOnline. - SQL Server Agent habilitado para jobs programados.
- Acceso administrativo al GameServer y al ConnectServer.
- Conocimiento del schema de tu build: nombres de
MEMB_INFO,MEMB_STAT,Character, columnas de conexión y de XP. - Un entorno de prueba (o cuenta de prueba) para validar antes de correr en producción.
- Backup completo de la base de datos antes de cualquier cambio.
- Idealmente, soporte de CAPTCHA/anti-bot nativo en el emulador o un módulo anti-cheat.
> Corre todo el pipeline en modo de log (sin banear) durante al menos 48 a 72 horas antes de activar cualquier ban automático. Esa fase de calibración es lo que separa un sistema que protege de uno que destruye la base de jugadores.
La filosofía: detección en capas con puntuación
Ninguna señal aislada prueba que una cuenta es un bot. Un jugador puede farmear mucho; otro puede estar online todo el día; un tercero puede repetir la misma ruta. Lo que delata al bot es la combinación de esas señales. Por eso el pipeline asigna puntos a cada indicio y solo actúa cuando la suma cruza un umbral. La tabla de abajo muestra un esquema de puntuación de ejemplo.
| Señal detectada | Puntos | Justificación |
|---|---|---|
| Kills/hora por encima del techo humano sostenido por 2h+ | 30 | Volumen imposible a mano |
| Sesión continua por encima de 20 horas | 25 | Bot 24/7 |
| Varianza de posición casi nula | 20 | Ruta fija automatizada |
| Cero mensajes de chat en una sesión larga | 10 | Ausencia de comportamiento social |
| Falla en CAPTCHA in-game | 40 | Señal casi inequívoca |
| Múltiples clientes en la misma IP por encima del límite | 15 | Granja de bots |
Con este esquema, una cuenta que solo farmea mucho acumula 30 puntos — sospechosa, pero no baneable. Si además mantiene una sesión de 22 horas (25) y falla el CAPTCHA (40), llega a 95 y se vuelve un caso claro. Los pesos y umbrales varían por season/emulador; ajústalos observando las cuentas del tope de tu ranking legítimo.
Paso 1 — Crear la infraestructura de puntuación
Empieza con dos tablas: una de eventos de detección y una de puntuación acumulada por cuenta.
USE MuOnline;
GO
CREATE TABLE dbo.Bot_Score (
AccountID VARCHAR(10) PRIMARY KEY,
TotalScore INT NOT NULL DEFAULT 0,
LastUpdate DATETIME DEFAULT GETDATE(),
Status TINYINT DEFAULT 0 -- 0=monitoreando,1=desafiado,2=baneado,3=falso positivo
);
GO
CREATE TABLE dbo.Bot_Event (
EventID INT IDENTITY(1,1) PRIMARY KEY,
AccountID VARCHAR(10) NOT NULL,
CharName VARCHAR(10) NULL,
Signal VARCHAR(60) NOT NULL, -- ej.: KILLS_HORA, SESSAO_LONGA
Points INT NOT NULL,
Detail VARCHAR(200) NULL,
CreatedAt DATETIME DEFAULT GETDATE()
);
GO
Cada vez que una verificación encuentra una señal, graba un evento en Bot_Event y suma los puntos en Bot_Score. Esto preserva el rastro de evidencia — indispensable si un jugador impugna el ban.
Paso 2 — Detección de comportamiento vía SQL
La capa más barata y poderosa es el análisis de comportamiento en la propia base de datos. El stored procedure de abajo recorre las cuentas online y registra las señales principales.
USE MuOnline;
GO
CREATE PROCEDURE dbo.SP_Bot_Scan
AS
BEGIN
SET NOCOUNT ON;
-- Señal 1: kills/hora por encima del techo, sostenido por 2h+
INSERT INTO dbo.Bot_Event (AccountID, CharName, Signal, Points, Detail)
SELECT c.AccountID, c.Name, 'KILLS_HORA', 30,
'PkCount=' + CAST(c.PkCount AS VARCHAR)
FROM Character c
INNER JOIN MEMB_STAT s ON c.AccountID = s.memb___id
WHERE s.ConnectStat = 1
AND DATEDIFF(HOUR, s.ConnectTM, GETDATE()) >= 2
AND (c.PkCount / NULLIF(DATEDIFF(HOUR, s.ConnectTM, GETDATE()), 0)) > 1000;
-- Señal 2: sesión continua por encima de 20 horas
INSERT INTO dbo.Bot_Event (AccountID, CharName, Signal, Points, Detail)
SELECT s.memb___id, c.Name, 'SESSAO_LONGA', 25,
CAST(DATEDIFF(HOUR, s.ConnectTM, GETDATE()) AS VARCHAR) + 'h'
FROM MEMB_STAT s
INNER JOIN Character c ON s.memb___id = c.AccountID
WHERE s.ConnectStat = 1
AND DATEDIFF(HOUR, s.ConnectTM, GETDATE()) > 20;
-- Consolidar puntuación
MERGE dbo.Bot_Score AS tgt
USING (
SELECT AccountID, SUM(Points) AS Pts
FROM dbo.Bot_Event
WHERE CreatedAt >= DATEADD(HOUR, -24, GETDATE())
GROUP BY AccountID
) AS src
ON tgt.AccountID = src.AccountID
WHEN MATCHED THEN
UPDATE SET TotalScore = src.Pts, LastUpdate = GETDATE()
WHEN NOT MATCHED THEN
INSERT (AccountID, TotalScore) VALUES (src.AccountID, src.Pts);
PRINT 'Bot scan concluido: ' + CAST(GETDATE() AS VARCHAR);
END;
GO
Fíjate en que la consolidación usa una ventana de 24 horas: los puntos antiguos expiran, evitando que un jugador acumule sospecha eterna por un día atípico de farm.
Paso 3 — Programar el scan en el SQL Server Agent
- En SSMS, expande SQL Server Agent → clic derecho en Jobs → New Job.
- Nombre:
Bot_Scan_Automatico. - Pestaña Steps → New Step: tipo
Transact-SQL, databaseMuOnline, comandoEXEC dbo.SP_Bot_Scan;. - Pestaña Schedules → New Schedule: frecuencia diaria, subfrecuencia cada 15 minutos.
- Confirma que el servicio
SQL Server Agentestá En ejecución enservices.msc.
Un intervalo de 15 minutos equilibra la frescura de la detección con la carga en la base de datos. Los servidores muy grandes pueden espaciarlo a 30 minutos.
Paso 4 — CAPTCHA in-game dirigido
El CAPTCHA es la capa de confirmación más decisiva, porque un bot tonto simplemente no responde. El error clásico es preguntar a todos los jugadores en un intervalo fijo, lo que irrita a la base. El enfoque inteligente es disparar el desafío solo para cuentas con puntuación sospechosa.
Si tu emulador tiene anti-bot nativo con CAPTCHA (común de Season 6 en adelante), configúralo para que dispare por sospecha cuando sea posible:
[AntiBot]
Enable = 1
QuestionEnable = 1
QuestionInterval = 1800 ; base de 30 min para sospechosos
QuestionTimeout = 120 ; tiempo para responder (segundos)
WrongAnswerLimit = 2 ; errores antes de castigar
Punishment = 1 ; 0=kick, 1=ban temp, 2=ban perma
Las preguntas quedan en un archivo de texto simple, una por línea en el formato pregunta,respuesta:
Cuanto es 6 mas 5?,11
De que color es la sangre?,rojo
Cuantos dias tiene una semana?,7
Que mes viene despues de junio?,julio
Marca en tu pipeline a quién se desafió y registra el resultado. Una falla de CAPTCHA vale muchos puntos justamente por ser casi inequívoca:
-- Registrar falla de CAPTCHA (llamado por el hook del emulador o manualmente)
INSERT INTO dbo.Bot_Event (AccountID, CharName, Signal, Points, Detail)
VALUES ('contaSuspeita', 'NickBot', 'CAPTCHA_FALHOU', 40, '2 errores consecutivos');
> Mantén las respuestas sin acentos e insensibles a mayúsculas/minúsculas. Muchos jugadores escriben sin acento y con capitalización inconsistente; exigir "Brasília" con acento genera un falso positivo en gente honesta.
Paso 5 — Telemetría de paquetes y límite por IP
La capa de red complementa a la de comportamiento. En el ConnectServer, limita las conexiones simultáneas por IP y protege contra el flood — las granjas de bots suelen correr muchos clientes de la misma dirección.
[ServerInfo]
MaxConnectionPerIP = 4 ; cuentas simultaneas por IP
PacketFloodProtection = 1
MaxPacketsPerSecond = 60 ; techo por conexion
Ajusta MaxConnectionPerIP con cuidado: los cibercafés y las familias legítimamente comparten IP. Un valor entre 3 y 5 suele equilibrar. La detección de inyección de memoria, la integridad del cliente (checksum del Main.exe) y la lectura de velocidad dependen del módulo anti-cheat de tu build y no están cubiertas por SQL puro.
Paso 6 — Baneo por umbral, con revisión
Ahora la pieza que cierra el pipeline: actuar sobre la puntuación. Divídelo en dos niveles — desafío automático para puntuación media y ban con revisión para puntuación alta.
USE MuOnline;
GO
CREATE PROCEDURE dbo.SP_Bot_Enforce
AS
BEGIN
SET NOCOUNT ON;
-- Nivel 1: 50-89 puntos -> marcar para desafio de CAPTCHA
UPDATE dbo.Bot_Score
SET Status = 1
WHERE TotalScore BETWEEN 50 AND 89 AND Status = 0;
-- Nivel 2: 90+ puntos -> banear y desconectar
UPDATE m
SET m.bloc_code = 1
FROM MEMB_INFO m
INNER JOIN dbo.Bot_Score b ON m.memb___id = b.AccountID
WHERE b.TotalScore >= 90 AND b.Status IN (0,1);
UPDATE s
SET s.ConnectStat = 0
FROM MEMB_STAT s
INNER JOIN dbo.Bot_Score b ON s.memb___id = b.AccountID
WHERE b.TotalScore >= 90;
UPDATE dbo.Bot_Score
SET Status = 2
WHERE TotalScore >= 90 AND Status IN (0,1);
PRINT 'Enforce concluido: ' + CAST(GETDATE() AS VARCHAR);
END;
GO
Incluso en el nivel 2, mantén una revisión humana al principio: corre en modo log, mira quién sería baneado y confírmalo manualmente durante unos días. Solo después libera la acción automática — y aun así revisa la cola a diario. Este es el mismo principio de moderación responsable que se aplica a cualquier castigo; si aún no estructuraste los comandos de moderación, conviene empezar por lo básico de cómo crear un servidor de MU Online y por la capa de ban manual antes de automatizar.
Paso 7 — Query de revisión y reversión de falso positivo
Todas las mañanas, revisa a quién atrapó el sistema:
SELECT b.AccountID, b.TotalScore, b.Status,
STRING_AGG(e.Signal, ', ') AS Sinais
FROM dbo.Bot_Score b
LEFT JOIN dbo.Bot_Event e
ON e.AccountID = b.AccountID
AND e.CreatedAt >= DATEADD(HOUR, -24, GETDATE())
WHERE b.Status IN (1,2)
GROUP BY b.AccountID, b.TotalScore, b.Status
ORDER BY b.TotalScore DESC;
Si identificas un falso positivo, revíértelo y márcalo para que el sistema no reincida:
UPDATE MEMB_INFO SET bloc_code = 0 WHERE memb___id = 'contaHonesta';
UPDATE dbo.Bot_Score SET Status = 3, TotalScore = 0 WHERE AccountID = 'contaHonesta';
Errores comunes y soluciones
| Problema | Causa probable | Solución |
|---|---|---|
| Demasiados falsos positivos | Umbrales calibrados para otro perfil | Aumenta el techo de kills/hora y el umbral de ban; observa el ranking legítimo |
| Los bots pasan desapercibidos | Detección de una sola señal, el bot randomiza el movimiento | Suma múltiples señales; agrega CAPTCHA dirigido |
| El scan no inserta eventos | Nombre de columna/tabla diferente en el build | Revisa el schema con INFORMATION_SCHEMA.COLUMNS |
| El CAPTCHA irrita a jugadores legítimos | Disparo por intervalo fijo global | Dispara el CAPTCHA solo para cuentas con puntuación sospechosa |
| El job no corre | SQL Server Agent detenido o sin permiso | Verifica services.msc y el historial del job en SSMS |
| El ban no impide el login | Columna de bloqueo incorrecta | Confirma el nombre real (bloc_code, block_code, IsBlock) en el schema |
| La cuenta baneada sigue online | Faltó poner en cero ConnectStat | Incluye el UPDATE de desconexión en el enforce |
Lista de verificación de lanzamiento
- Tablas
Bot_ScoreyBot_Eventcreadas SP_Bot_Scanvalidada en entorno de prueba- Job
Bot_Scan_Automaticoprogramado y Agent en ejecución - Esquema de puntuación calibrado con datos reales del servidor
- CAPTCHA in-game configurado y disparando por sospecha
- Preguntas del CAPTCHA sin acentos e insensibles a mayúsculas/minúsculas
- Límite de conexiones por IP ajustado en el ConnectServer
SP_Bot_Enforcecorriendo en modo log por 48-72h antes de banear- Rutina de revisión diaria de la cola de sospechosos definida
- Proceso de reversión de falso positivo documentado
- Evidencias (eventos) retenidas por al menos 30 días
- Backup de la base de datos hecho antes de activar en producción
Una detección de bots que funciona no es la más agresiva — es la más disciplinada. Al recolectar señales de forma automática, puntuar en capas, desafiar antes de castigar y reservar el ban para los casos claros, limpias el servidor de los bots reales sin convertir a cada jugador dedicado en víctima. Ese equilibrio es lo que mantiene la economía sana y a la base de jugadores confiando en tu servidor.
Preguntas frecuentes
¿Se puede banear bots de forma 100% automática sin riesgo?
No con seguridad total. La automatización total genera falsos positivos que banean a jugadores legítimos y destruyen la reputación del servidor. El enfoque recomendado es automático en la detección y en la recolección de evidencia, pero con una ventana de revisión humana o un sistema de puntuación con umbral alto antes del ban permanente. El ban 100% automático solo es aceptable para señales inequívocas, como una respuesta reprobada en un CAPTCHA repetido.
¿Cómo diferencio a un bot de un jugador dedicado que juega muchas horas?
Los jugadores humanos tienen varianza: pausas irregulares, cambios de spot, chat esporádico, tiempos de reacción que oscilan. Los bots son metronómicos — misma ruta, mismo intervalo entre kills, cero interacción social, sesiones continuas de 20 horas o más. La detección robusta cruza varias señales en vez de mirar una sola, justamente para no castigar al jugador hardcore legítimo.
¿El CAPTCHA in-game no irrita a los jugadores?
Si está mal calibrado, sí. La clave está en la frecuencia y el disparador. En vez de preguntar a todos cada 20 minutos, dispara el CAPTCHA solo para cuentas que ya acumularon puntos de sospecha por otras señales. Así el jugador honesto rara vez ve una pregunta, mientras el sospechoso es desafiado con frecuencia. El intervalo ideal varía por season/emulador y por el perfil de tu público.
¿Los bots logran burlar la detección por patrón de movimiento?
Los bots avanzados agregan ruido aleatorio para imitar humanos, lo que derrota una detección basada en una sola señal. Por eso la defensa eficaz es en capas: aunque el bot randomice el movimiento, tiende a fallar en el CAPTCHA, mantener sesiones demasiado largas o generar un volumen de kills imposible. Ninguna capa aislada es suficiente; el conjunto es lo que funciona.
¿Necesito un anti-cheat externo o la base de datos lo resuelve?
La base de datos resuelve la capa de comportamiento (kills/hora, tiempo online, patrones de XP) y es donde empiezas. Pero la telemetría de paquetes, la verificación de integridad del cliente y la detección de inyección de memoria exigen soporte del emulador o de un módulo anti-cheat externo. La cobertura completa combina el análisis SQL con lo que tu build ofrezca de protección del lado del cliente.