Custom framework

Learn how to add custom frameworks.


If you use a custom framework or want to add a framework that's not supported. You can add it to your project by following these steps.

  1. Create a new folder in the frameworks directory in the resource, named after your framework.

  2. Create a client.lua and server.lua file in the folder. Should look like this:

    ├── frameworks
    │   └── myframework
    │       ├── client.lua
    │       └── server.lua
  3. Add the following code to the client.lua file:

    /frameworks/myframework/client.lua
    AddFramework {
        'myframework',
        {
            benchOptions = {
                useCurrentWeapon = true, -- Use the current weapon the player is holding
                showAllWeapons = false, -- Show all weapons in the bench
                manualApplyMods = true -- Apply mods manually. If false, mods will be applied automatically
            },
            --[[
                inventory = Get the inventory to use for the framework.
            ]]
            -- inventory = useInventory('ox_inventory', { framework = 'esx' }),
            --[[
                init - Initialize the framework
     
                @param callback
            ]]
            init = function()
            end,
            --[[
                getCurrentWeapon - Get the current weapon the player is holding
     
                @param weaponHash
                @return nil | table
            ]]
            getCurrentWeapon = function(weaponHash)
                if not framework.inventory?.getCurrentWeapon then
                    return {}
                end
     
                return framework.inventory.getCurrentWeapon()
            end,
            --[[
                notification - Send a notification to the player
     
                @param message
            ]]
            notification = function(message)
            end,
        }
    }
  4. Add the following code to the server.lua file:

    /frameworks/myframework/server.lua
    AddFramework {
        'myframework',
        {
            benchOptions = {
                type = BenchTypes.ITEM, -- BenchTypes.ITEM | BenchTypes.PURCHASE
            },
            --[[
                items - Get the items to use for the framework.
     
                Use either
                    - the types specified in config.lua
                    - the nameGXT value which you can find for the components and tints in src/weapons.json
                to set the items
     
                These items will be overrided by some inventories, like ox_inventory
            ]]
            items = {
                components = {
                    default = 'weapon_component',
     
                    clip = 'clip_attachment',
                    suppressor = 'suppressor_attachment',
                    flashlight = 'flashlight_attachment',
                    compensator = 'compensator_attachment',
                    grip = 'grip_attachment',
                    small_scope = 'smallscope_attachment',
                    scope = 'medscope_attachment',
                    large_scope = 'largescope_attachment',
                    holo_scope = 'holoscope_attachment',
                    thermal_scope = 'thermalscope_attachment',
                    night_vision_scope = 'nvscope_attachment',
                    mounted_scope = 'medscope_attachment',
                    advanced_scope = 'advscope_attachment',
                    shell = 'shell_attachment',
     
                    ['WCT_VAR_GOLD'] = 'luxuryfinish_attachment',
                    ['WCT_CAMO_1'] = 'digicamo_attachment',
                    ['WCT_CAMO_2'] = 'brushcamo_attachment',
                    ['WCT_CAMO_3'] = 'woodcamo_attachment',
                    ['WCT_CAMO_4'] = 'skullcamo_attachment',
                    ['WCT_CAMO_5'] = 'sessantacamo_attachment',
                    ['WCT_CAMO_6'] = 'perseuscamo_attachment',
                    ['WCT_CAMO_7'] = 'leopardcamo_attachment',
                    ['WCT_CAMO_8'] = 'zebracamo_attachment',
                    ['WCT_CAMO_9'] = 'geocamo_attachment',
                    ['WCT_CAMO_10'] = 'boomcamo_attachment',
                    ['WCT_CAMO_IND'] = 'patriotcamo_attachment',
     
                    ['WCT_MUZZ1'] = 'flat_muzzle_brake',
                    ['WCT_MUZZ2'] = 'tactical_muzzle_brake',
                    ['WCT_MUZZ3'] = 'fat_end_muzzle_brake',
                    ['WCT_MUZZ4'] = 'precision_muzzle_brake',
                    ['WCT_MUZZ5'] = 'heavy_duty_muzzle_brake',
                    ['WCT_MUZZ6'] = 'slanted_muzzle_brake',
                    ['WCT_MUZZ7'] = 'split_end_muzzle_brake',
                    ['WCT_MUZZ8'] = 'squared_muzzle_brake',
                    ['WCT_MUZZ9'] = 'bellend_muzzle_brake',
                },
                tints = {
                    default = 'tint_component',
     
                    ['WM_TINT1'] = 'weapontint_1',
                    ['WM_TINT2'] = 'weapontint_2',
                    ['WM_TINT3'] = 'weapontint_3',
                    ['WM_TINT4'] = 'weapontint_4',
                    ['WM_TINT5'] = 'weapontint_5',
                    ['WM_TINT6'] = 'weapontint_6',
                    ['WM_TINT7'] = 'weapontint_7',
     
                    ['WCT_TINT_0'] = 'weapontint_mk2_0',
                    ['WCT_TINT_1'] = 'weapontint_mk2_1',
                    ['WCT_TINT_2'] = 'weapontint_mk2_2',
                    ['WCT_TINT_3'] = 'weapontint_mk2_3',
                    ['WCT_TINT_4'] = 'weapontint_mk2_4',
                    ['WCT_TINT_5'] = 'weapontint_mk2_5',
                    ['WCT_TINT_6'] = 'weapontint_mk2_6',
                    ['WCT_TINT_7'] = 'weapontint_mk2_7',
                    ['WCT_TINT_8'] = 'weapontint_mk2_8',
                    ['WCT_TINT_9'] = 'weapontint_mk2_9',
                    ['WCT_TINT_10'] = 'weapontint_mk2_10',
                    ['WCT_TINT_11'] = 'weapontint_mk2_11',
                    ['WCT_TINT_12'] = 'weapontint_mk2_12',
                    ['WCT_TINT_13'] = 'weapontint_mk2_13',
                    ['WCT_TINT_14'] = 'weapontint_mk2_14',
                    ['WCT_TINT_15'] = 'weapontint_mk2_15',
                    ['WCT_TINT_16'] = 'weapontint_mk2_16',
                    ['WCT_TINT_17'] = 'weapontint_mk2_17',
                    ['WCT_TINT_18'] = 'weapontint_mk2_18',
                    ['WCT_TINT_19'] = 'weapontint_mk2_19',
                    ['WCT_TINT_20'] = 'weapontint_mk2_20',
                    ['WCT_TINT_21'] = 'weapontint_mk2_21',
                    ['WCT_TINT_22'] = 'weapontint_mk2_22',
                    ['WCT_TINT_23'] = 'weapontint_mk2_23',
                    ['WCT_TINT_24'] = 'weapontint_mk2_24',
                    ['WCT_TINT_25'] = 'weapontint_mk2_25',
                    ['WCT_TINT_26'] = 'weapontint_mk2_26',
                    ['WCT_TINT_27'] = 'weapontint_mk2_27',
                    ['WCT_TINT_28'] = 'weapontint_mk2_28',
                    ['WCT_TINT_29'] = 'weapontint_mk2_29',
                    ['WCT_TINT_30'] = 'weapontint_mk2_30',
                    ['WCT_TINT_31'] = 'weapontint_mk2_31',
                }
            },
            --[[
                prices - Get the prices to use for the framework.
     
                Use either
                    - the types specified in config.lua
                    - the nameGXT value which you can find for the components and tints in src/weapons.json
                to set the prices
            ]]
            prices = {
                components = {
                    default = 100,
     
                    clip = 300,
                    suppressor = 400,
                    flashlight = 50,
                    compensator = 200,
                    grip = 300,
                    small_scope = 250,
                    scope = 300,
                    large_scope = 350,
                    holo_scope = 250,
                    thermal_scope = 250,
                    night_vision_scope = 400,
                    mounted_scope = 250,
                    advanced_scope = 400,
                    shell = 150,
     
                    ['WCT_VAR_GOLD'] = 100,
                    ['WCT_CAMO_1'] = 100,
                    ['WCT_CAMO_2'] = 100,
                    ['WCT_CAMO_3'] = 100,
                    ['WCT_CAMO_4'] = 100,
                    ['WCT_CAMO_5'] = 100,
                    ['WCT_CAMO_6'] = 100,
                    ['WCT_CAMO_7'] = 100,
                    ['WCT_CAMO_8'] = 100,
                    ['WCT_CAMO_9'] = 100,
                    ['WCT_CAMO_10'] = 100,
                    ['WCT_CAMO_IND'] = 100,
     
                    ['WCT_MUZZ1'] = 100,
                    ['WCT_MUZZ2'] = 100,
                    ['WCT_MUZZ3'] = 100,
                    ['WCT_MUZZ4'] = 100,
                    ['WCT_MUZZ5'] = 100,
                    ['WCT_MUZZ6'] = 100,
                    ['WCT_MUZZ7'] = 100,
                    ['WCT_MUZZ8'] = 100,
                    ['WCT_MUZZ9'] = 100,
                },
                tints = {
                    default = 100,
     
                    ['WM_TINT1'] = 100,
                    ['WM_TINT2'] = 100,
                    ['WM_TINT3'] = 100,
                    ['WM_TINT4'] = 100,
                    ['WM_TINT5'] = 100,
                    ['WM_TINT6'] = 100,
                    ['WM_TINT7'] = 100,
     
                    ['WCT_TINT_0'] = 100,
                    ['WCT_TINT_1'] = 100,
                    ['WCT_TINT_2'] = 100,
                    ['WCT_TINT_3'] = 100,
                    ['WCT_TINT_4'] = 100,
                    ['WCT_TINT_5'] = 100,
                    ['WCT_TINT_6'] = 100,
                    ['WCT_TINT_7'] = 100,
                    ['WCT_TINT_8'] = 100,
                    ['WCT_TINT_9'] = 100,
                    ['WCT_TINT_10'] = 100,
                    ['WCT_TINT_11'] = 100,
                    ['WCT_TINT_12'] = 100,
                    ['WCT_TINT_13'] = 100,
                    ['WCT_TINT_14'] = 100,
                    ['WCT_TINT_15'] = 100,
                    ['WCT_TINT_16'] = 100,
                    ['WCT_TINT_17'] = 100,
                    ['WCT_TINT_18'] = 100,
                    ['WCT_TINT_19'] = 100,
                    ['WCT_TINT_20'] = 100,
                    ['WCT_TINT_21'] = 100,
                    ['WCT_TINT_22'] = 100,
                    ['WCT_TINT_23'] = 100,
                    ['WCT_TINT_24'] = 100,
                    ['WCT_TINT_25'] = 100,
                    ['WCT_TINT_26'] = 100,
                    ['WCT_TINT_27'] = 100,
                    ['WCT_TINT_28'] = 100,
                    ['WCT_TINT_29'] = 100,
                    ['WCT_TINT_30'] = 100,
                    ['WCT_TINT_31'] = 100,
                }
            },
            --[[
                inventory - Get the inventory to use for the framework.
            ]]
            inventory = useInventory('ox_inventory', { framework = 'esx' }),
            --[[
                init - Initialize the framework.
            ]]
            init = function()
            end,
            --[[
                getPlayerIdentifier - Get the player's unique identifier.
     
                @param src number
                @return string
            ]]
            getPlayerIdentifier = function(src)
            end,
            --[[
                getAccessIdentifiers - Get the access identifiers, used for checking if a player has access to a bench.
     
                @return table { [string] = string }
            ]]
            getAccessIdentifiers = function()
                return {}
            end,
            --[[
                getPlayerAccess - Get the player's access identifiers.
     
                @param src number
                @return table { [number] = string }
            ]]
            getPlayerAccess = function(src)
                return {}
            end,
            --[[
                canUseEditor - Check if a player can use the editor.
     
                @param src number
                @param identifier string
                @return boolean
            ]]
            canUseEditor = function(src, identifier)
                return IsPlayerAceAllowed(src, 'weaponmodbench.editor') == 1 or IsPlayerAceAllowed(src, 'command.editor') == 1
            end,
            --[[
                onUseBench - Called when a player uses a weapon bench to determine if they have access.
     
                @param src number
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onUseBench = function(src, bench)
                return {
                    success = true
                }
            end,
            --[[
                onBuyComponent - Called when a player buys a component for a weapon.
     
                @param src number
                @param weapon table { hashKey = string, metadata = table }
                @param component table { hashKey = string, price = number, item = string }
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onBuyComponent = function(src, weapon, component, bench)
                if not framework.inventory?.buyComponent then
                    return {
                        success = true
                    }
                else
                    return framework.inventory.buyComponent(src, weapon, component)
                end
            end,
            --[[
                onEquipComponent - Called when a player equips a component to a weapon.
     
                @param src number
                @param weapon table { hashKey = string, metadata = table }
                @param component table { hashKey = string, price = number, item = string }
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onEquipComponent = function(src, weapon, component, bench)
                if not framework.inventory?.equipComponent then
                    return {
                        success = true
                    }
                else
                    return framework.inventory.equipComponent(src, weapon, component)
                end
            end,
            --[[
                onUnequipComponent - Called when a player equips a component to a weapon.
     
                @param src number
                @param weapon table { hashKey = string, metadata = table }
                @param component table { hashKey = string, price = number, item = string }
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onUnequipComponent = function(src, weapon, component, bench)
                if not framework.inventory?.unequipComponent then
                    return {
                        success = true
                    }
                else
                    return framework.inventory.unequipComponent(src, weapon, component)
                end
            end,
            --[[
                onBuyTint - Called when a player buys a tint.
     
                @param src number
                @param weapon table { hashKey = string, metadata = table }
                @param tint table { id = number, price = number, item = string }
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onBuyTint = function(src, weapon, tint, bench)
                if not framework.inventory?.buyTint then
                    return {
                        success = true
                    }
                else
                    return framework.inventory.buyTint(src, weapon, tint)
                end
            end,
            --[[
                onApplyTint - Called when a player applies a tint to a weapon.
     
                @param src number
                @param weapon table { hashKey = string, metadata = table }
                @param tint table { id = number, price = number, item = string }
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onApplyTint = function(src, weapon, tint, bench)
                if not framework.inventory?.applyTint then
                    return {
                        success = true
                    }
                else
                    return framework.inventory.applyTint(src, weapon, tint)
                end
            end,
            --[[
                onRemoveTint - Called when a player removes a tint from a weapon.
     
                @param src number
                @param weapon table { hashKey = string, metadata = table }
                @param tint table { id = number, price = number, item = string }
                @param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                @return table { success = boolean, message = string }
            ]]
            onRemoveTint = function(src, weapon, tint, bench)
                if not framework.inventory?.removeTint then
                    return {
                        success = true
                    }
                else
                    return framework.inventory.removeTint(src, weapon, tint)
                end
            end,
            --[[
                getWeapons - Get the player's weapons. This is used when BenchOptions.useCurrentWeapon is set to false to show all the player's weapons.
     
                @param src number
                @return table { [number] = { data = { itemId = string, name = string }, label = string, modelHash = string } }
            ]]
            getWeapons = function(src)
                if not framework.inventory?.getWeapons then
                    return {}
                else
                    return framework.inventory.getWeapons(src)
                end
            end,
            --[[
                getWeapon - Get a player's weapon.
     
                @param src number
                @param hash string
                @param metadata table
                @param weapon table { components = table, tints = table }
                @return nil | table { components = table { [number] = { hash = string, isEquiped = boolean } }, tints = table { [number] = { id = number, isEquiped = boolean } } }
            ]]
            getWeapon = function(src, hash, metadata, weapon)
                if not framework.inventory?.getWeapon then
                    return {
                        components = {},
                        tints = {}
                    }
                else
                    return framework.inventory?.getWeapon(src, hash, metadata, weapon)
                end
            end,
            --[[
                getWeaponMods - Get the weapon mods for a player. This is used if benchOptions.manualApplyMods is set to false in the client.lua.
     
                @param src number
                @param hash string
                @param metadata table
            ]]
            getWeaponMods = function(src, hash, metadata)
                return {
                    components = {},
                    tint = nil
                }
            end,
            --[[
                doesItemExist - Check if an item exists.
     
                @param name string
                @return boolean
            ]]
            doesItemExist = function(name)
                if not framework.inventory?.doesItemExist then
                    return true
                else
                    return framework.inventory.doesItemExist(name)
                end
            end,
            database = {
                init = function()
                    exports.oxmysql:transaction_async({
                        [[
                            CREATE TABLE IF NOT EXISTS `nxtgn_weap_benches` (
                                `uuid` uuid NOT NULL DEFAULT uuid(),
                                `title` varchar(50) NOT NULL,
                                `access` varchar(50) DEFAULT NULL,
                                `loc_x` float NOT NULL DEFAULT 0,
                                `loc_y` float NOT NULL DEFAULT 0,
                                `loc_z` float NOT NULL DEFAULT 0,
                                `loc_h` float NOT NULL DEFAULT 0,
                                `created_by` varchar(255) DEFAULT NULL,
                                `created_at` date NOT NULL DEFAULT current_timestamp(),
                                PRIMARY KEY (`uuid`)
                            )
                        ]]
                    })
                end,
                --[[
                    createBench - Create a new weapon bench.
     
                    @param data table { title = string, access = string, location = { x = number, y = number, z = number, h = number }, identifier = string }
                    @return string | boolean
                ]]
                createBench = function(data)
                    local uuid = Math:generateUUID()
     
                    local res = exports.oxmysql:query_async([[
                        INSERT INTO `nxtgn_weap_benches` (`uuid`, `title`, `access`, `loc_x`, `loc_y`, `loc_z`, `loc_h`, `created_by`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
                    ]], {
                        uuid,
                        data.title,
                        data.access,
                        data.location.x,
                        data.location.y,
                        data.location.z,
                        data.location.h,
                        data.identifier
                    })
     
                    if res.affectedRows == 0 then
                        return nil
                    end
     
                    return uuid
                end,
                --[[
                    updateBench - Update an existing weapon bench.
     
                    @param data table { title = string, access = string, location = { x = number, y = number, z = number, h = number }, uuid = string }
                    @return boolean
                ]]
                updateBench = function(data)
                    local res = exports.oxmysql:query_async([[
                        UPDATE `nxtgn_weap_benches` SET `title` = ?, `access` = ?, `loc_x` = ?, `loc_y` = ?, `loc_z` = ?, `loc_h` = ? WHERE `uuid` = ?
                    ]], {
                        data.title,
                        data.access,
                        data.location.x,
                        data.location.y,
                        data.location.z,
                        data.location.h,
                        data.uuid
                    })
     
                    if res.changedRows == 0 then
                        return false
                    end
     
                    return true
                end,
                --[[
                    removeBench - Remove a weapon bench.
     
                    @param data table { uuid = string }
                    @return boolean
                ]]
                removeBench = function(data)
                    local res = exports.oxmysql:query_async([[
                        DELETE FROM `nxtgn_weap_benches` WHERE `uuid` = ?
                    ]], { data.uuid })
     
                    if res.affectedRows == 0 then
                        return false
                    end
     
                    return true
                end,
                --[[
                    fetchBenches - Fetch benches.
     
                    @param data table { columnFilters = table { [string] = table { string }, orderColumn = string, orderDirection = string, count = number, offset = number }
                    @return nil | table { rows = table { [number] = table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }, pageCount = number }
                ]]
                fetchBenches = function(data)
                    local columnFiltersTable = {}
                    local i = 0
     
                    for k,v in pairs(data.columnFilters) do
                        if i == 0 then
                            table.insert(columnFiltersTable, "WHERE")
                        elseif i > 0 then
                            table.insert(columnFiltersTable, "AND")
                        end
     
                        if type(v) == 'string' then
                            table.insert(columnFiltersTable, "`" .. k .. "` LIKE '" .. v .. "%'")
                        else
                            table.insert(columnFiltersTable, "`" .. k .. "` IN ('" .. table.concat(v, "','") .. "')")
                        end
     
                        i = i + 1
                    end
     
                    local columnFilters = table.concat(columnFiltersTable, ' ')
     
                    local countRow = exports.oxmysql:single_async(([[
                        SELECT COUNT(*) AS `count`
                        FROM `nxtgn_weap_benches`
                        %s
                    ]]):format(columnFilters))
     
                    if not countRow or countRow.count == nil then
                        return nil
                    end
     
                    local res = exports.oxmysql:query_async(([[
                        SELECT
                            `uuid`,
                            `title`,
                            `access`,
                            `loc_x` AS `locationX`,
                            `loc_y` AS `locationY`,
                            `loc_z` AS `locationZ`,
                            `loc_h` AS `locationH`,
                            `created_by` AS `createdBy`,
                            `created_at` AS `createdAt`
                        FROM `nxtgn_weap_benches`
                        %s
                        ORDER BY `%s` %s
                        LIMIT %s OFFSET %s
                    ]]):format(
                        columnFilters,
                        data.orderColumn,
                        data.orderDirection,
                        data.count,
                        data.offset
                    ))
     
                    if not res then
                        return nil
                    end
     
                    local benches = {}
     
                    local accessIdentifiers = framework.getAccessIdentifiers()
     
                    for _, bench in ipairs(res) do
                        table.insert(benches, {
                            uuid = bench.uuid,
                            title = bench.title,
                            access = {
                                name = bench.access,
                                label = accessIdentifiers[bench.access] or bench.access,
                            },
                            location = {
                                x = bench.locationX,
                                y = bench.locationY,
                                z = bench.locationZ,
                                h = bench.locationH,
                            },
                            createdBy = bench.createdBy,
                            createdAt = bench.createdAt,
                        })
                    end
     
                    return {
                        rows = benches,
                        pageCount = math.ceil(countRow.count / data.count),
                    }
                end,
                --[[
                    fetchBench - Fetch a bench.
     
                    @param data table { uuid = string }
                    @return table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                ]]
                fetchAllBenches = function()
                    local benches = {}
     
                    local res = exports.oxmysql:query_async([[
                        SELECT
                            `uuid`,
                            `title`,
                            `access`,
                            `loc_x` AS `locationX`,
                            `loc_y` AS `locationY`,
                            `loc_z` AS `locationZ`,
                            `loc_h` AS `locationH`,
                            `created_by` AS `createdBy`,
                            `created_at` AS `createdAt`
                        FROM `nxtgn_weap_benches`
                    ]])
     
                    if not res then
                        return nil
                    end
     
                    local accessIdentifiers = framework.getAccessIdentifiers()
     
                    for _, bench in ipairs(res) do
                        table.insert(benches, {
                            uuid = bench.uuid,
                            title = bench.title,
                            access = {
                                name = bench.access,
                                label = accessIdentifiers[bench.access] or bench.access,
                            },
                            location = {
                                x = bench.locationX,
                                y = bench.locationY,
                                z = bench.locationZ,
                                h = bench.locationH,
                            },
                            createdBy = bench.createdBy,
                            createdAt = bench.createdAt,
                        })
                    end
     
                    return benches
                end,
                --[[
                    fetchBench - Fetch a bench.
     
                    @param data table { uuid = string }
                    @return nil | table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
                ]]
                fetchBench = function(data)
                    local res = exports.oxmysql:single_async([[
                        SELECT
                            `uuid`,
                            `title`,
                            `access`,
                            `loc_x` AS `locationX`,
                            `loc_y` AS `locationY`,
                            `loc_z` AS `locationZ`,
                            `loc_h` AS `locationH`,
                            `created_by` AS `createdBy`,
                            `created_at` AS `createdAt`
                        FROM `nxtgn_weap_benches` WHERE `uuid` = ?
                    ]], {
                        data.uuid
                    })
     
                    if not res then
                        return nil
                    end
     
                    local accessIdentifiers = framework.getAccessIdentifiers()
     
                    return {
                        uuid = res.uuid,
                        title = res.title,
                        access = {
                            name = res.access,
                            label = accessIdentifiers[res.access] or res.access,
                        },
                        location = {
                            x = res.locationX,
                            y = res.locationY,
                            z = res.locationZ,
                            h = res.locationH,
                        },
                        createdBy = res.createdBy,
                        createdAt = res.createdAt,
                    }
                end
            }
        }
    }
  5. Replace myframework with the name of your framework in the code.

  6. Write the code for your framework in the client.lua and server.lua files.

    • Make sure that the functions returns the correct values.
    • If you want to use an inventory, you can use the useInventory function.
    • If you want to use a database, you can use the oxmysql exports.
    • If your framework are similar to an existing framework, you can use the existing framework as a base.
  7. Change the Framework in the config.lua file to the name of your framework.

  8. Restart the resource.