2026-04-14 17:41:39 +02:00

278 lines
9.4 KiB
Lua

if Config.Inventory ~= 'qs-inventory' then return end
-- ════════════════════════════════════════
-- QS-INVENTORY SERVER INTEGRATION
-- ════════════════════════════════════════
local Inventory = {}
Inventory.Config = {
ItemName = Config.ItemName or 'phone',
RequireItem = Config.ItemRequired ~= false,
DebugMode = Config.Debug or false
}
-- ════════════════════════════════════════
-- UTILITY FUNCTIONS
-- ════════════════════════════════════════
local function Log(type, message, ...)
if not Inventory.Config.DebugMode then return end
local prefix = '^2[QS-Inventory]^7'
if type == 'error' then prefix = '^1[QS-Inventory ERROR]^7' end
if type == 'warn' then prefix = '^3[QS-Inventory WARNING]^7' end
print(string.format('%s %s', prefix, string.format(message, ...)))
end
local function ValidatePlayer(source)
local src = tonumber(source)
if not src or src == 0 then
Log('error', 'Invalid source: %s', tostring(source))
return nil
end
local Player = Core.Functions.GetPlayer(src)
if not Player then
Log('error', 'Player not found for source: %s', src)
return nil
end
return Player
end
-- ════════════════════════════════════════
-- INVENTORY FUNCTIONS
-- ════════════════════════════════════════
function Inventory.GetAllItems(source)
return exports['qs-inventory']:GetInventory(source) or {}
end
function Inventory.GetItemsByName(source, itemName)
itemName = itemName or Inventory.Config.ItemName
local items = {}
local inventory = Inventory.GetAllItems(source)
for slot, item in pairs(inventory) do
if item and item.name == itemName then
items[#items + 1] = {
slot = slot,
name = item.name,
amount = item.amount or 1,
info = item.info or {},
CodemPhoneNumber = item.info and item.info.CodemPhoneNumber or nil,
CodemFormattedNumber = item.info and item.info.CodemFormattedNumber or nil
}
end
end
return items
end
function Inventory.GetPhoneItem(source)
if not Inventory.Config.RequireItem then
Log('debug', 'Item requirement disabled, returning true')
return true
end
local Player = ValidatePlayer(source)
if not Player then return false end
local amount = exports['qs-inventory']:GetItemTotalAmount(source, Inventory.Config.ItemName)
if not amount or amount == 0 then
Log('warn', 'Player %s does not have phone item', source)
return nil
end
return true
end
function Inventory.HasPhoneWithNumber(source, phoneNumber)
local phones = Inventory.GetItemsByName(source, Inventory.Config.ItemName)
if #phones == 0 then
Log('debug', 'Player %s has no phone items', source)
return {
success = false,
itemAmount = 0,
}
end
local foundPhoneWithDifferentNumber = false
local differentNumber = nil
for i = 1, #phones do
local phone = phones[i]
if phone.CodemPhoneNumber then
if phone.CodemPhoneNumber == phoneNumber then
Log('debug', 'Player %s has phone with number %s', source, phoneNumber)
return {
success = true,
myPhone = true
}
else
foundPhoneWithDifferentNumber = true
differentNumber = phone.CodemPhoneNumber
end
end
end
if foundPhoneWithDifferentNumber then
Log('debug', 'Player %s has phone but with different number: %s (expected: %s)',
source, differentNumber, phoneNumber)
return {
success = true,
myPhone = false,
differentNumber = differentNumber
}
end
Log('debug', 'Player %s has phone but no number assigned', source)
return {
success = true,
myPhone = false,
firstSetup = true
}
end
function Inventory.HasAnyPhone(source)
local phones = Inventory.GetItemsByName(source, Inventory.Config.ItemName)
if #phones == 0 then
Log('debug', 'Player %s has no phone items', source)
return false
end
Log('debug', 'Player %s has %d phone item(s)', source, #phones)
return true
end
function Inventory.SetPhoneNumber(source, phoneNumber)
if not phoneNumber then
Log('error', 'SetPhoneNumber called without phone number')
return false
end
local inventory = Inventory.GetAllItems(source)
local updated = false
for slot, item in pairs(inventory) do
if item and item.name == Inventory.Config.ItemName then
if item.info and item.info.CodemPhoneNumber then
Log('debug', 'Skipping phone in slot %s (already has number)', slot)
goto continue
end
local newInfo = item.info or {}
newInfo.CodemPhoneNumber = phoneNumber
newInfo.CodemFormattedNumber = FormatPhoneNumber(phoneNumber)
exports['qs-inventory']:SetItemMetadata(source, slot, newInfo)
Log('debug', 'Assigned number %s to phone in slot %s', phoneNumber, slot)
updated = true
break
end
::continue::
end
if not updated then
Log('warn', 'Could not find available phone to assign number for player %s', source)
end
return updated
end
function Inventory.UpdatePhoneMetadata(source, phoneNumber, metadata)
local inventory = Inventory.GetAllItems(source)
local updated = false
for slot, item in pairs(inventory) do
if item and item.name == Inventory.Config.ItemName then
local itemNumber = item.info and item.info.CodemPhoneNumber
if itemNumber == phoneNumber then
local newInfo = item.info or {}
for key, value in pairs(metadata) do
if value == "DELETE" or value == nil then
newInfo[key] = nil
else
newInfo[key] = value
end
end
exports['qs-inventory']:SetItemMetadata(source, slot, newInfo)
Log('debug', 'Updated metadata for phone %s in slot %s', phoneNumber, slot)
updated = true
break
end
end
end
return updated
end
function Inventory.RemoveInventoryItem(source, itemname, amount)
local Player = ValidatePlayer(source)
if not Player then return false end
local removed = exports['qs-inventory']:RemoveItem(source, itemname, amount)
if removed then
Log('debug', 'Removed %d of item %s from player %s', amount, itemname, source)
else
Log('warn', 'Failed to remove item %s from player %s', itemname, source)
end
return removed
end
-- ════════════════════════════════════════
-- USEABLE ITEM REGISTRATION
-- ════════════════════════════════════════
Citizen.CreateThread(function()
exports['qs-inventory']:CreateUsableItem(Inventory.Config.ItemName, function(source, item)
if item then
TriggerClientEvent("codem-phone:PhoneUsed", source, item)
end
end)
if Config.BatterySystem.enable then
exports['qs-inventory']:CreateUsableItem(Config.BatterySystem.powerBankItemName, function(source, item)
TriggerClientEvent("codem-phone:UsePowerBank", source)
Inventory.RemoveInventoryItem(source, Config.BatterySystem.powerBankItemName, 1)
end)
end
end)
-- ════════════════════════════════════════
-- RPC REGISTRATIONS
-- ════════════════════════════════════════
RPC.Register('codem-phone:inventory:HasPhoneItem', function(source, phoneNumber)
return Inventory.HasPhoneWithNumber(source, phoneNumber)
end)
RPC.Register('codem-phone:inventory:HasAnyPhone', function(source)
return Inventory.HasAnyPhone(source)
end)
RPC.Register('codem-phone:inventory:GetPhoneItem', function(source)
return Inventory.GetPhoneItem(source)
end)
-- ════════════════════════════════════════
-- GLOBAL EXPORTS
-- ════════════════════════════════════════
GetPlayerInventoryItem = Inventory.GetPhoneItem
SetPhoneNumber = Inventory.SetPhoneNumber
UpdatePhoneMetadata = Inventory.UpdatePhoneMetadata
GetItemsByName = Inventory.GetItemsByName