SAFScriptsDocs

Configuration

SAF Anticheat is coming soon. These docs describe the build that will ship.

On this page

Everything is in config.lua, grouped by section. The per-check settings (severity, action, cooldown, cancel) are covered in Checks & codes.

General

OptionDefaultWhat it does
Config.Framework'auto''auto', 'qbx', 'qb', 'esx', 'nd', 'ox' or 'standalone'
Config.ServerNamenilShown at the top of the staff panel. nil uses your server's project name
Config.PrintFlagstruePrint every flag to the server console. Handy during the shadow week

Rollout

OptionDefaultWhat it does
Config.ShadowModefalseEverything runs and logs, but no action goes past Shadow.MaxAction
Config.Shadow.MaxAction'alert'Highest action in shadow mode
Config.Shadow.StillCancel4 codesCodes still blocked in shadow mode: ENT_BLACKLIST, EXPL_SILENT, EXPL_BLOCKED, WEAP_GIVE_OTHER
Config.AutoBanfalseAutomatic bans for codes in Config.Certain. With it off, a ban becomes a kick
Config.CanceltrueTurn every cancel (blocked entity, explosion, damage, task clear) on or off at once

Score and actions

Every flag adds its severity to the player's score. The highest of the code's own action and the score's action runs.

OptionDefaultWhat it does
Config.Score.Decay10Points drained per minute
Config.Score.Alert40Score that alerts staff
Config.Score.Screenshot70Score that takes a screenshot and alerts staff
Config.Score.Kick100Score that kicks, unless staff open or act on the player within KickDelay
Config.Score.KickDelay60Seconds staff have to step in before a score kick
Config.StaffMaxAction'screenshot'Highest automatic action for staff. nil treats staff exactly like players

Actions, weakest first:

ActionWhat happens
'log'Console and the player's history
'alert'Staff in game, Discord and a case
'screenshot'An alert plus a screenshot
'kick'The player is removed
'ban'Only for certain flags with AutoBan on

Alerts

OptionDefaultWhat it does
Config.Alerts.Cooldown60Same player and same code alerts staff at most once per this many seconds
Config.Alerts.DiscordtrueAlerts also go to the log
Config.Alerts.LogAllfalseSend every flag to Discord, not just alerts
Config.Alerts.Key'F10'Default key for /ac. Players can rebind it

Messages

Config.Messages holds the text players see: Kick (with the reason), Warn, Ban (ban id, reason, expiry and appeal text) and Checking, shown while a joining player is checked against the ban list.

Exemptions

Config.Exempt is empty by default. Entries are per identifier (players), per ACE (aces) or per code (codes). Each entry is one mode for every code, or a table of code = mode with '*' for the rest. See Exemptions.

Panel and permissions

Config.Permissions maps each panel action to an ACE:

PermissionDefault ACEAllows
viewac.staffOpen the panel, see players, flags and cases
alertsac.staffGet the in-game alerts
caseac.staffMark cases open, cheater or false positive
screenshotac.staffTake a screenshot
warnac.staffWarn a player
teleportac.staffSpectate, goto and bring
clearac.staffClear a player's score
kickac.kickKick
ban, unbanac.banBan and lift bans
ipac.ipSee IP addresses
exemptac.exemptThe "allow" action: log-only for the session
settingsac.staffSee the checks screen
OptionDefaultWhat it does
Config.AdminGroupsgod, admin, superadminFramework groups that get every permission
Config.PanelAllowMode'log'What "allow" from the panel does for the rest of the session: 'log' or 'ignore'

Grace windows

Config.Grace sets how long each window lasts and how much flags inside it count. severity scales the flag: 0 is no flag, 0.25 a quarter, 1 full. Flags inside a window are never certain. The full list is in Grace windows.

OptionDefaultWhat it does
Config.Grace.<kind>.secondsvariesLength of the window
Config.Grace.<kind>.severityvariesMultiplier for flags inside it
Config.Grace.client.max, .window6, 300A player's own client can ask at most 6 times per 5 minutes
Config.Grace.<kind>.coversmovement codesCodes the window applies to
Config.GraceCoversTP_DIST, SPD, NOCLIP, TP_OOB, SPECTATEDefault codes for windows without covers

Entities

OptionDefaultWhat it does
Config.Entities.Limits.object15 in 10 sMore created in the window is ENT_SPAM and blocked
Config.Entities.Limits.vehicle4 in 10 sSame, for vehicles
Config.Entities.Limits.ped6 in 10 sSame, for peds
Config.Entities.SpamCertain5 in 30 sENT_SPAM this often is certain
Config.Entities.Caps60 objects, 8 vehicles, 20 pedsMost entities one player may own at once (ENT_CAP)
Config.Entities.PopulationTypes{ [7] = true }Only script-created entities count. Ambient traffic is never touched
Config.Entities.ModelLimitsemptyPer-model limits: prop_roadcone02a = { max = 10, window = 60 } (ENT_MODEL)
Config.Entities.Blacklistabout 110 modelsModels with no legit use, blocked before they exist (ENT_BLACKLIST)

