Setup
1
Copy the standalone adapter
Copy the
standalone folders and name them custom. Copy qb-core or esx instead if your framework is based on one.2
Rename the provider
Change
'standalone' to 'custom' in the first lines of core.lua, players.lua, and vehicles.lua:3
Select it
config/config.lua
4
Fill in the functions
Replace each function body with calls to your framework. Each function below shows what it must return.
Players
File:core.lua.
GetOnlineSources
GetPlayerIdentifier
nil if not loaded.
If the identifier isn’t readable (like license:abc...), set Bridge.Framework.ReadableIdentifier = false. The MDT then shows the birthdate instead.
GetSourceFromIdentifier
nil if offline.
GetCharacterName
GetPlayerData
nil if not loaded.
HasGroup
Optional.true if the player is in any of groups. Used for Config.AdminGroups. Without it, the MDT checks the ACE in Config.AdminAce.
Jobs and duty
File:core.lua.
GetJobs
GetJobInfo
GetJobs, or nil.
GetPlayerJob
nil.
GetPlayerJobByIdentifier
GetPlayerJob, but works for offline characters.
SetPlayerJob
true on success. Must work for offline characters.
GetJobPlayers
job, and their count. With checkOnDuty, only those on duty.
GetPlayerDuty
true if the player is on duty.
SetPlayerDuty
true on success.
Callsign and badge
File:core.lua. Store these wherever your framework keeps character metadata.
GetPlayerMetadata
key, or nil.
SetPlayerMetadata
true on success.
GetPlayerCallsign
nil.
SetPlayerCallsign
true on success.
SetPlayerBadge
true on success.
Money
File:core.lua. type is the account name, such as 'cash' or 'bank'.
GetMoney
0.
AddMoney
true if the money was added.
RemoveMoney
true if the money was removed. Must work for offline characters. With allowDebt, the balance may go negative.
GetBankAccount
Optional. Needed forConfig.ShowCitizenBank.
nil.
Items and weapons
File:core.lua.
CreateUseableItem
GetItems
GetWeapons
GetWeaponLabel
Optional.VehicleModels
Optional. A table of vehicle models keyed by spawn name, likeQBCore.Shared.Vehicles. The MDT uses it for vehicle names and classes.
Characters
File:players.lua. These feed the Citizens page and the department pages. Every character is described with this shape. Only identifier is required.
GetIdentities
Always implement this one. Officers’ names come from it.SearchCitizens
Used whenConfig.AutoPopulateData = true.
total that match, ignoring offset and limit. If known_total is set, return it as total and skip counting.
Match query against names and identifiers that start with it, or a phone number or fingerprint equal to it. request.sql holds ready-made SQL fragments for the MDT’s own filters and record counts. See the comments in players.lua for every field.
GetCapabilities
nationality = false hides the nationality field and filter.
FindByPhoneNumbers
GetNameMatchQuery
SELECT of one column: identifiers of characters whose name starts with query. Return nil if your data isn’t in SQL.
SetImage
url = '' clears it. Returns false only if the character doesn’t exist. Return the photo as image in GetIdentities.
Job members
File:players.lua. These feed the roster, employees, and analytics pages. A job member is any character with that job, online or not.
ListJobMembers
total that match. Fill name, image, callsign, badge, phone_number, grade, and last_seen. Without it, the roster lists only online officers.
GetJobMembersQuery
SELECT of one column named identifier: every member of job. Return nil if your data isn’t in SQL.
CountJobMembers
GetCallsigns
jobs, keyed by identifier. Used to keep callsigns unique.
IsBadgeTaken
true if another member of job already has badge. Ignore the character except.
Vehicles
File:vehicles.lua. These feed the Vehicles page. Every vehicle is described with this shape:
IsAvailable
true if this adapter reads real vehicles. Return false to use only vehicles officers register in the MDT.
SearchVehicles
Used whenConfig.AutoPopulateData = true.
plate, model, owner_identifier, impounded) and the total that match. See the comments in vehicles.lua for every field.
GetVehicle
nil if no vehicle has this plate.
GetVehicles
with_color is false.
GetOwnedVehicles
limit.
GetOwner
nil. Called on every radar hit, so keep it fast.
GetOwnersQuery
SELECT of every identifier that owns a vehicle, such as SELECT DISTINCT owner FROM owned_vehicles. Return nil to hide the “owns a vehicle” filter.
GetImpoundedQuery
SELECT of every impounded plate, such as SELECT plate FROM owned_vehicles WHERE stored = 2. Return nil if your data isn’t in SQL.
SetImage
url = '' clears it. Returns false only if the vehicle doesn’t exist.
Events
Trigger these from your framework’s events so the MDT stays in sync:server/custom/framework/custom/core.lua
player-unloaded on playerDropped.