From dc8fbf04e9db19dbf44eeb4321836d2012a68c2a Mon Sep 17 00:00:00 2001 From: Zerio Date: Mon, 6 Jan 2025 21:31:23 +0100 Subject: [PATCH 1/5] feat: use promises in callbacks + cleanup --- client/events.lua | 11 +++++++++-- client/functions.lua | 33 +++++++++++++++++++++++++++------ server/events.lua | 14 +++++++++++--- server/functions.lua | 42 +++++++++++++++++++++++++++++------------- 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/client/events.lua b/client/events.lua index c172c16d3..67755aa25 100644 --- a/client/events.lua +++ b/client/events.lua @@ -208,7 +208,9 @@ end) -- Client Callback RegisterNetEvent('QBCore:Client:TriggerClientCallback', function(name, ...) - QBCore.Functions.TriggerClientCallback(name, function(...) + if not QBCore.ClientCallbacks[name] then return end + + QBCore.ClientCallbacks[name](function(...) TriggerServerEvent('QBCore:Server:TriggerClientCallback', name, ...) end, ...) end) @@ -216,7 +218,12 @@ end) -- Server Callback RegisterNetEvent('QBCore:Client:TriggerCallback', function(name, ...) if QBCore.ServerCallbacks[name] then - QBCore.ServerCallbacks[name](...) + QBCore.ServerCallbacks[name].promise:resolve(...) + + if QBCore.ServerCallbacks[name].callback then + QBCore.ServerCallbacks[name].callback(...) + end + QBCore.ServerCallbacks[name] = nil end end) diff --git a/client/functions.lua b/client/functions.lua index 45034a573..1d3da2398 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -6,14 +6,35 @@ function QBCore.Functions.CreateClientCallback(name, cb) QBCore.ClientCallbacks[name] = cb end -function QBCore.Functions.TriggerClientCallback(name, cb, ...) - if not QBCore.ClientCallbacks[name] then return end - QBCore.ClientCallbacks[name](cb, ...) -end +function QBCore.Functions.TriggerCallback(name, ...) + local cb = nil + local args = { ... } + + if type(args[1]) == "function" then + cb = args[1] + table.remove(args, 1) + elseif type(args[1]) == "table" then + local _, err = pcall(function() + args[1]["__cfx_functionReferenc"] = args[1]["__cfx_functionReferenc"] + end) + + if err and string.find(err, "Cannot index a funcref") then + cb = args[1] + table.remove(args, 1) + end + end + + QBCore.ServerCallbacks[name] = { + callback = cb, + promise = promise.new() + } -function QBCore.Functions.TriggerCallback(name, cb, ...) - QBCore.ServerCallbacks[name] = cb TriggerServerEvent('QBCore:Server:TriggerCallback', name, ...) + + if cb == nil then + Citizen.Await(QBCore.ServerCallbacks[name].promise) + return QBCore.ServerCallbacks[name].promise.value + end end function QBCore.Debug(resource, obj, depth) diff --git a/server/events.lua b/server/events.lua index 9311e80e8..00b0fa5a9 100644 --- a/server/events.lua +++ b/server/events.lua @@ -32,7 +32,7 @@ local databaseConnected, bansTableExists = readyFunction == nil, readyFunction = if readyFunction ~= nil then MySQL.ready(function() databaseConnected = true - + local DatabaseInfo = QBCore.Functions.GetDatabaseInfo() if not DatabaseInfo or not DatabaseInfo.exists then return end @@ -125,15 +125,23 @@ end) -- Client Callback RegisterNetEvent('QBCore:Server:TriggerClientCallback', function(name, ...) if QBCore.ClientCallbacks[name] then - QBCore.ClientCallbacks[name](...) + QBCore.ClientCallbacks[name].promise:resolve(...) + + if QBCore.ClientCallbacks[name].callback then + QBCore.ClientCallbacks[name].callback(...) + end + QBCore.ClientCallbacks[name] = nil end end) -- Server Callback RegisterNetEvent('QBCore:Server:TriggerCallback', function(name, ...) + if not QBCore.ServerCallbacks[name] then return end + local src = source - QBCore.Functions.TriggerCallback(name, src, function(...) + + QBCore.ServerCallbacks[name](src, function(...) TriggerClientEvent('QBCore:Client:TriggerCallback', src, name, ...) end, ...) end) diff --git a/server/functions.lua b/server/functions.lua index 9cfe78e76..74b25bfe4 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -434,9 +434,35 @@ end ---@param source any ---@param cb function ---@param ... any -function QBCore.Functions.TriggerClientCallback(name, source, cb, ...) - QBCore.ClientCallbacks[name] = cb +function QBCore.Functions.TriggerClientCallback(name, source, ...) + local cb = nil + local args = { ... } + + if type(args[1]) == "function" then + cb = args[1] + table.remove(args, 1) + elseif type(args[1]) == "table" then + local _, err = pcall(function() + args[1]["__cfx_functionReferenc"] = args[1]["__cfx_functionReferenc"] + end) + + if err and string.find(err, "Cannot index a funcref") then + cb = args[1] + table.remove(args, 1) + end + end + + QBCore.ClientCallbacks[name] = { + callback = cb, + promise = promise.new() + } + TriggerClientEvent('QBCore:Client:TriggerClientCallback', source, name, ...) + + if cb == nil then + Citizen.Await(QBCore.ClientCallbacks[name].promise) + return QBCore.ClientCallbacks[name].promise.value + end end ---Create Server Callback @@ -446,16 +472,6 @@ function QBCore.Functions.CreateCallback(name, cb) QBCore.ServerCallbacks[name] = cb end ----Trigger Serv er Callback ----@param name string ----@param source any ----@param cb function ----@param ... any -function QBCore.Functions.TriggerCallback(name, source, cb, ...) - if not QBCore.ServerCallbacks[name] then return end - QBCore.ServerCallbacks[name](source, cb, ...) -end - -- Items ---Create a usable item @@ -475,7 +491,7 @@ function QBCore.Functions.CreateUseableItem(item, data) elseif type(data) == "function" then rawFunc = data end - + if rawFunc then QBCore.UsableItems[item] = { func = rawFunc, From 8660c98d4957e868fe37e18d0dcb325aa575de56 Mon Sep 17 00:00:00 2001 From: Zerio Date: Mon, 6 Jan 2025 21:41:53 +0100 Subject: [PATCH 2/5] fix: wrong args passed --- client/functions.lua | 2 +- server/functions.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 1d3da2398..f1ead7010 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -29,7 +29,7 @@ function QBCore.Functions.TriggerCallback(name, ...) promise = promise.new() } - TriggerServerEvent('QBCore:Server:TriggerCallback', name, ...) + TriggerServerEvent('QBCore:Server:TriggerCallback', name, table.unpack(args)) if cb == nil then Citizen.Await(QBCore.ServerCallbacks[name].promise) diff --git a/server/functions.lua b/server/functions.lua index 74b25bfe4..7e4ac0ebb 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -457,7 +457,7 @@ function QBCore.Functions.TriggerClientCallback(name, source, ...) promise = promise.new() } - TriggerClientEvent('QBCore:Client:TriggerClientCallback', source, name, ...) + TriggerClientEvent('QBCore:Client:TriggerClientCallback', source, name, table.unpack(args)) if cb == nil then Citizen.Await(QBCore.ClientCallbacks[name].promise) From 8ab5f76bdfa6f917635e9817bf8ea2f9f85d1f77 Mon Sep 17 00:00:00 2001 From: Zerio Date: Tue, 7 Jan 2025 07:20:53 +0100 Subject: [PATCH 3/5] feat: simply funcref check --- client/functions.lua | 37 +++++++++++++++++++------------------ server/functions.lua | 40 ++++++++++++++++++++++------------------ shared/main.lua | 13 +++++++++++++ 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index f1ead7010..e3919ad0e 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -10,18 +10,9 @@ function QBCore.Functions.TriggerCallback(name, ...) local cb = nil local args = { ... } - if type(args[1]) == "function" then + if QBCore.Shared.IsFunction(args[1]) then cb = args[1] table.remove(args, 1) - elseif type(args[1]) == "table" then - local _, err = pcall(function() - args[1]["__cfx_functionReferenc"] = args[1]["__cfx_functionReferenc"] - end) - - if err and string.find(err, "Cannot index a funcref") then - cb = args[1] - table.remove(args, 1) - end end QBCore.ServerCallbacks[name] = { @@ -191,8 +182,12 @@ function QBCore.Functions.Notify(text, texttype, length, icon) SendNUIMessage(message) end -function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel) - if GetResourceState('progressbar') ~= 'started' then error('progressbar needs to be started in order for QBCore.Functions.Progressbar to work') end +function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, + propTwo, onFinish, onCancel) + if GetResourceState('progressbar') ~= 'started' then + error( + 'progressbar needs to be started in order for QBCore.Functions.Progressbar to work') + end exports['progressbar']:Progress({ name = name:lower(), duration = duration, @@ -977,7 +972,8 @@ function QBCore.Functions.StartParticleAtCoord(dict, ptName, looped, coords, rot SetPtfxAssetNextCall(dict) local particleHandle if looped then - particleHandle = StartParticleFxLoopedAtCoord(ptName, coords.x, coords.y, coords.z, rot.x, rot.y, rot.z, scale or 1.0) + particleHandle = StartParticleFxLoopedAtCoord(ptName, coords.x, coords.y, coords.z, rot.x, rot.y, rot.z, + scale or 1.0) if color then SetParticleFxLoopedColour(particleHandle, color.r, color.g, color.b, false) end @@ -996,7 +992,8 @@ function QBCore.Functions.StartParticleAtCoord(dict, ptName, looped, coords, rot return particleHandle end -function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bone, offset, rot, scale, alpha, color, evolution, duration) +function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bone, offset, rot, scale, alpha, color, + evolution, duration) QBCore.Functions.LoadParticleDictionary(dict) UseParticleFxAssetNextCall(dict) local particleHandle, boneID @@ -1007,9 +1004,11 @@ function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bo end if looped then if bone then - particleHandle = StartParticleFxLoopedOnEntityBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneID, scale) + particleHandle = StartParticleFxLoopedOnEntityBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot + .y, rot.z, boneID, scale) else - particleHandle = StartParticleFxLoopedOnEntity(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, scale) + particleHandle = StartParticleFxLoopedOnEntity(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, + rot.z, scale) end if evolution then SetParticleFxLoopedEvolution(particleHandle, evolution.name, evolution.amount, false) @@ -1028,7 +1027,8 @@ function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bo SetParticleFxNonLoopedColour(color.r, color.g, color.b) end if bone then - StartParticleFxNonLoopedOnPedBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneID, scale) + StartParticleFxNonLoopedOnPedBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneID, + scale) else StartParticleFxNonLoopedOnEntity(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, scale) end @@ -1092,7 +1092,8 @@ end function QBCore.Functions.GetGroundHash(entity) local coords = GetEntityCoords(entity) - local num = StartShapeTestCapsule(coords.x, coords.y, coords.z + 4, coords.x, coords.y, coords.z - 2.0, 1, 1, entity, 7) + local num = StartShapeTestCapsule(coords.x, coords.y, coords.z + 4, coords.x, coords.y, coords.z - 2.0, 1, 1, entity, + 7) local retval, success, endCoords, surfaceNormal, materialHash, entityHit = GetShapeTestResultEx(num) return materialHash, entityHit, surfaceNormal, endCoords, success, retval end diff --git a/server/functions.lua b/server/functions.lua index 7e4ac0ebb..1129c8b0d 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -399,26 +399,32 @@ function PaycheckInterval() if next(QBCore.Players) then for _, Player in pairs(QBCore.Players) do if Player then - local payment = QBShared.Jobs[Player.PlayerData.job.name]['grades'][tostring(Player.PlayerData.job.grade.level)].payment + local payment = QBShared.Jobs[Player.PlayerData.job.name]['grades'] + [tostring(Player.PlayerData.job.grade.level)].payment if not payment then payment = Player.PlayerData.job.payment end if Player.PlayerData.job and payment > 0 and (QBShared.Jobs[Player.PlayerData.job.name].offDutyPay or Player.PlayerData.job.onduty) then if QBCore.Config.Money.PayCheckSociety then local account = exports['qb-banking']:GetAccountBalance(Player.PlayerData.job.name) if account ~= 0 then -- Checks if player is employed by a society if account < payment then -- Checks if company has enough money to pay society - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('error.company_too_poor'), 'error') + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, + Lang:t('error.company_too_poor'), 'error') else Player.Functions.AddMoney('bank', payment, 'paycheck') - exports['qb-banking']:RemoveMoney(Player.PlayerData.job.name, payment, 'Employee Paycheck') - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) + exports['qb-banking']:RemoveMoney(Player.PlayerData.job.name, payment, + 'Employee Paycheck') + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, + Lang:t('info.received_paycheck', { value = payment })) end else Player.Functions.AddMoney('bank', payment, 'paycheck') - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, + Lang:t('info.received_paycheck', { value = payment })) end else Player.Functions.AddMoney('bank', payment, 'paycheck') - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, + Lang:t('info.received_paycheck', { value = payment })) end end end @@ -438,20 +444,12 @@ function QBCore.Functions.TriggerClientCallback(name, source, ...) local cb = nil local args = { ... } - if type(args[1]) == "function" then + if QBCore.Shared.IsFunction(args[1]) then cb = args[1] table.remove(args, 1) - elseif type(args[1]) == "table" then - local _, err = pcall(function() - args[1]["__cfx_functionReferenc"] = args[1]["__cfx_functionReferenc"] - end) - - if err and string.find(err, "Cannot index a funcref") then - cb = args[1] - table.remove(args, 1) - end end + QBCore.ClientCallbacks[name] = { callback = cb, promise = promise.new() @@ -651,7 +649,12 @@ function QBCore.Functions.IsPlayerBanned(source) if not result then return false end if os.time() < result.expire then local timeTable = os.date('*t', tonumber(result.expire)) - return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n' + return true, + 'You have been banned from the server:\n' .. + result.reason .. + '\nYour ban expires ' .. + timeTable.day .. + '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n' else MySQL.query('DELETE FROM bans WHERE id = ?', { result.id }) end @@ -732,7 +735,8 @@ function QBCore.Functions.PrepForSQL(source, data, pattern) local player = QBCore.Functions.GetPlayer(src) local result = string.match(data, pattern) if not result or string.len(result) ~= string.len(data) then - TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'SQL Exploit Attempted', 'red', string.format('%s attempted to exploit SQL!', player.PlayerData.license)) + TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'SQL Exploit Attempted', 'red', + string.format('%s attempted to exploit SQL!', player.PlayerData.license)) return false end return true diff --git a/shared/main.lua b/shared/main.lua index d01b93ccb..77dc265f6 100644 --- a/shared/main.lua +++ b/shared/main.lua @@ -68,6 +68,19 @@ function QBShared.ChangeVehicleExtra(vehicle, extra, enable) end end +function QBShared.IsFunction(value) + if type(value) == 'table' then + local success = pcall(function() + -- we just need to check if the table is indexable or not, this will simply return the error "cannot index a funcref" + return value.__cfx_functionReference + end) + + return success + end + + return type(value) == 'function' +end + function QBShared.SetDefaultVehicleExtras(vehicle, config) -- Clear Extras for i = 1, 20 do From d08d7bbebaa3c7741f52d52a2244d74d134d2096 Mon Sep 17 00:00:00 2001 From: Zerio Date: Tue, 7 Jan 2025 07:21:50 +0100 Subject: [PATCH 4/5] chore: remove accidental automatic format changes --- client/functions.lua | 26 ++++++++------------------ server/functions.lua | 29 ++++++++--------------------- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index e3919ad0e..8c03183e0 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -182,12 +182,8 @@ function QBCore.Functions.Notify(text, texttype, length, icon) SendNUIMessage(message) end -function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, - propTwo, onFinish, onCancel) - if GetResourceState('progressbar') ~= 'started' then - error( - 'progressbar needs to be started in order for QBCore.Functions.Progressbar to work') - end +function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel) + if GetResourceState('progressbar') ~= 'started' then error('progressbar needs to be started in order for QBCore.Functions.Progressbar to work') end exports['progressbar']:Progress({ name = name:lower(), duration = duration, @@ -972,8 +968,7 @@ function QBCore.Functions.StartParticleAtCoord(dict, ptName, looped, coords, rot SetPtfxAssetNextCall(dict) local particleHandle if looped then - particleHandle = StartParticleFxLoopedAtCoord(ptName, coords.x, coords.y, coords.z, rot.x, rot.y, rot.z, - scale or 1.0) + particleHandle = StartParticleFxLoopedAtCoord(ptName, coords.x, coords.y, coords.z, rot.x, rot.y, rot.z, scale or 1.0) if color then SetParticleFxLoopedColour(particleHandle, color.r, color.g, color.b, false) end @@ -992,8 +987,7 @@ function QBCore.Functions.StartParticleAtCoord(dict, ptName, looped, coords, rot return particleHandle end -function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bone, offset, rot, scale, alpha, color, - evolution, duration) +function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bone, offset, rot, scale, alpha, color, evolution, duration) QBCore.Functions.LoadParticleDictionary(dict) UseParticleFxAssetNextCall(dict) local particleHandle, boneID @@ -1004,11 +998,9 @@ function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bo end if looped then if bone then - particleHandle = StartParticleFxLoopedOnEntityBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot - .y, rot.z, boneID, scale) + particleHandle = StartParticleFxLoopedOnEntityBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneID, scale) else - particleHandle = StartParticleFxLoopedOnEntity(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, - rot.z, scale) + particleHandle = StartParticleFxLoopedOnEntity(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, scale) end if evolution then SetParticleFxLoopedEvolution(particleHandle, evolution.name, evolution.amount, false) @@ -1027,8 +1019,7 @@ function QBCore.Functions.StartParticleOnEntity(dict, ptName, looped, entity, bo SetParticleFxNonLoopedColour(color.r, color.g, color.b) end if bone then - StartParticleFxNonLoopedOnPedBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneID, - scale) + StartParticleFxNonLoopedOnPedBone(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneID, scale) else StartParticleFxNonLoopedOnEntity(ptName, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, scale) end @@ -1092,8 +1083,7 @@ end function QBCore.Functions.GetGroundHash(entity) local coords = GetEntityCoords(entity) - local num = StartShapeTestCapsule(coords.x, coords.y, coords.z + 4, coords.x, coords.y, coords.z - 2.0, 1, 1, entity, - 7) + local num = StartShapeTestCapsule(coords.x, coords.y, coords.z + 4, coords.x, coords.y, coords.z - 2.0, 1, 1, entity, 7) local retval, success, endCoords, surfaceNormal, materialHash, entityHit = GetShapeTestResultEx(num) return materialHash, entityHit, surfaceNormal, endCoords, success, retval end diff --git a/server/functions.lua b/server/functions.lua index 1129c8b0d..d9bfc57a6 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -399,32 +399,26 @@ function PaycheckInterval() if next(QBCore.Players) then for _, Player in pairs(QBCore.Players) do if Player then - local payment = QBShared.Jobs[Player.PlayerData.job.name]['grades'] - [tostring(Player.PlayerData.job.grade.level)].payment + local payment = QBShared.Jobs[Player.PlayerData.job.name]['grades'][tostring(Player.PlayerData.job.grade.level)].payment if not payment then payment = Player.PlayerData.job.payment end if Player.PlayerData.job and payment > 0 and (QBShared.Jobs[Player.PlayerData.job.name].offDutyPay or Player.PlayerData.job.onduty) then if QBCore.Config.Money.PayCheckSociety then local account = exports['qb-banking']:GetAccountBalance(Player.PlayerData.job.name) if account ~= 0 then -- Checks if player is employed by a society if account < payment then -- Checks if company has enough money to pay society - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, - Lang:t('error.company_too_poor'), 'error') + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('error.company_too_poor'), 'error') else Player.Functions.AddMoney('bank', payment, 'paycheck') - exports['qb-banking']:RemoveMoney(Player.PlayerData.job.name, payment, - 'Employee Paycheck') - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, - Lang:t('info.received_paycheck', { value = payment })) + exports['qb-banking']:RemoveMoney(Player.PlayerData.job.name, payment, 'Employee Paycheck') + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) end else Player.Functions.AddMoney('bank', payment, 'paycheck') - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, - Lang:t('info.received_paycheck', { value = payment })) + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) end else Player.Functions.AddMoney('bank', payment, 'paycheck') - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, - Lang:t('info.received_paycheck', { value = payment })) + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) end end end @@ -449,7 +443,6 @@ function QBCore.Functions.TriggerClientCallback(name, source, ...) table.remove(args, 1) end - QBCore.ClientCallbacks[name] = { callback = cb, promise = promise.new() @@ -649,12 +642,7 @@ function QBCore.Functions.IsPlayerBanned(source) if not result then return false end if os.time() < result.expire then local timeTable = os.date('*t', tonumber(result.expire)) - return true, - 'You have been banned from the server:\n' .. - result.reason .. - '\nYour ban expires ' .. - timeTable.day .. - '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n' + return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n' else MySQL.query('DELETE FROM bans WHERE id = ?', { result.id }) end @@ -735,8 +723,7 @@ function QBCore.Functions.PrepForSQL(source, data, pattern) local player = QBCore.Functions.GetPlayer(src) local result = string.match(data, pattern) if not result or string.len(result) ~= string.len(data) then - TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'SQL Exploit Attempted', 'red', - string.format('%s attempted to exploit SQL!', player.PlayerData.license)) + TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'SQL Exploit Attempted', 'red', string.format('%s attempted to exploit SQL!', player.PlayerData.license)) return false end return true From 369f15bd4c1cd6643019d7a74fc60e4338799ee2 Mon Sep 17 00:00:00 2001 From: Zerio Date: Tue, 7 Jan 2025 07:40:43 +0100 Subject: [PATCH 5/5] feat: further simplify of funcref check --- shared/main.lua | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/shared/main.lua b/shared/main.lua index 77dc265f6..2863b354d 100644 --- a/shared/main.lua +++ b/shared/main.lua @@ -70,12 +70,7 @@ end function QBShared.IsFunction(value) if type(value) == 'table' then - local success = pcall(function() - -- we just need to check if the table is indexable or not, this will simply return the error "cannot index a funcref" - return value.__cfx_functionReference - end) - - return success + return value.__cfx_functionReference ~= nil and type(value.__cfx_functionReference) == "string" end return type(value) == 'function'