The blacklist ships with stunt ramps and oversized props, military and weaponised vehicles (jets, tanks, the Oppressor Mk II, armed helicopters, cargo planes, blimps) and a few peds such as the juggernaut and whales. Remove a model if your server uses it legitimately.

Explosions

OptionDefaultWhat it does
Config.Explosions.Allowedlist of type idsExplosion types anyone may cause. Everything else is EXPL_BLOCKED
Config.Explosions.Ambientvehicle and fuel typesChecked with the larger AmbientDistance
Config.Explosions.RemoteDistance150Weapon explosions further than this from the sender are EXPL_REMOTE
Config.Explosions.AmbientDistance400Vehicle and fuel explosions further than this are EXPL_REMOTE
Config.Explosions.RemoteCertain500Further than this is certain
Config.Explosions.Rate4 in 5 sMore is EXPL_RATE
Config.Explosions.CheckSilenttrueInvisible or silent explosions are EXPL_SILENT

The allowed list covers molotovs, vehicles, fuel, pumps, gas canisters, barrels, propane, fire extinguishers, flares, smoke and BZ gas, snowballs, and flash and stun grenades. Grenades, rockets and explosive ammo are not on it. Type ids are listed in the FiveM natives docs under eExplosionTag.

Movement

OptionDefaultWhat it does
Config.Movement.Limitssee belowMetres per second by what the player is in
Config.Movement.Slack0.25Extra 25% on every limit
Config.Movement.MinDistance5Metres always allowed per sample on top
Config.Movement.TeleportRatio1.5Over this many times the limit in one second is TP_DIST
Config.Movement.BigRatio, BigSeverity3, 80Over 3 times the limit gets severity 80
Config.Movement.ShortDistance, ShortSeverity300, 10Jumps shorter than 300 m get severity 10 (elevators, MLO doors, interiors)
Config.Movement.CertainDistance2000On foot, outside any grace and none in the last 30 s, is certain
Config.Movement.SpeedSamples, SpeedHits5, 3SPD when over the limit in 3 of the last 5 seconds
Config.Movement.NoclipSeconds, NoclipHeight4, 3.0NOCLIP when client and server agree the player hangs this long, this high
Config.Movement.MinZ-800.0Under this is TP_OOB. Housing shells and some MLOs sit well under the map
Config.Movement.MaxXY-8000 to 8000, -8000 to 10000Map bounds for TP_OOB
Config.Movement.SpectateDistance, SpectateSeconds400, 30SPECTATE when the camera is this far from the ped for this long

Speed limits in m/s: foot 15, fall 70, cars, bikes, boats, trains and amphibious vehicles 110, heli and blimp 120, plane 220.

Health

OptionDefaultWhat it does
Config.Health.MaxHealth200Player ped max health. Raise it if a script gives more
Config.Health.MaxArmour100Max armour
Config.Health.Margin5Allowed over the max
Config.Health.CertainHealth500GOD_HP at or above this is certain
Config.Health.HealFrom, HealTo150, 195HEAL_INSTANT: from under 150 to at least 195 within a second
Config.Health.GodHits10GOD_DMG: confirmed hits in a row with no health or armour lost
Config.Health.GodWorkingShare0.5Only when at least half the hits on other players hurt them, so servers with friendly fire off never flag
Config.Health.InvincibleChecks3GOD_FLAG: client reports invincible this many checks in a row, 10 s apart
Config.Health.SafeZonesempty{ x, y, z, radius } areas where damage checks don't apply

Weapons and damage

OptionDefaultWhat it does
Config.RestrictedWeapons15 weaponsSpawn name to label. Removed from anyone holding them (WEAP_BLACKLIST)
Config.WeaponCheckEvery2Seconds between server checks of the weapon in hand
Config.Combat.Factor1.5Damage over the weapon's damage times this is DMG_AMOUNT
Config.Combat.RangeFactor, RangeExtra1.2, 10Hits beyond range times 1.2 plus 10 m are DMG_RANGE
Config.Combat.VehicleFarDistance300Vehicle damage from further is DMG_VEH_FAR
Config.Combat.WeaponMismatch3 in 10 sDMG_WEAPON after this many hits with a weapon not in hand
Config.Combat.MultiKill3 victims in 1.0 sDMG_MULTIKILL
Config.Combat.Headshots30 hits, rate 0.8, average 0.4DMG_HEADSHOT compares a player's rate with the server average
Config.Combat.HeadComponent20The hit component the game uses for the head
Config.Combat.CancelOutOfRangefalseAlso block hits from beyond range
Config.Combat.Weaponsabout 45 firearmsBase damage per hit and range in metres. Shotguns use factor = 3
Config.Combat.NonLethalstun gun, snowball, extinguisher...Weapons that never count towards GOD_DMG

Restricted by default: RPG, homing, grenade and compact launchers, minigun, railguns, EMP and firework launchers, the three ray weapons, sticky bombs, pipe bombs and proximity mines. Add a firearm to Config.Combat.Weapons if an addon weapon trips the damage checks:

custom/shared/weapons.lua
Config.Combat.Weapons.WEAPON_MYADDONRIFLE = { damage = 34, range = 500 }

