GKSHOP
GKSPHONE V2Configuration

Custom inventory

Connect an unsupported inventory to GKSPHONE.

GKSPHONE already supports codem-inventory, qb-inventory, ox_inventory, core_inventory, qs-inventory and tgiann-inventory.

If you use one of these, leave the setting on auto or enter its exact resource name:

Config.Inventory = "auto"

Short aliases such as qb, ox, core and codem are not valid.

For any other inventory, use the editable custom adapter.

1. Enable it

In config/config.lua:

Config.Inventory = "custom"

custom tells GKSPHONE to load these files:

gksphone/client/inventory/custom.lua
gksphone/server/inventory/custom.lua

Both files are included automatically. You do not need to edit fxmanifest.lua.

2. Map the server exports

The server adapter needs eight functions:

FunctionPurpose
AddItemGive an item
RemoveItemRemove an item
CanCarryItemCheck inventory capacity
HasItemCheck item quantity
GetItemInfoReturn item label and image
SearchPhoneItemsReturn the player's phone items
SetItemDataWrite all phone metadata
UpdateItemDataUpdate one metadata value

If your inventory has ox-style exports, the adapter is mostly a direct mapping:

gksphone/server/inventory/custom.lua
if Config.Inventory ~= "custom" then return end

local Inventory = exports["my-inventory"]

function RemoveItem(source, itemName, amount)
    return Inventory:RemoveItem(source, itemName, amount or 1) == true
end

function AddItem(source, itemName, amount, metadata)
    return Inventory:AddItem(source, itemName, amount or 1, metadata) == true
end

function CanCarryItem(source, itemName, amount)
    return Inventory:CanCarryItem(source, itemName, amount or 1) == true
end

function HasItem(source, itemName, amount)
    local count = Inventory:Search(source, "count", itemName)
    return (tonumber(count) or 0) >= (amount or 1)
end

function GetItemInfo(itemName)
    local items = Inventory:Items()
    local item = items and items[itemName]
    if not item then return nil, nil end

    return item.label, item.image or (itemName .. ".png")
end

function SearchPhoneItems(source)
    for itemName in pairs(Config.ItemName) do
        local items = Inventory:Search(source, "slots", itemName) or {}
        if #items > 0 then return items end
    end

    return {}
end

function SetItemData(source, item, metadata)
    if not item or not item.slot then return false end

    Inventory:SetMetadata(source, item.slot, metadata)
    return true
end

function UpdateItemData(source, item, key, value)
    if not item or not item.slot then return false end

    local metadata = item.metadata or item.info or {}
    metadata[key] = value
    Inventory:SetMetadata(source, item.slot, metadata)
    return true
end

Replace my-inventory and any export names that differ. For example, an inventory may call Search something like GetItemsByName, or SetMetadata something like SetItemMetadata.

AddItem, RemoveItem, CanCarryItem, HasItem and metadata writes must return a real boolean. Return false when the inventory operation fails.

If the inventory has no capacity export, this fallback is acceptable:

function CanCarryItem(source, itemName, amount)
    return true
end

AddItem will make the final decision.

3. Register usable items

If the inventory uses the framework's usable-item system, add this to the server adapter:

for itemName in pairs(Config.ItemName) do
    RegisterUsableItem(itemName, function(source, item)
        TriggerClientEvent(
            "gksphone:client:usePhone",
            source,
            itemName,
            item
        )
    end)
end

If the inventory uses a client export from its item definition instead:

gksphone/client/inventory/custom.lua
exports("UsePhoneItem", function(item)
    TriggerEvent("gksphone:client:usePhone", item.name, item)
end)

Use one method, not both.

4. Connect inventory changes

GKSPHONE needs to know when a phone is added or removed. Forward your inventory's update event to the built-in custom refresh event:

gksphone/client/inventory/custom.lua
if Config.Inventory ~= "custom" then return end

RegisterNetEvent("my-inventory:client:changed", function()
    TriggerEvent("gksphone:client:inventoryChanged")
end)

Replace my-inventory:client:changed with the real event. If there are separate add and remove events, forward both.

The Job Center also needs a general item check:

function JobCenterHasItem(itemName)
    local count = exports["my-inventory"]:Search("count", itemName)
    return (tonumber(count) or 0) > 0
end

This function checks any Job Center item. It does not use phoneID.

Unique phones

When Config.MetaItem = true, each returned phone item must contain:

{
    name = "phone",
    slot = 1,
    metadata = {
        phoneID = "GKS202501HM1D",
        eSIMNumber = "28946041",
        phoneLang = "en"
    }
}

info may be used instead of metadata. Phone items must be unique and non-stacking. See Unique phones.

Item images

For restaurant item images, add the custom path in config.lua:

Config.Restaurant.ItemImagePath["custom"] =
    "nui://my-inventory/html/images/"

Use false if the inventory does not provide images.

Quick test

  • Use a phone item.
  • Add and remove it while the phone is open.
  • Check a non-phone Job Center item.
  • With Config.MetaItem = true, restart and confirm the same phone keeps its phoneID.
  • Test a restaurant delivery with a full inventory.

If something fails, compare your adapter with the built-in files in gksphone/client/inventory/ and gksphone/server/inventory/.

On this page