diff --git a/client/client.lua b/client/client.lua index 840f811..a26a0f7 100644 --- a/client/client.lua +++ b/client/client.lua @@ -3,172 +3,211 @@ RegisterNetEvent("mri_Qstashes:openAdm", function() id = 'stashes_create', menu = 'menu_gerencial', title = locale("openadm.title"), - options = { - { - title = locale("openadm.options_title"), - icon = 'hand', - description = locale("openadm.options_description"), - onSelect = function() - TriggerEvent('mri_Qstashes:client:doray') - end, - }, - { - title = locale("openadm.options2_title"), - icon = 'fa-solid fa-location-dot', - description = locale("openadm.options2_description"), - onSelect = function() - local locations = lib.callback.await('stashesGetAll', false) - local options = {} - for i = 1, #locations do - options[#options + 1] = { - title = locations[i].name, - icon = 'marker', - description = locale("openadm.options2_description2"), - onSelect = function() + options = {{ + title = locale("openadm.options_title"), + icon = 'hand', + description = locale("openadm.options_description"), + onSelect = function() + TriggerEvent('mri_Qstashes:client:doray') + end + }, { + title = locale("openadm.options2_title"), + icon = 'fa-solid fa-location-dot', + description = locale("openadm.options2_description"), + onSelect = function() + local locations = lib.callback.await('stashesGetAll', false) + local options = {} + for i = 1, #locations do + options[#options + 1] = { + title = locations[i].name, + icon = 'marker', + description = locale("openadm.options2_description2"), + onSelect = function() SetEntityCoords(cache.ped, locations[i].loc.x, locations[i].loc.y, locations[i].loc.z) lib.notify({ - title = locale("openadm.options2_title2"), - description = locale("openadm.options2_description3")..' ' .. locations[i].name, + title = locale("openadm.options2_title2"), + description = locale("openadm.options2_description3") .. ' ' .. locations[i].name, + type = 'success' + }) + end + } + end + + lib.showContext('stashes_create') + + Citizen.Wait(500) -- Espera 500ms (meio segundo) + + + lib.registerContext({ + id = 'stashes_teleport', + menu = 'stashes_create', + title = locale("openadm.options2_title3"), + options = options + }) + lib.showContext('stashes_teleport') + end + }, { + title = locale("openadm.options3_title"), + icon = 'trash', + description = locale("openadm.options3_description"), + onSelect = function() + local stashes = lib.callback.await('stashesGetAll', false) + local options = {} + for i = 1, #stashes do + options[#options + 1] = { + title = stashes[i].name, + icon = 'trash', + description = locale("openadm.options3_description2") .. " | Stashe: " .. stashes[i].id, + onSelect = function() + local deleted = TriggerServerEvent("deleteStashesData", stashes[i].id) + if not deleted then + lib.notify({ + title = locale("openadm.title"), + description = locale("openadm.options3_description3"), type = 'success' }) - Citizen.Wait(500) -- Espera 500ms (meio segundo) + else + lib.notify({ + title = locale("openadm.title"), + description = locale("openadm.options3_description4"), + type = 'error' + }) + end + end + } + end + Citizen.Wait(500) -- Aguarda 500 ms (meio segundo) - lib.showContext('stashes_create') - end, - } - end - lib.registerContext({ - id = 'stashes_teleport', - menu = 'stashes_create', - title = locale("openadm.options2_title3"), - options = options - }) - lib.showContext('stashes_teleport') - end, - }, - { - title = locale("openadm.options3_title"), - icon = 'trash', - description = locale("openadm.options3_description"), - onSelect = function() - local stashes = lib.callback.await('stashesGetAll', false) - local options = {} - for i = 1, #stashes do - options[#options + 1] = { - title = stashes[i].name, - icon = 'trash', - description = locale("openadm.options3_description2").." | Stashe: "..stashes[i].id, - onSelect = function() - local deleted = TriggerServerEvent("deleteStashesData", stashes[i].id) - if not deleted then - lib.notify({ - title = locale("openadm.title"), - description = locale("openadm.options3_description3"), - type = 'success' - }) - else - lib.notify({ - title = locale("openadm.title"), - description = locale("openadm.options3_description4"), - type = 'error' - }) - end - Citizen.Wait(500) -- Aguarda 500 ms (meio segundo) - lib.showContext('stashes_create') - end, - } - end - lib.registerContext({ - id = 'stashes_delete', - menu = 'stashes_create', - title = locale("openadm.options3_title2"), - options = options - }) - lib.showContext('stashes_delete') - end, - }, - - } + lib.registerContext({ + id = 'stashes_delete', + title = locale("openadm.options3_title2"), + options = options + }) + lib.showContext('stashes_delete') + end + }} }) + lib.showContext('stashes_create') end) stashes = {} RegisterNetEvent('mri_Qstashes:start', function(stashesTable) Citizen.Wait(500) - for k, v in pairs (stashesTable) do - if v.job == nil then v.job = "" end - if v.gang == nil then v.gang = "" end - if v.targetlabel == "" then v.targetlabel = Config.DefaultMessage end - if v.weight == nil or "" then v.weight = Config.Defaultweight * 1000 end - if v.weight then v.weight = tonumber(v.weight) * 1000 end - if v.slots == nil or "" then v.slots = Config.Defaultslot end - if v.item == nil or "" then v.item = 1 end - if v.cid == nil or "" then v.cid = 2 end - if v.rank then v.rank = tonumber(v.rank) end - if v.rank == nil then v.rank = 0 end - if v.password == nil then v.password = 0 end + for k, v in pairs(stashesTable) do + if v.job == nil then + v.job = "" + end + if v.gang == nil then + v.gang = "" + end + if v.targetlabel == "" then + v.targetlabel = Config.DefaultMessage + end + if v.weight == nil or "" then + v.weight = Config.Defaultweight * 1000 + end + if v.weight then + v.weight = tonumber(v.weight) * 1000 + end + if v.slots == nil or "" then + v.slots = Config.Defaultslot + end + if v.item == nil or "" then + v.item = 1 + end + if v.cid == nil or "" then + v.cid = 2 + end + if v.rank then + v.rank = tonumber(v.rank) + end + if v.rank == nil then + v.rank = 0 + end + if v.password == nil then + v.password = 0 + end + if v.webhook == nil then + v.webhook = "" + end stashes[k] = exports.ox_target:addBoxZone({ coords = v.loc, - size = vec(1,1,5), + size = vec(1, 1, 5), rotation = 0, debug = Config.Debug, - options = { - { - name = 'openstashes', - icon = "fa-solid fa-box-open", - label = v.targetlabel, - distance = 4.5, - onSelect = function() - if v.password ~= 0 then - local input = lib.inputDialog(locale("target.input"), { - {type = 'number', label = locale("target.label"), description = locale("target.description"), min = 1, max = 99999, required = true}, + options = {{ + name = 'openstashes', + icon = "fa-solid fa-box-open", + label = v.targetlabel, + distance = 4.5, + onSelect = function() + if v.password ~= 0 then + local input = lib.inputDialog(locale("target.input"), {{ + type = 'number', + label = locale("target.label"), + description = locale("target.description"), + min = 1, + max = 99999, + required = true + }}) + if input == nil then + return + end + local combo = tonumber(input[1]) or 0 + if v.password == combo then + exports.ox_inventory:openInventory('stash', { + id = "mri_Qstashes" .. v.id }) - if input == nil then return end - local combo = tonumber(input[1]) or 0 - if v.password == combo then - exports.ox_inventory:openInventory('stash', {id = "mri_Qstashes"..v.id}) - end - else - exports.ox_inventory:openInventory('stash', {id = "mri_Qstashes"..v.id}) end - end, - canInteract = function() - if QBX.PlayerData.job.name == v.job or v.job == "" then - if QBX.PlayerData.job.grade.level >= v.rank or v.job == "" then - if QBX.PlayerData.gang.name == v.gang and QBX.PlayerData.gang.grade.level >= v.rank or v.gang == "" then - if v.item == 1 or QBX.HasItem(v.item) then - if QBX.PlayerData.citizenid == v.cid or v.cid == 2 then - return true end - end - end - end - end + else + exports.ox_inventory:openInventory('stash', { + id = "mri_Qstashes" .. v.id + }) end - }, - }, + end, + canInteract = function() + if QBX.PlayerData.job.name == v.job or v.job == "" then + if QBX.PlayerData.job.grade.level >= v.rank or v.job == "" then + if QBX.PlayerData.gang.name == v.gang and QBX.PlayerData.gang.grade.level >= v.rank or + v.gang == "" then + if v.item == 1 or QBX.HasItem(v.item) then + if QBX.PlayerData.citizenid == v.cid or v.cid == 2 then + return true + end + end + end + end + end + end + }} }) end print("[mri_Qstashes] - Loaded database.") end) RegisterNetEvent('mri_Qstashes:delete', function(stashesTable) - if stashes == {} or nil then return end - local table = stashesTable + if stashes == {} or nil then + return + end + local table = stashesTable for i = 1, #table + 1 do if stashes[i] ~= nil then - exports.ox_target:removeZone(stashes[i]) + exports.ox_target:removeZone(stashes[i]) end - end + end stashes = {} end) function StartRay() local run = true while run do - local hit, entity, endCoords = lib.raycast.cam(1|16) - lib.showTextUI(locale("raycast.title")..' \n X: ' .. endCoords.x .. ', \n Y: ' .. endCoords.y .. ', \n Z: ' .. endCoords.z .. ' \n '.. locale("raycast.e_button") ..' \n '..locale("raycast.del_button")) - DrawMarker(28, endCoords.x, endCoords.y, endCoords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.2, 255, 42, 24, 100, false, false, 0, true, false, false, false) + local hit, entity, endCoords = lib.raycast.cam(1 | 16) + lib.showTextUI(locale("raycast.title") .. ' \n X: ' .. endCoords.x .. ', \n Y: ' .. endCoords.y .. + ', \n Z: ' .. endCoords.z .. ' \n ' .. locale("raycast.e_button") .. ' \n ' .. + locale("raycast.del_button")) + DrawMarker(28, endCoords.x, endCoords.y, endCoords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.2, 255, 42, 24, + 100, false, false, 0, true, false, false, false) if IsControlJustReleased(0, 38) then lib.hideTextUI() run = false @@ -183,29 +222,80 @@ function StartRay() end RegisterNetEvent('mri_Qstashes:client:doray', function() - local stashmake = StartRay() - if stashmake ~= nil then - local input = lib.inputDialog(locale("createmenu.title"), { - {type = 'input', label = locale("createmenu.input1"), description = locale("createmenu.description1"), required = true}, - {type = 'input', label = locale("createmenu.input2"), description = locale("createmenu.description2")}, - {type = 'input', label = locale("createmenu.input3"), description = locale("createmenu.description3")}, - {type = 'input', label = locale("createmenu.input4"), description = locale("createmenu.description4")}, - {type = 'input', label = locale("createmenu.input5"), description = locale("createmenu.description5")}, - {type = 'number', label = locale("createmenu.input6"), description = locale("createmenu.description6")..' - default: '..Config.Defaultslot..' Slots)'}, - {type = 'number', label = locale("createmenu.input7"), description = locale("createmenu.description7")..' - default: '..Config.Defaultweight..' Kg)', min = 1, max = 999999999}, - {type = 'number',label = locale("createmenu.input8"), description = locale("createmenu.description8"), min = 1, max = 99999}, - {type = 'input', label = locale("createmenu.input9"), description = locale("createmenu.description9")}, - {type = 'input', label = locale("createmenu.input10"), description = locale("createmenu.description10")}, - }) - if input and input[1] ~= "" then - if input[6] == nil then input[6] = Config.Defaultslot end - if input[7] == nil then input[7] = Config.Defaultweight * 1000 else input[7] = input[7] * 1000 end - TriggerServerEvent("insertStashesData", input, stashmake) - lib.notify({ type = 'success', description = locale("createmenu.notify_sucess") }) - else - lib.notify({ type = 'error', description = locale("createmenu.notify_error") }) - end - end + local stashmake = StartRay() + if stashmake ~= nil then + local input = lib.inputDialog(locale("createmenu.title"), {{ + type = 'input', + label = locale("createmenu.input1"), + description = locale("createmenu.description1"), + required = true + }, { + type = 'input', + label = locale("createmenu.input2"), + description = locale("createmenu.description2") + }, { + type = 'input', + label = locale("createmenu.input3"), + description = locale("createmenu.description3") + }, { + type = 'input', + label = locale("createmenu.input4"), + description = locale("createmenu.description4") + }, { + type = 'input', + label = locale("createmenu.input5"), + description = locale("createmenu.description5") + }, { + type = 'number', + label = locale("createmenu.input6"), + description = locale("createmenu.description6") .. ' - default: ' .. Config.Defaultslot .. ' Slots)' + }, { + type = 'number', + label = locale("createmenu.input7"), + description = locale("createmenu.description7") .. ' - default: ' .. Config.Defaultweight .. ' Kg)', + min = 1, + max = 999999999 + }, { + type = 'number', + label = locale("createmenu.input8"), + description = locale("createmenu.description8"), + min = 1, + max = 99999 + }, { + type = 'input', + label = locale("createmenu.input9"), + description = locale("createmenu.description9") + }, { + type = 'input', + label = locale("createmenu.input10"), + description = locale("createmenu.") + }, { + type = 'input', + label = locale("createmenu.input11"), + description = locale("createmenu.description11") + }}) + if input and input[1] ~= "" then + if input[6] == nil then + input[6] = Config.Defaultslot + end + if input[7] == nil then + input[7] = Config.Defaultweight * 1000 + else + input[7] = input[7] * 1000 + end + TriggerServerEvent("insertStashesData", input, stashmake) + lib.notify({ + type = 'success', + description = locale("createmenu.notify_sucess") + }) + + else + lib.notify({ + type = 'error', + description = locale("createmenu.notify_error") + }) + end + end end) RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() @@ -214,4 +304,6 @@ end) RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() TriggerServerEvent("mri_Qstashes:server:Unload") -end) \ No newline at end of file +end) + + diff --git a/locales/en.json b/locales/en.json index 02148d6..8bacb25 100644 --- a/locales/en.json +++ b/locales/en.json @@ -48,6 +48,8 @@ "description9": "Enter allowed Citizen ID (optional)", "input10": "Target Description", "description10": "Enter if you want to customize the default 'Open Stash' message (optional)", + "input11": "Discord Webhook", + "description11": "Add the discord webhook to get a log of what is in and out of the chest", "notify_sucess": "Stash created successfully!", "notify_error": "Stash creation canceled!" }, diff --git a/locales/pt-br.json b/locales/pt-br.json index 328b218..0303b9b 100644 --- a/locales/pt-br.json +++ b/locales/pt-br.json @@ -48,6 +48,8 @@ "description9": "Digite o Citizen ID permitido (opcional)", "input10": "Descrição do Target", "description10": "Digite caso queira personalizar a mensagem padrão 'Abrir baú' (opcional)", + "input11": "Discord Webhook", + "description11": "Adicione o webhook do discord para obter um log do que é colocado e retirado do baú", "notify_sucess": "Baú criado com sucesso!", "notify_error": "Criação de baú cancelada!" }, diff --git a/server/server.lua b/server/server.lua index 575ba35..95213c6 100644 --- a/server/server.lua +++ b/server/server.lua @@ -2,10 +2,9 @@ ------------- data Set --------------------------------------------------------------- local stashesTable = {} - RegisterNetEvent("insertStashesData", function(input, loc) stashesTable[#stashesTable + 1] = { - id = math.random(100000,999999), + id = math.random(100000, 999999), name = input[1] or nil, job = input[2] or nil, gang = input[3] or nil, @@ -16,7 +15,8 @@ RegisterNetEvent("insertStashesData", function(input, loc) password = input[8] or nil, citizenID = input[9] or nil, targetlabel = input[10] or nil, - loc = loc or nil, + webhookURL = input[11] or nil, + loc = loc or nil } SaveStashesData() end) @@ -41,7 +41,7 @@ function SaveStashesData() local jsonData = json.encode(stashesTable) SaveResourceFile(GetCurrentResourceName(), "data.json", jsonData, -1) TriggerClientEvent('mri_Qstashes:start', -1, stashesTable) - RegisterStashData() + LoadStashesData() end function LoadStashesData() @@ -52,15 +52,33 @@ function LoadStashesData() RegisterStashData() end +local function RegisterHookData(stash) + local webhookURL = "" + local inventory = "" + exports.ox_inventory:registerHook('swapItems', function(payload) + if payload.fromInventory == stash.id then + webhookURL = stash.webhookURL + inventory = stash.label + WebhookPlayer(payload, webhookURL, inventory) + elseif payload.toInventory == stash.id and payload.action == "move"then + webhookURL = stash.webhookURL + inventory = stash.label + WebhookPlayer(payload, webhookURL, inventory) + end + end, options) +end + function RegisterStashData() - for k, v in pairs (stashesTable) do + for k, v in pairs(stashesTable) do local stash = { - id = "mri_Qstashes"..v.id, - label = v.name, - slots = v.slotSize, - weight = tonumber(v.weight), + id = "mri_Qstashes" .. v.id, + label = v.name, + slots = v.slotSize, + webhookURL = v.webhookURL, + weight = tonumber(v.weight) } exports.ox_inventory:RegisterStash(stash.id, stash.label, stash.slots, stash.weight) + RegisterHookData(stash) end end @@ -74,9 +92,11 @@ end) AddEventHandler('onResourceStart', function(resourceName) if GetCurrentResourceName() == resourceName then LoadStashesData() + if GetResourceState('ox_inventory') ~= 'started' then + return print("[mri_Qstashes] - ox_inventory não encontrado.") + end Wait(1000) TriggerClientEvent('mri_Qstashes:start', -1, stashesTable) - print("[mri_Qstashes] - Loaded database.") end end) @@ -94,14 +114,60 @@ RegisterNetEvent("mri_Qstashes:server:Unload", function() TriggerClientEvent("mri_Qstashes:delete", src, stashesTable) end) - --------------------------------------------------------------- ------------- addCommand --------------------------------------------------------------- lib.addCommand(Config.Command, { help = locale("command.help"), - restricted = 'group.admin', + restricted = 'group.admin' }, function(source, args, raw) local src = source TriggerClientEvent('mri_Qstashes:openAdm', src) end) + +--------------------------------------------------------------- +------------- Webhook Discord +--------------------------------------------------------------- + +local function sendWebhook(webhook, data) + if webhook == nil then + print('^1[logs] ^0Webhook ' .. webhook .. ' does not exist.') + return + end + + PerformHttpRequest(webhook, function(err, text, headers) + end, 'POST', json.encode({ + embeds = data + }), { + ['Content-Type'] = 'application/json' + }) +end + +function WebhookPlayer(payload, webhookURL, inventory) + local webhookURL = webhookURL + local description = "" + if not webhookURL then + return + end + local playerName = GetPlayerName(payload.source) + local playerdiscord = GetPlayerIdentifierByType(payload.source, 'discord'):match("%d+") + local playerIdentifier = GetPlayerIdentifiers(payload.source)[1] + local playerCoords = GetEntityCoords(GetPlayerPed(payload.source)) + + if payload.fromType == "player" and payload.toType == "stash" then + description = + ('Cidadão: **%s** \nDiscordID: <@%s> \nID: **%s** \nColocou Item: **%s** \nQuantidade: **%s** \nMetadata: **%s** \nNome do Bau: **%s** \nCoordenadas: ```%s```') + elseif payload.fromType == "stash" and payload.toType == "player" then + description = + ('Cidadão: **%s** \nDiscordID: <@%s> \nID: **%s** \nPegou Item: **%s** \nQuantidade: **%s** \nMetadata: **%s** \nNome do Bau: **%s** \nCoordenadas: ```%s```') + end + + sendWebhook(webhookURL, {{ + title = 'Bau', + description = description:format(playerName, playerdiscord, payload.source, payload.fromSlot.name, + payload.fromSlot.count, json.encode(payload.fromSlot.metadata), inventory, + ('%s, %s, %s'):format(playerCoords.x, playerCoords.y, playerCoords.z)), + color = Config.Color + }}) +end + diff --git a/shared/Config.lua b/shared/Config.lua index 844cd5b..eddc3ad 100644 --- a/shared/Config.lua +++ b/shared/Config.lua @@ -1,4 +1,5 @@ Config = {} +Config.Color = 0x00ff00 Config.Command = "bau" Config.Defaultslot = 50 Config.Defaultweight = 1000