diff --git a/[esx_addons]/esx_addoninventory/fxmanifest.lua b/[esx_addons]/esx_addoninventory/fxmanifest.lua index 8c5f72b0..d4158411 100644 --- a/[esx_addons]/esx_addoninventory/fxmanifest.lua +++ b/[esx_addons]/esx_addoninventory/fxmanifest.lua @@ -1,23 +1,22 @@ -fx_version 'adamant' - +fx_version 'cerulean' game 'gta5' - -description 'Adds a way for resources to store items for players' lua54 'yes' +use_fxv2_oal 'yes' -version '1.0' +author 'ESX-Framework' +description 'Adds a way for resources to store items for players.' +version '1.1' legacyversion '1.13.4' server_scripts { '@es_extended/imports.lua', '@oxmysql/lib/MySQL.lua', 'server/classes/addoninventory.lua', + 'server/database.lua', 'server/main.lua' } -server_exports { - 'GetSharedInventory', - 'AddSharedInventory' -} - -dependency 'es_extended' +-- server_exports { +-- 'GetSharedInventory', +-- 'AddSharedInventory' +-- } diff --git a/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua b/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua index 4725788f..a0425fe3 100644 --- a/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua +++ b/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua @@ -1,85 +1,68 @@ +---@alias AddonInventoryItem { name: string, count: number, label: string } + +---@class AddonInventory +---@field name string +---@field owner? string +---@field items table +---@field addItem fun(itemName: string, count: number) +---@field removeItem fun(itemName: string, count: number) +---@field setItem fun(itemName: string, count: number) +---@field getItem fun(itemName: string): AddonInventoryItem +---@field saveItem function + +---@param name string +---@param owner? string +---@param items table +---@return AddonInventory function CreateAddonInventory(name, owner, items) - local self = {} + ---@diagnostic disable-next-line: missing-fields + local self = {} --[[@type AddonInventory]] self.name = name self.owner = owner - self.items = items + self.items = {} - function self.addItem(name, count) - local item = self.getItem(name) - item.count = item.count + count + for _, item in ipairs(items) do + local itemName = item.name + self.items[itemName] = { + name = itemName, + count = item.count, + label = ESX.GetItemLabel(itemName), + } + end - self.saveItem(name, item.count) + function self.addItem(itemName, count) + local item = self.getItem(itemName) + item.count += count end - function self.removeItem(name, count) - if count > 0 then - local item = self.getItem(name) - item.count = item.count - count - - self.saveItem(name, item.count) - end + function self.removeItem(itemName, count) + if count <= 0 then return end + + local item = self.getItem(itemName) + item.count = math.max(0, item.count - count) end - function self.setItem(name, count) - local item = self.getItem(name) + function self.setItem(itemName, count) + local item = self.getItem(itemName) item.count = count - - self.saveItem(name, item.count) end - function self.getItem(name) - for i=1, #self.items, 1 do - if self.items[i].name == name then - return self.items[i] - end - end + function self.getItem(itemName) + local existingItem = self.items[itemName] + if existingItem then return existingItem end - item = { - name = name, + self.items[itemName] = { + name = itemName, count = 0, - label = Items[name] + label = ESX.GetItemLabel(itemName) } - table.insert(self.items, item) - - if self.owner == nil then - MySQL.update('INSERT INTO addon_inventory_items (inventory_name, name, count) VALUES (@inventory_name, @item_name, @count)', - { - ['@inventory_name'] = self.name, - ['@item_name'] = name, - ['@count'] = 0 - }) - else - MySQL.update('INSERT INTO addon_inventory_items (inventory_name, name, count, owner) VALUES (@inventory_name, @item_name, @count, @owner)', - { - ['@inventory_name'] = self.name, - ['@item_name'] = name, - ['@count'] = 0, - ['@owner'] = self.owner - }) - end - - return item + return self.items[itemName] end - function self.saveItem(name, count) - if self.owner == nil then - MySQL.update('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name', { - ['@inventory_name'] = self.name, - ['@item_name'] = name, - ['@count'] = count - }) - else - MySQL.update('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name AND owner = @owner', { - ['@inventory_name'] = self.name, - ['@item_name'] = name, - ['@count'] = count, - ['@owner'] = self.owner - }) - end + function self.saveItem(itemName, count) end return self end - diff --git a/[esx_addons]/esx_addoninventory/server/database.lua b/[esx_addons]/esx_addoninventory/server/database.lua new file mode 100644 index 00000000..be88891d --- /dev/null +++ b/[esx_addons]/esx_addoninventory/server/database.lua @@ -0,0 +1,35 @@ +Database = {} + +---@class DatabaseInventoryRow +---@field name string +---@field label string +---@field shared number + +---@class DatabaseInventoryItemRow +---@field id number +---@field inventory_name string +---@field name string +---@field count number +---@field owner? string + +---@param name string +---@param shared? boolean +---@return DatabaseInventoryRow? +function Database.fetchInventory(name, shared) + return MySQL.single.await('SELECT * FROM addon_inventory WHERE name = ? AND shared = ?', { name, shared and 1 or 0 }) +end + +---@param name string +---@param owner? string +---@return DatabaseInventoryItemRow[] +function Database.fetchInventoryItems(name, owner) + if owner then + return MySQL.query.await('SELECT * FROM addon_inventory_items WHERE inventory_name = ? AND owner = ?', { name, owner }) + end + + return MySQL.query.await('SELECT * FROM addon_inventory_items WHERE inventory_name = ?', { name }) +end + +function Database.saveInventories() + warn('Not implemented yet.') +end diff --git a/[esx_addons]/esx_addoninventory/server/main.lua b/[esx_addons]/esx_addoninventory/server/main.lua index b1818c56..0f6f09e8 100644 --- a/[esx_addons]/esx_addoninventory/server/main.lua +++ b/[esx_addons]/esx_addoninventory/server/main.lua @@ -1,134 +1,172 @@ -if ESX.GetConfig().OxInventory then - AddEventHandler('onServerResourceStart', function(resourceName) - if resourceName == 'ox_inventory' or resourceName == GetCurrentResourceName() then - local stashes = MySQL.query.await('SELECT * FROM addon_inventory') - - for i=1, #stashes do - local stash = stashes[i] - local jobStash = stash.name:find('society') and string.sub(stash.name, 9) - exports.ox_inventory:RegisterStash(stash.name, stash.label, 100, 200000, stash.shared == 0 and true or false, jobStash) - end - end - end) - - return -end - -Items = {} -local InventoriesIndex, Inventories, SharedInventories = {}, {}, {} - -MySQL.ready(function() - local items = MySQL.query.await('SELECT * FROM items') - - for i=1, #items, 1 do - Items[items[i].name] = items[i].label +Inventories, SharedInventories = {}, {} + +---@param name string +---@param owner string +---@return AddonInventory? +local function getInventory(name, owner) + -- for i = 1, #Inventories[name], 1 do + -- if Inventories[name][i].owner == owner then + -- return Inventories[name][i] + -- end + -- end + local existingInventory = Inventories[name]?[owner] + if existingInventory then return existingInventory end + + local dbInventory, dbItems = Database.fetchInventory(name, false), Database.fetchInventoryItems(name, owner) + if not dbInventory or not dbItems then return end + + if not Inventories[name] then + Inventories[name] = {} end - local result = MySQL.query.await('SELECT * FROM addon_inventory') - - for i=1, #result, 1 do - local name = result[i].name - local label = result[i].label - local shared = result[i].shared - - local result2 = MySQL.query.await('SELECT * FROM addon_inventory_items WHERE inventory_name = @inventory_name', { - ['@inventory_name'] = name - }) - - if shared == 0 then - - table.insert(InventoriesIndex, name) - - Inventories[name] = {} - local items = {} - - for j=1, #result2, 1 do - local itemName = result2[j].name - local itemCount = result2[j].count - local itemOwner = result2[j].owner - - if items[itemOwner] == nil then - items[itemOwner] = {} - end - - table.insert(items[itemOwner], { - name = itemName, - count = itemCount, - label = Items[itemName] - }) - end - - for k,v in pairs(items) do - local addonInventory = CreateAddonInventory(name, k, v) - table.insert(Inventories[name], addonInventory) - end - - else - local items = {} - - for j=1, #result2, 1 do - table.insert(items, { - name = result2[j].name, - count = result2[j].count, - label = Items[result2[j].name] - }) - end + Inventories[name][owner] = CreateAddonInventory(name, owner, dbItems) - local addonInventory = CreateAddonInventory(name, nil, items) - SharedInventories[name] = addonInventory - GlobalState.SharedInventories = SharedInventories - end - end -end) - -function GetInventory(name, owner) - for i=1, #Inventories[name], 1 do - if Inventories[name][i].owner == owner then - return Inventories[name][i] - end - end + return Inventories[name][owner] end -function GetSharedInventory(name) - return SharedInventories[name] -end +---@param name string +---@return AddonInventory? +local function getSharedInventory(name) + local existingInventory = SharedInventories[name] + if existingInventory then return existingInventory end -function AddSharedInventory(society) - if type(society) ~= 'table' or not society?.name or not society?.label then return end - -- society (array) containing name (string) and label (string) + local dbAccount, dbItems = Database.fetchInventory(name, true), Database.fetchInventoryItems(name) + if not dbAccount or not dbItems then return end - -- addon inventory: - MySQL.Async.execute('INSERT INTO addon_inventory (name, label, shared) VALUES (@name, @label, @shared)', { - ['name'] = society.name, - ['label'] = society.label, - ['shared'] = 1 - }) + SharedInventories[name] = CreateAddonInventory(name, nil, dbItems) - SharedInventories[society.name] = CreateAddonInventory(society.name, nil, {}) + GlobalState.SharedInventories = SharedInventories + return SharedInventories[name] end - -AddEventHandler('esx_addoninventory:getInventory', function(name, owner, cb) - cb(GetInventory(name, owner)) -end) - -AddEventHandler('esx_addoninventory:getSharedInventory', function(name, cb) - cb(GetSharedInventory(name)) -end) - -AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - local addonInventories = {} - - for i=1, #InventoriesIndex, 1 do - local name = InventoriesIndex[i] - local inventory = GetInventory(name, xPlayer.identifier) - - if inventory == nil then - inventory = CreateAddonInventory(name, xPlayer.identifier, {}) - table.insert(Inventories[name], inventory) - end - - table.insert(addonInventories, inventory) - end - - xPlayer.set('addonInventories', addonInventories) -end) +-- if ESX.GetConfig().OxInventory then +-- AddEventHandler('onServerResourceStart', function(resourceName) +-- if resourceName == 'ox_inventory' or resourceName == GetCurrentResourceName() then +-- local stashes = MySQL.query.await('SELECT * FROM addon_inventory') + +-- for i = 1, #stashes do +-- local stash = stashes[i] +-- local jobStash = stash.name:find('society') and string.sub(stash.name, 9) +-- exports.ox_inventory:RegisterStash(stash.name, stash.label, 100, 200000, stash.shared == 0 and true or false, jobStash) +-- end +-- end +-- end) + +-- return +-- end + +-- Items = {} +-- local InventoriesIndex, Inventories, SharedInventories = {}, {}, {} + +-- MySQL.ready(function() +-- local items = MySQL.query.await('SELECT * FROM items') + +-- for i = 1, #items, 1 do +-- Items[items[i].name] = items[i].label +-- end + +-- local result = MySQL.query.await('SELECT * FROM addon_inventory') + +-- for i = 1, #result, 1 do +-- local name = result[i].name +-- local label = result[i].label +-- local shared = result[i].shared + +-- local result2 = MySQL.query.await('SELECT * FROM addon_inventory_items WHERE inventory_name = @inventory_name', { +-- ['@inventory_name'] = name +-- }) + +-- if shared == 0 then +-- table.insert(InventoriesIndex, name) + +-- Inventories[name] = {} +-- local items = {} + +-- for j = 1, #result2, 1 do +-- local itemName = result2[j].name +-- local itemCount = result2[j].count +-- local itemOwner = result2[j].owner + +-- if items[itemOwner] == nil then +-- items[itemOwner] = {} +-- end + +-- table.insert(items[itemOwner], { +-- name = itemName, +-- count = itemCount, +-- label = Items[itemName] +-- }) +-- end + +-- for k, v in pairs(items) do +-- local addonInventory = CreateAddonInventory(name, k, v) +-- table.insert(Inventories[name], addonInventory) +-- end +-- else +-- local items = {} + +-- for j = 1, #result2, 1 do +-- table.insert(items, { +-- name = result2[j].name, +-- count = result2[j].count, +-- label = Items[result2[j].name] +-- }) +-- end + +-- local addonInventory = CreateAddonInventory(name, nil, items) +-- SharedInventories[name] = addonInventory +-- GlobalState.SharedInventories = SharedInventories +-- end +-- end +-- end) + +-- function GetInventory(name, owner) +-- for i = 1, #Inventories[name], 1 do +-- if Inventories[name][i].owner == owner then +-- return Inventories[name][i] +-- end +-- end +-- end + +-- function GetSharedInventory(name) +-- return SharedInventories[name] +-- end + +-- function AddSharedInventory(society) +-- if type(society) ~= 'table' or not society?.name or not society?.label then return end +-- -- society (array) containing name (string) and label (string) + +-- -- addon inventory: +-- MySQL.Async.execute('INSERT INTO addon_inventory (name, label, shared) VALUES (@name, @label, @shared)', { +-- ['name'] = society.name, +-- ['label'] = society.label, +-- ['shared'] = 1 +-- }) + +-- SharedInventories[society.name] = CreateAddonInventory(society.name, nil, {}) +-- end + +-- AddEventHandler('esx_addoninventory:getInventory', function(name, owner, cb) +-- cb(GetInventory(name, owner)) +-- end) + +-- AddEventHandler('esx_addoninventory:getSharedInventory', function(name, cb) +-- cb(GetSharedInventory(name)) +-- end) + +-- AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) +-- local addonInventories = {} + +-- for i = 1, #InventoriesIndex, 1 do +-- local name = InventoriesIndex[i] +-- local inventory = GetInventory(name, xPlayer.identifier) + +-- if inventory == nil then +-- inventory = CreateAddonInventory(name, xPlayer.identifier, {}) +-- table.insert(Inventories[name], inventory) +-- end + +-- table.insert(addonInventories, inventory) +-- end + +-- xPlayer.set('addonInventories', addonInventories) +-- end)