diff --git a/client/main.lua b/client/main.lua index ee53b12e..c138c878 100644 --- a/client/main.lua +++ b/client/main.lua @@ -288,8 +288,8 @@ RegisterNUICallback("searchProfiles", function(data, cb) end) -RegisterNetEvent('mdt:client:searchProfile', function(sentData, isLimited) - SendNUIMessage({ type = "profiles", data = sentData, isLimited = isLimited }) +RegisterNetEvent('mdt:client:searchProfile', function(sentData, isLimited, fingerprint) + SendNUIMessage({ action = "updateFingerprintData", fingerprint = fingerprint }) end) RegisterNUICallback("saveProfile", function(data, cb) @@ -301,8 +301,8 @@ RegisterNUICallback("saveProfile", function(data, cb) local tags = data.tags local gallery = data.gallery local licenses = data.licenses - - TriggerServerEvent("mdt:server:saveProfile", profilepic, information, cid, fName, sName, tags, gallery, licenses) + local fingerprint = data.fingerprint + TriggerServerEvent("mdt:server:saveProfile", profilepic, information, cid, fName, sName, tags, gallery, licenses, fingerprint) cb(true) end) @@ -335,6 +335,8 @@ RegisterNUICallback("getProfileData", function(data, cb) end end p = nil + + result['fingerprint'] = result['searchFingerprint'] return cb(result) end) @@ -1044,10 +1046,10 @@ end) for _, weaponInfo in ipairs(weaponInfos) do TriggerServerEvent('mdt:server:registerweapon', weaponInfo.serialnumber, weaponInfo.weaponurl, weaponInfo.notes, weaponInfo.owner, weaponInfo.weapClass, weaponInfo.weaponmodel) TriggerEvent('QBCore:Notify', "Weapon " .. weaponInfo.weaponmodel .. " has been added to police database.") - print("Weapon added to database") + --print("Weapon added to database") end else - print("No weapons found") + --print("No weapons found") end end) end, false) ]] diff --git a/fxmanifest.lua b/fxmanifest.lua index 9388a392..1b7e90cb 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -13,8 +13,7 @@ server_scripts { '@oxmysql/lib/MySQL.lua', 'server/utils.lua', 'server/dbm.lua', - 'server/main.lua', - 'server/versioncheck.lua' + 'server/main.lua' } client_scripts{ 'client/main.lua', @@ -30,4 +29,4 @@ files { 'ui/dashboard.html', 'ui/app.js', 'ui/style.css', -} +} \ No newline at end of file diff --git a/server/dbm.lua b/server/dbm.lua index 11e2babc..c85be6da 100644 --- a/server/dbm.lua +++ b/server/dbm.lua @@ -13,13 +13,10 @@ end -- (Start) Opening the MDT and sending data function AddLog(text) - --print(text) return MySQL.insert.await('INSERT INTO `mdt_logs` (`text`, `time`) VALUES (?,?)', {text, os.time() * 1000}) - -- return exports.oxmysql:execute('INSERT INTO `mdt_logs` (`text`, `time`) VALUES (:text, :time)', { text = text, time = os.time() * 1000 }) end function GetNameFromId(cid) - -- Should be a scalar? local result = MySQL.scalar.await('SELECT charinfo FROM players WHERE citizenid = @citizenid', { ['@citizenid'] = cid }) if result ~= nil then local charinfo = json.decode(result) @@ -29,37 +26,29 @@ function GetNameFromId(cid) --print('Player does not exist') return nil end - -- return exports.oxmysql:executeSync('SELECT firstname, lastname FROM `users` WHERE id = :id LIMIT 1', { id = cid }) end --- idk what this is used for either function GetPersonInformation(cid, jobtype) - local result = MySQL.query.await('SELECT information, tags, gallery, pfp FROM mdt_data WHERE cid = ? and jobtype = ?', { cid, jobtype}) - return result[1] - -- return exports.oxmysql:executeSync('SELECT information, tags, gallery FROM mdt WHERE cid= ? and type = ?', { cid, jobtype }) + local result = MySQL.query.await('SELECT information, tags, gallery, pfp, fingerprint FROM mdt_data WHERE cid = ? and jobtype = ?', { cid, jobtype}) + return result[1] end function GetIncidentName(id) - -- Should also be a scalar local result = MySQL.query.await('SELECT title FROM `mdt_incidents` WHERE id = :id LIMIT 1', { id = id }) return result[1] - -- return exports.oxmysql:executeSync('SELECT title FROM `mdt_incidents` WHERE id = :id LIMIT 1', { id = id }) end function GetConvictions(cids) return MySQL.query.await('SELECT * FROM `mdt_convictions` WHERE `cid` IN(?)', { cids }) - -- return exports.oxmysql:executeSync('SELECT * FROM `mdt_convictions` WHERE `cid` IN(?)', { cids }) end function GetLicenseInfo(cid) local result = MySQL.query.await('SELECT * FROM `licenses` WHERE `cid` = ?', { cid }) return result - -- return exports.oxmysql:executeSync('SELECT * FROM `licenses` WHERE `cid`=:cid', { cid = cid }) end function CreateUser(cid, tableName) AddLog("A user was created with the CID: "..cid) - -- return exports.oxmysql:insert("INSERT INTO `"..dbname.."` (cid) VALUES (:cid)", { cid = cid }) return MySQL.insert.await("INSERT INTO `"..tableName.."` (cid) VALUES (:cid)", { cid = cid }) end @@ -69,7 +58,6 @@ end function GetBulletins(JobType) return MySQL.query.await('SELECT * FROM `mdt_bulletin` WHERE `jobtype` = ? LIMIT 10', { JobType }) - -- return exports.oxmysql:executeSync('SELECT * FROM `mdt_bulletin` WHERE `type`= ? LIMIT 10', { JobType }) end function GetPlayerProperties(cid, cb) @@ -85,20 +73,16 @@ function GetPlayerDataById(id) else return MySQL.single.await('SELECT citizenid, charinfo, job, metadata FROM players WHERE citizenid = ? LIMIT 1', { id }) end - - -- return exports.oxmysql:executeSync('SELECT citizenid, charinfo, job FROM players WHERE citizenid = ? LIMIT 1', { id }) end function GetBoloStatus(plate) local result = MySQL.scalar.await('SELECT id FROM `mdt_bolos` WHERE LOWER(`plate`)=:plate', { plate = string.lower(plate)}) return result - -- return exports.oxmysql:scalarSync('SELECT id FROM `mdt_bolos` WHERE LOWER(`plate`)=:plate', { plate = string.lower(plate)}) end function GetOwnerName(cid) local result = MySQL.scalar.await('SELECT charinfo FROM `players` WHERE LOWER(`citizenid`) = ? LIMIT 1', {cid}) return result - -- return exports.oxmysql:scalarSync('SELECT charinfo FROM `players` WHERE id=:cid LIMIT 1', { cid = cid}) end function GetVehicleInformation(plate, cb) diff --git a/server/main.lua b/server/main.lua index 3099981d..829f3baf 100644 --- a/server/main.lua +++ b/server/main.lua @@ -206,43 +206,48 @@ RegisterNetEvent('mdt:server:openMDT', function() 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 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 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) - citizenIds[#citizenIds+1] = data.citizenid - citizenIdIndexMap[data.citizenid] = index - end - - local convictions = GetConvictions(citizenIds) + 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 - if next(convictions) then - for _, conv in pairs(convictions) do - if conv.warrant == "1" then people[citizenIdIndexMap[conv.cid]].warrant = true end + local convictions = GetConvictions(citizenIds) - local charges = json.decode(conv.charges) - people[citizenIdIndexMap[conv.cid]].convictions = people[citizenIdIndexMap[conv.cid]].convictions + #charges - end - end + 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, people[1].fingerprint) - return cb(people) - end - end + return cb(people) + end + end - return cb({}) + return cb({}) end) QBCore.Functions.CreateCallback("mdt:server:getWarrants", function(source, cb) @@ -418,12 +423,14 @@ QBCore.Functions.CreateCallback('mdt:server:GetProfileData', function(source, cb person.profilepic = mdtData.pfp person.tags = json.decode(mdtData.tags) person.gallery = json.decode(mdtData.gallery) + person.fingerprint = mdtData.fingerprint + print("Fetched fingerprint from mdt_data:", mdtData.fingerprint) end return cb(person) end) -RegisterNetEvent("mdt:server:saveProfile", function(pfp, information, cid, fName, sName, tags, gallery, licenses) +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) @@ -431,13 +438,14 @@ RegisterNetEvent("mdt:server:saveProfile", function(pfp, information, cid, fName 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) VALUES (:cid, :information, :pfp, :jobtype, :tags, :gallery) ON DUPLICATE KEY UPDATE cid = :cid, information = :information, pfp = :pfp, jobtype = :jobtype, tags = :tags, gallery = :gallery', { + 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 @@ -727,34 +735,41 @@ 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 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 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(`charinfo`) LIKE :query OR LOWER(`citizenid`) LIKE :query AND `jobtype` = :jobtype LIMIT 30", { - query = string.lower('%'..query..'%'), -- % wildcard, needed to search for all alike results - 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) + 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 diff --git a/server/versioncheck.lua b/server/versioncheck.lua deleted file mode 100644 index 3d933946..00000000 --- a/server/versioncheck.lua +++ /dev/null @@ -1,45 +0,0 @@ -local function versionCheck(repository) - local resource = GetInvokingResource() or GetCurrentResourceName() - - local currentVersion = GetResourceMetadata(resource, 'version', 0) - - if currentVersion then - currentVersion = currentVersion:match('%d+%.%d+%.%d+') - end - - if not currentVersion then return print(("^1Unable to determine current resource version for '%s' ^0"):format(resource)) end - - SetTimeout(1000, function() - PerformHttpRequest(('https://api.github.com/repos/%s/releases/latest'):format(repository), function(status, response) - if status ~= 200 then return end - - response = json.decode(response) - - if response.prerelease then return end - - local latestVersion = response.tag_name:match('%d+%.%d+%.%d+') - if not latestVersion or latestVersion == currentVersion then return end - - local cv = { string.strsplit('.', currentVersion) } - local lv = { string.strsplit('.', latestVersion) } - - for i = 1, #cv do - local current, minimum = tonumber(cv[i]), tonumber(lv[i]) - if current ~= minimum then - if current < minimum then - - print("^0.-----------------------------------------------.") - print("^0| Project Sloth |") - print("^0'-----------------------------------------------'") - print(('^6Your %s is outdated (your version: %s)\r\nMake sure to update: %s^0'):format(resource, currentVersion, response.html_url)) - print('^2'..response.body:gsub("\r\n\r\n\r", "^0")) - - - else break end - end - end - end, 'GET') - end) -end - -versionCheck('Project-Sloth/ps-mdt') diff --git a/shared/config.lua b/shared/config.lua index 22edd210..70ca8cab 100644 --- a/shared/config.lua +++ b/shared/config.lua @@ -704,4 +704,4 @@ function GetJobType(job) else return nil end -end +end \ No newline at end of file diff --git a/ui/app.js b/ui/app.js index cb9cc674..97830160 100644 --- a/ui/app.js +++ b/ui/app.js @@ -171,6 +171,14 @@ $(document).ready(() => { $(".profile-items").on("click", ".profile-item", async function () { let id = $(this).data("id"); + let profileFingerprint = $(this).data("fingerprint"); + + if (profileFingerprint && profileFingerprint !== "") { + $(".manage-profile-fingerprint-input").val(profileFingerprint); + } else { + $(".manage-profile-fingerprint-input").val(""); + } + let result = await $.post( `https://${GetParentResourceName()}/getProfileData`, JSON.stringify({ @@ -201,24 +209,13 @@ $(document).ready(() => { .addClass("fa-plus"); } - const { vehicles, tags, gallery, convictions, incidents, properties } = result + const { vehicles, tags, gallery, convictions, incidents, properties, fingerprint } = result; $(".manage-profile-editing-title").html(`You are currently editing ${result["firstname"]} ${result["lastname"]}`); $(".manage-profile-citizenid-input").val(result['cid']); $(".manage-profile-name-input-1").val(result["firstname"]); $(".manage-profile-name-input-2").val(result["lastname"]); $(".manage-profile-dob-input").val(result["dob"]); - if (AmbulanceJobs[playerJob] !== undefined) { - $(".manage-profile-fingerprint-input").val(result["fingerprint"]); - } - else { - if (convictions.length >= 1) { - $(".manage-profile-fingerprint-input").val(result["fingerprint"]); - } - else { - $(".manage-profile-fingerprint-input").val("No Fingerprints found!"); - } - } $(".manage-profile-phonenumber-input").val(result["phone"]); $(".manage-profile-job-input").val(`${result.job}, ${result.grade}`); $(".manage-profile-apartment-input").val(`${result.apartment}`); @@ -332,7 +329,6 @@ $(document).ready(() => { $(".gallery-inner-container").html(galleryHTML); $(".houses-holder").html(propertyHTML); }); - //
📝 Summary:
[Insert Report Summary Here]
🧍 Hostage: [Name Here]
🔪 Weapons/Items Confiscated:
· [Insert List Here]
-----
💸 Fine:
⌚ Sentence:
-----
'; + let template = ` +📝 Summary:
+[Insert Report Summary Here]
++
🧍 Hostage: [Name Here]
++
🔪 Weapons/Items Confiscated:
+· [Insert List Here]
++
-----
+💸 Fine:
++
⌚ Sentence:
+-----
+📝 ICU Room #: [ # ]
Report ID: [ Report ID ]
🧍Time Admitted: [ Date and Time Here ]
Surgery: [Yes/No]
Injuries/Ailments:
· [Enter List Of Injuries Here]
-----
Additional Attending:
· [ List Any Other Staff Here ]
🧑🤝🧑 Additional Emergency Contacts:
· [ Name And Number ]
Notes:
· [Additional Notes Here]
-----
'} + template = ` +📝 ICU Room #: [ # ]
+Report ID: [ Report ID ]
+🧍Time Admitted: [ Date and Time Here ]
+Surgery: [Yes/No]
+Injuries/Ailments:
+· [Enter List Of Injuries Here]
+
-----
+Additional Attending:
· [ List Any Other Staff Here ]
+🧑🤝🧑 Additional Emergency Contacts:
· [ Name And Number ]
+Notes:
· [Additional Notes Here]
+-----
+Submitted to ICU?: [Yes/No]
Incident Report:
· [ Brief summary of what happened and who did what while on scene. Note anything that stood out about the scene as well as what was done to treat the patient ]
List of Injuries:
· [ State what injury or injuries occurred ]
Surgical Report:· [ Full report on what was done in surgery, list any complications or anything that was found while in operation. Note who was attending and what they did during the surgery. At the end of the report be sure to note the state of the patient after ]
-----
Attending:
· [ List Any Attending Here ]
Medications Applied:
· [ List Any Attending Here ]
-----
Notes:
[ Additional Notes Here ]
"} + template = ` +Submitted to ICU?: [Yes/No]
+Incident Report:
+· [ Brief summary of what happened and who did what while on scene. Note anything that stood out about the scene as well as what was done to treat the patient ]
+List of Injuries:
+· [ State what injury or injuries occurred ]
+Surgical Report:
+· [ Full report on what was done in surgery, list any complications or anything that was found while in operation. Note who was attending and what they did during the surgery. At the end of the report be sure to note the state of the patient after ]
+-----
+Attending:
+· [ List Any Attending Here ]
+Medications Applied:
+· [ List Any Attending Here ]
+-----
+Notes:
+[ Additional Notes Here ]
+