From 9b9b7645dbf5175189da8970894ebe251373b165 Mon Sep 17 00:00:00 2001 From: delucecc <31872986+delucecc@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:22:31 -0800 Subject: [PATCH] Version 2 --- README.md | 2 +- client/client.lua | 28 +++++---- config.lua | 40 ++++++++++--- server/server.lua | 148 +++++++++++++++++++++++++++++++++------------- 4 files changed, 158 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index e348d8e..714281b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ngd-pdduty - ngd-pdduty is a simple system that uses Discord webhooks to notify when a police officer goes on and off duty. It also tracks the time someone was on duty, and enables the ability to use a slash command to toggle duty on and off. + ngd-jobduty is a simple system that uses Discord webhooks to notify when a player with a configured job goes on and off duty. It also enables the use of a / command to toggle duty if required. This script supports multiple jobs, with multiple webhooks. Created by Nemesis Gaming Development: https://discord.gg/AnXx2GVGcM diff --git a/client/client.lua b/client/client.lua index e0679f6..f280dfe 100644 --- a/client/client.lua +++ b/client/client.lua @@ -1,23 +1,29 @@ local QBCore = exports['qb-core']:GetCoreObject() - local PlayerData = {} RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() PlayerData = QBCore.Functions.GetPlayerData() + local isOnDuty = PlayerData.job and PlayerData.job.onduty + TriggerServerEvent('SetInitialDutyStatus', isOnDuty) + if isOnDuty then + TriggerServerEvent('SendOnDutyWebhook', PlayerData.job.name) + end end) RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() PlayerData = {} end) -if Config.UseCommand then - RegisterCommand(Config.Command, function() - if PlayerData.job and PlayerData.job.name == Config.PoliceJob or PlayerData.job and PlayerData.job.type == Config.PoliceJobType then - TriggerServerEvent('QBCore:ToggleDuty') - end - end) - - CreateThread(function() - TriggerEvent('chat:addSuggestion', Config.ChatSuggestion, Config.ChatSuggestionM, {}) - end) +for _, jobConfig in pairs(Config.Jobs) do + if jobConfig.UseCommand and jobConfig.UseCommand.Enabled then + RegisterCommand(jobConfig.UseCommand.Command, function() + if PlayerData.job and (PlayerData.job.name == jobConfig.JobName) then + TriggerServerEvent('QBCore:ToggleDuty') + end + end) + CreateThread(function() + TriggerEvent('chat:addSuggestion', jobConfig.UseCommand.ChatSuggestion, jobConfig.UseCommand.ChatSuggestionM, + {}) + end) + end end diff --git a/config.lua b/config.lua index 7240517..152ce76 100644 --- a/config.lua +++ b/config.lua @@ -1,9 +1,35 @@ Config = {} ---You can either use police job or the type below. -Config.PoliceJob = 'police' --Police job qbcore>shared>jobs.lua -Config.PoliceJobType = 'leo' --Police job type in qbcore>shared>jobs.lua type = -Config.UseCommand = true --Enables a / command for police to toggle duty. -Config.Command = "pdduty" --Name of / command for duty toggle -Config.ChatSuggestion = "/pdduty" --Chat suggestion -Config.ChatSuggestionM = "Duty Toggle For Police" --Chat suggestion +Config.Jobs = { + police = { --Name you must put in server.lua for webhook + JobName = 'police', --Name of job in qb-core>shared>jobs.lua + SendCallsign = true, --Send callsign to webhook (This requires a job setup for the qbcore /callsign command) + UseCommand = { + Enabled = true, --Enable the use of a / command + Command = "pdduty", --Command to toggle duty + ChatSuggestion = "/pdduty", --Shows the / command suggestion + ChatSuggestionM = "Duty Toggle For Police", --Shows the / command suggestion description + }, + }, + ambulance = { + JobName = 'ambulance', + SendCallsign = true, + UseCommand = { + Enabled = true, + Command = "emsduty", + ChatSuggestion = "/emsduty", + ChatSuggestionM = "Duty Toggle For EMS", + }, + }, + tobacco = { + JobName = 'tobacco', + SendCallsign = false, + UseCommand = { + Enabled = false, + Command = "tobaccoduty", + ChatSuggestion = "/tobaccoduty", + ChatSuggestionM = "Duty Toggle For Tobacco Farmer", + }, + }, + -- Add more jobs following the format above. +} diff --git a/server/server.lua b/server/server.lua index c92c778..37c2361 100644 --- a/server/server.lua +++ b/server/server.lua @@ -1,78 +1,144 @@ +local QBCore = exports['qb-core']:GetCoreObject() +local onDutyTimes = {} -- ██ ██ ███████ ██████ ██ ██ ██████ ██████ ██ ██ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ██ █ ██ █████ ██████ ███████ ██ ██ ██ ██ █████ -- ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ███ ███ ███████ ██████ ██ ██ ██████ ██████ ██ ██ +local JobWebhooks = { + police = 'CHANGEME', + ambulance = 'CHANGEME', + tobacco = 'CHANGEME', + --Add more to match config. +} -Config.Webhook = 'CHANGEME' ---------------------------------------------------------------------------------------------------------------------------------------------- - - -local QBCore = exports['qb-core']:GetCoreObject() -local onDutyTimes = {} - -AddEventHandler('playerDropped', function(reason) - local src = source - if onDutyTimes[src] then - local xPlayer = QBCore.Functions.GetPlayer(src) - local playerName = xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname - sendDutyTimeWebhook(src, playerName) - onDutyTimes[src] = nil - end -end) - -function sendDutyTimeWebhook(src, playerName) +function sendDutyTimeWebhook(src, playerName, jobName, jobLabel, playerDropped) local endTime = os.time() local timeOnDuty = os.difftime(endTime, onDutyTimes[src]) - local hours = math.floor(timeOnDuty / 3600) - local minutes = math.floor((timeOnDuty % 3600) / 60) - local seconds = timeOnDuty % 60 - sendToDiscord(playerName .. - " went off duty. Total time on duty: " .. hours .. "H " .. minutes .. "M " .. seconds .. "S") + local xPlayer = QBCore.Functions.GetPlayer(src) + local metadata = xPlayer.PlayerData.metadata + local callsign = "" + if Config.Jobs[jobName] and Config.Jobs[jobName].SendCallsign and metadata and metadata.callsign then + callsign = metadata.callsign + end + local dutyStatus = "Off Duty" + if playerDropped then + dutyStatus = "Off Duty - Player Dropped" + end + sendToDiscord(jobName, playerName, callsign, timeOnDuty, nil, dutyStatus, 16711680, jobLabel) end RegisterNetEvent('QBCore:ToggleDuty') AddEventHandler('QBCore:ToggleDuty', function() local src = source local xPlayer = QBCore.Functions.GetPlayer(src) - local playerName = xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname - local metadata = xPlayer.PlayerData.metadata - if metadata and metadata.callsign then - playerName = playerName .. " (Callsign: " .. metadata.callsign .. ")" - end - if xPlayer.PlayerData.job and xPlayer.PlayerData.job.name == Config.PoliceJob or xPlayer.PlayerData.job and xPlayer.PlayerData.job.type == Config.PoliceJobType then - if onDutyTimes[src] then - sendDutyTimeWebhook(src, playerName) + local jobName = xPlayer.PlayerData.job.name + local jobLabel = QBCore.Shared.Jobs[jobName] and QBCore.Shared.Jobs[jobName].label or jobName + local jobConfig = Config.Jobs[jobName] + if jobConfig and JobWebhooks[jobName] then + local playerName = xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname + local metadata = xPlayer.PlayerData.metadata + local callsign = "" + if jobConfig.SendCallsign and metadata and metadata.callsign then + callsign = metadata.callsign + end + if onDutyTimes[src] then --Off duty + sendDutyTimeWebhook(src, playerName, jobName, jobLabel) onDutyTimes[src] = nil else - onDutyTimes[src] = os.time() - sendToDiscord(playerName .. " went on duty.") + onDutyTimes[src] = os.time() -- On duty + sendToDiscord(jobName, playerName, callsign, nil, nil, "On Duty", 65280, jobLabel) end end end) +RegisterNetEvent('SendOnDutyWebhook') +AddEventHandler('SendOnDutyWebhook', function(jobName) + local src = source + local xPlayer = QBCore.Functions.GetPlayer(src) + local playerName = xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname + local jobLabel = QBCore.Shared.Jobs[jobName] and QBCore.Shared.Jobs[jobName].label or jobName + local metadata = xPlayer.PlayerData.metadata + local callsign = "" + if Config.Jobs[jobName].SendCallsign and metadata and metadata.callsign then + callsign = metadata.callsign + end + if JobWebhooks[jobName] then + local customMessage = "**Player Name:**\n`" .. playerName .. "`\n" + customMessage = customMessage .. "**Job:**\n`" .. jobLabel .. "`\n" + if callsign and callsign ~= "" then + customMessage = customMessage .. "**Callsign:**\n`" .. callsign .. "`\n" + end + customMessage = customMessage .. "\n" .. playerName .. " has loaded into the server and was put on duty." + sendToDiscord(jobName, playerName, callsign, nil, customMessage, "Player Logged In", 65280) + end +end) -function sendToDiscord(message) - local webhook = Config.Webhook - if webhook == '' or webhook == 'CHANGEME' then - print('Please put webhook into editableserver.lua') +RegisterNetEvent('SetInitialDutyStatus') +AddEventHandler('SetInitialDutyStatus', function(isOnDuty) + local src = source + if isOnDuty then + onDutyTimes[src] = os.time() + else + onDutyTimes[src] = nil + end +end) + +AddEventHandler('playerDropped', function(reason) + local src = source + if onDutyTimes[src] then + local xPlayer = QBCore.Functions.GetPlayer(src) + local playerName = xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname + local jobName = xPlayer.PlayerData.job.name + local jobLabel = QBCore.Shared.Jobs[jobName] and QBCore.Shared.Jobs[jobName].label or jobName + sendDutyTimeWebhook(src, playerName, jobName, jobLabel, true) + onDutyTimes[src] = nil + end +end) + + +function sendToDiscord(jobName, playerName, callsign, timeOnDuty, customMessage, dutyStatus, color, jobLabel) + local webhook = JobWebhooks[jobName] + if not webhook or webhook == 'CHANGEME' then + print('Webhook URL is not set for job: ' .. jobName) return end + local title = "Duty Status Update" + if dutyStatus then + title = title .. " (" .. dutyStatus .. ")" + end + local message + if customMessage then + message = customMessage + else + message = "**Player Name:**\n`" .. playerName .. "`\n" + message = message .. "**Job:**\n`" .. (jobLabel or jobName) .. "`\n" + if callsign and callsign ~= "" then + message = message .. "**Callsign:**\n`" .. callsign .. "`\n" + end + if timeOnDuty then + local hours = math.floor(timeOnDuty / 3600) + local minutes = math.floor((timeOnDuty % 3600) / 60) + local seconds = timeOnDuty % 60 + message = message .. "**Time on Duty:**\n`" .. hours .. "H " .. minutes .. "M " .. seconds .. "S`" + end + end local currentDateTime = os.date("%m-%d-%Y %H:%M:%S") local connect = { { - ["color"] = 255, - ["title"] = "Police Duty Log", + ["color"] = color or 255, -- Default color if none is provided + ["title"] = title, ["description"] = message, ["footer"] = { - ["icon_url"] = "https://media.discordapp.net/attachments/1077462714902917171/1077462755625418862/96Logo.png", + ["icon_url"] = + "https://media.discordapp.net/attachments/1077462714902917171/1077462755625418862/96Logo.png", ["text"] = "www.nemesisGD.com | " .. currentDateTime, }, } } PerformHttpRequest(webhook, function(err, text, headers) end, 'POST', json.encode({ - username = 'Nemesis Gaming Development | Police Duty', + username = 'Nemesis Gaming Development | Duty Status', embeds = connect, avatar_url = 'https://media.discordapp.net/attachments/1077462714902917171/1077462755625418862/96Logo.png' }),