Les cheats permettent aux clients malveillants de déclencher des événements dans n'importe quel contexte. Apprenez à sécuriser la communication client-serveur, à implémenter la validation côté serveur et à configurer les convars de sécurité de FXServer.
L'équipe anti-triche essaie toujours d'améliorer l'anti-triche, mais parfois des choses passent à travers.
Dans ce guide, nous allons essayer de vous aider à couvrir certaines pratiques courantes que vous pouvez adopter pour rendre votre serveur plus sûr en verrouillant correctement vos événements.
Les cheats peuvent permettre au client de déclencher des événements dans n'importe quel contexte.
Quand nous parlons de contexte, nous voulons dire qu'ils peuvent exécuter client->serveur (via TriggerServerEvent) ou ressource client->ressource client (via TriggerEvent).
Lorsque vous travaillez avec des événements en Lua, il est crucial de les enregistrer correctement selon qu'ils sont appelés par le client ou le serveur.
Une erreur courante consiste à enregistrer des événements serveur qui ne sont pas censés être appelés par le client, ou vice-versa, ce qui peut entraîner de graves vulnérabilités de sécurité.
Utilisez AddEventHandler lorsque l'événement est destiné à être déclenché dans le même contexte, soit client-client, soit serveur-serveur. Cela garantit que les événements ne sont pas mis en réseau et ne peuvent pas être appelés par le côté opposé.
AddEventHandler("eventName", function(eventParam1, eventParam2)
-- Le code ici sera exécuté une fois que l'événement est déclenché dans le même contexte.
end)Utilisez RegisterNetEvent lorsque l'événement doit être déclenché dans différents contextes, comme de client à serveur ou de serveur à client.
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
-- Le code ici sera exécuté une fois que l'événement est déclenché à travers différents contextes.
end)Cet exemple est pour le client, et comme tout ce qui se trouve sur le client, il n'est pas infaillible et peut être manipulé par des clients tricheurs.
Si vous souhaitez bloquer l'exécution depuis le même contexte (comme empêcher un événement réseau de serveur à serveur d'être déclenché par le client), vous devez enregistrer votre événement et vérifier la source de l'expéditeur :
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
-- Le serveur enverra l'id réseau `65535` pour les événements provenant du serveur
if source ~= 65535 then return end
end)Même si vous construisez un anti-triche solide, l'ajout de vérifications sur les événements du serveur les rend nettement plus sécurisés. C'est une pratique fortement recommandée, bien qu'elle ne prévienne pas tout. Ci-dessous, nous partageons quelques bons conseils.
Cela garantit l'intégrité et la sécurité de votre environnement de jeu.
Tous les exemples ci-dessous supposent l'utilisation d'un framework (tel que ESX, QB-Core, etc.).
Ceci est destiné à vous montrer de mauvaises façons de gérer les événements, vous ne devriez jamais faire cela. Ajouter directement des objets à l'utilisateur à partir de sa propre saisie est toujours une mauvaise pratique : vous devez toujours valider les saisies des utilisateurs.
RegisterNetEvent("job:givePlayerItem", function(item, count)
local ply = FX.GetPlayerFromSource(source)
-- L'ajout direct d'objets à l'utilisateur à partir de sa propre saisie est dangereux !
ply.addItem(item, count)
end)Voici un modèle de sécurité robuste. Le serveur suit l'état et les coordonnées du joueur, et vérifie les actions à l'aide de ticks côté serveur au lieu de s'en remettre uniquement aux déclencheurs du client.
-- coordonnée fictive
local VALID_JOB_COORD = vector3(125.0, 111.1, 35.83)
local MAX_ITEM_COUNT = 10
-- coordonnée fictive
local VALID_TURNIN_COORD = vector3(1888.0, 1254.1, 48.0)
local ITEM_NAME = 'log'
-- liste des joueurs avec un travail actif
local activeJobs = {}
AddEventHandler("playerDropped", function ()
if not activeJobs[source] then return end
activeJobs[source] = nil
end)
function isPedWithinRange(ped, tgtCoords)
return #(GetEntityCoords(ped) - tgtCoords) < 15.0
end
-- traiter le tick de travail et incrémenter les objets côté serveur
CreateThread(function()
while true do
for src, data in pairs(activeJobs) do
local ped = GetPlayerPed(src)
-- s'ils ne sont pas à portée, nous ne voulons pas leur donner l'objet
if isPedWithinRange(ped, VALID_JOB_COORD) then
-- donnez-leur l'objet, mais limitez-le à MAX_ITEM_COUNT
data.itemCount = math.min(data.itemCount + 1, MAX_ITEM_COUNT)
end
end
-- traiter le tick de travail une fois par seconde
Wait(1000)
end
end)
RegisterNetEvent("job:startJob", function()
local ped = GetPlayerPed(source)
-- s'ils sont à moins de 15 unités, ils font le travail
if isPedWithinRange(ped, VALID_JOB_COORD) then
activeJobs[source] = {
itemCount = 0,
}
end
end)
RegisterNetEvent("job:givePlayerItem", function()
local ply = FX.GetPlayerFromSource(source)
-- s'ils n'ont pas de travail actif, ils ne devraient pas atteindre cet événement !
local jobData = activeJobs[source]
if not jobData then return end
local ped = GetPlayerPed(source)
-- ils ne sont pas à portée des coordonnées de rendu, rejeter leurs modifications
if not isPedWithinRange(ped, VALID_TURNIN_COORD) then return end
-- réinitialiser les données de travail pour qu'ils ne puissent pas le déclencher plusieurs fois
activeJobs[source] = nil
-- ajouter les objets à l'utilisateur validés côté serveur
ply.addItem(ITEM_NAME, jobData.itemCount)
end)Veuillez noter que les paramètres suivants ne doivent pas être modifiés à moins que vous ne sachiez exactement ce que vous faites. L'équipe Cfx.re / Adhesive travaille très dur pour empêcher les tricheurs. La plupart de ces fonctionnalités seront activées par défaut avec la version de build FXServer 8450 et supérieure.
L'activation de ces convars entraînera probablement l'exclusion du joueur avec le motif suivant : Connection to CNL timed out.
Être exclu ne signifie pas que le joueur est automatiquement banni globalement (Global Banned). Cependant, cela fournit une indication solide de la fiabilité du joueur, ce qui est extrêmement utile pour évaluer sa confiance.
Les codes fournis ne sont pas censés fonctionner par simple copier-coller. Ce sont juste quelques conseils pour empêcher certaines actions qui pourraient se produire sur le serveur. Cela nécessite des connaissances en programmation. Vous êtes toujours libre de rejoindre notre Discord pour obtenir une aide supplémentaire.