Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add playerID feature to replace source ID #1171

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions client/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function QBCore.Functions.TriggerCallback(name, ...)
end
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Debug(resource, obj, depth)
TriggerServerEvent('QBCore:DebugSomething', resource, obj, depth)
end
Expand All @@ -39,11 +40,13 @@ function QBCore.Functions.GetPlayerData(cb)
cb(QBCore.PlayerData)
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetCoords(entity)
local coords = GetEntityCoords(entity)
return vector4(coords.x, coords.y, coords.z, GetEntityHeading(entity))
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.HasItem(items, amount)
return exports['qb-inventory']:HasItem(items, amount)
end
Expand Down Expand Up @@ -105,7 +108,7 @@ function QBCore.Functions.LookAtEntity(entity, timeout, speed)
end

-- Function to run an animation
--- @param animDic string: The name of the animation dictionary
--- @param animDict string: The name of the animation dictionary
--- @param animName string - The name of the animation within the dictionary
--- @param duration number - The duration of the animation in milliseconds. -1 will play the animation indefinitely
--- @param upperbodyOnly boolean - If true, the animation will only affect the upper body of the ped
Expand Down Expand Up @@ -167,7 +170,7 @@ function QBCore.Functions.IsWearingGloves()
end

-- NUI Calls

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.Notify(text, texttype, length, icon)
local message = {
action = 'notify',
Expand Down Expand Up @@ -224,6 +227,7 @@ function QBCore.Functions.GetObjects()
return GetGamePool('CObject')
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetPlayers()
return GetActivePlayers()
end
Expand All @@ -248,6 +252,7 @@ function QBCore.Functions.GetPlayersFromCoords(coords, distance)
return closePlayers
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestPlayer(coords)
local ped = PlayerPedId()
if coords then
Expand Down Expand Up @@ -288,6 +293,7 @@ function QBCore.Functions.GetPeds(ignoreList)
return peds
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestPed(coords, ignoreList)
local ped = PlayerPedId()
if coords then
Expand All @@ -311,6 +317,7 @@ function QBCore.Functions.GetClosestPed(coords, ignoreList)
return closestPed, closestDistance
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestVehicle(coords)
local ped = PlayerPedId()
local vehicles = GetGamePool('CVehicle')
Expand All @@ -333,6 +340,7 @@ function QBCore.Functions.GetClosestVehicle(coords)
return closestVehicle, closestDistance
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestObject(coords)
local ped = PlayerPedId()
local objects = GetGamePool('CObject')
Expand Down Expand Up @@ -364,6 +372,7 @@ function QBCore.Functions.LoadModel(model)
end
end

---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.SpawnVehicle(model, cb, coords, isnetworked, teleportInto)
local ped = PlayerPedId()
model = type(model) == 'string' and joaat(model) or model
Expand Down
8 changes: 4 additions & 4 deletions server/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ end, 'admin')
-- Money

