From 9cf4741010f398cc5668c0fe2fe710428a14a4e6 Mon Sep 17 00:00:00 2001 From: Manason Date: Fri, 1 Mar 2024 10:03:56 -0800 Subject: [PATCH] feat: support managing non primary jobs and gangs * feat: support managing not primary jobs and gangs * fixes after testing * fix indentation * cleanup the query --- client/main.lua | 4 +- locales/en.json | 4 +- server/main.lua | 158 ++++++++++++++++----------------------------- server/storage.lua | 16 +---- 4 files changed, 62 insertions(+), 120 deletions(-) diff --git a/client/main.lua b/client/main.lua index 60c8858..a2ac06a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -47,7 +47,7 @@ local function manageEmployee(player, groupName, groupType) title = gradeTitle.name, description = locale('menu.grade')..groupGrade, onSelect = function() - lib.callback.await('qbx_management:server:updateGrade', false, player.cid, player.grade.level, tonumber(groupGrade), groupType) + lib.callback.await('qbx_management:server:updateGrade', false, player.cid, player.grade, tonumber(groupGrade), groupType) OpenBossMenu(groupType) end, } @@ -86,7 +86,7 @@ local function employeeList(groupType) for _, employee in pairs(employees) do employeesMenu[#employeesMenu + 1] = { title = employee.name, - description = employee.grade.name, + description = groupType == 'job' and JOBS[groupName].grades[employee.grade].name or GANGS[groupName].grades[employee.grade].name, onSelect = function() manageEmployee(employee, groupName, groupType) end, diff --git a/locales/en.json b/locales/en.json index 4036de2..8c79d11 100644 --- a/locales/en.json +++ b/locales/en.json @@ -27,8 +27,8 @@ "kick_yourself": "You can't kick yourself...", "fire_yourself": "You can't fire yourself...", "fire_boss": "You can't fire someone with a higher grade...", - "you_gang_fired": "You've been expelled from the gang!", - "you_job_fired": "You've been fired! Good luck!", + "you_gang_fired": "You've been expelled from %s!", + "you_job_fired": "You've been fired from %s! Good luck!", "unable_fire": "You're unable to fire this person...", "person_doesnt_exist": "This person doesn't seem to exist...", "gang_fired": "Gang member expelled!", diff --git a/server/main.lua b/server/main.lua index cdd698c..3079d4f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -13,42 +13,21 @@ for groupName, menuInfo in pairs(config.menus) do menus[#menus + 1] = menuInfo end -local function getPlayerMenuEntry(isOnline, player, groupType) - if isOnline then - return { - cid = player.PlayerData.citizenid, - grade = player.PlayerData[groupType].grade, - isboss = player.PlayerData[groupType].isboss, - name = '🟢 '..player.PlayerData.charinfo.firstname..' '..player.PlayerData.charinfo.lastname - } - else - return { - cid = player.citizenid, - grade = player[groupType].grade, - isboss = player[groupType].isboss, - name = '❌ '..player.charinfo.firstname..' '..player.charinfo.lastname - } - end -end - local function getMenuEntries(groupName, groupType) - local onlinePlayers = {} local menuEntries = {} - local players = exports.qbx_core:GetQBPlayers() - for _, qbPlayer in pairs(players) do - if qbPlayer.PlayerData[groupType].name == groupName then - onlinePlayers[qbPlayer.PlayerData.citizenid] = true - menuEntries[#menuEntries + 1] = getPlayerMenuEntry(true, qbPlayer, groupType) - end - end - - local dbPlayers = FetchPlayerEntitiesByGroup(groupName, groupType) - for _, player in pairs(dbPlayers) do - if not onlinePlayers[player.citizenid] then - menuEntries[#menuEntries + 1] = getPlayerMenuEntry(false, player, groupType) - end - end + local groupEntries = FetchPlayersInGroup(groupName, groupType) + for i = 1, #groupEntries do + local citizenid = groupEntries[i].citizenid + local grade = groupEntries[i].grade + local player = exports.qbx_core:GetPlayerByCitizenId(citizenid) or exports.qbx_core:GetOfflinePlayer(citizenid) + local namePrefix = player.Offline and '❌ ' or '🟢 ' + menuEntries[#menuEntries + 1] = { + cid = citizenid, + grade = grade, + name = namePrefix..player.PlayerData.charinfo.firstname..' '..player.PlayerData.charinfo.lastname + } + end return menuEntries end @@ -64,7 +43,7 @@ lib.callback.register('qbx_management:server:getEmployees', function(source, gro local menuEntries = getMenuEntries(groupName, groupType) table.sort(menuEntries, function(a, b) - return a.grade.level > b.grade.level + return a.grade > b.grade end) return menuEntries @@ -94,10 +73,8 @@ lib.callback.register('qbx_management:server:updateGrade', function(source, citi if groupType == 'job' then exports.qbx_core:AddPlayerToJob(citizenId, jobName, newGrade) - exports.qbx_core:SetPlayerPrimaryJob(citizenId, jobName) else exports.qbx_core:AddPlayerToGang(citizenId, jobName, newGrade) - exports.qbx_core:SetPlayerPrimaryGang(citizenId, jobName) end if employee then @@ -121,23 +98,23 @@ lib.callback.register('qbx_management:server:hireEmployee', function(source, emp return end - local jobName = player.PlayerData[groupType].name + local groupName = player.PlayerData[groupType].name local logArea = groupType == 'gang' and 'Gang' or 'Boss' - local success = groupType == 'gang' and target.Functions.SetGang(jobName) or target.Functions.SetJob(jobName) - local grade = groupType == 'gang' and GANGS[jobName].grades[0].name or JOBS[jobName].grades[0].name - - if success then - local playerFullName = player.PlayerData.charinfo.firstname..' '..player.PlayerData.charinfo.lastname - local targetFullName = target.PlayerData.charinfo.firstname..' '..target.PlayerData.charinfo.lastname - local organizationLabel = player.PlayerData[groupType].label - exports.qbx_core:Notify(source, locale('success.hired_into', targetFullName, organizationLabel), 'success') - exports.qbx_core:Notify(target.PlayerData.source, locale('success.hired_to')..organizationLabel, 'success') - logger.log({source = 'qbx_management', event = 'hireEmployee', message = string.format('%s | %s hired %s into %s at grade %s', logArea, playerFullName, targetFullName, organizationLabel, grade), webhook = config.discordWebhook}) + if groupType == 'job' then + exports.qbx_core:AddPlayerToJob(target.PlayerData.citizenid, groupName, 0) + exports.qbx_core:SetPlayerPrimaryJob(target.PlayerData.citizenid, groupName) else - exports.qbx_core:Notify(source, locale('error.couldnt_hire'), 'error') + exports.qbx_core:AddPlayerToGang(target.PlayerData.citizenid, groupName, 0) + exports.qbx_core:SetPlayerPrimaryGang(target.PlayerData.citizenid, groupName) end - return nil + + local playerFullName = player.PlayerData.charinfo.firstname..' '..player.PlayerData.charinfo.lastname + local targetFullName = target.PlayerData.charinfo.firstname..' '..target.PlayerData.charinfo.lastname + local organizationLabel = player.PlayerData[groupType].label + exports.qbx_core:Notify(source, locale('success.hired_into', targetFullName, organizationLabel), 'success') + exports.qbx_core:Notify(target.PlayerData.source, locale('success.hired_to')..organizationLabel, 'success') + logger.log({source = 'qbx_management', event = 'hireEmployee', message = string.format('%s | %s hired %s into %s at grade %s', logArea, playerFullName, targetFullName, organizationLabel, 0), webhook = config.discordWebhook}) end) -- Returns playerdata for a given table of player server ids. @@ -164,82 +141,58 @@ lib.callback.register('qbx_management:server:getPlayers', function(_, closePlaye return players end) --- Function to fire an online player from a given group --- Should be merged with the offline player function once an export from the core is available ----@param source integer ----@param employee Player Player object of player being fired ----@param player Player Player object of player initiating firing action + +---@param employeeCitizenId string +---@param boss Player +---@param groupName string ---@param groupType GroupType -local function fireOnlineEmployee(source, employee, player, groupType) - if employee.PlayerData.citizenid == player.PlayerData.citizenid then +---@return boolean success +local function fireEmployee(employeeCitizenId, boss, groupName, groupType) + local employee = exports.qbx_core:GetPlayerByCitizenId(employeeCitizenId) or exports.qbx_core:GetOfflinePlayer(employeeCitizenId) + if employee.PlayerData.citizenid == boss.PlayerData.citizenid then local message = groupType == 'gang' and locale('error.kick_yourself') or locale('error.fire_yourself') - exports.qbx_core:Notify(source, message, 'error') + exports.qbx_core:Notify(boss.PlayerData.source, message, 'error') return false end - - if employee.PlayerData[groupType].grade.level >= player.PlayerData[groupType].grade.level then - exports.qbx_core:Notify(source, locale('error.fire_boss'), 'error') + if not employee then + exports.qbx_core:Notify(boss.PlayerData.source, locale('error.person_doesnt_exist'), 'error') return false end - local success = groupType == 'gang' and employee.Functions.SetGang('none', 0) or employee.Functions.SetJob('unemployed', 0) - if success then - local message = groupType == 'gang' and locale('error.you_gang_fired') or locale('error.you_job_fired') - exports.qbx_core:Notify(employee.PlayerData.source, message, 'error') - return true - end - - return false -end - --- Function to fire an offline player from a given group --- Should be merged with the online player function once an export from the core is available ----@param source integer ----@param employee string citizenid of player to be fired ----@param player Player Player object of player initiating firing action ----@param groupType GroupType -local function fireOfflineEmployee(source, employee, player, groupType) - local offlineEmployee = exports.qbx_core:GetOfflinePlayer(employee) - if not offlineEmployee[1] then - exports.qbx_core:Notify(source, locale('error.person_doesnt_exist'), 'error') - return false, nil + local employeeGrade = groupType == 'job' and employee.PlayerData.jobs?[groupName] or employee.PlayerData.gangs?[groupName] + local bossGrade = groupType == 'job' and boss.PlayerData.jobs?[groupName] or boss.PlayerData.gangs?[groupName] + if employeeGrade >= bossGrade then + exports.qbx_core:Notify(boss.PlayerData.source, locale('error.fire_boss'), 'error') + return false end - employee = offlineEmployee[1] - employee[groupType] = json.decode(employee[groupType]) - employee.charinfo = json.decode(employee.charinfo) - - if employee[groupType].grade.level >= player.PlayerData[groupType].grade.level then - exports.qbx_core:Notify(source, locale('error.fire_boss'), 'error') - return false, nil + if groupType == 'job' then + exports.qbx_core:RemovePlayerFromJob(employee.PlayerData.citizenid, groupName) + else + exports.qbx_core:RemovePlayerFromGang(employee.PlayerData.citizenid, groupName) end - exports.qbx_core:RemovePlayerFromJob(employee.PlayerData.citizenid, employee.PlayerData.job.name) - local employeeFullName = employee.charinfo.firstname..' '..employee.charinfo.lastname + if not employee.Offline then + local message = groupType == 'gang' and locale('error.you_gang_fired', GANGS[groupName].label) or locale('error.you_job_fired', JOBS[groupName].label) + exports.qbx_core:Notify(employee.PlayerData.source, message, 'error') + end - return true, employeeFullName + return true end -- Callback for firing a player from a given society. --- Branches to online and offline functions depending on if the target is available. --- Once an export is available this should be rewritten to remove the MySQL queries. ---@param employee string citizenid of employee to be fired ---@param groupType GroupType lib.callback.register('qbx_management:server:fireEmployee', function(source, employee, groupType) local player = exports.qbx_core:GetPlayer(source) - local firedEmployee = exports.qbx_core:GetPlayerByCitizenId(employee) or nil + local firedEmployee = exports.qbx_core:GetPlayerByCitizenId(employee) or exports.qbx_core:GetOfflinePlayer(employee) local playerFullName = player.PlayerData.charinfo.firstname..' '..player.PlayerData.charinfo.lastname local organizationLabel = player.PlayerData[groupType].label if not player.PlayerData[groupType].isboss then return end - - local success, employeeFullName - if firedEmployee then - employeeFullName = firedEmployee.PlayerData.charinfo.firstname..' '..firedEmployee.PlayerData.charinfo.lastname - success = fireOnlineEmployee(source, firedEmployee, player, groupType) - else - success, employeeFullName = fireOfflineEmployee(source, employee, player, groupType) - end + if not firedEmployee then lib.print.error("not able to find player with citizenid", employee) return end + local success = fireEmployee(employee, player, player.PlayerData[groupType].name, groupType) + local employeeFullName = firedEmployee.PlayerData.charinfo.firstname..' '..firedEmployee.PlayerData.charinfo.lastname if success then local logArea = groupType == 'gang' and 'Gang' or 'Boss' @@ -249,7 +202,6 @@ lib.callback.register('qbx_management:server:fireEmployee', function(source, emp else exports.qbx_core:Notify(source, locale('error.unable_fire'), 'error') end - return nil end) lib.callback.register('qbx_management:server:getBossMenus', function() diff --git a/server/storage.lua b/server/storage.lua index 96246c1..f5a9295 100644 --- a/server/storage.lua +++ b/server/storage.lua @@ -1,18 +1,8 @@ ---@alias GroupType 'gang' | 'job' ----Fetches DB Player Entities by Group ---@param name string ---@param type GroupType ----@return table[] -function FetchPlayerEntitiesByGroup(name, type) - local chars = {} - local result = MySQL.query.await("SELECT citizenid, charinfo, gang, job FROM `players` WHERE JSON_VALUE("..type..", '$.name') = ?", {name}) - for i = 1, #result do - chars[i] = result[i] - chars[i].charinfo = json.decode(result[i].charinfo) - chars[i].job = result[i].job and json.decode(result[i].job) - chars[i].gang = result[i].gang and json.decode(result[i].gang) - end - - return chars +---@return {citizenid: string, grade: integer}[] +function FetchPlayersInGroup(name, type) + return MySQL.query.await("SELECT citizenid, grade FROM player_groups WHERE `group` = ? AND `type` = ?", {name, type}) end \ No newline at end of file