diff --git a/client/common.lua b/client/common.lua index 14b6a4e6..26c0ed40 100644 --- a/client/common.lua +++ b/client/common.lua @@ -1,7 +1,7 @@ AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) + cb(ESX) end) function getSharedObject() - return ESX + return ESX end diff --git a/client/entityiter.lua b/client/entityiter.lua index 7c7ec4d5..20dd2018 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -25,55 +25,50 @@ OTHER DEALINGS IN THE SOFTWARE. ]] local entityEnumerator = { - __gc = function(enum) - if enum.destructor and enum.handle then - enum.destructor(enum.handle) - end - enum.destructor = nil - enum.handle = nil - end + __gc = function(enum) + if enum.destructor and enum.handle then + enum.destructor(enum.handle) + end + + enum.destructor = nil + enum.handle = nil + end } local function EnumerateEntities(initFunc, moveFunc, disposeFunc) - return coroutine.wrap(function() - local iter, id = initFunc() - if not id or id == 0 then - disposeFunc(iter) - return - end + return coroutine.wrap(function() + local iter, id = initFunc() + if not id or id == 0 then + disposeFunc(iter) + return + end - local enum = {handle = iter, destructor = disposeFunc} - setmetatable(enum, entityEnumerator) + local enum = {handle = iter, destructor = disposeFunc} + setmetatable(enum, entityEnumerator) - local next = true - repeat - coroutine.yield(id) - next, id = moveFunc(iter) - until not next + local next = true + repeat + coroutine.yield(id) + next, id = moveFunc(iter) + until not next - enum.destructor, enum.handle = nil, nil - disposeFunc(iter) - end) + enum.destructor, enum.handle = nil, nil + disposeFunc(iter) + end) end function EnumerateObjects() - return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) + return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) end function EnumeratePeds() - return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed) + return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed) end function EnumerateVehicles() - return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle) + return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle) end function EnumeratePickups() - return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup) + return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup) end - ---[[Usage: -for ped in EnumeratePeds() do - -end -]] diff --git a/client/functions.lua b/client/functions.lua index ae21a250..1867e8ba 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -20,32 +20,28 @@ ESX.Scaleform.Utils = {} ESX.Streaming = {} -ESX.GetConfig = function() - return Config -end - ESX.SetTimeout = function(msec, cb) - table.insert(ESX.TimeoutCallbacks, { - time = GetGameTimer() + msec, - cb = cb - }) - return #ESX.TimeoutCallbacks + table.insert(ESX.TimeoutCallbacks, { + time = GetGameTimer() + msec, + cb = cb + }) + return #ESX.TimeoutCallbacks end ESX.ClearTimeout = function(i) - ESX.TimeoutCallbacks[i] = nil + ESX.TimeoutCallbacks[i] = nil end ESX.IsPlayerLoaded = function() - return ESX.PlayerLoaded + return ESX.PlayerLoaded end ESX.GetPlayerData = function() - return ESX.PlayerData + return ESX.PlayerData end ESX.SetPlayerData = function(key, val) - ESX.PlayerData[key] = val + ESX.PlayerData[key] = val end ESX.ShowNotification = function(msg) @@ -70,587 +66,515 @@ ESX.ShowHelpNotification = function(msg) end ESX.TriggerServerCallback = function(name, cb, ...) + ESX.ServerCallbacks[ESX.CurrentRequestId] = cb - ESX.ServerCallbacks[ESX.CurrentRequestId] = cb - - TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) - - if ESX.CurrentRequestId < 65535 then - ESX.CurrentRequestId = ESX.CurrentRequestId + 1 - else - ESX.CurrentRequestId = 0 - end + TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) + if ESX.CurrentRequestId < 65535 then + ESX.CurrentRequestId = ESX.CurrentRequestId + 1 + else + ESX.CurrentRequestId = 0 + end end ESX.UI.HUD.SetDisplay = function(opacity) - - SendNUIMessage({ - action = 'setHUDDisplay', - opacity = opacity - }) - + SendNUIMessage({ + action = 'setHUDDisplay', + opacity = opacity + }) end ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) + local found = false - local found = false + for i=1, #ESX.UI.HUD.RegisteredElements, 1 do + if ESX.UI.HUD.RegisteredElements[i] == name then + found = true + break + end + end - for i=1, #ESX.UI.HUD.RegisteredElements, 1 do - if ESX.UI.HUD.RegisteredElements[i] == name then - found = true - break - end - end + if found then + return + end - if found then - return - end + table.insert(ESX.UI.HUD.RegisteredElements, name) - table.insert(ESX.UI.HUD.RegisteredElements, name) - - SendNUIMessage({ - action = 'insertHUDElement', - name = name, - index = index, - priority = priority, - html = html, - data = data, - }) - - ESX.UI.HUD.UpdateElement(name, data) + SendNUIMessage({ + action = 'insertHUDElement', + name = name, + index = index, + priority = priority, + html = html, + data = data, + }) + ESX.UI.HUD.UpdateElement(name, data) end ESX.UI.HUD.RemoveElement = function(name) + for i=1, #ESX.UI.HUD.RegisteredElements, 1 do + if ESX.UI.HUD.RegisteredElements[i] == name then + table.remove(ESX.UI.HUD.RegisteredElements, i) + break + end + end - for i=1, #ESX.UI.HUD.RegisteredElements, 1 do - if ESX.UI.HUD.RegisteredElements[i] == name then - table.remove(ESX.UI.HUD.RegisteredElements, i) - break - end - end - - SendNUIMessage({ - action = 'deleteHUDElement', - name = name - }) - + SendNUIMessage({ + action = 'deleteHUDElement', + name = name + }) end ESX.UI.HUD.UpdateElement = function(name, data) - - SendNUIMessage({ - action = 'updateHUDElement', - name = name, - data = data, - }) - + SendNUIMessage({ + action = 'updateHUDElement', + name = name, + data = data, + }) end ESX.UI.Menu.RegisterType = function(type, open, close) - - ESX.UI.Menu.RegisteredTypes[type] = { - open = open, - close = close, - } - + ESX.UI.Menu.RegisteredTypes[type] = { + open = open, + close = close, + } end -local _type = type - ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) + local menu = {} - local menu = {} + menu.type = type + menu.namespace = namespace + menu.name = name + menu.data = data + menu.submit = submit + menu.cancel = cancel + menu.change = change - menu.type = type - menu.namespace = namespace - menu.name = name - menu.data = data - menu.submit = submit - menu.cancel = cancel - menu.change = change + menu.close = function() - menu.close = function() + ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) - ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + ESX.UI.Menu.Opened[i] = nil + end + end + end - for i=1, #ESX.UI.Menu.Opened, 1 do + if close ~= nil then + close() + end - if ESX.UI.Menu.Opened[i] ~= nil then - if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then - ESX.UI.Menu.Opened[i] = nil - end - end + end - end + menu.update = function(query, newData) - if close ~= nil then - close() - end + for i=1, #menu.data.elements, 1 do + local match = true - end + for k,v in pairs(query) do + if menu.data.elements[i][k] ~= v then + match = false + end + end - menu.update = function(query, newData) + if match then + for k,v in pairs(newData) do + menu.data.elements[i][k] = v + end + end + end - for i=1, #menu.data.elements, 1 do + end - local match = true + menu.refresh = function() + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) + end - for k,v in pairs(query) do - if menu.data.elements[i][k] ~= v then - match = false - end - end + menu.setElement = function(i, key, val) + menu.data.elements[i][key] = val + end - if match then - for k,v in pairs(newData) do - menu.data.elements[i][k] = v - end - end - - end - - end - - menu.refresh = function() - ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) - end - - menu.setElement = function(i, key, val) - menu.data.elements[i][key] = val - end - - table.insert(ESX.UI.Menu.Opened, menu) - - ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) - - return menu + table.insert(ESX.UI.Menu.Opened, menu) + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) + return menu end ESX.UI.Menu.Close = function(type, namespace, name) - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then - ESX.UI.Menu.Opened[i].close() - ESX.UI.Menu.Opened[i] = nil - end - end - end - + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end + end + end end ESX.UI.Menu.CloseAll = function() - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - ESX.UI.Menu.Opened[i].close() - ESX.UI.Menu.Opened[i] = nil - end - end - + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end + end end ESX.UI.Menu.GetOpened = function(type, namespace, name) - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then - return ESX.UI.Menu.Opened[i] - end - end - end - + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + return ESX.UI.Menu.Opened[i] + end + end + end end ESX.UI.Menu.GetOpenedMenus = function() - return ESX.UI.Menu.Opened + return ESX.UI.Menu.Opened end ESX.UI.Menu.IsOpen = function(type, namespace, name) - return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil + return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil end ESX.UI.ShowInventoryItemNotification = function(add, item, count) - SendNUIMessage({ - action = 'inventoryNotification', - add = add, - item = item, - count = count - }) + SendNUIMessage({ + action = 'inventoryNotification', + add = add, + item = item, + count = count + }) end ESX.GetWeaponList = function() - return Config.Weapons + return Config.Weapons end ESX.GetWeaponLabel = function(name) + name = string.upper(name) + local weapons = ESX.GetWeaponList() - name = string.upper(name) - local weapons = ESX.GetWeaponList() - - for i=1, #weapons, 1 do - if weapons[i].name == name then - return weapons[i].label - end - end - + for i=1, #weapons, 1 do + if weapons[i].name == name then + return weapons[i].label + end + end end ESX.Game.GetPedMugshot = function(ped) - local mugshot = RegisterPedheadshot(ped) - while not IsPedheadshotReady(mugshot) do - Citizen.Wait(0) - end + local mugshot = RegisterPedheadshot(ped) + while not IsPedheadshotReady(mugshot) do + Citizen.Wait(0) + end - return mugshot, GetPedheadshotTxdString(mugshot) + return mugshot, GetPedheadshotTxdString(mugshot) end ESX.Game.Teleport = function(entity, coords, cb) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end - while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) - Citizen.Wait(0) - end - - SetEntityCoords(entity, coords.x, coords.y, coords.z) - - if cb ~= nil then - cb() - end + SetEntityCoords(entity, coords.x, coords.y, coords.z) + if cb ~= nil then + cb() + end end ESX.Game.SpawnObject = function(model, coords, cb) + local model = (type(model) == 'number' and model or GetHashKey(model)) - local model = (type(model) == 'number' and model or GetHashKey(model)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end - - local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) - - if cb ~= nil then - cb(obj) - end - - end) + local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) + if cb ~= nil then + cb(obj) + end + end) end ESX.Game.SpawnLocalObject = function(model, coords, cb) + local model = (type(model) == 'number' and model or GetHashKey(model)) - local model = (type(model) == 'number' and model or GetHashKey(model)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end - - local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) - - if cb ~= nil then - cb(obj) - end - - end) + local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) + if cb ~= nil then + cb(obj) + end + end) end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(vehicle, false, true) - DeleteVehicle(vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) end ESX.Game.DeleteObject = function(object) - SetEntityAsMissionEntity(object, false, true) - DeleteObject(object) + SetEntityAsMissionEntity(object, false, true) + DeleteObject(object) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) + local id = NetworkGetNetworkIdFromEntity(vehicle) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + SetNetworkIdCanMigrate(id, true) + SetEntityAsMissionEntity(vehicle, true, false) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetVehicleNeedsToBeHotwired(vehicle, false) + SetModelAsNoLongerNeeded(model) - local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) - SetVehicleNeedsToBeHotwired(vehicle, false) - SetModelAsNoLongerNeeded(model) + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - - SetVehRadioStation(vehicle, 'OFF') - - if cb ~= nil then - cb(vehicle) - end - - end) + SetVehRadioStation(vehicle, 'OFF') + if cb ~= nil then + cb(vehicle) + end + end) end ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + SetEntityAsMissionEntity(vehicle, true, false) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetVehicleNeedsToBeHotwired(vehicle, false) + SetModelAsNoLongerNeeded(model) - local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - SetEntityAsMissionEntity(vehicle, true, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) - SetVehicleNeedsToBeHotwired(vehicle, false) - SetModelAsNoLongerNeeded(model) + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - - SetVehRadioStation(vehicle, 'OFF') - - if cb ~= nil then - cb(vehicle) - end - - end) + SetVehRadioStation(vehicle, 'OFF') + if cb ~= nil then + cb(vehicle) + end + end) end ESX.Game.GetObjects = function() + local objects = {} - local objects = {} - - for object in EnumerateObjects() do - table.insert(objects, object) - end - - return objects + for object in EnumerateObjects() do + table.insert(objects, object) + end + return objects end ESX.Game.GetClosestObject = function(filter, coords) + local objects = ESX.Game.GetObjects() + local closestDistance = -1 + local closestObject = -1 + local filter = filter + local coords = coords - local objects = ESX.Game.GetObjects() - local closestDistance = -1 - local closestObject = -1 - local filter = filter - local coords = coords + if type(filter) == 'string' then + if filter ~= '' then + filter = {filter} + end + end - if type(filter) == 'string' then - if filter ~= '' then - filter = {filter} - end - end + if coords == nil then + local playerPed = PlayerPedId() + coords = GetEntityCoords(playerPed) + end - if coords == nil then - local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) - end + for i=1, #objects, 1 do - for i=1, #objects, 1 do + local foundObject = false - local foundObject = false + if filter == nil or (type(filter) == 'table' and #filter == 0) then + foundObject = true + else - if filter == nil or (type(filter) == 'table' and #filter == 0) then - foundObject = true - else + local objectModel = GetEntityModel(objects[i]) - local objectModel = GetEntityModel(objects[i]) + for j=1, #filter, 1 do + if objectModel == GetHashKey(filter[j]) then + foundObject = true + end + end - for j=1, #filter, 1 do - if objectModel == GetHashKey(filter[j]) then - foundObject = true - end - end + end - end + if foundObject then + local objectCoords = GetEntityCoords(objects[i]) + local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) - if foundObject then + if closestDistance == -1 or closestDistance > distance then + closestObject = objects[i] + closestDistance = distance + end + end - local objectCoords = GetEntityCoords(objects[i]) - local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] - closestDistance = distance - end - - end - - end - - return closestObject, closestDistance + end + return closestObject, closestDistance end ESX.Game.GetPlayers = function() + local maxPlayers = Config.MaxPlayers + local players = {} - local maxPlayers = Config.MaxPlayers - local players = {} + for i=0, maxPlayers, 1 do - for i=0, maxPlayers, 1 do + local ped = GetPlayerPed(i) - local ped = GetPlayerPed(i) - - if DoesEntityExist(ped) then - table.insert(players, i) - end - end - - return players + if DoesEntityExist(ped) then + table.insert(players, i) + end + end + return players end ESX.Game.GetClosestPlayer = function(coords) + local players = ESX.Game.GetPlayers() + local closestDistance = -1 + local closestPlayer = -1 + local coords = coords + local usePlayerPed = false + local playerPed = PlayerPedId() + local playerId = PlayerId() - local players = ESX.Game.GetPlayers() - local closestDistance = -1 - local closestPlayer = -1 - local coords = coords - local usePlayerPed = false - local playerPed = PlayerPedId() - local playerId = PlayerId() + if coords == nil then + usePlayerPed = true + coords = GetEntityCoords(playerPed) + end - if coords == nil then - usePlayerPed = true - coords = GetEntityCoords(playerPed) - end + for i=1, #players, 1 do + local target = GetPlayerPed(players[i]) - for i=1, #players, 1 do + if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then + local targetCoords = GetEntityCoords(target) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - local target = GetPlayerPed(players[i]) + if closestDistance == -1 or closestDistance > distance then + closestPlayer = players[i] + closestDistance = distance + end + end + end - if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then - - local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPlayer = players[i] - closestDistance = distance - end - - end - - end - - return closestPlayer, closestDistance + return closestPlayer, closestDistance end ESX.Game.GetPlayersInArea = function(coords, area) + local players = ESX.Game.GetPlayers() + local playersInArea = {} - local players = ESX.Game.GetPlayers() - local playersInArea = {} + for i=1, #players, 1 do + local target = GetPlayerPed(players[i]) + local targetCoords = GetEntityCoords(target) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #players, 1 do + if distance <= area then + table.insert(playersInArea, players[i]) + end + end - local target = GetPlayerPed(players[i]) - local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - - if distance <= area then - table.insert(playersInArea, players[i]) - end - - end - - return playersInArea + return playersInArea end ESX.Game.GetVehicles = function() + local vehicles = {} - local vehicles = {} - - for vehicle in EnumerateVehicles() do - table.insert(vehicles, vehicle) - end - - return vehicles + for vehicle in EnumerateVehicles() do + table.insert(vehicles, vehicle) + end + return vehicles end ESX.Game.GetClosestVehicle = function(coords) + local vehicles = ESX.Game.GetVehicles() + local closestDistance = -1 + local closestVehicle = -1 + local coords = coords - local vehicles = ESX.Game.GetVehicles() - local closestDistance = -1 - local closestVehicle = -1 - local coords = coords + if coords == nil then + local playerPed = PlayerPedId() + coords = GetEntityCoords(playerPed) + end - if coords == nil then - local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) - end + for i=1, #vehicles, 1 do + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #vehicles, 1 do - - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestVehicle = vehicles[i] - closestDistance = distance - end - - end - - return closestVehicle, closestDistance + if closestDistance == -1 or closestDistance > distance then + closestVehicle = vehicles[i] + closestDistance = distance + end + end + return closestVehicle, closestDistance end ESX.Game.GetVehiclesInArea = function(coords, area) + local vehicles = ESX.Game.GetVehicles() + local vehiclesInArea = {} - local vehicles = ESX.Game.GetVehicles() - local vehiclesInArea = {} + for i=1, #vehicles, 1 do + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #vehicles, 1 do + if distance <= area then + table.insert(vehiclesInArea, vehicles[i]) + end + end - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - - if distance <= area then - table.insert(vehiclesInArea, vehicles[i]) - end - - end - - return vehiclesInArea + return vehiclesInArea end ESX.Game.GetVehicleInDirection = function() @@ -670,434 +594,417 @@ ESX.Game.IsSpawnPointClear = function(coords, radius) end ESX.Game.GetPeds = function(ignoreList) + local ignoreList = ignoreList or {} + local peds = {} - local ignoreList = ignoreList or {} - local peds = {} + for ped in EnumeratePeds() do + local found = false - for ped in EnumeratePeds() do + for j=1, #ignoreList, 1 do + if ignoreList[j] == ped then + found = true + end + end - local found = false - - for j=1, #ignoreList, 1 do - if ignoreList[j] == ped then - found = true - end - end - - if not found then - table.insert(peds, ped) - end - - end - - return peds + if not found then + table.insert(peds, ped) + end + end + return peds end ESX.Game.GetClosestPed = function(coords, ignoreList) + local ignoreList = ignoreList or {} + local peds = ESX.Game.GetPeds(ignoreList) + local closestDistance = -1 + local closestPed = -1 - local ignoreList = ignoreList or {} - local peds = ESX.Game.GetPeds(ignoreList) - local closestDistance = -1 - local closestPed = -1 + for i=1, #peds, 1 do + local pedCoords = GetEntityCoords(peds[i]) + local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #peds, 1 do - - local pedCoords = GetEntityCoords(peds[i]) - local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPed = peds[i] - closestDistance = distance - end - - end - - return closestPed, closestDistance + if closestDistance == -1 or closestDistance > distance then + closestPed = peds[i] + closestDistance = distance + end + end + return closestPed, closestDistance end ESX.Game.GetVehicleProperties = function(vehicle) + local color1, color2 = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - local color1, color2 = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + return { - return { + model = GetEntityModel(vehicle), - model = GetEntityModel(vehicle), + plate = GetVehicleNumberPlateText(vehicle), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - plate = GetVehicleNumberPlateText(vehicle), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + health = GetEntityHealth(vehicle), + dirtLevel = GetVehicleDirtLevel(vehicle), - health = GetEntityHealth(vehicle), - dirtLevel = GetVehicleDirtLevel(vehicle), + color1 = color1, + color2 = color2, - color1 = color1, - color2 = color2, + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, - pearlescentColor = pearlescentColor, - wheelColor = wheelColor, + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + }, - neonEnabled = { - IsVehicleNeonLightEnabled(vehicle, 0), - IsVehicleNeonLightEnabled(vehicle, 1), - IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3), - }, + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), + modSpoilers = GetVehicleMod(vehicle, 0), + modFrontBumper = GetVehicleMod(vehicle, 1), + modRearBumper = GetVehicleMod(vehicle, 2), + modSideSkirt = GetVehicleMod(vehicle, 3), + modExhaust = GetVehicleMod(vehicle, 4), + modFrame = GetVehicleMod(vehicle, 5), + modGrille = GetVehicleMod(vehicle, 6), + modHood = GetVehicleMod(vehicle, 7), + modFender = GetVehicleMod(vehicle, 8), + modRightFender = GetVehicleMod(vehicle, 9), + modRoof = GetVehicleMod(vehicle, 10), - modSpoilers = GetVehicleMod(vehicle, 0), - modFrontBumper = GetVehicleMod(vehicle, 1), - modRearBumper = GetVehicleMod(vehicle, 2), - modSideSkirt = GetVehicleMod(vehicle, 3), - modExhaust = GetVehicleMod(vehicle, 4), - modFrame = GetVehicleMod(vehicle, 5), - modGrille = GetVehicleMod(vehicle, 6), - modHood = GetVehicleMod(vehicle, 7), - modFender = GetVehicleMod(vehicle, 8), - modRightFender = GetVehicleMod(vehicle, 9), - modRoof = GetVehicleMod(vehicle, 10), + modEngine = GetVehicleMod(vehicle, 11), + modBrakes = GetVehicleMod(vehicle, 12), + modTransmission = GetVehicleMod(vehicle, 13), + modHorns = GetVehicleMod(vehicle, 14), + modSuspension = GetVehicleMod(vehicle, 15), + modArmor = GetVehicleMod(vehicle, 16), - modEngine = GetVehicleMod(vehicle, 11), - modBrakes = GetVehicleMod(vehicle, 12), - modTransmission = GetVehicleMod(vehicle, 13), - modHorns = GetVehicleMod(vehicle, 14), - modSuspension = GetVehicleMod(vehicle, 15), - modArmor = GetVehicleMod(vehicle, 16), + modTurbo = IsToggleModOn(vehicle, 18), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), - modTurbo = IsToggleModOn(vehicle, 18), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), - - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), - - modPlateHolder = GetVehicleMod(vehicle, 25), - modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), - modOrnaments = GetVehicleMod(vehicle, 28), - modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), - modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), - modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), - modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), - modArchCover = GetVehicleMod(vehicle, 42), - modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), - modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleMod(vehicle, 48) - } + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleMod(vehicle, 48) + } end ESX.Game.SetVehicleProperties = function(vehicle, props) + SetVehicleModKit(vehicle, 0) - SetVehicleModKit(vehicle, 0) + if props.plate ~= nil then + SetVehicleNumberPlateText(vehicle, props.plate) + end - if props.plate ~= nil then - SetVehicleNumberPlateText(vehicle, props.plate) - end + if props.plateIndex ~= nil then + SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) + end - if props.plateIndex ~= nil then - SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) - end + if props.health ~= nil then + SetEntityHealth(vehicle, props.health) + end - if props.health ~= nil then - SetEntityHealth(vehicle, props.health) - end + if props.dirtLevel ~= nil then + SetVehicleDirtLevel(vehicle, props.dirtLevel) + end - if props.dirtLevel ~= nil then - SetVehicleDirtLevel(vehicle, props.dirtLevel) - end + if props.color1 ~= nil then + local color1, color2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, props.color1, color2) + end - if props.color1 ~= nil then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, props.color1, color2) - end + if props.color2 ~= nil then + local color1, color2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, color1, props.color2) + end - if props.color2 ~= nil then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, color1, props.color2) - end + if props.pearlescentColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) + end - if props.pearlescentColor ~= nil then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) - end + if props.wheelColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) + end - if props.wheelColor ~= nil then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) - end + if props.wheels ~= nil then + SetVehicleWheelType(vehicle, props.wheels) + end - if props.wheels ~= nil then - SetVehicleWheelType(vehicle, props.wheels) - end + if props.windowTint ~= nil then + SetVehicleWindowTint(vehicle, props.windowTint) + end - if props.windowTint ~= nil then - SetVehicleWindowTint(vehicle, props.windowTint) - end + if props.neonEnabled ~= nil then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end - if props.neonEnabled ~= nil then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) - SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) - end + if props.neonColor ~= nil then + SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) + end - if props.neonColor ~= nil then - SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) - end + if props.modSmokeEnabled ~= nil then + ToggleVehicleMod(vehicle, 20, true) + end - if props.modSmokeEnabled ~= nil then - ToggleVehicleMod(vehicle, 20, true) - end + if props.tyreSmokeColor ~= nil then + SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) + end - if props.tyreSmokeColor ~= nil then - SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) - end + if props.modSpoilers ~= nil then + SetVehicleMod(vehicle, 0, props.modSpoilers, false) + end - if props.modSpoilers ~= nil then - SetVehicleMod(vehicle, 0, props.modSpoilers, false) - end + if props.modFrontBumper ~= nil then + SetVehicleMod(vehicle, 1, props.modFrontBumper, false) + end - if props.modFrontBumper ~= nil then - SetVehicleMod(vehicle, 1, props.modFrontBumper, false) - end + if props.modRearBumper ~= nil then + SetVehicleMod(vehicle, 2, props.modRearBumper, false) + end - if props.modRearBumper ~= nil then - SetVehicleMod(vehicle, 2, props.modRearBumper, false) - end + if props.modSideSkirt ~= nil then + SetVehicleMod(vehicle, 3, props.modSideSkirt, false) + end - if props.modSideSkirt ~= nil then - SetVehicleMod(vehicle, 3, props.modSideSkirt, false) - end + if props.modExhaust ~= nil then + SetVehicleMod(vehicle, 4, props.modExhaust, false) + end - if props.modExhaust ~= nil then - SetVehicleMod(vehicle, 4, props.modExhaust, false) - end + if props.modFrame ~= nil then + SetVehicleMod(vehicle, 5, props.modFrame, false) + end - if props.modFrame ~= nil then - SetVehicleMod(vehicle, 5, props.modFrame, false) - end + if props.modGrille ~= nil then + SetVehicleMod(vehicle, 6, props.modGrille, false) + end - if props.modGrille ~= nil then - SetVehicleMod(vehicle, 6, props.modGrille, false) - end + if props.modHood ~= nil then + SetVehicleMod(vehicle, 7, props.modHood, false) + end - if props.modHood ~= nil then - SetVehicleMod(vehicle, 7, props.modHood, false) - end + if props.modFender ~= nil then + SetVehicleMod(vehicle, 8, props.modFender, false) + end - if props.modFender ~= nil then - SetVehicleMod(vehicle, 8, props.modFender, false) - end + if props.modRightFender ~= nil then + SetVehicleMod(vehicle, 9, props.modRightFender, false) + end - if props.modRightFender ~= nil then - SetVehicleMod(vehicle, 9, props.modRightFender, false) - end + if props.modRoof ~= nil then + SetVehicleMod(vehicle, 10, props.modRoof, false) + end - if props.modRoof ~= nil then - SetVehicleMod(vehicle, 10, props.modRoof, false) - end + if props.modEngine ~= nil then + SetVehicleMod(vehicle, 11, props.modEngine, false) + end - if props.modEngine ~= nil then - SetVehicleMod(vehicle, 11, props.modEngine, false) - end + if props.modBrakes ~= nil then + SetVehicleMod(vehicle, 12, props.modBrakes, false) + end - if props.modBrakes ~= nil then - SetVehicleMod(vehicle, 12, props.modBrakes, false) - end + if props.modTransmission ~= nil then + SetVehicleMod(vehicle, 13, props.modTransmission, false) + end - if props.modTransmission ~= nil then - SetVehicleMod(vehicle, 13, props.modTransmission, false) - end + if props.modHorns ~= nil then + SetVehicleMod(vehicle, 14, props.modHorns, false) + end - if props.modHorns ~= nil then - SetVehicleMod(vehicle, 14, props.modHorns, false) - end + if props.modSuspension ~= nil then + SetVehicleMod(vehicle, 15, props.modSuspension, false) + end - if props.modSuspension ~= nil then - SetVehicleMod(vehicle, 15, props.modSuspension, false) - end + if props.modArmor ~= nil then + SetVehicleMod(vehicle, 16, props.modArmor, false) + end - if props.modArmor ~= nil then - SetVehicleMod(vehicle, 16, props.modArmor, false) - end + if props.modTurbo ~= nil then + ToggleVehicleMod(vehicle, 18, props.modTurbo) + end - if props.modTurbo ~= nil then - ToggleVehicleMod(vehicle, 18, props.modTurbo) - end + if props.modXenon ~= nil then + ToggleVehicleMod(vehicle, 22, props.modXenon) + end - if props.modXenon ~= nil then - ToggleVehicleMod(vehicle, 22, props.modXenon) - end + if props.modFrontWheels ~= nil then + SetVehicleMod(vehicle, 23, props.modFrontWheels, false) + end - if props.modFrontWheels ~= nil then - SetVehicleMod(vehicle, 23, props.modFrontWheels, false) - end + if props.modBackWheels ~= nil then + SetVehicleMod(vehicle, 24, props.modBackWheels, false) + end - if props.modBackWheels ~= nil then - SetVehicleMod(vehicle, 24, props.modBackWheels, false) - end + if props.modPlateHolder ~= nil then + SetVehicleMod(vehicle, 25, props.modPlateHolder, false) + end - if props.modPlateHolder ~= nil then - SetVehicleMod(vehicle, 25, props.modPlateHolder , false) - end + if props.modVanityPlate ~= nil then + SetVehicleMod(vehicle, 26, props.modVanityPlate, false) + end - if props.modVanityPlate ~= nil then - SetVehicleMod(vehicle, 26, props.modVanityPlate , false) - end + if props.modTrimA ~= nil then + SetVehicleMod(vehicle, 27, props.modTrimA, false) + end - if props.modTrimA ~= nil then - SetVehicleMod(vehicle, 27, props.modTrimA , false) - end + if props.modOrnaments ~= nil then + SetVehicleMod(vehicle, 28, props.modOrnaments, false) + end - if props.modOrnaments ~= nil then - SetVehicleMod(vehicle, 28, props.modOrnaments , false) - end + if props.modDashboard ~= nil then + SetVehicleMod(vehicle, 29, props.modDashboard, false) + end - if props.modDashboard ~= nil then - SetVehicleMod(vehicle, 29, props.modDashboard , false) - end + if props.modDial ~= nil then + SetVehicleMod(vehicle, 30, props.modDial, false) + end - if props.modDial ~= nil then - SetVehicleMod(vehicle, 30, props.modDial , false) - end + if props.modDoorSpeaker ~= nil then + SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) + end - if props.modDoorSpeaker ~= nil then - SetVehicleMod(vehicle, 31, props.modDoorSpeaker , false) - end + if props.modSeats ~= nil then + SetVehicleMod(vehicle, 32, props.modSeats, false) + end - if props.modSeats ~= nil then - SetVehicleMod(vehicle, 32, props.modSeats , false) - end + if props.modSteeringWheel ~= nil then + SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) + end - if props.modSteeringWheel ~= nil then - SetVehicleMod(vehicle, 33, props.modSteeringWheel , false) - end + if props.modShifterLeavers ~= nil then + SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) + end - if props.modShifterLeavers ~= nil then - SetVehicleMod(vehicle, 34, props.modShifterLeavers , false) - end + if props.modAPlate ~= nil then + SetVehicleMod(vehicle, 35, props.modAPlate, false) + end - if props.modAPlate ~= nil then - SetVehicleMod(vehicle, 35, props.modAPlate , false) - end + if props.modSpeakers ~= nil then + SetVehicleMod(vehicle, 36, props.modSpeakers, false) + end - if props.modSpeakers ~= nil then - SetVehicleMod(vehicle, 36, props.modSpeakers , false) - end + if props.modTrunk ~= nil then + SetVehicleMod(vehicle, 37, props.modTrunk, false) + end - if props.modTrunk ~= nil then - SetVehicleMod(vehicle, 37, props.modTrunk , false) - end + if props.modHydrolic ~= nil then + SetVehicleMod(vehicle, 38, props.modHydrolic, false) + end - if props.modHydrolic ~= nil then - SetVehicleMod(vehicle, 38, props.modHydrolic , false) - end + if props.modEngineBlock ~= nil then + SetVehicleMod(vehicle, 39, props.modEngineBlock, false) + end - if props.modEngineBlock ~= nil then - SetVehicleMod(vehicle, 39, props.modEngineBlock , false) - end + if props.modAirFilter ~= nil then + SetVehicleMod(vehicle, 40, props.modAirFilter, false) + end - if props.modAirFilter ~= nil then - SetVehicleMod(vehicle, 40, props.modAirFilter , false) - end + if props.modStruts ~= nil then + SetVehicleMod(vehicle, 41, props.modStruts, false) + end - if props.modStruts ~= nil then - SetVehicleMod(vehicle, 41, props.modStruts , false) - end + if props.modArchCover ~= nil then + SetVehicleMod(vehicle, 42, props.modArchCover, false) + end - if props.modArchCover ~= nil then - SetVehicleMod(vehicle, 42, props.modArchCover , false) - end + if props.modAerials ~= nil then + SetVehicleMod(vehicle, 43, props.modAerials, false) + end - if props.modAerials ~= nil then - SetVehicleMod(vehicle, 43, props.modAerials , false) - end + if props.modTrimB ~= nil then + SetVehicleMod(vehicle, 44, props.modTrimB, false) + end - if props.modTrimB ~= nil then - SetVehicleMod(vehicle, 44, props.modTrimB , false) - end + if props.modTank ~= nil then + SetVehicleMod(vehicle, 45, props.modTank, false) + end - if props.modTank ~= nil then - SetVehicleMod(vehicle, 45, props.modTank , false) - end - - if props.modWindows ~= nil then - SetVehicleMod(vehicle, 46, props.modWindows , false) - end - - if props.modLivery ~= nil then - SetVehicleMod(vehicle, 48, props.modLivery , false) - end + if props.modWindows ~= nil then + SetVehicleMod(vehicle, 46, props.modWindows, false) + end + if props.modLivery ~= nil then + SetVehicleMod(vehicle, 48, props.modLivery, false) + end end ESX.Game.Utils.DrawText3D = function(coords, text, size) + local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) + local camCoords = GetGameplayCamCoords() + local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) + local size = size - local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) - local camCoords = GetGameplayCamCoords() - local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) - local size = size + if size == nil then + size = 1 + end - if size == nil then - size = 1 - end + local scale = (size / dist) * 2 + local fov = (1 / GetGameplayCamFov()) * 100 + local scale = scale * fov - local scale = (size / dist) * 2 - local fov = (1 / GetGameplayCamFov()) * 100 - local scale = scale * fov - - if onScreen then - - SetTextScale(0.0 * scale, 0.55 * scale) - SetTextFont(0) - SetTextProportional(1) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(2, 0, 0, 0, 150) - SetTextDropShadow() - SetTextOutline() - SetTextEntry('STRING') - SetTextCentre(1) - - AddTextComponentString(text) - - DrawText(x, y) - end + if onScreen then + SetTextScale(0.0 * scale, 0.55 * scale) + SetTextFont(0) + SetTextProportional(1) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(2, 0, 0, 0, 150) + SetTextDropShadow() + SetTextOutline() + SetTextEntry('STRING') + SetTextCentre(1) + AddTextComponentString(text) + DrawText(x, y) + end end ESX.ShowInventory = function() - local playerPed = PlayerPedId() local elements = {} if ESX.PlayerData.money > 0 then table.insert(elements, { - label = _U('cash', ESX.PlayerData.money), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true + label = _U('cash', ESX.PlayerData.money), + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true }) end @@ -1339,8 +1246,8 @@ ESX.ShowInventory = function() end if type == 'item_weapon' then - local pedAmmo = GetAmmoInPedWeapon(PlayerPedId(),GetHashKey(item)) - + local pedAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) + -- does the player have any ammo for the weapon? if pedAmmo > 0 then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', @@ -1410,7 +1317,7 @@ ESX.ShowInventory = function() ESX.ShowNotification(_U('in_vehicle')) return end - + if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then @@ -1463,13 +1370,13 @@ end RegisterNetEvent('esx:serverCallback') AddEventHandler('esx:serverCallback', function(requestId, ...) - ESX.ServerCallbacks[requestId](...) - ESX.ServerCallbacks[requestId] = nil + ESX.ServerCallbacks[requestId](...) + ESX.ServerCallbacks[requestId] = nil end) RegisterNetEvent('esx:showNotification') AddEventHandler('esx:showNotification', function(msg) - ESX.ShowNotification(msg) + ESX.ShowNotification(msg) end) RegisterNetEvent('esx:showAdvancedNotification') @@ -1484,24 +1391,21 @@ end) -- SetTimeout Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(0) + Citizen.Wait(0) + local currTime = GetGameTimer() - local currTime = GetGameTimer() + for i=1, #ESX.TimeoutCallbacks, 1 do - for i=1, #ESX.TimeoutCallbacks, 1 do + if ESX.TimeoutCallbacks[i] ~= nil then + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + end - if ESX.TimeoutCallbacks[i] ~= nil then + end - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil - end - - end - - end - - end + end end) diff --git a/client/main.lua b/client/main.lua index 7894280c..014e93d5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -19,40 +19,36 @@ local isDead = false RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) + ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + for i=1, #xPlayer.accounts, 1 do + local accountTpl = '
 {{money}}
