mirror of
https://github.com/qbcore-fivem/qb-core.git
synced 2026-08-29 01:08:57 +00:00
reset branch
This commit is contained in:
+671
-112
@@ -1,14 +1,444 @@
|
||||
-- Callbacks
|
||||
QBCore.Functions = {}
|
||||
QBCore.Player_Buckets = {}
|
||||
QBCore.Entity_Buckets = {}
|
||||
QBCore.UsableItems = {}
|
||||
|
||||
function QBCore.Functions.CreateCallback(name, cb)
|
||||
QBCore.ServerCallbacks[name] = cb
|
||||
-- Getters
|
||||
-- Get your player first and then trigger a function on them
|
||||
-- ex: local player = QBCore.Functions.GetPlayer(source)
|
||||
-- ex: local example = player.Functions.functionname(parameter)
|
||||
|
||||
---Gets the coordinates of an entity
|
||||
---@param entity number
|
||||
---@return vector4
|
||||
function QBCore.Functions.GetCoords(entity)
|
||||
local coords = GetEntityCoords(entity, false)
|
||||
local heading = GetEntityHeading(entity)
|
||||
return vector4(coords.x, coords.y, coords.z, heading)
|
||||
end
|
||||
|
||||
---Gets player identifier of the given type
|
||||
---@param source any
|
||||
---@param idtype string
|
||||
---@return string?
|
||||
function QBCore.Functions.GetIdentifier(source, idtype)
|
||||
if GetConvarInt('sv_fxdkMode', 0) == 1 then return 'license:fxdk' end
|
||||
return GetPlayerIdentifierByType(source, idtype or 'license')
|
||||
end
|
||||
|
||||
---Gets a players server id (source). Returns 0 if no player is found.
|
||||
---@param identifier string
|
||||
---@return number
|
||||
function QBCore.Functions.GetSource(identifier)
|
||||
for src, _ in pairs(QBCore.Players) do
|
||||
local idens = GetPlayerIdentifiers(src)
|
||||
for _, id in pairs(idens) do
|
||||
if identifier == id then
|
||||
return src
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
---Get player with given server id (source)
|
||||
---@param source any
|
||||
---@return table
|
||||
function QBCore.Functions.GetPlayer(source)
|
||||
if tonumber(source) ~= nil then -- If a number is a string ("1"), this will still correctly identify the index to use.
|
||||
return QBCore.Players[tonumber(source)]
|
||||
else
|
||||
return QBCore.Players[QBCore.Functions.GetSource(source)]
|
||||
end
|
||||
end
|
||||
|
||||
---Get player by citizen id
|
||||
---@param citizenid string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByCitizenId(citizenid)
|
||||
for src in pairs(QBCore.Players) do
|
||||
if QBCore.Players[src].PlayerData.citizenid == citizenid then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get offline player by citizen id
|
||||
---@param citizenid string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetOfflinePlayerByCitizenId(citizenid)
|
||||
return QBCore.Player.GetOfflinePlayer(citizenid)
|
||||
end
|
||||
|
||||
---Get player by license
|
||||
---@param license string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByLicense(license)
|
||||
return QBCore.Player.GetPlayerByLicense(license)
|
||||
end
|
||||
|
||||
---Get player by phone number
|
||||
---@param number number
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByPhone(number)
|
||||
for src in pairs(QBCore.Players) do
|
||||
if QBCore.Players[src].PlayerData.charinfo.phone == number then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get player by account id
|
||||
---@param account string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByAccount(account)
|
||||
for src in pairs(QBCore.Players) do
|
||||
if QBCore.Players[src].PlayerData.charinfo.account == account then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get player passing property and value to check exists
|
||||
---@param property string
|
||||
---@param value string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByCharInfo(property, value)
|
||||
for src in pairs(QBCore.Players) do
|
||||
local charinfo = QBCore.Players[src].PlayerData.charinfo
|
||||
if charinfo[property] ~= nil and charinfo[property] == value then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get all players. Returns the server ids of all players.
|
||||
---@return table
|
||||
function QBCore.Functions.GetPlayers()
|
||||
local sources = {}
|
||||
for k in pairs(QBCore.Players) do
|
||||
sources[#sources + 1] = k
|
||||
end
|
||||
return sources
|
||||
end
|
||||
|
||||
---Will return an array of QB Player class instances
|
||||
---unlike the GetPlayers() wrapper which only returns IDs
|
||||
---@return table
|
||||
function QBCore.Functions.GetQBPlayers()
|
||||
return QBCore.Players
|
||||
end
|
||||
|
||||
---Gets a list of all on duty players of a specified job and the number
|
||||
---@param job string
|
||||
---@return table, number
|
||||
function QBCore.Functions.GetPlayersOnDuty(job)
|
||||
local players = {}
|
||||
local count = 0
|
||||
for src, Player in pairs(QBCore.Players) do
|
||||
if Player.PlayerData.job.name == job then
|
||||
if Player.PlayerData.job.onduty then
|
||||
players[#players + 1] = src
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return players, count
|
||||
end
|
||||
|
||||
---Returns only the amount of players on duty for the specified job
|
||||
---@param job string
|
||||
---@return number
|
||||
function QBCore.Functions.GetDutyCount(job)
|
||||
local count = 0
|
||||
for _, Player in pairs(QBCore.Players) do
|
||||
if Player.PlayerData.job.name == job then
|
||||
if Player.PlayerData.job.onduty then
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return string closestPlayer - The Player that is closest to the source player (or the provided coordinates). Returns -1 if no Players are found.
|
||||
--- @return number closestDistance - The distance to the closest Player. Returns -1 if no Players are found.
|
||||
function QBCore.Functions.GetClosestPlayer(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local players = GetPlayers()
|
||||
local closestDistance, closestPlayer = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #players do
|
||||
local playerId = players[i]
|
||||
local playerPed = GetPlayerPed(playerId)
|
||||
if playerPed ~= ped then
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local distance = #(playerCoords - coords)
|
||||
if closestDistance == -1 or distance < closestDistance then
|
||||
closestPlayer = playerId
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPlayer, closestDistance
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return number closestObject - The Object that is closest to the source player (or the provided coordinates). Returns -1 if no Objects are found.
|
||||
--- @return number closestDistance - The distance to the closest Object. Returns -1 if no Objects are found.
|
||||
function QBCore.Functions.GetClosestObject(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local objects = GetAllObjects()
|
||||
local closestDistance, closestObject = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #objects do
|
||||
local objectCoords = GetEntityCoords(objects[i])
|
||||
local distance = #(objectCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestObject = objects[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestObject, closestDistance
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return number closestVehicle - The Vehicle that is closest to the source player (or the provided coordinates). Returns -1 if no Vehicles are found.
|
||||
--- @return number closestDistance - The distance to the closest Vehicle. Returns -1 if no Vehicles are found.
|
||||
function QBCore.Functions.GetClosestVehicle(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local vehicles = GetAllVehicles()
|
||||
local closestDistance, closestVehicle = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #vehicles do
|
||||
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||
local distance = #(vehicleCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestVehicle = vehicles[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestVehicle, closestDistance
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return number closestPed - The Ped that is closest to the source player (or the provided coordinates). Returns -1 if no Peds are found.
|
||||
--- @return number closestDistance - The distance to the closest Ped. Returns -1 if no Peds are found.
|
||||
function QBCore.Functions.GetClosestPed(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local peds = GetAllPeds()
|
||||
local closestDistance, closestPed = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #peds do
|
||||
if peds[i] ~= ped then
|
||||
local pedCoords = GetEntityCoords(peds[i])
|
||||
local distance = #(pedCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestPed = peds[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPed, closestDistance
|
||||
end
|
||||
|
||||
-- Routing buckets (Only touch if you know what you are doing)
|
||||
|
||||
---Returns the objects related to buckets, first returned value is the player buckets, second one is entity buckets
|
||||
---@return table, table
|
||||
function QBCore.Functions.GetBucketObjects()
|
||||
return QBCore.Player_Buckets, QBCore.Entity_Buckets
|
||||
end
|
||||
|
||||
---Will set the provided player id / source into the provided bucket id
|
||||
---@param source any
|
||||
---@param bucket any
|
||||
---@return boolean
|
||||
function QBCore.Functions.SetPlayerBucket(source, bucket)
|
||||
if source and bucket then
|
||||
local plicense = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
Player(source).state:set('instance', bucket, true)
|
||||
SetPlayerRoutingBucket(source, bucket)
|
||||
QBCore.Player_Buckets[plicense] = { id = source, bucket = bucket }
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Will set any entity into the provided bucket, for example peds / vehicles / props / etc.
|
||||
---@param entity number
|
||||
---@param bucket number
|
||||
---@return boolean
|
||||
function QBCore.Functions.SetEntityBucket(entity, bucket)
|
||||
if entity and bucket then
|
||||
SetEntityRoutingBucket(entity, bucket)
|
||||
QBCore.Entity_Buckets[entity] = { id = entity, bucket = bucket }
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Will return an array of all the player ids inside the current bucket
|
||||
---@param bucket number
|
||||
---@return table|boolean
|
||||
function QBCore.Functions.GetPlayersInBucket(bucket)
|
||||
local curr_bucket_pool = {}
|
||||
if QBCore.Player_Buckets and next(QBCore.Player_Buckets) then
|
||||
for _, v in pairs(QBCore.Player_Buckets) do
|
||||
if v.bucket == bucket then
|
||||
curr_bucket_pool[#curr_bucket_pool + 1] = v.id
|
||||
end
|
||||
end
|
||||
return curr_bucket_pool
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Will return an array of all the entities inside the current bucket
|
||||
---(not for player entities, use GetPlayersInBucket for that)
|
||||
---@param bucket number
|
||||
---@return table|boolean
|
||||
function QBCore.Functions.GetEntitiesInBucket(bucket)
|
||||
local curr_bucket_pool = {}
|
||||
if QBCore.Entity_Buckets and next(QBCore.Entity_Buckets) then
|
||||
for _, v in pairs(QBCore.Entity_Buckets) do
|
||||
if v.bucket == bucket then
|
||||
curr_bucket_pool[#curr_bucket_pool + 1] = v.id
|
||||
end
|
||||
end
|
||||
return curr_bucket_pool
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Server side vehicle creation with optional callback
|
||||
---the CreateVehicle RPC still uses the client for creation so players must be near
|
||||
---@param source any
|
||||
---@param model any
|
||||
---@param coords vector
|
||||
---@param warp boolean
|
||||
---@return number
|
||||
function QBCore.Functions.SpawnVehicle(source, model, coords, warp)
|
||||
local ped = GetPlayerPed(source)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, true)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then
|
||||
while GetVehiclePedIsIn(ped) ~= veh do
|
||||
Wait(0)
|
||||
TaskWarpPedIntoVehicle(ped, veh, -1)
|
||||
end
|
||||
end
|
||||
while NetworkGetEntityOwner(veh) ~= source do Wait(0) end
|
||||
return veh
|
||||
end
|
||||
|
||||
---Server side vehicle creation with optional callback
|
||||
---the CreateAutomobile native is still experimental but doesn't use client for creation
|
||||
---doesn't work for all vehicles!
|
||||
---comment
|
||||
---@param source any
|
||||
---@param model any
|
||||
---@param coords vector
|
||||
---@param warp boolean
|
||||
---@return number
|
||||
function QBCore.Functions.CreateAutomobile(source, model, coords, warp)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
if not coords then coords = GetEntityCoords(GetPlayerPed(source)) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local CreateAutomobile = `CREATE_AUTOMOBILE`
|
||||
local veh = Citizen.InvokeNative(CreateAutomobile, model, coords, heading, true, true)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then TaskWarpPedIntoVehicle(GetPlayerPed(source), veh, -1) end
|
||||
return veh
|
||||
end
|
||||
|
||||
--- New & more reliable server side native for creating vehicles
|
||||
---comment
|
||||
---@param source any
|
||||
---@param model any
|
||||
---@param vehtype any
|
||||
-- The appropriate vehicle type for the model info.
|
||||
-- Can be one of automobile, bike, boat, heli, plane, submarine, trailer, and (potentially), train.
|
||||
-- This should be the same type as the type field in vehicles.meta.
|
||||
---@param coords vector
|
||||
---@param warp boolean
|
||||
---@return number
|
||||
function QBCore.Functions.CreateVehicle(source, model, vehtype, coords, warp)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
vehtype = type(vehtype) == 'string' and tostring(vehtype) or vehtype
|
||||
if not coords then coords = GetEntityCoords(GetPlayerPed(source)) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local veh = CreateVehicleServerSetter(model, vehtype, coords, heading)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then TaskWarpPedIntoVehicle(GetPlayerPed(source), veh, -1) end
|
||||
return veh
|
||||
end
|
||||
|
||||
function PaycheckInterval()
|
||||
if not next(QBCore.Players) then
|
||||
SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckInterval) -- Prevent paychecks from stopping forever once 0 players
|
||||
return
|
||||
end
|
||||
for _, Player in pairs(QBCore.Players) do
|
||||
if not Player then return end
|
||||
local payment = QBShared.Jobs[Player.PlayerData.job.name]['grades'][tostring(Player.PlayerData.job.grade.level)].payment
|
||||
if not payment then payment = Player.PlayerData.job.payment end
|
||||
if Player.PlayerData.job and payment > 0 and (QBShared.Jobs[Player.PlayerData.job.name].offDutyPay or Player.PlayerData.job.onduty) then
|
||||
if QBCore.Config.Money.PayCheckSociety then
|
||||
local account = exports['qb-banking']:GetAccountBalance(Player.PlayerData.job.name)
|
||||
if account ~= 0 then
|
||||
if account < payment then
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('error.company_too_poor'), 'error')
|
||||
else
|
||||
Player.Functions.AddMoney('bank', payment, 'paycheck')
|
||||
exports['qb-banking']:RemoveMoney(Player.PlayerData.job.name, payment, 'Employee Paycheck')
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment }))
|
||||
end
|
||||
else
|
||||
Player.Functions.AddMoney('bank', payment, 'paycheck')
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment }))
|
||||
end
|
||||
else
|
||||
Player.Functions.AddMoney('bank', payment, 'paycheck')
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment }))
|
||||
end
|
||||
end
|
||||
end
|
||||
SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckInterval)
|
||||
end
|
||||
|
||||
-- Callback Functions --
|
||||
|
||||
---Trigger Client Callback
|
||||
---@param name string
|
||||
---@param source any
|
||||
---@param cb function
|
||||
---@param ... any
|
||||
function QBCore.Functions.TriggerClientCallback(name, source, ...)
|
||||
local cb = nil
|
||||
local args = { ... }
|
||||
|
||||
if QBCore.Functions.IsFunction(args[1]) then
|
||||
if QBCore.Shared.IsFunction(args[1]) then
|
||||
cb = args[1]
|
||||
table.remove(args, 1)
|
||||
end
|
||||
@@ -26,8 +456,201 @@ function QBCore.Functions.TriggerClientCallback(name, source, ...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Functions
|
||||
---Create Server Callback
|
||||
---@param name string
|
||||
---@param cb function
|
||||
function QBCore.Functions.CreateCallback(name, cb)
|
||||
QBCore.ServerCallbacks[name] = cb
|
||||
end
|
||||
|
||||
-- Items
|
||||
|
||||
---Create a usable item
|
||||
---@param item string
|
||||
---@param data function
|
||||
function QBCore.Functions.CreateUseableItem(item, data)
|
||||
local rawFunc = nil
|
||||
|
||||
if type(data) == 'table' then
|
||||
if rawget(data, '__cfx_functionReference') then
|
||||
rawFunc = data
|
||||
elseif data.cb and rawget(data.cb, '__cfx_functionReference') then
|
||||
rawFunc = data.cb
|
||||
elseif data.callback and rawget(data.callback, '__cfx_functionReference') then
|
||||
rawFunc = data.callback
|
||||
end
|
||||
elseif type(data) == 'function' then
|
||||
rawFunc = data
|
||||
end
|
||||
|
||||
if rawFunc then
|
||||
QBCore.UsableItems[item] = {
|
||||
func = rawFunc,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
---Checks if the given item is usable
|
||||
---@param item string
|
||||
---@return any
|
||||
function QBCore.Functions.CanUseItem(item)
|
||||
return QBCore.UsableItems[item]
|
||||
end
|
||||
|
||||
---Use item
|
||||
---@param source any
|
||||
---@param item string
|
||||
function QBCore.Functions.UseItem(source, item)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
exports['qb-inventory']:UseItem(source, item)
|
||||
end
|
||||
|
||||
---Kick Player
|
||||
---@param source any
|
||||
---@param reason string
|
||||
---@param setKickReason boolean
|
||||
---@param deferrals boolean
|
||||
function QBCore.Functions.Kick(source, reason, setKickReason, deferrals)
|
||||
reason = '\n' .. reason .. '\n🔸 Check our Discord for further information: ' .. QBCore.Config.Server.Discord
|
||||
if setKickReason then
|
||||
setKickReason(reason)
|
||||
end
|
||||
CreateThread(function()
|
||||
if deferrals then
|
||||
deferrals.update(reason)
|
||||
Wait(2500)
|
||||
end
|
||||
if source then
|
||||
DropPlayer(source, reason)
|
||||
end
|
||||
for _ = 0, 4 do
|
||||
while true do
|
||||
if source then
|
||||
if GetPlayerPing(source) >= 0 then
|
||||
break
|
||||
end
|
||||
Wait(100)
|
||||
CreateThread(function()
|
||||
DropPlayer(source, reason)
|
||||
end)
|
||||
end
|
||||
end
|
||||
Wait(5000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
---Check if player is whitelisted, kept like this for backwards compatibility or future plans
|
||||
---@param source any
|
||||
---@return boolean
|
||||
function QBCore.Functions.IsWhitelisted(source)
|
||||
if not QBCore.Config.Server.Whitelist then return true end
|
||||
if QBCore.Functions.HasPermission(source, QBCore.Config.Server.WhitelistPermission) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Setting & Removing Permissions
|
||||
|
||||
---Add permission for player
|
||||
---@param source any
|
||||
---@param permission string
|
||||
function QBCore.Functions.AddPermission(source, permission)
|
||||
if not IsPlayerAceAllowed(source, permission) then
|
||||
ExecuteCommand(('add_principal player.%s qbcore.%s'):format(source, permission))
|
||||
QBCore.Commands.Refresh(source)
|
||||
end
|
||||
end
|
||||
|
||||
---Remove permission from player
|
||||
---@param source any
|
||||
---@param permission string
|
||||
function QBCore.Functions.RemovePermission(source, permission)
|
||||
if permission then
|
||||
if IsPlayerAceAllowed(source, permission) then
|
||||
ExecuteCommand(('remove_principal player.%s qbcore.%s'):format(source, permission))
|
||||
QBCore.Commands.Refresh(source)
|
||||
end
|
||||
else
|
||||
for _, v in pairs(QBCore.Config.Server.Permissions) do
|
||||
if IsPlayerAceAllowed(source, v) then
|
||||
ExecuteCommand(('remove_principal player.%s qbcore.%s'):format(source, v))
|
||||
QBCore.Commands.Refresh(source)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Checking for Permission Level
|
||||
|
||||
---Check if player has permission
|
||||
---@param source any
|
||||
---@param permission string
|
||||
---@return boolean
|
||||
function QBCore.Functions.HasPermission(source, permission)
|
||||
if type(permission) == 'string' then
|
||||
if IsPlayerAceAllowed(source, permission) then return true end
|
||||
elseif type(permission) == 'table' then
|
||||
for _, permLevel in pairs(permission) do
|
||||
if IsPlayerAceAllowed(source, permLevel) then return true end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
---Get the players permissions
|
||||
---@param source any
|
||||
---@return table
|
||||
function QBCore.Functions.GetPermission(source)
|
||||
local src = source
|
||||
local perms = {}
|
||||
for _, v in pairs(QBCore.Config.Server.Permissions) do
|
||||
if IsPlayerAceAllowed(src, v) then
|
||||
perms[v] = true
|
||||
end
|
||||
end
|
||||
return perms
|
||||
end
|
||||
|
||||
---Get admin messages opt-in state for player
|
||||
---@param source any
|
||||
---@return boolean
|
||||
function QBCore.Functions.IsOptin(source)
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
if not license or not QBCore.Functions.HasPermission(source, 'admin') then return false end
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
return Player.PlayerData.optin
|
||||
end
|
||||
|
||||
---Toggle opt-in to admin messages
|
||||
---@param source any
|
||||
function QBCore.Functions.ToggleOptin(source)
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
if not license or not QBCore.Functions.HasPermission(source, 'admin') then return end
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
Player.PlayerData.optin = not Player.PlayerData.optin
|
||||
Player.Functions.SetPlayerData('optin', Player.PlayerData.optin)
|
||||
end
|
||||
|
||||
---Check if player is banned
|
||||
---@param source any
|
||||
---@return boolean, string?
|
||||
function QBCore.Functions.IsPlayerBanned(source)
|
||||
local plicense = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local result = MySQL.single.await('SELECT id, reason, expire FROM bans WHERE license = ?', { plicense })
|
||||
if not result then return false end
|
||||
if os.time() < result.expire then
|
||||
local timeTable = os.date('*t', tonumber(result.expire))
|
||||
return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n'
|
||||
else
|
||||
MySQL.query('DELETE FROM bans WHERE id = ?', { result.id })
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Retrieves information about the database connection.
|
||||
--- @return table; A table containing the database information.
|
||||
function QBCore.Functions.GetDatabaseInfo()
|
||||
local details = {
|
||||
exists = false,
|
||||
@@ -56,11 +679,9 @@ function QBCore.Functions.GetDatabaseInfo()
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetIdentifier(source, idtype)
|
||||
if GetConvarInt('sv_fxdkMode', 0) == 1 then return 'license:fxdk' end
|
||||
return GetPlayerIdentifierByType(source, idtype or 'license')
|
||||
end
|
||||
|
||||
---Check for duplicate license
|
||||
---@param license any
|
||||
---@return boolean
|
||||
function QBCore.Functions.IsLicenseInUse(license)
|
||||
local players = GetPlayers()
|
||||
for _, player in pairs(players) do
|
||||
@@ -70,111 +691,49 @@ function QBCore.Functions.IsLicenseInUse(license)
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.HasPermission(source, permission)
|
||||
if type(permission) == 'string' then
|
||||
if IsPlayerAceAllowed(source, permission) then return true end
|
||||
elseif type(permission) == 'table' then
|
||||
for _, permLevel in pairs(permission) do
|
||||
if IsPlayerAceAllowed(source, permLevel) then return true end
|
||||
end
|
||||
-- Utility functions
|
||||
|
||||
---Check if a player has an item [deprecated]
|
||||
---@param source any
|
||||
---@param items table|string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
function QBCore.Functions.HasItem(source, items, amount)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
return exports['qb-inventory']:HasItem(source, items, amount)
|
||||
end
|
||||
|
||||
---Notify
|
||||
---@param source any
|
||||
---@param text string
|
||||
---@param type string
|
||||
---@param length number
|
||||
function QBCore.Functions.Notify(source, text, type, length)
|
||||
TriggerClientEvent('QBCore:Notify', source, text, type, length)
|
||||
end
|
||||
|
||||
---???? ... ok
|
||||
---@param source any
|
||||
---@param data any
|
||||
---@param pattern any
|
||||
---@return boolean
|
||||
function QBCore.Functions.PrepForSQL(source, data, pattern)
|
||||
data = tostring(data)
|
||||
local src = source
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
local result = string.match(data, pattern)
|
||||
if not result or string.len(result) ~= string.len(data) then
|
||||
TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'SQL Exploit Attempted', 'red', string.format('%s attempted to exploit SQL!', player.PlayerData.license))
|
||||
return false
|
||||
end
|
||||
return false
|
||||
return true
|
||||
end
|
||||
|
||||
function QBCore.Functions.IsWhitelisted(source)
|
||||
if not QBCore.Config.Server.Whitelist then return true end
|
||||
if QBCore.Functions.HasPermission(source, QBCore.Config.Server.WhitelistPermission) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.IsPlayerBanned(source)
|
||||
local plicense = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local result = MySQL.single.await('SELECT id, reason, expire FROM bans WHERE license = ?', { plicense })
|
||||
if not result then return false end
|
||||
if os.time() < result.expire then
|
||||
local timeTable = os.date('*t', tonumber(result.expire))
|
||||
return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n'
|
||||
else
|
||||
MySQL.query('DELETE FROM bans WHERE id = ?', { result.id })
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetPlayer(source)
|
||||
if tonumber(source) then
|
||||
return QBCore.Players[tonumber(source)]
|
||||
else
|
||||
return QBCore.Players[QBCore.Functions.GetSource(source)]
|
||||
for functionName, func in pairs(QBCore.Functions) do
|
||||
if type(func) == 'function' then
|
||||
exports(functionName, func)
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetQBPlayers()
|
||||
return QBCore.Players
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateUseableItem(item, data)
|
||||
local rawFunc = nil
|
||||
|
||||
if type(data) == 'table' then
|
||||
if rawget(data, '__cfx_functionReference') then
|
||||
rawFunc = data
|
||||
elseif data.cb and rawget(data.cb, '__cfx_functionReference') then
|
||||
rawFunc = data.cb
|
||||
elseif data.callback and rawget(data.callback, '__cfx_functionReference') then
|
||||
rawFunc = data.callback
|
||||
end
|
||||
elseif type(data) == 'function' then
|
||||
rawFunc = data
|
||||
end
|
||||
|
||||
if rawFunc then
|
||||
QBCore.UsableItems[item] = {
|
||||
func = rawFunc,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- Player Setup
|
||||
|
||||
function QBCore.Functions.CreateCitizenId()
|
||||
local CitizenId = tostring(QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(5)):upper()
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE citizenid = ?) AS uniqueCheck', { CitizenId })
|
||||
if result == 0 then return CitizenId end
|
||||
return QBCore.Functions.CreateCitizenId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateAccountNumber()
|
||||
local AccountNumber = 'US0' .. math.random(1, 9) .. 'QBCore' .. math.random(1111, 9999) .. math.random(1111, 9999) .. math.random(11, 99)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.account")) = ?) AS uniqueCheck', { AccountNumber })
|
||||
if result == 0 then return AccountNumber end
|
||||
return QBCore.Functions.CreateAccountNumber()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreatePhoneNumber()
|
||||
local PhoneNumber = math.random(100, 999) .. math.random(1000000, 9999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.phone")) = ?) AS uniqueCheck', { PhoneNumber })
|
||||
if result == 0 then return PhoneNumber end
|
||||
return QBCore.Functions.CreatePhoneNumber()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateFingerId()
|
||||
local FingerId = tostring(QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(1) .. QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(4))
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.fingerprint")) = ?) AS uniqueCheck', { FingerId })
|
||||
if result == 0 then return FingerId end
|
||||
return QBCore.Functions.CreateFingerId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateWalletId()
|
||||
local WalletId = 'QB-' .. math.random(11111111, 99999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.walletid")) = ?) AS uniqueCheck', { WalletId })
|
||||
if result == 0 then return WalletId end
|
||||
return QBCore.Functions.CreateWalletId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateSerialNumber()
|
||||
local SerialNumber = math.random(11111111, 99999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.phonedata.SerialNumber")) = ?) AS uniqueCheck', { SerialNumber })
|
||||
if result == 0 then return SerialNumber end
|
||||
return QBCore.Functions.CreateSerialNumber()
|
||||
end
|
||||
-- Access a specific function directly:
|
||||
-- exports['qb-core']:Notify(source, 'Hello Player!')
|
||||
|
||||
Reference in New Issue
Block a user