392 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			392 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
FM.player = {}
 | 
						|
 | 
						|
function string.split(str, delimiter)
 | 
						|
    local result = {}
 | 
						|
    local from = 1
 | 
						|
    local delim_from, delim_to = string.find(str, delimiter, from)
 | 
						|
 | 
						|
    while delim_from do
 | 
						|
        table.insert(result, string.sub(str, from, delim_from - 1))
 | 
						|
        from = delim_to + 1
 | 
						|
        delim_from, delim_to = string.find(str, delimiter, from)
 | 
						|
    end
 | 
						|
 | 
						|
    table.insert(result, string.sub(str, from))
 | 
						|
    return result
 | 
						|
end
 | 
						|
 | 
						|
local function isNewQBInv()
 | 
						|
    local version = GetResourceMetadata(Resources.QBInv or 'qb-inventory', 'version', 0)
 | 
						|
    if not version then return false end
 | 
						|
 | 
						|
    local vNums = {}
 | 
						|
 | 
						|
    for num in version:gmatch("(%d+)") do
 | 
						|
        vNums[#vNums + 1] = tonumber(num)
 | 
						|
    end
 | 
						|
 | 
						|
    return vNums and vNums[1] >= 2
 | 
						|
end
 | 
						|
 | 
						|
local function getPlayerBySrc(src)
 | 
						|
    if not src then return end
 | 
						|
 | 
						|
    local _fwp = ESX and ESX.GetPlayerFromId(src) or QB and QB.Functions.GetPlayer(src) or nil
 | 
						|
    if not _fwp or not type(_fwp) == 'table' then return end
 | 
						|
 | 
						|
    _fwp.source = QB and _fwp.PlayerData.source or _fwp.source
 | 
						|
    return _fwp
 | 
						|
end
 | 
						|
 | 
						|
local function getPlayerByIdentifier(identifier)
 | 
						|
    if not identifier then return end
 | 
						|
    local _fwp = ESX and ESX.GetPlayerFromIdentifier(identifier) or QB and QB.Functions.GetPlayerByCitizenId(identifier) or nil
 | 
						|
    if not _fwp or not type(_fwp) == 'table' then return end
 | 
						|
 | 
						|
    _fwp.source = QB and _fwp.PlayerData.source or _fwp.source
 | 
						|
    return _fwp
 | 
						|
end
 | 
						|
 | 
						|
---@param id number|string
 | 
						|
function FM.player.get(id)
 | 
						|
    local _fwp = type(id) == 'number' and getPlayerBySrc(id) or type(id) == 'string' and getPlayerByIdentifier(id) or nil
 | 
						|
    if not _fwp or type(_fwp) ~= 'table' then return end
 | 
						|
 | 
						|
    local p = {
 | 
						|
        src = _fwp.source
 | 
						|
    }
 | 
						|
 | 
						|
    ---@param item string
 | 
						|
    ---@param amount number
 | 
						|
    ---@param metadata? any
 | 
						|
    ---@param ignoreCheck? boolean
 | 
						|
    p.addItem = function(item, amount, metadata, ignoreCheck)
 | 
						|
        if not item or not amount then return false end
 | 
						|
        if not ignoreCheck and not p.canAddItem(item, amount) then return false end
 | 
						|
 | 
						|
        if OXInv then
 | 
						|
            OXInv:AddItem(_fwp.source, item, amount, metadata)
 | 
						|
 | 
						|
            return true
 | 
						|
        elseif ESX then
 | 
						|
            if CHEZZAInv and string.find(item:lower(), 'weapon') then
 | 
						|
                _fwp.addWeapon(item, 0)
 | 
						|
            else
 | 
						|
                _fwp.addInventoryItem(item, amount)
 | 
						|
            end
 | 
						|
 | 
						|
            return true
 | 
						|
        elseif QB then
 | 
						|
            return _fwp.Functions.AddItem(item, amount, nil, metadata)
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param amount number
 | 
						|
    ---@param moneyType? string
 | 
						|
    ---@param transactionData? { type?: 'deposit' | 'withdraw' | 'transfer' | 'interest' | 'payment', reason?: string, fromIban?: string }
 | 
						|
    p.addMoney = function(amount, moneyType, transactionData)
 | 
						|
        moneyType = moneyType or Defaults.MONEY
 | 
						|
        if not amount then return end
 | 
						|
 | 
						|
        if transactionData and moneyType == 'bank' then
 | 
						|
            if GetResourceState(Resources.RX_BANKING.name) == 'started' then
 | 
						|
                local personalAcc = exports[Resources.RX_BANKING.name]:GetPlayerPersonalAccount(p.getIdentifier())
 | 
						|
                if personalAcc then
 | 
						|
                    exports[Resources.RX_BANKING.name]:CreateTransaction(amount, transactionData.type, transactionData.fromIban, personalAcc.iban, transactionData.reason)
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
 | 
						|
        if ESX then _fwp.addAccountMoney(moneyType, amount)
 | 
						|
        elseif QB then _fwp.Functions.AddMoney(moneyType, amount) end
 | 
						|
    end
 | 
						|
 | 
						|
    p.canAddItem = function(item, amount)
 | 
						|
        if not item or not amount then return false end
 | 
						|
 | 
						|
        if OXInv then return OXInv:CanCarryItem(_fwp.source, item, amount)
 | 
						|
        elseif QBInv and isNewQBInv() then return QBInv:CanAddItem(_fwp.source, item, amount)
 | 
						|
        elseif QSInv then return QSInv:CanCarryItem(_fwp.source, item, amount)
 | 
						|
        elseif ESX then return _fwp.canCarryItem(item, amount)
 | 
						|
        elseif QB then return true end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param moneyType? string
 | 
						|
    ---@return number | nil amount
 | 
						|
    p.getMoney = function(moneyType)
 | 
						|
        moneyType = moneyType or Defaults.MONEY
 | 
						|
 | 
						|
        if ESX then
 | 
						|
            local acc = _fwp.getAccount(moneyType)
 | 
						|
            if not acc then FM.console.err('Money Type not found: '..moneyType) return 0 end
 | 
						|
 | 
						|
            return acc.money
 | 
						|
        elseif QB then
 | 
						|
            local money = _fwp.PlayerData.money[moneyType]
 | 
						|
            if money == nil then FM.console.err('Money Type not found: '..moneyType) return 0 end
 | 
						|
 | 
						|
            return money
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return string identifier
 | 
						|
    p.getIdentifier = function()
 | 
						|
        if ESX then return _fwp.getIdentifier()
 | 
						|
        elseif QB then return _fwp.PlayerData.citizenid end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return { name: string, label: string, grade: number, gradeLabel: string } job
 | 
						|
    p.getJob = function()
 | 
						|
        if ESX then
 | 
						|
            return {
 | 
						|
                name = _fwp.job.name,
 | 
						|
                label = _fwp.job.label,
 | 
						|
                grade = _fwp.job.grade,
 | 
						|
                gradeLabel = _fwp.job.grade_label
 | 
						|
            }
 | 
						|
        elseif QB then
 | 
						|
            return {
 | 
						|
                name = _fwp.PlayerData.job.name,
 | 
						|
                label = _fwp.PlayerData.job.label,
 | 
						|
                grade = _fwp.PlayerData.job.grade.level,
 | 
						|
                gradeLabel = _fwp.PlayerData.job.grade.name
 | 
						|
            }
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return { name: string, label: string, grade: number, gradeLabel: string } | nil gang
 | 
						|
    p.getGang = function()
 | 
						|
        if ESX then
 | 
						|
            local job = p.getJob()
 | 
						|
            if not job then return end
 | 
						|
 | 
						|
            return {
 | 
						|
                name = job.name,
 | 
						|
                label = job.label,
 | 
						|
                grade = job.grade,
 | 
						|
                gradeLabel = job.gradeLabel
 | 
						|
            }
 | 
						|
        elseif QB then
 | 
						|
            return {
 | 
						|
                name = _fwp.PlayerData.gang.name,
 | 
						|
                label = _fwp.PlayerData.gang.label,
 | 
						|
                grade = _fwp.PlayerData.gang.grade.level,
 | 
						|
                gradeLabel = _fwp.PlayerData.gang.grade.name
 | 
						|
            }
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param item string
 | 
						|
    ---@return { name: string, label: string, amount: number } item
 | 
						|
    p.getItem = function(item)
 | 
						|
        if not item then return end
 | 
						|
 | 
						|
        if OXInv then
 | 
						|
            item = OXInv:GetItem(_fwp.source, item, nil, false)
 | 
						|
            if not item then return end
 | 
						|
 | 
						|
            return {
 | 
						|
                name = item.name,
 | 
						|
                label = item.label,
 | 
						|
                amount = item.count
 | 
						|
            }
 | 
						|
        elseif ESX then
 | 
						|
            if CHEZZAInv and string.find(item:lower(), 'weapon') then
 | 
						|
                local loadoutNum, weapon = _fwp.getWeapon(item)
 | 
						|
 | 
						|
                if weapon then
 | 
						|
                    item = weapon
 | 
						|
                    item.count = 1 -- CHEZZAInv compatibility fix
 | 
						|
                end
 | 
						|
            else
 | 
						|
                item = _fwp.getInventoryItem(item)
 | 
						|
            end
 | 
						|
 | 
						|
            if not item then return end
 | 
						|
 | 
						|
            return {
 | 
						|
                name = item.name,
 | 
						|
                label = item.label,
 | 
						|
                amount = item.count
 | 
						|
            }
 | 
						|
        elseif QB then
 | 
						|
            item = _fwp.Functions.GetItemByName(item)
 | 
						|
            if not item then return end
 | 
						|
 | 
						|
            return {
 | 
						|
                name = item.name,
 | 
						|
                label = item.label,
 | 
						|
                amount = item.amount
 | 
						|
            }
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return { [slot]: { name: string, amount: number, label: string, metadata?: any } } inventory
 | 
						|
    p.getItems = function()
 | 
						|
        local inventory = {}
 | 
						|
 | 
						|
        if OXInv then
 | 
						|
            local items = OXInv:GetInventory(_fwp.source).items
 | 
						|
 | 
						|
            for slot, item in pairs(items) do
 | 
						|
                inventory[slot] = {
 | 
						|
                    name = item.name,
 | 
						|
                    label = item.label,
 | 
						|
                    amount = item.count,
 | 
						|
                    metadata = item.metadata,
 | 
						|
                }
 | 
						|
            end
 | 
						|
        elseif QSInv then
 | 
						|
            local items = QSInv:GetInventory(_fwp.source)
 | 
						|
            for itemName, itemData in pairs(items) do
 | 
						|
                inventory[itemData.slot] = {
 | 
						|
                    name = itemName,
 | 
						|
                    label = itemData.label,
 | 
						|
                    amount = itemData.count,
 | 
						|
                    metadata = itemData.info,
 | 
						|
                }
 | 
						|
            end
 | 
						|
        elseif COREInv then
 | 
						|
            local items = COREInv:getInventory()
 | 
						|
            for _, item in pairs(items) do
 | 
						|
                inventory[item.slot] = {
 | 
						|
                    name = item.name,
 | 
						|
                    label = item.label,
 | 
						|
                    amount = item.amount,
 | 
						|
                    metadata = item.metadata,
 | 
						|
                }
 | 
						|
            end
 | 
						|
        elseif ESX then
 | 
						|
            local items = _fwp.getInventory()
 | 
						|
            for slot, item in pairs(items) do
 | 
						|
                inventory[slot] = {
 | 
						|
                    name = item.name,
 | 
						|
                    label = item.label,
 | 
						|
                    amount = item.count
 | 
						|
                }
 | 
						|
            end
 | 
						|
        elseif QB then
 | 
						|
            local items = _fwp.PlayerData.items
 | 
						|
            for slot, item in pairs(items) do
 | 
						|
                if item.amount == nil then item.amount = item.count end -- Simple QBox compatibility fix
 | 
						|
 | 
						|
                inventory[slot] = {
 | 
						|
                    name = item.name,
 | 
						|
                    label = item.label,
 | 
						|
                    amount = item.amount,
 | 
						|
                    metadata = item.info,
 | 
						|
                }
 | 
						|
            end
 | 
						|
        end
 | 
						|
 | 
						|
        return inventory
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return string firstName
 | 
						|
    p.getFirstName = function()
 | 
						|
        if ESX then return string.split(_fwp.getName(), ' ')[1]
 | 
						|
        elseif QB then return _fwp.PlayerData.charinfo.firstname end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return string lastName
 | 
						|
    p.getLastName = function()
 | 
						|
        if ESX then return string.split(_fwp.getName(), ' ')[2]
 | 
						|
        elseif QB then return _fwp.PlayerData.charinfo.lastname end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return string fullName
 | 
						|
    p.getFullName = function()
 | 
						|
        if ESX then return _fwp.getName()
 | 
						|
        elseif QB then return _fwp.PlayerData.charinfo.firstname .. ' ' .. _fwp.PlayerData.charinfo.lastname end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param item string
 | 
						|
    ---@param amount number
 | 
						|
    ---@return boolean
 | 
						|
    p.hasItemAmount = function(item, amount)
 | 
						|
        if not item then return end
 | 
						|
 | 
						|
        item = p.getItem(item)
 | 
						|
        return item and item.amount >= amount or false
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return boolean
 | 
						|
    p.isAdmin = function()
 | 
						|
        if ESX then
 | 
						|
            if _fwp.getGroup() == Defaults.ADMIN_ESX then
 | 
						|
                return true
 | 
						|
            end
 | 
						|
        elseif QB then
 | 
						|
            if QB.Functions.HasPermission(_fwp.source, Defaults.ADMIN_QB) or QB.Functions.HasPermission(_fwp.source, Defaults.GOD_QB) then
 | 
						|
                return true
 | 
						|
            end
 | 
						|
        end
 | 
						|
 | 
						|
        return IsPlayerAceAllowed(_fwp.source, 'command')
 | 
						|
 | 
						|
        -- Want custom admin group? Uncomment below and add the group in server.cfg
 | 
						|
        -- IN SERVER.CFG: add_ace group.admin fmLib.admin allow
 | 
						|
        -- return IsPlayerAceAllowed(_fwp.source, 'fmLib.admin')
 | 
						|
    end
 | 
						|
 | 
						|
    ---@return string | table group
 | 
						|
    p.getGroup = function()
 | 
						|
        if ESX then return _fwp.getGroup()
 | 
						|
        elseif QB then return QB.Functions.GetPermission(_fwp.source) end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param message string
 | 
						|
    ---@param type? 'success'|'error'
 | 
						|
    p.notify = function(message, type)
 | 
						|
        if not message then return end
 | 
						|
 | 
						|
        if ESX then TriggerClientEvent('esx:showNotification', _fwp.source, message, type)
 | 
						|
        elseif QB then TriggerClientEvent('QBCore:Notify', _fwp.source, message, type) end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param item string
 | 
						|
    ---@param amount number
 | 
						|
    ---@param slotId? number
 | 
						|
    ---@param metadata? any
 | 
						|
    p.removeItem = function(item, amount, slotId, metadata)
 | 
						|
        if not item or not amount then return end
 | 
						|
 | 
						|
        if OXInv then OXInv:RemoveItem(_fwp.source, item, amount, metadata, slotId)
 | 
						|
        elseif ESX then _fwp.removeInventoryItem(item, amount)
 | 
						|
        elseif QB then _fwp.Functions.RemoveItem(item, amount) end
 | 
						|
    end
 | 
						|
 | 
						|
    ---@param amount number
 | 
						|
    ---@param moneyType? string
 | 
						|
    ---@param transactionData? { type?: 'deposit' | 'withdraw' | 'transfer' | 'interest' | 'payment', reason?: string, toIban?: string }
 | 
						|
    p.removeMoney = function(amount, moneyType, transactionData)
 | 
						|
        moneyType = moneyType or Defaults.MONEY
 | 
						|
        if not amount then return end
 | 
						|
 | 
						|
        if transactionData and moneyType == 'bank' then
 | 
						|
            if GetResourceState(Resources.RX_BANKING.name) == 'started' then
 | 
						|
                local personalAcc = exports[Resources.RX_BANKING.name]:GetPlayerPersonalAccount(p.getIdentifier())
 | 
						|
                if personalAcc then
 | 
						|
                    exports[Resources.RX_BANKING.name]:CreateTransaction(amount, transactionData.type, personalAcc.iban, transactionData.toIban, transactionData.reason)
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
 | 
						|
        if ESX then _fwp.removeAccountMoney(moneyType, amount)
 | 
						|
        elseif QB then _fwp.Functions.RemoveMoney(moneyType, amount) end
 | 
						|
    end
 | 
						|
 | 
						|
    return p
 | 
						|
end
 | 
						|
 | 
						|
--[[
 | 
						|
    INTERNAL EVENT HANDLERS
 | 
						|
    DO NOT USE
 | 
						|
--]]
 | 
						|
 | 
						|
FM.callback.register('fm:internal:getGang', function(src)
 | 
						|
    return FM.player.get(src).getGang()
 | 
						|
end)
 | 
						|
 | 
						|
-- Aliases
 | 
						|
FM.p = FM.player
 |