Explorer
KNOW-ANT-FIVEM-001

Event spamming - Ne pas envoyer d'events sans rate limiting

Domaine
backend
Type
anti-pattern
Priorité
P2

Parent : [[INDEX-FIVEM-BACKEND]]

Anti-Pattern : Event Spamming (FiveM)

Erreur à éviter

Envoyer des events serveur depuis le client sans rate limiting, permettant le spam et la surcharge du serveur.

Exemple incorrect

-- ❌ DANGER - Event spamming
RegisterCommand('heal', function()
    -- Appelé à chaque frame si bind sur touche maintenue
    TriggerServerEvent('wasabi_ambulance:healTarget', closestPlayer)
end, false)

-- Dans un thread while true sans cooldown
Citizen.CreateThread(function()
    while true do
        TriggerServerEvent('updatePosition', GetEntityCoords(PlayerPedId()))
        Wait(0) -- 60 fois par seconde !
    end
end)

Pourquoi c'est dangereux

  • Surcharge du serveur (CPU/network)
  • Possible DoS par event flooding
  • Bypass des vérifications côté serveur
  • Lag généralisé pour tous les joueurs

Bonne pratique

-- ✅ CORRECT - Rate limiting côté client
local lastHeal = 0
local HEAL_COOLDOWN = 5000 -- 5 secondes

RegisterCommand('heal', function()
    local currentTime = GetGameTimer()
    if currentTime - lastHeal < HEAL_COOLDOWN then
        exports['wasabi_ems']:Notify('error', 'Veuillez patienter...')
        return
    end
    
    lastHeal = currentTime
    TriggerServerEvent('wasabi_ambulance:healTarget', closestPlayer)
end, false)

-- Côté serveur : double vérification
RegisterNetEvent('wasabi_ambulance:healTarget')
AddEventHandler('wasabi_ambulance:healTarget', function(targetId)
    local src = source
    
    -- Rate limiting côté serveur (essentiel!)
    if not exports['wasabi_ems']:CanPerformAction(src, 'heal') then
        return
    end
    
    -- Logique métier
    HealPlayer(targetId)
end)

Pattern de rate limiting

-- Utilitaire de cooldown
local playerCooldowns = {}

function CanPerformAction(playerId, action)
    local key = playerId .. ':' .. action
    local currentTime = os.time()
    
    if playerCooldowns[key] and currentTime < playerCooldowns[key] then
        return false
    end
    
    -- Définir le cooldown (ex: 5 secondes)
    playerCooldowns[key] = currentTime + 5
    return true
end

Détection

Rechercher dans le code :

  • TriggerServerEvent dans des boucles while true avec Wait(0) ou Wait(<100)
  • Absence de variables lastAction ou cooldown
  • Events appelés depuis onResourceStart sans délai

Références

  • Pattern WASABI : Gestion des events ambulance
  • CFX Docs : Event optimization
  • Anti-cheat : Rate limiting detection