local QBCore, ESX = nil, nil local currentFramework = Config.Framework if currentFramework == "qb" or currentFramework == "qbox" then local success, result = pcall(function() return exports['qb-core']:GetCoreObject() end) if success then QBCore = result end elseif currentFramework == "esx" then local success, result = pcall(function() return exports['es_extended']:getSharedObject() end) if success then ESX = result end end AllFrameworkJobs = AllFrameworkJobs or {} local FrameworkHandlers = { ['qb'] = { table = 'players', identifier = 'citizenid', jobColumn = 'job', isJson = true, getJobs = function(core) return core and core.Shared and core.Shared.Jobs end, defaultJob = { type = "none", payment = 10, grade = { name = "Freelancer", level = 0 }, label = 'Civilian', name = "unemployed", onduty = true } }, ['qbox'] = { table = 'players', identifier = 'citizenid', jobColumn = 'job', isJson = true, getJobs = function(core) return core and core.Shared and core.Shared.Jobs end, defaultJob = { type = "none", payment = 10, grade = { name = "Freelancer", level = 0 }, label = 'Civilian', name = "unemployed", onduty = true } }, ['esx'] = { table = 'users', identifier = 'identifier', jobColumn = 'job', gradeColumn = 'job_grade', isJson = false, getJobs = function(core) return core and core.Jobs end, defaultJob = 'unemployed', defaultGrade = 0 }, ['standalone'] = { } } local handler = FrameworkHandlers[currentFramework] or {} local function tableLength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end local function getGradeInfo(jobName, gradeLevel) local gradeKey = tostring(gradeLevel) local job = AllFrameworkJobs[jobName] if job and job.grades and job.grades[gradeKey] then local gradeData = job.grades[gradeKey] return { level = gradeLevel, name = gradeData.name, payment = gradeData.payment, isboss = gradeData.isboss } end return { level = gradeLevel, name = "Grade " .. gradeLevel, payment = 5000 + (gradeLevel * 2500), isboss = gradeLevel >= 6 } end local function PopulateAllFrameworkJobs() AllFrameworkJobs = {} local jobsData = nil if handler.getJobs then if currentFramework == "esx" then jobsData = handler.getJobs(ESX) or handler.getJobs(Core) else jobsData = handler.getJobs(QBCore) end end if not jobsData then return end local isEsx = currentFramework == "esx" for jobName, jobData in pairs(jobsData) do AllFrameworkJobs[jobName] = { grades = {} } if jobData.grades then for gradeLevel, gradeData in pairs(jobData.grades) do AllFrameworkJobs[jobName].grades[tostring(gradeLevel)] = { name = gradeData.name or gradeData.label or ("Grade " .. gradeLevel), payment = isEsx and (gradeData.salary or 0) or (gradeData.payment or 0), isboss = gradeData.isboss or false } end end end end local function removeFromCoreJobs(identifier, jobName) local CoreJobs = Core.JobbyJobs or {} if not CoreJobs[jobName] or not CoreJobs[jobName].players then return end for index, player in pairs(CoreJobs[jobName].players) do if player.identifier == identifier then table.remove(CoreJobs[jobName].players, index) UpdateJobPlayerData(jobName, 'removeemployee', { identifier = identifier }) break end end end local function sqlFire(identifier, jobName) if currentFramework == "standalone" then return true end if not handler.table then return false end local query = string.format("SELECT %s FROM `%s` WHERE `%s` = ?", handler.jobColumn, handler.table, handler.identifier) local result = MySQL.query.await(query, { identifier }) if result and result[1] then if handler.isJson then local targetJob = handler.defaultJob MySQL.update.await( string.format("UPDATE `%s` SET `%s` = ? WHERE `%s` = ?", handler.table, handler.jobColumn, handler.identifier), { json.encode(targetJob), identifier } ) else MySQL.update.await( string.format("UPDATE `%s` SET `%s` = ?, `%s` = ? WHERE `%s` = ?", handler.table, handler.jobColumn, handler.gradeColumn, handler.identifier), { handler.defaultJob, handler.defaultGrade, identifier } ) end end removeFromCoreJobs(identifier, jobName) return true end local function changeRank(identifier, jobName, currentGrade, direction) if currentFramework == "standalone" then return true end local newGrade = direction == "up" and (currentGrade + 1) or math.max(0, currentGrade - 1) if handler.isJson then -- QB/QBox local query = string.format("SELECT %s FROM `%s` WHERE `%s` = ?", handler.jobColumn, handler.table, handler.identifier) local result = MySQL.query.await(query, { identifier }) if result and result[1] then local jobData = json.decode(result[1][handler.jobColumn]) if jobData and jobData.name == jobName then local newGradeInfo = getGradeInfo(jobName, newGrade) jobData.grade = newGradeInfo jobData.isboss = newGradeInfo.isboss jobData.payment = newGradeInfo.payment MySQL.update.await( string.format("UPDATE `%s` SET `%s` = ? WHERE `%s` = ?", handler.table, handler.jobColumn, handler.identifier), { json.encode(jobData), identifier } ) return true end end else -- ESX local result = MySQL.update.await( string.format("UPDATE `%s` SET `%s` = ? WHERE `%s` = ? AND `%s` = ?", handler.table, handler.gradeColumn, handler.identifier, handler.jobColumn), { newGrade, identifier, jobName } ) return result > 0 end return false end function SqlFire(identifier, jobName) return sqlFire(identifier, jobName) end function RankUpPlayer(source, identifier, jobName, currentGrade) if source and IsPlayerInGame(source) then return Core.Functions.SetPlayerJob(source, jobName, currentGrade + 1) end return changeRank(identifier, jobName, currentGrade, "up") end function RankDownPlayer(source, identifier, jobName, currentGrade) if source and IsPlayerInGame(source) then return Core.Functions.SetPlayerJob(source, jobName, math.max(0, currentGrade - 1)) end return changeRank(identifier, jobName, currentGrade, "down") end CreateThread(function() Wait(5000) PopulateAllFrameworkJobs() Wait(10000) if tableLength(AllFrameworkJobs) == 0 then PopulateAllFrameworkJobs() end end)