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/client.lua

lua
function ControlsDisabled()
    DisablePlayerFiring(PlayerPedId(), true)
    HudWeaponWheelIgnoreSelection()
    DisableControlAction(0, 1, true)
    DisableControlAction(0, 2, true)
    DisableControlAction(0, 24, true)
    DisableControlAction(0, 25, true)
    DisableControlAction(0, 37, true)
    DisableControlAction(0, 38, true)
    DisableControlAction(0, 45, true)
    DisableControlAction(0, 46, true)
    DisableControlAction(0, 245, true)
    DisableControlAction(0, 263, true)
    DisableControlAction(0, 264, true)
    DisableControlAction(0, 257, true)
    DisableControlAction(0, 140, true)
    DisableControlAction(0, 141, true)
    DisableControlAction(0, 142, true)
    DisableControlAction(0, 143, true)
    DisableControlAction(0, 322, true)
end

---@param message string
---@param data table
function SendMessage(message, data)
    if not Config.DisableMessages then
        print('Player: '..json.encode(data, { indent = true }))
        TriggerEvent('chat:addMessage', {
            templateId = 'default',
            multiline = true,
            args = {"Player List", message}
        })
    end
end

---@param data table { coords: vec3, font_size: number, font_style: number, color: {r: number, g: number, b: number}, text: string }
function OverHeadText(data)
	local onScreen, screenX, screenY = World3dToScreen2d(data.coords.x, data.coords.y, data.coords.z)
	if onScreen then
		local camCoords = GetGameplayCamCoords()
		local distance = #(data.coords - camCoords)
		local fov = (1 / GetGameplayCamFov()) * 75
		local scale = (1 / distance) * (4) * fov * (data.font_size)
		SetTextScale(0.0, scale)
		SetTextFont(data.font_style)
		SetTextProportional(true)
		SetTextColour(data.color.r, data.color.g, data.color.b, 255)
		SetTextOutline()
		SetTextEntry("STRING")
		SetTextCentre(true)
		AddTextComponentString(data.text)
		DrawText(screenX, screenY)
	end
end

bridge/server.lua

lua
---@param playerSrc number
---@param format string ('identifier' | 'name_identifier' | 'name_ping' | 'name' | 'id' | 'citizenid')
---@return string
local function formatPlayerText(playerSrc, format)
    local playerId = tostring(playerSrc)
    local identifier = GetPlayerIdentifierByType(playerId, Config.UseIdentifier)

    if format == 'identifier' then
        return identifier or 'Unknown'
    elseif format == 'name_identifier' then
        return string.format('%s (%s)', GetPlayerName(playerId), identifier or 'Could not load')
    elseif format == 'name_ping' then
        return string.format('%s (%d)', GetPlayerName(playerId), GetPlayerPing(playerId))
    elseif format == 'name' then
        return GetPlayerName(playerId)
    elseif format == 'id' then
        return playerId
    elseif format == 'citizenid' then
        return GetCharacterId(playerSrc) or 'Unknown'
    end

    return identifier or 'Unknown'
end

---@param playerSrc number
---@param player table (Framework Player Data)
function GetText(playerSrc, player)
    return formatPlayerText(playerSrc, Config.TextFormat or 'identifier')
end

---@param playerSrc number
---@param player table (Framework Player Data)
function GetTextOverHead(playerSrc, player)
    return formatPlayerText(playerSrc, Config.TextOverHeadFormat or 'id')
end

---@param playerSrc number
---@param player table (Framework Player Data)
function GetPlayerColor(playerSrc, player)
    if IsPlayerAceAllowed(playerSrc --[[@as string]], 'command')
    or IsPlayerAceAllowed(playerSrc --[[@as string]], 'admin') then
        return '#DB0F0F'
    end
    local identifier = GetPlayerIdentifierByType(playerSrc --[[@as string]], Config.UseIdentifier)
    -- Keep in mind Config.UseIdentifier should be same as the one in `cad-queue`
    if GetResourceState('cad-queue') == 'started' then
        local prio = exports['cad-queue']:GetPrio(identifier)
        -- returns: { label: string, name: string, points: number }
        return prio.name == 'police' and '#06214C' or prio.name == 'ambulance' and '#DE264F' or nil
    end
    return nil
end

local cachedImages = {}

---@param playerSrc number
---@param player table (Framework Player Data)
function GetImage(playerSrc, player)
    local playerId = tostring(playerSrc)
    local identifier = GetPlayerIdentifierByType(playerId, Config.UseIdentifier)
    if cachedImages[identifier] then return cachedImages[identifier] end
    local timeout = 5
    local imageUrl = nil
    if Config.UseIdentifier == 'steam' then
        local hex = {string.strsplit(':', identifier)}
        if not hex or not hex[2] then goto skip end
        local steamId = tonumber(hex[2], 16)
        local apiKey = Config.SteamAPIKey
        local apiUrl = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" .. apiKey .. "&steamids=" .. steamId
        PerformHttpRequest(apiUrl, function(status, response)
            if status == 200 then
                local responseData = json.decode(response)
                if responseData.response.players[1] then
                    local avatarURL = responseData.response.players[1].avatarmedium
                    imageUrl = avatarURL
                    cachedImages[identifier] = avatarURL
                end
            end
        end, "GET", "", {["Content-Type"] = "application/json"})
    elseif Config.UseIdentifier == 'discord' then
        local discordId = {string.strsplit(':', identifier)}
        if not discordId or not discordId[2] then goto skip end
        PerformHttpRequest(('https://discord.com/api/v8/users/%s'):format(discordId[2]), function(_, response)
            if response then
                local _response = json.decode(response)
                local avatarURL = ('https://cdn.discordapp.com/avatars/%s/%s'):format(_response.id, _response.avatar)
                imageUrl = avatarURL
                cachedImages[identifier] = avatarURL
            end
        end, 'GET', '', {
            ['Content-Type'] = 'application/json',
            ['Authorization'] = ('Bot %s'):format(Config.DiscordBotToken)
        })
    end

    while timeout > 0 and (imageUrl == nil) do
        timeout = timeout - 1
        Wait(100)
    end

    ::skip::

    return imageUrl or false
