Utils
Quality of life scripts for your FiveM server. Performance optimized resources that install in minutes, with free updates and support that actually answers.
bridge/framework/client.lua
lua
if Config.Framework == 'qbox' then
local PlayerData = exports.qbx_core:GetPlayerData()
function GetJob()
return PlayerData.job.name
end
function HasLicense(name)
return PlayerData.metadata.licences[name]
end
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val)
PlayerData = val
if PlayerData.metadata and (PlayerData.metadata.inlaststand or PlayerData.metadata.isdead) then
exports['cad-identity']:closeIdentity()
end
end)
end
if Config.Framework == 'qb' then
local QBCore = exports['qb-core']:GetCoreObject()
local PlayerData = QBCore.Functions.GetPlayerData()
function GetJob()
return PlayerData.job.name
end
function HasLicense(name)
return PlayerData.metadata.licences[name]
end
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
PlayerData = QBCore.Functions.GetPlayerData()
end)
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val)
PlayerData = val
if PlayerData.metadata and (PlayerData.metadata.inlaststand or PlayerData.metadata.isdead) then
exports['cad-identity']:closeIdentity()
end
end)
end
if Config.Framework == 'esx' then
local ESX = exports.es_extended:getSharedObject()
function GetJob()
local data = ESX.GetPlayerData()
return data.job.name
end
function HasLicense(name)
ESX.TriggerServerCallback('esx_license:getLicense', function(data)
return data
end, name)
end
end
AddStateBagChangeHandler('invOpen', nil, function(_, _, value)
if value then exports['cad-identity']:closeIdentity() end
end)
AddStateBagChangeHandler('inv_busy', ('player:%s'):format(cache.serverId), function(_, _, value)
if value then exports['cad-identity']:closeIdentity() end
end)bridge/framework/server.lua
lua
if Config.Framework == 'qbox' then
local function getGender(gender)
return gender == 1 and 'F' or 'M'
end
function GetPlayerInfo(src)
local player = exports.qbx_core:GetPlayer(src)
local photo = exports['cad-identity']:getPedHeadshot(src)
return player and photo and {
source = player.PlayerData.source,
citizenid = player.PlayerData.citizenid,
firstname = player.PlayerData.charinfo.firstname,
lastname = player.PlayerData.charinfo.lastname,
sex = getGender(player.PlayerData.charinfo.gender),
dob = player.PlayerData.charinfo.birthdate,
nationality = player.PlayerData.charinfo.nationality,
height = math.random(5, 6),
photo = photo,
driverNo = GenerateRandomLicense('DL') .. player.PlayerData.citizenid,
pilotNo = GenerateRandomLicense('P') .. player.PlayerData.citizenid,
businessNo = GenerateRandomLicense('LS') .. player.PlayerData.citizenid,
issued = os.date("%x", os.time()),
weaponType = 'Class IV',
licenseType = 'PPL',
designation = string.format('%s %s', player.PlayerData.job.label, player.PlayerData.job.grade.name)
}
end
function AddLicense(source, license)
local player = exports.qbx_core:GetPlayer(source)
if not player then return false end
local licences = player.PlayerData.metadata['licences']
licences[license] = true
player.Functions.SetMetaData('licences', licences)
return true
end
function RemoveLicense(source, license)
local player = exports.qbx_core:GetPlayer(source)
if not player then return false end
local licences = player.PlayerData.metadata['licences']
licences[license] = false
player.Functions.SetMetaData('licences', licences)
return true
end
function RemoveMoney(src, amount)
local player = exports.qbx_core:GetPlayer(src)
return player and player.Functions.RemoveMoney('bank', amount) or false
end
end
if Config.Framework == 'qb' then
local QBCore = exports['qb-core']:GetCoreObject()
local function getGender(gender)
return gender == 1 and 'F' or 'M'
end
function GetPlayerInfo(src)
local player = QBCore.Functions.GetPlayer(src)
local photo = exports['cad-identity']:getPedHeadshot(src)
return player and photo and {
source = player.PlayerData.source,
citizenid = player.PlayerData.citizenid,
firstname = player.PlayerData.charinfo.firstname,
lastname = player.PlayerData.charinfo.lastname,
sex = getGender(player.PlayerData.charinfo.gender),
dob = player.PlayerData.charinfo.birthdate,
nationality = player.PlayerData.charinfo.nationality,
height = math.random(5, 6),
photo = photo,
driverNo = GenerateRandomLicense('DL') .. player.PlayerData.citizenid,
pilotNo = GenerateRandomLicense('P') .. player.PlayerData.citizenid,
businessNo = GenerateRandomLicense('LS') .. player.PlayerData.citizenid,
issued = os.date("%x", os.time()),
weaponType = 'Class IV',
licenseType = 'PPL',
designation = string.format('%s %s', player.PlayerData.job.label, player.PlayerData.job.grade.name)
}
end
function AddLicense(source, license)
local player = QBCore.Functions.GetPlayer(source)
if not player then return false end
local licences = player.PlayerData.metadata['licences']
licences[license] = true
player.Functions.SetMetaData('licences', licences)
return true
end
function RemoveLicense(source, license)
local player = QBCore.Functions.GetPlayer(source)
if not player then return false end
local licences = player.PlayerData.metadata['licences']
licences[license] = false
player.Functions.SetMetaData('licences', licences)
return true
end
function RemoveMoney(src, amount)
local player = QBCore.Functions.GetPlayer(src)
return player and player.Functions.RemoveMoney('bank', amount) or false
end
if Config.Inventory ~= 'ox_inventory' then
for name, _ in pairs(Config.Identities) do
QBCore.Functions.CreateUseableItem(name, function(source, item)
local metadata = item.info
metadata.slot = item.slot
if metadata?.citizenid then
exports['cad-identity']:showIdentity(source, item.name, metadata)
return false
else
exports['cad-identity']:requestIdentity(source, item.name, false)
return true
end
end)
end
end
end
if Config.Framework == 'esx' then
local ESX = exports.es_extended:getSharedObject()
function GetPlayerInfo(src)
local xPlayer = ESX.GetPlayerFromId(src)
local photo = exports['cad-identity']:getPedHeadshot(src)
return xPlayer and photo and {
source = xPlayer.source,
citizenid = xPlayer.identifier,
firstname = xPlayer.firstname,
lastname = xPlayer.lastname,
sex = xPlayer.sex,
dob = xPlayer.dateofbirth,
nationality = 'Los Santos',
height = math.random(5, 6),
photo = photo,
driverNo = GenerateRandomLicense('DL') .. xPlayer.identifier,
pilotNo = GenerateRandomLicense('P') .. xPlayer.identifier,
businessNo = GenerateRandomLicense('LS') .. xPlayer.identifier,
issued = os.date("%x", os.time()),
weaponType = 'Class IV',
licenseType = 'PPL',
designation = string.format('%s %s', xPlayer.job.label, xPlayer.job.grade_label)
}
end
function AddLicense(source, license)
TriggerEvent('esx_license:addLicense', source, license)
return true
end
function RemoveLicense(source, license)
TriggerEvent('esx_license:removeLicense', source, license)
return true
end
function RemoveMoney(src, amount)
local xPlayer = ESX.GetPlayerFromId(src)
local bank = xPlayer.getAccount('bank')
if bank and bank.money >= amount then
xPlayer.removeAccountMoney('bank', amount)
return true
end
return false
end
end
if Config.Inventory == 'ox_inventory' then
function AddItem(src, item, amount, info)
if info?.itemLabel and info?.itemImage then
info.label = info?.itemLabel
info.imageurl = info?.itemImage
info.itemLabel = nil
info.itemImage = nil
end
return exports.ox_inventory:AddItem(src, item, amount, info)
end
exports('useCards', function(event, item, inv, slot, _)
local playerId = inv.id
if event == 'usingItem' then
if Config.Identities[item.name] then
local data = exports.ox_inventory:GetSlot(playerId, slot)
if data.metadata?.citizenid then
exports['cad-identity']:showIdentity(playerId, item.name, data.metadata)
return false
else
exports['cad-identity']:requestIdentity(playerId, item.name, false)
return true
end
end
return
end
end)
else
function AddItem(src, item, amount, info)
local success = exports[Config.Inventory]:AddItem(src, item, amount, nil, info)
if success then
if info?.itemLabel then
exports[Config.Inventory]:SetItemData(src, item, 'label', info?.itemLabel)
info.itemLabel = nil
end
if info?.itemImage then
exports[Config.Inventory]:SetItemData(src, item, 'image', info?.itemImage)
info.itemImage = nil
end
if GetResourceState('qb-core') == 'started' then
local items = exports['qb-core']:GetSharedItems()
TriggerClientEvent('qb-inventory:client:ItemBox', src, items[item], 'add')
end
end
return success
end
end
exports('addLicense', AddLicense)
exports('removeLicense', RemoveLicense)
lib.addCommand('provide_license', {
help = 'Provide license',
params = {
{
name = 'target',
type = 'playerId',
help = 'Target player\'s server id',
},
{
name = 'license',
type = 'string',
help = 'license type',
optional = true
},
},
restricted = 'group.admin'
}, function(source, args, raw)
AddLicense(args.target, args.license)
end)
lib.addCommand('revoke_license', {
help = 'Revoke license',
params = {
{
name = 'target',
type = 'playerId',
help = 'Target player\'s server id',
},
{
name = 'license',
type = 'string',
help = 'license type',
optional = true
},
},
restricted = 'group.admin'
}, function(source, args, raw)
RemoveLicense(args.target, args.license)
end)bridge/utils/client.lua
lua
function Notify(msg, type)
if Config.Notify == 'ox' then
if type == nil then type = 'inform' end
lib.notify({ description = msg, type = type })
elseif Config.Notify == 'qb' then
TriggerEvent('QBCore:Notify', msg, type)
end
end
function ShowTextUI(msg)
lib.showTextUI(msg)
end
function HideTextUI()
lib.hideTextUI()
end
function PlayEmote(identity)
local card = Config.Identities[identity]
if not card or not card.emote then return end
if Config.Emotes == 'scully_emotemenu' then
exports.scully_emotemenu:playEmoteByCommand(card.emote)
elseif Config.Emotes == 'rpemotes' then
exports["rpemotes"]:EmoteCommandStart(card.emote)
elseif Config.Emotes == 'dpemotes' then
ExecuteCommand('e '..card.emote)
end
end
function CancelEmote()
if Config.Emotes == 'scully_emotemenu' then
exports.scully_emotemenu:cancelEmote()
elseif Config.Emotes == 'rpemotes' then
exports["rpemotes"]:EmoteCancel(true)
elseif Config.Emotes == 'dpemotes' then
ExecuteCommand('e c')
end
end
function DisableControls()
CreateThread(function()
while LocalPlayer.state.cad_identity do
Wait(8)
DisablePlayerFiring(PlayerId(), true)
DisableControlAction(0, 199, true) -- Disable pause menu
DisableControlAction(0, 200, true) -- Disable pause menu
if IsControlJustPressed(0, 202) or IsControlJustPressed(0, 177) then
exports['cad-identity']:closeIdentity()
end
end
end)
end
RegisterNetEvent('identification:onIdentityOpen', function(identityInfo, identity, playEmote)
if playEmote then PlayEmote(identity) end
DisableControls()
end)
RegisterNetEvent('identification:onIdentityClose', function(identityInfo, identity, playEmote)
CancelEmote()
end)
CreateThread(function()
for _, data in pairs(Config.Blips) do
local blip = AddBlipForCoord(data.coords.x, data.coords.y, data.coords.z)
SetBlipAsShortRange(blip, true)
SetBlipSprite(blip, data.sprite)
SetBlipColour(blip, data.color)
SetBlipScale(blip, 0.7)
SetBlipDisplay(blip, 6)
BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(data.label)
EndTextCommandSetBlipName(blip)
end
end)
CreateThread(function()
local function hasAccess(data)
if data.jobs then
return lib.table.contains(data.jobs, GetJob()) or false
end
if data.license then
return HasLicense(data.license) or false
end
return true
end
if Config.Target == 'ox' then
local options = {}
for card, _data in pairs(Config.Identities) do
if _data.showInList then
options[#options+1] = {
label = _data.label,
icon = _data.icon,
canInteract = function()
return hasAccess(_data)
end,
onSelect = function()
CollectIdentification(card)
end
}
end
end
for _, data in pairs(Config.IdentityCollection) do
exports.ox_target:addSphereZone({
coords = vec3(data.coords.x, data.coords.y, data.coords.z),
radius = data.distance or 2,
debug = Config.Debug,
options = options
})
end
elseif Config.Target == 'qb' then
local options = {}
for card, _data in pairs(Config.Identities) do
if _data.showInList then
options[#options+1] = {
num = 1,
icon = _data.icon,
label = _data.label,
action = function()
CollectIdentification(card)
end,
canInteract = function()
return hasAccess(_data)
end
}
end
end
for index, data in pairs(Config.IdentityCollection) do
exports['qb-target']:AddCircleZone("identitycollection"..index, vec3(data.coords.x, data.coords.y, data.coords.z), 2.0, {
name = "identitycollection"..index,
debugPoly = Config.Debug,
}, {
options = options,
distance = data.distance,
})
end
else
for _, data in pairs(Config.IdentityCollection) do
local point = lib.points.new({
coords = vec3(data.coords.x, data.coords.y, data.coords.z),
distance = data.distance,
})
function point:onEnter()
ShowTextUI(Config.Language.collect_idcard)
end
function point:onExit()
HideTextUI()
end
function point:nearby()
if IsControlJustReleased(0, 46) then
local options = {}
for card, _data in pairs(Config.Identities) do
if hasAccess(_data) and _data.showInList then
options[#options+1] = {
title = _data.label,
icon = _data.icon,
onSelect = function()
CollectIdentification(card)
end
}
end
end
lib.registerContext({
id = 'collect_idcard',
title = 'Get Identification',
options = options
})
lib.showContext('collect_idcard')
end
end
end
end
end)
lib.callback.register('identification:requestDetails', function()
local nationalities = {
'Afghan','Albanian','Algerian','American','Andorran','Angolan','Antiguan','Argentinean','Armenian','Aruban',
'Australian','Austrian','Azerbaijani','Bahamian','Bahraini','Bangladeshi','Barbadian','Barbudans','Belarusian','Belgian',
'Belizean','Beninese','Bermudian','Bhutanese','Bolivian','Bosnian','Brazilian','British','Bruneian','Bulgarian',
'Burkinabe','Burmese','Burundian','Cambodian','Cameroonian','Canadian','Cape Verdean','Caymanian','Central African','Chadian',
'Chilean','Chinese','Colombian','Comoran','Congolese','Costa Rican','Croatian','Cuban','Curaçaoan','Cypriot',
'Czech','Danish','Djiboutian','Dominican','Dutch','East Timorese','Ecuadorean','Egyptian','Emirian','Equatorial Guinean',
'Eritrean','Estonian','Ethiopian','Fijian','Filipino','Finnish','French','Gabonese','Gambian','Georgian',
'German','Ghanaian','Greek','Grenadian','Guatemalan','Guinea-Bissauan','Guinean','Guyanese','Haitian','Herzegovinian',
'Honduran','Hungarian','I-Kiribati','Icelander','Indian','Indonesian','Iranian','Iraqi','Irish','Israeli',
'Italian','Ivorian','Jamaican','Japanese','Jordanian','Kazakhstani','Kenyan','Kittian and Nevisian','Kuwaiti','Kyrgyzstani',
'Laotian','Latvian','Lebanese','Liberian','Libyan','Liechtensteiner','Lithuanian','Luxembourger','Macedonian','Malagasy',
'Malawian','Malaysian','Maldivan','Malian','Maltese','Marshallese','Mauritanian','Mauritian','Mexican','Micronesian',
'Moldovan','Monacan','Mongolian','Montenegrin','Moroccan','Mosotho','Motswana','Mozambican','Namibian','Nauruan',
'Nepalese','New Zealander','Nicaraguan','Nigerian','Niuean','Ni-Vanuatu','Northern Mariana Islander','North Korean','Northern Irish','Norwegian',
'Omani','Pakistani','Palauan','Palestinian','Panamanian','Papua New Guinean','Paraguayan','Peruvian','Polish','Portuguese',
'Qatari','Romanian','Russian','Rwandan','Saint Lucian','Salvadoran','Samoan','San Marinese','Sao Tomean','Saudi',
'Scottish','Senegalese','Serbian','Seychellois','Sierra Leonean','Singaporean','Slovakian','Slovenian','Solomon Islander','Somali',
'South African','South Korean','South Sudanese','Spanish','Sri Lankan','Sudanese','Surinamer','Swazi','Swedish','Swiss',
'Syrian','Taiwanese','Tajikistani','Tanzanian','Thai','Togolese','Tongan','Trinbagonian','Tunisian','Turkish',
'Turkmenistani','Tuvaluan','Ugandan','Ukrainian','Uruguayan','Uzbekistani','Venezuelan','Vietnamese','Vincentian and Grenadinian','Wallisian',
'Welsh','Yemenite','Zambian','Zimbabwean'
}
local nationalitiesOptions = {}
for _, nationality in ipairs(nationalities) do
nationalitiesOptions[#nationalitiesOptions + 1] = { label = nationality, value = nationality }
end
local inputRows = {
{type = 'input', label = 'Citizen ID', description = 'Ex: XXXXXX'},
{type = 'input', label = 'First Name', description = 'Ex: John'},
{type = 'input', label = 'Last Name', description = 'Ex: Doe'},
{type = 'select', label = 'Gender', options = { {label = 'Male', value = 'M'}, {label = 'Female', value = 'F'}, {label = 'Other', value = 'O'} }},
{type = 'input', label = 'Date of Birth', description = "Ex: DD/MM/YYYY"},
{type = 'select', label = 'Nationality', options = nationalitiesOptions, searchable = true},
{type = 'number', label = 'Height (cm)', description = 'Height in centimeters', min = 140, max = 220, default = 170, step = 1},
{type = 'input', label = 'Photo', description = 'Image URL'},
{type = 'input', label = 'Background', description = 'Image URL (if customidcard)'},
{type = 'input', label = 'Driver License No.', description = 'Format: DL-XXXXXX (optional)'},
{type = 'input', label = 'Pilot License No.', description = 'Format: P-XXXXXX (optional)'},
{type = 'input', label = 'Business License No.', description = 'Format: BL-XXXXXX (optional)'},
{type = 'input', label = 'Issued Date', description = "Ex: DD/MM/YYYY"},
{type = 'select', label = 'Weapon License Type', options = { {label = 'Class A', value = 'Class A'}, {label = 'Class B', value = 'Class B'}, {label = 'Class C', value = 'Class C'} }},
{type = 'select', label = 'License Type', options = {{label = 'LMV (Driving)', value = 'LMV'}, {label = 'MCWG (Driving)', value = 'MCWG'}, {label = 'HMV (Driving)', value = 'HMV'}, {label = 'CPL (Pilot)', value = 'CPL'}, {label = 'SPL (Pilot)', value = 'SPL'}, {label = 'PPL (Pilot)', value = 'PPL'}, {label = 'ATPL (Pilot)', value = 'ATPL'} }},
{type = 'input', label = 'Designation/Occupation', description = 'Professional title (optional)'}
}
local input = lib.inputDialog('Custom Identity Creation', inputRows, { allowCancel = true, size = 'xs' })
if not input then return false end
local identity = {
citizenid = input[1],
firstname = input[2],
lastname = input[3],
gender = input[4],
dob = input[5],
nationality = input[6],
height = input[7],
photo = input[8],
backgroundImage = input[9],
driverNo = input[10],
pilotNo = input[11],
businessNo = input[12],
issued = input[13],
weaponType = input[14],
licenseType = input[15],
designation = input[16]
}
inputRows = {
{type = 'input', label = 'Item Label', description = 'Ex: Custom ID'},
{type = 'input', label = 'Item Image', description = 'Image URL'}
}
input = lib.inputDialog('Item Data', inputRows, { allowCancel = true, size = 'xs' })
if not input then return false end
identity.itemLabel = input[1]
identity.itemImage = input[2]
for key, value in pairs(identity) do
if not value or value == nil or value == '' then
identity[key] = nil
end
end
return identity
end)bridge/utils/server.lua
lua
function Notify(src, msg, type)
if Config.Notify == 'ox' then
if type == nil then type = 'inform' end
TriggerClientEvent('ox_lib:notify', src, { description = msg, type = type })
elseif Config.Notify == 'qb' then
TriggerClientEvent('QBCore:Notify', src, msg, type)
end
end
function Logger(source, name, message, data)
local webhook = ""
local title = ('[%d] - %s - %s'):format(source, GetPlayerName(source), name)
local headers = { ['Content-Type'] = 'application/json' }
local _data = json.encode({
username = "Cad Identity",
embeds = {
{
title = title,
color = 10650848,
author = {
name = "cadburry",
},
description = "\n** Message :** "..message.." \n **Data : ** "..json.encode(data).." ",
footer = {
text = os.date('%c'),
},
}
}
})
PerformHttpRequest(webhook, function() end, 'POST', _data, headers)
lib.logger(source, name, message, data)
end
function GenerateRandomLicense(preffix)
local suffix = math.random(11, 99)
local number = preffix..'-'..suffix
return number
end
lib.addCommand('show_identity', {
help = 'Show ID (Admin only)',
params = {
{
name = 'target',
type = 'playerId',
help = 'Target player\'s server id',
},
{
name = 'identity',
type = 'string',
help = 'Identity Name'
},
},
restricted = 'group.admin'
}, function(source, args, raw)
args.identity = args.identity or 'customidcard'
exports['cad-identity']:showIdentity(args.target, args.identity)
end)
lib.addCommand('create_identity', {
help = 'Create Identity (Admin only)',
params = {
{
name = 'target',
type = 'playerId',
help = 'Target player\'s server id',
},
{
name = 'identity',
type = 'string',
help = 'Identity Name'
},
},
restricted = 'group.admin'
}, function(source, args, raw)
args.identity = args.identity or 'customidcard'
local data = lib.callback.await('identification:requestDetails', source)
if not data then return end
exports['cad-identity']:requestIdentity(source, args.identity, data)
end)