bridge/integrations.lua

-- ==========================================
-- INTEGRATIONS BRIDGE  (server-side only)
-- ==========================================
-- Wraps external resource calls (MDT, multi-job, player photos)
-- so servers can swap implementations without touching escrowed code.
--
-- Each integration checks whether its resource is actually running
-- at startup.  If a resource is missing, the corresponding functions
-- return safe defaults and are never called — no pcall overhead, no
-- error spam in the console.
--
-- Global table:  Integration
-- ==========================================

Integration = {}

-- ==========================================
-- RESOURCE DETECTION  (runs once at startup)
-- ==========================================
local hasMultiJob  = GetResourceState('fiveous_multijob') == 'started'
local hasLBTablet  = GetResourceState('lb-tablet') == 'started'
local hasCsLicense = GetResourceState('cs_license') == 'started'

--- Expose availability flags so escrowed code can skip entire blocks
--- rather than calling functions that return empty defaults.
Integration.hasMDT       = hasLBTablet
Integration.hasPhotos    = hasCsLicense
Integration.hasMultiJob  = hasMultiJob

-- Log what's available so server owners know what to expect
local detected = {}
if hasMultiJob  then detected[#detected + 1] = 'fiveous_multijob' end
if hasLBTablet  then detected[#detected + 1] = 'lb-tablet (MDT)' end
if hasCsLicense then detected[#detected + 1] = 'cs_license (photos)' end

if #detected > 0 then
    print('[fiveous_drones] Integrations detected: ' .. table.concat(detected, ', '))
else
    print('[fiveous_drones] No optional integrations detected (MDT callsigns/charges and player photos will be unavailable)')
end

-- ==========================================
-- MULTI-JOB  (fiveous_multijob)
-- ==========================================
-- Returns true if the player holds the given job name as a
-- dormant/secondary job (multi-job systems).
-- If your server uses a different multi-job resource, change this.

--- @param src number  server id
--- @param jobName string  e.g. 'police'
--- @return boolean
function Integration.HasMultiJob(src, jobName)
    if not hasMultiJob then return false end
    local ok, result = pcall(function()
        return exports['fiveous_multijob']:hasJob(src, jobName)
    end)
    return ok and result == true
end

-- ==========================================
-- MDT CALLSIGNS  (lb-tablet)
-- ==========================================
-- Looks up a player's callsign from the MDT system.
-- If your server uses a different MDT (e.g. ps-mdt, bub-mdt),
-- change these functions and update the resource check above.

--- Get police callsign for a citizen
--- @param identifier string  citizenid
--- @return string|nil  callsign, or nil if unavailable
function Integration.GetPoliceCallsign(identifier)
    if not hasLBTablet then return nil end
    local ok, callsign = pcall(function()
        return exports['lb-tablet']:GetPoliceCallsign(identifier)
    end)
    if ok and callsign and callsign ~= '' then return callsign end
    return nil
end

--- Get ambulance/EMS callsign for a citizen
--- @param identifier string  citizenid
--- @return string|nil  callsign, or nil if unavailable
function Integration.GetAmbulanceCallsign(identifier)
    if not hasLBTablet then return nil end
    local ok, callsign = pcall(function()
        return exports['lb-tablet']:GetAmbulanceCallsign(identifier)
    end)
    if ok and callsign and callsign ~= '' then return callsign end
    return nil
end

-- ==========================================
-- CRIMINAL CHARGES  (lb-tablet)
-- ==========================================
-- Looks up a player's criminal record from the MDT.

--- Get criminal charges for a citizen
--- @param identifier string  citizenid
--- @return table|nil  { hasFelony = bool, chargeCount = number } or nil if MDT unavailable
function Integration.GetCharges(identifier)
    if not hasLBTablet then return nil end
    local ok, charges = pcall(function()
        return exports['lb-tablet']:GetPolicePlayerCharges(identifier)
    end)
    if ok and charges and type(charges) == 'table' then
        local hasFelony = false
        local chargeCount = #charges
        for _, entry in ipairs(charges) do
            if entry.offence and entry.offence.class and entry.offence.class:lower() == 'felony' then
                hasFelony = true
                break
            end
        end
        return { hasFelony = hasFelony, chargeCount = chargeCount }
    end
    return nil
end

-- ==========================================
-- PLAYER PHOTO  (cs_license)
-- ==========================================
-- Fetches a player's photo URL (e.g. from a license/ID system).
-- If your server uses a different photo system, change this and
-- update the resource check above.

--- Get player photo URL
--- @param serverId number  target player's server id
--- @return string|nil  photo URL, or nil if unavailable
function Integration.GetPlayerPhoto(serverId)
    if not hasCsLicense then return nil end
    local ok, url = pcall(function()
        return exports['cs_license']:fetchPic(serverId)
    end)
    if ok and url and url ~= '' and url ~= false then
        return url
    end
    return nil
end

Last updated