Pasted into every project I touch:
local lastFire = {}
function isThrottled(src, event, intervalMs)
local key = src .. ':' .. event
local now = GetGameTimer()
if lastFire[key] and (now - lastFire[key]) < intervalMs then return true end
lastFire[key] = now
return false
end
Usage:
RegisterNetEvent('shop:buy', function(itemId)
local src = source
if isThrottled(src, 'shop:buy', 500) then return end
-- handle buy
end)
Catches 99% of "client spams the same event" exploits. Clean it up periodically with SetInterval(function() lastFire = {} end, 600000) if you want to avoid memory creep.
Not glamorous, but I've stopped 4-5 dupe exploits in the wild with literally this.