Merge pull request #1031 from esx-framework/callback-await

feat(es_extended): add Await for callbacks
This commit is contained in:
Gergo
2023-05-01 11:38:44 +02:00
committed by GitHub
3 changed files with 153 additions and 96 deletions
+77 -78
View File
@@ -522,82 +522,82 @@ AddEventHandler("esx:tpm", function()
local GetBlipInfoIdCoord = GetBlipInfoIdCoord
local GetVehiclePedIsIn = GetVehiclePedIsIn
ESX.TriggerServerCallback("esx:isUserAdmin", function(admin)
if not admin then
return
end
local blipMarker = GetFirstBlipInfoId(8)
if not DoesBlipExist(blipMarker) then
ESX.ShowNotification(TranslateCap('tpm_nowaypoint'), true, false, 140)
return 'marker'
local admin = ESX.TriggerServerCallback.Await("esx:isUserAdmin")
if not admin then
return
end
local blipMarker = GetFirstBlipInfoId(8)
if not DoesBlipExist(blipMarker) then
ESX.ShowNotification(TranslateCap('tpm_nowaypoint'), true, false, 140)
return 'marker'
end
-- Fade screen to hide how clients get teleported.
DoScreenFadeOut(650)
while not IsScreenFadedOut() do
Wait(0)
end
local ped, coords = ESX.PlayerData.ped, GetBlipInfoIdCoord(blipMarker)
local vehicle = GetVehiclePedIsIn(ped, false)
local oldCoords = GetEntityCoords(ped)
-- Unpack coords instead of having to unpack them while iterating.
-- 825.0 seems to be the max a player can reach while 0.0 being the lowest.
local x, y, groundZ, Z_START = coords['x'], coords['y'], 850.0, 950.0
local found = false
FreezeEntityPosition(vehicle > 0 and vehicle or ped, true)
for i = Z_START, 0, -25.0 do
local z = i
if (i % 2) ~= 0 then
z = Z_START - i
end
-- Fade screen to hide how clients get teleported.
DoScreenFadeOut(650)
while not IsScreenFadedOut() do
NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0)
local curTime = GetGameTimer()
while IsNetworkLoadingScene() do
if GetGameTimer() - curTime > 1000 then
break
end
Wait(0)
end
NewLoadSceneStop()
SetPedCoordsKeepVehicle(ped, x, y, z)
local ped, coords = ESX.PlayerData.ped, GetBlipInfoIdCoord(blipMarker)
local vehicle = GetVehiclePedIsIn(ped, false)
local oldCoords = GetEntityCoords(ped)
-- Unpack coords instead of having to unpack them while iterating.
-- 825.0 seems to be the max a player can reach while 0.0 being the lowest.
local x, y, groundZ, Z_START = coords['x'], coords['y'], 850.0, 950.0
local found = false
FreezeEntityPosition(vehicle > 0 and vehicle or ped, true)
for i = Z_START, 0, -25.0 do
local z = i
if (i % 2) ~= 0 then
z = Z_START - i
end
NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0)
local curTime = GetGameTimer()
while IsNetworkLoadingScene() do
if GetGameTimer() - curTime > 1000 then
break
end
Wait(0)
end
NewLoadSceneStop()
SetPedCoordsKeepVehicle(ped, x, y, z)
while not HasCollisionLoadedAroundEntity(ped) do
RequestCollisionAtCoord(x, y, z)
if GetGameTimer() - curTime > 1000 then
break
end
Wait(0)
end
-- Get ground coord. As mentioned in the natives, this only works if the client is in render distance.
found, groundZ = GetGroundZFor_3dCoord(x, y, z, false)
if found then
Wait(0)
SetPedCoordsKeepVehicle(ped, x, y, groundZ)
while not HasCollisionLoadedAroundEntity(ped) do
RequestCollisionAtCoord(x, y, z)
if GetGameTimer() - curTime > 1000 then
break
end
Wait(0)
end
-- Remove black screen once the loop has ended.
DoScreenFadeIn(650)
FreezeEntityPosition(vehicle > 0 and vehicle or ped, false)
if not found then
-- If we can't find the coords, set the coords to the old ones.
-- We don't unpack them before since they aren't in a loop and only called once.
SetPedCoordsKeepVehicle(ped, oldCoords['x'], oldCoords['y'], oldCoords['z'] - 1.0)
ESX.ShowNotification(TranslateCap('tpm_success'), true, false, 140)
-- Get ground coord. As mentioned in the natives, this only works if the client is in render distance.
found, groundZ = GetGroundZFor_3dCoord(x, y, z, false)
if found then
Wait(0)
SetPedCoordsKeepVehicle(ped, x, y, groundZ)
break
end
Wait(0)
end
-- If Z coord was found, set coords in found coords.
SetPedCoordsKeepVehicle(ped, x, y, groundZ)
-- Remove black screen once the loop has ended.
DoScreenFadeIn(650)
FreezeEntityPosition(vehicle > 0 and vehicle or ped, false)
if not found then
-- If we can't find the coords, set the coords to the old ones.
-- We don't unpack them before since they aren't in a loop and only called once.
SetPedCoordsKeepVehicle(ped, oldCoords['x'], oldCoords['y'], oldCoords['z'] - 1.0)
ESX.ShowNotification(TranslateCap('tpm_success'), true, false, 140)
end)
end
-- If Z coord was found, set coords in found coords.
SetPedCoordsKeepVehicle(ped, x, y, groundZ)
ESX.ShowNotification(TranslateCap('tpm_success'), true, false, 140)
end)
local noclip = false
@@ -646,24 +646,23 @@ local function noclipThread()
end
RegisterNetEvent("esx:noclip")
AddEventHandler("esx:noclip", function(input)
ESX.TriggerServerCallback("esx:isUserAdmin", function(admin)
if not admin then
return
end
AddEventHandler("esx:noclip", function()
local admin = ESX.TriggerServerCallback.Await("esx:isUserAdmin")
if not admin then
return
end
if not noclip then
noclip_pos = GetEntityCoords(ESX.PlayerData.ped, false)
heading = GetEntityHeading(ESX.PlayerData.ped)
end
if not noclip then
noclip_pos = GetEntityCoords(ESX.PlayerData.ped, false)
heading = GetEntityHeading(ESX.PlayerData.ped)
end
noclip = not noclip
if noclip then
CreateThread(noclipThread)
end
noclip = not noclip
if noclip then
CreateThread(noclipThread)
end
ESX.ShowNotification(TranslateCap('noclip_message', noclip and "enabled" or "disabled"), true, false, 140)
end)
ESX.ShowNotification(TranslateCap('noclip_message', noclip and "enabled" or "disabled"), true, false, 140)
end)
RegisterNetEvent("esx:killPlayer")
+34 -9
View File
@@ -3,22 +3,47 @@ local serverRequests = {}
local clientCallbacks = {}
---@param eventName string
---@param callback function
---@param ... any
ESX.TriggerServerCallback = function(eventName, callback, ...)
serverRequests[RequestId] = callback
TriggerServerEvent('esx:triggerServerCallback', eventName, RequestId, GetInvokingResource() or "unknown", ...)
ESX.TriggerServerCallback = setmetatable({
---@param eventName string
---@param ... any
Await = function(eventName, ...)
assert(type(eventName) == 'string', 'Argument 1 `eventName` is not a string!')
local p = promise.new()
RequestId = RequestId + 1
end
serverRequests[RequestId] = p
TriggerServerEvent('esx:triggerServerCallback', eventName, RequestId, GetInvokingResource() or "unknown", ...)
RequestId = RequestId + 1
return Citizen.Await(p)
end
}, {
---@param eventName string
---@param callback function
---@param ... any
__call = function(_, eventName, callback, ...)
assert(type(eventName) == 'string', 'Argument 1 `eventName` is not a string!')
assert(type(callback) == 'function', 'Argument 2 `callback` is not a function!')
serverRequests[RequestId] = callback
TriggerServerEvent('esx:triggerServerCallback', eventName, RequestId, GetInvokingResource() or "unknown", ...)
RequestId = RequestId + 1
end
})
RegisterNetEvent('esx:serverCallback', function(requestId, invoker, ...)
if not serverRequests[requestId] then
return print(('[^1ERROR^7] Server Callback with requestId ^5%s^7 Was Called by ^5%s^7 but does not exist.'):format(requestId, invoker))
end
if type(serverRequests[requestId]) == 'table' then
serverRequests[requestId]:resolve(...)
return
end
serverRequests[requestId](...)
serverRequests[requestId] = nil
end)
+42 -9
View File
@@ -21,23 +21,56 @@ RegisterNetEvent('esx:triggerServerCallback', function(eventName, requestId, inv
end, ...)
end)
---@param player number playerId
---@param eventName string
---@param callback function
---@param ... any
ESX.TriggerClientCallback = function(player, eventName, callback, ...)
clientRequests[RequestId] = callback
ESX.TriggerClientCallback = setmetatable({
---@param player number?
---@param eventName string
---@param ... any
Await = function(player, eventName, ...)
player = tonumber(player)
TriggerClientEvent('esx:triggerClientCallback', player, eventName, RequestId, GetInvokingResource() or "unknown", ...)
assert(player, 'Argument 1 `player` is not a number!')
assert(type(eventName) == 'string', 'Argument 2 `eventName` is not a string!')
RequestId = RequestId + 1
end
local p = promise.new()
clientRequests[RequestId] = p
TriggerClientEvent('esx:triggerClientCallback', player, eventName, RequestId, GetInvokingResource() or "unknown", ...)
RequestId = RequestId + 1
return Citizen.Await(p)
end
}, {
---@param player number? playerId
---@param eventName string
---@param callback function
---@param ... any
__call = function(_, player, eventName, callback, ...)
player = tonumber(player)
assert(player, 'Argument 1 `player` is not a number!')
assert(type(eventName) == 'string', 'Argument 2 `eventName` is not a string!')
assert(type(callback) == 'function', 'Argument 3 `callback` is not a function!')
clientRequests[RequestId] = callback
TriggerClientEvent('esx:triggerClientCallback', player, eventName, RequestId, GetInvokingResource() or "unknown", ...)
RequestId = RequestId + 1
end
})
RegisterNetEvent('esx:clientCallback', function(requestId, invoker, ...)
if not clientRequests[requestId] then
return print(('[^1ERROR^7] Client Callback with requestId ^5%s^7 Was Called by ^5%s^7 but does not exist.'):format(requestId, invoker))
end
if type(clientRequests[requestId]) == 'table' then
clientRequests[requestId]:resolve(...)
return
end
clientRequests[requestId](...)
clientRequests[requestId] = nil
end)