1937 lines
74 KiB
Lua
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)
|