Custom Framework - Server

Make sure to check the qb.lua and esx.lua files for examples on how to implement the phone for your framework. They are always up to date with the latest changes.

Framework check

At the top of the file, add a check for Config.Framework. If it's not set to your framework, return to prevent it from loading.

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

Framework functions

You need to implement the following functions for the phone to work with your framework.

GetIdentifier

Get a player's identifier. If you use multicharacter, make sure to return the identifier of the current character.

---@param source number
---@return string | nil
function GetIdentifier(source)
    -- This is an example from the lb-phone esx.lua file
    return ESX.GetPlayerFromId(source)?.identifier
end

HasPhoneItem

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

---@param source number
---@param number string
---@return boolean
function HasPhoneItem(source, number)
    if not Config.Item.Require then
        return true
    end
 
    if Config.Item.Unique then
        -- HasPhoneNumber is a function defined in the unique phones file
        return HasPhoneNumber(source, number)
    end
 
	-- Implement your own check here
    return true
end

CreateUsableItem

Optional. Used to create a usable item for the phone. Callback the source that used the item.

---@param item string
---@param cb function
function CreateUsableItem(item, cb)
    -- This is an example from the lb-phone esx.lua file
    ESX.RegisterUsableItem(item, cb)
end

GetCharacterName

Get a player's character name.

---@param source number
---@return string firstname
---@return string lastname
function GetCharacterName(source)
    -- This is an example from the lb-phone qb.lua file
    local ch = QB.Functions.GetPlayer(source).PlayerData.charinfo
 
    return ch.firstname, ch.lastname
end

GetBalance

Get the bank balance of a player

---@param source any
---@return integer
function GetBalance(source)
    return 0
end

AddMoney

Add money to a player's bank account

---@param source any
---@param amount integer
---@return boolean success
function AddMoney(source, amount)
    return true
end

AddMoneyOffline

Add money to a player's bank account via their identifier

---@param identifier string
---@param amount number
---@return boolean
function AddMoneyOffline(identifier, amount)
    if amount <= 0 then
        return false
    end
 
    amount = math.floor(amount + 0.5)
 
    return MySQL.update.await("UPDATE users SET accounts = JSON_SET(accounts, '$.bank', JSON_EXTRACT(accounts, '$.bank') + ?) WHERE identifier = ?", { amount, identifier }) > 0
end

RemoveMoney

Remove money from a player's bank account

---@param source any
---@param amount integer
---@return boolean success
function RemoveMoney(source, amount)
    return true
end

GetPlayerVehicles

Get a list of a player's vehicles

---@param source number
---@return VehicleData[] vehicles An array of vehicles that the player owns
function GetPlayerVehicles(source)
    return {}
end

VehicleData:

  • plate: string
  • type: "car" | "boat" | "plane" | "bike" | "truck"
  • location: string - The location of the vehicle (garage name), set to "out" if the vehicle is out
  • model: number - The vehicle model
  • statistics?: VehicleStatistics
    • engine?: number - The engine health, 0-100
    • body?: number - The body health, 0-100
    • fuel?: number - The fuel level, 0-100
  • impounded: boolean - Whether the vehicle is impounded or not
  • impoundReason? - optional
    • reason?: string
    • retrievable?: string
    • price?: number
    • impounder?: string - The name of the person that impounded the vehicle

GetVehicle

Get a player's vehicle by plate

---@param source number
---@param plate string
---@return Vehicle?
function GetVehicle(source, plate)
    return {}
end

Vehicle:

  • model: number - The vehicle model
  • any other data you want (this will be sent to CreateFrameworkVehicle & ApplyVehicleMods)

IsAdmin

Check if a player is admin, this will allow them to delete posts etc.

---@param source number
function IsAdmin(source)
    return IsPlayerAceAllowed(source, "command.lbphone_admin") == 1
end

GetJob

Get the player's job

---@param source number
---@return string job
function GetJob(source)
    -- This is an example from the lb-phone qb.lua file
    return QB.Functions.GetPlayer(source)?.PlayerData.job.name or "unemployed"
end

GetEmployees

Get an array of player sources with a specific job

---@param job string
---@return number[] employees
function GetEmployees(job)
    -- This is an example from the lb-phone qb.lua file
    local employees = {}
    local players = QB.Functions.GetQBPlayers()
 
    for _, v in pairs(players) do
        if v?.PlayerData.job.name == job and v.PlayerData.job.onduty then
            employees[#employees+1] = v.PlayerData.source
        end
    end
 
    return employees
end

GetAllEmployees

Get all employees (even offline) with a specific job

---@param job string
---@return { firstname: string, lastname: string, grade: string, number: string }[] employees
function GetAllEmployees(job)
    -- This is an example from the lb-phone esx.lua file
    local numberTable = Config.Item.Unique and "phone_last_phone" or "phone_phones"
 
    return MySQL.query.await(([[
        SELECT
            u.firstname, u.lastname,
            u.job_grade AS grade,
            p.phone_number AS `number`,
            j.label AS gradeLabel
        FROM users u
        LEFT JOIN %s p ON u.identifier = p.id COLLATE UTF8MB4_GENERAL_CI
        JOIN job_grades j ON u.job = j.job_name AND u.job_grade = j.grade
        WHERE u.job = ?
    ]]):format(numberTable), { job })
end

RefreshCompanies

Refresh Config.Companies.Services to show if they are open or not

function RefreshCompanies()
    for i = 1, #Config.Companies.Services do
        local jobData = Config.Companies.Services[i]
 
        -- implement your own check here
        jobData.open = true
    end
end