Scripts de roubo de loja e banco em FiveM: configuração e design lado do servidor
Como configurar e projetar roubos de loja e banco em FiveM: contagem de polícia, cooldowns lado do servidor, recompensas dadas apenas pelo servidor, alertas de polícia e verificações de distância.
O sintoma: jogadores roubam uma loja sem polícia online, a mesma loja é roubada dez vezes seguidas, ou um cheater dispara um evento e pega todo o payout.
Um script de roubo é uma pequena máquina de estado lado do servidor: verifique as regras, comece, aguarde, pague. A maioria dos exploits vem de colocar essas etapas no cliente. Este artigo cobre um design seguro e os erros de config que causam os problemas acima.
O fluxo que você quer
Pense em cada roubo como quatro etapas, e execute as etapas 1, 2 e 4 no servidor:
- Pedido de início: o cliente pede para roubar uma loja. O servidor verifica contagem de polícia, cooldown, distância e que ninguém já está roubando.
- Travar: o servidor marca a loja como sendo roubada e define o cooldown.
- Ação: o cliente toca a barra de progresso, o hack ou o lockpick.
- Terminar: o cliente relata feito, o servidor verifica o tempo que passou e a distância novamente, depois paga.
O cliente apenas lida com os visuais. Nunca decide o resultado.
Contagem de polícia
Exija um número mínimo de oficiais em duty, contados no servidor. Um script que lê a contagem do cliente, ou de um valor que o cliente envia, é trivial de contornar. O código de contagem está em setting up a police job. Verifique quando o roubo começar, e decida se deve ser verificado novamente antes do payout.
Cooldowns armazenados no servidor
Mantenha o estado em uma tabela do servidor, codificada por id de localização:
-- 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
endDois detalhes importam:
- Uma tabela na memória reseta quando o recurso reinicia. Se você quer que o cooldown sobreviva a um reinício, armazene o tempo do último roubo no banco de dados.
- Defina
busyquando o roubo começa e limpe quando termina ou quando o ladrão se desconecta, ou a loja fica trancada para sempre.
Recompensas apenas do servidor
O exploit mais comum é um evento de recompensa que o cliente pode disparar sozinho:
-- WRONG: any client can fire this
RegisterNetEvent('robbery:reward', function(amount)
exports.ox_inventory:AddItem(source, 'money', amount)
end)A solução é não ter esse evento de jeito nenhum. O servidor decide o valor e paga dentro do código que verificou o roubo:
-- 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)Observe as três verificações: o mesmo jogador começou, tempo suficiente passou, e o jogador ainda está na loja. Distância lado do servidor funciona porque o servidor conhece a posição do jogador com OneSync. Veja securing server events e server callbacks para o padrão.
Atenção: o nome do item para cash depende de sua configuração. Use o item ou a função de framework que seu servidor usa para dinheiro, e mantenha-o no servidor.
Alertando a polícia
Avise os oficiais quando o roubo começar, do servidor, para cada jogador de polícia em duty:
-- 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)No cliente, adicione um blip e uma notificação. Você também pode passar o alerta para seu recurso de dispatch em vez de construir o seu próprio, o que dá aos oficiais um único lugar para todas as chamadas. Um pequeno atraso ou uma chance de um alarma silencioso faz o roubo parecer menos scriptado. Blips são cobertos em creating blips.
Erros comuns de config
- Contagem de polícia definida para 0 enquanto testava, depois deixada assim no servidor ao vivo.
- Intervalo de recompensa muito alto. Um roubo que paga mais de uma hora de qualquer trabalho é farmado. Compare com seu holerite, como em balancing the server economy.
- Cooldown muito curto. Com poucas lojas e cooldowns rápidos, os jogadores alternam entre elas.
- Nenhuma verificação de distância no passo de conclusão, então um jogador pode começar o roubo e coletar de outro lado do mapa.
- Itens necessários (lockpick, drill) nunca removidos, ou removidos no cliente.
- Flag ocupado nunca limpo após desconexão ou erro de script.
- Coordenadas copiadas de outro mapa. Se você usar um MLO ou mapa diferente, a localização da loja está errada.
Teste com uma segunda conta que não é administrador, porque permissões de admin podem ocultar uma verificação faltante.
Lista de verificação
| Sintoma | Solução |
|---|---|
| Roubo sem polícia online | Conte oficiais em duty no servidor, defina um mínimo acima de 0 |
| Loja roubada novamente imediatamente | Adicione um cooldown do servidor codificado por id de loja |
| Cheater obtém o payout | Remova eventos de recompensa do cliente, pague dentro do código do servidor verificado |
| Payout de longe | Verifique distância no servidor no início e fim |
| Loja trancada para sempre | Limpe a flag ocupado ao terminar, falhar e desconectar |
| Cooldown perdido na reinicialização | Armazene o tempo do último roubo no banco de dados |
Respostas rápidas
Onde o cooldown de roubo deve ser armazenado?
No servidor, em uma tabela codificada por id de loja ou banco. Um cooldown mantido no cliente reseta a cada reconexão e é fácil de pular.
Por que os jogadores ganham dinheiro de roubos sem os fazer?
O evento de recompensa confisa no cliente. Dê a recompensa apenas dentro do código do servidor que começou e verificou o roubo, nunca de um evento que o cliente pode disparar sozinho.
Quantos policiais um roubo deve precisar?
Depende de quantos oficiais seu servidor geralmente tem. Um começo comum é um ou dois para uma pequena loja e mais para um banco, depois ajuste pelo que você vê.
Scripts sem esse problema
CCTV Security CamerasCâmeras posicionáveis, um tablet com várias telas ao vivo e fotos impressas como prova.Ver script →
Advanced BoostingBoosting de veículos pelo tablet: contratos da classe D à S+, crews e fila ao vivo.Ver script →
Shop CreatorMonte uma loja em menos de um minuto — donos, funcionários, cofres e assaltos inclusos.Ver script →