1
0
Fork 0
forked from Simnation/Main
Main/resources/[tools]/bl_bridge/utils.lua
2025-08-04 04:28:47 +02:00

290 lines
9.1 KiB
Lua

local Utils = {}
local function retreiveExportsData(export, override)
local newMethods = {}
for k, v in pairs(override) do
local method = export[v.originalMethod]
if method then
v.selfEffect = function(...)
return method(export, ...)
end
newMethods[k] = v
end
end
return newMethods
end
local function retreiveStringIndexedData(wrappedData, functionsOverride, src)
local newMethods = {}
local function modifyMethods(data, method, modification)
if type(modification) ~= 'table' then return end
local selfEffect = modification.selfEffect
local originalMethod = selfEffect or modification.originalMethod
local ref = selfEffect or data[originalMethod]
local modifier = modification.modifier
if ref and originalMethod then
local lastEffect
if modifier then
local executeFunc, effect, passSource = modifier.executeFunc, modifier.effect, modifier.passSource
if passSource and executeFunc then
assert(src, 'source not exist')
lastEffect = effect and effect(ref, src) or ref(src)
elseif executeFunc then
lastEffect = effect and effect(ref) or ref
else
lastEffect = function(...)
assert(not passSource or src, 'source not exist')
if passSource and src and effect then
return effect(ref, src, ...)
elseif effect then
return effect(ref, ...)
else
return ref(src, ...)
end
end
end
else
lastEffect = ref
end
newMethods[method] = lastEffect
end
end
local function processTable(tableToProcess, overrides)
for method, modification in pairs(overrides) do
if type(modification) == 'table' and not modification.originalMethod and not modification.add then
processTable(tableToProcess[method], modification)
else
modifyMethods(tableToProcess, method, modification)
end
end
end
processTable(wrappedData, functionsOverride)
return newMethods
end
local function retreiveNumberIndexedData(playerTable, functionsOverride)
local newMethods = {}
local function modifyMethods(data, method, modification)
for dataIndex, dataValue in ipairs(data) do
local originalMethods = type(modification.originalMethod) == 'table' and modification.originalMethod or
{ modification.originalMethod }
local originalMethodRef
local originalMethod
for _, method in ipairs(originalMethods) do
originalMethod = method
originalMethodRef = originalMethod and dataValue[method]
if originalMethodRef then
break
end
end
local hasKeys = modification.hasKeys
if hasKeys then
local modifier = modification.modifier
if modifier and modifier.effect then
newMethods[dataIndex][method] = modifier.effect(dataValue)
end
end
if originalMethodRef then
local modifier = modification.modifier
newMethods[dataIndex] = newMethods[dataIndex] or {}
local effect
if modifier then
if modifier.executeFunc then
effect = modifier.effect(originalMethodRef, originalMethod)
else
effect = function(...)
return modifier.effect(originalMethodRef, ...)
end
end
else
effect = originalMethodRef
end
newMethods[dataIndex][method] = effect
end
end
end
local function processTable(tableToProcess, overrides)
for _, value in ipairs(tableToProcess) do
for method, modification in pairs(overrides) do
if type(modification) == 'table' and not modification.originalMethod then
processTable(value[method], modification)
else
modifyMethods(tableToProcess, method, modification)
end
end
end
end
processTable(playerTable, functionsOverride)
return newMethods
end
local function UUID(num)
num = type(num) == 'number' and num or 5
local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
local uuid = string.gsub(template, '[xy]', function(c)
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
return string.format('%x', v)
end)
local timestamp = os.time()
local uuidWithTime = string.format("%s-%s", uuid, timestamp)
if num > 0 and num <= #uuidWithTime then
uuidWithTime = string.sub(uuidWithTime, 1, num)
end
return uuidWithTime
end
local context = IsDuplicityVersion() and 'server' or 'client'
--https://github.com/overextended/ox_lib/blob/master/imports/waitFor/shared.lua
function Utils.waitFor(cb, errMessage, timeout)
local value = cb()
if value ~= nil then return value end
if timeout or timeout == nil then
if type(timeout) ~= 'number' then timeout = 1000 end
end
local start = timeout and GetGameTimer()
while value == nil do
Wait(0)
local elapsed = timeout and GetGameTimer() - start
if elapsed and elapsed > timeout then
return error(('%s (waited %.1fms)'):format(errMessage or 'failed to resolve callback', elapsed), 2)
end
value = cb()
end
return value
end
--https://github.com/overextended/ox_lib/blob/master/imports/callback/client.lua - thanks
--https://github.com/overextended/ox_lib/blob/master/imports/callback/server.lua
if context == 'client' then
local pendingCallbacks = {}
local timers = {}
local cbEvent = '__ox_cb_%s'
local resource = GetCurrentResourceName()
RegisterNetEvent(cbEvent:format(resource), function(key, ...)
local cb = pendingCallbacks[key]
pendingCallbacks[key] = nil
return cb and cb(...)
end)
local function eventTimer(event, delay)
if delay and type(delay) == 'number' and delay > 0 then
local time = GetGameTimer()
if (timers[event] or 0) > time then
return false
end
timers[event] = time + delay
end
return true
end
local function triggerServerCallback(_, event, delay, cb, ...)
if not eventTimer(event, delay) then return end
local key
repeat
key = ('%s:%s'):format(event, math.random(0, 100000))
until not pendingCallbacks[key]
TriggerServerEvent(cbEvent:format(event), resource, key, ...)
---@type promise | false
local promise = not cb and promise.new()
pendingCallbacks[key] = function(response, ...)
response = { response, ... }
if promise then
return promise:resolve(response)
end
if cb then
cb(table.unpack(response))
end
end
if promise then
SetTimeout(300000, function() promise:reject(("callback event '%s' timed out"):format(key)) end)
return table.unpack(Citizen.Await(promise))
end
end
function Utils.await(event, delay, ...)
return triggerServerCallback(nil, event, delay, false, ...)
end
else
local cbEvent = '__ox_cb_%s'
local function callbackResponse(success, result, ...)
if not success then
if result then
return print(('^1SCRIPT ERROR: %s^0\n%s'):format(result,
Citizen.InvokeNative(`FORMAT_STACK_TRACE` & 0xFFFFFFFF, nil, 0, Citizen.ResultAsString()) or ''))
end
return false
end
return result, ...
end
function Utils.register(name, cb)
RegisterNetEvent(cbEvent:format(name), function(resource, key, ...)
TriggerClientEvent(cbEvent:format(resource), source, key, callbackResponse(pcall(cb, source, ...)))
end)
end
end
local function table_merge(t1, t2, addDuplicateNumbers)
if addDuplicateNumbers == nil then addDuplicateNumbers = true end
for k, v in pairs(t2) do
local type1 = type(t1[k])
local type2 = type(v)
if type1 == 'table' and type2 == 'table' then
table_merge(t1[k], v, addDuplicateNumbers)
elseif addDuplicateNumbers and (type1 == 'number' and type2 == 'number') then
t1[k] += v
else
t1[k] = v
end
end
return t1
end
exports('UUID', UUID)
Utils.table_merge = table_merge
Utils.retreiveStringIndexedData = retreiveStringIndexedData
Utils.retreiveExportsData = retreiveExportsData
Utils.retreiveNumberIndexedData = retreiveNumberIndexedData
Utils.UUID = UUID
return Utils