Merge pull request #1862 from rwixy/ox-inv

refactor(oxinventory): improve inventory module initialization and cleanup
This commit is contained in:
_Not_
2026-08-06 13:27:35 -05:00
committed by GitHub
@@ -1,11 +1,107 @@
local Inventory local OxInventory
if Config.CustomInventory ~= "ox" then return end if Config.CustomInventory ~= "ox" then
return
end
local requiredMethods = {
"GetItem",
"AddItem",
"RemoveItem",
"SetItem",
"CanCarryItem",
"CanSwapItem",
"SetMaxWeight",
}
---Stores the reference to the internal ox_inventory module.
---@param module table
---@return boolean
---@return string? error
local function setOxInventory(module)
if type(module) ~= "table" then
return false, "module is not a table"
end
for i = 1, #requiredMethods do
local method = requiredMethods[i]
if type(module[method]) ~= "function" then
return false, ("missing method %s"):format(method)
end
end
OxInventory = module
return true
end
---Returns the internal ox_inventory module.
---If es_extended missed the load event, it will attempt to retrieve it via the export.
---@return table
local function getOxInventory()
if OxInventory then
return OxInventory
end
local state = GetResourceState("ox_inventory")
if state ~= "started" then
error(
("[es_extended] ox_inventory not started; current status: %s")
:format(tostring(state)),
2
)
end
local success, module = pcall(function()
return exports.ox_inventory:Inventory()
end)
if not success then
error(
("[es_extended] Failed to execute exports.ox_inventory:Inventory(): %s")
:format(tostring(module)),
2
)
end
local ok, err = setOxInventory(module)
if not ok then
error(
("[es_extended] The Inventory export from ox_inventory returned an invalid module: %s")
:format(err),
2
)
end
return OxInventory
end
-- Standard method used when ox_inventory finishes loading..
AddEventHandler("ox_inventory:loadInventory", function(module) AddEventHandler("ox_inventory:loadInventory", function(module)
Inventory = module local ok, err = setOxInventory(module)
if not ok then
print(("^1[es_extended] ox_inventory:loadInventory returned an invalid module: %s^7"):format(err))
end
end) end)
-- Standard method used when ox_inventory is stopped.
AddEventHandler("onResourceStop", function(resourceName)
if resourceName == "ox_inventory" then
OxInventory = nil
end
end)
local function emptyMethod()
return function() end
end
local function falseMethod()
return function()
return false
end
end
Core.PlayerFunctionOverrides.OxInventory = { Core.PlayerFunctionOverrides.OxInventory = {
getInventory = function(self) getInventory = function(self)
return function(minimal) return function(minimal)
@@ -13,26 +109,26 @@ Core.PlayerFunctionOverrides.OxInventory = {
return self.inventory return self.inventory
end end
local minimalInventory = {} local result = {}
for k, v in pairs(self.inventory) do for slot, item in pairs(self.inventory) do
if v.count and v.count > 0 then if item.count and item.count > 0 then
local metadata = v.metadata local metadata = item.metadata
if v.metadata and next(v.metadata) == nil then if type(metadata) == "table" and next(metadata) == nil then
metadata = nil metadata = nil
end end
minimalInventory[#minimalInventory + 1] = { result[#result + 1] = {
name = v.name, name = item.name,
count = v.count, count = item.count,
slot = k, slot = slot,
metadata = metadata, metadata = metadata,
} }
end end
end end
return minimalInventory return result
end end
end, end,
@@ -45,18 +141,33 @@ Core.PlayerFunctionOverrides.OxInventory = {
setAccountMoney = function(self) setAccountMoney = function(self)
return function(accountName, money, reason) return function(accountName, money, reason)
reason = reason or "unknown" reason = reason or "unknown"
if money < 0 then return end
if money < 0 then
return
end
local account = self.getAccount(accountName) local account = self.getAccount(accountName)
if not account then return end if not account then
return
end
money = account.round and ESX.Math.Round(money) or money money = account.round and ESX.Math.Round(money) or money
self.accounts[account.index].money = money self.accounts[account.index].money = money
self.triggerEvent("esx:setAccountMoney", account) self.triggerEvent("esx:setAccountMoney", account)
TriggerEvent("esx:setAccountMoney", self.source, accountName, money, reason) TriggerEvent(
if Inventory.accounts[accountName] then "esx:setAccountMoney",
Inventory.SetItem(self.source, accountName, money) self.source,
accountName,
money,
reason
)
local inventory = getOxInventory()
if inventory.accounts[accountName] then
inventory.SetItem(self.source, accountName, money)
end end
end end
end, end,
@@ -64,17 +175,34 @@ Core.PlayerFunctionOverrides.OxInventory = {
addAccountMoney = function(self) addAccountMoney = function(self)
return function(accountName, money, reason) return function(accountName, money, reason)
reason = reason or "unknown" reason = reason or "unknown"
if money < 1 then return end
if money < 1 then
return
end
local account = self.getAccount(accountName) local account = self.getAccount(accountName)
if not account then return end
if not account then
return
end
money = account.round and ESX.Math.Round(money) or money money = account.round and ESX.Math.Round(money) or money
self.accounts[account.index].money = self.accounts[account.index].money + money self.accounts[account.index].money =
self.accounts[account.index].money + money
self.triggerEvent("esx:setAccountMoney", account) self.triggerEvent("esx:setAccountMoney", account)
TriggerEvent("esx:addAccountMoney", self.source, accountName, money, reason) TriggerEvent(
if Inventory.accounts[accountName] then "esx:addAccountMoney",
Inventory.AddItem(self.source, accountName, money) self.source,
accountName,
money,
reason
)
local inventory = getOxInventory()
if inventory.accounts[accountName] then
inventory.AddItem(self.source, accountName, money)
end end
end end
end, end,
@@ -82,54 +210,103 @@ Core.PlayerFunctionOverrides.OxInventory = {
removeAccountMoney = function(self) removeAccountMoney = function(self)
return function(accountName, money, reason) return function(accountName, money, reason)
reason = reason or "unknown" reason = reason or "unknown"
if money < 1 then return end
if money < 1 then
return
end
local account = self.getAccount(accountName) local account = self.getAccount(accountName)
if not account then return end
if not account then
return
end
money = account.round and ESX.Math.Round(money) or money money = account.round and ESX.Math.Round(money) or money
self.accounts[account.index].money = self.accounts[account.index].money - money self.accounts[account.index].money =
self.accounts[account.index].money - money
self.triggerEvent("esx:setAccountMoney", account) self.triggerEvent("esx:setAccountMoney", account)
TriggerEvent("esx:removeAccountMoney", self.source, accountName, money, reason) TriggerEvent(
if Inventory.accounts[accountName] then "esx:removeAccountMoney",
Inventory.RemoveItem(self.source, accountName, money) self.source,
accountName,
money,
reason
)
local inventory = getOxInventory()
if inventory.accounts[accountName] then
inventory.RemoveItem(self.source, accountName, money)
end end
end end
end, end,
getInventoryItem = function(self) getInventoryItem = function(self)
return function(name, metadata) return function(name, metadata)
return Inventory.GetItem(self.source, name, metadata) return getOxInventory().GetItem(
self.source,
name,
metadata
)
end end
end, end,
addInventoryItem = function(self) addInventoryItem = function(self)
return function(name, count, metadata, slot) return function(name, count, metadata, slot)
return Inventory.AddItem(self.source, name, count or 1, metadata, slot) return getOxInventory().AddItem(
self.source,
name,
count or 1,
metadata,
slot
)
end end
end, end,
removeInventoryItem = function(self) removeInventoryItem = function(self)
return function(name, count, metadata, slot) return function(name, count, metadata, slot)
return Inventory.RemoveItem(self.source, name, count or 1, metadata, slot) return getOxInventory().RemoveItem(
self.source,
name,
count or 1,
metadata,
slot
)
end end
end, end,
setInventoryItem = function(self) setInventoryItem = function(self)
return function(name, count, metadata) return function(name, count, metadata)
return Inventory.SetItem(self.source, name, count, metadata) return getOxInventory().SetItem(
self.source,
name,
count,
metadata
)
end end
end, end,
canCarryItem = function(self) canCarryItem = function(self)
return function(name, count, metadata) return function(name, count, metadata)
return Inventory.CanCarryItem(self.source, name, count, metadata) return getOxInventory().CanCarryItem(
self.source,
name,
count,
metadata
)
end end
end, end,
canSwapItem = function(self) canSwapItem = function(self)
return function(firstItem, firstItemCount, testItem, testItemCount) return function(firstItem, firstItemCount, testItem, testItemCount)
return Inventory.CanSwapItem(self.source, firstItem, firstItemCount, testItem, testItemCount) return getOxInventory().CanSwapItem(
self.source,
firstItem,
firstItemCount,
testItem,
testItemCount
)
end end
end, end,
@@ -137,83 +314,71 @@ Core.PlayerFunctionOverrides.OxInventory = {
return function(newWeight) return function(newWeight)
self.maxWeight = newWeight self.maxWeight = newWeight
self.triggerEvent("esx:setMaxWeight", self.maxWeight) self.triggerEvent("esx:setMaxWeight", self.maxWeight)
return Inventory.SetMaxWeight(self.source, newWeight)
return getOxInventory().SetMaxWeight(
self.source,
newWeight
)
end end
end, end,
addWeapon = function() addWeapon = emptyMethod,
return function() end addWeaponComponent = emptyMethod,
end, addWeaponAmmo = emptyMethod,
updateWeaponAmmo = emptyMethod,
setWeaponTint = emptyMethod,
getWeaponTint = emptyMethod,
removeWeapon = emptyMethod,
removeWeaponComponent = emptyMethod,
removeWeaponAmmo = emptyMethod,
addWeaponComponent = function() hasWeaponComponent = falseMethod,
return function() end hasWeapon = falseMethod,
end,
addWeaponAmmo = function()
return function() end
end,
updateWeaponAmmo = function()
return function() end
end,
setWeaponTint = function()
return function() end
end,
getWeaponTint = function()
return function() end
end,
removeWeapon = function()
return function() end
end,
removeWeaponComponent = function()
return function() end
end,
removeWeaponAmmo = function()
return function() end
end,
hasWeaponComponent = function()
return function()
return false
end
end,
hasWeapon = function()
return function()
return false
end
end,
hasItem = function(self) hasItem = function(self)
return function(name, metadata) return function(name, metadata)
return Inventory.GetItem(self.source, name, metadata) local item = getOxInventory().GetItem(
self.source,
name,
metadata
)
if not item or not item.count or item.count < 1 then
return false
end
return item, item.count
end end
end, end,
getWeapon = function() getWeapon = emptyMethod,
return function() end
end,
syncInventory = function(self) syncInventory = function(self)
return function(weight, maxWeight, items, money) return function(weight, maxWeight, items, money)
self.weight, self.maxWeight = weight, maxWeight self.weight = weight
self.maxWeight = maxWeight
self.inventory = items self.inventory = items
if not money then return end if not money then
return
end
for accountName, amount in pairs(money) do for accountName, amount in pairs(money) do
local account = self.getAccount(accountName) local account = self.getAccount(accountName)
if account and ESX.Math.Round(account.money) ~= amount then if account and ESX.Math.Round(account.money) ~= amount then
account.money = amount account.money = amount
self.triggerEvent("esx:setAccountMoney", account) self.triggerEvent("esx:setAccountMoney", account)
TriggerEvent("esx:setAccountMoney", self.source, accountName, amount, "Sync account with item") TriggerEvent(
"esx:setAccountMoney",
self.source,
accountName,
amount,
"Sync account with item"
)
end end
end end
end end
end, end,
} }