> For the complete documentation index, see [llms.txt](https://doc.var-fivem.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.var-fivem.com/paintball/configuration/anti-cheat-integration.md).

# Anti-Cheat Integration

Var-PaintBall is a non-lethal combat gamemode. During a match, players legitimately have behaviour that most anti-cheats flag as cheating :

* **No combat damage** : players don't take real health damage (elimination is kevlar-based).
* **Infinite / high ammo :** the paintball weapon is given large ammo counts.

To prevent **false-positive bans** during a match, Var-PaintBall exposes two **server-side events** that fire when a player enters and leaves a live match. You hook these from your own resource to whitelist players in your anti-cheat — and **un**-whitelist them the moment the match is over.

{% hint style="info" %}
The script has **no hard dependency** on any anti-cheat. These are generic hooks, they work with WaveShield, FiveGuard, or any system that exposes a per-player bypass.
{% endhint %}

***

### How it works

All authority stays **server-side**. The client never decides who is whitelisted, so a cheater cannot self-whitelist by replaying a client event.

| Event                                     | Args                               | Fires when                                                              |
| ----------------------------------------- | ---------------------------------- | ----------------------------------------------------------------------- |
| `var-paintball:server:match:playerJoined` | `src` (number), `matchId` (number) | The player is placed into a live match.                                 |
| `var-paintball:server:match:playerLeft`   | `src` (number)                     | Match end, death/elimination, kick, leave, **or disconnect mid-match.** |

The two events are strictly **paired** : every `playerJoined` is followed by exactly one `playerLeft`, covering every exit path (match finished, player eliminated, kicked, left the lobby, or dropped from the server mid-match). This guarantees a bypass is always revoked.

***

### Setup

Create a small server file in **your own** resource (do **not** edit Var-PaintBall), and listen to the two events.

#### WaveShield

```lua
-- server.lua (in your own resource)

AddEventHandler("var-paintball:server:match:playerJoined", function(src)
    exports["WaveShield"]:toggleBypass(src, true)
end)

AddEventHandler("var-paintball:server:match:playerLeft", function(src)
    exports["WaveShield"]:toggleBypass(src, false)
end)
```

That's it. Players are whitelisted for the duration of the match and re-protected the instant it ends.

#### Any other anti-cheat

The pattern is identical — swap the export for your anti-cheat's whitelist/bypass call:

```lua
AddEventHandler("var-paintball:server:match:playerJoined", function(src)
    -- enable your anti-cheat bypass for `src`
end)

AddEventHandler("var-paintball:server:match:playerLeft", function(src)
    -- disable your anti-cheat bypass for `src`
end)
```

***

### Optional : safety-net auto-expire

If your anti-cheat supports a **timed** bypass, you can add one on join as a fallback. If a `playerLeft` is ever missed (e.g. an anti-cheat resource restart), the bypass still expires on its own instead of staying open.

```lua
AddEventHandler("var-paintball:server:match:playerJoined", function(src)
    exports["WaveShield"]:toggleBypass(src, true)
    exports["WaveShield"]:tempBypass(src, 1800) -- auto-expires after 30 min
end)
```

{% hint style="warning" %}
Set the auto-expire duration **longer than your longest possible match**, otherwise a long match could lose its bypass mid-game. The paired `playerLeft` handler remains the primary way the bypass is revoked, `tempBypass` is only a fallback.
{% endhint %}

***

### FAQ

**Do I have to edit the Var-PaintBall files ?** No. The hooks are built in. All your integration lives in your own resource.

**What if a player disconnects in the middle of a match ?** `playerLeft` still fires for them, so any bypass is revoked. (Most anti-cheats also clear per-player state on disconnect anyway.)

**Can a cheater abuse the bypass outside a match ?** No. The events fire only when the server places a player into a real match and removes them. The client has no control over this.

**Which anti-cheats are supported ?** Any of them, the hooks are generic. WaveShield is shown above because it ships ready-made `toggleBypass` / `tempBypass` exports.
