diff --git a/[core]/es_extended/client/functions.lua b/[core]/es_extended/client/functions.lua index 09e60c22..32f8f5d9 100644 --- a/[core]/es_extended/client/functions.lua +++ b/[core]/es_extended/client/functions.lua @@ -85,7 +85,7 @@ end function ESX.SetPlayerData(key, val) local current = ESX.PlayerData[key] ESX.PlayerData[key] = val - if key ~= "inventory" and key ~= "loadout" then + if key ~= "loadout" then if type(val) == "table" or val ~= current then TriggerEvent("esx:setPlayerData", key, val, current) end diff --git a/[core]/es_extended/client/modules/events.lua b/[core]/es_extended/client/modules/events.lua index 771bfef1..764a897a 100644 --- a/[core]/es_extended/client/modules/events.lua +++ b/[core]/es_extended/client/modules/events.lua @@ -57,6 +57,10 @@ ESX.SecureNetEvent("esx:setMaxWeight", function(newMaxWeight) ESX.SetPlayerData("maxWeight", newMaxWeight) end) +ESX.SecureNetEvent("esx:setInventory", function(newInventory) + ESX.SetPlayerData("inventory", newInventory) +end) + local function onPlayerSpawn() ESX.SetPlayerData("ped", PlayerPedId()) ESX.SetPlayerData("dead", false) diff --git a/[core]/es_extended/locales/en.lua b/[core]/es_extended/locales/en.lua index 194d2912..b10966a9 100644 --- a/[core]/es_extended/locales/en.lua +++ b/[core]/es_extended/locales/en.lua @@ -65,6 +65,8 @@ return { ["command_repair_success_target"] = "An admin repaired your vehicle", ["command_clear"] = "Clear chat Text", ["command_clearall"] = "Clear chat Text for all players", + ["command_refreshitems"] = "Reload all items from the database.", + ["command_refreshitems_success"] = "Successfully reloaded %d items.", ["command_clearinventory"] = "Remove All items from the Players Inventory", ["command_clearloadout"] = "Remove All weapons from the Players Loadout", ["command_freeze"] = "Freeze a player", diff --git a/[core]/es_extended/server/common.lua b/[core]/es_extended/server/common.lua index 49071d8b..a0f571df 100644 --- a/[core]/es_extended/server/common.lua +++ b/[core]/es_extended/server/common.lua @@ -36,11 +36,9 @@ end MySQL.ready(function() Core.DatabaseConnected = true + if not Config.CustomInventory then - local items = MySQL.query.await("SELECT * FROM items") - for _, v in ipairs(items) do - ESX.Items[v.name] = { label = v.label, weight = v.weight, rare = v.rare, canRemove = v.can_remove } - end + ESX.RefreshItems() end ESX.RefreshJobs() diff --git a/[core]/es_extended/server/functions.lua b/[core]/es_extended/server/functions.lua index 633d5b95..fa23d378 100644 --- a/[core]/es_extended/server/functions.lua +++ b/[core]/es_extended/server/functions.lua @@ -637,6 +637,124 @@ if not Config.CustomInventory then TriggerClientEvent("esx:createPickup", -1, pickupId, label, coords, itemType, name, components, tintIndex) Core.PickupId = pickupId end + + local function refreshPlayerInventories() + local xPlayers = ESX.GetExtendedPlayers() + for i = 1, #xPlayers do + local xPlayer = xPlayers[i] + local minimalInv = xPlayer.getInventory(true) + + for itemName, itemCount in pairs(minimalInv) do + if not ESX.Items[itemName] then + xPlayer.setInventoryItem(itemName, 0) + minimalInv[itemName] = nil + end + end + + xPlayer.inventory = {} + local playerInvIndex = 1 + for itemName, itemData in pairs(ESX.Items) do + xPlayer.inventory[playerInvIndex] = { + name = itemName, + count = minimalInv[itemName] or 0, + label = itemData.label, + weight = itemData.weight, + usable = Core.UsableItemsCallbacks[itemName] ~= nil, + rare = itemData.rare, + canRemove = itemData.canRemove, + } + playerInvIndex += 1 + end + + TriggerClientEvent("esx:setInventory", xPlayer.source, xPlayer.inventory) + end + end + + ---@return number newItemCount + function ESX.RefreshItems() + ESX.Items = {} + + local items = MySQL.query.await("SELECT * FROM items") + local itemCount = #items + for i = 1, itemCount do + local item = items[i] + ESX.Items[item.name] = { label = item.label, weight = item.weight, rare = item.rare, canRemove = item.can_remove } + end + refreshPlayerInventories() + + return itemCount + end + + ---@param items { name: string, label: string, weight?: number, rare?: boolean, canRemove?: boolean }[] + function ESX.AddItems(items) + local toInsert = {} + local toInsertIndex = 1 + + for i = 1, #items do + local item = items[i] + local name = item.name + local label = item.label + local weight = item.weight or 1 + local rare = item.rare or false + local canRemove = item.canRemove ~= false + + if type(name) ~= "string" then + print(("^1[AddItems]^0 Invalid item name: %s"):format(name)) + goto continue + end + + if ESX.Items[name] then + goto continue + end + + if type(label) ~= "string" then + print(("^1[AddItems]^0 Invalid label for item '%s'"):format(name)) + goto continue + end + + if type(weight) ~= "number" then + print(("^1[AddItems]^0 Invalid weight for item '%s'"):format(name)) + goto continue + end + + if type(rare) ~= "boolean" then + print(("^1[AddItems]^0 Invalid rare flag for item '%s'"):format(name)) + goto continue + end + + if type(canRemove) ~= "boolean" then + print(("^1[AddItems]^0 Invalid canRemove flag for item '%s'"):format(name)) + goto continue + end + + toInsert[toInsertIndex] = { + name = name, + label = label, + weight = weight, + rare = rare, + canRemove = canRemove, + } + toInsertIndex += 1 + + ::continue:: + end + + if #toInsert > 0 then + MySQL.prepare.await("INSERT IGNORE INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES (?, ?, ?, ?, ?)", toInsert) + + for i = 1, #toInsert do + local row = toInsert[i] + ESX.Items[row.name] = { + label = row.label, + weight = row.weight, + rare = row.rare, + canRemove = row.canRemove, + } + end + + refreshPlayerInventories() + end + end end ---@param job string diff --git a/[core]/es_extended/server/modules/commands.lua b/[core]/es_extended/server/modules/commands.lua index 628e85ea..a8c7d6a6 100644 --- a/[core]/es_extended/server/modules/commands.lua +++ b/[core]/es_extended/server/modules/commands.lua @@ -439,6 +439,12 @@ ESX.RegisterCommand("refreshjobs", "admin", function() end, true, { help = TranslateCap("command_clearall") }) if not Config.CustomInventory then + ESX.RegisterCommand("refreshitems", "admin", function(xPlayer) + local itemCount = ESX.RefreshItems() + + xPlayer.showNotification(Translate("command_refreshitems_success", itemCount), true, false, 140) + end, true, { help = TranslateCap("command_refreshitems") }) + ESX.RegisterCommand( "clearinventory", "admin",