308 lines
14 KiB
Lua
Raw Normal View History

2025-04-07 01:41:12 +00:00
lib.versionCheck('Qbox-project/qbx_adminmenu')
local config = require 'config.server'
local isFrozen = {}
local reportsCount = 0
REPORTS = {}
--- Trigger something on players who have the passed permission
--- @param permission string - The required permission
--- @param cb function - The function, will return player object as parameter
function OnAdmin(permission, cb)
for k, v in pairs(exports.qbx_core:GetQBPlayers()) do
if IsPlayerAceAllowed(k, permission) then
cb(v)
end
end
end
--- Sends a report to online staff members
--- @param source string - The player's ID
--- @param message string - Message for the report
function SendReport(source, message)
local reportId = #REPORTS + 1
reportsCount += 1
REPORTS[reportId] = {
id = reportsCount,
senderId = source,
senderName = GetPlayerName(source),
message = message,
claimed = 'Nobody'
}
table.sort(REPORTS, function(a, b) return a.id < b.id end)
exports.qbx_core:Notify(source, locale('success.report_sent'), 'success')
OnAdmin(config.commandPerms.reportReply, function(target)
exports.qbx_core:Notify(target.PlayerData.source, locale('success.new_report'), 'success')
end)
end
--- Checks if the source is inside of the target's routingbucket
--- if not set the source's routingbucket to the target's
--- @param source string - The player's ID
--- @param target string - The player's ID
function CheckRoutingbucket(source, target)
local sourceBucket = GetPlayerRoutingBucket(source)
local targetBucket = GetPlayerRoutingBucket(target)
if sourceBucket ~= targetBucket then SetPlayerRoutingBucket(source, targetBucket) end
end
RegisterNetEvent('qbx_admin:server:sendReply', function(report, message)
if not IsPlayerAceAllowed(source, config.commandPerms.reportReply) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
for k, v in pairs(REPORTS) do
if v.id == report.id then
local name = GetPlayerName(source)
TriggerClientEvent('chatMessage', report.senderId, "", {255, 0, 0}, string.format('[REPORT #%s] [%s] ^7%s', report.id, name, message))
exports.qbx_core:Notify(source, locale('success.sent_report_reply'), 'success')
if REPORTS[k].claimed == 'Nobody' then
REPORTS[k].claimed = name
OnAdmin(config.commandPerms.reportReply, function(target)
exports.qbx_core:Notify(target.PlayerData.source, string.format(locale('success.report_claimed_by'), report.id, name), 'success')
end)
end
return
end
end
end)
RegisterNetEvent('qbx_admin:server:deleteReport', function(report)
if not IsPlayerAceAllowed(source, config.commandPerms.reportReply) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
for k, v in pairs(REPORTS) do
if v.id == report.id then
return table.remove(REPORTS, k)
end
end
end)
local generalOptions = {
function(selectedPlayer) TriggerClientEvent('qbx_admin:client:killPlayer', selectedPlayer.id) end,
function(selectedPlayer) TriggerClientEvent('qbx_medical:client:playerRevived', selectedPlayer.id) end,
function(selectedPlayer)
if isFrozen[selectedPlayer.id] then
FreezeEntityPosition(GetPlayerPed(selectedPlayer.id), false)
isFrozen[selectedPlayer.id] = false
else
FreezeEntityPosition(GetPlayerPed(selectedPlayer.id), true)
isFrozen[selectedPlayer.id] = true
end
end,
function(selectedPlayer, source)
local coords = GetEntityCoords(GetPlayerPed(selectedPlayer.id))
CheckRoutingbucket(source, selectedPlayer.id)
SetEntityCoords(GetPlayerPed(source), coords.x, coords.y, coords.z, false, false, false, false)
end,
function(selectedPlayer, source)
local coords = GetEntityCoords(GetPlayerPed(source))
CheckRoutingbucket(selectedPlayer.id, source)
SetEntityCoords(GetPlayerPed(selectedPlayer.id), coords.x, coords.y, coords.z, false, false, false, false)
end,
function(selectedPlayer, source)
local vehicle = GetVehiclePedIsIn(GetPlayerPed(selectedPlayer.id), false)
local seat = -1
if vehicle == 0 then return end
for i = 0, 8, 1 do if GetPedInVehicleSeat(vehicle, i) == 0 then seat = i break end end
if seat == -1 then return end
SetPedIntoVehicle(GetPlayerPed(source), vehicle, seat)
end,
function(selectedPlayer, _, input)
exports.qbx_core:SetPlayerBucket(selectedPlayer.id, input)
end,
}
RegisterNetEvent('qbx_admin:server:playerOptionsGeneral', function(selected, selectedPlayer, input)
if not IsPlayerAceAllowed(source, config.eventPerms.playerOptionsGeneral) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
---@diagnostic disable-next-line: redundant-parameter
generalOptions[selected](selectedPlayer, source, input)
end)
local administrationOptions = {
function(source, selectedPlayer, input)
if not IsPlayerAceAllowed(source, config.eventPerms.kick) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
DropPlayer(selectedPlayer.id, input)
end,
function(source, selectedPlayer, input)
if not IsPlayerAceAllowed(source, config.eventPerms.ban) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
local banDuration = (input[2] or 0) * 3600 + (input[3] or 0) * 86400 + (input[4] or 0) * 2629743
DropPlayer(selectedPlayer.id, locale('player_options.administration.banreason', input[1], os.date('%c', os.time() + banDuration)))
MySQL.Async.insert('INSERT INTO bans (name, license, discord, ip, reason, expire, bannedby) VALUES (?, ?, ?, ?, ?, ?, ?)', {
GetPlayerName(selectedPlayer.id), GetPlayerIdentifierByType(selectedPlayer.id, 'license'), GetPlayerIdentifierByType(selectedPlayer.id, 'discord'),
GetPlayerIdentifierByType(selectedPlayer.id, 'ip'), input[1], os.time() + banDuration, GetPlayerName(source)
})
end,
function(source, selectedPlayer, input)
if not IsPlayerAceAllowed(source, config.eventPerms.changePerms) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
if input == 'remove' then exports.qbx_core:RemovePermission(selectedPlayer.id) else exports.qbx_core:AddPermission(selectedPlayer.id, input) end
end,
}
RegisterNetEvent('qbx_admin:server:playerAdministration', function(selected, selectedPlayer, input)
administrationOptions[selected](source, selectedPlayer, input)
end)
local playerDataOptions = {
name = function(target, input)
if input[1] then target.PlayerData.charinfo.firstname = input[1] end
if input[2] then target.PlayerData.charinfo.lastname = input[2] end
target.Functions.SetPlayerData('charinfo', target.PlayerData.charinfo)
end,
food = function(target, input) target.Functions.SetMetaData('hunger', input[1]) end,
thirst = function(target, input) target.Functions.SetMetaData('thirst', input[1]) end,
stress = function(target, input) target.Functions.SetMetaData('stress', input[1]) end,
armor = function(target, input) target.Functions.SetMetaData('armor', input[1]) SetPedArmour(GetPlayerPed(target.PlayerData.source), input[1]) end,
phone = function(target, input)
target.PlayerData.charinfo.phone = input[1]
target.Functions.SetPlayerData('charinfo', target.PlayerData.charinfo)
end,
crafting = function(target, input) target.Functions.SetMetaData('craftingrep', input[1]) end,
dealer = function(target, input) target.Functions.SetMetaData('dealerrep', input[1]) end,
cash = function(target, input)
target.Functions.SetMoney('cash', input[1], 'qbx_adminmenu')
end,
bank = function(target, input)
target.Functions.SetMoney('bank', input[1], 'qbx_adminmenu')
end,
job = function(target, input)
target.Functions.SetJob(input[1], input[2])
end,
gang = function(target, input)
target.Functions.SetGang(input[1], input[2])
end,
radio = function(target, input)
exports['pma-voice']:setPlayerRadio(target.PlayerData.source, input[1])
end,
}
RegisterNetEvent('qbx_admin:server:changePlayerData', function(selected, selectedPlayer, input)
local target = exports.qbx_core:GetPlayer(selectedPlayer.id)
if not IsPlayerAceAllowed(source, config.eventPerms.changePlayerData) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
if not target then return end
playerDataOptions[selected](target, input)
end)
RegisterNetEvent('qbx_admin:server:giveAllWeapons', function(weaponType, playerID)
local src = playerID or source
local target = exports.qbx_core:GetPlayer(src)
if not IsPlayerAceAllowed(source, config.eventPerms.giveAllWeapons) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
for i = 1, #config.weaponList[weaponType], 1 do
target.Functions.AddItem(config.weaponList[weaponType][i], 1)
end
end)
lib.callback.register('qbx_admin:callback:getradiolist', function(source, frequency)
local list = exports['pma-voice']:getPlayersInRadioChannel(tonumber(frequency))
local players = {}
if not IsPlayerAceAllowed(source, config.eventPerms.getRadioList) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
for targetSource, _ in pairs(list) do -- cheers Knight who shall not be named
local player = exports.qbx_core:GetPlayer(targetSource)
players[#players + 1] = {
id = targetSource,
name = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname .. ' | (' .. GetPlayerName(targetSource) .. ')'
}
end
return players, frequency
end)
lib.callback.register('qbx_admin:server:getPlayers', function(source)
if not IsPlayerAceAllowed(source, config.eventPerms.useMenu) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
local players = {}
for k, v in pairs(exports.qbx_core:GetQBPlayers()) do
players[#players + 1] = {
id = k,
cid = v.PlayerData.citizenid,
name = v.PlayerData.charinfo.firstname .. ' ' .. v.PlayerData.charinfo.lastname .. ' | (' .. GetPlayerName(k) .. ')',
food = Player(v.PlayerData.source).state.hunger,
water = Player(v.PlayerData.source).state.thirst,
stress = Player(v.PlayerData.source).state.stress,
armor = v.PlayerData.metadata.armor,
phone = v.PlayerData.charinfo.phone,
craftingrep = v.PlayerData.metadata.craftingrep,
dealerrep = v.PlayerData.metadata.dealerrep,
cash = v.PlayerData.money.cash,
bank = v.PlayerData.money.bank,
job = v.PlayerData.job.label .. ' | ' .. v.PlayerData.job.grade.level,
gang = v.PlayerData.gang.label,
license = GetPlayerIdentifierByType(k, 'license') or 'Unknown',
discord = GetPlayerIdentifierByType(k, 'discord') or 'Not Linked',
steam = GetPlayerIdentifierByType(k, 'steam') or 'Not Linked',
}
end
table.sort(players, function(a, b) return a.id < b.id end)
return players
end)
lib.callback.register('qbx_admin:server:getPlayer', function(source, playerToGet)
if not IsPlayerAceAllowed(source, config.eventPerms.useMenu) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
local playerData = exports.qbx_core:GetPlayer(playerToGet).PlayerData
local player = {
id = playerToGet,
cid = playerData.citizenid,
name = playerData.charinfo.firstname .. ' ' .. playerData.charinfo.lastname .. ' | (' .. GetPlayerName(playerToGet) .. ')',
food = Player(playerData.source).state.hunger,
water = Player(playerData.source).state.thirst,
stress = Player(playerData.source).state.stress,
armor = playerData.metadata.armor,
phone = playerData.charinfo.phone,
craftingrep = playerData.metadata.craftingrep,
dealerrep = playerData.metadata.dealerrep,
cash = playerData.money.cash,
bank = playerData.money.bank,
job = playerData.job.label .. ' | ' .. playerData.job.grade.level,
gang = playerData.gang.label,
license = GetPlayerIdentifierByType(playerToGet, 'license') or 'Unknown',
discord = GetPlayerIdentifierByType(playerToGet, 'discord') or 'Not Linked',
steam = GetPlayerIdentifierByType(playerToGet, 'steam') or 'Not Linked',
}
return player
end)
lib.callback.register('qbx_admin:server:clothingMenu', function(source, target)
if not IsPlayerAceAllowed(source, config.eventPerms.clothingMenu) then
exports.qbx_core:Notify(source, locale('error.no_perms'), 'error')
return false
end
TriggerClientEvent('qb-clothing:client:openMenu', target)
return true
end)
lib.callback.register('qbx_admin:server:canUseMenu', function(source)
if not IsPlayerAceAllowed(source, config.eventPerms.useMenu) then
exports.qbx_core:Notify(source, locale('error.no_perms'), 'error')
return false
end
return true
end)
lib.callback.register('qbx_admin:server:spawnVehicle', function(source, model)
local ped = GetPlayerPed(source)
local netId, vehicle = qbx.spawnVehicle({
model = model,
spawnSource = ped,
warp = true,
})
exports.qbx_vehiclekeys:GiveKeys(source, vehicle)
return netId
end)
lib.callback.register('qbx_admin:server:getReports', function(source)
if not IsPlayerAceAllowed(source, config.commandPerms.reportReply) then exports.qbx_core:Notify(source, locale('error.no_perms'), 'error') return end
return REPORTS
end)