Safe Events
Mod menus can fire any server event they like, for example your boss menu's withdrawMoney. Safe events only accept a protected event if it came from your own client code.
It has two parts.
1. Client wrapper
client/safeevents.lua wraps TriggerServerEvent. Each time a script calls it, the wrapper first sends a short sbanticheat:server:validateEvent message naming the event, waits 250 ms, then sends the real event. An executor that fires the event directly skips the wrapper, so the heads-up never reaches the server.
Add it to the fxmanifest.lua of each resource whose events you want protected. It must be the first client script:
client_scripts {
'@sbanticheat/client/safeevents.lua', -- must be above everything else
'client/main.lua',
}Because of the 250 ms wait, only use it on resources that fire events occasionally, such as menus and banking. Don't use it on events that fire every frame.
2. Server list
shared/safeevents.lua:
SB.safeEvents = {
enabled = true,
punishment = "log", -- "ban" | "kick" | "log"
protectedEvents = {
["qb-bossmenu:server:withdrawMoney"] = true,
["qb-bossmenu:server:depositMoney"] = true,
},
}For every event set to true, the server expects the heads-up from that same player just before the event arrives. If it doesn't come, the event is cancelled, a SafeEventViolation is logged, and the player gets the punishment set here, not the global one. Set an event to false to stop protecting it.
Safe events is off by default. Start with "log" so you can confirm your legitimate scripts aren't being caught, then switch to "kick" or "ban".
