local Resource, Promises, Functions, CallIdentifier = GetCurrentResourceName(), {}, {}, 0 RPC = {} function ClearPromise(callID) Citizen.SetTimeout(5000, function() Promises[callID] = nil end) end function ParamPacker(...) local params, pack = {...} , {} for i = 1, 15, 1 do pack[i] = params[i] end return pack end function ParamUnpacker(params, index) local idx = index or 1 if idx <= #params then return params[idx], ParamUnpacker(params, idx + 1) end end function UnPacker(params, index) local idx = index or 1 if idx <= 15 then return params[idx], UnPacker(params, idx + 1) end end ------------------------------------------------------------------ -- (Trigger Server Calls) ------------------------------------------------------------------ function RPC.execute(name, ...) local callID, solved = CallIdentifier, false CallIdentifier = CallIdentifier + 1 Promises[callID] = promise:new() TriggerServerEvent("rpc:request", Resource, name, callID, ParamPacker(...)) Citizen.SetTimeout(35000, function() if not solved then Promises[callID]:resolve({nil}) TriggerServerEvent("rpc:server:timeout", Resource, name) end end) local response = Citizen.Await(Promises[callID]) solved = true ClearPromise(callID) return ParamUnpacker(response) end function RPC.executeLatent(name, timeout, ...) local callID, solved = CallIdentifier, false CallIdentifier = CallIdentifier + 1 Promises[callID] = promise:new() TriggerLatentServerEvent("rpc:latent:request", 50000, Resource, name, callID, ParamPacker(...), true) Citizen.SetTimeout(timeout, function() if not solved then Promises[callID]:resolve({nil}) TriggerServerEvent("rpc:server:timeout", Resource, name) end end) local response = Citizen.Await(Promises[callID]) solved = true ClearPromise(callID) return ParamUnpacker(response) end RegisterNetEvent("rpc:response") AddEventHandler("rpc:response", function(origin, callID, response) if Resource == origin and Promises[callID] then Promises[callID]:resolve(response) end end) ------------------------------------------------------------------ -- (Receive Remote Calls) ------------------------------------------------------------------ function RPC.register(name, func) Functions[name] = func end function RPC.remove(name) Functions[name] = nil end RegisterNetEvent("rpc:request") AddEventHandler("rpc:request", function(origin, name, callID, params) local response if Functions[name] == nil then return end local success, error = pcall(function() if packaged then response = ParamPacker(Functions[name](ParamUnpacker(params))) else response = ParamPacker(Functions[name](UnPacker(params))) end end) if not success then TriggerServerEvent("rpc:client:error", Resource, origin, name, error) end if response == nil then response = {} end TriggerServerEvent("rpc:response", origin, callID, response, true) end) RegisterNetEvent("rpc:latent:request") AddEventHandler("rpc:latent:request", function(origin, name, callID, params) local response if Functions[name] == nil then return end local success, error = pcall(function() if packaged then response = ParamPacker(Functions[name](ParamUnpacker(params))) else response = ParamPacker(Functions[name](UnPacker(params))) end end) if not success then TriggerServerEvent("rpc:client:error", Resource, origin, name, error) end if response == nil then response = {} end TriggerLatentServerEvent("rpc:response", 50000, origin, callID, response, true) end) RegisterNetEvent("rpc:client:error") AddEventHandler("rpc:client:error", function(resource, origin, name, error) if resource == GetCurrentResourceName() then Citizen.Trace(("[RPC] Error: %s %s %s %s"):format(resource, origin, name, error)) end end)