Scope PIN rate-limit to the safe instead of the player

A wrong PIN now only locks that specific safe, so the player can
still try opening other safes. Also surfaces remaining attempts and
lock duration in the notify messages.
This commit is contained in:
Bxio 2026-08-03 11:14:29 +00:00
parent 781607a434
commit 825284d722
2 changed files with 10 additions and 7 deletions

View File

@ -7,7 +7,7 @@ Config.Debug = true
Config.PlaceTime = 2500 Config.PlaceTime = 2500
-- Segurança do PIN -- Segurança do PIN
Config.PinMaxAttempts = 3 -- tentativas erradas de PIN antes de bloquear o jogador Config.PinMaxAttempts = 1 -- tentativas erradas de PIN antes de bloquear o jogador
Config.PinBlockTime = 30 -- segundos de bloqueio após exceder as tentativas Config.PinBlockTime = 30 -- segundos de bloqueio após exceder as tentativas
-- Distância máxima (metros) para abrir ou recolher um safe -- Distância máxima (metros) para abrir ou recolher um safe

View File

@ -193,11 +193,11 @@ end)
RegisterNetEvent('safe:open', function(id, pin) RegisterNetEvent('safe:open', function(id, pin)
local src = source local src = source
local now = os.time() local now = os.time()
local attempt = pinAttempts[src] local attempt = pinAttempts[id] -- bloqueio é do cofre, não do jogador
if attempt and now < attempt.blockedUntil then if attempt and now < attempt.blockedUntil then
local remaining = math.ceil(attempt.blockedUntil - now) local remaining = math.ceil(attempt.blockedUntil - now)
return TriggerClientEvent('ox_lib:notify', src, {type='error', description=('Muitas tentativas erradas. Aguarde %d segundos.'):format(remaining)}) return TriggerClientEvent('ox_lib:notify', src, {type='error', description=('Este safe está bloqueado. Aguarde %d segundos.'):format(remaining)})
end end
local safe = safes[id] local safe = safes[id]
@ -217,14 +217,17 @@ RegisterNetEvent('safe:open', function(id, pin)
if attempt.count >= Config.PinMaxAttempts then if attempt.count >= Config.PinMaxAttempts then
attempt.blockedUntil = now + Config.PinBlockTime attempt.blockedUntil = now + Config.PinBlockTime
attempt.count = 0 attempt.count = 0
dbg('Jogador', src, 'bloqueado por tentativas de PIN erradas') pinAttempts[id] = attempt
dbg('Safe', id, 'bloqueado por tentativas de PIN erradas')
return TriggerClientEvent('ox_lib:notify', src, {type='error', description=('PIN incorreto. Safe bloqueado por %d segundos.'):format(Config.PinBlockTime)})
end end
pinAttempts[src] = attempt pinAttempts[id] = attempt
return TriggerClientEvent('ox_lib:notify', src, {type='error', description='PIN incorreto.'}) local remainingAttempts = Config.PinMaxAttempts - attempt.count
return TriggerClientEvent('ox_lib:notify', src, {type='error', description=('PIN incorreto. Mais %d tentativa(s) antes do safe ser bloqueado.'):format(remainingAttempts)})
end end
pinAttempts[src] = nil pinAttempts[id] = nil
local cfg = Config.SafeTypes[safe.type] local cfg = Config.SafeTypes[safe.type]
TriggerClientEvent('safe:openInventory', src, {id=id, slots=cfg.slots, weight=cfg.weight}) TriggerClientEvent('safe:openInventory', src, {id=id, slots=cfg.slots, weight=cfg.weight})