Event firewall

OptionDefaultWhat it does
Config.Firewall.EnabledtrueTurn the firewall off
Config.Firewall.AutoDiscovertrueFind the net events of every running resource from the files each fxmanifest names
Config.Firewall.Rate40 in 10 s, certain at 200Default rate limit per event (EVT_RATE)
Config.Firewall.LimitsemptyPer event: ['my:event'] = { max = 100, window = 10, certain = 1000 }, or false to skip it
Config.Firewall.WatchemptyExtra events auto discovery can't find, such as ones in globbed files
Config.Firewall.Ignore4 eventsNever rate limited: playerJoining, playerDropped and two internal ones
Config.Firewall.NoisyPlayers, NoisyWindow2, 600An event this many players go over in 600 s is the resource's own doing and stops being checked until restart
Config.Firewall.Honeypotsabout 35 namesFake events cheat menus try (EVT_HONEYPOT). Skipped when a running resource owns the name
Config.Firewall.SchemasemptyArgument checks for any event (EVT_SCHEMA), see below
Config.Firewall.Known10 eventsKnown exploitable events and who may fire them (EVT_EXPLOIT)

The honeypots are old ESX, vRP and admin menu money and job events that menus fire blindly. The known list covers revive, cuff, jail and boss withdraw events from common free resources, limited to the ambulance or police job or to bosses.

Schemas are opt in. A ? after a type means the argument may be missing:

custom/shared/firewall.lua
Config.Firewall.Schemas['shop:buy'] = {
    args = { 'string', 'number' },
    ranges = { [2] = { 1, 50 } },
    near = { vec3(25.7, -1347.3, 29.5), 20.0 },
}
Config.Firewall.Known['my-job:server:payout'] = { jobs = { 'trucker' } }

Players affecting players

OptionDefaultWhat it does
Config.Players.AttachSeconds5Attached to another player's ped this long without an attach grace is PLY_ATTACH
Config.Players.TasksCertain3 in 10 sPLY_TASKS this often is certain
Config.Players.TasksNear, TasksNearSeverity5.0, 10A task clear from this close is likely a script (cuffs, escort): severity 10, never certain
Config.Players.PtfxDistance150.0Particle effects further than this are PLY_PTFX
Config.Players.PtfxRate30 in 10 sParticle flood limit

Heartbeat and client checks

OptionDefaultWhat it does
Config.Heartbeat.Every15Seconds between client heartbeats
Config.Heartbeat.Timeout60Missed this long is HB_MISS
Config.Heartbeat.KickAfter3Misses in a row before a kick
Config.Heartbeat.FirstWithin300A player who never sends one this long after joining counts as a miss
Config.Heartbeat.WatchemptyResources whose client stop is reported (RES_STOP). Add your important ones
Config.Heartbeat.IgnoreResources_cfx_internalNever reported
Config.Client.CheckEvery30Seconds between client menu checks, spread over frames
Config.Client.Textures18 namesTexture dictionaries known menus load (MENU_TXD)
Config.Client.Commands15 namesCommands known menus register (MENU_CMD)
Config.Client.CommandOwnersemptyResources allowed to register those commands
Config.Client.Globals27 namesGlobals known menus leave behind (MENU_GLOBAL)
Config.Client.SuperJumpHeight4.0A jump that climbs more is MENU_PEDFLAG
Config.Client.InfiniteAmmoShots40Sampled shots with the ammo count never dropping (AMMO_INFINITE)

Bans

OptionDefaultWhat it does
Config.Bans.IdPrefix'AC'Ban ids look like AC-7K2Q
Config.Bans.AppealText'Appeal at: ...'Shown on the ban screen. Put your appeal link here
Config.Bans.StoreIpfalseKeep the IP with the ban
Config.Bans.MatchIpfalseAlso refuse joins from a banned IP
Config.Bans.TokenMatches2Hardware tokens that must match. One alone can be shared
Config.Bans.Identifierslicense, license2, fivem, discord, steam, xbl, liveIdentifier types that ban on a single match
Config.Bans.UseTxAdminfalseAlso call Bridge.ExternalBan for each ban

Logs and screenshots

OptionDefaultWhat it does
Config.Discord.Webhook''Discord webhook for logs. Empty is console only
Config.Discord.Name'Anticheat'Name on the webhook posts
Config.Discord.Color0xD7262CEmbed colour
Config.Screenshots.Webhook''Discord webhook screenshots are uploaded to. Empty turns screenshots off
Config.Screenshots.Quality0.6JPEG quality
Config.Screenshots.Cooldown120At most one per player per this many seconds

To send logs or screenshots somewhere other than Discord, replace Bridge.Log or Bridge.UploadScreenshot. See Custom servers.

Hooks

The bottom of config.lua lists the Hooks.* functions you can set from custom/ to change any check without touching the resource. They are covered in Custom servers.

SAF Scripts by San Andreas' Finest StoreDiscordsupprot@safrp.org

Not affiliated with or endorsed by Rockstar Games, Take-Two Interactive or Cfx.re.