Brazil's biggest MU Online portal — since 2003
Tutorial Advanced Admin

How to detect and ban bots automatically in MU Online

Build an automatic bot-detection pipeline for your MU Online server by combining database pattern analysis, in-game CAPTCHA, packet telemetry and scheduled banning, without flooding legitimate players with false positives.

GA Gabriel · Updated on Oct 10, 2024 · ⏱ 18 min read
Quick answer

Bots are the silent plague of MU Online servers. While you sleep, a single bot user runs ten clients on XP spots, piles up Zen and rare items, crashes market prices and discourages the legitimate players who play by hand. In 72 hours an undefended server becomes scorched earth economically. The temp

Bots are the silent plague of MU Online servers. While you sleep, a single bot user runs ten clients on XP spots, piles up Zen and rare items, crashes market prices and discourages the legitimate players who play by hand. In 72 hours an undefended server becomes scorched earth economically. The temptation is to enable an aggressive automatic ban — and the result is usually worse: false positives ban the hardcore player who spends 16 hours farming honestly, generate complaints and burn the server's reputation. The right way out is a layered pipeline: collect signals automatically, score each account, challenge the suspects with a CAPTCHA and reserve the permanent ban for unequivocal cases. This guide shows how to build that pipeline. All table names, columns and thresholds are examples that vary by season/emulator — calibrate them with your server's real data.

Prerequisites

  • SQL Server Management Studio (SSMS) connected to the MuOnline database.
  • SQL Server Agent enabled for scheduled jobs.
  • Administrative access to the GameServer and the ConnectServer.
  • Knowledge of your build's schema: names of MEMB_INFO, MEMB_STAT, Character, and the connection and XP columns.
  • A test environment (or test account) to validate before running in production.
  • A full database backup before any change.
  • Ideally, native CAPTCHA/anti-bot support in the emulator or an anti-cheat module.

> Run the whole pipeline in log mode (without banning) for at least 48 to 72 hours before enabling any automatic ban. This calibration phase is what separates a system that protects from one that destroys the player base.

The philosophy: layered detection with scoring

No single signal proves an account is a bot. One player may farm a lot; another may stay online all day; a third may repeat the same route. What gives away the bot is the combination of these signals. That's why the pipeline assigns points to each indicator and only acts when the sum crosses a threshold. The table below shows an example scoring scheme.

Detected signalPointsRationale
Kills/hour above the human ceiling sustained for 2h+30Volume impossible by hand
Continuous session above 20 hours2524/7 bot
Near-zero position variance20Fixed automated route
Zero chat messages in a long session10Absence of social behavior
Failed in-game CAPTCHA40Almost unequivocal signal
Multiple clients on the same IP above the limit15Bot farm

With this scheme, an account that merely farms a lot accumulates 30 points — suspicious, but not bannable. If it also keeps a 22-hour session (25) and fails the CAPTCHA (40), it reaches 95 and becomes a clear case. The weights and thresholds vary by season/emulator; adjust them by observing the accounts at the top of your legitimate ranking.

Step 1 — Build the scoring infrastructure

Start with two tables: one for detection events and one for accumulated score per account.

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=monitoring,1=challenged,2=banned,3=false positive
);
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,   -- e.g. KILLS_HORA, SESSAO_LONGA
    Points      INT          NOT NULL,
    Detail      VARCHAR(200) NULL,
    CreatedAt   DATETIME     DEFAULT GETDATE()
);
GO

Each time a check finds a signal, it writes an event to Bot_Event and adds the points to Bot_Score. This preserves the evidence trail — indispensable if a player contests the ban.

Step 2 — Behavioral detection via SQL

The cheapest and most powerful layer is behavioral analysis in the database itself. The stored procedure below scans online accounts and records the main signals.

USE MuOnline;
GO

CREATE PROCEDURE dbo.SP_Bot_Scan
AS
BEGIN
    SET NOCOUNT ON;

    -- Signal 1: kills/hour above the ceiling, sustained for 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;

    -- Signal 2: continuous session above 20 hours
    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;

    -- Consolidate the score
    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 complete: ' + CAST(GETDATE() AS VARCHAR);
