Scripts/resources/[ps]/ps-mdt/server/main.lua
2024-12-29 21:28:24 +01:00

1937 lines
74 KiB
Lua

local QBCore = exports['qb-core']:GetCoreObject()
local incidents = {}
local convictions = {}
local bolos = {}
local MugShots = {}
local activeUnits = {}
local impound = {}
local dispatchMessages = {}
local isDispatchRunning = false
local antiSpam = false
--------------------------------
-- SET YOUR WEHBOOKS IN HERE
-- Images for mug shots will be uploaded here. Add a Discord webhook.
local MugShotWebhook = 'https://discord.com/api/webhooks/1188025948134707321/6SzjGTwogoKuDXnkfpMhc7162ms3TZnM1BlcDlP3Hzw9WCiPo6-ITGYBSdvs-R65q-aT'
-- Clock-in notifications for duty. Add a Discord webhook.
-- Command /mdtleaderboard, will display top players per clock-in hours.
local ClockinWebhook = 'https://discord.com/api/webhooks/1188025868879134801/TTugGxevAZhB__oYosPEWv-FalL2WeKYUI9je8shU5Xx85EyeJUAmVQKcmOZh8UT_46Z'
--------------------------------
QBCore.Functions.CreateCallback('ps-mdt:server:MugShotWebhook', function(source, cb)
if MugShotWebhook == '' then
print("\27[31mA webhook is missing in: MugShotWebhook (server > main.lua > line 16)\27[0m")
else
cb(MugShotWebhook)
end
end)
local function GetActiveData(cid)
local player = type(cid) == "string" and cid or tostring(cid)
if player then
return activeUnits[player] and true or false
end
return false
end
local function IsPoliceOrEms(job)
for k, v in pairs(Config.PoliceJobs) do
if job == k then
return true
end
end
for k, v in pairs(Config.AmbulanceJobs) do
if job == k then
return true
end
end
return false
end
function getTopOfficers(callback)
local result = {}
local query = 'SELECT * FROM mdt_clocking ORDER BY total_time DESC LIMIT 25'
MySQL.Async.fetchAll(query, {}, function(officers)
for k, officer in ipairs(officers) do
table.insert(result, {
rank = k,
name = officer.firstname .. " " .. officer.lastname,
callsign = officer.user_id,
totalTime = format_time(officer.total_time)
})
end
callback(result)
end)
end
RegisterServerEvent("mdt:requestOfficerData")
AddEventHandler("mdt:requestOfficerData", function()
local src = source
getTopOfficers(function(officerData)
TriggerClientEvent("mdt:receiveOfficerData", src, officerData)
end)
end)
function sendToDiscord(color, name, message, footer)
if ClockinWebhook == '' then
print("\27[31mA webhook is missing in: ClockinWebhook (server > main.lua > line 20)\27[0m")
else
local embed = {
{
color = color,
title = "**".. name .."**",
description = message,
footer = {
text = footer,
},
}
}
PerformHttpRequest(ClockinWebhook, function(err, text, headers) end, 'POST', json.encode({username = name, embeds = embed}), { ['Content-Type'] = 'application/json' })
end
end
function format_time(time)
local days = math.floor(time / 86400)
time = time % 86400
local hours = math.floor(time / 3600)
time = time % 3600
local minutes = math.floor(time / 60)
local seconds = time % 60
local formattedTime = ""
if days > 0 then
formattedTime = string.format("%d day%s ", days, days == 1 and "" or "s")
end
if hours > 0 then
formattedTime = formattedTime .. string.format("%d hour%s ", hours, hours == 1 and "" or "s")
end
if minutes > 0 then
formattedTime = formattedTime .. string.format("%d minute%s ", minutes, minutes == 1 and "" or "s")
end
if seconds > 0 then
formattedTime = formattedTime .. string.format("%d second%s", seconds, seconds == 1 and "" or "s")
end
return formattedTime
end
function GetPlayerPropertiesByCitizenId(citizenid)
local properties = {}
local result = MySQL.Sync.fetchAll("SELECT * FROM properties WHERE owner_citizenid = @citizenid", {
['@citizenid'] = citizenid
})
if result and #result > 0 then
for i = 1, #result do
table.insert(properties, result[i])
end
end
return properties
end
RegisterServerEvent("ps-mdt:dispatchStatus", function(bool)
isDispatchRunning = bool
end)
if Config.UseWolfknightRadar == true then
RegisterNetEvent("wk:onPlateScanned")
AddEventHandler("wk:onPlateScanned", function(cam, plate, index)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local PlayerData = GetPlayerData(src)
local vehicleOwner = GetVehicleOwner(plate)
local bolo, title, boloId = GetBoloStatus(plate)
local warrant, owner, incidentId = GetWarrantStatus(plate)
local driversLicense = PlayerData.metadata['licences'].driver
if bolo == true then
TriggerClientEvent('QBCore:Notify', src, 'BOLO ID: '..boloId..' | Titel: '..title..' | Registreret ejer: '..vehicleOwner..' | Nummerplade: '..plate, 'error', Config.WolfknightNotifyTime)
end
if warrant == true then
TriggerClientEvent('QBCore:Notify', src, 'EFTERLYST - HÆNDELSES-ID: '..incidentId..' | Registreret ejer: '..owner..' | Nummerplade: '..plate, 'error', Config.WolfknightNotifyTime)
end
if Config.PlateScanForDriversLicense and driversLicense == false and vehicleOwner then
TriggerClientEvent('QBCore:Notify', src, 'INTET KØREKORT | Registreret ejer: '..vehicleOwner..' | Nummerplade: '..plate, 'error', Config.WolfknightNotifyTime)
end
if bolo or warrant or (Config.PlateScanForDriversLicense and not driversLicense) then
TriggerClientEvent("wk:togglePlateLock", src, cam, true, 1)
end
end)
end
AddEventHandler('onResourceStart', function(resourceName)
if GetCurrentResourceName() ~= resourceName then return end
Wait(3000)
if MugShotWebhook == '' then
print("\27[31mA webhook is missing in: MugShotWebhook (server > main.lua > line 16)\27[0m")
end
if ClockinWebhook == '' then
print("\27[31mA webhook is missing in: ClockinWebhook (server > main.lua > line 20)\27[0m")
end
end)
RegisterNetEvent("ps-mdt:server:OnPlayerUnload", function()
--// Delete player from the MDT on logout
local src = source
local player = QBCore.Functions.GetPlayer(src)
if GetActiveData(player.PlayerData.citizenid) then
activeUnits[player.PlayerData.citizenid] = nil
end
end)
AddEventHandler('playerDropped', function(reason)
local src = source
local PlayerData = GetPlayerData(src)
if PlayerData == nil then return end -- Player not loaded in correctly and dropped early
local time = os.date("%Y-%m-%d %H:%M:%S")
local job = PlayerData.job.name
local firstName = PlayerData.charinfo.firstname:sub(1,1):upper()..PlayerData.charinfo.firstname:sub(2)
local lastName = PlayerData.charinfo.lastname:sub(1,1):upper()..PlayerData.charinfo.lastname:sub(2)
-- Auto clock out if the player is off duty
if IsPoliceOrEms(job) and PlayerData.job.onduty then
MySQL.query.await('UPDATE mdt_clocking SET clock_out_time = NOW(), total_time = TIMESTAMPDIFF(SECOND, clock_in_time, NOW()) WHERE user_id = @user_id ORDER BY id DESC LIMIT 1', {
['@user_id'] = PlayerData.citizenid
})
local result = MySQL.scalar.await('SELECT total_time FROM mdt_clocking WHERE user_id = @user_id', {
['@user_id'] = PlayerData.citizenid
})
if result then
local time_formatted = format_time(tonumber(result))
sendToDiscord(16711680, "MDT klokkede ud", 'Spiller: **' .. firstName .. " ".. lastName .. '**\n\nJob: **' .. PlayerData.job.name .. '**\n\nRank: **' .. PlayerData.job.grade.name .. '**\n\nStatus: **Gået hjem**\n Total tid:' .. time_formatted, "ps-mdt | Lavet af Project Sloth")
end
end
-- Delete player from the MDT on logout
if PlayerData ~= nil then
if GetActiveData(PlayerData.citizenid) then
activeUnits[PlayerData.citizenid] = nil
end
else
local license = QBCore.Functions.GetIdentifier(src, "license")
local citizenids = GetCitizenID(license)
for _, v in pairs(citizenids) do
if GetActiveData(v.citizenid) then
activeUnits[v.citizenid] = nil
end
end
end
end)
RegisterNetEvent("ps-mdt:server:ToggleDuty", function()
local src = source
local player = QBCore.Functions.GetPlayer(src)
if not player.PlayerData.job.onduty then
--// Remove from MDT
if GetActiveData(player.PlayerData.citizenid) then
activeUnits[player.PlayerData.citizenid] = nil
end
end
end)
QBCore.Commands.Add("mdtleaderboard", "Vis MDT leaderboard", {}, false, function(source, args)
local PlayerData = GetPlayerData(source)
local job = PlayerData.job.name
if not IsPoliceOrEms(job) then
TriggerClientEvent('QBCore:Notify', source, "Du har ikke tilladelse til denne command", 'error')
return
end
local result = MySQL.Sync.fetchAll('SELECT firstname, lastname, total_time FROM mdt_clocking ORDER BY total_time DESC')
local leaderboard_message = '**MDT Leaderboard**\n\n'
for i, record in ipairs(result) do
local firstName = record.firstname:sub(1,1):upper()..record.firstname:sub(2)
local lastName = record.lastname:sub(1,1):upper()..record.lastname:sub(2)
local total_time = format_time(record.total_time)
leaderboard_message = leaderboard_message .. i .. '. **' .. firstName .. ' ' .. lastName .. '** - ' .. total_time .. '\n'
end
sendToDiscord(16753920, "MDT Leaderboard", leaderboard_message, "ps-mdt | Lavet af Project Sloth")
TriggerClientEvent('QBCore:Notify', source, "MDT leaderboard blev sendt til Discord!", 'success')
end)
RegisterNetEvent("ps-mdt:server:ClockSystem", function()
local src = source
local PlayerData = GetPlayerData(src)
local time = os.date("%Y-%m-%d %H:%M:%S")
local firstName = PlayerData.charinfo.firstname:sub(1,1):upper()..PlayerData.charinfo.firstname:sub(2)
local lastName = PlayerData.charinfo.lastname:sub(1,1):upper()..PlayerData.charinfo.lastname:sub(2)
if PlayerData.job.onduty then
TriggerClientEvent('QBCore:Notify', source, "Du gik på arbejde", 'success')
MySQL.Async.insert('INSERT INTO mdt_clocking (user_id, firstname, lastname, clock_in_time) VALUES (:user_id, :firstname, :lastname, :clock_in_time) ON DUPLICATE KEY UPDATE user_id = :user_id, firstname = :firstname, lastname = :lastname, clock_in_time = :clock_in_time', {
user_id = PlayerData.citizenid,
firstname = firstName,
lastname = lastName,
clock_in_time = time
}, function()
end)
sendToDiscord(65280, "MDT Klokkede ind", 'Spiller: **' .. firstName .. " ".. lastName .. '**\n\nJob: **' .. PlayerData.job.name .. '**\n\nRank: **' .. PlayerData.job.grade.name .. '**\n\nStatus: **På arbejde**', "ps-mdt | Lavet af Project Sloth")
else
TriggerClientEvent('QBCore:Notify', source, "Du klokkede ud", 'success')
MySQL.query.await('UPDATE mdt_clocking SET clock_out_time = NOW(), total_time = TIMESTAMPDIFF(SECOND, clock_in_time, NOW()) WHERE user_id = @user_id ORDER BY id DESC LIMIT 1', {
['@user_id'] = PlayerData.citizenid
})
local result = MySQL.scalar.await('SELECT total_time FROM mdt_clocking WHERE user_id = @user_id', {
['@user_id'] = PlayerData.citizenid
})
local time_formatted = format_time(tonumber(result))
sendToDiscord(16711680, "MDT Klokkede ud", 'Spillet: **' .. firstName .. " ".. lastName .. '**\n\nJob: **' .. PlayerData.job.name .. '**\n\nRank: **' .. PlayerData.job.grade.name .. '**\n\nStatus: **Gået hjem**\n Total tid:' .. time_formatted, "ps-mdt | Lavet af Project Sloth")
end
end)
RegisterNetEvent('mdt:server:openMDT', function()
local src = source
local PlayerData = GetPlayerData(src)
if not PermCheck(src, PlayerData) then return end
local Radio = Player(src).state.radioChannel or 0
activeUnits[PlayerData.citizenid] = {
cid = PlayerData.citizenid,
callSign = PlayerData.metadata['callsign'],
firstName = PlayerData.charinfo.firstname:sub(1,1):upper()..PlayerData.charinfo.firstname:sub(2),
lastName = PlayerData.charinfo.lastname:sub(1,1):upper()..PlayerData.charinfo.lastname:sub(2),
radio = Radio,
unitType = PlayerData.job.name,
duty = PlayerData.job.onduty
}
local JobType = GetJobType(PlayerData.job.name)
local bulletin = GetBulletins(JobType)
local calls = exports['ps-dispatch']:GetDispatchCalls()
TriggerClientEvent('mdt:client:open', src, bulletin, activeUnits, calls, PlayerData.citizenid)
end)
QBCore.Functions.CreateCallback('mdt:server:SearchProfile', function(source, cb, sentData)
if not sentData then return cb({}) end
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType ~= nil then
local people = MySQL.query.await("SELECT p.citizenid, p.charinfo, md.pfp, md.fingerprint FROM players p LEFT JOIN mdt_data md on p.citizenid = md.cid WHERE LOWER(CONCAT(JSON_VALUE(p.charinfo, '$.firstname'), ' ', JSON_VALUE(p.charinfo, '$.lastname'))) LIKE :query OR LOWER(`charinfo`) LIKE :query OR LOWER(`citizenid`) LIKE :query OR LOWER(md.fingerprint) LIKE :query AND jobtype = :jobtype LIMIT 20", { query = string.lower('%'..sentData..'%'), jobtype = JobType })
local citizenIds = {}
local citizenIdIndexMap = {}
if not next(people) then cb({}) return end
for index, data in pairs(people) do
people[index]['warrant'] = false
people[index]['convictions'] = 0
people[index]['licences'] = GetPlayerLicenses(data.citizenid)
people[index]['pp'] = ProfPic(data.gender, data.pfp)
if data.fingerprint and data.fingerprint ~= "" then
people[index]['fingerprint'] = data.fingerprint
else
people[index]['fingerprint'] = ""
end
citizenIds[#citizenIds+1] = data.citizenid
citizenIdIndexMap[data.citizenid] = index
end
local convictions = GetConvictions(citizenIds)
if next(convictions) then
for _, conv in pairs(convictions) do
if conv.warrant == "1" then people[citizenIdIndexMap[conv.cid]].warrant = true end
local charges = json.decode(conv.charges)
people[citizenIdIndexMap[conv.cid]].convictions = people[citizenIdIndexMap[conv.cid]].convictions + #charges
end
end
TriggerClientEvent('mdt:client:searchProfile', src, people, false)
return cb(people)
end
end
return cb({})
end)
QBCore.Functions.CreateCallback("mdt:server:getWarrants", function(source, cb)
local WarrantData = {}
local data = MySQL.query.await("SELECT * FROM mdt_convictions", {})
for _, value in pairs(data) do
if value.warrant == "1" then
WarrantData[#WarrantData+1] = {
cid = value.cid,
linkedincident = value.linkedincident,
name = GetNameFromId(value.cid),
time = value.time
}
end
end
cb(WarrantData)
end)
QBCore.Functions.CreateCallback('mdt:server:OpenDashboard', function(source, cb)
local PlayerData = GetPlayerData(source)
if not PermCheck(source, PlayerData) then return end
local JobType = GetJobType(PlayerData.job.name)
local bulletin = GetBulletins(JobType)
cb(bulletin)
end)
RegisterNetEvent('mdt:server:NewBulletin', function(title, info, time)
local src = source
local PlayerData = GetPlayerData(src)
if not PermCheck(src, PlayerData) then return end
local JobType = GetJobType(PlayerData.job.name)
local playerName = GetNameFromPlayerData(PlayerData)
local newBulletin = MySQL.insert.await('INSERT INTO `mdt_bulletin` (`title`, `desc`, `author`, `time`, `jobtype`) VALUES (:title, :desc, :author, :time, :jt)', {
title = title,
desc = info,
author = playerName,
time = tostring(time),
jt = JobType
})
AddLog(("En ny note blev tilføjet af %s med titlen: %s!"):format(playerName, title))
TriggerClientEvent('mdt:client:newBulletin', -1, src, {id = newBulletin, title = title, info = info, time = time, author = PlayerData.CitizenId}, JobType)
end)
RegisterNetEvent('mdt:server:deleteBulletin', function(id, title)
if not id then return false end
local src = source
local PlayerData = GetPlayerData(src)
if not PermCheck(src, PlayerData) then return end
local JobType = GetJobType(PlayerData.job.name)
MySQL.query.await('DELETE FROM `mdt_bulletin` where id = ?', {id})
AddLog("Note med titel: "..title.." blev slettet af " .. GetNameFromPlayerData(PlayerData) .. ".")
end)
QBCore.Functions.CreateCallback('mdt:server:GetProfileData', function(source, cb, sentId)
if not sentId then return cb({}) end
local src = source
local PlayerData = GetPlayerData(src)
if not PermCheck(src, PlayerData) then return cb({}) end
local JobType = GetJobType(PlayerData.job.name)
local target = GetPlayerDataById(sentId)
local JobName = PlayerData.job.name
if not target or not next(target) then return cb({}) end
if type(target.job) == 'string' then target.job = json.decode(target.job) end
if type(target.charinfo) == 'string' then target.charinfo = json.decode(target.charinfo) end
if type(target.metadata) == 'string' then target.metadata = json.decode(target.metadata) end
local licencesdata = target.metadata['licences'] or {
['driver'] = false,
['business'] = false,
['weapon'] = false,
['pilot'] = false
}
local job, grade = UnpackJob(target.job)
local apartmentData = GetPlayerApartment(target.citizenid)
--property_id, street, region, apartment
if Config.UsingPsHousing and not Config.UsingDefaultQBApartments then
local propertyData = GetPlayerPropertiesByCitizenId(target.citizenid)
if propertyData and next(propertyData) then
if propertyData[1] then
apartmentData = propertyData[1].apartment .. ' #' .. propertyData[1].property_id
else
TriggerClientEvent("QBCore:Notify", src, 'Borgeren har ikke en ejendom.', 'error')
-- print('The citizen does not have a property. Set Config.UsingPsHousing to false.')
end
else
TriggerClientEvent("QBCore:Notify", src, 'Borgeren har ikke en ejendom.', 'error')
-- print('The citizen does not have a property. Set Config.UsingPsHousing to false.')
end
elseif Config.UsingDefaultQBApartments then
apartmentData = GetPlayerApartment(target.citizenid)
if apartmentData then
if apartmentData[1] then
apartmentData = apartmentData[1].street .. ' (' ..apartmentData[1].property_id..')'
else
TriggerClientEvent("QBCore:Notify", src, 'Borgeren har ikke en lejlighed.', 'error')
-- print('Borgeren har ikke en lejlighed. Set Config.UsingDefaultQBApartments to false.')
end
else
TriggerClientEvent("QBCore:Notify", src, 'Borgeren har ikke en lejlighed.', 'error')
-- print('Borgeren har ikke en lejlighed. Set Config.UsingDefaultQBApartments to false.')
end
end
local person = {
cid = target.citizenid,
firstname = target.charinfo.firstname,
lastname = target.charinfo.lastname,
job = job.label,
grade = grade.name,
apartment = apartmentData,
pp = ProfPic(target.charinfo.gender),
licences = licencesdata,
dob = target.charinfo.birthdate,
fingerprint = target.metadata.fingerprint,
phone = target.charinfo.phone,
mdtinfo = '',
tags = {},
vehicles = {},
properties = {},
gallery = {},
isLimited = false
}
if Config.PoliceJobs[JobName] or Config.DojJobs[JobName] then
local convictions = GetConvictions({person.cid})
local incidents = {}
person.convictions2 = {}
local convCount = 1
if next(convictions) then
for _, conv in pairs(convictions) do
if conv.warrant == "1" then person.warrant = true end
-- Get the incident details
local id = conv.linkedincident
local incident = GetIncidentName(id)
if incident then
incidents[#incidents + 1] = {
id = id,
title = incident.title,
time = conv.time
}
end
local charges = json.decode(conv.charges)
for _, charge in pairs(charges) do
person.convictions2[convCount] = charge
convCount = convCount + 1
end
end
end
person.incidents = incidents
local hash = {}
person.convictions = {}
for _,v in ipairs(person.convictions2) do
if (not hash[v]) then
person.convictions[#person.convictions+1] = v
hash[v] = true
end
end
local vehicles = GetPlayerVehicles(person.cid)
if vehicles then
person.vehicles = vehicles
end
local Coords = {}
local Houses = {}
local properties= GetPlayerProperties(person.cid)
for k, v in pairs(properties) do
Coords[#Coords+1] = {
coords = json.decode(v["door_data"]),
}
end
for index = 1, #Coords, 1 do
local x = Coords[index]["coords"]["x"] or 0
local y = Coords[index]["coords"]["y"] or 0
local z = Coords[index]["coords"]["z"] or 0
local label
if properties[index]["street"] then
label = tostring(properties[index]["street"])
else
label = tostring(properties[index]["apartment"])
end
Houses[#Houses+1] = {
label = label .. " " .. tostring(properties[index]["property_id"]),
coords = tostring(x .. "," .. y .. "," .. z),
}
end
person.properties = Houses
end
local mdtData = GetPersonInformation(sentId, JobType)
if mdtData then
person.mdtinfo = mdtData.information
person.profilepic = mdtData.pfp
person.tags = json.decode(mdtData.tags)
person.gallery = json.decode(mdtData.gallery)
person.fingerprint = mdtData.fingerprint
end
return cb(person)
end)
RegisterNetEvent("mdt:server:saveProfile", function(pfp, information, cid, fName, sName, tags, gallery, licenses, fingerprint)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
UpdateAllLicenses(cid, licenses)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'doj' then JobType = 'police' end
MySQL.Async.insert('INSERT INTO mdt_data (cid, information, pfp, jobtype, tags, gallery, fingerprint) VALUES (:cid, :information, :pfp, :jobtype, :tags, :gallery, :fingerprint) ON DUPLICATE KEY UPDATE cid = :cid, information = :information, pfp = :pfp, jobtype = :jobtype, tags = :tags, gallery = :gallery, fingerprint = :fingerprint', {
cid = cid,
information = information,
pfp = pfp,
jobtype = JobType,
tags = json.encode(tags),
gallery = json.encode(gallery),
fingerprint = fingerprint,
}, function()
end)
end
end)
-- Mugshotd
RegisterNetEvent('cqc-mugshot:server:triggerSuspect', function(suspect)
TriggerClientEvent('cqc-mugshot:client:trigger', suspect, suspect)
end)
RegisterNetEvent('psmdt-mugshot:server:MDTupload', function(citizenid, MugShotURLs)
MugShots[citizenid] = MugShotURLs
local cid = citizenid
MySQL.Async.insert('INSERT INTO mdt_data (cid, pfp, gallery, tags) VALUES (:cid, :pfp, :gallery, :tags) ON DUPLICATE KEY UPDATE cid = :cid, pfp = :pfp, tags = :tags, gallery = :gallery', {
cid = cid,
pfp = MugShotURLs[1],
tags = json.encode(tags),
gallery = json.encode(MugShotURLs),
})
end)
RegisterNetEvent("mdt:server:updateLicense", function(cid, type, status)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if GetJobType(Player.PlayerData.job.name) == 'police' then
ManageLicense(cid, type, status)
end
end
end)
-- Incidents
RegisterNetEvent('mdt:server:getAllIncidents', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local matches = MySQL.query.await("SELECT * FROM `mdt_incidents` ORDER BY `id` DESC LIMIT 30", {})
TriggerClientEvent('mdt:client:getAllIncidents', src, matches)
end
end
end)
RegisterNetEvent('mdt:server:searchIncidents', function(query)
if query then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local matches = MySQL.query.await("SELECT * FROM `mdt_incidents` WHERE `id` LIKE :query OR LOWER(`title`) LIKE :query OR LOWER(`author`) LIKE :query OR LOWER(`details`) LIKE :query OR LOWER(`tags`) LIKE :query OR LOWER(`officersinvolved`) LIKE :query OR LOWER(`civsinvolved`) LIKE :query OR LOWER(`author`) LIKE :query ORDER BY `id` DESC LIMIT 50", {
query = string.lower('%'..query..'%') -- % wildcard, needed to search for all alike results
})
TriggerClientEvent('mdt:client:getIncidents', src, matches)
end
end
end
end)
RegisterNetEvent('mdt:server:getIncidentData', function(sentId)
if sentId then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local matches = MySQL.query.await("SELECT * FROM `mdt_incidents` WHERE `id` = :id", {
id = sentId
})
local data = matches[1]
data['tags'] = json.decode(data['tags'])
data['officersinvolved'] = json.decode(data['officersinvolved'])
data['civsinvolved'] = json.decode(data['civsinvolved'])
data['evidence'] = json.decode(data['evidence'])
local convictions = MySQL.query.await("SELECT * FROM `mdt_convictions` WHERE `linkedincident` = :id", {
id = sentId
})
if convictions ~= nil then
for i=1, #convictions do
local res = GetNameFromId(convictions[i]['cid'])
if res ~= nil then
convictions[i]['name'] = res
else
convictions[i]['name'] = "Ukendt"
end
convictions[i]['charges'] = json.decode(convictions[i]['charges'])
end
end
TriggerClientEvent('mdt:client:getIncidentData', src, data, convictions)
end
end
end
end)
RegisterNetEvent('mdt:server:getAllBolos', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
local matches = MySQL.query.await("SELECT * FROM `mdt_bolos` WHERE jobtype = :jobtype", {jobtype = JobType})
TriggerClientEvent('mdt:client:getAllBolos', src, matches)
end
end)
RegisterNetEvent('mdt:server:searchBolos', function(sentSearch)
if sentSearch then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
local matches = MySQL.query.await("SELECT * FROM `mdt_bolos` WHERE `id` LIKE :query OR LOWER(`title`) LIKE :query OR `plate` LIKE :query OR LOWER(`owner`) LIKE :query OR LOWER(`individual`) LIKE :query OR LOWER(`detail`) LIKE :query OR LOWER(`officersinvolved`) LIKE :query OR LOWER(`tags`) LIKE :query OR LOWER(`author`) LIKE :query AND jobtype = :jobtype", {
query = string.lower('%'..sentSearch..'%'), -- % wildcard, needed to search for all alike results
jobtype = JobType
})
TriggerClientEvent('mdt:client:getBolos', src, matches)
end
end
end)
RegisterNetEvent('mdt:server:getBoloData', function(sentId)
if sentId then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
local matches = MySQL.query.await("SELECT * FROM `mdt_bolos` WHERE `id` = :id AND jobtype = :jobtype LIMIT 1", {
id = sentId,
jobtype = JobType
})
local data = matches[1]
data['tags'] = json.decode(data['tags'])
data['officersinvolved'] = json.decode(data['officersinvolved'])
data['gallery'] = json.decode(data['gallery'])
TriggerClientEvent('mdt:client:getBoloData', src, data)
end
end
end)
RegisterNetEvent('mdt:server:newBolo', function(existing, id, title, plate, owner, individual, detail, tags, gallery, officersinvolved, time)
if id then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
local function InsertBolo()
MySQL.insert('INSERT INTO `mdt_bolos` (`title`, `author`, `plate`, `owner`, `individual`, `detail`, `tags`, `gallery`, `officersinvolved`, `time`, `jobtype`) VALUES (:title, :author, :plate, :owner, :individual, :detail, :tags, :gallery, :officersinvolved, :time, :jobtype)', {
title = title,
author = fullname,
plate = plate,
owner = owner,
individual = individual,
detail = detail,
tags = json.encode(tags),
gallery = json.encode(gallery),
officersinvolved = json.encode(officersinvolved),
time = tostring(time),
jobtype = JobType
}, function(r)
if r then
TriggerClientEvent('mdt:client:boloComplete', src, r)
TriggerEvent('mdt:server:AddLog', "En efterlysning blev oprettet på "..fullname.." med titel ("..title..") og ID ("..id..")")
end
end)
end
local function UpdateBolo()
MySQL.update("UPDATE mdt_bolos SET `title`=:title, plate=:plate, owner=:owner, individual=:individual, detail=:detail, tags=:tags, gallery=:gallery, officersinvolved=:officersinvolved WHERE `id`=:id AND jobtype = :jobtype LIMIT 1", {
title = title,
plate = plate,
owner = owner,
individual = individual,
detail = detail,
tags = json.encode(tags),
gallery = json.encode(gallery),
officersinvolved = json.encode(officersinvolved),
id = id,
jobtype = JobType
}, function(r)
if r then
TriggerClientEvent('mdt:client:boloComplete', src, id)
TriggerEvent('mdt:server:AddLog', "En efterlysning blev opdateret på "..fullname.." med titel ("..title..") og ID ("..id..")")
end
end)
end
if existing then
UpdateBolo()
elseif not existing then
InsertBolo()
end
end
end
end)
RegisterNetEvent('mdt:server:deleteWeapons', function(id)
if id then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Config.RemoveWeaponsPerms[Player.PlayerData.job.name] then
if Config.RemoveWeaponsPerms[Player.PlayerData.job.name][Player.PlayerData.job.grade.level] then
local fullName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
MySQL.update("DELETE FROM `mdt_weaponinfo` WHERE id=:id", { id = id })
TriggerEvent('mdt:server:AddLog', "Våbeninformation blev slettet af "..fullName.." med ID ("..id..")")
else
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
TriggerClientEvent("QBCore:Notify", src, 'Du har ikke tilladelse til dette!', 'error')
TriggerEvent('mdt:server:AddLog', fullname.." prøvede at slette våbeninformation med ID ("..id..")")
end
end
end
end)
RegisterNetEvent('mdt:server:deleteReports', function(id)
if id then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Config.RemoveReportPerms[Player.PlayerData.job.name] then
if Config.RemoveReportPerms[Player.PlayerData.job.name][Player.PlayerData.job.grade.level] then
local fullName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
MySQL.update("DELETE FROM `mdt_reports` WHERE id=:id", { id = id })
TriggerEvent('mdt:server:AddLog', "A Report was deleted by "..fullName.." med ID ("..id..")")
else
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
TriggerClientEvent("QBCore:Notify", src, 'Du har ikke tilladelse til dette!', 'error')
TriggerEvent('mdt:server:AddLog', fullname.." prøvede at slette en rapport med ID ("..id..")")
end
end
end
end)
RegisterNetEvent('mdt:server:deleteIncidents', function(id)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Config.RemoveIncidentPerms[Player.PlayerData.job.name] then
if Config.RemoveIncidentPerms[Player.PlayerData.job.name][Player.PlayerData.job.grade.level] then
local fullName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
MySQL.update("DELETE FROM `mdt_convictions` WHERE `linkedincident` = :id", {id = id})
MySQL.update("UPDATE `mdt_convictions` SET `warrant` = '0' WHERE `linkedincident` = :id", {id = id}) -- Delete any outstanding warrants from incidents
MySQL.update("DELETE FROM `mdt_incidents` WHERE id=:id", { id = id }, function(rowsChanged)
if rowsChanged > 0 then
TriggerEvent('mdt:server:AddLog', "En hændelse blev slettet af "..fullName.." med ID ("..id..")")
end
end)
else
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
TriggerClientEvent("QBCore:Notify", src, 'Du har ikke tilladelse til dette!', 'error')
TriggerEvent('mdt:server:AddLog', fullname.." prøvede at slette en hændelse med ID ("..id..")")
end
end
end)
RegisterNetEvent('mdt:server:deleteBolo', function(id)
if id then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' then
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
MySQL.update("DELETE FROM `mdt_bolos` WHERE id=:id", { id = id, jobtype = JobType })
TriggerEvent('mdt:server:AddLog', "En efterlysning blev slette af "..fullname.." med ID ("..id..")")
end
end
end)
RegisterNetEvent('mdt:server:deleteICU', function(id)
if id then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'ambulance' then
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
MySQL.update("DELETE FROM `mdt_bolos` WHERE id=:id", { id = id, jobtype = JobType })
TriggerEvent('mdt:server:AddLog', "Et ICU-checkin blev slettet af "..fullname.." med ID ("..id..")")
end
end
end)
RegisterNetEvent('mdt:server:incidentSearchPerson', function(query)
if query then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' or JobType == 'ambulance' then
local function ProfPic(gender, profilepic)
if profilepic then return profilepic end;
if gender == "f" then return "img/female.png" end;
return "img/male.png"
end
local firstname, lastname = query:match("^(%S+)%s*(%S*)$")
firstname = firstname or query
lastname = lastname or query
local result = MySQL.query.await("SELECT p.citizenid, p.charinfo, p.metadata, md.pfp from players p LEFT JOIN mdt_data md on p.citizenid = md.cid WHERE (LOWER(JSON_UNQUOTE(JSON_EXTRACT(`charinfo`, '$.firstname'))) LIKE :firstname AND LOWER(JSON_UNQUOTE(JSON_EXTRACT(`charinfo`, '$.lastname'))) LIKE :lastname) OR LOWER(`citizenid`) LIKE :citizenid AND `jobtype` = :jobtype LIMIT 30", {
firstname = string.lower('%' .. firstname .. '%'),
lastname = string.lower('%' .. lastname .. '%'),
citizenid = string.lower('%' .. query .. '%'),
jobtype = JobType
})
local data = {}
for i=1, #result do
local charinfo = json.decode(result[i].charinfo)
local metadata = json.decode(result[i].metadata)
data[i] = {
id = result[i].citizenid,
firstname = charinfo.firstname,
lastname = charinfo.lastname,
profilepic = ProfPic(charinfo.gender, result[i].pfp),
callsign = metadata.callsign
}
end
TriggerClientEvent('mdt:client:incidentSearchPerson', src, data)
end
end
end
end)
RegisterNetEvent('mdt:server:getAllReports', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' or JobType == 'ambulance' then
if JobType == 'doj' then JobType = 'police' end
local matches = MySQL.query.await("SELECT * FROM `mdt_reports` WHERE jobtype = :jobtype ORDER BY `id` DESC LIMIT 30", {
jobtype = JobType
})
TriggerClientEvent('mdt:client:getAllReports', src, matches)
end
end
end)
RegisterNetEvent('mdt:server:getReportData', function(sentId)
if sentId then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' or JobType == 'ambulance' then
if JobType == 'doj' then JobType = 'police' end
local matches = MySQL.query.await("SELECT * FROM `mdt_reports` WHERE `id` = :id AND `jobtype` = :jobtype LIMIT 1", {
id = sentId,
jobtype = JobType
})
local data = matches[1]
data['tags'] = json.decode(data['tags'])
data['officersinvolved'] = json.decode(data['officersinvolved'])
data['civsinvolved'] = json.decode(data['civsinvolved'])
data['gallery'] = json.decode(data['gallery'])
TriggerClientEvent('mdt:client:getReportData', src, data)
end
end
end
end)
RegisterNetEvent('mdt:server:searchReports', function(sentSearch)
if sentSearch then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' or JobType == 'ambulance' then
if JobType == 'doj' then JobType = 'police' end
local matches = MySQL.query.await("SELECT * FROM `mdt_reports` WHERE `id` LIKE :query OR LOWER(`author`) LIKE :query OR LOWER(`title`) LIKE :query OR LOWER(`type`) LIKE :query OR LOWER(`details`) LIKE :query OR LOWER(`tags`) LIKE :query AND `jobtype` = :jobtype ORDER BY `id` DESC LIMIT 50", {
query = string.lower('%'..sentSearch..'%'), -- % wildcard, needed to search for all alike results
jobtype = JobType
})
TriggerClientEvent('mdt:client:getAllReports', src, matches)
end
end
end
end)
RegisterNetEvent('mdt:server:newReport', function(existing, id, title, reporttype, details, tags, gallery, officers, civilians, time)
if id then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType ~= nil then
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
local function InsertReport()
MySQL.insert('INSERT INTO `mdt_reports` (`title`, `author`, `type`, `details`, `tags`, `gallery`, `officersinvolved`, `civsinvolved`, `time`, `jobtype`) VALUES (:title, :author, :type, :details, :tags, :gallery, :officersinvolved, :civsinvolved, :time, :jobtype)', {
title = title,
author = fullname,
type = reporttype,
details = details,
tags = json.encode(tags),
gallery = json.encode(gallery),
officersinvolved = json.encode(officers),
civsinvolved = json.encode(civilians),
time = tostring(time),
jobtype = JobType,
}, function(r)
if r then
TriggerClientEvent('mdt:client:reportComplete', src, r)
TriggerEvent('mdt:server:AddLog', "En ny rapport blevet skrevet af "..fullname.." med titel ("..title..") og ID ("..id..")")
end
end)
end
local function UpdateReport()
MySQL.update("UPDATE `mdt_reports` SET `title` = :title, type = :type, details = :details, tags = :tags, gallery = :gallery, officersinvolved = :officersinvolved, civsinvolved = :civsinvolved, jobtype = :jobtype WHERE `id` = :id LIMIT 1", {
title = title,
type = reporttype,
details = details,
tags = json.encode(tags),
gallery = json.encode(gallery),
officersinvolved = json.encode(officers),
civsinvolved = json.encode(civilians),
jobtype = JobType,
id = id,
}, function(affectedRows)
if affectedRows > 0 then
TriggerClientEvent('mdt:client:reportComplete', src, id)
TriggerEvent('mdt:server:AddLog', "En rapport blev opdateret af "..fullname.." med titel ("..title..") og ID ("..id..")")
end
end)
end
if existing then
UpdateReport()
elseif not existing then
InsertReport()
end
end
end
end
end)
QBCore.Functions.CreateCallback('mdt:server:SearchVehicles', function(source, cb, sentData)
if not sentData then return cb({}) end
local src = source
local PlayerData = GetPlayerData(src)
if not PermCheck(source, PlayerData) then return cb({}) end
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local vehicles = MySQL.query.await("SELECT pv.id, pv.citizenid, pv.plate, pv.vehicle, pv.mods, pv.state, p.charinfo FROM `player_vehicles` pv LEFT JOIN players p ON pv.citizenid = p.citizenid WHERE LOWER(`plate`) LIKE :query OR LOWER(`vehicle`) LIKE :query LIMIT 25", {
query = string.lower('%'..sentData..'%')
})
if not next(vehicles) then cb({}) return end
for _, value in ipairs(vehicles) do
if value.state == 0 then
value.state = "Ude"
elseif value.state == 1 then
value.state = "Parkeret"
elseif value.state == 2 then
value.state = "Beslaglagt"
end
value.bolo = false
local boloResult = GetBoloStatus(value.plate)
if boloResult then
value.bolo = true
end
value.code = false
value.stolen = false
value.image = "img/not-found.webp"
local info = GetVehicleInformation(value.plate)
if info then
value.code = info['code5']
value.stolen = info['stolen']
value.image = info['image']
end
local ownerResult = json.decode(value.charinfo)
value.owner = ownerResult['firstname'] .. " " .. ownerResult['lastname']
end
return cb(vehicles)
end
return cb({})
end
end)
RegisterNetEvent('mdt:server:getVehicleData', function(plate)
if plate then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local vehicle = MySQL.query.await("select pv.*, p.charinfo from player_vehicles pv LEFT JOIN players p ON pv.citizenid = p.citizenid where pv.plate = :plate LIMIT 1", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1")})
if vehicle and vehicle[1] then
vehicle[1]['impound'] = false
if vehicle[1].state == 2 then
vehicle[1]['impound'] = true
end
vehicle[1]['bolo'] = GetBoloStatus(vehicle[1]['plate'])
vehicle[1]['information'] = ""
vehicle[1]['name'] = "Ukendt person"
local ownerResult = json.decode(vehicle[1].charinfo)
vehicle[1]['name'] = ownerResult['firstname'] .. " " .. ownerResult['lastname']
local color1 = json.decode(vehicle[1].mods)
vehicle[1]['color1'] = color1['color1']
vehicle[1]['dbid'] = 0
local info = GetVehicleInformation(vehicle[1]['plate'])
if info then
vehicle[1]['information'] = info['information']
vehicle[1]['dbid'] = info['id']
vehicle[1]['points'] = info['points']
vehicle[1]['image'] = info['image']
vehicle[1]['code'] = info['code5']
vehicle[1]['stolen'] = info['stolen']
end
if vehicle[1]['image'] == nil then vehicle[1]['image'] = "img/not-found.webp" end
end
TriggerClientEvent('mdt:client:getVehicleData', src, vehicle)
end
end
end
end)
RegisterNetEvent('mdt:server:saveVehicleInfo', function(dbid, plate, imageurl, notes, stolen, code5, impoundInfo, points)
if plate then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if GetJobType(Player.PlayerData.job.name) == 'police' then
if dbid == nil then dbid = 0 end;
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
TriggerEvent('mdt:server:AddLog', "Køretøjet med nummerpladen ("..plate..") fik et nyt billede ("..imageurl.."), opdateret af "..fullname)
if tonumber(dbid) == 0 then
MySQL.insert('INSERT INTO `mdt_vehicleinfo` (`plate`, `information`, `image`, `code5`, `stolen`, `points`) VALUES (:plate, :information, :image, :code5, :stolen, :points)', { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1"), information = notes, image = imageurl, code5 = code5, stolen = stolen, points = tonumber(points) }, function(infoResult)
if infoResult then
TriggerClientEvent('mdt:client:updateVehicleDbId', src, infoResult)
TriggerEvent('mdt:server:AddLog', "Køretøjet med nummerpladen ("..plate..") blev tilføjet til databasen af "..fullname)
end
end)
elseif tonumber(dbid) > 0 then
MySQL.update("UPDATE mdt_vehicleinfo SET `information`= :information, `image`= :image, `code5`= :code5, `stolen`= :stolen, `points`= :points WHERE `plate`= :plate LIMIT 1", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1"), information = notes, image = imageurl, code5 = code5, stolen = stolen, points = tonumber(points) })
end
if impoundInfo.impoundChanged then
local vehicle = MySQL.single.await("SELECT p.id, p.plate, i.vehicleid AS impoundid FROM `player_vehicles` p LEFT JOIN `mdt_impound` i ON i.vehicleid = p.id WHERE plate=:plate", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1") })
if impoundInfo.impoundActive then
local plate, linkedreport, fee, time = impoundInfo['plate'], impoundInfo['linkedreport'], impoundInfo['fee'], impoundInfo['time']
if (plate and linkedreport and fee and time) then
if vehicle.impoundid == nil then
-- This section is copy pasted from request impound and needs some attention.
-- sentVehicle doesnt exist.
-- data is defined twice
-- INSERT INTO will not work if it exists already (which it will)
local data = vehicle
MySQL.insert('INSERT INTO `mdt_impound` (`vehicleid`, `linkedreport`, `fee`, `time`) VALUES (:vehicleid, :linkedreport, :fee, :time)', {
vehicleid = data['id'],
linkedreport = linkedreport,
fee = fee,
time = os.time() + (time * 60)
}, function(res)
local data = {
vehicleid = data['id'],
plate = plate,
beingcollected = 0,
vehicle = sentVehicle,
officer = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
number = Player.PlayerData.charinfo.phone,
time = os.time() * 1000,
src = src,
}
local vehicle = NetworkGetEntityFromNetworkId(sentVehicle)
FreezeEntityPosition(vehicle, true)
impound[#impound+1] = data
TriggerClientEvent("police:client:ImpoundVehicle", src, true, fee)
end)
-- Read above comment
end
end
else
if vehicle.impoundid ~= nil then
local data = vehicle
local result = MySQL.single.await("SELECT id, vehicle, fuel, engine, body FROM `player_vehicles` WHERE plate=:plate LIMIT 1", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1")})
if result then
local data = result
MySQL.update("DELETE FROM `mdt_impound` WHERE vehicleid=:vehicleid", { vehicleid = data['id'] })
result.currentSelection = impoundInfo.CurrentSelection
result.plate = plate
TriggerClientEvent('ps-mdt:client:TakeOutImpound', src, result)
end
end
end
end
end
end
end
end)
RegisterNetEvent('mdt:server:searchCalls', function(calls)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' then
local calls = exports['ps-dispatch']:GetDispatchCalls()
TriggerClientEvent('mdt:client:getCalls', src, calls)
end
end)
QBCore.Functions.CreateCallback('mdt:server:SearchWeapons', function(source, cb, sentData)
if not sentData then return cb({}) end
local PlayerData = GetPlayerData(source)
if not PermCheck(source, PlayerData) then return cb({}) end
local Player = QBCore.Functions.GetPlayer(source)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local matches = MySQL.query.await('SELECT * FROM mdt_weaponinfo WHERE LOWER(`serial`) LIKE :query OR LOWER(`weapModel`) LIKE :query OR LOWER(`owner`) LIKE :query LIMIT 25', {
query = string.lower('%'..sentData..'%')
})
cb(matches)
end
end
end)
RegisterNetEvent('mdt:server:saveWeaponInfo', function(serial, imageurl, notes, owner, weapClass, weapModel)
if serial then
local PlayerData = GetPlayerData(source)
if not PermCheck(source, PlayerData) then return cb({}) end
local Player = QBCore.Functions.GetPlayer(source)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
if imageurl == nil then imageurl = 'img/not-found.webp' end
--AddLog event?
local result = false
result = MySQL.Async.insert('INSERT INTO mdt_weaponinfo (serial, owner, information, weapClass, weapModel, image) VALUES (:serial, :owner, :notes, :weapClass, :weapModel, :imageurl) ON DUPLICATE KEY UPDATE owner = :owner, information = :notes, weapClass = :weapClass, weapModel = :weapModel, image = :imageurl', {
['serial'] = serial,
['owner'] = owner,
['notes'] = notes,
['weapClass'] = weapClass,
['weapModel'] = weapModel,
['imageurl'] = imageurl,
})
if result then
TriggerEvent('mdt:server:AddLog', "Våben med serienummer ("..serial..") blev tilføjet til databasen af "..fullname)
else
TriggerEvent('mdt:server:AddLog', "Våben med serienummer ("..serial..") blev forsøgt tilføjet af "..fullname.." men der opstod en fejl")
end
end
end
end
end)
function CreateWeaponInfo(serial, imageurl, notes, owner, weapClass, weapModel)
local results = MySQL.query.await('SELECT * FROM mdt_weaponinfo WHERE serial = ?', { serial })
if results[1] then
return
end
if serial == nil then return end
if imageurl == nil then imageurl = 'img/not-found.webp' end
MySQL.Async.insert('INSERT INTO mdt_weaponinfo (serial, owner, information, weapClass, weapModel, image) VALUES (:serial, :owner, :notes, :weapClass, :weapModel, :imageurl) ON DUPLICATE KEY UPDATE owner = :owner, information = :notes, weapClass = :weapClass, weapModel = :weapModel, image = :imageurl', {
['serial'] = serial,
['owner'] = owner,
['notes'] = notes,
['weapClass'] = weapClass,
['weapModel'] = weapModel,
['imageurl'] = imageurl,
})
end
exports('CreateWeaponInfo', CreateWeaponInfo)
RegisterNetEvent('mdt:server:getWeaponData', function(serial)
if serial then
local Player = QBCore.Functions.GetPlayer(source)
if Player then
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'doj' then
local results = MySQL.query.await('SELECT * FROM mdt_weaponinfo WHERE serial = ?', { serial })
TriggerClientEvent('mdt:client:getWeaponData', Player.PlayerData.source, results)
end
end
end
end)
RegisterNetEvent('mdt:server:getAllLogs', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if Config.LogPerms[Player.PlayerData.job.name] then
if Config.LogPerms[Player.PlayerData.job.name][Player.PlayerData.job.grade.level] then
local JobType = GetJobType(Player.PlayerData.job.name)
local infoResult = MySQL.query.await('SELECT * FROM mdt_logs WHERE `jobtype` = :jobtype ORDER BY `id` DESC LIMIT 250', {jobtype = JobType})
TriggerLatentClientEvent('mdt:client:getAllLogs', src, 30000, infoResult)
end
end
end
end)
-- Penal Code
local function IsCidFelon(sentCid, cb)
if sentCid then
local convictions = MySQL.query.await('SELECT charges FROM mdt_convictions WHERE cid=:cid', { cid = sentCid })
local Charges = {}
for i=1, #convictions do
local currCharges = json.decode(convictions[i]['charges'])
for x=1, #currCharges do
Charges[#Charges+1] = currCharges[x]
end
end
local PenalCode = Config.PenalCode
for i=1, #Charges do
for p=1, #PenalCode do
for x=1, #PenalCode[p] do
if PenalCode[p][x]['title'] == Charges[i] then
if PenalCode[p][x]['class'] == 'Felony' then
cb(true)
return
end
break
end
end
end
end
cb(false)
end
end
exports('IsCidFelon', IsCidFelon) -- exports['erp_mdt']:IsCidFelon()
RegisterCommand("isfelon", function(source, args, rawCommand)
IsCidFelon(1998, function(res)
end)
end, false)
RegisterNetEvent('mdt:server:getPenalCode', function()
local src = source
TriggerClientEvent('mdt:client:getPenalCode', src, Config.PenalCodeTitles, Config.PenalCode)
end)
RegisterNetEvent('mdt:server:setCallsign', function(cid, newcallsign)
local Player = QBCore.Functions.GetPlayerByCitizenId(cid)
Player.Functions.SetMetaData("callsign", newcallsign)
end)
RegisterNetEvent('mdt:server:saveIncident', function(id, title, information, tags, officers, civilians, evidence, associated, time)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if GetJobType(Player.PlayerData.job.name) == 'police' then
if id == 0 then
local fullname = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
MySQL.insert('INSERT INTO `mdt_incidents` (`author`, `title`, `details`, `tags`, `officersinvolved`, `civsinvolved`, `evidence`, `time`, `jobtype`) VALUES (:author, :title, :details, :tags, :officersinvolved, :civsinvolved, :evidence, :time, :jobtype)',
{
author = fullname,
title = title,
details = information,
tags = json.encode(tags),
officersinvolved = json.encode(officers),
civsinvolved = json.encode(civilians),
evidence = json.encode(evidence),
time = time,
jobtype = 'police',
}, function(infoResult)
if infoResult then
for i=1, #associated do
MySQL.insert('INSERT INTO `mdt_convictions` (`cid`, `linkedincident`, `warrant`, `guilty`, `processed`, `associated`, `charges`, `fine`, `sentence`, `recfine`, `recsentence`, `time`) VALUES (:cid, :linkedincident, :warrant, :guilty, :processed, :associated, :charges, :fine, :sentence, :recfine, :recsentence, :time)', {
cid = associated[i]['Cid'],
linkedincident = infoResult,
warrant = associated[i]['Warrant'],
guilty = associated[i]['Guilty'],
processed = associated[i]['Processed'],
associated = associated[i]['Isassociated'],
charges = json.encode(associated[i]['Charges']),
fine = tonumber(associated[i]['Fine']),
sentence = tonumber(associated[i]['Sentence']),
recfine = tonumber(associated[i]['recfine']),
recsentence = tonumber(associated[i]['recsentence']),
time = time
})
end
TriggerClientEvent('mdt:client:updateIncidentDbId', src, infoResult)
--TriggerEvent('mdt:server:AddLog', "Køretøjet med nummerpladen ("..plate..") was added to the vehicle information database by "..player['fullname'])
end
end)
elseif id > 0 then
MySQL.update("UPDATE mdt_incidents SET title=:title, details=:details, civsinvolved=:civsinvolved, tags=:tags, officersinvolved=:officersinvolved, evidence=:evidence WHERE id=:id", {
title = title,
details = information,
tags = json.encode(tags),
officersinvolved = json.encode(officers),
civsinvolved = json.encode(civilians),
evidence = json.encode(evidence),
id = id
})
for i=1, #associated do
TriggerEvent('mdt:server:handleExistingConvictions', associated[i], id, time)
end
end
end
end
end)
RegisterNetEvent('mdt:server:handleExistingConvictions', function(data, incidentId, time)
MySQL.query('SELECT * FROM mdt_convictions WHERE cid=:cid AND linkedincident=:linkedincident', {
cid = data['Cid'],
linkedincident = incidentId
}, function(convictionRes)
if convictionRes and convictionRes[1] and convictionRes[1]['id'] then
MySQL.update('UPDATE mdt_convictions SET cid=:cid, linkedincident=:linkedincident, warrant=:warrant, guilty=:guilty, processed=:processed, associated=:associated, charges=:charges, fine=:fine, sentence=:sentence, recfine=:recfine, recsentence=:recsentence WHERE cid=:cid AND linkedincident=:linkedincident', {
cid = data['Cid'],
linkedincident = incidentId,
warrant = data['Warrant'],
guilty = data['Guilty'],
processed = data['Processed'],
associated = data['Isassociated'],
charges = json.encode(data['Charges']),
fine = tonumber(data['Fine']),
sentence = tonumber(data['Sentence']),
recfine = tonumber(data['recfine']),
recsentence = tonumber(data['recsentence']),
})
else
MySQL.insert('INSERT INTO `mdt_convictions` (`cid`, `linkedincident`, `warrant`, `guilty`, `processed`, `associated`, `charges`, `fine`, `sentence`, `recfine`, `recsentence`, `time`) VALUES (:cid, :linkedincident, :warrant, :guilty, :processed, :associated, :charges, :fine, :sentence, :recfine, :recsentence, :time)', {
cid = data['Cid'],
linkedincident = incidentId,
warrant = data['Warrant'],
guilty = data['Guilty'],
processed = data['Processed'],
associated = data['Isassociated'],
charges = json.encode(data['Charges']),
fine = tonumber(data['Fine']),
sentence = tonumber(data['Sentence']),
recfine = tonumber(data['recfine']),
recsentence = tonumber(data['recsentence']),
time = time
})
end
end)
end)
RegisterNetEvent('mdt:server:removeIncidentCriminal', function(cid, incident)
MySQL.update('DELETE FROM mdt_convictions WHERE cid=:cid AND linkedincident=:linkedincident', {
cid = cid,
linkedincident = incident
})
end)
-- Dispatch
RegisterNetEvent('mdt:server:setWaypoint', function(callid)
local src = source
local Player = QBCore.Functions.GetPlayer(source)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
if isDispatchRunning then
local calls = exports['ps-dispatch']:GetDispatchCalls()
TriggerClientEvent('mdt:client:setWaypoint', src, calls[callid])
end
end
end
end)
RegisterNetEvent('mdt:server:callDetach', function(callid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local playerdata = {
fullname = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
job = Player.PlayerData.job,
cid = Player.PlayerData.citizenid,
callsign = Player.PlayerData.metadata.callsign
}
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
TriggerEvent('dispatch:removeUnit', callid, playerdata, function(newNum)
TriggerClientEvent('mdt:client:callDetach', -1, callid, newNum)
end)
end
end
end)
RegisterNetEvent('mdt:server:callAttach', function(callid)
local src = source
local plyState = Player(source).state
local Radio = plyState.radioChannel or 0
local Player = QBCore.Functions.GetPlayer(src)
local playerdata = {
fullname = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
job = Player.PlayerData.job,
cid = Player.PlayerData.citizenid,
callsign = Player.PlayerData.metadata.callsign,
radio = Radio
}
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
TriggerEvent('dispatch:addUnit', callid, playerdata, function(newNum)
TriggerClientEvent('mdt:client:callAttach', -1, callid, newNum)
end)
end
end
end)
RegisterNetEvent('mdt:server:attachedUnits', function(callid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
if isDispatchRunning then
local calls = exports['ps-dispatch']:GetDispatchCalls()
TriggerClientEvent('mdt:client:attachedUnits', src, calls[callid]['units'], callid)
end
end
end
end)
RegisterNetEvent('mdt:server:callDispatchDetach', function(callid, cid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local playerdata = {
fullname = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
job = Player.PlayerData.job,
cid = Player.PlayerData.citizenid,
callsign = Player.PlayerData.metadata.callsign
}
local callid = tonumber(callid)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
TriggerEvent('dispatch:removeUnit', callid, playerdata, function(newNum)
TriggerClientEvent('mdt:client:callDetach', -1, callid, newNum)
end)
end
end
end)
RegisterNetEvent('mdt:server:setDispatchWaypoint', function(callid, cid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local callid = tonumber(callid)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
if isDispatchRunning then
local calls = exports['ps-dispatch']:GetDispatchCalls()
TriggerClientEvent('mdt:client:setWaypoint', src, calls[callid])
end
end
end
end)
RegisterNetEvent('mdt:server:callDragAttach', function(callid, cid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local playerdata = {
name = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
job = Player.PlayerData.job.name,
cid = Player.PlayerData.citizenid,
callsign = Player.PlayerData.metadata.callsign
}
local callid = tonumber(callid)
local JobType = GetJobType(Player.PlayerData.job.name)
if JobType == 'police' or JobType == 'ambulance' then
if callid then
TriggerEvent('dispatch:addUnit', callid, playerdata, function(newNum)
TriggerClientEvent('mdt:client:callAttach', -1, callid, newNum)
end)
end
end
end)
RegisterNetEvent('mdt:server:setWaypoint:unit', function(cid)
local src = source
local Player = QBCore.Functions.GetPlayerByCitizenId(cid)
local PlayerCoords = GetEntityCoords(GetPlayerPed(Player.PlayerData.source))
TriggerClientEvent("mdt:client:setWaypoint:unit", src, PlayerCoords)
end)
-- Dispatch chat
RegisterNetEvent('mdt:server:sendMessage', function(message, time)
if message and time then
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
MySQL.scalar("SELECT pfp FROM `mdt_data` WHERE cid=:id LIMIT 1", {
id = Player.PlayerData.citizenid -- % wildcard, needed to search for all alike results
}, function(data)
if data == "" then data = nil end
local ProfilePicture = ProfPic(Player.PlayerData.charinfo.gender, data)
local callsign = Player.PlayerData.metadata.callsign or "000"
local Item = {
profilepic = ProfilePicture,
callsign = Player.PlayerData.metadata.callsign,
cid = Player.PlayerData.citizenid,
name = '('..callsign..') '..Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
message = message,
time = time,
job = Player.PlayerData.job.name
}
dispatchMessages[#dispatchMessages+1] = Item
TriggerClientEvent('mdt:client:dashboardMessage', -1, Item)
end)
end
end
end)
RegisterNetEvent('mdt:server:refreshDispatchMsgs', function()
local src = source
local PlayerData = GetPlayerData(src)
if IsJobAllowedToMDT(PlayerData.job.name) then
TriggerClientEvent('mdt:client:dashboardMessages', src, dispatchMessages)
end
end)
RegisterNetEvent('mdt:server:getCallResponses', function(callid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if IsPoliceOrEms(Player.PlayerData.job.name) then
if isDispatchRunning then
local calls = exports['ps-dispatch']:GetDispatchCalls()
TriggerClientEvent('mdt:client:getCallResponses', src, calls[callid]['responses'], callid)
end
end
end)
RegisterNetEvent('mdt:server:sendCallResponse', function(message, time, callid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local name = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname
if IsPoliceOrEms(Player.PlayerData.job.name) then
TriggerEvent('dispatch:sendCallResponse', src, callid, message, time, function(isGood)
if isGood then
TriggerClientEvent('mdt:client:sendCallResponse', -1, message, time, callid, name)
end
end)
end
end)
RegisterNetEvent('mdt:server:setRadio', function(cid, newRadio)
local src = source
local targetPlayer = QBCore.Functions.GetPlayerByCitizenId(cid)
local targetSource = targetPlayer.PlayerData.source
local targetName = targetPlayer.PlayerData.charinfo.firstname .. ' ' .. targetPlayer.PlayerData.charinfo.lastname
local radio = targetPlayer.Functions.GetItemByName("radio")
if radio ~= nil then
TriggerClientEvent('mdt:client:setRadio', targetSource, newRadio)
else
TriggerClientEvent("QBCore:Notify", src, targetName..' har ikke en radio!', 'error')
end
end)
local function isRequestVehicle(vehId)
local found = false
for i=1, #impound do
if impound[i]['vehicle'] == vehId then
found = true
impound[i] = nil
break
end
end
return found
end
exports('isRequestVehicle', isRequestVehicle)
RegisterNetEvent('mdt:server:impoundVehicle', function(sentInfo, sentVehicle)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if GetJobType(Player.PlayerData.job.name) == 'police' then
if sentInfo and type(sentInfo) == 'table' then
local plate, linkedreport, fee, time = sentInfo['plate'], sentInfo['linkedreport'], sentInfo['fee'], sentInfo['time']
if (plate and linkedreport and fee and time) then
local vehicle = MySQL.query.await("SELECT id, plate FROM `player_vehicles` WHERE plate=:plate LIMIT 1", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1") })
if vehicle and vehicle[1] then
local data = vehicle[1]
MySQL.insert('INSERT INTO `mdt_impound` (`vehicleid`, `linkedreport`, `fee`, `time`) VALUES (:vehicleid, :linkedreport, :fee, :time)', {
vehicleid = data['id'],
linkedreport = linkedreport,
fee = fee,
time = os.time() + (time * 60)
}, function(res)
local data = {
vehicleid = data['id'],
plate = plate,
beingcollected = 0,
vehicle = sentVehicle,
officer = Player.PlayerData.charinfo.firstname.. " "..Player.PlayerData.charinfo.lastname,
number = Player.PlayerData.charinfo.phone,
time = os.time() * 1000,
src = src,
}
local vehicle = NetworkGetEntityFromNetworkId(sentVehicle)
FreezeEntityPosition(vehicle, true)
impound[#impound+1] = data
TriggerClientEvent("police:client:ImpoundVehicle", src, true, fee)
end)
end
end
end
end
end
end)
RegisterNetEvent('mdt:server:getImpoundVehicles', function()
TriggerClientEvent('mdt:client:getImpoundVehicles', source, impound)
end)
RegisterNetEvent('mdt:server:removeImpound', function(plate, currentSelection)
-- print("Removing impound", plate, currentSelection)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if GetJobType(Player.PlayerData.job.name) == 'police' then
local result = MySQL.single.await("SELECT id, vehicle FROM `player_vehicles` WHERE plate=:plate LIMIT 1", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1")})
if result and result[1] then
local data = result[1]
MySQL.update("DELETE FROM `mdt_impound` WHERE vehicleid=:vehicleid", { vehicleid = data['id'] })
TriggerClientEvent('police:client:TakeOutImpound', src, currentSelection)
end
end
end
end)
RegisterNetEvent('mdt:server:statusImpound', function(plate)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player then
if GetJobType(Player.PlayerData.job.name) == 'police' then
local vehicle = MySQL.query.await("SELECT id, plate FROM `player_vehicles` WHERE plate=:plate LIMIT 1", { plate = string.gsub(plate, "^%s*(.-)%s*$", "%1")})
if vehicle and vehicle[1] then
local data = vehicle[1]
local impoundinfo = MySQL.query.await("SELECT * FROM `mdt_impound` WHERE vehicleid=:vehicleid LIMIT 1", { vehicleid = data['id'] })
if impoundinfo and impoundinfo[1] then
TriggerClientEvent('mdt:client:statusImpound', src, impoundinfo[1], plate)
end
end
end
end
end)
RegisterServerEvent("mdt:server:AddLog", function(text)
AddLog(text)
end)
function GetBoloStatus(plate)
local result = MySQL.query.await("SELECT * FROM mdt_bolos where plate = @plate", {['@plate'] = plate})
if result and result[1] then
local title = result[1]['title']
local boloId = result[1]['id']
return true, title, boloId
end
return false
end
function GetWarrantStatus(plate)
local result = MySQL.query.await("SELECT p.plate, p.citizenid, m.id FROM player_vehicles p INNER JOIN mdt_convictions m ON p.citizenid = m.cid WHERE m.warrant =1 AND p.plate =?", {plate})
if result and result[1] then
local citizenid = result[1]['citizenid']
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)
local owner = Player.PlayerData.charinfo.firstname.." "..Player.PlayerData.charinfo.lastname
local incidentId = result[1]['id']
return true, owner, incidentId
end
return false
end
function GetVehicleInformation(plate)
local result = MySQL.query.await('SELECT * FROM mdt_vehicleinfo WHERE plate = @plate', {['@plate'] = plate})
if result[1] then
return result[1]
else
return false
end
end
function GetVehicleOwner(plate)
local result = MySQL.query.await('SELECT plate, citizenid, id FROM player_vehicles WHERE plate = @plate', {['@plate'] = plate})
if result and result[1] then
local citizenid = result[1]['citizenid']
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)
local owner = Player.PlayerData.charinfo.firstname.." "..Player.PlayerData.charinfo.lastname
return owner
end
end
-- Returns the source for the given citizenId
QBCore.Functions.CreateCallback('mdt:server:GetPlayerSourceId', function(source, cb, targetCitizenId)
local targetPlayer = QBCore.Functions.GetPlayerByCitizenId(targetCitizenId)
if targetPlayer == nil then
TriggerClientEvent('QBCore:Notify', source, "Borgeren sover eller er forsvundet", "error")
return
end
local targetSource = targetPlayer.PlayerData.source
cb(targetSource)
end)
QBCore.Functions.CreateCallback('getWeaponInfo', function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
local weaponInfos = {}
if Config.InventoryForWeaponsImages == "ox_inventory" then
local inv = exports.ox_inventory:GetInventoryItems(source)
for _, item in pairs(inv) do
if string.find(item.name, "WEAPON_") then
local invImage = ("https://cfx-nui-ox_inventory/web/images/%s.png"):format(item.name)
if invImage then
weaponInfo = {
serialnumber = item.metadata.serial,
owner = Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname,
weaponmodel = QBCore.Shared.Items[string.lower(item.name)].label,
weaponurl = invImage,
notes = "Selvregistreret",
weapClass = "Klasse 1",
}
break
end
end
end
else -- qb/lj
for _, item in pairs(Player.PlayerData.items) do
if item.type == "weapon" then
local invImage = ("https://cfx-nui-%s/html/images/%s"):format(Config.InventoryForWeaponsImages, item.image)
if invImage then
local weaponInfo = {
serialnumber = item.info.serie,
owner = Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname,
weaponmodel = QBCore.Shared.Items[item.name].label,
weaponurl = invImage,
notes = "Selvregistreret",
weapClass = "Klasse 1",
}
table.insert(weaponInfos, weaponInfo)
end
end
end
end
cb(weaponInfos)
end)
RegisterNetEvent('mdt:server:registerweapon', function(serial, imageurl, notes, owner, weapClass, weapModel)
exports['ps-mdt']:CreateWeaponInfo(serial, imageurl, notes, owner, weapClass, weapModel)
end)
local function giveCitationItem(src, citizenId, fine, incidentId)
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenId)
local PlayerName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
local Officer = QBCore.Functions.GetPlayer(src)
local OfficerFullName = '(' .. Officer.PlayerData.metadata.callsign .. ') ' .. Officer.PlayerData.charinfo.firstname .. ' ' .. Officer.PlayerData.charinfo.lastname
local date = os.date("%Y-%m-%d %H:%M")
local info = {
citizenId = citizenId,
fine = "$"..fine,
date = date,
incidentId = "#"..incidentId,
officer = OfficerFullName,
}
Player.Functions.AddItem('mdtcitation', 1, false, info)
TriggerClientEvent('QBCore:Notify', src, PlayerName.." (" ..citizenId.. ") modtog en bøde!")
if Config.QBManagementUse then
exports['qb-management']:AddMoney(Officer.PlayerData.job.name, fine)
end
TriggerClientEvent('inventory:client:ItemBox', Player.PlayerData.source, QBCore.Shared.Items['mdtcitation'], "add")
TriggerEvent('mdt:server:AddLog', "En bøde blev udskrevet af "..OfficerFullName.." og sendt til "..PlayerName..". Bøden lyder på ".. fine ..",-. (ID: "..incidentId.. ")")
end
-- Removes money from the players bank and gives them a citation item
RegisterNetEvent('mdt:server:removeMoney', function(citizenId, fine, incidentId)
local src = source
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenId)
if not antiSpam then
if Player.Functions.RemoveMoney('bank', fine, 'Bøde: '..fine..",-") then
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, fine..",- blev fjernet fra din bank-konto!")
giveCitationItem(src, citizenId, fine, incidentId)
else
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, "Der gik noget galt.")
end
antiSpam = true
SetTimeout(60000, function()
antiSpam = false
end)
else
TriggerClientEvent('QBCore:Notify', src, "Vent før du udskriver en ny bøde!")
end
end)
-- Gives the player a citation item
RegisterNetEvent('mdt:server:giveCitationItem', function(citizenId, fine, incidentId)
local src = source
giveCitationItem(src, citizenId, fine, incidentId)
end)