RSGCore.Player.Login
- On player login, gets their data or sets default values
Copy
function RSGCore.Player.Login(source, citizenid, newData)
if source and source ~= '' then
if citizenid then
local license = RSGCore.Functions.GetIdentifier(source, 'license')
local PlayerData = MySQL.prepare.await('SELECT * FROM players where citizenid = ?', { citizenid })
if PlayerData and license == PlayerData.license then
PlayerData.money = json.decode(PlayerData.money)
PlayerData.job = json.decode(PlayerData.job)
PlayerData.gang = json.decode(PlayerData.gang)
PlayerData.position = json.decode(PlayerData.position)
PlayerData.metadata = json.decode(PlayerData.metadata)
PlayerData.charinfo = json.decode(PlayerData.charinfo)
RSGCore.Player.CheckPlayerData(source, PlayerData)
else
DropPlayer(source, Lang:t('info.exploit_dropped'))
TriggerEvent('rsg-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(source) .. ' Has Been Dropped For Character Joining Exploit', false)
end
else
RSGCore.Player.CheckPlayerData(source, newData)
end
return true
else
RSGCore.ShowError(resourceName, 'ERROR RSGCore.PLAYER.LOGIN - NO SOURCE GIVEN!')
return false
end
end
RSGCore.Player.CheckPlayerData
- Function called above on player join to gather player data (this is where you can add/remove additional player data)
Copy
function RSGCore.Player.CheckPlayerData(source, PlayerData)
PlayerData = PlayerData or {}
local Offline = not source
if source then
PlayerData.source = source
PlayerData.license = PlayerData.license or RSGCore.Functions.GetIdentifier(source, 'license')
PlayerData.name = GetPlayerName(source)
end
local validatedJob = false
if PlayerData.job and PlayerData.job.name ~= nil and PlayerData.job.grade and PlayerData.job.grade.level ~= nil then
local jobInfo = RSGCore.Shared.Jobs[PlayerData.job.name]
if jobInfo then
local jobGradeInfo = jobInfo.grades[tostring(PlayerData.job.grade.level)]
if jobGradeInfo then
PlayerData.job.label = jobInfo.label
PlayerData.job.grade.name = jobGradeInfo.name
PlayerData.job.payment = jobGradeInfo.payment
PlayerData.job.grade.isboss = jobGradeInfo.isboss or false
PlayerData.job.isboss = jobGradeInfo.isboss or false
validatedJob = true
end
end
end
if validatedJob == false then
-- set to nil, as the default job (unemployed) will be added by `applyDefaults`
PlayerData.job = nil
end
local validatedGang = false
if PlayerData.gang and PlayerData.gang.name ~= nil and PlayerData.gang.grade and PlayerData.gang.grade.level ~= nil then
local gangInfo = RSGCore.Shared.Gangs[PlayerData.gang.name]
if gangInfo then
local gangGradeInfo = gangInfo.grades[tostring(PlayerData.gang.grade.level)]
if gangGradeInfo then
PlayerData.gang.label = gangInfo.label
PlayerData.gang.grade.name = gangGradeInfo.name
PlayerData.gang.payment = gangGradeInfo.payment
PlayerData.gang.grade.isboss = gangGradeInfo.isboss or false
PlayerData.gang.isboss = gangGradeInfo.isboss or false
validatedGang = true
end
end
end
if validatedGang == false then
-- set to nil, as the default gang (unemployed) will be added by `applyDefaults`
PlayerData.gang = nil
end
applyDefaults(PlayerData, RSGCore.Config.Player.PlayerDefaults)
if GetResourceState('rsg-inventory') ~= 'missing' then
PlayerData.items = exports['rsg-inventory']:LoadInventory(PlayerData.source, PlayerData.citizenid)
end
return RSGCore.Player.CreatePlayer(PlayerData, Offline)
end
RSGCore.Player.Logout
- Saves player on logout and removes them from active players table
Copy
function RSGCore.Player.Logout(source)
TriggerClientEvent('RSGCore:Client:OnPlayerUnload', source)
TriggerEvent('RSGCore:Server:OnPlayerUnload', source)
TriggerClientEvent('RSGCore:Player:UpdatePlayerData', source)
Wait(200)
RSGCore.Players[source] = nil
end
RSGCore.Player.CreatePlayer
- Creates a new character and sets default data (any function inside the self table can be called on the player after using the GetPlayer function)
Copy
function RSGCore.Player.CreatePlayer(PlayerData, Offline)
local self = {}
self.Functions = {}
self.PlayerData = PlayerData
self.Offline = Offline
function self.Functions.UpdatePlayerData()
if self.Offline then return end
TriggerEvent('RSGCore:Player:SetPlayerData', self.PlayerData)
TriggerClientEvent('RSGCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData)
end
function self.Functions.SetJob(job, grade)
job = job:lower()
grade = grade or '0'
if not RSGCore.Shared.Jobs[job] then return false end
self.PlayerData.job = {
name = job,
label = RSGCore.Shared.Jobs[job].label,
onduty = RSGCore.Shared.Jobs[job].defaultDuty,
type = RSGCore.Shared.Jobs[job].type or 'none',
grade = {
name = 'No Grades',
level = 0,
payment = 30,
isboss = false
}
}
local gradeKey = tostring(grade)
local jobGradeInfo = RSGCore.Shared.Jobs[job].grades[gradeKey]
if jobGradeInfo then
self.PlayerData.job.grade.name = jobGradeInfo.name
self.PlayerData.job.grade.level = tonumber(gradeKey)
self.PlayerData.job.grade.payment = jobGradeInfo.payment
self.PlayerData.job.grade.isboss = jobGradeInfo.isboss or false
self.PlayerData.job.isboss = jobGradeInfo.isboss or false
end
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('RSGCore:Server:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
TriggerClientEvent('RSGCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
end
return true
end
function self.Functions.SetGang(gang, grade)
gang = gang:lower()
grade = grade or '0'
if not RSGCore.Shared.Gangs[gang] then return false end
self.PlayerData.gang = {
name = gang,
label = RSGCore.Shared.Gangs[gang].label,
grade = {
name = 'No Grades',
level = 0,
isboss = false
}
}
local gradeKey = tostring(grade)
local gangGradeInfo = RSGCore.Shared.Gangs[gang].grades[gradeKey]
if gangGradeInfo then
self.PlayerData.gang.grade.name = gangGradeInfo.name
self.PlayerData.gang.grade.level = tonumber(gradeKey)
self.PlayerData.gang.grade.isboss = gangGradeInfo.isboss or false
self.PlayerData.gang.isboss = gangGradeInfo.isboss or false
end
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('RSGCore:Server:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
TriggerClientEvent('RSGCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
end
return true
end
function self.Functions.HasItem(items, amount)
return RSGCore.Functions.HasItem(self.PlayerData.source, items, amount)
end
function self.Functions.SetJobDuty(onDuty)
self.PlayerData.job.onduty = not not onDuty
TriggerEvent('RSGCore:Server:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
TriggerClientEvent('RSGCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
self.Functions.UpdatePlayerData()
end
function self.Functions.SetPlayerData(key, val)
if not key or type(key) ~= 'string' then return end
self.PlayerData[key] = val
self.Functions.UpdatePlayerData()
end
function self.Functions.SetMetaData(meta, val)
if not meta or type(meta) ~= 'string' then return end
if meta == 'hunger' or meta == 'thirst' or meta == 'cleanliness' then
val = val > 100 and 100 or val
end
self.PlayerData.metadata[meta] = val
self.Functions.UpdatePlayerData()
end
function self.Functions.GetMetaData(meta)
if not meta or type(meta) ~= 'string' then return end
return self.PlayerData.metadata[meta]
end
function self.Functions.AddRep(rep, amount)
if not rep or not amount then return end
local addAmount = tonumber(amount)
local currentRep = self.PlayerData.metadata['rep'][rep] or 0
self.PlayerData.metadata['rep'][rep] = currentRep + addAmount
self.Functions.UpdatePlayerData()
end
function self.Functions.RemoveRep(rep, amount)
if not rep or not amount then return end
local removeAmount = tonumber(amount)
local currentRep = self.PlayerData.metadata['rep'][rep] or 0
if currentRep - removeAmount < 0 then
self.PlayerData.metadata['rep'][rep] = 0
else
self.PlayerData.metadata['rep'][rep] = currentRep - removeAmount
end
self.Functions.UpdatePlayerData()
end
function self.Functions.GetRep(rep)
if not rep then return end
return self.PlayerData.metadata['rep'][rep] or 0
end
function self.Functions.AddMoney(moneytype, amount, reason)
reason = reason or 'unknown'
moneytype = moneytype:lower()
amount = tonumber(amount)
if amount < 0 then return end
if not self.PlayerData.money[moneytype] then return false end
self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] + amount
if not self.Offline then
self.Functions.UpdatePlayerData()
if amount > 100000 then
TriggerEvent('rsg-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') added, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason, true)
else
TriggerEvent('rsg-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') added, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason)
end
TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, false)
TriggerClientEvent('RSGCore:Client:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'add', reason)
TriggerEvent('RSGCore:Server:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'add', reason)
end
return true
end
function self.Functions.RemoveMoney(moneytype, amount, reason)
reason = reason or 'unknown'
moneytype = moneytype:lower()
amount = tonumber(amount)
if amount < 0 then return end
if not self.PlayerData.money[moneytype] then return false end
for _, mtype in pairs(RSGCore.Config.Money.DontAllowMinus) do
if mtype == moneytype then
if (self.PlayerData.money[moneytype] - amount) < 0 then
return false
end
end
end
self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] - amount
if not self.Offline then
self.Functions.UpdatePlayerData()
if amount > 100000 then
TriggerEvent('rsg-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') removed, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason, true)
else
TriggerEvent('rsg-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') removed, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason)
end
TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, true)
if moneytype == 'bank' then
TriggerClientEvent('rsg-phone:client:RemoveBankMoney', self.PlayerData.source, amount)
end
TriggerClientEvent('RSGCore:Client:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'remove', reason)
TriggerEvent('RSGCore:Server:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'remove', reason)
end
return true
end
function self.Functions.SetMoney(moneytype, amount, reason)
reason = reason or 'unknown'
moneytype = moneytype:lower()
amount = tonumber(amount)
if amount < 0 then return false end
if not self.PlayerData.money[moneytype] then return false end
local difference = amount - self.PlayerData.money[moneytype]
self.PlayerData.money[moneytype] = amount
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('rsg-log:server:CreateLog', 'playermoney', 'SetMoney', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') set, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason)
TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, math.abs(difference), difference < 0)
TriggerClientEvent('RSGCore:Client:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'set', reason)
TriggerEvent('RSGCore:Server:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'set', reason)
end
return true
end
function self.Functions.GetMoney(moneytype)
if not moneytype then return false end
moneytype = moneytype:lower()
return self.PlayerData.money[moneytype]
end
function self.Functions.Save()
if self.Offline then
RSGCore.Player.SaveOffline(self.PlayerData)
else
RSGCore.Player.Save(self.PlayerData.source)
end
end
function self.Functions.Logout()
if self.Offline then return end
RSGCore.Player.Logout(self.PlayerData.source)
end
function self.Functions.AddMethod(methodName, handler)
self.Functions[methodName] = handler
end
function self.Functions.AddField(fieldName, data)
self[fieldName] = data
end
if self.Offline then
return self
else
RSGCore.Players[self.PlayerData.source] = self
RSGCore.Player.Save(self.PlayerData.source)
TriggerEvent('RSGCore:Server:PlayerLoaded', self)
self.Functions.UpdatePlayerData()
end
end
RSGCore.Player.Save
- Saves the playerโs info to the database
Copy
function RSGCore.Player.Save(source)
local ped = GetPlayerPed(source)
local pcoords = GetEntityCoords(ped)
local PlayerData = RSGCore.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('rsg-inventory') ~= 'missing' then exports['rsg-inventory']:SaveInventory(source) end
RSGCore.ShowSuccess(resourceName, PlayerData.name .. ' PLAYER SAVED!')
else
RSGCore.ShowError(resourceName, 'ERROR RSGCore.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
end
end
RSGCore.Player.DeleteCharacter
- Deletes a character and all corresponding data in the database
Copy
local playertables = { -- Add tables as needed
{ table = 'players'},
{ table = 'playeroutfit'},
{ table = 'playerskins'},
{ table = 'player_horses'},
{ table = 'player_weapons'},
{ table = 'address_book'},
{ table = 'telegrams'},
}
function RSGCore.Player.DeleteCharacter(source, citizenid)
local license = RSGCore.Functions.GetIdentifier(source, 'license')
local result = MySQL.scalar.await('SELECT license FROM players where citizenid = ?', { citizenid })
if license == result then
local query = 'DELETE FROM %s WHERE citizenid = ?'
local tableCount = #playertables
local queries = table.create(tableCount, 0)
for i = 1, tableCount do
local v = playertables[i]
queries[i] = { query = query:format(v.table), values = { citizenid } }
end
MySQL.transaction(queries, function(result2)
if result2 then
TriggerEvent('rsg-log:server:CreateLog', 'joinleave', 'Character Deleted', 'red', '**' .. GetPlayerName(source) .. '** ' .. license .. ' deleted **' .. citizenid .. '**..')
end
end)
else
DropPlayer(source, Lang:t('info.exploit_dropped'))
TriggerEvent('rsg-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(source) .. ' Has Been Dropped For Character Deletion Exploit', true)
end
end
Player Object Functions
Once you have a Player object (viaRSGCore.Functions.GetPlayer(source)), you can use the following functions on that player:
Player.Functions.SetJob
- Sets a playerโs job and grade
Copy
function Player.Functions.SetJob(job, grade)
job = job:lower()
grade = grade or '0'
-- Sets the job and triggers events
return true/false
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.SetJob('vallaw', '2') -- Set to Valentine Law Sheriff
Player.Functions.SetGang
- Sets a playerโs gang and grade
Copy
function Player.Functions.SetGang(gang, grade)
gang = gang:lower()
grade = grade or '0'
-- Sets the gang and triggers events
return true/false
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.SetGang('odriscoll', '1') -- Set to O'Driscoll Enforcer
Player.Functions.SetJobDuty
- Sets a playerโs on/off duty status for their job
Copy
function Player.Functions.SetJobDuty(onDuty)
-- Sets duty status and triggers events
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.SetJobDuty(true) -- Clock player in
Player.Functions.SetJobDuty(false) -- Clock player out
Player.Functions.AddMoney
- Add money to a playerโs account
Copy
function Player.Functions.AddMoney(moneytype, amount, reason)
-- Adds money and triggers events/logs
return true/false
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
if Player.Functions.AddMoney('cash', 100, 'Sold item') then
print('Added $100 cash to player')
end
-- Different money types: 'cash', 'bank', 'valbank', 'rhobank', 'blkbank', 'armbank', 'bloodmoney'
Player.Functions.RemoveMoney
- Remove money from a playerโs account
Copy
function Player.Functions.RemoveMoney(moneytype, amount, reason)
-- Removes money if player has enough
return true/false
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
if Player.Functions.RemoveMoney('cash', 50, 'Bought item') then
print('Removed $50 cash from player')
else
print('Player does not have enough money')
end
Player.Functions.SetMoney
- Set a playerโs money to a specific amount
Copy
function Player.Functions.SetMoney(moneytype, amount, reason)
-- Sets money to exact amount
return true/false
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.SetMoney('bank', 5000, 'Admin set money')
Player.Functions.GetMoney
- Get the amount of money a player has in a specific account
Copy
function Player.Functions.GetMoney(moneytype)
return amount
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
local cashAmount = Player.Functions.GetMoney('cash')
print('Player has $' .. cashAmount .. ' cash')
Player.Functions.SetMetaData
- Set metadata for a player
Copy
function Player.Functions.SetMetaData(meta, val)
-- Sets metadata (hunger, thirst, cleanliness are clamped to 0-100)
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.SetMetaData('hunger', 75) -- Set hunger to 75
Player.Functions.SetMetaData('thirst', 80) -- Set thirst to 80
Player.Functions.SetMetaData('isdead', false) -- Set player as alive
Player.Functions.SetMetaData('armor', 100) -- Set armor to 100
-- You can also pass a table to set multiple at once
Player.Functions.SetMetaData({
hunger = 100,
thirst = 100,
stress = 0
})
Player.Functions.GetMetaData
- Get metadata for a player
Copy
function Player.Functions.GetMetaData(meta)
return value
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
local hunger = Player.Functions.GetMetaData('hunger')
if hunger < 20 then
print('Player is very hungry!')
end
Player.Functions.AddRep
- Add reputation points for a specific reputation type
Copy
function Player.Functions.AddRep(rep, amount)
-- Adds reputation points
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.AddRep('hunting', 10) -- Add 10 hunting rep
Player.Functions.AddRep('fishing', 5) -- Add 5 fishing rep
Player.Functions.RemoveRep
- Remove reputation points for a specific reputation type
Copy
function Player.Functions.RemoveRep(rep, amount)
-- Removes reputation points (won't go below 0)
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.RemoveRep('hunting', 5) -- Remove 5 hunting rep
Player.Functions.GetRep
- Get reputation points for a specific reputation type
Copy
function Player.Functions.GetRep(rep)
return amount
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
local huntingRep = Player.Functions.GetRep('hunting')
if huntingRep >= 100 then
print('Player is a master hunter!')
end
Player.Functions.HasItem
- Check if player has a specific item
Copy
function Player.Functions.HasItem(items, amount)
return RSGCore.Functions.HasItem(source, items, amount)
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
if Player.Functions.HasItem('bread', 1) then
print('Player has bread')
end
Player.Functions.SetPlayerData
- Set any player data field
Copy
function Player.Functions.SetPlayerData(key, val)
-- Sets player data and updates
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.SetPlayerData('weight', 50000) -- Change inventory weight
Player.Functions.SetPlayerData('slots', 30) -- Change inventory slots
Player.Functions.Save
- Manually save a playerโs data to database
Copy
function Player.Functions.Save()
-- Saves player data to database
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
-- Make changes to player data
Player.Functions.SetMoney('cash', 1000, 'test')
-- Manually save
Player.Functions.Save()
Player.Functions.Logout
- Log a player out (removes from active players)
Copy
function Player.Functions.Logout()
-- Logs player out and triggers events
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
Player.Functions.Logout()
Player.Functions.UpdatePlayerData
- Trigger an update of player data to client
Copy
function Player.Functions.UpdatePlayerData()
-- Updates player data on client
end
-- Example
local Player = RSGCore.Functions.GetPlayer(source)
-- Make changes
Player.PlayerData.charinfo.firstname = 'John'
-- Manually trigger update
Player.Functions.UpdatePlayerData()
Accessing Player Data
Once you have a Player object, you can access their data directly:Copy
local Player = RSGCore.Functions.GetPlayer(source)
-- Access character info
local firstname = Player.PlayerData.charinfo.firstname
local lastname = Player.PlayerData.charinfo.lastname
local birthdate = Player.PlayerData.charinfo.birthdate
local gender = Player.PlayerData.charinfo.gender
local account = Player.PlayerData.charinfo.account
-- Access money
local cash = Player.PlayerData.money.cash
local bank = Player.PlayerData.money.bank
-- Access job info
local jobName = Player.PlayerData.job.name
local jobLabel = Player.PlayerData.job.label
local jobGrade = Player.PlayerData.job.grade.level
local jobGradeName = Player.PlayerData.job.grade.name
local jobPayment = Player.PlayerData.job.payment
local onDuty = Player.PlayerData.job.onduty
local isBoss = Player.PlayerData.job.isboss
-- Access gang info
local gangName = Player.PlayerData.gang.name
local gangLabel = Player.PlayerData.gang.label
local gangGrade = Player.PlayerData.gang.grade.level
local gangIsBoss = Player.PlayerData.gang.isboss
-- Access metadata
local hunger = Player.PlayerData.metadata.hunger
local thirst = Player.PlayerData.metadata.thirst
local cleanliness = Player.PlayerData.metadata.cleanliness
local stress = Player.PlayerData.metadata.stress
local isDead = Player.PlayerData.metadata.isdead
local armor = Player.PlayerData.metadata.armor
local bloodtype = Player.PlayerData.metadata.bloodtype
local fingerprint = Player.PlayerData.metadata.fingerprint
local walletid = Player.PlayerData.metadata.walletid
local callsign = Player.PlayerData.metadata.callsign
-- Access other info
local citizenid = Player.PlayerData.citizenid
local license = Player.PlayerData.license
local name = Player.PlayerData.name
local source = Player.PlayerData.source