Server

Ensure you review the qb.lua and esx.lua files to understand how the phone integrates with each framework. These files are kept up to date with the latest changes.

Step 1: Framework Compatibility Check

At the beginning of your integration file, add a check for Config.Framework to avoid loading for unsupported frameworks.

if Config.Framework ~= "your-framework" then
    return
end

Step 2: Required Framework Functions

Below are the essential functions you need to implement for the phone to function correctly with your custom framework.

GetIdentifier

Retrieve the current character's identifier. For multi-character setups, return the active character's identifier.

function GetIdentifier(source)
    -- This is an example from the gksphone esx.lua file
    return Config.Core.GetPlayerFromId(source)?.identifier
end

GetPlayerFromIdentifier

Check if a character is online using their identifier.

function GetPlayerFromIdentifier(identifier)
    -- This is an example from the gksphone esx.lua file
    return Config.Core.GetPlayerFromIdentifier(identifier)
end

GetCharacterName

Returns the character's full name.

function GetCharacterName(source)
    -- This is an example from the gksphone qb.lua file
    local xPlayer = Config.Core.Functions.GetPlayer(source)
    local name = xPlayer.PlayerData.charinfo.firstname .. ' ' .. xPlayer.PlayerData.charinfo.lastname
    return name
end

GetCharacterBirthDate

Returns the character's birth date.

function GetCharacterBirthDate(source)
    -- This is an example from the gksphone qb.lua file
    local xPlayer = Config.Core.Functions.GetPlayer(source)
    local date = xPlayer.PlayerData.charinfo.birthdate
    return date
end

GetCharacterAllVehicles

Returns a list of all vehicles owned by a player.

---@param source number
---@return vehiclesData[] vehicles An array of vehicles that the player owns
function GetCharacterAllVehicles(identifier, appname)
    local vehicles = {}
    -- Example
    vehiclesData = [
        {
            plate = "GKS11111",
            hash = 1274868363,
            model = "bestiagts",
            fuel = 100,
            engine = 1000,
            body = 1000,
            garage = "Garage Name", -- garage name, Out, Impounded, On The Street
            carseller = 0,
            name = "Bestia GTS",
            type = "Car"
        }
    ]
    return vehiclesData
end

GetVehicle

Fetch a specific vehicle using its plate number.

function GetVehicle(identifier, plate)
    -- Example
    local vehData = {
        plate = "GKS11111",
        hash = 1274868363,
        model = "bestiagts",
        fuel = 100,
        carseller = 0,
        vehMods = {} -- vehicle modification information
    }
    return vehData
end

VehicleUpdate

Updates vehicle status when it's retrieved via valet

function VehicleUpdate(plate)
    -- This is an example from the gksphone esx.lua file
    if GetResourceState("loaf_garage") == "started" then
        MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = @stored, `parking` = @parking WHERE `plate` = @plate',
            {
                ['@plate'] = plate,
                ['@stored'] = 0,
                ['@parking'] = nil
            })
    elseif GetResourceState("cd_garage") == "started" or GetResourceState("jg-advancedgarages") == "started" then
        MySQL.Async.execute('UPDATE owned_vehicles SET  `in_garage` = @in_garage WHERE `plate` = @plate', {
            ['@plate'] = plate,
            ['@in_garage'] = 0,
        })
    elseif GetResourceState("esx_garage") == "started" then
        MySQL.Async.execute('UPDATE owned_vehicles SET  `stored` = @stored WHERE `plate` = @plate', {
            ['@plate'] = plate,
            ['@stored'] = 0,
        })
    end
end

VehicleUpdateCarseller

Handles vehicle ownership changes made through the Car Seller app.

