aether-framework/resources/[aether]/aether-admin/server/module/dashboard.lua
Jerrit Fritzsche e4b82dd685 Aether-Framework: Fachmodule, Admin-Panel und Docker-Datenbank
- aether-medical: Stationen/Belegung, Intensivstation, Blutbank, Fuhrpark,
  Nachrichten/Aushänge, Berichte und Textbausteine (server + NUI)
- aether-admin: vollständiges Server-Admin-Panel als echtes FiveM-Resource,
  an aether-core gekoppelt (Rechte über aether_users.admin_group), mit
  WebRTC-Live-Kameras (Bildschirmfreigabe) und separatem Media-Server (SFU)
- Prototypen admin/ vervollständigt
- SQL-Schema aether_admin.sql
- Docker-Compose mit MariaDB und idempotenter Auto-Migration (schema_migrations)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 18:55:32 +02:00

60 lines
2.1 KiB
Lua

-- =====================================================================
-- aether-admin / Modul: Dashboard
--
-- Der Überblick. Jede Zahl kommt frisch — nichts wird geschätzt. Die
-- Spielerkurve ist ein echtes, über die Laufzeit gesammeltes Abbild
-- (kein erfundener Verlauf).
-- =====================================================================
Admin = Admin or {}
-- Rollierender Verlauf der Spielerzahl (ein Wert je Sammelintervall)
local verlauf = {}
local MAX_PUNKTE = 24
CreateThread(function()
while true do
local anzahl = #(GetPlayers() or {})
verlauf[#verlauf + 1] = anzahl
if #verlauf > MAX_PUNKTE then table.remove(verlauf, 1) end
Wait(60000) -- jede Minute ein Punkt
end
end)
Admin.Kern.Registriere('dashboard', 'laden', function(handelnder, daten)
local online = #(GetPlayers() or {})
local slots = GetConvarInt('sv_maxclients', 48)
local offeneReports = tonumber(MySQL.scalar.await(
"SELECT COUNT(*) FROM aether_admin_reports WHERE status <> 'geschlossen'")) or 0
local aktiveBans = tonumber(MySQL.scalar.await(
'SELECT COUNT(*) FROM aether_admin_bans WHERE aktiv = 1')) or 0
-- Ressourcen-Kurzstatus
local resAnzahl = GetNumResources() or 0
local laufend = 0
for i = 0, resAnzahl - 1 do
local r = GetResourceByFindIndex(i)
if r and GetResourceState(r) == 'started' then laufend = laufend + 1 end
end
-- Spieler mit hohem Ping (grobe Health-Anzeige)
local hoherPing = 0
for _, sid in ipairs(GetPlayers() or {}) do
if (GetPlayerPing(tonumber(sid)) or 0) >= 120 then hoherPing = hoherPing + 1 end
end
return {
online = online,
slots = slots,
auslastung = slots > 0 and math.floor(online / slots * 100) or 0,
offeneReports = offeneReports,
aktiveBans = aktiveBans,
hoherPing = hoherPing,
ressourcen = { laufend = laufend, gesamt = resAnzahl },
verlauf = #verlauf > 1 and verlauf or { online, online },
letzteLogs = Admin.Log.Lies({ limit = 6 }),
serverName = GetConvar('sv_hostname', 'Aether RP'),
}
end)