first commit
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
local frozenPlayers = {}
|
||||
|
||||
local function isAdmin(source)
|
||||
return source == 0 or IsPlayerAceAllowed(source, 'devx.admin')
|
||||
end
|
||||
|
||||
local function cleanReason(value)
|
||||
if type(value) ~= 'string' then return 'Keine Begründung angegeben.' end
|
||||
value = value:gsub('^%s+', ''):gsub('%s+$', '')
|
||||
if value == '' then return 'Keine Begründung angegeben.' end
|
||||
return value:sub(1, 255)
|
||||
end
|
||||
|
||||
local function playerRows()
|
||||
local rows = {}
|
||||
for _, id in ipairs(GetPlayers()) do
|
||||
local source = tonumber(id)
|
||||
local player = exports.devx_core:GetPlayer(source)
|
||||
rows[#rows + 1] = {
|
||||
source = source,
|
||||
connectionName = GetPlayerName(source) or ('Spieler %s'):format(source),
|
||||
fullName = player and player.fullName or 'Kein Charakter geladen',
|
||||
characterId = player and player.characterId or nil,
|
||||
phoneNumber = player and player.phoneNumber or nil,
|
||||
cash = player and player.cash or 0,
|
||||
bank = player and player.bank or 0,
|
||||
rpXp = player and player.rpXp or 0,
|
||||
frozen = frozenPlayers[source] == true
|
||||
}
|
||||
end
|
||||
table.sort(rows, function(a, b) return a.source < b.source end)
|
||||
return rows
|
||||
end
|
||||
|
||||
DevXRegisterCallback('admin:bootstrap', function(source)
|
||||
if not isAdmin(source) then return { ok = false, error = 'Keine Administratorberechtigung.' } end
|
||||
|
||||
local weapons = {}
|
||||
for name, label in pairs(DevXConfig.AdminWeapons or {}) do
|
||||
weapons[#weapons + 1] = { name = name, label = label }
|
||||
end
|
||||
table.sort(weapons, function(a, b) return a.label < b.label end)
|
||||
|
||||
return { ok = true, players = playerRows(), weapons = weapons }
|
||||
end)
|
||||
|
||||
DevXRegisterCallback('admin:action', function(source, payload)
|
||||
if not isAdmin(source) then return { ok = false, error = 'Keine Administratorberechtigung.' } end
|
||||
|
||||
local action = tostring(payload.action or '')
|
||||
local target = tonumber(payload.target)
|
||||
local targetPlayer = target and exports.devx_core:GetPlayer(target) or nil
|
||||
|
||||
if action == 'refresh' then return { ok = true, players = playerRows() } end
|
||||
if not target or not GetPlayerName(target) then return { ok = false, error = 'Spieler ist nicht mehr online.' } end
|
||||
|
||||
if action == 'setcash' then
|
||||
local amount = math.floor(tonumber(payload.amount) or -1)
|
||||
if amount < 0 or amount > DevXConfig.MaxMoneyOperation or not targetPlayer then
|
||||
return { ok = false, error = 'Ungültiger Bargeldbetrag.' }
|
||||
end
|
||||
if not exports.devx_core:SetCash(target, amount, ('Admin %s'):format(source)) then
|
||||
return { ok = false, error = 'Bargeld konnte nicht geändert werden.' }
|
||||
end
|
||||
|
||||
elseif action == 'setbank' then
|
||||
local amount = math.floor(tonumber(payload.amount) or -1)
|
||||
if amount < 0 or amount > DevXConfig.MaxMoneyOperation or not targetPlayer then
|
||||
return { ok = false, error = 'Ungültiger Bankbetrag.' }
|
||||
end
|
||||
local success, errorMessage = exports.devx_banking:SetPlayerBalance(target, amount, ('Admin %s'):format(source))
|
||||
if not success then return { ok = false, error = errorMessage } end
|
||||
|
||||
elseif action == 'giveweapon' then
|
||||
local weapon = tostring(payload.weapon or ''):upper()
|
||||
if not DevXConfig.AdminWeapons[weapon] then return { ok = false, error = 'Waffe ist nicht freigegeben.' } end
|
||||
TriggerClientEvent('devx_admin:client:giveWeapon', target, weapon, 250)
|
||||
|
||||
elseif action == 'heal' then
|
||||
TriggerClientEvent('devx_admin:client:heal', target)
|
||||
|
||||
elseif action == 'freeze' then
|
||||
frozenPlayers[target] = not frozenPlayers[target]
|
||||
TriggerClientEvent('devx_admin:client:freeze', target, frozenPlayers[target])
|
||||
|
||||
elseif action == 'goto' then
|
||||
local ped = GetPlayerPed(target)
|
||||
if ped <= 0 then return { ok = false, error = 'Zielposition ist nicht verfügbar.' } end
|
||||
local coords = GetEntityCoords(ped)
|
||||
TriggerClientEvent('devx_admin:client:teleport', source, { x = coords.x, y = coords.y, z = coords.z + 1.0 })
|
||||
|
||||
elseif action == 'bring' then
|
||||
local ped = GetPlayerPed(source)
|
||||
if ped <= 0 then return { ok = false, error = 'Adminposition ist nicht verfügbar.' } end
|
||||
local coords = GetEntityCoords(ped)
|
||||
TriggerClientEvent('devx_admin:client:teleport', target, { x = coords.x, y = coords.y, z = coords.z + 1.0 })
|
||||
|
||||
elseif action == 'setphone' then
|
||||
local number = tostring(payload.phoneNumber or ''):gsub('%s+', '')
|
||||
if not targetPlayer or not number:match('^%d%d%d%-%d%d%d%d+$') or #number > 16 then
|
||||
return { ok = false, error = 'Telefonnummer muss wie 555-1234 aussehen.' }
|
||||
end
|
||||
local duplicate = MySQL.scalar.await('SELECT id FROM devx_characters WHERE phone_number = ? AND id <> ? LIMIT 1', {
|
||||
number, targetPlayer.characterId
|
||||
})
|
||||
if duplicate then return { ok = false, error = 'Telefonnummer ist bereits vergeben.' } end
|
||||
MySQL.update.await('UPDATE devx_characters SET phone_number = ? WHERE id = ?', { number, targetPlayer.characterId })
|
||||
targetPlayer.phoneNumber = number
|
||||
TriggerClientEvent('devx_core:client:playerData', target, targetPlayer)
|
||||
|
||||
elseif action == 'kick' then
|
||||
local reason = cleanReason(payload.reason)
|
||||
DropPlayer(target, ('Du wurdest von einem Administrator getrennt.\nGrund: %s'):format(reason))
|
||||
|
||||
elseif action == 'ban' then
|
||||
local reason = cleanReason(payload.reason)
|
||||
local minutes = math.max(0, math.floor(tonumber(payload.minutes) or 0))
|
||||
local license = exports.devx_core:GetLicense(target)
|
||||
if not license then return { ok = false, error = 'Spielerlizenz konnte nicht ermittelt werden.' } end
|
||||
|
||||
local expiresAt = nil
|
||||
if minutes > 0 then
|
||||
expiresAt = os.date('!%Y-%m-%d %H:%M:%S', os.time() + minutes * 60)
|
||||
end
|
||||
|
||||
MySQL.insert.await([[
|
||||
INSERT INTO devx_bans (license, player_name, reason, banned_by, expires_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
]], {
|
||||
license,
|
||||
targetPlayer and targetPlayer.fullName or GetPlayerName(target),
|
||||
reason,
|
||||
GetPlayerName(source) or ('Admin %s'):format(source),
|
||||
expiresAt
|
||||
})
|
||||
|
||||
DropPlayer(target, ('Du wurdest von DevX-City gesperrt.\nGrund: %s'):format(reason))
|
||||
else
|
||||
return { ok = false, error = 'Unbekannte Adminaktion.' }
|
||||
end
|
||||
|
||||
return { ok = true, players = playerRows() }
|
||||
end)
|
||||
|
||||
AddEventHandler('playerDropped', function()
|
||||
frozenPlayers[source] = nil
|
||||
end)
|
||||
Reference in New Issue
Block a user