From 8ab5f76bdfa6f917635e9817bf8ea2f9f85d1f77 Mon Sep 17 00:00:00 2001 From: Zerio Date: Tue, 7 Jan 2025 07:20:53 +0100 Subject: [PATCH] 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 f1ead70..e3919ad 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 7e4ac0e..1129c8b 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 d01b93c..77dc265 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