2026-04-14 17:41:39 +02:00

547 lines
19 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

if Config.Framework ~= "qb" then
return
end
local nameCache = {}
Core = {
CoreReady = false,
JobbyJobs = {},
JobbyJobsReady = false,
}
Core.__index = Core
Core.Functions = {}
local databaseReady = false
AddEventHandler('codem-phone:database:ready', function()
databaseReady = true
end)
local function CheckQBCoreStatus()
local resourceState = GetResourceState('qb-core')
return resourceState == "started" or resourceState == "starting"
end
local QBCore = nil
if CheckQBCoreStatus() then
local success, result = pcall(function()
return exports['qb-core']:GetCoreObject()
end)
if success and result then
QBCore = result
Core.CoreReady = true
Citizen.CreateThread(function()
local timeout = 0
while not databaseReady and timeout < 60000 do
Wait(100)
timeout = timeout + 100
end
if not databaseReady then
print('^1[CODEM-PHONE] Framework ERROR: Database initialization timeout!^7')
return
end
local JobbyConfig = LoadFile('config/AppConfig/JobbyConfig.lua')
local players = MySQL.query.await('SELECT citizenid, job, charinfo FROM players')
for k, v in pairs(JobbyConfig.AllowJobs) do
Core.JobbyJobs[k] = {
label = QBCore.Shared.Jobs[k] and QBCore.Shared.Jobs[k].label or 'Unknown Job',
players = {},
name = k,
grades = QBCore.Shared.Jobs[k] and QBCore.Shared.Jobs[k].grades or {},
money = 0,
announcements = {},
logs = {},
}
local ShowSQl = MySQL.scalar.await(
"SELECT 1 FROM information_schema.tables WHERE table_name = 'codem_mphone_jobby_announcements' LIMIT 1")
local announcementSql = {}
if ShowSQl then
announcementSql = MySQL.query.await(
'SELECT id, title, content, created_at FROM codem_mphone_jobby_announcements WHERE jobname = ? ORDER BY created_at DESC LIMIT 15',
{ k }
)
end
local ShowLogSQl = MySQL.scalar.await(
"SELECT 1 FROM information_schema.tables WHERE table_name = 'codem_mphone_jobby_log' LIMIT 1")
local logsSql = {}
if ShowLogSQl then
logsSql = MySQL.query.await(
'SELECT id, action, amount, playername, phone_number, date FROM codem_mphone_jobby_log WHERE jobname = ? ORDER BY date DESC LIMIT 20',
{ k }
)
end
for __, vv in pairs(players) do
local jobs = json.decode(vv.job)
if jobs and jobs.name and jobs.name == k then
local charinfo = vv.charinfo and json.decode(vv.charinfo) or nil
local playerName = 'Unknown Player'
if charinfo and charinfo.firstname and charinfo.lastname then
playerName = charinfo.firstname .. ' ' .. charinfo.lastname
end
local PhoneNumber = MySQL.query.await(
"SELECT phone_number FROM codem_mphone_data WHERE owner = ? LIMIT 1", { vv.citizenid })
local gradeLevel = (jobs.grade and jobs.grade.level) or 0
local gradeName = (jobs.grade and jobs.grade.name) or 'Unknown Grade'
Core.JobbyJobs[k].players[#Core.JobbyJobs[k].players + 1] = {
name = playerName,
grade_level = gradeLevel,
grade_name = gradeName,
src = false,
identifier = vv.citizenid,
boss = false,
phone_number = PhoneNumber and PhoneNumber[1] and PhoneNumber[1].phone_number or nil,
}
end
end
Core.JobbyJobs[k].money = GetJobMoney(k)
Core.JobbyJobs[k].announcements = announcementSql or {}
Core.JobbyJobs[k].logs = logsSql or {}
end
Core.JobbyJobsReady = true
end)
else
DebugPrint('Error: QB-Core object could not be retrieved')
end
else
DebugPrint('Error: QB-Core resource not found or not started')
return
end
-- Example job structure from QBCore:
-- "realestate": {
-- "label": "Real Estate",
-- "offDutyPay": false,
-- "grades": {
-- "3": {
-- "payment": 125,
-- "name": "Broker"
-- },
-- "4": {
-- "isboss": true,
-- "payment": 150,
-- "name": "Manager"
-- },
-- "0": {
-- "payment": 50,
-- "name": "Recruit"
-- },
-- "1": {
-- "payment": 75,
-- "name": "House Sales"
-- },
-- "2": {
-- "payment": 100,
-- "name": "Business Sales"
-- }
-- },
-- "defaultDuty": true
-- }
function JobHasIsBossField(job)
local AllFrameworkJobs = Core.JobbyJobs or {}
if not AllFrameworkJobs[job] then return false end
local AllGrades = AllFrameworkJobs[job].grades or {}
for _, gradeData in pairs(AllGrades) do
if gradeData.isboss == true then
return true
end
end
return false
end
function IsGradeBoss(job, gradeLevel)
local AllFrameworkJobs = Core.JobbyJobs or {}
if not AllFrameworkJobs[job] then return false end
local AllGrades = AllFrameworkJobs[job].grades or {}
local gradeData = AllGrades[tonumber(gradeLevel)] or AllGrades[tostring(gradeLevel)]
if gradeData and gradeData.isboss == true then
return true
end
return false
end
function GetHighestGrade(job)
local AllFrameworkJobs = Core.JobbyJobs or {}
if AllFrameworkJobs[job] then
local AllGrades = AllFrameworkJobs[job].grades
local highestGrade = -1
for key, _ in pairs(AllGrades) do
local gradeNum = tonumber(key)
if gradeNum and gradeNum > highestGrade then
highestGrade = gradeNum
end
end
return highestGrade
else
return false
end
end
function IsBoss(job, gradeLevel)
if JobHasIsBossField(job) then
return IsGradeBoss(job, gradeLevel)
else
local highestGrade = GetHighestGrade(job)
return highestGrade and gradeLevel >= highestGrade
end
end
Core.Functions.GetPlayer = function(playerid)
if not playerid then
DebugPrint('Error: playerId is required')
return nil
end
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerid)
if success and playerData then
return playerData
else
return false
end
else
return false
end
end
Core.Functions.GetIdentifier = function(playerId)
if not playerId then
DebugPrint('Error: playerId is required')
return nil
end
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerId)
if success and playerData and playerData.PlayerData then
return playerData.PlayerData.citizenid or nil
else
return false
end
else
return false
end
end
Core.Functions.GetSourceFromIdentifier = function(identifier)
if not identifier then
DebugPrint('Error: identifier is required')
return nil
end
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, player = pcall(QBCore.Functions.GetPlayerByCitizenId, identifier)
if success and player then
return player.PlayerData.source
else
return false
end
else
return false
end
end
-- Example job data structure from QBCore:
--[[
{
"payment": 150,
"grade": {
"payment": 150,
"name": "Chief",
"isboss": true,
"level": 4
},
"type": "leo",
"name": "police",
"label": "Law Enforcement",
"isboss": true,
"onduty": true
}
]]
Core.Functions.GetPlayerJob = function(playerId)
if not playerId then
DebugPrint('Error: playerId is required')
return false
end
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerId)
if success and playerData and playerData.PlayerData and playerData.PlayerData.job then
return {
name = playerData.PlayerData.job.name or 'unemployed',
label = playerData.PlayerData.job.label or 'Unemployed',
onduty = playerData.PlayerData.job.onduty or false,
grade_name = playerData.PlayerData.job.grade.name or 'unemployed',
grade_level = playerData.PlayerData.job.grade.level or 0,
isboss = playerData.PlayerData.job.grade.isboss or false
}
else
return false
end
else
return false
end
end
Core.Functions.IsPlayerAdmin = function(playerId)
if not playerId then
DebugPrint('Error: playerId is required')
return false
end
local permissions = Config.Permissions or { 'god' }
if type(permissions) ~= 'table' or #permissions == 0 then
DebugPrint('Warning: Config.Permissions is invalid, using default permissions')
permissions = { 'god' }
end
for _, v in pairs(Config.AdminPermissions) do
if QBCore.Functions.HasPermission(playerId, v) or IsPlayerAceAllowed(playerId, 'command') then
return true
end
end
return false
end
AddEventHandler("QBCore:Server:OnJobUpdate", function(src, job)
TriggerClientEvent('codem-phone:client:OnJobUpdate', src)
OnJobUpdate(src, {
jobname = job.name or 'unemployed',
onduty = job.onduty or false,
})
OnJobbyJobUpdate(src)
end)
AddEventHandler("QBCore:Server:SetDuty", function(src, onDuty)
local playerJob = Core.Functions.GetPlayerJob(src)
OnJobUpdate(src, {
jobname = playerJob and playerJob.name or 'unemployed',
onduty = onDuty or false,
})
OnJobbyJobUpdate(src)
end)
Core.Functions.GetName = function(playerId, nameType)
if not playerId then
DebugPrint('Error: playerId is required')
return 'Unknown'
end
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerId)
if success and playerData and playerData.PlayerData then
local firstname = playerData.PlayerData.charinfo.firstname or ""
local lastname = playerData.PlayerData.charinfo.lastname or ""
if nameType and nameType:lower() == 'first' then
return (firstname):gsub("^%l", string.upper) or 'Unknown'
elseif nameType and nameType:lower() == 'full' then
return (firstname .. " " .. lastname):gsub("^%l", string.upper) or 'Unknown'
end
return (firstname .. " " .. lastname):gsub("^%l", string.upper) or 'Unknown'
else
-- offline player ismini çekmek için Core.Functions.GetName fonksiyonunu çağırırken playerId yerine identifier'ini yaz
if nameCache[playerId] then
if nameType and nameType:lower() == 'first' then
return (nameCache[playerId].firstname):gsub("^%l", string.upper) or 'Unknown'
elseif nameType and nameType:lower() == 'full' then
return (nameCache[playerId].firstname .. " " .. nameCache[playerId].lastname):gsub("^%l",
string.upper) or 'Unknown'
end
return (nameCache[playerId].firstname .. " " .. nameCache[playerId].lastname):gsub("^%l", string.upper) or
'Unknown'
end
local result = MySQL.single.await("SELECT charinfo FROM players WHERE citizenid = ? LIMIT 1", { playerId })
if result and result.charinfo then
local charinfo = json.decode(result.charinfo)
if nameType and nameType:lower() == 'first' then
return (charinfo.firstname):gsub("^%l", string.upper) or 'Unknown'
elseif nameType and nameType:lower() == 'full' then
return (charinfo.firstname .. " " .. charinfo.lastname):gsub("^%l", string.upper) or 'Unknown'
end
nameCache[playerId] = {
firstname = charinfo.firstname,
lastname = charinfo.lastname,
}
return (charinfo.firstname .. " " .. charinfo.lastname):gsub("^%l", string.upper) or 'Unknown'
end
end
else
DebugPrint('Error: QB-Core Functions not available')
end
return 'Unknown'
end
Core.Functions.GetMoney = function(playerId, moneyType)
if not playerId then
DebugPrint('Error: playerId is required')
return 0
end
moneyType = moneyType or 'bank'
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerId)
if success and playerData and playerData.PlayerData and playerData.PlayerData.money then
return {
success = true,
money = playerData.PlayerData.money[moneyType] or 0
}
else
return {
success = false,
message = 'Error: Player data could not be retrieved - ID: ' .. tostring(playerId)
}
end
else
return {
success = false,
message = 'Error: QB-Core Functions not available'
}
end
end
Core.Functions.RemoveMoney = function(playerId, amount, moneyType)
if not playerId then
DebugPrint('Error: playerId is required')
return false
end
if not amount or amount <= 0 then
DebugPrint('Error: amount must be a positive number')
return false
end
moneyType = moneyType or 'bank'
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerId)
if success and playerData and playerData.PlayerData and playerData.PlayerData.money then
local currentMoney = playerData.PlayerData.money[moneyType] or 0
if currentMoney >= amount then
local removeSuccess, removeResult = pcall(function()
return playerData.Functions.RemoveMoney(moneyType, amount, "codem-phone")
end)
if removeSuccess and removeResult then
return true
else
return false
end
else
return false
end
else
return false
end
else
return false
end
end
Core.Functions.AddMoney = function(playerId, amount, moneyType)
if not playerId then
DebugPrint('Error: playerId is required')
return false
end
if not amount or amount <= 0 then
DebugPrint('Error: amount must be a positive number')
return false
end
moneyType = moneyType or 'bank'
if QBCore and QBCore.Functions and QBCore.Functions.GetPlayer then
local success, playerData = pcall(QBCore.Functions.GetPlayer, playerId)
if success and playerData and playerData.PlayerData and playerData.PlayerData.money then
local addSuccess, addResult = pcall(function()
return playerData.Functions.AddMoney(moneyType, amount, "codem-phone")
end)
if addSuccess then
return addResult
else
return false
end
else
return false
end
else
return false
end
end
Core.Functions.AddMoneyOffline = function(citizenid, amount, moneyType)
if not citizenid then
return { success = false, message = "Citizen ID is required." }
end
if not amount or amount <= 0 then
return { success = false, message = "Invalid amount." }
end
moneyType = moneyType or 'bank'
if QBCore and QBCore.Functions then
local moneyData = MySQL.scalar.await(
"SELECT money FROM players WHERE citizenid = ?",
{ citizenid }
)
if not moneyData then
return { success = false, message = "Player not found in database." }
end
local playerData = json.decode(moneyData) or {}
local currentMoney = playerData[moneyType] or 0
playerData[moneyType] = currentMoney + amount
local affectedRows = MySQL.update.await(
"UPDATE players SET money = ? WHERE citizenid = ?",
{ json.encode(playerData), citizenid }
)
if affectedRows > 0 then
return { success = true }
else
return { success = false, message = "Failed to update money for offline player." }
end
else
return { success = false, message = "Core Functions not available." }
end
end
Core.Functions.SetPlayerJob = function(playerid, jobname, grade)
local player = Core.Functions.GetPlayer(playerid)
if player then
player.Functions.SetJob(jobname, grade)
return true
else
DebugPrint('Error: Player not found - ID: ' .. tostring(playerid))
return false
end
end
Core.Functions.CreateUseableItem = function(itemName, callback)
if not itemName or type(itemName) ~= 'string' then
DebugPrint('Error: itemName must be a valid string')
return
end
if not callback or type(callback) ~= 'function' then
DebugPrint('Error: callback must be a valid function')
return
end
if QBCore and QBCore.Functions and QBCore.Functions.CreateUseableItem then
QBCore.Functions.CreateUseableItem(itemName, callback)
else
DebugPrint('Error: QB-Core Functions not available')
end
end