SAFScriptsDocs

Custom servers

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

On this page

bridge/server.lua and bridge/client.lua are open in every edition. They hold everything SAF Anticheat asks your server. You can edit them, but the better place for your changes is custom/: updates never touch it.

How custom/ works

Files in custom/ load after config.lua and bridge/, so anything defined there replaces the original.

FolderUse it for
custom/shared/*.luaChanging Config values and setting hooks
custom/client/*.luaReplacing the client Bridge.Notify
custom/server/*.luaReplacing any server Bridge.* function and setting hooks

Config overrides

custom/shared/config.lua
Config.ShadowMode = true
Config.Movement.Limits.plane = 260
Config.Health.MaxHealth = 300

Server hooks

FunctionWhat it doesDefault
Bridge.GetName(src)Name in the panel and logsCharacter name if loaded, else the FiveM name
Bridge.GetJob(src)Job name and whether they're a boss, for the known exploitable eventsFrom the framework
Bridge.Can(src, perm)Panel and alert permissions: view, alerts, case, screenshot, warn, teleport, clear, kick, ban, unban, ip, exempt, settingsThe ACEs in Config.Permissions, plus Config.AdminGroups
Bridge.IsStaff(src)The staff tag in the panel. No special treatmentFrom the permissions
Bridge.Notify(src, msg, kind)A message to a playerFramework notification
Bridge.Log(entry)Where logs go. entry = { title, text, color, fields, src, image }Console and Config.Discord.Webhook
Bridge.CaptureScreenshot(src, cb)Take a screenshot, cb(dataUri or nil)screenshot-basic
Bridge.UploadScreenshot(dataUri, name, cb)Store it, cb(url or nil)Posts it to Config.Screenshots.Webhook
Bridge.ExternalBan(src, ban), Bridge.ExternalUnban(ban)Copy bans to another ban list, with Config.Bans.UseTxAdmin onNothing

Your own ranks

custom/server/ranks.lua
function Bridge.Can(src, perm)
    if perm == 'ip' or perm == 'exempt' then
        return exports['my-ranks']:IsOwner(src)
    end
    return exports['my-ranks']:IsStaff(src)
end

Logs somewhere else

custom/server/logs.lua
function Bridge.Log(entry)
    exports['my-logger']:Send('anticheat', entry.title, entry.text, entry.fields)
end

Another ban list

txAdmin has no public ban API for resources, so Bridge.ExternalBan does nothing by default. Point it at whatever your panel offers and set Config.Bans.UseTxAdmin = true:

custom/server/bans.lua
function Bridge.ExternalBan(src, ban)
    exports['my-panel']:AddBan(src, ban.reason)
end

Hooks

Hooks change any check without touching the resource. Set them from custom/shared/ or custom/server/.

HookReturn
Hooks.BeforeFlag(src, code, severity, data)false drops the flag, a number replaces the severity
Hooks.AfterFlag(src, flag)Nothing. Runs after every flag
Hooks.BeforeAction(src, flag, action)false does nothing, or a new action name
Hooks.BeforeBan(src, ban)false stops the ban
Hooks.AllowEntity(src, model, kind, handle)true lets it through every entity check
Hooks.AllowExplosion(src, ev)true lets it through every explosion check
Hooks.Exempt(src, code)'ignore', 'log', 'normal' or nil
Hooks.Grace(src, kind, seconds)Runs when a grace window opens
custom/server/hooks.lua
-- boats are fast on this server
Hooks.BeforeFlag = function(src, code, severity, data)
    if code == 'SPD' and data.vehicle == 'boat' then return false end
end

-- the event props script spawns cones in bulk
Hooks.AllowEntity = function(src, model, kind, handle)
    return model == `prop_roadcone02a` and IsPlayerAceAllowed(src, 'props.place')
end
SAF Scripts by San Andreas' Finest StoreDiscordsupprot@safrp.org

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