Server
Player
get_players()
Returns a copy of the players table. The players table contains all current active players.
Function
--- Get all players in the boii.players table.
--- @return All connected players.
local function get_players()
return utils.tables.deep_copy(boii.players)
end
boii.get_players = get_players
exports('get_players', get_players)
Example
--- Retrieve all players.
local players = boii.get_players()
print('Players:', json.encode(players))
get_player()
Returns a specific player from the active players table.
A source ID must be provided to ensure the correct player is returned.
Function
local function get_player(_src)
return boii.players[_src]
end
boii.get_player = get_player
exports('get_player', get_player)
Example
local player = boii.get_player(source)
--- Accessing player data.
print('Player first name:', player.data.identity.first_name)
--- Using player functions.
local identity = player.get_identity()
print('Identity:', json.encode(identity))
get_identifier()
Returns a specific player identifier.
Function
local function get_identifier(_src, id_type)
if not id_type then DEBUG('err', 'Function: get_identifier | Note: ID Type was missing.') return end
return GetPlayerIdentifierByType(src, id_type)
end
boii.get_identifier = get_identifier
exports('get_identifier', get_identifier)
Example
--- Retrieve identifier for player.
local license = boii.get_identifier(source, 'license')
--- Print identifier.
print('License:', license)
get_uid()
Returns the players unique id.
Unique ID's are assigned to players through boii_utils when they first connect and a user account is created for their license.
Function
local function get_uid(license)
if not license then DEBUG('err', 'Function: get_uid | Note: Player license was missing.') return nil end
local result = MySQL.query.await('SELECT unique_id FROM user_accounts WHERE license = @license', { ['@license'] = license })
return result[1] and result[1].unique_id or nil
end
boii.get_uid = get_uid
exports('get_uid', get_uid)
Example
--- Retrieve players unique id by license
local license = boii.get_identifier(source, 'license')
local unique_id = boii.get_uid(license)
--- Print UID.
print('Unique ID:', unique_id)
get_data()
Gets a players server side data.
Function
local function get_data(player, data_type)
return data_type and player.data[data_type] or player.data
end
boii.get_data = get_data
exports('get_data', get_data)
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Retreive players identity data.
local identity = boii.get_data(player, 'identity')
--- Print players indentity data.
print('Identity:', json.encode(identity))
create_character()
Add a new character for the player into the database.
All player tables have default values provided except for Unique ID and Passport, these must always be provided.
Function
local function create_character(data)
local queries = {
{ query = 'INSERT INTO players (unique_id, char_id, passport) VALUES (?, ?, ?)', params = { data.unique_id, data.char_id, data.passport }},
{ query = 'INSERT INTO player_statuses (passport) VALUES (?)', params = { data.passport }},
{ query = 'INSERT INTO player_groups (passport) VALUES (?)', params = { data.passport }},
{ query = 'INSERT INTO player_inventory (passport) VALUES (?)', params = { data.passport }},
{ query = 'INSERT INTO player_stats (passport) VALUES (?)', params = { data.passport }},
{ query = 'INSERT INTO player_achievements (passport) VALUES (?)', params = { data.passport }}
}
for _, account in ipairs(config.player_data.accounts) do
queries[#queries + 1] = { query = 'INSERT INTO player_accounts (passport, account_type, amount, allow_negative, interest_rate, interest_time) VALUES (?, ?, ?, ?, ?, ?)', params = { data.passport, account.account_type, account.amount, account.allow_negative, account.interest_rate, account.interest_time }}
end
for _, query_data in ipairs(queries) do
MySQL.Async.execute(query_data.query, query_data.params, function(rows_changed)
if rows_changed <= 0 then DEBUG('err', 'Failed to create character in table: ' .. query_data.query) return false end
end)
end
return true
end
boii.create_character = create_character
exports('create_character', create_character)
Example
--- Define character data.
local data = {
unique_id = 'BOII_JZFG3',
char_id = 1,
passport = 'B12345678',
identity = {
first_name = 'John',
last_name = 'Doe'
--- Additional fields here.
}
--- Additional fields here.
}
boii.create_character(data)
Player Methods
These functions can be used directly on the players object.
Before using any player method you must first retrieve the correct player.
Get functions are created on the players object for each data type specified under PLAYER_DATA_TYPES.
--- Player data types.
local PLAYER_DATA_TYPES <const> = { 'identity', 'position', 'statuses', 'accounts', 'groups', 'inventory', 'stats', 'achievements' }
--- Loop inside player_methods function to add get functions.
for _, data_type in pairs(PLAYER_DATA_TYPES) do
player['get_' .. data_type] = function()
return get_data(player, data_type)
end
end
get_data()
Get player data.
Function
function player.get_data(data_type)
return data_type and player.data[data_type] or player.data
end
Example
--- Retrieve player.
local player = boii.get_player(source)
--- Retreive players identity data.
local identity = player.get_data('identity')
--- Print players indentity data.
print('Identity:', json.encode(identity))
get_identity()
Returns a players identity data.
Example
local player = boii.get_player(source)
local identity = player.get_identity()
print('Identity:', json.encode(identity))
get_position()
Returns a players position data.
Example
local player = boii.get_player(source)
local position = player.get_position()
print('Position:', position)
get_statuses()
Returns a players statuses data.
Example
local player = boii.get_player(source)
local statuses = player.get_statuses()
print('Statuses:', json.encode(statuses))
get_accounts()
Returns a players accounts data.
Example
local player = boii.get_player(source)
local accounts = player.get_accounts()
print('Accounts:', json.encode(accounts))
get_groups()
Returns a players groups data.
Example
local player = boii.get_player(source)
local groups = player.get_groups()
print('Groups:', json.encode(groups))
get_inventory()
Returns a players inventory data.
Example
local player = boii.get_player(source)
local inventory = player.get_inventory()
print('Inventory:', json.encode(inventory))
get_stats()
Returns a players stats data.
Example
local player = boii.get_player(source)
local stats = player.get_stats()
print('Stats:', json.encode(stats))
get_achievements()
Returns a players achievements data.
Example
local player = boii.get_player(source)
local achievements = player.get_achievements()
print('Achievements:', json.encode(achievements))
adjust_statuses()
Adjust a players status values.
Function
function player.adjust_statuses(updates)
if not updates or type(updates) ~= 'table' then DEBUG('err', 'Function: player.adjust_statuses | Note: Invalid input, expected a table.') return false end
for status, effect in pairs(updates) do
if not utils.tables.table_contains(TABLE_MAP.statuses.fields, status) then DEBUG('warn', 'Function: player.adjust_statuses | Invalid status: ' .. status) return false end
if type(player.data.statuses[status]) == 'number' then
local current_value = player.data.statuses[status] or 0
local new_value = current_value + (effect.add or 0) - (effect.remove or 0)
if status == 'health' then
new_value = math.min(200, math.max(0, new_value))
else
new_value = math.min(100, math.max(0, new_value))
end
player.data.statuses[status] = new_value
DEBUG('info', 'Updated ' .. status .. ' for player ' .. tostring(player.source) .. ': ' .. tostring(new_value - current_value))
elseif status == 'illnesses' or status == 'injuries' or status == 'infections' or status == 'buffs' or status == 'debuffs' then
player.data.statuses[status] = effect
else
player.data.statuses[status] = effect and 1 or 0
end
end
player.set_data({ 'statuses' }, true)
DEBUG('info', 'Function: player.adjust_statuses | Statuses adjusted for player ' .. player.source)
return true
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Adjust statuses.
player.adjust_statuses(player, {
health = { add = 20 },
hunger = { remove = 10 },
fatigue = { add = 5 },
is_injured = true,
injuries = { leg_fracture = true }
})
kill()
KIll the player.
Function
function player.kill()
local statuses = { 'health', 'armour', 'hunger', 'thirst', 'stamina', 'stress', 'hygiene', 'fatigue', 'temperature' }
for _, status in ipairs(statuses) do
player.data.statuses[status] = 0
end
player.data.statuses.is_dead = 1
player.data.statuses.is_bleeding = 0
player.data.statuses.is_unconscious = 0
player.data.statuses.is_ill = 0
player.data.statuses.is_injured = 0
player.data.statuses.is_poisoned = 0
player.data.statuses.is_infected = 0
player.data.statuses.illnesses = json.encode({})
player.data.statuses.injuries = json.encode({})
player.data.statuses.infections = json.encode({})
player.data.statuses.buffs = json.encode({})
player.data.statuses.debuffs = json.encode({})
player.set_data({ 'statuses' }, true)
DEBUG('info', 'Function: player.kill | Player ' .. player.source .. ' has been killed.')
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Kill the player.
player.kill()
revive()
Revive the player and reset statuses back to default values.
Function
function player.revive()
player.data.statuses.health = 200
player.data.statuses.armour = 0
local statuses = { hunger = 100, thirst = 100, stamina = 100, stress = 0, hygiene = 100, fatigue = 0, temperature = 37 }
for status, value in pairs(statuses) do
player.data.statuses[status] = value
end
player.data.statuses.is_dead = 0
player.data.statuses.is_bleeding = 0
player.data.statuses.is_unconscious = 0
player.data.statuses.is_ill = 0
player.data.statuses.is_injured = 0
player.data.statuses.is_poisoned = 0
player.data.statuses.is_infected = 0
player.data.statuses.illnesses = json.encode({})
player.data.statuses.injuries = json.encode({})
player.data.statuses.infections = json.encode({})
player.data.statuses.buffs = json.encode({})
player.data.statuses.debuffs = json.encode({})
player.set_data({ 'statuses' }, true)
DEBUG('info', 'Function: player.revive | Player ' .. player.source .. ' has been revived.')
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Revive the player.
player.revive()
add_account()
Adds a new account entry for the player.
Function
function player.add_account(account_type, data)
if not player.data.accounts then DEBUG('err', 'Function: player.add_account | player.data.accounts is missing for ' .. player.source) return false end
if player.data.accounts[account_type] then DEBUG('warn', 'Function: player.add_account | Account type ' .. account_type .. ' already exists for player ' .. player.source) return false end
player.data.accounts[account_type] = { account_type = account_type, amount = data.amount or 0, allow_negative = data.allow_negative or false, interest_rate = data.interest_rate or 0, interest_time = data.interest_time or 0, interest_accrued = 0, last_payout = utils.dates.convert_timestamp(os.time()).formatted }
add_account(player, account_type)
player.set_data({ 'accounts' }, false)
DEBUG('info', 'Function: player.add_account | New account added successfully for player ' .. player.source)
return true
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Add a savings account for the player.
player.add_account('savings', { amount = 0 })
remove_account()
Removes an account entry for the player.
Function
function player.remove_account(account_type)
if not player.data.accounts then DEBUG('err', 'Function: player.remove_account | player.data.accounts is missing for ' .. player.source) return false end
if not player.data.accounts[account_type] then DEBUG('warn', 'Function: player.remove_account | Account type ' .. account_type .. ' not found for player ' .. player.source) return false end
player.data.accounts[account_type] = nil
player.set_data({ 'accounts' }, true)
remove_account(player, account_type)
DEBUG('info', 'Function: player.remove_account | Account removed successfully for player ' .. player.source)
return true
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Remove a players savings account.
player.remove_account('savings')
add_to_account()
Adds money to a specified player account.
Function
function player.add_to_account(account_type, amount)
if not player.data.accounts then DEBUG('err', 'Function: player.add_to_account | Note: player.data.accounts is missing for ' .. player.source) return false end
local account = player.data.accounts[account_type]
if not account then DEBUG('warn', 'Function: player.add_to_account | Note: Account type ' .. account_type .. ' not found for player ' .. player.source) return false end
account.amount += amount
player.set_data({ 'accounts' }, true)
DEBUG('info', 'Function: player.add_to_account | Note: Account added successfully for player ' .. player.source)
return true
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Add value to a players savings account.
player.add_to_account('savings', 1000)
remove_from_account()
Removes money from a specified player account.
Function
function player.remove_from_account(account_type, amount)
if not player.data.accounts then DEBUG('err', 'Function: player.remove_from_account | Note: player.data.accounts is missing for ' .. player.source) return false end
local account = player.data.accounts[account_type]
if not account then DEBUG('warn', 'Function: player.remove_from_account | Note: Account type ' .. account_type .. ' not found for player ' .. player.source) return false end
account.amount -= amount
player.set_data({ 'accounts' }, true)
DEBUG('info', 'Function: player.remove_from_account | Note: Account removed successfully for player ' .. player.source ..')')
return true
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Remove value from a players savings account.
player.remove_from_account('savings', 1000)
set_account()
Sets a new value for a specified player account.
Function
function player.set_account(account_type, amount)
if not player.data.accounts then DEBUG('err', 'Function: player.set_account | Note: player.data.accounts is missing for ' .. player.source) return false end
local account = player.data.accounts[account_type]
if not account then DEBUG('warn', 'Function: player.set_account | Note: Account type ' .. account_type .. ' not found for player ' .. player.source) return false end
account.amount = amount
player.set_data({ 'accounts' }, true)
DEBUG('info', 'Function: player.set_account | Note: Account set successfully for player ' .. player.source)
return true
end
Example
--- Retreive the player.
local player = boii.get_player(source)
--- Set a players savings account value.
player.set_account('savings', 1000)
add_group()
Adds a new group for the player.
Function
function player.add_group(group_type, group, grade)
if not player.data.groups then DEBUG('err', 'Function: player.add_group | Note: player.data.groups is missing for ' .. player.source) return false end
player.data.groups[group_type] = { group = group, grade = grade }
player.set_data({ 'groups' }, true)
DEBUG('info', 'Function: player.add_group | Note: Group added/updated successfully for player ' .. player.source)
return true
end
Example
local player = boii.get_player(source)
player.add_group('job', 'police', 0)
remove_group()
Removes a specified group from the player.
Function
function player.remove_group(group_type, group_name)
if not player.data.groups then DEBUG('err', 'Function: player.remove_group | Note: player.data.groups is missing for ' .. player.source) return false end
if not player.data.groups[group_type][group_name] then DEBUG('warn', 'Function: player.remove_group | Note: Group ' .. group_name .. ' not found for player ' .. player.source) return false end
player.data.groups[group_type][group_name] = nil
player.set_data({ 'groups' }, true)
DEBUG('info', 'Function: player.remove_group | Note: Group removed successfully for player ' .. player.source)
return true
end
Example
local player = boii.get_player(source)
player.remove_group('job', 'police')
change_group_grade()
Modifies a players current group grade.
Function
function player.change_group_grade(group_type, group_name, grade)
if not player.data.groups then DEBUG('err', 'Function: player.change_group_grade | Note: player.data.groups is missing for ' .. player.source) return false end
if not player.data.groups[group_type][group_name] then DEBUG('warn', 'Function: player.change_group_grade | Note: Group type ' .. group_type .. ' not found for player ' .. player.source) return false end
player.data.groups[group_type][group_name].grade = grade
player.set_data({ 'groups' }, true)
DEBUG('info', 'Function: player.change_group_grade | Note: Group grade modified successfully for player ' .. player.source)
return true
end
Example
local player = boii.get_player(source)
player.change_group_grade('job', 'police', 1)
increase_stat()
Increase the value of a specified player stat.
Function
function player.increase_stat(stat_category, stat_name, amount)
if not player.data.stats then DEBUG('err', 'Function: player.increase_stat | player.data.stats is missing for ' .. player.source) return false end
local stats = player.data.stats[stat_category]
if not stats then DEBUG('warn', 'Function: player.increase_stat | Stat category ' .. stat_category .. ' not found for player ' .. player.source) return false end
if not stats[stat_name] then DEBUG('warn', 'Function: player.increase_stat | Stat name ' .. stat_name .. ' not found in category ' .. stat_category .. ' for player ' .. player.source) return false end
stats[stat_name] += amount
DEBUG('info', 'Function: player.increase_stat | Stat ' .. stat_name .. ' increased by ' .. amount .. ' for player ' .. player.source)
player.set_data({ 'stats' }, true)
return true
end
Example
local player = boii.get_player(source)
player.increase_stat('general', 'total_money_earned', 1000)
decrease_stat()
Decrease the value of a specified player stat.
Function
function player.decrease_stat(stat_category, stat_name, amount)
if not player.data.stats then DEBUG('err', 'Function: player.decrease_stat | player.data.stats is missing for ' .. player.source) return false end
local stats = player.data.stats[stat_category]
if not stats then DEBUG('warn', 'Function: player.decrease_stat | Stat category ' .. stat_category .. ' not found for player ' .. player.source) return false end
if not stats[stat_name] then DEBUG('warn', 'Function: player.decrease_stat | Stat name ' .. stat_name .. ' not found in category ' .. stat_category .. ' for player ' .. player.source) return false end
stats[stat_name] -= amount
DEBUG('info', 'Function: player.decrease_stat | Stat ' .. stat_name .. ' decreased by ' .. amount .. ' for player ' .. player.source)
player.set_data({ 'stats' }, true)
return true
end
Example
local player = boii.get_player(source)
player.decrease_stat('general', 'total_money_earned', 1000)
set_stat()
Set a value for a specified player stat.
Function
function player.set_stat(stat_category, stat_name, amount)
if not player.data.stats then DEBUG('err', 'Function: player.set_stat | player.data.stats is missing for ' .. player.source) return false end
local stats = player.data.stats[stat_category]
if not stats then DEBUG('warn', 'Function: player.set_stat | Stat category ' .. stat_category .. ' not found for player ' .. player.source) return false end
if not stats[stat_name] then DEBUG('warn', 'Function: player.set_stat | Stat name ' .. stat_name .. ' not found in category ' .. stat_category .. ' for player ' .. player.source) return false end
stats[stat_name] = amount
DEBUG('info', 'Function: player.set_stat | Stat ' .. stat_name .. ' set to ' .. amount .. ' for player ' .. player.source)
player.set_data({ 'stats' }, true)
return true
end
Example
local player = boii.get_player(source)
player.set_stat('general', 'total_money_earned', 1000)
check_achievement()
Checks the current status of a specified player achievement.
Function
function player.check_achievement(achievement_name)
if not player.data.achievements then DEBUG('err', 'Function: player.check_achievement | Note: player.data.achievements is missing for ' .. player.source) return false end
local achievement = player.data.achievements[achievement_name]
return achievement ~= nil and achievement.achieved == true
end
Example
local player = boii.get_player(source)
local has_achievement = player.check_achievement('bought_first_vehicle')
print(tostring(has_achievement))
grant_achievement()
Grants an achievement to the player.
Function
function player.grant_achievement(achievement_name)
if not player.data.achievements then DEBUG('err', 'Function: player.grant_achievement | Note: player.data.achievements is missing for ' .. player.source) return false end
if player.data.achievements[achievement_name] and player.data.achievements[achievement_name].achieved then DEBUG('warn', 'Function: player.grant_achievement | Note: Achievement ' .. achievement_name .. ' already granted to player ' .. player.source) return false end
player.data.achievements[achievement_name] = {
achieved = true,
timestamp = utils.dates.convert_timestamp(os.time())
}
player.set_data({ 'achievements' }, true)
DEBUG('info', 'Function: player.grant_achievement | Note: Achievement ' .. achievement_name .. ' granted to player ' .. player.source)
return true
end
Example
local player = boii.get_player(source)
player.grant_achievement('bought_first_car')
set_data()
Sets a players data.
Data updates can be optionally flagged to save to the database.
Function
function player.set_data(data_types, save_to_db)
data_types = next(data_types) and data_types or PLAYER_DATA_TYPES
local data_table = { passport = player.passport }
for _, data_type in pairs(data_types) do
if not player.data[data_type] then DEBUG('warn', 'Function: player.set_data | Note: Data type ' .. data_type .. ' not found in player data.') return end
data_table[data_type] = player.data[data_type]
end
TriggerClientEvent('boii:cl:set_data', player.source, data_table)
if save_to_db then
player.save_data(data_types)
end
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Setting all player data without saving.
player.set_data({})
--- Setting and saving.
player.set_data({}, true)
--- Changing the players first name.
player.data.identity.first_name = 'Bob'
--- Setting a specified data type.
player.set_data({'identity'})
save_data()
Saves player data updates to database.
Updates will only be saved to the database if flagged to do so through player.set_data(data_types, save_to_db)
Function
function player.save_data(data_types)
local queries = {}
for _, field in pairs(data_types) do
local data = player.data[field]
if data then
local table_info = TABLE_MAP[field]
if not table_info then DEBUG('err', 'Function: player.save_data | Note: No table defined for data type: ' .. field) return end
local is_batch = type(data) == 'table' and #data > 0 and type(data[1]) == 'table'
for _, record in ipairs(is_batch and data or {data}) do
local field_updates, params = create_query(player, table_info, record)
if #params > 0 then
local query = string.format('UPDATE %s SET %s WHERE %s', table_info.table, table.concat(field_updates, ', '), table.concat(table_info.where, ' = ? AND ') .. ' = ?')
queries[#queries + 1] = { query = query, params = params, record = record }
end
end
end
end
for _, query_data in ipairs(queries) do
MySQL.Async.execute(query_data.query, query_data.params, function(rows_changed)
if rows_changed <= 0 then DEBUG('err', 'Function: player.save_data | Note: Failed to save data for query: ' .. query_data.query .. ' | Data: ' .. json.encode(query_data.record or {})) return false end
end)
end
end
Example
--- Retrieve the player.
local player = boii.get_player(source)
--- Save specific player data types.
player.save_data({'identity', 'accounts'})
Last updated