END;
GO

Note that the consolidation uses a 24-hour window: old points expire, preventing a player from accumulating eternal suspicion over one atypical farming day.

Step 3 — Schedule the scan in SQL Server Agent

  1. In SSMS, expand SQL Server Agent → right-click JobsNew Job.
  2. Name: Bot_Scan_Automatico.
  3. Steps tab → New Step: type Transact-SQL, database MuOnline, command EXEC dbo.SP_Bot_Scan;.
  4. Schedules tab → New Schedule: daily frequency, sub-frequency every 15 minutes.
  5. Confirm that the SQL Server Agent service is Running in services.msc.

A 15-minute interval balances detection freshness with database load. Very large servers can space it to 30 minutes.

Step 4 — Targeted in-game CAPTCHA

The CAPTCHA is the most decisive confirmation layer, because a dumb bot simply doesn't answer. The classic mistake is to ask all players at a fixed interval, which annoys the base. The smart approach is to fire the challenge only at accounts with a suspicious score.

If your emulator has a native anti-bot with CAPTCHA (common from Season 6 onward), configure it to trigger by suspicion where possible:

[AntiBot]
Enable            = 1
QuestionEnable    = 1
QuestionInterval  = 1800     ; 30-min base for suspects
QuestionTimeout   = 120      ; time to answer (seconds)
WrongAnswerLimit  = 2        ; errors before punishing
Punishment        = 1        ; 0=kick, 1=temp ban, 2=perma ban

The questions live in a plain text file, one per line in the format question,answer:

How much is 6 plus 5?,11
What color is blood?,red
How many days are in a week?,7
What month comes after June?,july

Flag in your pipeline who was challenged and record the result. A CAPTCHA failure is worth many points precisely because it's almost unequivocal:

-- Record a CAPTCHA failure (called by the emulator hook or manually)
INSERT INTO dbo.Bot_Event (AccountID, CharName, Signal, Points, Detail)
VALUES ('suspiciousAccount', 'NickBot', 'CAPTCHA_FALHOU', 40, '2 consecutive errors');

> Keep the answers without accents and case-insensitive. Many Brazilian players type without accents and with inconsistent capitalization; requiring "Brasília" with an accent generates false positives among honest people.

Step 5 — Packet telemetry and per-IP limit

The network layer complements the behavioral one. On the ConnectServer, limit simultaneous connections per IP and protect against flooding — bot farms tend to run many clients from the same address.

[ServerInfo]
MaxConnectionPerIP    = 4      ; simultaneous accounts per IP
PacketFloodProtection = 1
MaxPacketsPerSecond   = 60     ; ceiling per connection

Adjust MaxConnectionPerIP carefully: LAN houses and families legitimately share an IP. A value between 3 and 5 usually balances it. Memory-injection detection, client integrity (Main.exe checksum) and speed reading depend on your build's anti-cheat module and are not covered by pure SQL.

Step 6 — Threshold-based banning, with review

Now the piece that closes the pipeline: acting on the score. Split it into two levels — automatic challenge for a medium score and ban with review for a high score.

USE MuOnline;
GO

CREATE PROCEDURE dbo.SP_Bot_Enforce
AS
BEGIN
    SET NOCOUNT ON;

    -- Level 1: 50-89 points -> flag for CAPTCHA challenge
    UPDATE dbo.Bot_Score
    SET Status = 1
    WHERE TotalScore BETWEEN 50 AND 89 AND Status = 0;

    -- Level 2: 90+ points -> ban and disconnect
    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 complete: ' + CAST(GETDATE() AS VARCHAR);
END;
GO

Even at level 2, keep a human review at first: run in log mode, see who would be banned and check manually for a few days. Only then enable the automatic action — and even so, review the queue daily. This is the same principle of responsible moderation that applies to any punishment; if you haven't structured your moderation commands yet, it's worth starting with the basics of how to set up a MU Online server and the manual ban layer before automating.

Step 7 — Review query and false-positive reversal

