esx_addoninventory
esx_addoninventory stores items for societies and properties in ESX Legacy. SQL setup, inventory object, exports, events and ox_inventory stash behavior.
esx_addoninventory is a server-only library resource that stores item counts outside of a player's own inventory. Use it for society storage rooms, property stashes and similar containers. Other resources such as esx_society and esx_property read and write these inventories.
Overview
| Resource | esx_addoninventory (version 1.0) |
| Side | Server only |
| Dependencies | esx_lib, es_extended, oxmysql |
| SQL file | esx_addoninventory.sql |
| Exports | GetSharedInventory, AddSharedInventory |
Like esx_addonaccount, inventories are either shared (shared = 1, one inventory without an owner) or personal (shared = 0, one inventory per player identifier, created when the player loads and stored as xPlayer.get('addonInventories')).
Installation
Import the SQL
Run esx_addoninventory.sql. It creates addon_inventory (definitions) and addon_inventory_items (item rows). The script uses plain CREATE TABLE, so it fails if the tables already exist. That is expected on an existing database.
Ensure the resource
ensure es_extended
ensure esx_addoninventory
ensure esx_societyDefine inventories
INSERT INTO `addon_inventory` (`name`, `label`, `shared`) VALUES
('society_mechanic', 'Mechanic', 1);Configuration
There is no config.lua. The addon_inventory table is the configuration.
| Column | Type | Description |
|---|---|---|
name | VARCHAR(60) | Unique inventory name, e.g. society_police |
label | VARCHAR(100) | Display label (used as stash label with ox_inventory) |
shared | INT | 1 = shared, 0 = one inventory per player |
Item labels come from the ESX items table and are loaded on startup.
ox_inventory mode
If ox_inventory is running (ESX sets Config.OxInventory automatically), the resource does not load its own inventories. Instead it registers each addon_inventory row as an ox_inventory stash:
| Stash setting | Value |
|---|---|
| Stash id | name |
| Label | label |
| Slots | 100 |
| Max weight | 200000 |
| Owner | true for shared = 0 (one stash per player), otherwise shared |
| Groups | Job name for names containing society: the text after society_ |
In this mode the exports and the getter events are not registered. Use exports.ox_inventory functions on the stash id instead.
Server exports
GetSharedInventory
exports.esx_addoninventory:GetSharedInventory(name)| Name | Type | Description |
|---|---|---|
name | string | Inventory name from addon_inventory |
Returns the inventory object or nil.
local inventory = exports.esx_addoninventory:GetSharedInventory('society_mechanic')
if inventory then
inventory.addItem('fixkit', 5)
endAddSharedInventory
exports.esx_addoninventory:AddSharedInventory(society)| Name | Type | Description |
|---|---|---|
society | table | { name = string, label = string } |
Inserts a shared inventory row and creates an empty inventory in memory. It does not check whether the inventory already exists: calling it twice replaces the in-memory inventory with an empty one (the database insert fails on the primary key). Check with GetSharedInventory first.
if not exports.esx_addoninventory:GetSharedInventory('society_bahama') then
exports.esx_addoninventory:AddSharedInventory({ name = 'society_bahama', label = 'Bahama Mamas' })
endInventory object
| Field / method | Description |
|---|---|
name, owner | Inventory name and owner identifier (nil when shared) |
items | Array of { name, count, label } |
getItem(name) | Returns the item entry. Creates a row with count 0 if it does not exist |
addItem(name, count) | Adds count and saves |
removeItem(name, count) | Removes count (only when count > 0) and saves |
setItem(name, count) | Sets the count and saves |
No validation
The inventory methods do not check item names, negative counts or whether enough items exist. removeItem happily goes below zero. Always validate on your side before you call them, especially when the request comes from a client.
RegisterNetEvent('myresource:takeFromStorage', function(itemName, count)
local xPlayer = ESX.GetPlayerFromId(source)
count = math.floor(tonumber(count) or 0)
if not xPlayer or xPlayer.job.name ~= 'mechanic' or count < 1 then return end
local inventory = exports.esx_addoninventory:GetSharedInventory('society_mechanic')
local item = inventory and inventory.getItem(itemName)
if not item or item.count < count or not xPlayer.canCarryItem(itemName, count) then return end
inventory.removeItem(itemName, count)
xPlayer.addInventoryItem(itemName, count)
end)Events
Both events are local server events (AddEventHandler). Clients cannot trigger them.
| Event | Arguments | Description |
|---|---|---|
esx_addoninventory:getInventory | name, owner, cb | cb(inventory) for a personal inventory |
esx_addoninventory:getSharedInventory | name, cb | cb(inventory) for a shared inventory |
TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayer.identifier, function(inventory)
if inventory then inventory.addItem('bread', 1) end
end)Integration tips
- Use the same
society_<job>name in esx_addonaccount, esx_addoninventory and esx_datastore so job resources find all three. - Shared inventories are also mirrored to
GlobalState.SharedInventories. - New
addon_inventoryrows are loaded without a restart when ESX firesesx:sqlCatalogReadyforaddon_inventoryoritems.
Common issues
No such export GetSharedInventory: ox_inventory is running, so the resource is in stash mode. Use ox_inventory stashes.- Item shows without a label: the item is missing from the
itemstable. - SQL import error "table already exists": the tables are already there. Skip the import.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_addonaccount
esx_addonaccount stores extra money accounts such as society funds in ESX Legacy. Covers SQL setup, the account object, exports, events and pitfalls.
esx_adminmenu
Complete guide to esx_adminmenu for ESX Legacy. Permissions, all config sections, commands, bans, admin action logs, Discord webhook and server exports.