function VehicleUpdateCarseller(plate, data, source, identifier)
    -- This is an example from the gksphone esx.lua file
    if data == 1 or data == 0 then
        MySQL.Async.execute('UPDATE owned_vehicles SET `carseller` = @carseller WHERE `plate` = @plate', {
            ['@plate'] = plate,
            ['@carseller'] = data
        })
    else
        local query = string.format(
        'UPDATE owned_vehicles SET `carseller` = @carseller, `owner` = @owner, %s = @garage, %s WHERE `plate` = @plate',
            Config.GarageDBColumn, Config.GarageStored)
        MySQL.Async.execute(query, {
            ['@owner'] = identifier,
            ['@plate'] = plate,
            ['@carseller'] = 0,
            ['@garage'] = Config.GarageDefaultName
        })
    end
end

GetCharacterJob

Retrieves job-related data for the character.

function GetCharacterJob(source)
    -- This is an example from the gksphone esx.lua file
    local xPlayer = Config.Core.GetPlayerFromId(source) or Config.Core.GetPlayerFromIdentifier(identifier)
    if xPlayer then
        local jobData = {
            source = xPlayer.source,
            identifier = xPlayer.identifier,
            name = xPlayer.job.name,
            label = xPlayer.job.label,
            grade = xPlayer.job.grade,
            grade_salary = xPlayer.job.grade_salary,
            grade_label = xPlayer.job.grade_label,
            grade_name = xPlayer.job.grade_name,
        }
        return jobData
    end
    return nil
end

GetJobs

Returns a list of available jobs in the framework.

function GetCharacterJob(source)
    -- This is an example from the gksphone qb.lua file
    -- example list
    local jobList = {
	police = {
		label = 'Law Enforcement',
		type = 'leo',
		defaultDuty = true,
		offDutyPay = false,
		grades = {
			['0'] = { name = 'Recruit', payment = 50 },
			['1'] = { name = 'Officer', payment = 75 },
			['2'] = { name = 'Sergeant', payment = 100 },
			['3'] = { name = 'Lieutenant', payment = 125 },
			['4'] = { name = 'Chief', isboss = true, payment = 150 },
		},
	},
	ambulance = {
		label = 'EMS',
		type = 'ems',
		defaultDuty = true,
		offDutyPay = false,
		grades = {
			['0'] = { name = 'Recruit', payment = 50 },
			['1'] = { name = 'Paramedic', payment = 75 },
			['2'] = { name = 'Doctor', payment = 100 },
			['3'] = { name = 'Surgeon', payment = 125 },
			['4'] = { name = 'Chief', isboss = true, payment = 150 },
		},
	},
    }
    
    return Config.Core.Shared.Jobs
end

GetAllEmployees

Fetches a list of employees (online and offline) for a specific job.

function GetAllEmployees(job)
    -- This is an example from the gksphone qb.lua file
    local query =
    [[SELECT
            JSON_UNQUOTE(JSON_EXTRACT(u.charinfo, '$.firstname')) AS firstname,
            JSON_UNQUOTE(JSON_EXTRACT(u.charinfo, '$.lastname')) AS lastname,
            JSON_UNQUOTE(JSON_EXTRACT(u.job, '$.payment')) AS payment,
            JSON_UNQUOTE(JSON_EXTRACT(u.job, '$.grade.name')) AS gradeLabel,
            JSON_UNQUOTE(JSON_EXTRACT(u.job, '$.grade.level')) AS job_grade,
            u.citizenid AS `identifier`
        FROM players u
        WHERE JSON_UNQUOTE(JSON_EXTRACT(u.job, '$.name')) = ?]]
    local result = MySQL.Sync.fetchAll(query, { job })
    return result
end

SetJob

Updates a player's job and grade.

function SetJob(identifier, job, grade)
    -- This is an example from the gksphone qb.lua file
    local xPlayer = Config.Core.Functions.GetPlayerByCitizenId(identifier) or
        Config.Core.Functions.GetOfflinePlayerByCitizenId(identifier)
    if xPlayer then
        if xPlayer.Functions.SetJob(job, grade) then
            xPlayer.Functions.Save()
            return true
        end
    end
    return false
end

ToggleDuty

Changes a character's duty status.

