- 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>
60 lines
2.1 KiB
Lua
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)
|