forked from Simnation/Main
290 lines
9.1 KiB
Lua
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
|