function ToggleDuty(source, toggle)
    -- This is an example from the gksphone esx.lua file
    local xPlayer = Config.Core.Functions.GetPlayer(source)
    if xPlayer then
        xPlayer.Functions.SetJobDuty(toggle)
    end
end

GetBankBalance

Returns the current bank balance of a character.

function GetBankBalance(source)
    -- This is an example from the gksphone esx.lua file
    local xPlayer = Config.Core.Functions.GetPlayer(source)
    return xPlayer?.PlayerData?.money?.bank or 0
end

GetBankBalanceByIndetifier

Returns the bank balance based on the character's identifier.

function GetBankBalanceByIndetifier(identifier)
    -- This is an example from the gksphone esx.lua file
    local bank = 0
    local xPlayer = GetPlayerFromIdentifier(identifier)
    if xPlayer then
        bank = xPlayer?.PlayerData?.money?.bank or 0
        return bank
    else
        xPlayer = GetOfflinePlayerByIdentifier(identifier)
        if xPlayer then
            bank = xPlayer?.PlayerData?.money?.bank or 0
            return bank
        end
    end
    return bank
end

RemoveBankMoney

Deducts money from a character's bank account.

function RemoveBankMoney(source, amount, type)
    -- This is an example from the gksphone esx.lua file
    if type == "identifier" then
        local xPlayer = GetPlayerFromIdentifier(source)
        if not xPlayer or amount < 0 or GetBankBalanceByIndetifier(source) < amount then
            return false
        end
        xPlayer.Functions.RemoveMoney('bank', amount, 'gksphone')
        return true
    else
        local xPlayer = Config.Core.Functions.GetPlayer(source)
        if not xPlayer or amount < 0 or GetBankBalance(source) < amount then
            return false
        end
        xPlayer.Functions.RemoveMoney('bank', amount, 'gksphone')
        return true
    end
end

AddBankMoney

Adds money to a character's bank account.

function AddBankMoney(source, amount, type)
    -- This is an example from the gksphone qb.lua file
    if type == "identifier" then
        local xPlayer = GetPlayerFromIdentifier(source)
        if not xPlayer or amount < 0 then
            return false
        end
        xPlayer.Functions.AddMoney('bank', amount, "Bank Transfer")
        return true
    end
    local xPlayer = Config.Core.Functions.GetPlayer(source)
    if not xPlayer or amount < 0 then
        return false
    end
    xPlayer.Functions.AddMoney('bank', amount, "Bank Transfer")
    return true
end

GetExtendedPlayers

Returns an array of player sources with a specified job.

function GetExtendedPlayers(key, val)
    -- This is an example from the gksphone qb.lua file
    local xPlayers = {}
    local players = Config.Core.Functions.GetQBPlayers()
    for _, v in pairs(players) do
        if key then
            if (key == 'job' and v.PlayerData.job.name == val) then
                xPlayers[#xPlayers + 1] = {
                    source = v.PlayerData.source,
                    job = {
                        name = v.PlayerData.job.name,
                        grade = v.PlayerData.job.grade.level
                    }
                }
            end
        end
    end
    return xPlayers
end

RegisterUsableItem

Registers a usable item and sets a callback for when the item is used.

function RegisterUsableItem(item, cb)
    -- This is an example from the gksphone qb.lua file
    Config.Core.Functions.CreateUseableItem(item, cb)
end

RemoveItem

Removes a specific item from a player's inventory.

function RemoveItem(source, itemname, amount)
    -- This is an example from the gksphone qb.lua file
    local Player = Config.Core.Functions.GetPlayer(source)
    if Player then
        Player.Functions.RemoveItem(itemname, amount)
    end
end

FreamworkSavePhoneNumber

Saves a player's phone number to the framework's meta or SQL data.

function FreamworkSavePhoneNumber(phoneNumber, source)
    -- This is an example from the gksphone qb.lua file
    local src = source
    local Player = Config.Core.Functions.GetPlayer(src)
    if Player and phoneNumber then
        Player.PlayerData.charinfo.phone = phoneNumber
        Player.Functions.SetPlayerData('charinfo', Player.PlayerData.charinfo)
    end
