From e4944045c94180738d50568301df0eb42a3f9c44 Mon Sep 17 00:00:00 2001 From: "Jordan.#2139" Date: Thu, 6 Jun 2024 17:42:43 -0400 Subject: [PATCH 1/5] v2.9.30 - Add additional util functions to core --- sonorancad/core/server.lua | 248 ++++++++++++++++++++++++++++++++++++- sonorancad/fxmanifest.lua | 2 +- sonorancad/version.json | 2 +- 3 files changed, 249 insertions(+), 3 deletions(-) diff --git a/sonorancad/core/server.lua b/sonorancad/core/server.lua index d8b7cf6..cf1c8a7 100644 --- a/sonorancad/core/server.lua +++ b/sonorancad/core/server.lua @@ -278,4 +278,250 @@ RegisterNetEvent('SonoranScripts::Call911', function(caller, location, descripti call911(caller, location, description, postal, plate, function(response) json.encode(response) -- Not, CB's can only be used on the server side, so we just print this here for you to see. end, silenceAlert, useCallLocation) -end) \ No newline at end of file +end) + +-- Jordan - CAD Utils +dispatchOnline = false +ActiveDispatchers = {} + +registerEndpoints = function() + exports['sonorancad']:registerApiType('MODIFY_BLIP', 'emergency') + exports['sonorancad']:registerApiType('ADD_BLIP', 'emergency') + exports['sonorancad']:registerApiType('REMOVE_BLIP', 'emergency') + exports['sonorancad']:registerApiType('GET_BLIPS', 'emergency') + exports['sonorancad']:registerApiType('MODIFY_BLIP', 'emergency') + exports['sonorancad']:registerApiType('CALL_911', 'emergency') + exports['sonorancad']:registerApiType('ADD_CALL_NOTE', 'emergency') + exports['sonorancad']:registerApiType('REMOVE_911', 'emergency') + exports['sonorancad']:registerApiType('LOOKUP', 'general') + exports['sonorancad']:registerApiType('SET_CALL_POSTAL', 'emergency') + exports['sonorancad']:registerApiType('GET_ACTIVE_UNITS', 'emergency') +end +addBlip = function(coords, colorHex, subType, toolTip, icon, dataTable, cb) + local data = { + { + ['serverId'] = GetConvar('sonoran_serverId', 1), + ['blip'] = { + ['id'] = -1, + ['subType'] = subType, + ['coordinates'] = { + ['x'] = coords.x, + ['y'] = coords.y + }, + ['icon'] = icon, + ['color'] = colorHex, + ['tooltip'] = toolTip, + ['data'] = dataTable + } + } + } + exports['sonorancad']:performApiRequest(data, 'ADD_BLIP', function(res) + if cb ~= nil then + cb(res) + end + end) +end +addBlips = function(blips, cb) + exports['sonorancad']:performApiRequest(blips, 'ADD_BLIP', function(res) + if cb ~= nil then + cb(res) + end + end) +end +removeBlip = function(ids, cb) + exports['sonorancad']:performApiRequest({ + { + ['ids'] = ids + } + }, 'REMOVE_BLIP', function(res) + if cb ~= nil then + cb(res) + end + end) +end +modifyBlipd = function(blipId, dataTable) + exports['sonorancad']:performApiRequest({ + { + ['id'] = blipId, + ['data'] = dataTable + } + }, 'MODIFY_BLIP', function(_) + end) +end +getBlips = function(cb) + local data = { + { + ['serverId'] = GetConvar('sonoran_serverId', 1) + } + } + exports['sonorancad']:performApiRequest(data, 'GET_BLIPS', function(res) + if cb ~= nil then + cb(res) + end + end) +end +removeWithSubtype = function(subType, cb) + getBlips(function(res) + local dres = json.decode(res) + local ids = {} + if type(dres) == 'table' then + for _, v in ipairs(dres) do + if v.subType == subType then + table.insert(ids, #ids + 1, v.id) + end + end + if #ids > 0 then + removeBlip(ids, cb) + end + else + warnLog('No blips were returned.') + end + end) +end +call911 = function(caller, location, description, postal, plate, cb) + exports['sonorancad']:performApiRequest({ + { + ['serverId'] = GetConvar('sonoran_serverId', 1), + ['isEmergency'] = true, + ['caller'] = caller, + ['location'] = location, + ['description'] = description, + ['metaData'] = { + ['plate'] = plate, + ['postal'] = postal + } + } + }, 'CALL_911', cb) +end +addTempBlipData = function(blipId, blipData, waitSeconds, returnToData) + exports['sonorancad']:performApiRequest({ + { + ['id'] = blipId, + ['data'] = blipData + } + }, 'MODIFY_BLIP', function(_) + + end) + + Citizen.CreateThread(function() + Citizen.Wait(waitSeconds * 1000) + exports['sonorancad']:performApiRequest({ + { + ['id'] = blipId, + ['data'] = returnToData + } + }, 'MODIFY_BLIP', function(_) + + end) + end) +end +addTempBlipColor = function(blipId, color, waitSeconds, returnToColor) + exports['sonorancad']:performApiRequest({ + { + ['id'] = blipId, + ['color'] = color + } + }, 'MODIFY_BLIP', function(_) + + end) + + Citizen.CreateThread(function() + Citizen.Wait(waitSeconds * 1000) + exports['sonorancad']:performApiRequest({ + { + ['id'] = blipId, + ['color'] = returnToColor + } + }, 'MODIFY_BLIP', function(_) + + end) + end) +end +remove911 = function(callId) + exports['sonorancad']:performApiRequest({ + { + ['serverId'] = GetConvar('sonoran_serverId', 1), + ['callId'] = callId + } + }, 'REMOVE_911', function(_) + end) +end +addCallNote = function(callId, caller) + exports['sonorancad']:performApiRequest({ + { + ['serverId'] = GetConvar('sonoran_serverId', 1), + ['callId'] = callId, + ['note'] = caller + } + }, 'ADD_CALL_NOTE', function(_) + end) +end +setCallPostal = function(callId, postal) + exports['sonorancad']:performApiRequest({ + { + ['serverId'] = GetConvar('sonoran_serverId', 1), + ['callId'] = callId, + ['postal'] = postal + } + }, 'SET_CALL_POSTAL', function(_) + end) +end +performLookup = function(plate, cb) + exports['sonorancad']:performApiRequest({ + { + ['types'] = { + 2, + 3 + }, + ['plate'] = plate, + ['partial'] = false, + ['first'] = '', + ['last'] = '', + ['mi'] = '' + } + }, 'LOOKUP', function(res) + if cb ~= nil then + cb(res) + end + end) +end +checkCADSubscriptionType = function() + while exports['sonorancad']:getCadVersion() == nil or exports['sonorancad']:getCadVersion() == -1 do + Citizen.Wait(100) + end + local version = exports['sonorancad']:getCadVersion() + if version ~= 4 and version == 3 then + errorLog('The live map blip feature require the Pro plan for the CAD. It will be disabled for this run.' + .. ' We recommend either upgrading your plan or disabling this feature in the config file.') + Config.integration.SonoranCAD_integration.addLiveMapBlips = false + Config.modified = true + TriggerClientEvent(GetCurrentResourceName() .. '::ModifiedConfig', -1, Config) + elseif version ~= 4 and version ~= 3 and version ~= 5 and version ~= 6 then + errorLog('SonoranCAD integration with this script requires at least a Plus plan for the CAD. It will be' + .. ' disabled for this run. We recommend either upgrading your plan or disabling this' .. ' feature in the config file.') + Config.integration.SonoranCAD_integration.use = false + Config.modified = true + TriggerClientEvent(GetCurrentResourceName() .. '::ModifiedConfig', -1, Config) + end +end +getDispatchStatus = function(_) + return dispatchOnline +end + +exports('registerEndpoints', registerEndpoints) +exports('addBlip', addBlip) +exports('addBlips', addBlips) +exports('removeBlip', removeBlip) +exports('modifyBlipd', modifyBlipd) +exports('getBlips', getBlips) +exports('removeWithSubtype', removeWithSubtype) +exports('call911', call911) +exports('addTempBlipData', addTempBlipData) +exports('addTempBlipColor', addTempBlipColor) +exports('remove911', remove911) +exports('addCallNote', addCallNote) +exports('setCallPostal', setCallPostal) +exports('performLookup', performLookup) +exports('checkCADSubscriptionType', checkCADSubscriptionType) +exports('getDispatchStatus', getDispatchStatus) +-- Jordan - CAD Utils \ No newline at end of file diff --git a/sonorancad/fxmanifest.lua b/sonorancad/fxmanifest.lua index c3ceed1..a9d9555 100644 --- a/sonorancad/fxmanifest.lua +++ b/sonorancad/fxmanifest.lua @@ -3,7 +3,7 @@ games {'gta5'} author 'Sonoran CAD' description 'Sonoran CAD FiveM Integration' -version '2.9.29' +version '2.9.30' server_scripts { 'core/http.js' diff --git a/sonorancad/version.json b/sonorancad/version.json index 65f0f3c..6961bba 100644 --- a/sonorancad/version.json +++ b/sonorancad/version.json @@ -1,4 +1,4 @@ { - "resource" : "2.9.29", + "resource" : "2.9.30", "testedFxServerVersion": "5932" } From 4d80bc7b7ea08f84d7828a2db67128b714e9a581 Mon Sep 17 00:00:00 2001 From: "Jordan.#2139" <65438497+Jordan2139@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:58:41 -0400 Subject: [PATCH 2/5] tablet --- tablet/cl_main.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tablet/cl_main.lua b/tablet/cl_main.lua index db1bb6b..77c771e 100644 --- a/tablet/cl_main.lua +++ b/tablet/cl_main.lua @@ -23,9 +23,9 @@ Citizen.CreateThread(function() local comId = GetConvar("sonoran_communityID", "") if comId ~= "" then - SetModuleUrl("cad", GetConvar("sonorantablet_cadUrl", 'https://sonorancad.com/login?comid='..comId)) + SetModuleUrl("cad", GetConvar("sonorantablet_cadUrl", 'https://sonorancad.com/login?comid='..comId), true) else - SetModuleUrl("cad", GetConvar("sonorantablet_cadUrl", 'https://sonorancad.com/')) + SetModuleUrl("cad", GetConvar("sonorantablet_cadUrl", 'https://sonorancad.com/'), false) end TriggerServerEvent("SonoranCAD::mini:CallSync_S") @@ -124,11 +124,11 @@ function DisplayModule(module, show) end -- Set Module URL (for iframes) -function SetModuleUrl(module, url) +function SetModuleUrl(module, url, hasComID) DebugMessage("sending url update message to nui", module) SendNUIMessage({ type = "setUrl", - url = url, + url = url + hasComID and ("&cachebuster=" + GetGameTimer()) or ("?cachebuster=" + GetGameTimer()), module = module }) end @@ -226,7 +226,7 @@ RegisterCommand("minicadrows", function(source, args, rawCommand) if #args ~= 1 then PrintChatMessage("Please specify a number of rows to display.") return - else + else SetModuleConfigValue("hud", "maxrows", tonumber(args[1]) - 1) PrintChatMessage("Maximum Mini-CAD call notes set to " .. args[1]) end @@ -322,11 +322,11 @@ AddEventHandler("SonoranCAD::mini:CallSync", function(CallCache, EmergencyCache) }) end) -AddEventHandler('onClientResourceStart', function(resourceName) --When resource starts, stop the GUI showing. +AddEventHandler('onClientResourceStart', function(resourceName) --When resource starts, stop the GUI showing. if(GetCurrentResourceName() ~= resourceName) then return end - SetFocused(false) + SetFocused(false) TriggerServerEvent("sonoran:tablet:forceCheckApiId") end) From 54c17d7a307367b15dccaaf806d3168413d2d6a7 Mon Sep 17 00:00:00 2001 From: "Jordan.#2139" <65438497+Jordan2139@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:06:09 -0400 Subject: [PATCH 3/5] v2.9.31 - Tablet cache busting --- sonorancad/fxmanifest.lua | 2 +- sonorancad/version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sonorancad/fxmanifest.lua b/sonorancad/fxmanifest.lua index a9d9555..44981b3 100644 --- a/sonorancad/fxmanifest.lua +++ b/sonorancad/fxmanifest.lua @@ -3,7 +3,7 @@ games {'gta5'} author 'Sonoran CAD' description 'Sonoran CAD FiveM Integration' -version '2.9.30' +version '2.9.31' server_scripts { 'core/http.js' diff --git a/sonorancad/version.json b/sonorancad/version.json index 6961bba..fdc8635 100644 --- a/sonorancad/version.json +++ b/sonorancad/version.json @@ -1,4 +1,4 @@ { - "resource" : "2.9.30", + "resource" : "2.9.31", "testedFxServerVersion": "5932" } From 04a18267b0c9f385de1b1e539fb568305f24dcfd Mon Sep 17 00:00:00 2001 From: "Jordan.#2139" Date: Wed, 28 Aug 2024 19:10:52 -0400 Subject: [PATCH 4/5] Set url in JS --- tablet/cl_main.lua | 5 +++-- tablet/html/script.js | 13 +++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tablet/cl_main.lua b/tablet/cl_main.lua index 77c771e..fa3767c 100644 --- a/tablet/cl_main.lua +++ b/tablet/cl_main.lua @@ -128,8 +128,9 @@ function SetModuleUrl(module, url, hasComID) DebugMessage("sending url update message to nui", module) SendNUIMessage({ type = "setUrl", - url = url + hasComID and ("&cachebuster=" + GetGameTimer()) or ("?cachebuster=" + GetGameTimer()), - module = module + url = url, + module = module, + comId = hasComID }) end diff --git a/tablet/html/script.js b/tablet/html/script.js index 43e0fd8..3636281 100644 --- a/tablet/html/script.js +++ b/tablet/html/script.js @@ -170,7 +170,7 @@ function attach() { // Don't reattach to the same call. if (isAttached(CallCache.active[currCall])) { for (const call of CallCache.active) { - // Detach from other calls. + // Detach from other calls. if (isAttached(call)) { console.log("Detaching from call #" + call.dispatch.callId); $.post('https://tablet/DetachFromCall', JSON.stringify({callId: call.dispatch.callId})); @@ -178,7 +178,7 @@ function attach() { } } else { for (const call of CallCache.active) { - // Detach from other calls. + // Detach from other calls. if (isAttached(call)) { console.log("Detaching from call #" + call.dispatch.callId); $.post('https://tablet/DetachFromCall', JSON.stringify({callId: call.dispatch.callId})); @@ -259,6 +259,11 @@ $(function () { } else if (event.data.type == "setUrl") { if (event.data.module == "cad") { + if (event.data.comId) { + document.getElementById("cadFrame").src = event.data.url + "&cachebuster=" + new Date.now(); + } else { + document.getElementById("cadFrame").src = event.data.url + "?cachebuster=" + new Date.now(); + } document.getElementById("cadFrame").src = event.data.url; document.getElementById('cadFrame').setAttribute("name", Date.now()) } @@ -304,7 +309,7 @@ $(function () { switch (data.which) { case 27: $.post('https://tablet/NUIFocusOff', JSON.stringify({})); - break; + break; default: break; } @@ -322,7 +327,7 @@ function dragElement(elmnt) { // if present, the header is where you move the DIV from: document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown; } else { - // otherwise, move the DIV from anywhere inside the DIV: + // otherwise, move the DIV from anywhere inside the DIV: elmnt.onmousedown = dragMouseDown; } From 25bf893aef08e834203423530d67340aac4ede44 Mon Sep 17 00:00:00 2001 From: "Jordan.#2139" Date: Thu, 29 Aug 2024 00:03:21 -0400 Subject: [PATCH 5/5] Use date.now --- tablet/cl_main.lua | 4 ++-- tablet/html/script.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tablet/cl_main.lua b/tablet/cl_main.lua index fa3767c..ca14e18 100644 --- a/tablet/cl_main.lua +++ b/tablet/cl_main.lua @@ -20,8 +20,8 @@ Citizen.CreateThread(function() InitModuleSize("cad") InitModuleSize("hud") InitModuleConfig("hud") - - local comId = GetConvar("sonoran_communityID", "") + local convar = GetConvar("sonorantablet_cadUrl", 'https://sonorancad.com/') + local comId = convar:match("comid=(%w+)") if comId ~= "" then SetModuleUrl("cad", GetConvar("sonorantablet_cadUrl", 'https://sonorancad.com/login?comid='..comId), true) else diff --git a/tablet/html/script.js b/tablet/html/script.js index 3636281..a484059 100644 --- a/tablet/html/script.js +++ b/tablet/html/script.js @@ -259,12 +259,12 @@ $(function () { } else if (event.data.type == "setUrl") { if (event.data.module == "cad") { + let date = Date.now() if (event.data.comId) { - document.getElementById("cadFrame").src = event.data.url + "&cachebuster=" + new Date.now(); + document.getElementById("cadFrame").src = event.data.url + "&cachebuster=" + date; } else { - document.getElementById("cadFrame").src = event.data.url + "?cachebuster=" + new Date.now(); + document.getElementById("cadFrame").src = event.data.url + "?cachebuster=" + date; } - document.getElementById("cadFrame").src = event.data.url; document.getElementById('cadFrame').setAttribute("name", Date.now()) } }