Scripts de braquage de magasin et banque FiveM : configuration et conception côté serveur

Comment configurer et concevoir les braquages de magasin et banque sur FiveM : compte de police, cooldowns côté serveur, récompenses données uniquement par le serveur, alertes de police et vérifications de distance.

Le symptôme : les joueurs braquent un magasin sans police en ligne, le même magasin est braqué dix fois d'affilée, ou un cheater tire un événement et obtient le paiement complet.

Un script de braquage est une petite machine d'état côté serveur : vérifier les règles, commencer, attendre, payer. La plupart des failles proviennent du fait de mettre ces étapes sur le client. Cet article couvre une conception sûre et les erreurs de configuration qui causent les problèmes ci-dessus.

Le flux que vous voulez

Pensez à chaque braquage comme quatre étapes, et exécutez les étapes 1, 2 et 4 sur le serveur :

  1. Demande de démarrage : le client demande à braquer un magasin. Le serveur vérifie le compte de police, le cooldown, la distance et que personne ne le braque déjà.
  2. Verrouillage : le serveur marque le magasin comme étant braqué et définit le cooldown.
  3. Action : le client joue la barre de progression, le hack ou le crochetage.
  4. Fin : le client signale terminé, le serveur vérifie le temps écoulé et la distance à nouveau, puis paie.

Le client ne gère que les visuels. Il ne décide jamais du résultat.

Compte de police

Exigez un nombre minimum d'agents en service, comptés sur le serveur. Un script qui lit le compte à partir du client, ou à partir d'une valeur que le client envoie, est trivial à contourner. Le code de comptage est dans configuration d'un métier de police. Vérifiez-le quand le braquage commence, et décidez s'il doit être vérifié à nouveau avant le paiement.

Cooldowns stockés sur le serveur

Gardez l'état dans une table serveur, indexée par l'id de lieu :

lua
-- server
-- [id] = { busy = bool, last = os.time(), robber = source, started = os.time() }
local robberies = {}

local function canRob(id, cooldown)
    local state = robberies[id]
    if not state then return true end
    if state.busy then return false end
    return (os.time() - state.last) >= cooldown
end

Deux détails sont importants :

  • Une table en mémoire réinitialise quand la ressource redémarre. Si vous voulez que le cooldown survive à un redémarrage, stockez la dernière heure de braquage dans la base de données.
  • Définissez busy quand le braquage commence et nettoyez-le quand il se termine ou quand le braqueur se déconnecte, sinon le magasin reste verrouillé pour toujours.

Récompenses uniquement à partir du serveur

L'exploit le plus courant est un événement de récompense que le client peut déclencher seul :

lua
-- WRONG: any client can fire this
RegisterNetEvent('robbery:reward', function(amount)
    exports.ox_inventory:AddItem(source, 'money', amount)
end)

La solution est de ne pas avoir cet événement du tout. Le serveur décide le montant et paie à l'intérieur du code qui a vérifié le braquage :

lua
-- server (ox_lib callback)
lib.callback.register('robbery:finish', function(source, id)
    local state = robberies[id]
    if not state or state.robber ~= source then return false end
    if os.time() - state.started < Config.MinDuration then return false end

    local ped = GetPlayerPed(source)
    if #(GetEntityCoords(ped) - Config.Stores[id].coords) > 5.0 then return false end

    state.busy = false
    state.last = os.time()
    local amount = math.random(Config.Reward.min, Config.Reward.max)
    exports.ox_inventory:AddItem(source, 'money', amount)
    return true
end)

Remarquez les trois vérifications : le même joueur l'a commencé, assez de temps a passé, et le joueur est toujours au magasin. La distance côté serveur fonctionne parce que le serveur connaît la position du joueur avec OneSync. Consultez sécurisation des événements serveur et callbacks serveur pour le modèle.

Attention : le nom de l'article pour l'argent comptant dépend de votre configuration. Utilisez l'article ou la fonction framework de votre serveur pour l'argent, et gardez-le sur le serveur.

Alerter la police

Informez les agents quand le braquage commence, du serveur, à chaque joueur de police en service :

lua
-- server: send to each on-duty officer you found with your police count
TriggerClientEvent('robbery:policeAlert', officerSrc, Config.Stores[id].coords, Config.Stores[id].label)

Sur le client, ajoutez un blip et une notification. Vous pouvez aussi remettre l'alerte à votre ressource de dispatch au lieu de construire votre propre, ce qui donne aux agents un seul endroit pour tous les appels. Un petit délai ou une chance d'alarme silencieuse rend le braquage moins scriptographique. Les blips sont couverts dans création de blips.

Erreurs de configuration courantes

  • Compte de police défini sur 0 pendant les tests, puis laissé comme ça sur le serveur en direct.
  • Plage de récompense trop élevée. Un braquage qui paie plus qu'une heure de n'importe quel travail est exploité. Comparez avec votre salaire, comme dans équilibrage de l'économie du serveur.
  • Cooldown trop court. Avec quelques magasins et des cooldowns rapides, les joueurs tournent entre eux.
  • Pas de vérification de distance à l'étape de fin, donc un joueur peut commencer le braquage et le collecter de l'autre côté de la carte.
  • Articles nécessaires (lockpick, drill) jamais supprimés, ou supprimés sur le client.
  • Drapeau occupé jamais nettoyé après une déconnexion ou une erreur de script.
  • Coordonnées copiées d'une autre carte. Si vous utilisez un MLO ou une carte différente, l'emplacement du magasin est faux.

Testez avec un second compte qui n'est pas administrateur, car les permissions d'administrateur peuvent masquer une vérification manquante.

Liste de contrôle

Symptôme Solution
Braquage sans police en ligne Comptez les agents en service sur le serveur, définissez un minimum au-dessus de 0
Magasin braqué à nouveau immédiatement Ajoutez un cooldown serveur indexé par l'id du magasin
Le cheater reçoit le paiement Supprimez les événements de récompense client, payez à l'intérieur du code serveur vérifié
Paiement de loin Vérifiez la distance sur le serveur au début et à la fin
Magasin verrouillé pour toujours Nettoyez le drapeau occupé à la fin, l'échec et la déconnexion
Cooldown perdu au redémarrage Stockez la dernière heure de braquage dans la base de données

Réponses rapides

Où le cooldown du braquage doit-il être stocké ?

Sur le serveur, dans une table indexée par l'id du magasin ou de la banque. Un cooldown gardé sur le client réinitialise à chaque reconnexion et est facile à contourner.

Pourquoi les joueurs reçoivent-ils de l'argent des braquages sans les faire ?

L'événement de récompense fait confiance au client. Donnez la récompense uniquement à l'intérieur du code serveur qui a commencé et vérifié le braquage, jamais à partir d'un événement que le client peut déclencher seul.

Combien de police un braquage devrait-il avoir besoin ?

Cela dépend du nombre d'agents que votre serveur a généralement. Un début courant est un ou deux pour un petit magasin et plus pour une banque, puis ajustez selon ce que vous voyez.

Des scripts sans ce problème

CCTV Security CamerasDes caméras à placer, une tablette multi-vues en direct et des photos imprimées comme preuves.Voir le script →Advanced BoostingDu boosting de véhicules piloté par tablette : contrats de classe D à S+, crews et file d’attente en direct.Voir le script →Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →

À lire aussi