mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 17:28:53 +00:00
f89e051756
This commit implements a new way of saving and getting player coords. Player coords are synced with its assigned xPlayer, the syncing interval is defined in the configuration file. Also coords wont sync if the player is too close to their previous location. Existing servers must change their database to account for the new length of the position varchar, at 53 chars max. There's also a column default value specified in the sql file. New xPlayer functions: - .getCoords() - .setCoords() (x,y,z,heading (optional) table - .updateCoords() The last one is used for syncing coords from client (interval). The second one will teleport the player. First one is a renamed .getLastPosition()
193 lines
4.5 KiB
Lua
193 lines
4.5 KiB
Lua
ESX.Trace = function(msg)
|
|
if Config.EnableDebug then
|
|
print(('[es_extended] [^2TRACE^7] %s^7'):format(msg))
|
|
end
|
|
end
|
|
|
|
ESX.SetTimeout = function(msec, cb)
|
|
local id = ESX.TimeoutCount + 1
|
|
|
|
SetTimeout(msec, function()
|
|
if ESX.CancelledTimeouts[id] then
|
|
ESX.CancelledTimeouts[id] = nil
|
|
else
|
|
cb()
|
|
end
|
|
end)
|
|
|
|
ESX.TimeoutCount = id
|
|
|
|
return id
|
|
end
|
|
|
|
ESX.ClearTimeout = function(id)
|
|
ESX.CancelledTimeouts[id] = true
|
|
end
|
|
|
|
ESX.RegisterServerCallback = function(name, cb)
|
|
ESX.ServerCallbacks[name] = cb
|
|
end
|
|
|
|
ESX.TriggerServerCallback = function(name, requestId, source, cb, ...)
|
|
if ESX.ServerCallbacks[name] ~= nil then
|
|
ESX.ServerCallbacks[name](source, cb, ...)
|
|
else
|
|
print(('[es_extended] [^3WARNING^7] Server callback "%s" does not exist. Make sure that the server sided file really is loading, an error in that file might cause it to not load.'):format(name))
|
|
end
|
|
end
|
|
|
|
ESX.SavePlayer = function(xPlayer, cb)
|
|
local asyncTasks = {}
|
|
|
|
-- User accounts
|
|
for k,v in ipairs(xPlayer.accounts) do
|
|
if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then
|
|
table.insert(asyncTasks, function(cb)
|
|
MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', {
|
|
['@money'] = v.money,
|
|
['@identifier'] = xPlayer.identifier,
|
|
['@name'] = v.name
|
|
}, function(rowsChanged)
|
|
cb()
|
|
end)
|
|
end)
|
|
|
|
ESX.LastPlayerData[xPlayer.source].accounts[v.name] = v.money
|
|
end
|
|
end
|
|
|
|
-- Inventory items
|
|
for k,v in ipairs(xPlayer.inventory) do
|
|
if ESX.LastPlayerData[xPlayer.source].items[v.name] ~= v.count then
|
|
table.insert(asyncTasks, function(cb)
|
|
MySQL.Async.execute('UPDATE user_inventory SET count = @count WHERE identifier = @identifier AND item = @item', {
|
|
['@count'] = v.count,
|
|
['@identifier'] = xPlayer.identifier,
|
|
['@item'] = v.name
|
|
}, function(rowsChanged)
|
|
cb()
|
|
end)
|
|
end)
|
|
|
|
ESX.LastPlayerData[xPlayer.source].items[v.name] = v.count
|
|
end
|
|
end
|
|
|
|
-- Job, loadout and position
|
|
table.insert(asyncTasks, function(cb)
|
|
MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position WHERE identifier = @identifier', {
|
|
['@job'] = xPlayer.job.name,
|
|
['@job_grade'] = xPlayer.job.grade,
|
|
['@loadout'] = json.encode(xPlayer.getLoadout()),
|
|
['@position'] = json.encode(xPlayer.getCoords()),
|
|
['@identifier'] = xPlayer.identifier
|
|
}, function(rowsChanged)
|
|
cb()
|
|
end)
|
|
end)
|
|
|
|
Async.parallel(asyncTasks, function(results)
|
|
print(('[es_extended] [^2INFO^7] Saved player "%s^7"'):format(xPlayer.getName()))
|
|
|
|
if cb ~= nil then
|
|
cb()
|
|
end
|
|
end)
|
|
end
|
|
|
|
ESX.SavePlayers = function(cb)
|
|
local asyncTasks = {}
|
|
local xPlayers = ESX.GetPlayers()
|
|
|
|
for i=1, #xPlayers, 1 do
|
|
table.insert(asyncTasks, function(cb)
|
|
local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
|
|
ESX.SavePlayer(xPlayer, cb)
|
|
end)
|
|
end
|
|
|
|
Async.parallelLimit(asyncTasks, 8, function(results)
|
|
print(('[es_extended] [^2INFO^7] Saved %s player(s)'):format(#xPlayers))
|
|
if cb ~= nil then
|
|
cb()
|
|
end
|
|
end)
|
|
end
|
|
|
|
ESX.StartDBSync = function()
|
|
function saveData()
|
|
ESX.SavePlayers()
|
|
SetTimeout(10 * 60 * 1000, saveData)
|
|
end
|
|
|
|
SetTimeout(10 * 60 * 1000, saveData)
|
|
end
|
|
|
|
ESX.GetPlayers = function()
|
|
local sources = {}
|
|
|
|
for k,v in pairs(ESX.Players) do
|
|
table.insert(sources, k)
|
|
end
|
|
|
|
return sources
|
|
end
|
|
|
|
ESX.GetPlayerFromId = function(source)
|
|
return ESX.Players[tonumber(source)]
|
|
end
|
|
|
|
ESX.GetPlayerFromIdentifier = function(identifier)
|
|
for k,v in pairs(ESX.Players) do
|
|
if v.identifier == identifier then
|
|
return v
|
|
end
|
|
end
|
|
end
|
|
|
|
ESX.RegisterUsableItem = function(item, cb)
|
|
ESX.UsableItemsCallbacks[item] = cb
|
|
end
|
|
|
|
ESX.UseItem = function(source, item)
|
|
ESX.UsableItemsCallbacks[item](source)
|
|
end
|
|
|
|
ESX.GetItemLabel = function(item)
|
|
if ESX.Items[item] ~= nil then
|
|
return ESX.Items[item].label
|
|
end
|
|
end
|
|
|
|
ESX.CreatePickup = function(type, name, count, label, playerId, components)
|
|
local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1)
|
|
local xPlayer = ESX.GetPlayerFromId(playerId)
|
|
|
|
ESX.Pickups[pickupId] = {
|
|
type = type,
|
|
name = name,
|
|
count = count,
|
|
label = label,
|
|
coords = xPlayer.getCoords(),
|
|
}
|
|
|
|
if type == 'item_weapon' then
|
|
ESX.Pickups[pickupId].components = components
|
|
end
|
|
|
|
TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components)
|
|
ESX.PickupId = pickupId
|
|
end
|
|
|
|
ESX.DoesJobExist = function(job, grade)
|
|
grade = tostring(grade)
|
|
|
|
if job and grade then
|
|
if ESX.Jobs[job] and ESX.Jobs[job].grades[grade] then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|