end

FreamworkGetPhoneNumberBySource

Retrieves a player's registered phone number.

function FreamworkGetPhoneNumberBySource(source)
    -- This is an example from the gksphone qb.lua file
    local src = source
    local Player = Config.Core.Functions.GetPlayer(src)
    if Player then
        return Player.PlayerData.charinfo.phone
    end
    return nil
end

HasPhoneItem

Checks if the player has a phone item in their inventory.

function HasPhoneItem(source)
    -- This is an example from the gksphone qb.lua file
    local src = source
    local Player = Config.Core.Functions.GetPlayer(src)
    local itemData = {}
    if Player then
        for k, _ in pairs(Config.ItemName) do
            local itemCheck = Player.Functions.GetItemsByName(k)
            if itemCheck and #itemCheck > 0 then
                itemData = itemCheck
                break
            end
        end
        if #itemData > 0 then
            return itemData
        end
    end
    return itemData
end

CallingPlayerStatus

Determines if a player is available to receive calls based on handcuff or downed status.

function CallingPlayerStatus(source)
    -- This is an example from the gksphone qb.lua file
    local retval = false
    local Player = Config.Core.Functions.GetPlayer(source)
    if Player and (Player.PlayerData.metadata["ishandcuffed"] or Player.PlayerData.metadata["isdead"] or Player.PlayerData.metadata["inlaststand"]) then
        retval = true
    end
    return retval
end

GetOfflinePlayerByIdentifier

Returns limited data about an offline player using their identifier.

function GetOfflinePlayerByIdentifier(identifier)
    local self = {}
    self.accounts = {}
    function self.getAccount(account)
        if self.accounts[account] then
            return {money = self.accounts[account]}
        end
        return nil
    end

    function self.removeAccountMoney(account, amount, reason)
        return true
    end

    function self.addAccountMoney(account, amount, reason)
        return true
    end

    function self.getName()
        return ""
    end

    return self
end

Society (Job System)

SocietyGetMoney

Returns the amount of money in the job's account.

function SocietyGetMoney(jobname)
    -- This is an example from the gksphone qb.lua file
    local BusinessMoney = 0
    if GetResourceState("qb-banking") == "started" then
        BusinessMoney = exports['qb-banking']:GetAccount(jobname)?.account_balance or 0
    elseif GetResourceState("Renewed-Banking") == "started" then
        BusinessMoney = exports['Renewed-Banking']:getAccountMoney(jobname) or 0
    end
    return BusinessMoney
end

SocietyRemoveMoney

Deducts money from the job's account, if sufficient funds exist.

function SocietyRemoveMoney(job, amount)
    -- This is an example from the gksphone qb.lua file
    local process = false
    if GetResourceState("qb-banking") == "started" then
        local jobPrice = SocietyGetMoney(job)
        if jobPrice >= amount then
            if exports['qb-banking']:RemoveMoney(job, amount) then
                process = true
            end
        end
    elseif GetResourceState("Renewed-Banking") == "started" then
        local jobPrice = SocietyGetMoney(job)
        if jobPrice >= amount then
            if exports['Renewed-Banking']:removeAccountMoney(job, amount) then
                process = true
            end
        end
    end
    return process
end

SocietyAddMoney

Adds money to the job's account.

function SocietyAddMoney(job, amount)
    -- This is an example from the gksphone qb.lua file
    local process = false
    if GetResourceState("qb-banking") == "started" then
        if exports['qb-banking']:AddMoney(job, amount) then
            process = true
        end
    elseif GetResourceState("Renewed-Banking") == "started" then
        if exports['Renewed-Banking']:addAccountMoney(job, amount) then
            process = true
        end
    end
    return process
end

Note:

  • The code samples provided are from esx.lua and qb.lua.

  • Replace placeholder logic with implementations based on your framework structure.

  • Ensure all data formats and player handling methods are compatible with your existing systems.

Last updated