Exemplos Práticos

💰 Sistema de Dinheiro Otimizado

-- Cache de dados de jogador com fallback para database
function getPlayerMoney(player)
    local serial = getPlayerSerial(player)
    local cacheKey = "money_" .. serial
    
    -- Tentar cache primeiro (instantâneo)
    local money = LockSystem.Cache.get(cacheKey)
    if money then
        return money
    end
    
    -- Se não tiver cache, consultar database (lento)
    local query = dbQuery(db, "SELECT money FROM players WHERE serial = ?", serial)
    local result = dbPoll(query, -1)
    dbFree(query)
    
    if result and #result > 0 then
        money = result[1].money
        -- Armazenar no cache por 2 minutos
        LockSystem.Cache.set(cacheKey, money, 120)
        return money
    end
    
    return 0
end

function setPlayerMoney(player, amount)
    local serial = getPlayerSerial(player)
    local cacheKey = "money_" .. serial
    
    -- Atualizar database
    dbExec(db, "UPDATE players SET money = ? WHERE serial = ?", amount, serial)
    
    -- Atualizar cache também para manter sincronização
    LockSystem.Cache.set(cacheKey, amount, 120)
    
    setElementData(player, "money", amount)
end

🏆 Sistema de Ranking com Cache

-- Ranking atualizado apenas a cada 5 minutos
function getTopRichPlayers()
    return LockSystem.Cache.remember("top_rich_players", 300, function()
        -- Query complexa executada apenas quando cache expira
        local query = dbQuery(db, [[
            SELECT name, money, lastLogin FROM players 
            WHERE money > 1000 
            ORDER BY money DESC 
            LIMIT 20
        ]])
        local result = dbPoll(query, -1)
        dbFree(query)
        return result or {}
    end)
end

-- Comando que usa cache automaticamente
addCommandHandler("top", function(player)
    local topPlayers = getTopRichPlayers() -- Instantâneo após primeira execução
    
    outputChatBox("=== TOP 20 PLAYERS MAIS RICOS ===", player, 255, 215, 0)
    for i, data in ipairs(topPlayers) do
        outputChatBox(i .. ". " .. data.name .. " - $" .. formatMoney(data.money), player)
    end
end)

🌍 Cache de Dados de API Externa

-- Cache de localização por IP (não muda frequentemente)
function getPlayerCountry(player)
    local ip = getPlayerIP(player)
    local cacheKey = "country_" .. ip
    
    -- Verificar cache primeiro
    local country = LockSystem.Cache.get(cacheKey)
    if country then
        triggerClientEvent(player, "onPlayerCountryReceived", player, country)
        return country
    end
    
    -- Fazer request apenas se necessário
    fetchRemote("https://ipapi.co/" .. ip .. "/country_name/", function(data)
        if data and data ~= "" then
            -- Cache por 24 horas (países não mudam)
            LockSystem.Cache.set(cacheKey, data, 86400)
            triggerClientEvent(player, "onPlayerCountryReceived", player, data)
        end
    end)
end

-- Usar no login do player
addEventHandler("onPlayerJoin", root, function()
    -- Cache evita múltiplas requests para mesmo IP
    getPlayerCountry(source)
end)

🛡️ Sistema de Rate Limiting

-- Controle de spam usando cache
function checkRateLimit(player, action, maxAttempts, windowSeconds)
    local serial = getPlayerSerial(player)
    local cacheKey = "rate_" .. action .. "_" .. serial
    
    local attempts = LockSystem.Cache.get(cacheKey) or 0
    
    if attempts >= maxAttempts then
        return false -- Rate limited
    end
    
    -- Incrementar tentativas e definir TTL
    LockSystem.Cache.set(cacheKey, attempts + 1, windowSeconds)
    return true
end

-- Aplicar rate limiting em comandos
addCommandHandler("pm", function(player, cmd, target, ...)
    -- Máximo 5 PMs por minuto
    if not checkRateLimit(player, "pm", 5, 60) then
        outputChatBox("Você está enviando PMs muito rápido! Aguarde.", player, 255, 100, 100)
        return
    end
    
    -- Processar PM normalmente
    local message = table.concat({...}, " ")
    -- ... código do PM
end)

-- Rate limiting em chat
addEventHandler("onPlayerChat", root, function(message)
    -- Máximo 10 mensagens por 30 segundos
    if not checkRateLimit(source, "chat", 10, 30) then
        outputChatBox("Você está falando muito rápido!", source, 255, 0, 0)
        cancelEvent()
        return
    end
end)

⚙️ Cache de Configurações e Permissões

-- Cache de configurações do servidor
function getServerConfig()
    return LockSystem.Cache.remember("server_config", 3600, function()
        local file = fileOpen("server_config.json")
        if not file then 
            return {maxPlayers = 100, pvpEnabled = true} 
        end
        
        local content = fileRead(file, fileGetSize(file))
        fileClose(file)
        
        return json:parse(content) or {}
    end)
end

-- Cache de permissões ACL (evita consultas constantes)
function hasAdminPermission(player)
    local serial = getPlayerSerial(player)
    local cacheKey = "admin_perm_" .. serial
    
    -- Cache por 30 segundos (permissões podem mudar)
    return LockSystem.Cache.remember(cacheKey, 30, function()
        return hasObjectPermissionTo(player, "general.administrator")
    end)
end

-- Usar em comandos administrativos
addCommandHandler("ban", function(player, cmd, target, ...)
    -- Verificação instantânea após primeira consulta
    if not hasAdminPermission(player) then
        outputChatBox("Você não tem permissão!", player, 255, 0, 0)
        return
    end
    
    -- Processar comando de ban
end)

📊 Sistema de Estatísticas com Cache

-- Estatísticas do servidor atualizadas periodicamente
function getServerStats()
    return LockSystem.Cache.remember("server_stats", 180, function()
        local stats = {}
        
        -- Contar players online
        stats.playersOnline = #getElementsByType("player")
        
        -- Buscar estatísticas do database
        local query = dbQuery(db, "SELECT COUNT(*) as total FROM players")
        local result = dbPoll(query, -1)
        stats.totalRegistered = result[1].total
        dbFree(query)
        
        -- Calcular uptime
        stats.uptime = getTickCount()
        
        return stats
    end)
end

-- Comando de stats com cache
addCommandHandler("stats", function(player)
    local stats = getServerStats()
    
    outputChatBox("=== ESTATÍSTICAS DO SERVIDOR ===", player, 100, 255, 100)
    outputChatBox("Players Online: " .. stats.playersOnline, player)
    outputChatBox("Total Registrados: " .. stats.totalRegistered, player)
    outputChatBox("Uptime: " .. math.floor(stats.uptime/60000) .. " minutos", player)
end)

Atualizado