1
0
Fork 0
forked from Simnation/Main
Main/resources/[standalone]/fmLib/wrappers/server/player.lua
2025-06-07 08:51:21 +02:00

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