end

function GetAllPlayers()
    if GetResourceState('qbx_core') == 'started' then
        return exports.qbx_core:GetQBPlayers()
    elseif GetResourceState('qb-core') == 'started' then
        local QBCore = exports['qb-core']:GetCoreObject()
        return QBCore.Functions.GetQBPlayers()
    elseif GetResourceState('ox_core') == 'started' then
        local Ox = require '@ox_core.lib.init'
        return Ox.GetPlayers()
    elseif GetResourceState('es_extended') == 'started' then
        local ESX = exports.es_extended:getSharedObject()
        return ESX.GetExtendedPlayers()
    else
        assert(false, 'No framework initialised, jobs count set to null')
        return {}
    end
end

function GetJobCounts()
    if GetResourceState('qbx_core') == 'started' then
        local players = exports.qbx_core:GetQBPlayers()
        local jobCounts = {}

        for _, player in pairs(players) do
            local jobName = player.PlayerData.job.name
            local jobOnduty = player.PlayerData.job.onduty
            local jobData = Config.Jobs[jobName]
            if jobData and jobOnduty then
                if not jobCounts[jobName] then jobCounts[jobName] = 0 end
                jobCounts[jobName] = jobCounts[jobName] + 1
            end
        end

        return jobCounts
    elseif GetResourceState('qb-core') == 'started' then
        local QBCore = exports['qb-core']:GetCoreObject()
        local players = QBCore.Functions.GetQBPlayers()
        local jobCounts = {}

        for _, player in pairs(players) do
            local jobName = player.PlayerData.job.name
            local jobOnduty = player.PlayerData.job.onduty
            local jobData = Config.Jobs[jobName]
            if jobData and jobOnduty then
                if not jobCounts[jobName] then jobCounts[jobName] = 0 end
                jobCounts[jobName] = jobCounts[jobName] + 1
            end
        end

        return jobCounts
    elseif GetResourceState('ox_core') == 'started' then
        local Ox = require '@ox_core.lib.init'
        local jobCounts = {}

        for name in pairs(Config.Jobs) do
            jobCounts[name] = Ox.GetGroupActivePlayers(name) or 0
        end

        return jobCounts
    elseif GetResourceState('es_extended') == 'started' then
        local ESX = exports.es_extended:getSharedObject()
        local jobCounts = {}

        for name in pairs(Config.Jobs) do
            jobCounts[name] = ESX.GetNumPlayers('job', 'police')
        end

        return jobCounts
    else
        assert(nil, 'No framework initialised, jobs count set to null')
        return nil
    end
end

---@param playerSrc number
---@return string|nil
function GetCharacterId(playerSrc)
    if GetResourceState('qbx_core') == 'started' then
        local player = exports.qbx_core:GetPlayer(playerSrc)
        return player and player.PlayerData.citizenid or nil
    elseif GetResourceState('qb-core') == 'started' then
        local QBCore = exports['qb-core']:GetCoreObject()
        local player = QBCore.Functions.GetPlayer(playerSrc)
        return player and player.PlayerData.citizenid or nil
    elseif GetResourceState('es_extended') == 'started' then
        local ESX = exports.es_extended:getSharedObject()
        local player = ESX.GetPlayerFromId(playerSrc)
        return player and player.identifier or nil
    elseif GetResourceState('ox_core') == 'started' then
        local Ox = require '@ox_core.lib.init'
        local player = Ox.GetPlayer(playerSrc)
        return player and tostring(player.charId) or nil
    end
    return nil
end

if GetResourceState('qbx_core') == 'started' or GetResourceState('qb-core') == 'started' then
    RegisterNetEvent('QBCore:Server:PlayerLoaded', function(player)
        TriggerEvent('cad-playerlist:playerLoaded', player.PlayerData.source, player)
    end)
elseif GetResourceState('es_extended') == 'started' then
    AddEventHandler('esx:playerLoaded', function (playerId, xPlayer, isNew)
        TriggerEvent('playerlist:playerLoaded', playerId, xPlayer)
    end)
elseif GetResourceState('ox_core') == 'started' then
    local Ox = require '@ox_core.lib.init'
    AddEventHandler('ox:playerLoaded', function(playerId, userId, charId)
        TriggerEvent('playerlist:playerLoaded', playerId, Ox.GetPlayer(playerId))
    end)
else
    AddEventHandler('playerJoining', function(source)
        TriggerEvent('playerlist:playerLoaded', source, nil)
    end)
end
Last updated Cadburry Scripts