Scriptingintermediate13 min readupdated 11 Sept 2026

Validating weapons and damage on the server

The short answer

Treat everything the client says as a claim. Give weapons only from server code, check with GetSelectedPedWeapon on the server that the weapon a player holds is one their inventory says they own, and use the server events weaponDamageEvent, giveWeaponEvent and explosionEvent to inspect and CancelEvent() suspicious actions. Log first, punish later: lag and scripts can create false positives.

Every FiveM cheat menu can spawn weapons, add ammo and fake damage on the client. You cannot stop a player controlling their own game — but you can make sure the server never believes them. Good weapon protection is not one magic anticheat resource; it is a handful of server-side rules that make cheating pointless and easy to catch.

Validating weapons and damage on the server — illustrated with a FiveM-compatible minimap render

#The one rule: the client only makes requests

The classic hole is a server event like TriggerServerEvent('shop:giveWeapon', 'WEAPON_RPG') that does whatever the client asks. A cheater can trigger any event with any arguments. Every event must re-check on the server: is the player near the shop, do they have the money, are they allowed this weapon? Only then does the server add the item.

server.lua — the server decides, not the client
local SHOP = vec3(22.0, -1107.0, 29.8)
local PRICES = { WEAPON_PISTOL = 2500 }

RegisterNetEvent('shop:buy', function(weapon)
    local src = source
    local price = PRICES[weapon]
    if not price then return end

    local ped = GetPlayerPed(src)
    if #(GetEntityCoords(ped) - SHOP) > 10.0 then
        print(('[shop] %s tried to buy away from the shop'):format(GetPlayerName(src)))
        return
    end

    -- take money and add the item through your framework here
end)

The same pattern applies to every event: see secure server events for the general version.

#Checking the weapon in hand

With OneSync the server can read the weapon a player is holding. Compare it periodically with what your inventory says they own. A weapon in hand that the inventory does not know about was spawned by the client.

server.lua — spot weapons the inventory never gave out
local UNARMED = `WEAPON_UNARMED`

local function ownsWeapon(src, hash)
    -- ask your inventory: ox_inventory, qb-inventory, ESX loadout...
    return true
end

CreateThread(function()
    while true do
        Wait(5000)
        for _, id in ipairs(GetPlayers()) do
            local src = tonumber(id)
            local hash = GetSelectedPedWeapon(GetPlayerPed(src))
            if hash ~= 0 and hash ~= UNARMED and not ownsWeapon(src, hash) then
                print(('[weapons] %s holds %s without owning it'):format(GetPlayerName(src), hash))
            end
        end
    end
end)

#The server-side game events

FiveM forwards certain game actions to the server as events before they are applied for other players. Calling CancelEvent() inside the handler blocks them.

EventFires whenUseful fields
weaponDamageEventA player damages an entity with a weaponweaponType, weaponDamage, hitGlobalId, willKill, hitComponent
giveWeaponEventA client tries to give a weapon to a networked pedpedId, weaponType, ammo
removeWeaponEvent / removeAllWeaponsEventA client removes weapons from a pedpedId, weaponType
explosionEventA client creates an explosionexplosionType, posX, posY, posZ, ownerNetId
server.lua — block damage from weapons the server never allowed
local BLOCKED = {
    [`WEAPON_RAILGUN`] = true,
    [`WEAPON_RPG`] = true,
    [`WEAPON_MINIGUN`] = true,
}

AddEventHandler('weaponDamageEvent', function(sender, data)
    if BLOCKED[data.weaponType] then
        CancelEvent()
        print(('[weapons] %s did damage with a blocked weapon'):format(GetPlayerName(sender)))
    end
end)

AddEventHandler('giveWeaponEvent', function(sender, data)
    CancelEvent() -- clients may not hand weapons to other peds
end)

AddEventHandler('explosionEvent', function(sender, ev)
    if ev.explosionType == 4 or ev.explosionType == 5 then -- ROCKET, TANKSHELL
        CancelEvent()
    end
end)

#Stopping spawned props and vehicles

sv_entityLockdown controls which entities clients may create. relaxed blocks entities created by client scripts (ambient traffic and peds still work); strict blocks every client-created entity. Either way, your own scripts must then spawn vehicles and objects on the server (for example with CreateVehicleServerSetter), so test it in development first.

server.cfg
set sv_entityLockdown relaxed   # or strict once every script spawns server-side

#Damage sanity checks

  • Hits from a distance the weapon cannot reach (a pistol “hitting” someone 400 m away).
  • willKill on a full-health, armoured target with one pistol round.
  • More hits per second than the weapon’s fire rate allows.
  • Damage while the attacker is dead, in a vehicle without drive-by, or in another routing bucket.

Each of these produces false positives under lag, so score them rather than banning on one event. Balanced damage settings themselves are covered in the damage modifier guide and headshot settings.

#Logging and punishment

  1. Log every detection with player identifiers, weapon hash and coordinates (a Discord webhook is common).
  2. Review patterns for a week and tune thresholds.
  3. Automate only the checks with zero false positives (for example a blocked weapon hash dealing damage).
  4. Keep ban evidence — appeals are easier when you can show the log.
Share this guideXRedditFacebook

Questions

Can I stop cheaters spawning weapons in FiveM?
You cannot stop the client doing it locally, but the server can detect weapons the inventory never gave (with GetSelectedPedWeapon) and cancel damage from them in weaponDamageEvent.
What is weaponDamageEvent?
A server-side event fired when a player damages an entity with a weapon. It includes the weapon hash, damage and target, and can be cancelled with CancelEvent().
Does GetSelectedPedWeapon work on the server?
Yes, with OneSync enabled. Pass the player’s ped from GetPlayerPed(source).
What does sv_entityLockdown do?
It limits which entities clients can create: relaxed blocks client-script entities, strict blocks all client-created entities. Server scripts then spawn vehicles and objects.
Should I auto-ban on detections?
Only for checks with no false positives. Log and review the rest; lag and legitimate scripts trigger many naive checks.

Ready to pick a map?

Twelve themes on three base map styles, $8 each, instant download.

Relevant to what you just read

The tool for this

Twenty theme pairs for ox_lib and ox_inventory From $15, built in the browser, exported as a drop-in resource.

Look it up while you work

The reference tables this guide leans on, free and without an account.