Bridge / API
The bridge layer is an open-source abstraction that lets server owners customize data providers, hooks, and third-party integrations without modifying core code.
Open Source: The
bridge/ folder is fully open-source and editable. The rest of the resource (client/, server/, web/) is obfuscated.
Architecture
The bridge system uses two global Lua tables:
| Table | Side | File | Purpose |
|---|---|---|---|
Bridge | Client | bridge/client.lua | Location system, plate hit handler, NUI interaction hooks |
BridgeServer | Server | bridge/server.lua | Data providers, dispatch hooks, radar integration |
The core system calls bridge functions at specific points. If a bridge function returns data, the core uses it. If it returns nil, the core falls back to default behavior.
Server Bridge Functions
Override these functions in bridge/server.lua to customize server-side behavior.
Data Provider Hooks
| Function | Parameters | Returns | Description |
|---|---|---|---|
BridgeServer.GetPersonProfileExtras(citizenid) |
citizenid: string | table or nil | Add extra fields to person profiles (e.g., mugshot URL, physical description) |
BridgeServer.GetPhysicalDescription(citizenid) |
citizenid: string | string or nil | Return a text description of the person's appearance |
BridgeServer.GetVehicleExtras(plate) |
plate: string | table or nil | Add extra fields to vehicle profiles (e.g., insurance status, mods) |
Dispatch Hooks
| Function | Parameters | Description |
|---|---|---|
BridgeServer.OnCallCreated(callData) |
callData: table | Called when a new dispatch call is created. Use for external integrations (Discord webhooks, etc.) |
BridgeServer.OnUnitAssigned(callId, unitData) |
callId: number, unitData: table | Called when a unit is assigned to a call |
BridgeServer.OnCallClosed(callData) |
callData: table | Called when a dispatch call is closed |
Example: Discord Webhook on Call Created
function BridgeServer.OnCallCreated(callData)
-- Send a Discord webhook when a new dispatch call is created
local embed = {
title = callData.code .. ' - ' .. callData.title,
description = callData.description or 'No description',
color = callData.priority == 3 and 16711680 or 16776960,
fields = {
{ name = 'Location', value = callData.location or 'Unknown', inline = true },
{ name = 'Priority', value = tostring(callData.priority), inline = true },
},
}
-- PerformHttpRequest(webhookUrl, function() end, 'POST', json.encode({embeds = {embed}}), {['Content-Type'] = 'application/json'})
end
Radar / ALPR Integration (wk_wars2x)
The bridge includes built-in integration with wk_wars2x (Wraith ARS 2X) for automatic plate scanning and alert generation.
Optional: This integration only activates if
wk_wars2x is running on your server. The MDT works fine without it.How It Works
- Officer activates the radar/ALPR in their vehicle (wk_wars2x)
- When a plate is scanned, wk_wars2x fires the
wk:onPlateScannedevent - The bridge intercepts this event and calls
BridgeServer.OnPlateScanned() - The server checks the plate against:
- Vehicle Flags — Active flags in
computer_vehicle_flagstable (stolen, BOLO, wanted, etc.) - Active BOLOs — Any active BOLO in
computer_bolosthat matches the plate
- Vehicle Flags — Active flags in
- If a hit is found, the server sends an alert to the scanning officer
- The plate reader automatically locks onto the flagged plate
- The client shows a notification and optionally forwards the hit to the MDT UI
Server-side Functions
bridge/server.lua - Radar Functions
--- Called when wk_wars2x scans a plate
--- @param source number Player server ID
--- @param cam string Camera name ('front' or 'rear')
--- @param plate string The scanned plate (trimmed, uppercase)
--- @param index number Plate reader index
function BridgeServer.OnPlateScanned(source, cam, plate, index)
-- Checks plate against vehicle flags + active BOLOs
-- Sends hit to officer if found
-- Auto-locks the plate reader
end
--- Lock/unlock the plate reader on a specific camera
--- @param source number Player server ID
--- @param cam string Camera name
function BridgeServer.LockPlateReader(source, cam)
-- Uses wk_wars2x TogglePlateLock export
end
Client-side Functions
bridge/client.lua - Plate Hit Handler
--- Called when a plate hit is received from the server
--- @param hit table { plate, flags, bolos }
function Bridge.OnPlateHit(hit)
-- Default behavior:
-- 1. Show lib.notify with plate and flag/BOLO details
-- 2. Forward hit data to MDT NUI (plateHit message)
-- 3. Play alert sound
end
Customizing Radar Behavior
You can override the default radar functions to customize alerts:
Example: Custom Alert with Sound
-- In bridge/client.lua, override OnPlateHit:
function Bridge.OnPlateHit(hit)
-- Custom notification
lib.notify({
title = 'ALPR HIT',
description = ('Plate: %s | Flags: %d | BOLOs: %d'):format(
hit.plate,
#(hit.flags or {}),
#(hit.bolos or {})
),
type = 'error',
duration = 10000,
})
-- Forward to MDT
SendNUIMessage({ action = 'plateHit', data = hit })
-- Custom sound
PlaySoundFrontend(-1, 'CONFIRM_BEEP', 'HUD_MINI_GAME_SOUNDSET', true)
end
Client Bridge Functions
Location System
| Function | Parameters | Returns | Description |
|---|---|---|---|
Bridge.GetCurrentLocationData() |
none | table { street, area, coords } | Returns the player's current location data for dispatch calls. Uses GTA native street/zone names by default. |
Example: Custom Location Provider
-- Override in bridge/client.lua
function Bridge.GetCurrentLocationData()
local coords = GetEntityCoords(cache.ped)
local streetHash, crossHash = GetStreetNameAtCoord(coords.x, coords.y, coords.z)
local street = GetStreetNameFromHashKey(streetHash)
local zone = GetNameOfZone(coords.x, coords.y, coords.z)
local area = GetLabelText(zone)
return {
street = street,
area = area,
coords = { x = coords.x, y = coords.y, z = coords.z },
}
end
File Loading Order
The bridge files load in a specific order defined in fxmanifest.lua:
Loading Order
1. shared/config/*.lua -- All config files
2. bridge/server.lua -- Server bridge (BridgeServer table)
3. bridge/client.lua -- Client bridge (Bridge table)
4. server/modules/*.lua -- Core server modules
5. server/*.lua -- Core server scripts
6. client/*.lua -- Core client scripts
Bridge files load before core scripts, so all bridge functions are available when the core initializes.