mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 17:28:53 +00:00
Now we can extend xPlayer without touching core files
This commit is contained in:
+3
-3
@@ -2,9 +2,9 @@ Config = {}
|
||||
Config.Locale = 'en'
|
||||
|
||||
Config.Accounts = {
|
||||
bank = _U('account_bank'),
|
||||
bank = _U('account_bank'),
|
||||
black_money = _U('account_black_money'),
|
||||
money = _U('account_money')
|
||||
money = _U('account_money')
|
||||
}
|
||||
|
||||
Config.StartingAccountMoney = {bank = 50000}
|
||||
@@ -17,5 +17,5 @@ Config.MaxWeight = 24 -- the max inventory weight without backpack
|
||||
|
||||
Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds
|
||||
|
||||
Config.EnableDebug = false
|
||||
Config.EnableDebug = false
|
||||
Config.InventoryKey = 'REPLAY_START_STOP_RECORDING_SECONDARY' -- Key F2 by default
|
||||
|
||||
+4
-20
@@ -11,16 +11,7 @@ server_scripts {
|
||||
'@mysql-async/lib/MySQL.lua',
|
||||
|
||||
'locale.lua',
|
||||
'locales/de.lua',
|
||||
'locales/br.lua',
|
||||
'locales/fr.lua',
|
||||
'locales/en.lua',
|
||||
'locales/fi.lua',
|
||||
'locales/sv.lua',
|
||||
'locales/pl.lua',
|
||||
'locales/cs.lua',
|
||||
'locales/sc.lua',
|
||||
'locales/tc.lua',
|
||||
'locales/*.lua',
|
||||
|
||||
'config.lua',
|
||||
'config.weapons.lua',
|
||||
@@ -40,17 +31,9 @@ server_scripts {
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
|
||||
'locale.lua',
|
||||
'locales/de.lua',
|
||||
'locales/br.lua',
|
||||
'locales/fr.lua',
|
||||
'locales/en.lua',
|
||||
'locales/fi.lua',
|
||||
'locales/sv.lua',
|
||||
'locales/pl.lua',
|
||||
'locales/cs.lua',
|
||||
'locales/sc.lua',
|
||||
'locales/tc.lua',
|
||||
'locales/*.lua',
|
||||
|
||||
'config.lua',
|
||||
'config.weapons.lua',
|
||||
@@ -134,6 +117,7 @@ esxmodule 'menu_list' -- List menu
|
||||
|
||||
-- Misc
|
||||
esxmodule 'skin' -- Skin management
|
||||
esxmodule 'accessories' -- Skin accessories management
|
||||
|
||||
-- Jobs
|
||||
esxmodule 'job_police' -- Job police
|
||||
|
||||
+326
-20
@@ -1,19 +1,13 @@
|
||||
function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords)
|
||||
local self = {}
|
||||
function CreateExtendedPlayer(data)
|
||||
|
||||
self.accounts = accounts
|
||||
self.coords = coords
|
||||
self.group = group
|
||||
self.identifier = identifier
|
||||
self.inventory = inventory
|
||||
self.job = job
|
||||
self.loadout = loadout
|
||||
self.name = name
|
||||
self.playerId = playerId
|
||||
self.source = playerId
|
||||
self.variables = {}
|
||||
self.weight = weight
|
||||
self.maxWeight = Config.MaxWeight
|
||||
local self = {}
|
||||
|
||||
self.source = data.playerId
|
||||
self.maxWeight = Config.MaxWeight
|
||||
|
||||
for k,v in pairs(data) do
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group))
|
||||
|
||||
@@ -76,11 +70,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
end
|
||||
|
||||
self.set = function(k, v)
|
||||
self.variables[k] = v
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
self.get = function(k)
|
||||
return self.variables[k]
|
||||
return self[k]
|
||||
end
|
||||
|
||||
self.getAccounts = function(minimal)
|
||||
@@ -270,7 +264,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
|
||||
return newWeight <= self.maxWeight
|
||||
end
|
||||
|
||||
|
||||
self.maxCarryItem = function(name)
|
||||
local count = 0
|
||||
local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight
|
||||
@@ -326,7 +320,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
else
|
||||
self.job.skin_female = {}
|
||||
end
|
||||
|
||||
|
||||
TriggerEvent('esx:setJob', self.source, self.job, lastJob)
|
||||
self.triggerEvent('esx:setJob', self.job)
|
||||
else
|
||||
@@ -507,5 +501,317 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration)
|
||||
end
|
||||
|
||||
return self
|
||||
self.serialize = function()
|
||||
|
||||
local data = {
|
||||
accounts = self.getAccounts(),
|
||||
coords = self.getCoords(),
|
||||
identifier = self.getIdentifier(),
|
||||
inventory = self.getInventory(),
|
||||
job = self.getJob(),
|
||||
loadout = self.getLoadout(),
|
||||
maxWeight = self.getMaxWeight(),
|
||||
money = self.getMoney()
|
||||
}
|
||||
|
||||
TriggerEvent('esx:player:serialize', self, function(extraData)
|
||||
|
||||
for k,v in pairs(extraData) do
|
||||
data[k] = v
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
return data
|
||||
|
||||
end
|
||||
|
||||
self.serializeDB = function()
|
||||
|
||||
local job = self.getJob()
|
||||
|
||||
local data = {
|
||||
identifier = self.getIdentifier(),
|
||||
accounts = json.encode(self.getAccounts(true)),
|
||||
group = self.getGroup(),
|
||||
inventory = json.encode(self.getInventory(true)),
|
||||
job = job.name,
|
||||
job_grade = job.grade,
|
||||
loadout = json.encode(self.getLoadout(true)),
|
||||
position = json.encode(self.getCoords())
|
||||
}
|
||||
|
||||
TriggerEvent('esx:player:serialize:db', self, function(extraData)
|
||||
|
||||
for k,v in pairs(extraData) do
|
||||
data[k] = v
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
return data
|
||||
|
||||
end
|
||||
|
||||
TriggerEvent('esx:player:create', self) -- You can hook this event to extend xPlayer
|
||||
|
||||
return self
|
||||
|
||||
end
|
||||
|
||||
function LoadExtendedPlayer(identifier, playerId, cb)
|
||||
|
||||
MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(result)
|
||||
|
||||
local tasks = {}
|
||||
|
||||
local userData = {
|
||||
playerId = playerId,
|
||||
identifier = identifier,
|
||||
weight = 0,
|
||||
}
|
||||
|
||||
for entryName, entryValue in pairs(result[1]) do
|
||||
|
||||
TriggerEvent('esx:player:load:' .. entryName, identifier, playerId, result[1], userData, function(task)
|
||||
tasks[#tasks + 1] = task
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
Async.parallelLimit(tasks, 5, function(results)
|
||||
|
||||
for i=1, #results, 1 do
|
||||
|
||||
local result = results[i]
|
||||
|
||||
for k,v in pairs(result) do
|
||||
userData[k] = v
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local xPlayer = CreateExtendedPlayer(userData)
|
||||
|
||||
ESX.Players[playerId] = xPlayer
|
||||
|
||||
TriggerEvent('esx:playerLoaded', playerId, xPlayer)
|
||||
|
||||
xPlayer.triggerEvent('esx:playerLoaded', xPlayer.serialize())
|
||||
xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups)
|
||||
xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands)
|
||||
|
||||
if cb ~= nil then
|
||||
cb()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
AddEventHandler('esx:player:load:accounts', function(identifier, playerId, row, userData, addTask)
|
||||
|
||||
addTask(function(cb)
|
||||
|
||||
local data = {}
|
||||
local foundAccounts = {}
|
||||
|
||||
if row.accounts and row.accounts ~= '' then
|
||||
|
||||
local accounts = json.decode(row.accounts)
|
||||
|
||||
for account, money in pairs(accounts) do
|
||||
foundAccounts[account] = money
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for account, label in pairs(Config.Accounts) do
|
||||
|
||||
table.insert(data, {
|
||||
name = account,
|
||||
money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0,
|
||||
label = label
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
cb({accounts = data})
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('esx:player:load:job', function(identifier, playerId, row, userData, addTask)
|
||||
|
||||
addTask(function(cb)
|
||||
|
||||
local data = {}
|
||||
local jobObject, gradeObject = {}, {}
|
||||
|
||||
if ESX.DoesJobExist(row.job, row.job_grade) then
|
||||
jobObject, gradeObject = ESX.Jobs[row.job], ESX.Jobs[row.job].grades[tostring(row.job_grade)]
|
||||
else
|
||||
|
||||
print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(identifier, job, grade))
|
||||
|
||||
job, grade = 'unemployed', '0'
|
||||
jobObject, gradeObject = ESX.Jobs[row.job], ESX.Jobs[row.job].grades[tostring(rrow.job_grade)]
|
||||
|
||||
end
|
||||
|
||||
data.id = jobObject.id
|
||||
data.name = jobObject.name
|
||||
data.label = jobObject.label
|
||||
|
||||
data.grade = row.job_grade
|
||||
data.grade_name = gradeObject.name
|
||||
data.grade_label = gradeObject.label
|
||||
data.grade_salary = gradeObject.salary
|
||||
|
||||
data.skin_male = {}
|
||||
data.skin_female = {}
|
||||
|
||||
if gradeObject.skin_male then data.skin_male = json.decode(gradeObject.skin_male) end
|
||||
if gradeObject.skin_female then data.skin_female = json.decode(gradeObject.skin_female) end
|
||||
|
||||
cb({job = data})
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('esx:player:load:inventory', function(identifier, playerId, row, userData, addTask)
|
||||
|
||||
addTask(function(cb)
|
||||
|
||||
local data = {
|
||||
weight = userData.weight,
|
||||
inventory = {}
|
||||
}
|
||||
|
||||
local foundItems = {}
|
||||
|
||||
if row.inventory and row.inventory ~= '' then
|
||||
|
||||
local inventory = json.decode(row.inventory)
|
||||
|
||||
for name,count in pairs(inventory) do
|
||||
|
||||
local item = ESX.Items[name]
|
||||
|
||||
if item then
|
||||
foundItems[name] = count
|
||||
else
|
||||
print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, identifier))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for name,item in pairs(ESX.Items) do
|
||||
|
||||
local count = foundItems[name] or 0
|
||||
|
||||
if count > 0 then
|
||||
data.weight = data.weight + (item.weight * count)
|
||||
end
|
||||
|
||||
table.insert(data.inventory, {
|
||||
name = name,
|
||||
count = count,
|
||||
label = item.label,
|
||||
weight = item.weight,
|
||||
usable = ESX.UsableItemsCallbacks[name] ~= nil,
|
||||
rare = item.rare,
|
||||
canRemove = item.canRemove
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
table.sort(data.inventory, function(a, b)
|
||||
return a.label < b.label
|
||||
end)
|
||||
|
||||
cb(data)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('esx:player:load:group', function(identifier, playerId, row, userData, addTask)
|
||||
|
||||
addTask(function(cb)
|
||||
|
||||
local data = {}
|
||||
|
||||
if row.group then
|
||||
data = row.group
|
||||
else
|
||||
data.group = 'user'
|
||||
end
|
||||
|
||||
cb({group = data})
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('esx:player:load:loadout', function(identifier, playerId, row, userData, addTask)
|
||||
|
||||
addTask(function(cb)
|
||||
|
||||
local data = {}
|
||||
|
||||
if row.loadout and row.loadout ~= '' then
|
||||
|
||||
local loadout = json.decode(row.loadout)
|
||||
|
||||
for name,weapon in pairs(loadout) do
|
||||
|
||||
local label = ESX.GetWeaponLabel(name)
|
||||
|
||||
if label then
|
||||
|
||||
if not weapon.components then weapon.components = {} end
|
||||
if not weapon.tintIndex then weapon.tintIndex = 0 end
|
||||
|
||||
table.insert(data, {
|
||||
name = name,
|
||||
ammo = weapon.ammo,
|
||||
label = label,
|
||||
components = weapon.components,
|
||||
tintIndex = weapon.tintIndex
|
||||
})
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
cb({loadout = data})
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('esx:player:load:position', function(identifier, playerId, row, userData, addTask)
|
||||
|
||||
addTask(function(cb)
|
||||
|
||||
local data = {}
|
||||
|
||||
if row.position and row.position ~= '' then
|
||||
data = json.decode(row.position)
|
||||
else
|
||||
print('[es_extended] [^3WARNING^7] Column "position" in "users" table is missing required default value. Using backup coords, fix your database.')
|
||||
data = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8}
|
||||
end
|
||||
|
||||
cb({coords = data})
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
+30
-19
@@ -231,30 +231,41 @@ ESX.TriggerServerCallback = function(name, requestId, source, cb, ...)
|
||||
end
|
||||
|
||||
ESX.SavePlayer = function(xPlayer, cb)
|
||||
local asyncTasks = {}
|
||||
|
||||
table.insert(asyncTasks, function(cb2)
|
||||
MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, `group` = @group, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', {
|
||||
['@accounts'] = json.encode(xPlayer.getAccounts(true)),
|
||||
['@job'] = xPlayer.job.name,
|
||||
['@job_grade'] = xPlayer.job.grade,
|
||||
['@group'] = xPlayer.getGroup(),
|
||||
['@loadout'] = json.encode(xPlayer.getLoadout(true)),
|
||||
['@position'] = json.encode(xPlayer.getCoords()),
|
||||
['@identifier'] = xPlayer.getIdentifier(),
|
||||
['@inventory'] = json.encode(xPlayer.getInventory(true))
|
||||
}, function(rowsChanged)
|
||||
cb2()
|
||||
end)
|
||||
end)
|
||||
local data = xPlayer.serializeDB()
|
||||
local statement = 'UPDATE users SET'
|
||||
local fields = {}
|
||||
|
||||
local first = true
|
||||
|
||||
for k,v in pairs(data) do
|
||||
|
||||
if first then
|
||||
statement = statement .. ' `' .. k .. '` = ' .. '@' .. k
|
||||
first = false
|
||||
else
|
||||
statement = statement .. ', `' .. k .. '` = ' .. '@' .. k
|
||||
end
|
||||
|
||||
fields['@' .. k] = v
|
||||
|
||||
end
|
||||
|
||||
statement = statement .. ' WHERE `identifier` = @identifier'
|
||||
|
||||
print(statement)
|
||||
print(ESX.DumpTable(fields))
|
||||
|
||||
MySQL.Async.execute(statement, fields, function(rowsChanged)
|
||||
|
||||
Async.parallel(asyncTasks, function(results)
|
||||
print(('[es_extended] [^2INFO^7] Saved player "%s^7"'):format(xPlayer.getName()))
|
||||
|
||||
if cb then
|
||||
if cb then
|
||||
cb()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
ESX.SavePlayers = function(cb)
|
||||
|
||||
+10
-162
@@ -50,9 +50,13 @@ function onPlayerJoined(playerId)
|
||||
MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', {
|
||||
['@identifier'] = identifier
|
||||
}, function(result)
|
||||
if result then
|
||||
loadESXPlayer(identifier, playerId)
|
||||
else
|
||||
|
||||
if result then
|
||||
|
||||
LoadExtendedPlayer(identifier, playerId)
|
||||
|
||||
else
|
||||
|
||||
local accounts = {}
|
||||
|
||||
for account,money in pairs(Config.StartingAccountMoney) do
|
||||
@@ -63,8 +67,9 @@ function onPlayerJoined(playerId)
|
||||
['@accounts'] = json.encode(accounts),
|
||||
['@identifier'] = identifier
|
||||
}, function(rowsChanged)
|
||||
loadESXPlayer(identifier, playerId)
|
||||
end)
|
||||
LoadExtendedPlayer(identifier, playerId)
|
||||
end)
|
||||
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -96,163 +101,6 @@ AddEventHandler('playerConnecting', function(name, setCallback, deferrals)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
function loadESXPlayer(identifier, playerId)
|
||||
local tasks = {}
|
||||
|
||||
local userData = {
|
||||
accounts = {},
|
||||
inventory = {},
|
||||
job = {},
|
||||
loadout = {},
|
||||
playerName = GetPlayerName(playerId),
|
||||
weight = 0
|
||||
}
|
||||
|
||||
table.insert(tasks, function(cb)
|
||||
MySQL.Async.fetchAll('SELECT accounts, job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', {
|
||||
['@identifier'] = identifier
|
||||
}, function(result)
|
||||
local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade)
|
||||
local foundAccounts, foundItems = {}, {}
|
||||
|
||||
-- Accounts
|
||||
if result[1].accounts and result[1].accounts ~= '' then
|
||||
local accounts = json.decode(result[1].accounts)
|
||||
|
||||
for account,money in pairs(accounts) do
|
||||
foundAccounts[account] = money
|
||||
end
|
||||
end
|
||||
|
||||
for account,label in pairs(Config.Accounts) do
|
||||
table.insert(userData.accounts, {
|
||||
name = account,
|
||||
money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0,
|
||||
label = label
|
||||
})
|
||||
end
|
||||
|
||||
-- Job
|
||||
if ESX.DoesJobExist(job, grade) then
|
||||
jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]
|
||||
else
|
||||
print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(identifier, job, grade))
|
||||
job, grade = 'unemployed', '0'
|
||||
jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]
|
||||
end
|
||||
|
||||
userData.job.id = jobObject.id
|
||||
userData.job.name = jobObject.name
|
||||
userData.job.label = jobObject.label
|
||||
|
||||
userData.job.grade = tonumber(grade)
|
||||
userData.job.grade_name = gradeObject.name
|
||||
userData.job.grade_label = gradeObject.label
|
||||
userData.job.grade_salary = gradeObject.salary
|
||||
|
||||
userData.job.skin_male = {}
|
||||
userData.job.skin_female = {}
|
||||
|
||||
if gradeObject.skin_male then userData.job.skin_male = json.decode(gradeObject.skin_male) end
|
||||
if gradeObject.skin_female then userData.job.skin_female = json.decode(gradeObject.skin_female) end
|
||||
|
||||
-- Inventory
|
||||
if result[1].inventory and result[1].inventory ~= '' then
|
||||
local inventory = json.decode(result[1].inventory)
|
||||
|
||||
for name,count in pairs(inventory) do
|
||||
local item = ESX.Items[name]
|
||||
|
||||
if item then
|
||||
foundItems[name] = count
|
||||
else
|
||||
print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, identifier))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for name,item in pairs(ESX.Items) do
|
||||
local count = foundItems[name] or 0
|
||||
if count > 0 then userData.weight = userData.weight + (item.weight * count) end
|
||||
|
||||
table.insert(userData.inventory, {
|
||||
name = name,
|
||||
count = count,
|
||||
label = item.label,
|
||||
weight = item.weight,
|
||||
usable = ESX.UsableItemsCallbacks[name] ~= nil,
|
||||
rare = item.rare,
|
||||
canRemove = item.canRemove
|
||||
})
|
||||
end
|
||||
|
||||
table.sort(userData.inventory, function(a, b)
|
||||
return a.label < b.label
|
||||
end)
|
||||
|
||||
-- Group
|
||||
if result[1].group then
|
||||
userData.group = result[1].group
|
||||
else
|
||||
userData.group = 'user'
|
||||
end
|
||||
|
||||
-- Loadout
|
||||
if result[1].loadout and result[1].loadout ~= '' then
|
||||
local loadout = json.decode(result[1].loadout)
|
||||
|
||||
for name,weapon in pairs(loadout) do
|
||||
local label = ESX.GetWeaponLabel(name)
|
||||
|
||||
if label then
|
||||
if not weapon.components then weapon.components = {} end
|
||||
if not weapon.tintIndex then weapon.tintIndex = 0 end
|
||||
|
||||
table.insert(userData.loadout, {
|
||||
name = name,
|
||||
ammo = weapon.ammo,
|
||||
label = label,
|
||||
components = weapon.components,
|
||||
tintIndex = weapon.tintIndex
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Position
|
||||
if result[1].position and result[1].position ~= '' then
|
||||
userData.coords = json.decode(result[1].position)
|
||||
else
|
||||
print('[es_extended] [^3WARNING^7] Column "position" in "users" table is missing required default value. Using backup coords, fix your database.')
|
||||
userData.coords = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8}
|
||||
end
|
||||
|
||||
cb()
|
||||
end)
|
||||
end)
|
||||
|
||||
Async.parallel(tasks, function(results)
|
||||
local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.weight, userData.job, userData.loadout, userData.playerName, userData.coords)
|
||||
ESX.Players[playerId] = xPlayer
|
||||
TriggerEvent('esx:playerLoaded', playerId, xPlayer)
|
||||
|
||||
xPlayer.triggerEvent('esx:playerLoaded', {
|
||||
accounts = xPlayer.getAccounts(),
|
||||
coords = xPlayer.getCoords(),
|
||||
identifier = xPlayer.getIdentifier(),
|
||||
inventory = xPlayer.getInventory(),
|
||||
job = xPlayer.getJob(),
|
||||
loadout = xPlayer.getLoadout(),
|
||||
maxWeight = xPlayer.getMaxWeight(),
|
||||
money = xPlayer.getMoney()
|
||||
})
|
||||
|
||||
xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups)
|
||||
xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands)
|
||||
end)
|
||||
end
|
||||
|
||||
AddEventHandler('chatMessage', function(playerId, author, message)
|
||||
if message:sub(1, 1) == '/' and playerId > 0 then
|
||||
CancelEvent()
|
||||
|
||||
Reference in New Issue
Block a user