X3D Anti-Cheat
BETA pricing, join the testing. Evidence-first anti-cheat: Discord embeds with screenshots, HWID bans, Steam/Discord account lock, two-line event guard.
Buy / Get freeConfig builderInstallation
1. Database
Run the bundled install.sql against the same database oxmysql uses.
mysql -u <user> -p <database> < install.sql
Or paste the whole file into HeidiSQL / phpMyAdmin / DBeaver and run it. Safe to re-run. The resource never creates tables itself; a missing one is reported in console.
2. Files
Put the x3d_anticheat folder in resources/ — do not rename the folder (other resources include it by this name).
3. server.cfg
ensure it after oxmysql / es_extended and before any resource that uses the injection layer.
ensure oxmysql
ensure es_extended
ensure x3d_anticheat
set x3d_license_x3d-anticheat "X3D-XXXXX-XXXXX-XXXXX-XXXXX"
set x3d_anticheat_webhook "https://discord.com/api/webhooks/..."
add_ace group.admin x3d_anticheat.admin allow
add_ace group.admin x3d_anticheat.bypass allow
Use set, not sets — sets replicates the value to players.
4. Start the server and verify
Console should show Anti-Cheat system fully initialized and Captured NNN expected resources.
Join the server, then type ac status in the console — it should report the players being tracked.
A red LICENSE CHECK FAILED box means the key has not passed yet. Your server keeps running and players can still join; the detectors just stay idle.
5. Protect your own resources
Two lines in that resource's fxmanifest.lua (first line of each block). No changes to existing code.
server_scripts { '@x3d_anticheat/core/server/inject.lua', 'server/main.lua' }
client_scripts { '@x3d_anticheat/core/client/inject.lua', 'client/main.lua' }
Configuration — config/
| File | What |
|---|---|
config.general.lua |
debug · admin groups · player/resource whitelist · heartbeat · screenshot |
config.detect.lua |
detector switches · Config.Ban.AutoBan · speed/distance thresholds · weapon blacklist · explosions |
config.connect.lua |
connect guard · duplicate accounts · Account Lock · queue · global ban |
config.discord.lua |
embed name/colors |
config.license.lua |
key |
functions/config.functions.server.lua |
hooks onReady · onPunished · onAdminAction · onScreenshot |
Default = evidence-only: detect, store evidence, notify admins; auto-ban only on vehicle/weapon spawn, money cheat, injection, event manipulation, armor. Enable more in Config.Ban.AutoBan once real logs show no false positives.
Discord
Webhooks are set through convars only (players cannot read them): x3d_anticheat_webhook plus per-channel _playercaptured _localbanned _adminactivities _suspiciousaction _globalbanned.
Screenshots need screenshot-basic. By default (Config.Screenshot.Upload = 'discord') the image is attached to the embed directly — nothing is written to disk and no port has to be reachable; the image lives in RAM until the upload answers, then it is dropped.
Want your own archive? Upload = 'link' writes a ring buffer of x3d_anticheat_shots_keep files (default 500) under shots/ and needs a publicly reachable x3d_anticheat_shots_baseurl.
Optional features (off out of the box)
| Feature | Enable at | Needs |
|---|---|---|
| Account Lock | Config.AccountLock.Enabled |
steam_webApiKey + x3d_anticheat_discord_bottoken |
| Require Discord membership | Config.AccountLock.Guild.RequireMember |
GuildId + bot token |
| Priority queue | Config.Queue.Enabled |
bot token + RolePoints |
| Global ban | Config.GlobalBan.Enabled |
ApiEndpoint + x3d_anticheat_globalban_apikey |
Other frameworks / standalone — addons/framework/
The core never touches ESX; everything goes through Framework.* in addons/framework/server.lua and client.lua. A standalone example sits at the bottom of both files — copy it over. Notifications live in addons/notify/.
Commands
/ac help · /ac status · /ac check <id> · /ac violations <id> · /ac ban <id> <days|0> <reason> · /ac unban <identifier> · /ac kick <id> <reason> · /ac banlist · /ac account <discordId|id> · /ac unbind … · /ac queue · /spectate <id>
Exports
exports.x3d_anticheat:BanPlayer(src, reason, days, by)
exports.x3d_anticheat:RecordViolation(src, 'MY_TYPE', 'details', 'medium')
exports.x3d_anticheat:CaptureShot(src, 'tag')
exports.x3d_anticheat:GrantTeleportGrace(src, ms) -- before a legit teleport
exports.x3d_anticheat:RegisterVehicle(netId, src) -- / RegisterPed / RegisterObject
exports.x3d_anticheat:RegisterWeapon(src, weaponHash)
-- client
exports.x3d_anticheat:SetGodModeExempt(true) -- entering a safezone that grants god mode
Troubleshooting
LICENSE CHECK FAILED—LICENSE_INVALIDkey belongs to another product ·NETWORKcannot reach the licence server ·LICENSE_IP_MISMATCHserver IP changed, update it on your account pageTable 'x3d_anticheat_xxx' is missing—install.sqlhas not been run- god mode false positive — safezone scripts must call
SetGodModeExempt(true) - script vehicles/peds deleted — add the resource to
Config.Whitelist.Resourcesor callRegisterVehicle/RegisterPed - ox_lib callbacks rate-limited —
exports.<res>:InjectSetRateLimit(200, 10000)inside that resource - no image in Discord —
ensure screenshot-basic(linkmode also needs a base URL reachable from outside)