' - for i=1, #xPlayer.accounts, 1 do + ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { + money = 0 + }) - local accountTpl = '
 {{money}}
' + ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { + money = xPlayer.accounts[i].money + }) + end - ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { - money = 0 - }) + local jobTpl = '
{{job_label}} - {{grade_label}}
' - ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { - money = xPlayer.accounts[i].money - }) + if xPlayer.job.grade_label == '' then + jobTpl = '
{{job_label}}
' + end - end - - local jobTpl = '
{{job_label}} - {{grade_label}}
' - - if xPlayer.job.grade_label == '' then - jobTpl = '
{{job_label}}
' - end - - ESX.UI.HUD.RegisterElement('job', #xPlayer.accounts, 0, jobTpl, { - job_label = '', - grade_label = '' - }) - - ESX.UI.HUD.UpdateElement('job', { - job_label = xPlayer.job.label, - grade_label = xPlayer.job.grade_label - }) + ESX.UI.HUD.RegisterElement('job', #xPlayer.accounts, 0, jobTpl, { + job_label = '', + grade_label = '' + }) + ESX.UI.HUD.UpdateElement('job', { + job_label = xPlayer.job.label, + grade_label = xPlayer.job.grade_label + }) end) AddEventHandler('playerSpawned', function() @@ -122,7 +118,6 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) TriggerEvent('esx:onPlayerDeath', data) TriggerServerEvent('esx:onPlayerDeath', data) - end) AddEventHandler('esx:onPlayerDeath', function() @@ -134,82 +129,77 @@ AddEventHandler('skinchanger:loadDefaultModel', function() end) AddEventHandler('skinchanger:modelLoaded', function() - while not ESX.PlayerLoaded do - Citizen.Wait(1) - end + while not ESX.PlayerLoaded do + Citizen.Wait(1) + end - TriggerEvent('esx:restoreLoadout') + TriggerEvent('esx:restoreLoadout') end) AddEventHandler('esx:restoreLoadout', function() - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() - RemoveAllPedWeapons(playerPed, true) + RemoveAllPedWeapons(playerPed, true) - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) - end + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true + LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + end + end - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account - end - end - - ESX.UI.HUD.UpdateElement('account_' .. account.name, { - money = account.money - }) + ESX.UI.HUD.UpdateElement('account_' .. account.name, { + money = account.money + }) end) RegisterNetEvent('es:activateMoney') AddEventHandler('es:activateMoney', function(money) - ESX.PlayerData.money = money + ESX.PlayerData.money = money end) RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item - end - end - - ESX.UI.ShowInventoryItemNotification(true, item, count) - - if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end + ESX.UI.ShowInventoryItemNotification(true, item, count) + if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end end) RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item - end - end - - ESX.UI.ShowInventoryItemNotification(false, item, count) - - if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end + ESX.UI.ShowInventoryItemNotification(false, item, count) + if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) RegisterNetEvent('esx:addWeapon') @@ -240,185 +230,157 @@ end) -- Commands RegisterNetEvent('esx:teleport') AddEventHandler('esx:teleport', function(pos) --- heading?! - pos.x = pos.x + 0.0 - pos.y = pos.y + 0.0 - pos.z = pos.z + 0.0 + pos.x = pos.x + 0.0 + pos.y = pos.y + 0.0 + pos.z = pos.z + 0.0 - RequestCollisionAtCoord(pos.x, pos.y, pos.z) + RequestCollisionAtCoord(pos.x, pos.y, pos.z) - while not HasCollisionLoadedAroundEntity(PlayerPedId()) do - RequestCollisionAtCoord(pos.x, pos.y, pos.z) - Citizen.Wait(1) - end - - SetEntityCoords(PlayerPedId(), pos.x, pos.y, pos.z) + while not HasCollisionLoadedAroundEntity(PlayerPedId()) do + RequestCollisionAtCoord(pos.x, pos.y, pos.z) + Citizen.Wait(1) + end + SetEntityCoords(PlayerPedId(), pos.x, pos.y, pos.z) end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - ESX.UI.HUD.UpdateElement('job', { - job_label = job.label, - grade_label = job.grade_label - }) + ESX.UI.HUD.UpdateElement('job', { + job_label = job.label, + grade_label = job.grade_label + }) end) RegisterNetEvent('esx:loadIPL') AddEventHandler('esx:loadIPL', function(name) - - Citizen.CreateThread(function() - LoadMpDlcMaps() - EnableMpDlcMaps(true) - RequestIpl(name) - end) - + Citizen.CreateThread(function() + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl(name) + end) end) RegisterNetEvent('esx:unloadIPL') AddEventHandler('esx:unloadIPL', function(name) - - Citizen.CreateThread(function() - RemoveIpl(name) - end) - + Citizen.CreateThread(function() + RemoveIpl(name) + end) end) RegisterNetEvent('esx:playAnim') AddEventHandler('esx:playAnim', function(dict, anim) + Citizen.CreateThread(function() + local playerPed = PlayerPedId() + RequestAnimDict(dict) - Citizen.CreateThread(function() - - local pid = PlayerPedId() - - RequestAnimDict(dict) - - while not HasAnimDictLoaded(dict) do - Citizen.Wait(1) - end - - TaskPlayAnim(pid, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) - - end) + while not HasAnimDictLoaded(dict) do + Citizen.Wait(1) + end + TaskPlayAnim(playerPed, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) + end) end) RegisterNetEvent('esx:playEmote') AddEventHandler('esx:playEmote', function(emote) + Citizen.CreateThread(function() - Citizen.CreateThread(function() + local playerPed = PlayerPedId() - local playerPed = PlayerPedId() - - TaskStartScenarioInPlace(playerPed, emote, 0, false); - Citizen.Wait(20000) - ClearPedTasks(playerPed) - - end) + TaskStartScenarioInPlace(playerPed, emote, 0, false); + Citizen.Wait(20000) + ClearPedTasks(playerPed) + end) end) RegisterNetEvent('esx:spawnVehicle') AddEventHandler('esx:spawnVehicle', function(model) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - + ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) end) RegisterNetEvent('esx:spawnObject') AddEventHandler('esx:spawnObject', function(model) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) - + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) end) RegisterNetEvent('esx:pickup') AddEventHandler('esx:pickup', function(id, label, player) + local ped = GetPlayerPed(GetPlayerFromServerId(player)) + local coords = GetEntityCoords(ped) + local forward = GetEntityForwardVector(ped) + local x, y, z = table.unpack(coords + forward * -2.0) - local ped = GetPlayerPed(GetPlayerFromServerId(player)) - local coords = GetEntityCoords(ped) - local forward = GetEntityForwardVector(ped) - local x, y, z = table.unpack(coords + forward * -2.0) - - ESX.Game.SpawnLocalObject('prop_money_bag_01', { - x = x, - y = y, - z = z - 2.0, - }, function(obj) - - SetEntityAsMissionEntity(obj, true, false) - - PlaceObjectOnGroundProperly(obj) - - Pickups[id] = { - id = id, - obj = obj, - label = label, - inRange = false, - coords = { - x = x, - y = y, - z = z - }, - } - - end) + ESX.Game.SpawnLocalObject('prop_money_bag_01', { + x = x, + y = y, + z = z - 2.0, + }, function(obj) + SetEntityAsMissionEntity(obj, true, false) + PlaceObjectOnGroundProperly(obj) + Pickups[id] = { + id = id, + obj = obj, + label = label, + inRange = false, + coords = { + x = x, + y = y, + z = z + } + } + end) end) RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) - ESX.Game.DeleteObject(Pickups[id].obj) - Pickups[id] = nil + ESX.Game.DeleteObject(Pickups[id].obj) + Pickups[id] = nil end) RegisterNetEvent('esx:pickupWeapon') AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName,ammo) - - local ped = PlayerPedId() - local playerPedPos = GetEntityCoords(ped, true) - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) - + local ped = PlayerPedId() + local playerPedPos = GetEntityCoords(ped, true) + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) end) RegisterNetEvent('esx:spawnPed') AddEventHandler('esx:spawnPed', function(model) + model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() - - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(1) - end - - CreatePed(5, model, x, y, z, 0.0, true, false) - - end) + while not HasModelLoaded(model) do + Citizen.Wait(1) + end + CreatePed(5, model, x, y, z, 0.0, true, false) + end) end) RegisterNetEvent('esx:deleteVehicle') @@ -438,127 +400,121 @@ end) -- Pause menu disable HUD display Citizen.CreateThread(function() - while true do - Citizen.Wait(1) - if IsPauseMenuActive() and not IsPaused then - IsPaused = true - TriggerEvent('es:setMoneyDisplay', 0.0) - ESX.UI.HUD.SetDisplay(0.0) - elseif not IsPauseMenuActive() and IsPaused then - IsPaused = false - TriggerEvent('es:setMoneyDisplay', 1.0) - ESX.UI.HUD.SetDisplay(1.0) - end - end + while true do + Citizen.Wait(1) + + if IsPauseMenuActive() and not IsPaused then + IsPaused = true + TriggerEvent('es:setMoneyDisplay', 0.0) + ESX.UI.HUD.SetDisplay(0.0) + elseif not IsPauseMenuActive() and IsPaused then + IsPaused = false + TriggerEvent('es:setMoneyDisplay', 1.0) + ESX.UI.HUD.SetDisplay(1.0) + end + end end) -- Save loadout Citizen.CreateThread(function() + while true do - while true do + Citizen.Wait(1) - Citizen.Wait(1) + local playerPed = PlayerPedId() + local loadout = {} + local loadoutChanged = false - local playerPed = PlayerPedId() - local loadout = {} - local loadoutChanged = false + if IsPedDeadOrDying(playerPed) then + LoadoutLoaded = false + end - if IsPedDeadOrDying(playerPed) then - LoadoutLoaded = false - end + for i=1, #Config.Weapons, 1 do - for i=1, #Config.Weapons, 1 do + local weaponHash = GetHashKey(Config.Weapons[i].name) - local weaponHash = GetHashKey(Config.Weapons[i].name) + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then + loadoutChanged = true + end - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + LastLoadout[Config.Weapons[i].name] = ammo - if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then - loadoutChanged = true - end + table.insert(loadout, { + name = Config.Weapons[i].name, + ammo = ammo, + label = Config.Weapons[i].label + }) + else + if LastLoadout[Config.Weapons[i].name] ~= nil then + loadoutChanged = true + end - LastLoadout[Config.Weapons[i].name] = ammo + LastLoadout[Config.Weapons[i].name] = nil + end - table.insert(loadout, { - name = Config.Weapons[i].name, - ammo = ammo, - label = Config.Weapons[i].label - }) + end - else + if loadoutChanged and LoadoutLoaded then + ESX.PlayerData.loadout = loadout + TriggerServerEvent('esx:updateLoadout', loadout) + end - if LastLoadout[Config.Weapons[i].name] ~= nil then - loadoutChanged = true - end - - LastLoadout[Config.Weapons[i].name] = nil - - end - - end - - if loadoutChanged and LoadoutLoaded then - ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) - end - - end + end end) -- Menu interactions Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(10) + Citizen.Wait(10) - if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end + if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end - end + end end) -- Dot above head if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() - while true do + Citizen.CreateThread(function() + while true do - Citizen.Wait(1) + Citizen.Wait(1) - local players = ESX.Game.GetPlayers() + local players = ESX.Game.GetPlayers() + for i = 1, #players, 1 do + if players[i] ~= PlayerId() then + local ped = GetPlayerPed(players[i]) + local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) + end + end - for i = 1, #players, 1 do - if players[i] ~= PlayerId() then - local ped = GetPlayerPed(players[i]) - local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) - end - end - - end - end) + end + end) end -- Disable wanted level if Config.DisableWantedLevel then - Citizen.CreateThread(function() - while true do + Citizen.CreateThread(function() + while true do - Citizen.Wait(10) + Citizen.Wait(10) - local playerId = PlayerId() + local playerId = PlayerId() + if GetPlayerWantedLevel(playerId) ~= 0 then + SetPlayerWantedLevel(playerId, 0, false) + SetPlayerWantedLevelNow(playerId, false) + end - if GetPlayerWantedLevel(playerId) ~= 0 then - SetPlayerWantedLevel(playerId, 0, false) - SetPlayerWantedLevelNow(playerId, false) - end - - end - end) + end + end) end @@ -602,37 +558,29 @@ end) -- Last position Citizen.CreateThread(function() + while true do - while true do + Citizen.Wait(1000) + if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - Citizen.Wait(1000) - - if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then - - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if not IsEntityDead(playerPed) then - ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} - end - - end - - end + if not IsEntityDead(playerPed) then + ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} + end + end + end end) Citizen.CreateThread(function() + while true do - while true do - - Citizen.Wait(1000) - - local playerPed = PlayerPedId() - - if IsEntityDead(playerPed) and PlayerSpawned then - PlayerSpawned = false - end - end + Citizen.Wait(1000) + local playerPed = PlayerPedId() + if IsEntityDead(playerPed) and PlayerSpawned then + PlayerSpawned = false + end + end end) diff --git a/client/wrapper.lua b/client/wrapper.lua index 9ac13dcf..441312d8 100644 --- a/client/wrapper.lua +++ b/client/wrapper.lua @@ -1,16 +1,14 @@ local Chunks = {} RegisterNUICallback('__chunk', function(data, cb) + Chunks[data.id] = Chunks[data.id] or '' + Chunks[data.id] = Chunks[data.id] .. data.chunk - Chunks[data.id] = Chunks[data.id] or '' - Chunks[data.id] = Chunks[data.id] .. data.chunk - - if data['end'] then - local msg = json.decode(Chunks[data.id]) - TriggerEvent(GetCurrentResourceName() .. ':message:' .. data.__type, msg) - Chunks[data.id] = nil - end - - cb('') + if data['end'] then + local msg = json.decode(Chunks[data.id]) + TriggerEvent(GetCurrentResourceName() .. ':message:' .. data.__type, msg) + Chunks[data.id] = nil + end + cb('') end) diff --git a/html/css/app.css b/html/css/app.css index cfe7e0ab..e4327c9c 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,95 +1,87 @@ @font-face { - font-family: 'Pricedown'; - src: url('../fonts/pdown.ttf') /* TTF file for CSS3 browsers */ + font-family: 'Pricedown'; + src: url('../fonts/pdown.ttf')/* TTF file for CSS3 browsers */ } @font-face { - font-family: 'bankgothic'; - src: url('../fonts/bankgothic.ttf') /* TTF file for CSS3 browsers */ + font-family: 'bankgothic'; + src: url('../fonts/bankgothic.ttf')/* TTF file for CSS3 browsers */ } html { - overflow: hidden; + overflow: hidden; } #hud { - position : absolute; - font-family: 'Pricedown'; - font-size : 35px; - color : white; - padding : 4px; - text-shadow: - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000; - - text-align: right; - top : 80; - right : 40; + position: absolute; + font-family: 'Pricedown'; + font-size: 35px; + color: white; + padding: 4px; + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; + text-align: right; + top: 80; + right: 40; } #inventory_notifications { - font-family: bankgothic; - position : absolute; - right : 40; - bottom : 40; - font-size : 2em; - font-weight: bold; - color : #FFF; - text-shadow: - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000; + font-family: bankgothic; + position: absolute; + right: 40; + bottom: 40; + font-size: 2em; + font-weight: bold; + color: #FFF; + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; } .menu { - font-family: 'Open Sans', sans-serif; - min-width : 400px; - min-height : 250px; - color : #fff; - position : absolute; - left : 40; - top : 0; + font-family: 'Open Sans', sans-serif; + min-width: 400px; + min-height: 250px; + color: #fff; + position: absolute; + left: 40; + top: 0; } .menu .head { - font-family: 'Open Sans', sans-serif; - font-size: 28px; - padding: 10px; - background: #1A1A1A; - border-bottom: 3px solid #BC1635; - border-radius: 10px 10px 0 0; - -webkit-border-radius: 10px 10px 0 0; - -moz-border-radius: 10px 10px 0 0; - -o-border-radius: 10px 10px 0 0; - box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); - -webkit-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); - -moz-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); - -o-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); - box-shadow: 1px 1px 10px 4px rgba(0, 0, 0, 0.4); + font-family: 'Open Sans', sans-serif; + font-size: 28px; + padding: 10px; + background: #1A1A1A; + border-bottom: 3px solid #BC1635; + border-radius: 10px 10px 0 0; + -webkit-border-radius: 10px 10px 0 0; + -moz-border-radius: 10px 10px 0 0; + -o-border-radius: 10px 10px 0 0; + box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + -webkit-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + -moz-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + -o-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + box-shadow: 1px 1px 10px 4px rgba(0, 0, 0, 0.4); } + .menu .head span { - font-family: 'Pricedown'; - font-size: 28px; - padding-left: 15px; - padding-top: 6px; + font-family: 'Pricedown'; + font-size: 28px; + padding-left: 15px; + padding-top: 6px; } .menu .menu-items .menu-item { - font-family : 'Open Sans', sans-serif; - font-size : 14px; - height : 40px; - display : block; - background-color: #f1f1f1; - box-shadow : inset 1px 0px 0px 1px #b8b8b8; - height : 32px; - line-height : 32px; - color : #3A3A3A; - text-align : center; + font-family: 'Open Sans', sans-serif; + font-size: 14px; + height: 40px; + display: block; + background-color: #f1f1f1; + box-shadow: inset 1px 0px 0px 1px #b8b8b8; + height: 32px; + line-height: 32px; + color: #3A3A3A; + text-align: center; } .menu .menu-items .menu-item.selected { background-color: #ccc; -} +} \ No newline at end of file diff --git a/html/js/app.js b/html/js/app.js index 6da6d52b..901e081e 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -30,7 +30,6 @@ ESX.HUDElements[i].data = data; ESX.refreshHUD(); - } ESX.deleteHUDElement = function(name){ diff --git a/html/js/wrapper.js b/html/js/wrapper.js index 054e8d06..0d208709 100644 --- a/html/js/wrapper.js +++ b/html/js/wrapper.js @@ -1,42 +1,42 @@ (() => { - let ESXWrapper = {}; - ESXWrapper.MessageSize = 1024; - ESXWrapper.messageId = 0; + let ESXWrapper = {}; + ESXWrapper.MessageSize = 1024; + ESXWrapper.messageId = 0; - window.SendMessage = function(namespace, type, msg) { + window.SendMessage = function (namespace, type, msg) { - ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0; - const str = JSON.stringify(msg); + ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0; + const str = JSON.stringify(msg); - for(let i=0; i= 0 then + self.player.setMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 cash balance)') + end + end + + self.getMoney = function() + return self.player.get('money') + end + + self.setBankBalance = function(m) + if m >= 0 then + self.player.setBankBalance(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 bank balance)') + end + end + + self.getBank = function() + return self.player.get('bank') + end + + self.getCoords = function() + return self.player.get('coords') + end + + self.setCoords = function(x, y, z) + self.player.coords = {x = x, y = y, z = z} + end + + self.kick = function(r) + self.player.kick(r) + end + + self.addMoney = function(m) + if m >= 0 then + self.player.addMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 cash balance)') + end + end + + self.removeMoney = function(m) + if m >= 0 then + self.player.removeMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 cash balance)') + end + end + + self.addBank = function(m) + if m >= 0 then + self.player.addBank(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 bank balance)') + end + end + + self.removeBank = function(m) + if m >= 0 then + self.player.removeBank(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 bank balance)') + end + end + + self.displayMoney = function(m) + self.player.displayMoney(m) + end + + self.displayBank = function(m) + self.player.displayBank(m) + end + + self.setSessionVar = function(key, value) + self.player.setSessionVar(key, value) + end + + self.getSessionVar = function(k) + return self.player.getSessionVar(k) + end + + self.getPermissions = function() + return self.player.getPermissions() + end + + self.setPermissions = function(p) + self.player.setPermissions(p) + end + + self.getIdentifier = function() + return self.player.getIdentifier() + end + + self.getGroup = function() + return self.player.getGroup() + end + + self.set = function(k, v) + self.player.set(k, v) + end + + self.get = function(k) + return self.player.get(k) + end + + self.getPlayer = function() + return self.player + end + + self.getAccounts = function() + local accounts = {} + + for i=1, #Config.Accounts, 1 do + if Config.Accounts[i] == 'bank' then + + table.insert(accounts, { + name = 'bank', + money = self.get('bank'), + label = Config.AccountLabels['bank'] + }) + + else + + for j=1, #self.accounts, 1 do + if self.accounts[j].name == Config.Accounts[i] then + table.insert(accounts, self.accounts[j]) + end + end + + end + end + + return accounts + end + + self.getAccount = function(a) + if a == 'bank' then + return { + name = 'bank', + money = self.get('bank'), + label = Config.AccountLabels['bank'] + } + end + + for i=1, #self.accounts, 1 do + if self.accounts[i].name == a then + return self.accounts[i] + end + end + end + + self.getInventory = function() + return self.inventory + end + + self.getJob = function() + return self.job + end + + self.getLoadout = function() + return self.loadout + end - local self = {} - - self.player = player - self.accounts = accounts - self.inventory = inventory - self.job = job - self.loadout = loadout - self.name = name - self.lastPosition = lastPosition - - self.source = self.player.get('source') - self.identifier = self.player.get('identifier') - - self.setMoney = function(m) - if m >= 0 then - self.player.setMoney(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 cash balance)') - end - end - - self.getMoney = function() - return self.player.get('money') - end - - self.setBankBalance = function(m) - if m >= 0 then - self.player.setBankBalance(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 bank balance)') - end - end - - self.getBank = function() - return self.player.get('bank') - end - - self.getCoords = function() - return self.player.get('coords') - end - - self.setCoords = function(x, y, z) - self.player.coords = {x = x, y = y, z = z} - end - - self.kick = function(r) - self.player.kick(r) - end - - self.addMoney = function(m) - if m >= 0 then - self.player.addMoney(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 cash balance)') - end - end - - self.removeMoney = function(m) - if m >= 0 then - self.player.removeMoney(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 cash balance)') - end - end - - self.addBank = function(m) - if m >= 0 then - self.player.addBank(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 bank balance)') - end - end - - self.removeBank = function(m) - if m >= 0 then - self.player.removeBank(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 bank balance)') - end - end - - self.displayMoney = function(m) - self.player.displayMoney(m) - end - - self.displayBank = function(m) - self.player.displayBank(m) - end - - self.setSessionVar = function(key, value) - self.player.setSessionVar(key, value) - end - - self.getSessionVar = function(k) - return self.player.getSessionVar(k) - end - - self.getPermissions = function() - return self.player.getPermissions() - end - - self.setPermissions = function(p) - self.player.setPermissions(p) - end - - self.getIdentifier = function() - return self.player.getIdentifier() - end - - self.getGroup = function() - return self.player.getGroup() - end - - self.set = function(k, v) - self.player.set(k, v) - end - - self.get = function(k) - return self.player.get(k) - end + self.getName = function() + return self.name + end - self.getPlayer = function() - return self.player - end + self.getLastPosition = function() + return self.lastPosition + end - self.getAccounts = function() + self.getMissingAccounts = function(cb) + MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + ['@identifier'] = self.getIdentifier() + }, function(result) - local accounts = {} - - for i=1, #Config.Accounts, 1 do - - if Config.Accounts[i] == 'bank' then - - table.insert(accounts, { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels['bank'] - }) - - else - - for j=1, #self.accounts, 1 do - if self.accounts[j].name == Config.Accounts[i] then - table.insert(accounts, self.accounts[j]) - end - end - - end - end - - return accounts - - end - - self.getAccount = function(a) - - if a == 'bank' then - - return { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels['bank'] - } - - end - - for i=1, #self.accounts, 1 do - if self.accounts[i].name == a then - return self.accounts[i] - end - end - end - - self.getInventory = function() - return self.inventory - end - - self.getJob = function() - return self.job - end - - self.getLoadout = function() - return self.loadout - end - - self.getName = function() - return self.name - end - - self.getLastPosition = function() - return self.lastPosition - end - - self.getMissingAccounts = function(cb) - - MySQL.Async.fetchAll( - 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', - { - ['@identifier'] = self.getIdentifier() - }, - function(result) - - local missingAccounts = {}; - - for i=1, #Config.Accounts, 1 do - - if Config.Accounts[i] ~= 'bank' then - - local found = false - - for j=1, #result, 1 do - if Config.Accounts[i] == result[j].name then - found = true - end - end - - if not found then - table.insert(missingAccounts, Config.Accounts[i]) - end - - end - - end - - cb(missingAccounts) - - end - ) - - end - - self.createAccounts = function(missingAccounts, cb) - - for i=1, #missingAccounts, 1 do - MySQL.Async.execute( - 'INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', - { - ['@identifier'] = self.getIdentifier(), - ['@name'] = missingAccounts[i] - }, - function(rowsChanged) - if cb ~= nil then - cb() - end - end - ) - end - - end - - self.setAccountMoney = function(a, m) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 account balance)') - return - end - - local account = self.getAccount(a) - local prevMoney = account.money - local newMoney = m - - account.money = newMoney - - if a == 'bank' then - self.set('bank', newMoney) - end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) - end - - self.addAccountMoney = function(a, m) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 account balance)') - return - end - - local account = self.getAccount(a) - local newMoney = account.money + m - - account.money = newMoney - - if a == 'bank' then - self.set('bank', newMoney) - end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) - end - - self.removeAccountMoney = function(a, m) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 account balance)') - return - end - - local account = self.getAccount(a) - local newMoney = account.money - m - - account.money = newMoney - - if a == 'bank' then - self.set('bank', newMoney) - end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) - end - - self.getInventoryItem = function(name) - - for i=1, #self.inventory, 1 do - if self.inventory[i].name == name then - return self.inventory[i] - end - end - - end - - self.addInventoryItem = function(name, count) - - local item = self.getInventoryItem(name) - local newCount = item.count + count - item.count = newCount - - TriggerEvent("esx:onAddInventoryItem", self.source, item, count) - TriggerClientEvent("esx:addInventoryItem", self.source, item, count) - - end - - self.removeInventoryItem = function(name, count) - - local item = self.getInventoryItem(name) - local newCount = item.count - count - item.count = newCount - - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, count) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, count) - - end - - self.setInventoryItem = function(name, count) - - local item = self.getInventoryItem(name) - local oldCount = item.count - item.count = count - - if oldCount > item.count then - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count ) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count ) - else - TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) - TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) - end - - end - - self.setJob = function(name, grade) - - local lastJob = json.decode(json.encode(self.job)) - - MySQL.Async.fetchAll( - 'SELECT * FROM `jobs` WHERE `name` = @name', - { - ['@name'] = name - }, - function(result) - - self.job['id'] = result[1].id - self.job['name'] = result[1].name - self.job['label'] = result[1].label - - MySQL.Async.fetchAll( - 'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', - { - ['@job_name'] = name, - ['@grade'] = grade - }, - function(result) - - self.job['grade'] = grade - self.job['grade_name'] = result[1].name - self.job['grade_label'] = result[1].label - self.job['grade_salary'] = result[1].salary - - self.job['skin_male'] = nil - self.job['skin_female'] = nil - - if result[1].skin_male ~= nil then - self.job['skin_male'] = json.decode(result[1].skin_male) - end - - if result[1].skin_female ~= nil then - self.job['skin_female'] = json.decode(result[1].skin_female) - end - - TriggerEvent("esx:setJob", self.source, self.job, lastJob) - TriggerClientEvent("esx:setJob", self.source, self.job) - - end - ) - - end - ) - - end - - self.addWeapon = function(weaponName, ammo) - - local weaponLabel = weaponName - - for i=1, #Config.Weapons, 1 do - if Config.Weapons[i].name == weaponName then - weaponLabel = Config.Weapons[i].label - break - end - end - - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - foundWeapon = true - end - end - - if not foundWeapon then - table.insert(self.loadout, { - name = weaponName, - ammo = ammo, - label = weaponLabel - }) - end - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) - end - - self.removeWeapon = function(weaponName, ammo) - - local weaponLabel = weaponName - - for i=1, #Config.Weapons, 1 do - if Config.Weapons[i].name == weaponName then - weaponLabel = Config.Weapons[i].label - break - end - end - - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - table.remove(self.loadout, i) - break - end - end - - TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) - end - - return self + local missingAccounts = {} + + for i=1, #Config.Accounts, 1 do + if Config.Accounts[i] ~= 'bank' then + + local found = false + + for j=1, #result, 1 do + if Config.Accounts[i] == result[j].name then + found = true + end + end + + if not found then + table.insert(missingAccounts, Config.Accounts[i]) + end + + end + + end + + cb(missingAccounts) + + end) + end + + self.createAccounts = function(missingAccounts, cb) + for i=1, #missingAccounts, 1 do + MySQL.Async.execute('INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', + { + ['@identifier'] = self.getIdentifier(), + ['@name'] = missingAccounts[i] + }, function(rowsChanged) + if cb ~= nil then + cb() + end + end) + end + end + + self.setAccountMoney = function(a, m) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 account balance)') + return + end + + local account = self.getAccount(a) + local prevMoney = account.money + local newMoney = m + + account.money = newMoney + + if a == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) + end + + self.addAccountMoney = function(a, m) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 account balance)') + return + end + + local account = self.getAccount(a) + local newMoney = account.money + m + + account.money = newMoney + + if a == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) + end + + self.removeAccountMoney = function(a, m) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 account balance)') + return + end + + local account = self.getAccount(a) + local newMoney = account.money - m + + account.money = newMoney + + if a == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) + end + + self.getInventoryItem = function(name) + for i=1, #self.inventory, 1 do + if self.inventory[i].name == name then + return self.inventory[i] + end + end + end + + self.addInventoryItem = function(name, count) + local item = self.getInventoryItem(name) + local newCount = item.count + count + item.count = newCount + + TriggerEvent("esx:onAddInventoryItem", self.source, item, count) + TriggerClientEvent("esx:addInventoryItem", self.source, item, count) + end + + self.removeInventoryItem = function(name, count) + local item = self.getInventoryItem(name) + local newCount = item.count - count + item.count = newCount + + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, count) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, count) + end + + self.setInventoryItem = function(name, count) + local item = self.getInventoryItem(name) + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count) + else + TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) + TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) + end + end + + self.setJob = function(name, grade) + local lastJob = json.decode(json.encode(self.job)) + + MySQL.Async.fetchAll('SELECT * FROM `jobs` WHERE `name` = @name', { + ['@name'] = name + }, function(result) + + self.job['id'] = result[1].id + self.job['name'] = result[1].name + self.job['label'] = result[1].label + + MySQL.Async.fetchAll('SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', { + ['@job_name'] = name, + ['@grade'] = grade + }, function(result) + self.job['grade'] = grade + self.job['grade_name'] = result[1].name + self.job['grade_label'] = result[1].label + self.job['grade_salary'] = result[1].salary + + self.job['skin_male'] = nil + self.job['skin_female'] = nil + + if result[1].skin_male ~= nil then + self.job['skin_male'] = json.decode(result[1].skin_male) + end + + if result[1].skin_female ~= nil then + self.job['skin_female'] = json.decode(result[1].skin_female) + end + + TriggerEvent("esx:setJob", self.source, self.job, lastJob) + TriggerClientEvent("esx:setJob", self.source, self.job) + end) + end) + end + + self.addWeapon = function(weaponName, ammo) + local weaponLabel = weaponName + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == weaponName then + weaponLabel = Config.Weapons[i].label + break + end + end + + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(self.loadout, { + name = weaponName, + ammo = ammo, + label = weaponLabel + }) + end + + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + end + + self.removeWeapon = function(weaponName, ammo) + local weaponLabel = weaponName + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == weaponName then + weaponLabel = Config.Weapons[i].label + break + end + end + + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + table.remove(self.loadout, i) + break + end + end + + TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) + end + + return self end diff --git a/server/commands.lua b/server/commands.lua index bfd0ca9e..3de2797e 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -13,7 +13,7 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid coordinates!") end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) @@ -28,37 +28,37 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid usage.") end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:loadIPL', -1, args[1]) + TriggerClientEvent('esx:loadIPL', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('load_ipl')}) TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:unloadIPL', -1, args[1]) + TriggerClientEvent('esx:unloadIPL', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('unload_ipl')}) TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) - TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) + TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('play_anim')}) TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) - TriggerClientEvent('esx:playEmote', -1, args[1]) + TriggerClientEvent('esx:playEmote', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('play_emote')}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnVehicle', source, args[1]) + TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) @@ -68,26 +68,25 @@ end, function(source, args, user) end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnPed', source, args[1]) + TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnObject', source, args[1]) + TriggerClientEvent('esx:spawnObject', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_object'), params = {{name = "name"}}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local _source = source - local target = tonumber(args[1]) local money_type = args[2] local money_amount = tonumber(args[3]) @@ -113,63 +112,57 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) if xPlayer.source ~= _source then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[1]) + local account = args[2] + local amount = tonumber(args[3]) - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[1]) - local account = args[2] - local amount = tonumber(args[3]) - - if amount ~= nil then - if xPlayer.getAccount(account) ~= nil then - xPlayer.addAccountMoney(account, amount) - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) - end - else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) - end - + if amount ~= nil then + if xPlayer.getAccount(account) ~= nil then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) + end + else + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[1]) + local item = args[2] + local count = (args[3] == nil and 1 or tonumber(args[3])) - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[1]) - local item = args[2] - local count = (args[3] == nil and 1 or tonumber(args[3])) - - if count ~= nil then - if xPlayer.getInventoryItem(item) ~= nil then - xPlayer.addInventoryItem(item, count) - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) - end - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) - end - + if count ~= nil then + if xPlayer.getInventoryItem(item) ~= nil then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) + end + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) + local xPlayer = ESX.GetPlayerFromId(args[1]) + local weaponName = string.upper(args[2]) - local xPlayer = ESX.GetPlayerFromId(args[1]) - local weaponName = string.upper(args[2]) - - xPlayer.addWeapon(weaponName, tonumber(args[3])) - + xPlayer.addWeapon(weaponName, tonumber(args[3])) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}, {name = "ammo", help = _U('amountammo')}}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) @@ -206,4 +199,4 @@ TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, u TriggerClientEvent('chat:clear', -1) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear_all')}) \ No newline at end of file +end, {help = _U('chat_clear_all')}) diff --git a/server/common.lua b/server/common.lua index 2a2eef94..4ed0d53a 100644 --- a/server/common.lua +++ b/server/common.lua @@ -10,70 +10,57 @@ ESX.Pickups = {} ESX.PickupId = 0 AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) + cb(ESX) end) function getSharedObject() - return ESX + return ESX end AddEventHandler('onMySQLReady', function() - - MySQL.Async.fetchAll( - 'SELECT * FROM items', - {}, - function(result) - - for i=1, #result, 1 do - ESX.Items[result[i].name] = { - label = result[i].label, - limit = result[i].limit, - rare = (result[i].rare == 1 and true or false), - canRemove = (result[i].can_remove == 1 and true or false), - } - end - - end - ) - + MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) + for i=1, #result, 1 do + ESX.Items[result[i].name] = { + label = result[i].label, + limit = result[i].limit, + rare = (result[i].rare == 1 and true or false), + canRemove = (result[i].can_remove == 1 and true or false), + } + end + end) end) AddEventHandler('esx:playerLoaded', function(source) + local xPlayer = ESX.GetPlayerFromId(source) + local accounts = {} + local items = {} + local xPlayerAccounts = xPlayer.getAccounts() + local xPlayerItems = xPlayer.getInventory() - local xPlayer = ESX.GetPlayerFromId(source) - local accounts = {} - local items = {} - local xPlayerAccounts = xPlayer.getAccounts() - local xPlayerItems = xPlayer.getInventory() + for i=1, #xPlayerAccounts, 1 do + accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money + end - for i=1, #xPlayerAccounts, 1 do - accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money - end - - for i=1, #xPlayerItems, 1 do - items[xPlayerItems[i].name] = xPlayerItems[i].count - end - - ESX.LastPlayerData[source] = { - accounts = accounts, - items = items - } + for i=1, #xPlayerItems, 1 do + items[xPlayerItems[i].name] = xPlayerItems[i].count + end + ESX.LastPlayerData[source] = { + accounts = accounts, + items = items + } end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") + RconPrint(msg .. "\n") end) RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) + local _source = source - local _source = source - - ESX.TriggerServerCallback(name, requestID, _source, function(...) - TriggerClientEvent('esx:serverCallback', _source, requestId, ...) - end, ...) - + ESX.TriggerServerCallback(name, requestID, _source, function(...) + TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + end, ...) end) - diff --git a/server/functions.lua b/server/functions.lua index da0673c2..60d3cd17 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -1,226 +1,171 @@ -local Charset = {} - -for i = 48, 57 do table.insert(Charset, string.char(i)) end -for i = 65, 90 do table.insert(Charset, string.char(i)) end -for i = 97, 122 do table.insert(Charset, string.char(i)) end - ESX.Trace = function(str) - if Config.EnableDebug then - print('ESX> ' .. str) - end -end - -ESX.GetConfig = function() - return Config -end - -ESX.GetRandomString = function(length) - - math.randomseed(os.time()) - - if length > 0 then - return ESX.GetRandomString(length - 1) .. Charset[math.random(1, #Charset)] - else - return '' - end - + if Config.EnableDebug then + print('ESX> ' .. str) + end end ESX.SetTimeout = function(msec, cb) + local id = ESX.TimeoutCount + 1 - local id = ESX.TimeoutCount + 1 + SetTimeout(msec, function() + if ESX.CancelledTimeouts[id] then + ESX.CancelledTimeouts[id] = nil + else + cb() + end + end) - SetTimeout(msec, function() - - if ESX.CancelledTimeouts[id] then - ESX.CancelledTimeouts[id] = nil - else - cb() - end - - end) - - ESX.TimeoutCount = id - - return id + ESX.TimeoutCount = id + return id end ESX.ClearTimeout = function(id) - ESX.CancelledTimeouts[id] = true + ESX.CancelledTimeouts[id] = true end ESX.RegisterServerCallback = function(name, cb) - ESX.ServerCallbacks[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('TriggerServerCallback => [' .. name .. '] does not exist') - end - + if ESX.ServerCallbacks[name] ~= nil then + ESX.ServerCallbacks[name](source, cb, ...) + else + print('es_extended: TriggerServerCallback => [' .. name .. '] does not exist') + end end ESX.SavePlayer = function(xPlayer, cb) + local asyncTasks = {} + xPlayer.lastPosition = xPlayer.get('coords') - local asyncTasks = {} - xPlayer.lastPosition = xPlayer.get('coords') + -- User accounts + for i=1, #xPlayer.accounts, 1 do - -- User accounts - for i=1, #xPlayer.accounts, 1 do + if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then + table.insert(asyncTasks, function(cb) + MySQL.Async.execute('UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', + { + ['@money'] = xPlayer.accounts[i].money, + ['@identifier'] = xPlayer.identifier, + ['@name'] = xPlayer.accounts[i].name + }, function(rowsChanged) + cb() + end) + end) - table.insert(asyncTasks, function(cb) + ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money - MySQL.Async.execute( - 'UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', - { - ['@money'] = xPlayer.accounts[i].money, - ['@identifier'] = xPlayer.identifier, - ['@name'] = xPlayer.accounts[i].name - }, - function(rowsChanged) - cb() - end - ) + end - end) + end - ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money + -- Inventory items + for i=1, #xPlayer.inventory, 1 do - end + if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then - end + table.insert(asyncTasks, function(cb) + MySQL.Async.execute('UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', + { + ['@count'] = xPlayer.inventory[i].count, + ['@identifier'] = xPlayer.identifier, + ['@item'] = xPlayer.inventory[i].name + }, function(rowsChanged) + cb() + end) + end) - -- Inventory items - for i=1, #xPlayer.inventory, 1 do + ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then + end - table.insert(asyncTasks, function(cb) + end - MySQL.Async.execute( - 'UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', - { - ['@count'] = xPlayer.inventory[i].count, - ['@identifier'] = xPlayer.identifier, - ['@item'] = xPlayer.inventory[i].name - }, - function(rowsChanged) - cb() - 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.loadout), + ['@position'] = json.encode(xPlayer.lastPosition), + ['@identifier'] = xPlayer.identifier + }, function(rowsChanged) + cb() + end) + end) - end) + Async.parallel(asyncTasks, function(results) + RconPrint('[SAVED] ' .. xPlayer.name .. "\n") - ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].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.loadout), - ['@position'] = json.encode(xPlayer.lastPosition), - ['@identifier'] = xPlayer.identifier - }, - function(rowsChanged) - cb() - end - ) - - end) - - Async.parallel(asyncTasks, function(results) - - RconPrint('[SAVED] ' .. xPlayer.name .. "\n") - - if cb ~= nil then - cb() - end - - end) + if cb ~= nil then + cb() + end + end) end ESX.SavePlayers = function(cb) + local asyncTasks = {} + local xPlayers = ESX.GetPlayers() - 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 - 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) - - RconPrint('[SAVED] All players' .. "\n") - - if cb ~= nil then - cb() - end - - end) + Async.parallelLimit(asyncTasks, 8, function(results) + RconPrint('[SAVED] All players' .. "\n") + if cb ~= nil then + cb() + end + end) end ESX.StartDBSync = function() + function saveData() + ESX.SavePlayers() + SetTimeout(10 * 60 * 1000, saveData) + end - function saveData() - ESX.SavePlayers() - SetTimeout(10 * 60 * 1000, saveData) - end - - SetTimeout(10 * 60 * 1000, saveData) - + SetTimeout(10 * 60 * 1000, saveData) end ESX.GetPlayers = function() + local sources = {} - local sources = {} + for k,v in pairs(ESX.Players) do + table.insert(sources, k) + end - for k,v in pairs(ESX.Players) do - table.insert(sources, k) - end - - return sources + return sources end ESX.GetPlayerFromId = function(source) - return ESX.Players[tonumber(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 - + 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 + ESX.UsableItemsCallbacks[item] = cb end ESX.UseItem = function(source, item) - ESX.UsableItemsCallbacks[item](source) + ESX.UsableItemsCallbacks[item](source) end ESX.GetItemLabel = function(item) @@ -230,34 +175,29 @@ ESX.GetItemLabel = function(item) end ESX.GetWeaponList = function() - return Config.Weapons + return Config.Weapons end ESX.GetWeaponLabel = function(name) + name = string.upper(name) + local weapons = ESX.GetWeaponList() - name = string.upper(name) - local weapons = ESX.GetWeaponList() - - for i=1, #weapons, 1 do - if weapons[i].name == name then - return weapons[i].label - end - end - + for i=1, #weapons, 1 do + if weapons[i].name == name then + return weapons[i].label + end + end end ESX.CreatePickup = function(type, name, count, label, player) + local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) - local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + ESX.Pickups[pickupId] = { + type = type, + name = name, + count = count + } - ESX.Pickups[pickupId] = { - type = type, - name = name, - count = count - } - - TriggerClientEvent('esx:pickup', -1, pickupId, label, player) - - ESX.PickupId = pickupId - -end \ No newline at end of file + TriggerClientEvent('esx:pickup', -1, pickupId, label, player) + ESX.PickupId = pickupId +end diff --git a/server/main.lua b/server/main.lua index 81c88fb6..abe364e1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,298 +1,252 @@ AddEventHandler('es:playerLoaded', function(source, _player) + local _source = source + local tasks = {} + + local userData = { + accounts = {}, + inventory = {}, + job = {}, + loadout = {}, + playerName = GetPlayerName(_source), + lastPosition = nil + } + + TriggerEvent('es:getPlayerFromId', _source, function(player) + + -- Update user name in DB + table.insert(tasks, function(cb) + MySQL.Async.execute('UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier(), + ['@name'] = userData.playerName + }, function(rowsChanged) + cb() + end) + end) + + -- Get accounts + table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(accounts) + + for i=1, #Config.Accounts, 1 do + for j=1, #accounts, 1 do + if accounts[j].name == Config.Accounts[i] then + table.insert(userData.accounts, { + name = accounts[j].name, + money = accounts[j].money, + label = Config.AccountLabels[accounts[j].name] + }) + end + end + end + + cb() + end) + end) + + -- Get inventory + table.insert(tasks, function(cb) + + MySQL.Async.fetchAll('SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(inventory) + + local tasks2 = {} + + for i=1, #inventory, 1 do + table.insert(userData.inventory, { + name = inventory[i].item, + count = inventory[i].count, + label = ESX.Items[inventory[i].item].label, + limit = ESX.Items[inventory[i].item].limit, + usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, + rare = ESX.Items[inventory[i].item].rare, + canRemove = ESX.Items[inventory[i].item].canRemove + }) + end + + for k,v in pairs(ESX.Items) do + local found = false + + for j=1, #userData.inventory, 1 do + if userData.inventory[j].name == k then + found = true + break + end + end + + if not found then + + table.insert(userData.inventory, { + name = k, + count = 0, + label = ESX.Items[k].label, + limit = ESX.Items[k].limit, + usable = ESX.UsableItemsCallbacks[k] ~= nil, + rare = ESX.Items[k].rare, + canRemove = ESX.Items[k].canRemove + }) + + local scope = function(item, identifier) + + table.insert(tasks2, function(cb2) + MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', + { + ['@identifier'] = identifier, + ['@item'] = item, + ['@count'] = 0 + }, function(rowsChanged) + cb2() + end) + end) + + end + + scope(k, player.getIdentifier()) + + end + + end + + Async.parallelLimit(tasks2, 5, function(results) end) + + table.sort(userData.inventory, function(a,b) + return a.label < b.label + end) + + cb() + end) + + end) + + -- Get job and loadout + table.insert(tasks, function(cb) + + local tasks2 = {} + + -- Get job name, grade and last position + table.insert(tasks2, function(cb2) - local _source = source - local tasks = {} - - local userData = { - accounts = {}, - inventory = {}, - job = {}, - loadout = {}, - playerName = GetPlayerName(_source), - lastPosition = nil - } - - TriggerEvent('es:getPlayerFromId', _source, function(player) - - -- Update user name in DB - table.insert(tasks, function(cb) - - MySQL.Async.execute( - 'UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', - { - ['@identifier'] = player.getIdentifier(), - ['@name'] = userData.playerName - }, - function(rowsChanged) - cb() - end - ) - - end) - - -- Get accounts - table.insert(tasks, function(cb) - - MySQL.Async.fetchAll( - 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', - { - ['@identifier'] = player.getIdentifier() - }, - function(accounts) - - for i=1, #Config.Accounts, 1 do - for j=1, #accounts, 1 do - if accounts[j].name == Config.Accounts[i] then - table.insert(userData.accounts, { - name = accounts[j].name, - money = accounts[j].money, - label = Config.AccountLabels[accounts[j].name] - }) - end - end - - end - - cb() - end - ) - - end) - - -- Get Inventory - table.insert(tasks, function(cb) - - MySQL.Async.fetchAll( - 'SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', - { - ['@identifier'] = player.getIdentifier() - }, - function(inventory) - - local tasks2 = {} - - for i=1, #inventory, 1 do - table.insert(userData.inventory, { - name = inventory[i].item, - count = inventory[i].count, - label = ESX.Items[inventory[i].item].label, - limit = ESX.Items[inventory[i].item].limit, - usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, - rare = ESX.Items[inventory[i].item].rare, - canRemove = ESX.Items[inventory[i].item].canRemove, - }) - end - - for k,v in pairs(ESX.Items) do - - local found = false - - for j=1, #userData.inventory, 1 do - if userData.inventory[j].name == k then - found = true - break - end - end + MySQL.Async.fetchAll('SELECT * FROM `users` WHERE `identifier` = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(result) + userData.job['name'] = result[1].job + userData.job['grade'] = result[1].job_grade - if not found then + if result[1].loadout ~= nil then + userData.loadout = json.decode(result[1].loadout) + end - table.insert(userData.inventory, { - name = k, - count = 0, - label = ESX.Items[k].label, - limit = ESX.Items[k].limit, - usable = ESX.UsableItemsCallbacks[k] ~= nil, - rare = ESX.Items[k].rare, - canRemove = ESX.Items[k].canRemove, - }) - - local scope = function(item, identifier) + if result[1].position ~= nil then + userData.lastPosition = json.decode(result[1].position) + end - table.insert(tasks2, function(cb2) + cb2() + end) - MySQL.Async.execute( - 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', - { - ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 - }, - function(rowsChanged) - cb2() - end - ) + end) - end) + -- Get job label + table.insert(tasks2, function(cb2) + MySQL.Async.fetchAll('SELECT * FROM `jobs` WHERE `name` = @name', { + ['@name'] = userData.job.name + }, function(result) + userData.job['label'] = result[1].label + cb2() + end) + end) - end + -- Get job grade data + table.insert(tasks2, function(cb2) - scope(k, player.getIdentifier()) + MySQL.Async.fetchAll('SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', + { + ['@job_name'] = userData.job.name, + ['@grade'] = userData.job.grade + }, function(result) - end + userData.job['grade_name'] = result[1].name + userData.job['grade_label'] = result[1].label + userData.job['grade_salary'] = result[1].salary - end + userData.job['skin_male'] = {} + userData.job['skin_female'] = {} - Async.parallelLimit(tasks2, 5, function(results) end) + if result[1].skin_male ~= nil then + userData.job['skin_male'] = json.decode(result[1].skin_male) + end - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) + if result[1].skin_female ~= nil then + userData.job['skin_female'] = json.decode(result[1].skin_female) + end - cb() - end - ) + cb2() + end) - end) + end) - -- Get job and loadout - table.insert(tasks, function(cb) + Async.series(tasks2, cb) - local tasks2 = {} + end) - -- Get job name, grade and last position - table.insert(tasks2, function(cb2) + -- Run Tasks + Async.parallel(tasks, function(results) - MySQL.Async.fetchAll( - 'SELECT * FROM `users` WHERE `identifier` = @identifier', - { - ['@identifier'] = player.getIdentifier() - }, - function(result) + local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) - userData.job['name'] = result[1].job - userData.job['grade'] = result[1].job_grade + xPlayer.getMissingAccounts(function(missingAccounts) - if result[1].loadout ~= nil then - userData.loadout = json.decode(result[1].loadout) - end + if #missingAccounts > 0 then - if result[1].position ~= nil then - userData.lastPosition = json.decode(result[1].position) - end + for i=1, #missingAccounts, 1 do + table.insert(xPlayer.accounts, { + name = missingAccounts[i], + money = 0, + label = Config.AccountLabels[missingAccounts[i]] + }) + end - cb2() + xPlayer.createAccounts(missingAccounts) + end - end - ) + ESX.Players[_source] = xPlayer - end) + TriggerEvent('esx:playerLoaded', _source) - -- Get job label - table.insert(tasks2, function(cb2) + TriggerClientEvent('esx:playerLoaded', _source, { + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) - MySQL.Async.fetchAll( - 'SELECT * FROM `jobs` WHERE `name` = @name', - { - ['@name'] = userData.job.name - }, - function(result) + xPlayer.player.displayMoney(xPlayer.get('money')) - userData.job['label'] = result[1].label + end) - cb2() + end) - end - ) - - end) - - -- Get job grade data - table.insert(tasks2, function(cb2) - - MySQL.Async.fetchAll( - 'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', - { - ['@job_name'] = userData.job.name, - ['@grade'] = userData.job.grade - }, - function(result) - - userData.job['grade_name'] = result[1].name - userData.job['grade_label'] = result[1].label - userData.job['grade_salary'] = result[1].salary - - userData.job['skin_male'] = {} - userData.job['skin_female'] = {} - - if result[1].skin_male ~= nil then - userData.job['skin_male'] = json.decode(result[1].skin_male) - end - - if result[1].skin_female ~= nil then - userData.job['skin_female'] = json.decode(result[1].skin_female) - end - - cb2() - - end - ) - - end) - - Async.series(tasks2, cb) - - end) - - -- Run Tasks - Async.parallel(tasks, function(results) - - local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) - - xPlayer.getMissingAccounts(function(missingAccounts) - - if #missingAccounts > 0 then - - for i=1, #missingAccounts, 1 do - table.insert(xPlayer.accounts, { - name = missingAccounts[i], - money = 0, - label = Config.AccountLabels[missingAccounts[i]] - }) - end - - xPlayer.createAccounts(missingAccounts) - end - - ESX.Players[_source] = xPlayer - - TriggerEvent('esx:playerLoaded', _source) - - TriggerClientEvent('esx:playerLoaded', _source, { - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - - xPlayer.player.displayMoney(xPlayer.get('money')) - - end) - - end) - - end) + end) end) AddEventHandler('playerDropped', function(reason) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - - if xPlayer ~= nil then - - TriggerEvent('esx:playerDropped', _source, reason) - - ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil - ESX.LastPlayerData[_source] = nil - end) - - end + if xPlayer ~= nil then + TriggerEvent('esx:playerDropped', _source, reason) + ESX.SavePlayer(xPlayer, function() + ESX.Players[_source] = nil + ESX.LastPlayerData[_source] = nil + end) + end end) RegisterServerEvent('esx:updateLoadout') @@ -310,293 +264,271 @@ end) RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) + local _source = source - local _source = source + local sourceXPlayer = ESX.GetPlayerFromId(_source) + local targetXPlayer = ESX.GetPlayerFromId(target) - local sourceXPlayer = ESX.GetPlayerFromId(_source) - local targetXPlayer = ESX.GetPlayerFromId(target) + if type == 'item_standard' then - if type == 'item_standard' then + local sourceItem = sourceXPlayer.getInventoryItem(itemName) + local targetItem = targetXPlayer.getInventoryItem(itemName) - local sourceItem = sourceXPlayer.getInventoryItem(itemName) - local targetItem = targetXPlayer.getInventoryItem(itemName) + if itemCount > 0 and sourceItem.count >= itemCount then - if itemCount > 0 and sourceItem.count >= itemCount then + if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then + TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) + else + sourceXPlayer.removeInventoryItem(itemName, itemCount) + targetXPlayer.addInventoryItem (itemName, itemCount) + + TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) + end - if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) - else - sourceXPlayer.removeInventoryItem(itemName, itemCount) - targetXPlayer.addInventoryItem (itemName, itemCount) - - TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) - end + else + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - end + elseif type == 'item_money' then - elseif type == 'item_money' then + if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then - if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then + sourceXPlayer.removeMoney(itemCount) + targetXPlayer.addMoney (itemCount) - sourceXPlayer.removeMoney(itemCount) - targetXPlayer.addMoney (itemCount) + TriggerClientEvent('esx:showNotification', _source, _U('gave_money', itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_money', itemCount, sourceXPlayer.name)) - TriggerClientEvent('esx:showNotification', _source, _U('gave_money', itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_money', itemCount, sourceXPlayer.name)) + else + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - end + elseif type == 'item_account' then - elseif type == 'item_account' then + if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then - if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then + sourceXPlayer.removeAccountMoney(itemName, itemCount) + targetXPlayer.addAccountMoney (itemName, itemCount) - sourceXPlayer.removeAccountMoney(itemName, itemCount) - targetXPlayer.addAccountMoney (itemName, itemCount) + TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', itemCount, Config.AccountLabels[itemName], targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_account_money', itemCount, Config.AccountLabels[itemName], sourceXPlayer.name)) - TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', itemCount, Config.AccountLabels[itemName], targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_account_money', itemCount, Config.AccountLabels[itemName], sourceXPlayer.name)) + else + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - end - - elseif type == 'item_weapon' then - - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) - - local weaponLabel = ESX.GetWeaponLabel(itemName) - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, itemCount, sourceXPlayer.name)) - end + elseif type == 'item_weapon' then + + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) + + local weaponLabel = ESX.GetWeaponLabel(itemName) + TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, itemCount, sourceXPlayer.name)) + end end) RegisterServerEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) + local _source = source - local _source = source + if type == 'item_standard' then - if type == 'item_standard' then + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + else - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - else + local xPlayer = ESX.GetPlayerFromId(source) + local foundItem = nil - local xPlayer = ESX.GetPlayerFromId(source) - local foundItem = nil + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].name == itemName then + foundItem = xPlayer.inventory[i] + end + end - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].name == itemName then - foundItem = xPlayer.inventory[i] - end - end + if itemCount > foundItem.count then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + else - if itemCount > foundItem.count then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - else + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + SetTimeout(Config.RemoveInventoryItemDelay, function() + local remainingCount = xPlayer.getInventoryItem(itemName).count + local total = itemCount - SetTimeout(Config.RemoveInventoryItemDelay, function() + if remainingCount < itemCount then + total = remainingCount + end - local remainingCount = xPlayer.getInventoryItem(itemName).count - local total = itemCount + if total > 0 then + xPlayer.removeInventoryItem(itemName, total) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label .. ' [' .. itemCount .. ']', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) + end + end) + end - if remainingCount < itemCount then - total = remainingCount - end + end - if total > 0 then - xPlayer.removeInventoryItem(itemName, total) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) - end + elseif type == 'item_money' then - end) + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - end + local xPlayer = ESX.GetPlayerFromId(source) - end + if itemCount > xPlayer.player.get('money') then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - elseif type == 'item_money' then + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + SetTimeout(Config.RemoveInventoryItemDelay, function() + local remainingCount = xPlayer.player.get('money') + local total = itemCount - local xPlayer = ESX.GetPlayerFromId(source) + if remainingCount < itemCount then + total = remainingCount + end - if itemCount > xPlayer.player.get('money') then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + if total > 0 then + xPlayer.removeMoney(total) + ESX.CreatePickup('item_money', 'money', total, 'Cash' .. ' [' .. itemCount .. ']', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) + end + end) + end - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + end - SetTimeout(Config.RemoveInventoryItemDelay, function() + elseif type == 'item_account' then - local remainingCount = xPlayer.player.get('money') - local total = itemCount + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - if remainingCount < itemCount then - total = remainingCount - end + local xPlayer = ESX.GetPlayerFromId(source) - if total > 0 then - xPlayer.removeMoney(total) - ESX.CreatePickup('item_money', 'money', total, 'Cash' .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end + if itemCount > xPlayer.getAccount(itemName).money then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - end) + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - end + SetTimeout(Config.RemoveInventoryItemDelay, function() + local remainingCount = xPlayer.getAccount(itemName).money + local total = itemCount - end + if remainingCount < itemCount then + total = remainingCount + end - elseif type == 'item_account' then + if total > 0 then + xPlayer.removeAccountMoney(itemName, total) + ESX.CreatePickup('item_account', itemName, total, Config.AccountLabels[itemName] .. ' [' .. itemCount .. ']', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) + end + end) + end - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + end - local xPlayer = ESX.GetPlayerFromId(source) + elseif type == 'item_weapon' then - if itemCount > xPlayer.getAccount(itemName).money then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + local xPlayer = ESX.GetPlayerFromId(source) + local weaponName = itemName + local weaponLabel = ESX.GetWeaponLabel(weaponName) + local weaponPickup = 'PICKUP_' .. weaponName + + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + + SetTimeout(Config.RemoveInventoryItemDelay, function() + xPlayer.removeWeapon(itemName) + if Config.EnableWeaponPickup then + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName, itemCount) + end - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - - local remainingCount = xPlayer.getAccount(itemName).money - local total = itemCount - - if remainingCount < itemCount then - total = remainingCount - end - - if total > 0 then - xPlayer.removeAccountMoney(itemName, total) - ESX.CreatePickup('item_account', itemName, total, Config.AccountLabels[itemName] .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end - - end) - - end - - end - - elseif type == 'item_weapon' then - - local xPlayer = ESX.GetPlayerFromId(source) - local weaponName = itemName - local weaponLabel = ESX.GetWeaponLabel(weaponName) - local weaponPickup = 'PICKUP_' .. weaponName - - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - - xPlayer.removeWeapon(itemName) - if Config.EnableWeaponPickup then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName, itemCount) - end - - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel, itemCount)) - - end) - - end + TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel, itemCount)) + end) + end end) RegisterServerEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) + local xPlayer = ESX.GetPlayerFromId(source) + local count = xPlayer.getInventoryItem(itemName).count - local xPlayer = ESX.GetPlayerFromId(source) - local count = xPlayer.getInventoryItem(itemName).count - - if count > 0 then - ESX.UseItem(source, itemName) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) - end - + if count > 0 then + ESX.UseItem(source, itemName) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) + end end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) + local _source = source + local pickup = ESX.Pickups[id] + local xPlayer = ESX.GetPlayerFromId(_source) - local _source = source - local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(_source) + if pickup.type == 'item_standard' then - if pickup.type == 'item_standard' then + local item = xPlayer.getInventoryItem(pickup.name) + local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 + local total = pickup.count < canTake and pickup.count or canTake + local remaining = pickup.count - total - local item = xPlayer.getInventoryItem(pickup.name) - local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 - local total = pickup.count < canTake and pickup.count or canTake - local remaining = pickup.count - total + TriggerClientEvent('esx:removePickup', -1, id) - TriggerClientEvent('esx:removePickup', -1, id) + if total > 0 then + xPlayer.addInventoryItem(pickup.name, total) + end - if total > 0 then - xPlayer.addInventoryItem(pickup.name, total) - end - - if remaining > 0 then - TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) - ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) - end - - elseif pickup.type == 'item_money' then - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addMoney(pickup.count) - elseif pickup.type == 'item_account' then - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addAccountMoney(pickup.name, pickup.count) - end + if remaining > 0 then + TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) + ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) + end + elseif pickup.type == 'item_money' then + TriggerClientEvent('esx:removePickup', -1, id) + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + TriggerClientEvent('esx:removePickup', -1, id) + xPlayer.addAccountMoney(pickup.name, pickup.count) + end end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) - local xPlayer = ESX.GetPlayerFromId(source) - - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) end) ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target) + local xPlayer = ESX.GetPlayerFromId(target) - local xPlayer = ESX.GetPlayerFromId(target) - - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) end) TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) diff --git a/shared/functions.lua b/shared/functions.lua index 222c163f..d55ec2b0 100644 --- a/shared/functions.lua +++ b/shared/functions.lua @@ -14,6 +14,10 @@ ESX.GetRandomString = function(length) end end +ESX.GetConfig = function() + return Config +end + ESX.TableContainsValue = function(table, value) for k, v in pairs(table) do if v == value then