Every morning, review who the system caught:

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;

If you identify a false positive, reverse it and flag it so the system won't reoffend:

UPDATE MEMB_INFO SET bloc_code = 0 WHERE memb___id = 'honestAccount';
UPDATE dbo.Bot_Score SET Status = 3, TotalScore = 0 WHERE AccountID = 'honestAccount';

Common errors and fixes

ProblemLikely causeFix
Too many false positivesThresholds calibrated for another profileRaise the kills/hour ceiling and the ban threshold; watch the legitimate ranking
Bots go unnoticedSingle-signal detection, bot randomizes movementSum multiple signals; add a targeted CAPTCHA
Scan inserts no eventsDifferent column/table name in the buildCheck the schema with INFORMATION_SCHEMA.COLUMNS
CAPTCHA annoys legitimate playersFixed global-interval triggerFire the CAPTCHA only at accounts with a suspicious score
Job won't runSQL Server Agent stopped or without permissionCheck services.msc and the job history in SSMS
Ban doesn't prevent loginWrong block columnConfirm the real name (bloc_code, block_code, IsBlock) in the schema
Banned account stays onlineForgot to clear ConnectStatInclude the disconnect UPDATE in the enforce

Launch checklist

  • Bot_Score and Bot_Event tables created
  • SP_Bot_Scan validated in the test environment
  • Bot_Scan_Automatico job scheduled and Agent running
  • Scoring scheme calibrated with the server's real data
  • In-game CAPTCHA configured and triggering by suspicion
  • CAPTCHA questions without accents and case-insensitive
  • Per-IP connection limit adjusted on the ConnectServer
  • SP_Bot_Enforce running in log mode for 48-72h before banning
  • Daily review routine for the suspect queue defined
  • False-positive reversal process documented
  • Evidence (events) retained for at least 30 days
  • Database backup taken before enabling in production

Bot detection that works isn't the most aggressive — it's the most disciplined. By collecting signals automatically, scoring in layers, challenging before punishing and reserving the ban for clear cases, you clean the real bots off your server without turning every dedicated player into a victim. That balance is what keeps the economy healthy and the player base trusting your server.

Frequently asked questions

Can you ban bots 100% automatically without risk?

Not with full safety. Full automation generates false positives that ban legitimate players and destroy the server's reputation. The recommended approach is automatic in detection and evidence collection, but with a human review window or a scoring system with a high threshold before a permanent ban. A 100% automatic ban is only acceptable for unequivocal signals, such as a failed answer on a repeated CAPTCHA.

How do I tell a bot from a dedicated player who plays many hours?

Human players have variance: irregular breaks, spot changes, sporadic chat, reaction times that fluctuate. Bots are metronomic — the same route, the same interval between kills, zero social interaction, continuous sessions of 20 hours or more. Robust detection cross-references several signals instead of looking at just one, precisely so it doesn't punish the legitimate hardcore player.

Doesn't an in-game CAPTCHA annoy players?

If poorly calibrated, yes. The key is the frequency and the trigger. Instead of asking everyone every 20 minutes, fire the CAPTCHA only at accounts that have already accumulated suspicion points from other signals. That way the honest player rarely sees a question, while the suspect is challenged frequently. The ideal interval varies by season/emulator and by your audience's profile.

Can bots evade movement-pattern detection?

Advanced bots add random noise to mimic humans, which defeats detection based on a single signal alone. That's why effective defense is layered: even if the bot randomizes its movement, it tends to fail the CAPTCHA, keep sessions that are too long or generate an impossible volume of kills. No single layer is enough; the combination is what works.

Do I need an external anti-cheat or does the database solve it?

The database solves the behavioral layer (kills/hour, time online, XP patterns) and is where you start. But packet telemetry, client integrity checks and memory-injection detection require support from the emulator or an external anti-cheat module. Full coverage combines SQL analysis with whatever client-side protection your build offers.

GA
Guides & builds editor

Gabriel covers gameplay, class builds, PvP and progression. He tests every strategy on a live server before publishing.

Keep reading

Related articles