ESX = exports['es_extended']:getSharedObject() -- ===================== -- WEBHOOK HELPER -- ===================== local function SendRefundWebhook(title, message, color) if not Config.WebhookRefund or Config.WebhookRefund == "" then return end local embed = { { ["color"] = color or 10181046, ["title"] = "**" .. title .. "**", ["description"] = message, ["footer"] = { ["text"] = os.date("%d.%m.%Y | %H:%M:%S") }, } } PerformHttpRequest(Config.WebhookRefund, function() end, 'POST', json.encode({username = "Refund System", embeds = embed}), { ['Content-Type'] = 'application/json' }) end -- ===================== -- SQL SETUP -- ===================== MySQL.ready(function() MySQL.query.await([[ CREATE TABLE IF NOT EXISTS refund_codes ( id INT AUTO_INCREMENT PRIMARY KEY, code VARCHAR(10) NOT NULL UNIQUE, items JSON DEFAULT NULL, money INT DEFAULT 0, bank_money INT DEFAULT 0, reason TEXT, created_by VARCHAR(100) NOT NULL, created_by_id VARCHAR(30) NOT NULL, discord_channel_id VARCHAR(30), redeemed_by_identifier VARCHAR(60) DEFAULT NULL, redeemed_by_name VARCHAR(100) DEFAULT NULL, redeemed_at TIMESTAMP NULL DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_code (code), INDEX idx_redeemed (redeemed_at) ) ]]) print('[mercyv-refund] Database ready') end) -- ===================== -- HELPERS -- ===================== local function GetIdentifier(source) local xPlayer = ESX.GetPlayerFromId(source) if not xPlayer then return nil end return xPlayer.getIdentifier() end local function GetPlayerName(source) local xPlayer = ESX.GetPlayerFromId(source) if not xPlayer then return 'Unbekannt' end return xPlayer.getName() end local function SendMessage(source, msg) TriggerClientEvent('chat:addMessage', source, { color = {155, 89, 182}, multiline = true, args = {'Refund', msg} }) end -- ===================== -- CODE EINLOESEN -- ===================== local function redeemCode(source, codeStr) local xPlayer = ESX.GetPlayerFromId(source) if not xPlayer then return end local identifier = GetIdentifier(source) local playerName = GetPlayerName(source) if not identifier then SendMessage(source, '~r~Fehler: Spieler konnte nicht identifiziert werden.') return end -- Code in DB suchen local result = MySQL.query.await('SELECT * FROM refund_codes WHERE code = ?', { codeStr }) if not result or #result == 0 then SendMessage(source, '~r~Ungueltiger Code.') return end local row = result[1] -- Bereits eingeloest? if row.redeemed_at ~= nil then SendMessage(source, '~r~Dieser Code wurde bereits eingeloest.') return end -- Items geben local itemsGiven = {} local itemsFailed = {} if row.items and row.items ~= '' then local items = json.decode(row.items) if items and type(items) == 'table' then for _, itemData in ipairs(items) do local success = pcall(function() exports['codem-inventory']:AddItem(source, itemData.item, itemData.amount) end) if success then table.insert(itemsGiven, itemData.amount .. 'x ' .. itemData.item) else table.insert(itemsFailed, itemData.amount .. 'x ' .. itemData.item) end end end end -- Geld geben if row.money and row.money > 0 then xPlayer.addMoney(row.money) end if row.bank_money and row.bank_money > 0 then xPlayer.addAccountMoney('bank', row.bank_money) end -- Code als eingeloest markieren MySQL.query.await( 'UPDATE refund_codes SET redeemed_by_identifier = ?, redeemed_by_name = ?, redeemed_at = NOW() WHERE code = ?', { identifier, playerName, codeStr } ) -- Spieler benachrichtigen local msg = '~g~Code erfolgreich eingeloest!' if #itemsGiven > 0 then msg = msg .. '\n~w~Items: ' .. table.concat(itemsGiven, ', ') end if row.money and row.money > 0 then msg = msg .. '\n~w~Bargeld: $' .. tostring(row.money) end if row.bank_money and row.bank_money > 0 then msg = msg .. '\n~w~Bank: $' .. tostring(row.bank_money) end if #itemsFailed > 0 then msg = msg .. '\n~r~Fehlgeschlagen: ' .. table.concat(itemsFailed, ', ') end SendMessage(source, msg) -- Webhook Log local webhookMsg = '**Spieler:** ' .. playerName .. '\n' webhookMsg = webhookMsg .. '**Identifier:** ' .. identifier .. '\n' webhookMsg = webhookMsg .. '**Code:** `' .. codeStr .. '`\n' webhookMsg = webhookMsg .. '**Grund:** ' .. (row.reason or 'Kein Grund') .. '\n' if #itemsGiven > 0 then webhookMsg = webhookMsg .. '**Items erhalten:** ' .. table.concat(itemsGiven, ', ') .. '\n' end if #itemsFailed > 0 then webhookMsg = webhookMsg .. '**Items fehlgeschlagen:** ' .. table.concat(itemsFailed, ', ') .. '\n' end if row.money and row.money > 0 then webhookMsg = webhookMsg .. '**Bargeld:** $' .. tostring(row.money) .. '\n' end if row.bank_money and row.bank_money > 0 then webhookMsg = webhookMsg .. '**Bank:** $' .. tostring(row.bank_money) .. '\n' end local webhookColor = #itemsFailed > 0 and 15158332 or 3066993 -- Rot bei Fehlern, Gruen bei Erfolg SendRefundWebhook('Code eingeloest', webhookMsg, webhookColor) print('[mercyv-refund] Code ' .. codeStr .. ' eingeloest von ' .. playerName .. ' (' .. identifier .. ')') end -- ===================== -- F8 COMMAND -- ===================== RegisterCommand('code', function(source, args) if source == 0 then return end -- Kein RCON if not args[1] or args[1] == '' then SendMessage(source, '~y~Benutze: code ') return end redeemCode(source, args[1]) end, false) print('[mercyv-refund] Resource gestartet')