1
0
Fork 0
forked from Simnation/Main
Main/resources/[standalone]/ps-multijob/server/sv_main.lua
2025-07-01 06:06:36 +02:00

296 lines
No EOL
10 KiB
Lua

local QBCore = exports['qb-core']:GetCoreObject()
local function GetJobs(citizenid)
local p = promise.new()
MySQL.Async.fetchAll("SELECT jobdata FROM multijobs WHERE citizenid = @citizenid",{
["@citizenid"] = citizenid
}, function(jobs)
if jobs[1] and jobs ~= "[]" then
jobs = json.decode(jobs[1].jobdata)
else
local Player = QBCore.Functions.GetOfflinePlayerByCitizenId(citizenid)
local temp = {}
if not Config.IgnoredJobs[Player.PlayerData.job.name] then
temp[Player.PlayerData.job.name] = Player.PlayerData.job.grade.level
MySQL.insert('INSERT INTO multijobs (citizenid, jobdata) VALUES (:citizenid, :jobdata) ON DUPLICATE KEY UPDATE jobdata = :jobdata', {
citizenid = citizenid,
jobdata = json.encode(temp),
})
end
jobs = temp
end
p:resolve(jobs)
end)
return Citizen.Await(p)
end
exports("GetJobs", GetJobs)
local function AddJob(citizenid, job, grade)
local jobs = GetJobs(citizenid)
for ignored in pairs(Config.IgnoredJobs) do
if jobs[ignored] then
jobs[ignored] = nil
end
end
jobs[job] = grade
MySQL.insert('INSERT INTO multijobs (citizenid, jobdata) VALUES (:citizenid, :jobdata) ON DUPLICATE KEY UPDATE jobdata = :jobdata', {
citizenid = citizenid,
jobdata = json.encode(jobs),
})
end
exports("AddJob", AddJob)
local function UpdatePlayerJob(Player, job, grade)
if Player.PlayerData.source ~= nil then
Player.Functions.SetJob(job,grade)
else -- player is offline
local sharedJobData = QBCore.Shared.Jobs[job]
if sharedJobData == nil then return end
local sharedGradeData = sharedJobData.grades[grade]
if sharedGradeData == nil then return end
local isBoss = false
if sharedGradeData.isboss then isBoss = true end
MySQL.update.await("update players set job = @jobData where citizenid = @citizenid", {
jobData = json.encode({
label = sharedJobData.label,
name = job,
isboss = isBoss,
onduty = sharedJobData.defaultDuty,
payment = sharedGradeData.payment,
grade = {
name = sharedGradeData.name,
level = grade,
},
}),
citizenid = Player.PlayerData.citizenid
})
end
end
local function UpdateJobRank(citizenid, job, grade)
local Player = QBCore.Functions.GetOfflinePlayerByCitizenId(citizenid)
if Player == nil then
return
end
local jobs = GetJobs(citizenid)
if jobs[job] == nil then
return
end
jobs[job] = grade
MySQL.update.await("update multijobs set jobdata = :jobdata where citizenid = :citizenid", {
citizenid = citizenid,
jobdata = json.encode(jobs),
})
-- if the current job matches, then update
if Player.PlayerData.job.name == job then
UpdatePlayerJob(Player, job, grade)
end
end
exports("UpdateJobRank", UpdateJobRank)
local function RemoveJob(citizenid, job)
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)
if Player == nil then
Player = QBCore.Functions.GetOfflinePlayerByCitizenId(citizenid)
end
if Player == nil then return end
local jobs = GetJobs(citizenid)
jobs[job] = nil
-- Since we removed a job, put player in a new job
local foundNewJob = false
if Player.PlayerData.job.name == job then
for k,v in pairs(jobs) do
UpdatePlayerJob(Player, k,v)
foundNewJob = true
break
end
end
if not foundNewJob then
UpdatePlayerJob(Player, "unemployed", 0)
end
MySQL.insert('INSERT INTO multijobs (citizenid, jobdata) VALUES (:citizenid, :jobdata) ON DUPLICATE KEY UPDATE jobdata = :jobdata', {
citizenid = citizenid,
jobdata = json.encode(jobs),
})
end
exports("RemoveJob", RemoveJob)
QBCore.Commands.Add('removejob', 'Remove Multi Job (Admin Only)', { { name = 'id', help = 'ID of player' }, { name = 'job', help = 'Job Name' } }, false, function(source, args)
local source = source
if source ~= 0 then
if args[1] then
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
if Player then
if args[2] then
RemoveJob(Player.PlayerData.citizenid, args[2])
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
end, 'admin')
QBCore.Commands.Add('addjob', 'Add Multi Job (Admin Only)', { { name = 'id', help = 'ID of player' }, { name = 'job', help = 'Job Name' }, { name = 'grade', help = 'Job Grade' } }, false, function(source, args)
local source = source
if source ~= 0 then
if args[1] then
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
if Player then
if args[2]and args[3] then
AddJob(Player.PlayerData.citizenid, args[2], args[3])
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
else
TriggerClientEvent("QBCore:Notify", source, "Wrong usage!")
end
end, 'admin')
QBCore.Functions.CreateCallback("ps-multijob:getJobs", function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
local jobs = GetJobs(Player.PlayerData.citizenid)
local multijobs = {}
local whitelistedjobs = {}
local civjobs = {}
local active = {}
local getjobs = {}
local Players = QBCore.Functions.GetPlayers()
local invalidJobs = {} -- Track invalid jobs for potential cleanup
for i = 1, #Players, 1 do
local xPlayer = QBCore.Functions.GetPlayer(Players[i])
active[xPlayer.PlayerData.job.name] = 0
if active[xPlayer.PlayerData.job.name] and xPlayer.PlayerData.job.onduty then
active[xPlayer.PlayerData.job.name] = active[xPlayer.PlayerData.job.name] + 1
end
end
for job, grade in pairs(jobs) do
if QBCore.Shared.Jobs[job] == nil then
-- Instead of just printing, add to invalid jobs list
-- but don't immediately remove - could be loaded later by jobs_creator
invalidJobs[job] = true
-- Still print for debugging
print("Warning: Job '" .. job .. "' not found in QBCore.Shared.Jobs. It may be loaded later by jobs_creator.")
else
local online = active[job] or 0
getjobs = {
name = job,
grade = grade,
description = Config.Descriptions[job],
icon = Config.FontAwesomeIcons[job],
label = QBCore.Shared.Jobs[job].label,
gradeLabel = QBCore.Shared.Jobs[job].grades[tostring(grade)].name,
salary = QBCore.Shared.Jobs[job].grades[tostring(grade)].payment,
active = online,
}
if Config.WhitelistJobs[job] then
whitelistedjobs[#whitelistedjobs+1] = getjobs
else
civjobs[#civjobs+1] = getjobs
end
end
end
multijobs = {
whitelist = whitelistedjobs,
civilian = civjobs,
}
cb(multijobs)
end)
RegisterNetEvent("ps-multijob:changeJob",function(cjob, cgrade)
local source = source
local Player = QBCore.Functions.GetPlayer(source)
if cjob == "unemployed" and cgrade == 0 then
Player.Functions.SetJob(cjob, cgrade)
return
end
local jobs = GetJobs(Player.PlayerData.citizenid)
for job, grade in pairs(jobs) do
if cjob == job and cgrade == grade then
Player.Functions.SetJob(job, grade)
end
end
end)
RegisterNetEvent("ps-multijob:removeJob",function(job, grade)
local source = source
local Player = QBCore.Functions.GetPlayer(source)
RemoveJob(Player.PlayerData.citizenid, job)
end)
-- QBCORE EVENTS
RegisterNetEvent('ps-multijob:server:removeJob', function(targetCitizenId)
MySQL.Async.execute('DELETE FROM multijobs WHERE citizenid = ?', { targetCitizenId }, function(affectedRows)
if affectedRows > 0 then
print('Removed job: ' .. targetCitizenId)
else
print('Cannot remove job: ' .. targetCitizenId)
end
end)
end)
RegisterNetEvent('QBCore:Server:OnJobUpdate', function(source, newJob)
local source = source
local Player = QBCore.Functions.GetPlayer(source)
local jobs = GetJobs(Player.PlayerData.citizenid)
local amount = 0
local setjob = newJob
for k,v in pairs(jobs) do
amount = amount + 1
end
local maxJobs = Config.MaxJobs
if QBCore.Functions.HasPermission(source, "admin") then
maxJobs = math.huge
end
if amount < maxJobs and not Config.IgnoredJobs[setjob.name] then
local foundOldJob = jobs[setjob.name]
if not foundOldJob or foundOldJob ~= setjob.grade.level then
AddJob(Player.PlayerData.citizenid, setjob.name, setjob.grade.level)
end
end
end)
RegisterNetEvent('QBCore:Server:OnJobUpdate', function(source, newJob)
-- Existing code...
end)
-- Add the new event listener here, at the bottom of the file
RegisterNetEvent("jobs_creator:injectJobs", function(jobs)
-- This will run when jobs are injected, allowing ps-multijob to know about new jobs
print("ps-multijob: Jobs have been updated by jobs_creator")
-- You could potentially refresh any cached job data here
end)