InnocentRP

Custom Framework Integration

This is a guide designed to lead you through the successful framework integration process of the script. Please follow the steps and do not deviate from the instructions.

Custom

Don't run QBCore, Qbox, or ESX? inn-laundry never calls a framework's own API directly — every part of the script only ever calls six functions on a Framework table, defined once per framework under bridge/framework/. Implementing a custom framework means filling in those six functions yourself.

Note

Most frameworks expose their functionality via exports['your-framework']:FunctionName(...) — Qbox (qbx_core) works exactly this way (see the reference implementation below). Some, like QBCore and ESX, instead expose a single "core object" via one export (GetCoreObject()/getSharedObject()) and put everything else as methods on that object — check your framework's own docs to see which pattern it uses.

Open the custom framework template

Open inn-laundry/bridge/framework/custom.lua. It already contains every function signature you need, each currently just raising an error so you can't accidentally ship it unfinished.

Implement each function

FunctionReturnsPurpose
Framework.GetPlayer(src)opaque player object, or nil if offlineLooked up once and reused — the shape of this object is entirely up to you, nothing outside your own bridge file reads it directly.
Framework.GetIdentifier(src)string identifier, or nilStored as the owner on zones/machines — must be stable across sessions (e.g. a license or citizenid), not the temporary server id.
Framework.GetJob(src){ name, grade, isboss }, or nilisboss marks the player as the automatic owner of a job-locked zone on that job.
Framework.AddMoney(src, amount, reason, moneyType)boolean successmoneyType is 'cash' or 'bank', falling back to Config.Payout.moneyType when not given.
Framework.RemoveMoney(src, amount, reason, moneyType)boolean successMust fail (return false) and remove nothing if the player doesn't have enough.
Framework.GetPlayersOnJob(job)number[] of source idsUsed to find every online player to notify for a job (e.g. police during a raid).
Note

Framework.HasPermission(src) also exists on the Framework table, but it's implemented once in bridge/framework/init.lua using FiveM's native ace permissions (IsPlayerAceAllowed) — it's the same for every framework, so you don't need to (and shouldn't) implement it yourself.

Point the config at your bridge

Open config/config.lua and set:

lua
Config.Framework = 'custom'

Reference implementation

Every function above is implemented for Qbox in bridge/framework/qbox.lua — a clean example of the pure-export pattern, since qbx_core exposes everything as a direct export call with no core object to fetch first:

lua
function Framework.GetPlayer(src)
    return exports.qbx_core:GetPlayer(src)
end

function Framework.GetIdentifier(src)
    local Player = exports.qbx_core:GetPlayer(src)
    return Player and Player.PlayerData.citizenid or nil
end

function Framework.GetJob(src)
    local Player = exports.qbx_core:GetPlayer(src)
    if not Player then return nil end

    return {
        name = Player.PlayerData.job.name,
        grade = Player.PlayerData.job.grade.level,
        isboss = Player.PlayerData.job.isboss or false,
    }
end

function Framework.AddMoney(src, amount, reason, moneyType)
    return exports.qbx_core:AddMoney(src, moneyType or Config.Payout.moneyType, amount, reason or 'inn-laundry')
end

If your framework instead uses the "one core object" pattern (QBCore and ESX both do), fetch it once at the top of your file and call its methods from there — bridge/framework/qb.lua:

lua
local QBCore = exports['qb-core']:GetCoreObject()

function Framework.GetPlayer(src)
    return QBCore.Functions.GetPlayer(src)
end

function Framework.AddMoney(src, amount, reason, moneyType)
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return false end

    return Player.Functions.AddMoney(moneyType or Config.Payout.moneyType, amount, reason or 'inn-laundry')
end
Warning

ESX has no built-in "boss" concept the way QBCore/Qbox do. If your custom framework is ESX-like, don't hardcode isboss = falseinn-laundry falls back to Config.ESXBossGrades (in config/config.lua) to decide the automatic owner grade per job in that case. Match that same pattern in your custom bridge, or every job-locked zone will start with no automatic owner at all.

We use a few essential cookies to keep your basket and sign-in working across the site. Privacy Policy