From 57228734722e792289bc22b96d45d16912078b17 Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Mon, 28 Apr 2025 18:01:28 +0200 Subject: [PATCH 1/5] feat(es_extended/server/functions): add promise support for ESX.GetVehicleType --- [core]/es_extended/server/functions.lua | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/[core]/es_extended/server/functions.lua b/[core]/es_extended/server/functions.lua index 5ba47867..9b20c92f 100644 --- a/[core]/es_extended/server/functions.lua +++ b/[core]/es_extended/server/functions.lua @@ -386,19 +386,38 @@ end ---@param model string|number ---@param player number ----@param cb function +---@param cb function? ---@diagnostic disable-next-line: duplicate-set-field +---@return string? function ESX.GetVehicleType(model, player, cb) + if cb and not ESX.IsFunctionReference(cb) then + error("Invalid callback function") + end + + local promise = not cb and promise.new() + + local function resolve(result) + if promise then + promise:resolve(result) + elseif cb then + cb(result) + end + end + model = type(model) == "string" and joaat(model) or model if Core.vehicleTypesByModel[model] then - return cb(Core.vehicleTypesByModel[model]) + return resolve(Core.vehicleTypesByModel[model]) end ESX.TriggerClientCallback(player, "esx:GetVehicleType", function(vehicleType) Core.vehicleTypesByModel[model] = vehicleType - cb(vehicleType) + resolve(vehicleType) end, model) + + if promise then + return Citizen.Await(promise) + end end ---@param name string From 372c8a224d5e71dc7169a49761679268144a80ff Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Mon, 28 Apr 2025 18:01:48 +0200 Subject: [PATCH 2/5] feat(es_extended/server/modules/onesync): add optional vehicleType to SpawnVehicle --- [core]/es_extended/server/modules/onesync.lua | 78 +++++++++++-------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/[core]/es_extended/server/modules/onesync.lua b/[core]/es_extended/server/modules/onesync.lua index de4f4eb8..8c5c76d3 100644 --- a/[core]/es_extended/server/modules/onesync.lua +++ b/[core]/es_extended/server/modules/onesync.lua @@ -78,57 +78,67 @@ function ESX.OneSync.GetClosestPlayer(source, maxDistance, ignore) return getNearbyPlayers(source, true, maxDistance, ignore) end ----@param model number|string +---@param vehicleModel number|string ---@param coords vector3|table ---@param heading number ----@param properties table +---@param vehicleProperties table ---@param cb? fun(netId: number) +---@param vehicleType string? ---@return number? netId -function ESX.OneSync.SpawnVehicle(model, coords, heading, properties, cb) +function ESX.OneSync.SpawnVehicle(vehicleModel, coords, heading, vehicleProperties, cb, vehicleType) if cb and not ESX.IsFunctionReference(cb) then error("Invalid callback function") end - - local vehicleModel = joaat(model) - local vehicleProperties = properties + vehicleModel = joaat(vehicleModel) local promise = not cb and promise.new() + + local function resolve(result) + if promise then + promise:resolve(result) + elseif cb then + cb(result) + end + end + + local function reject(err) + if promise then + promise:reject(err) + end + error(err) + end + CreateThread(function() - local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) - ESX.GetVehicleType(vehicleModel, xPlayer.id, function(vehicleType) - if not vehicleType then - if (promise) then - return promise:reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) - end - error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + if not vehicleType then + local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) + if not xPlayer then + return reject("No players found nearby to check vehicle type!") end + vehicleType = ESX.GetVehicleType(vehicleModel, xPlayer.id) + end - local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) - local tries = 0 + if not vehicleType then + return reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(vehicleModel)) + end - while not createdVehicle or createdVehicle == 0 or NetworkGetEntityOwner(createdVehicle) == -1 do - Wait(200) - tries = tries + 1 - if tries > 40 then - if promise then - return promise:reject(("Could not spawn vehicle - ^5%s^7!"):format(model)) - end - error(("Could not spawn vehicle - ^5%s^7!"):format(model)) - end + local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) + local tries = 0 + + while not createdVehicle or createdVehicle == 0 or NetworkGetEntityOwner(createdVehicle) == -1 do + Wait(200) + tries = tries + 1 + if tries > 40 then + return reject(("Could not spawn vehicle - ^5%s^7!"):format(vehicleModel)) end + end - -- luacheck: ignore - SetEntityOrphanMode(createdVehicle, 2) - local networkId = NetworkGetNetworkIdFromEntity(createdVehicle) - Entity(createdVehicle).state:set("VehicleProperties", vehicleProperties, true) + -- luacheck: ignore + SetEntityOrphanMode(createdVehicle, 2) + local networkId = NetworkGetNetworkIdFromEntity(createdVehicle) + Entity(createdVehicle).state:set("VehicleProperties", vehicleProperties, true) - if promise then - promise:resolve(networkId) - elseif cb then - cb(networkId) - end - end) + resolve(networkId) end) if promise then From 4e8da192177c806958ce7b27300e593c3e54314a Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Sat, 14 Jun 2025 21:15:11 +0200 Subject: [PATCH 3/5] refactor(es_extended/server/functions): fix diagnostics --- [core]/es_extended/server/functions.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/[core]/es_extended/server/functions.lua b/[core]/es_extended/server/functions.lua index 9b20c92f..920b25ab 100644 --- a/[core]/es_extended/server/functions.lua +++ b/[core]/es_extended/server/functions.lua @@ -387,15 +387,14 @@ end ---@param model string|number ---@param player number ---@param cb function? ----@diagnostic disable-next-line: duplicate-set-field ---@return string? +---@diagnostic disable-next-line: duplicate-set-field function ESX.GetVehicleType(model, player, cb) if cb and not ESX.IsFunctionReference(cb) then error("Invalid callback function") end local promise = not cb and promise.new() - local function resolve(result) if promise then promise:resolve(result) From e43d694c36ddba363c77c591af3047538c45e2cc Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Sat, 14 Jun 2025 22:12:37 +0200 Subject: [PATCH 4/5] fix(es_extended/server/modules/onesync): only await net owner if valid player is nearby --- [core]/es_extended/server/modules/onesync.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/[core]/es_extended/server/modules/onesync.lua b/[core]/es_extended/server/modules/onesync.lua index 8c5c76d3..c807f4f8 100644 --- a/[core]/es_extended/server/modules/onesync.lua +++ b/[core]/es_extended/server/modules/onesync.lua @@ -110,8 +110,8 @@ function ESX.OneSync.SpawnVehicle(vehicleModel, coords, heading, vehicleProperti end CreateThread(function() + local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) if not vehicleType then - local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) if not xPlayer then return reject("No players found nearby to check vehicle type!") end @@ -125,7 +125,9 @@ function ESX.OneSync.SpawnVehicle(vehicleModel, coords, heading, vehicleProperti local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) local tries = 0 - while not createdVehicle or createdVehicle == 0 or NetworkGetEntityOwner(createdVehicle) == -1 do + while not createdVehicle or createdVehicle == 0 + or (xPlayer and NetworkGetEntityOwner(createdVehicle) == -1) + or (not xPlayer and not DoesEntityExist(createdVehicle)) do Wait(200) tries = tries + 1 if tries > 40 then From ae1a3faa2d98d1c6afedbb384a736ccac9782cc9 Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Sat, 14 Jun 2025 22:39:09 +0200 Subject: [PATCH 5/5] fix(es_extended/server/modules/onesync): dont await ent ownership if no valid client nearby --- [core]/es_extended/server/modules/onesync.lua | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/[core]/es_extended/server/modules/onesync.lua b/[core]/es_extended/server/modules/onesync.lua index c807f4f8..14c09698 100644 --- a/[core]/es_extended/server/modules/onesync.lua +++ b/[core]/es_extended/server/modules/onesync.lua @@ -110,24 +110,21 @@ function ESX.OneSync.SpawnVehicle(vehicleModel, coords, heading, vehicleProperti end CreateThread(function() - local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) - if not vehicleType then - if not xPlayer then - return reject("No players found nearby to check vehicle type!") - end - vehicleType = ESX.GetVehicleType(vehicleModel, xPlayer.id) - end + local closestPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) + local closestPlayerFound = next(closestPlayer) ~= nil + + vehicleType = vehicleType or (closestPlayerFound and ESX.GetVehicleType(vehicleModel, closestPlayer.id) or nil) if not vehicleType then - return reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(vehicleModel)) + return reject("No players found nearby to check vehicle type! Alternatively, you can specify the vehicle type manually.") end local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) local tries = 0 while not createdVehicle or createdVehicle == 0 - or (xPlayer and NetworkGetEntityOwner(createdVehicle) == -1) - or (not xPlayer and not DoesEntityExist(createdVehicle)) do + or (closestPlayerFound and NetworkGetEntityOwner(createdVehicle) == -1) + or (not closestPlayerFound and not DoesEntityExist(createdVehicle)) do Wait(200) tries = tries + 1 if tries > 40 then