From 17da7688f02e1f85369c4867c7431d7e76f08111 Mon Sep 17 00:00:00 2001 From: Kakarot Date: Mon, 20 Apr 2026 18:58:05 -0500 Subject: [PATCH] Run paychecks in async thread and fix society check Move the paycheck loop into a CreateThread to avoid blocking the main thread and prevent paychecks from stopping. Add a nil guard for Player and keep existing payment lookup logic. Tighten society payroll logic: check the society account balance before removing funds and still pay employees if the account is zero, avoiding duplicate AddMoney/Notify branches. Add a short Wait(50) between player iterations to yield. Preserve the existing SetTimeout scheduling for the next paycheck run. --- server/functions.lua | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 47a69c3..439b714 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -405,31 +405,35 @@ function PaycheckInterval() SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckInterval) -- Prevent paychecks from stopping forever once 0 players return end - for _, Player in pairs(QBCore.Players) do - if not Player then return end - 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 - if account < payment then - TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('error.company_too_poor'), 'error') + CreateThread(function() + 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 + 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 + if account < payment then + 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 })) + end + else + Player.Functions.AddMoney('bank', payment, 'paycheck') + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment })) + end 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 })) end - else - Player.Functions.AddMoney('bank', payment, '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 })) + Wait(50) end end - end + end) SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckInterval) end