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.luaBoth files are included automatically. You do not need to edit
fxmanifest.lua.
2. Map the server exports
The server adapter needs eight functions:
| Function | Purpose |
|---|---|
AddItem | Give an item |
RemoveItem | Remove an item |
CanCarryItem | Check inventory capacity |
HasItem | Check item quantity |
GetItemInfo | Return item label and image |
SearchPhoneItems | Return the player's phone items |
SetItemData | Write all phone metadata |
UpdateItemData | Update one metadata value |
If your inventory has ox-style exports, the adapter is mostly a direct mapping:
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
endReplace 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
endAddItem 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)
endIf the inventory uses a client export from its item definition instead:
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:
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
endThis 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 itsphoneID. - 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/.