QBCore.Commands.Add('givemoney', Lang:t('command.givemoney.help'), { { name = Lang:t('command.givemoney.params.id.name'), help = Lang:t('command.givemoney.params.id.help') }, { name = Lang:t('command.givemoney.params.moneytype.name'), help = Lang:t('command.givemoney.params.moneytype.help') }, { name = Lang:t('command.givemoney.params.amount.name'), help = Lang:t('command.givemoney.params.amount.help') } }, true, function(source, args)
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
local Player = QBCore.Functions.GetPlayerByPlayerId(tonumber(args[1]))
if Player then
Player.Functions.AddMoney(tostring(args[2]), tonumber(args[3]), 'Admin give money')
else
Expand All @@ -229,7 +229,7 @@ QBCore.Commands.Add('givemoney', Lang:t('command.givemoney.help'), { { name = La
end, 'admin')

QBCore.Commands.Add('setmoney', Lang:t('command.setmoney.help'), { { name = Lang:t('command.setmoney.params.id.name'), help = Lang:t('command.setmoney.params.id.help') }, { name = Lang:t('command.setmoney.params.moneytype.name'), help = Lang:t('command.setmoney.params.moneytype.help') }, { name = Lang:t('command.setmoney.params.amount.name'), help = Lang:t('command.setmoney.params.amount.help') } }, true, function(source, args)
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
local Player = QBCore.Functions.GetPlayerByPlayerId(tonumber(args[1]))
if Player then
Player.Functions.SetMoney(tostring(args[2]), tonumber(args[3]))
else
Expand All @@ -245,7 +245,7 @@ QBCore.Commands.Add('job', Lang:t('command.job.help'), {}, false, function(sourc
end, 'user')

QBCore.Commands.Add('setjob', Lang:t('command.setjob.help'), { { name = Lang:t('command.setjob.params.id.name'), help = Lang:t('command.setjob.params.id.help') }, { name = Lang:t('command.setjob.params.job.name'), help = Lang:t('command.setjob.params.job.help') }, { name = Lang:t('command.setjob.params.grade.name'), help = Lang:t('command.setjob.params.grade.help') } }, true, function(source, args)
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
local Player = QBCore.Functions.GetPlayerByPlayerId(tonumber(args[1]))
if Player then
Player.Functions.SetJob(tostring(args[2]), tonumber(args[3]))
else
Expand All @@ -261,7 +261,7 @@ QBCore.Commands.Add('gang', Lang:t('command.gang.help'), {}, false, function(sou
end, 'user')

QBCore.Commands.Add('setgang', Lang:t('command.setgang.help'), { { name = Lang:t('command.setgang.params.id.name'), help = Lang:t('command.setgang.params.id.help') }, { name = Lang:t('command.setgang.params.gang.name'), help = Lang:t('command.setgang.params.gang.help') }, { name = Lang:t('command.setgang.params.grade.name'), help = Lang:t('command.setgang.params.grade.help') } }, true, function(source, args)
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
local Player = QBCore.Functions.GetPlayerByPlayerId(tonumber(args[1]))
if Player then
Player.Functions.SetGang(tostring(args[2]), tonumber(args[3]))
else
Expand Down
29 changes: 27 additions & 2 deletions server/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ QBCore.UsableItems = {}
---Gets the coordinates of an entity
---@param entity number
---@return vector4
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetCoords(entity)
local coords = GetEntityCoords(entity, false)
local heading = GetEntityHeading(entity)
Expand All @@ -19,7 +20,7 @@ end

---Gets player identifier of the given type
---@param source any
---@param idtype string
---@param idtype? string
---@return string?
function QBCore.Functions.GetIdentifier(source, idtype)
if GetConvarInt('sv_fxdkMode', 0) == 1 then return 'license:fxdk' end
Expand All @@ -30,6 +31,7 @@ end
---@param identifier string
---@return number
function QBCore.Functions.GetSource(identifier)
if not identifier then return 0 end
for src, _ in pairs(QBCore.Players) do
local idens = GetPlayerIdentifiers(src)
for _, id in pairs(idens) do
Expand All @@ -45,6 +47,7 @@ end
---@param source any
---@return table
function QBCore.Functions.GetPlayer(source)
if not source then return nil end
if type(source) == 'number' then
return QBCore.Players[source]
else
Expand All @@ -56,6 +59,7 @@ end
---@param citizenid string
---@return table?
function QBCore.Functions.GetPlayerByCitizenId(citizenid)
if not citizenid then return nil end
for src in pairs(QBCore.Players) do
if QBCore.Players[src].PlayerData.citizenid == citizenid then
return QBCore.Players[src]
Expand All @@ -64,6 +68,20 @@ function QBCore.Functions.GetPlayerByCitizenId(citizenid)
return nil
end

---Get player by player id
---@param playerid number
---@return table?
function QBCore.Functions.GetPlayerByPlayerId(playerid)
playerid = tonumber(playerid)
if not playerid then return nil end
for src in pairs(QBCore.Players) do
if QBCore.Players[src].PlayerData.playerid == playerid then
return QBCore.Players[src]
end
end
return nil
end

---Get offline player by citizen id
---@param citizenid string
---@return table?
Expand Down Expand Up @@ -118,6 +136,7 @@ end

---Get all players. Returns the server ids of all players.
---@return table
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetPlayers()
local sources = {}
for k in pairs(QBCore.Players) do
Expand Down Expand Up @@ -169,6 +188,7 @@ end
--- @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.
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestPlayer(source, coords)
local ped = GetPlayerPed(source)
local players = GetPlayers()
Expand All @@ -194,6 +214,7 @@ end
--- @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.
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestObject(source, coords)
local ped = GetPlayerPed(source)
local objects = GetAllObjects()
Expand All @@ -215,6 +236,7 @@ end
--- @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.
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestVehicle(source, coords)
local ped = GetPlayerPed(source)
local vehicles = GetAllVehicles()
Expand All @@ -236,6 +258,7 @@ end
--- @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.
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.GetClosestPed(source, coords)
local ped = GetPlayerPed(source)
local peds = GetAllPeds()
Expand Down Expand Up @@ -335,6 +358,7 @@ end
---@param coords vector
---@param warp boolean
---@return number
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.SpawnVehicle(source, model, coords, warp)
local ped = GetPlayerPed(source)
model = type(model) == 'string' and joaat(model) or model
Expand Down Expand Up @@ -429,7 +453,6 @@ end
---Trigger Client Callback
---@param name string
---@param source any
---@param cb function
---@param ... any
function QBCore.Functions.TriggerClientCallback(name, source, ...)
local cb = nil
Expand Down Expand Up @@ -695,6 +718,7 @@ end
---@param items table|string
---@param amount number
---@return boolean
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.HasItem(source, items, amount)
if GetResourceState('qb-inventory') == 'missing' then return end
return exports['qb-inventory']:HasItem(source, items, amount)
Expand All @@ -705,6 +729,7 @@ end
---@param text string
---@param type string
---@param length number
---@diagnostic disable-next-line: duplicate-set-field
function QBCore.Functions.Notify(source, text, type, length)
TriggerClientEvent('QBCore:Notify', source, text, type, length)
end
Expand Down
84 changes: 43 additions & 41 deletions server/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,9 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)

function self.Functions.Save()
if self.Offline then
QBCore.Player.SaveOffline(self.PlayerData)
return QBCore.Player.SaveOffline(self.PlayerData)
else
QBCore.Player.Save(self.PlayerData.source)
return QBCore.Player.Save(self.PlayerData.source)
end
end

Expand All @@ -417,8 +417,8 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
if self.Offline then
return self
else
self.PlayerData = QBCore.Player.Save(self.PlayerData.source, self.PlayerData)
QBCore.Players[self.PlayerData.source] = self
QBCore.Player.Save(self.PlayerData.source)
TriggerEvent('QBCore:Server:PlayerLoaded', self)
self.Functions.UpdatePlayerData()
end
Expand Down Expand Up @@ -481,50 +481,52 @@ function QBCore.Functions.AddPlayerField(ids, fieldName, data)
end

-- Save player info to database (make sure citizenid is the primary key in your database)
---@param source number
---@param PlayerData table | nil
---@return table | nil
function QBCore.Player.Save(source, PlayerData)
PlayerData = PlayerData or QBCore.Players[source].PlayerData
if not PlayerData then return QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!') end

function QBCore.Player.Save(source)
local ped = GetPlayerPed(source)
local pcoords = GetEntityCoords(ped)
local PlayerData = QBCore.Players[source].PlayerData
if PlayerData then
MySQL.insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', {
citizenid = PlayerData.citizenid,
cid = tonumber(PlayerData.cid),
license = PlayerData.license,
name = PlayerData.name,
money = json.encode(PlayerData.money),
charinfo = json.encode(PlayerData.charinfo),
job = json.encode(PlayerData.job),
gang = json.encode(PlayerData.gang),
position = json.encode(pcoords),
metadata = json.encode(PlayerData.metadata)
})
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(source) end
QBCore.ShowSuccess(resourceName, PlayerData.name .. ' PLAYER SAVED!')
else
QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
end
PlayerData.playerid = MySQL.insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', {
citizenid = PlayerData.citizenid,
cid = tonumber(PlayerData.cid),
license = PlayerData.license,
name = PlayerData.name,
money = json.encode(PlayerData.money),
charinfo = json.encode(PlayerData.charinfo),
job = json.encode(PlayerData.job),
gang = json.encode(PlayerData.gang),
position = json.encode(pcoords),
metadata = json.encode(PlayerData.metadata)
})
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(source) end
QBCore.ShowSuccess(resourceName, PlayerData.name .. ' PLAYER SAVED!')
return PlayerData
end

---@param PlayerData table
---@return table | nil
function QBCore.Player.SaveOffline(PlayerData)
if PlayerData then
MySQL.insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', {
citizenid = PlayerData.citizenid,
cid = tonumber(PlayerData.cid),
license = PlayerData.license,
name = PlayerData.name,
money = json.encode(PlayerData.money),
charinfo = json.encode(PlayerData.charinfo),
job = json.encode(PlayerData.job),
gang = json.encode(PlayerData.gang),
position = json.encode(PlayerData.position),
metadata = json.encode(PlayerData.metadata)
})
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(PlayerData, true) end
QBCore.ShowSuccess(resourceName, PlayerData.name .. ' OFFLINE PLAYER SAVED!')
else
QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.SAVEOFFLINE - PLAYERDATA IS EMPTY!')
end
if not PlayerData then return QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.SAVEOFFLINE - PLAYERDATA IS EMPTY!') end

PlayerData.playerid = MySQL.insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', {
citizenid = PlayerData.citizenid,
cid = tonumber(PlayerData.cid),
license = PlayerData.license,
name = PlayerData.name,
money = json.encode(PlayerData.money),
charinfo = json.encode(PlayerData.charinfo),
job = json.encode(PlayerData.job),
gang = json.encode(PlayerData.gang),
position = json.encode(PlayerData.position),
metadata = json.encode(PlayerData.metadata)
})
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(PlayerData, true) end
QBCore.ShowSuccess(resourceName, PlayerData.name .. ' OFFLINE PLAYER SAVED!')
return PlayerData
end

-- Delete character
Expand Down