Cadburry ScriptsCadburry Scripts

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)
Last updated Cadburry Scripts