# Validating weapons and damage on the server

> Stop weapon cheats in FiveM with server-side checks: never trust client events, use weaponDamageEvent and giveWeaponEvent, and avoid false bans.

Source: https://fam-tools.com/guides/fivem-weapon-anticheat-validation · FAM Tools · published 2026-09-11 · updated 2026-09-11 · about 13 min

**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.

## Key points

- The server decides who owns which weapon — never a client event.
- `GetSelectedPedWeapon(GetPlayerPed(src))` works server-side with OneSync.
- `weaponDamageEvent`, `giveWeaponEvent` and `explosionEvent` can be cancelled.
- `sv_entityLockdown` limits which entities clients may create.
- Log and review before auto-banning; false bans kill communities.

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.

## 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*

```lua
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](https://pityus.net/guides/fivem-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*

```lua
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)
```

> **ox_inventory already tracks this** — ox_inventory equips weapons from items and knows the current weapon slot on the server, so a weapon that did not come from an item is easy to detect. Script-given weapons (police tasers, event weapons) must also go through items, or your check will flag them.

## 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.

| Event | Fires when | Useful fields |
| --- | --- | --- |
| `weaponDamageEvent` | A player damages an entity with a weapon | `weaponType`, `weaponDamage`, `hitGlobalId`, `willKill`, `hitComponent` |
| `giveWeaponEvent` | A client tries to give a weapon to a networked ped | `pedId`, `weaponType`, `ammo` |
| `removeWeaponEvent` / `removeAllWeaponsEvent` | A client removes weapons from a ped | `pedId`, `weaponType` |
| `explosionEvent` | A client creates an explosion | `explosionType`, `posX`, `posY`, `posZ`, `ownerNetId` |

*server.lua — block damage from weapons the server never allowed*

```lua
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)
```

> **Test before you deploy** — Some resources legitimately create explosions or give weapons to peds. Log what each handler would block for a few days first; blocking blindly can break heists, fire scripts or NPC police.

## 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*

```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](https://fam-tools.com/guides/fivem-weapon-damage-modifier) and [headshot settings](https://fam-tools.com/guides/fivem-headshot-damage-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.

## 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.

## Related

- https://fam-tools.com/guides/fivem-free-weapons-safe-download
- https://fam-tools.com/guides/fivem-give-weapon-to-player
- https://fam-tools.com/guides/fivem-weapon-damage-modifier
- https://fam-tools.com/guides/fivem-weapon-serial-numbers
- https://fam-tools.com/guides/fivem-weapon-shop-setup
