- 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>
194 lines
7.7 KiB
Lua
194 lines
7.7 KiB
Lua
-- =====================================================================
|
|
-- aether-admin — Konfiguration (Client + Server)
|
|
--
|
|
-- Alles, was Betreiber anpassen wollen, ohne Code zu ändern. Kein Wert
|
|
-- hier vergibt selbst ein Recht — er beschreibt nur, welches Recht wofür
|
|
-- nötig ist. Die Prüfung selbst passiert immer serverseitig.
|
|
-- =====================================================================
|
|
|
|
AdminConfig = {}
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Rechtegruppen
|
|
--
|
|
-- BEWUSST identisch zu Config.AdminGruppen aus aether-core. Die Hoheit
|
|
-- über die Gruppe eines Spielers liegt in `aether_users.admin_group`;
|
|
-- dieses Modul liest sie nur und rechnet mit derselben Rangordnung.
|
|
-- ---------------------------------------------------------------------
|
|
AdminConfig.Gruppen = {
|
|
['user'] = 0,
|
|
['support'] = 1,
|
|
['admin'] = 2,
|
|
['owner'] = 3,
|
|
}
|
|
|
|
-- Ab welcher Gruppe das Panel überhaupt geöffnet werden darf
|
|
AdminConfig.MindestGruppe = 'support'
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Rechte-Matrix · [modul.aktion] = benötigte Gruppe
|
|
--
|
|
-- Fehlt eine Aktion hier, gilt AdminConfig.StandardRecht. Lesen ist
|
|
-- günstig, Eingreifen teuer, Unwiderrufliches am teuersten.
|
|
-- ---------------------------------------------------------------------
|
|
AdminConfig.StandardRecht = 'admin'
|
|
|
|
AdminConfig.Rechte = {
|
|
-- Überblick & Lesen
|
|
['dashboard.laden'] = 'support',
|
|
['spieler.liste'] = 'support',
|
|
['spieler.details'] = 'support',
|
|
['weltkarte.laden'] = 'support',
|
|
['logs.laden'] = 'admin',
|
|
['team.laden'] = 'support',
|
|
['ressourcen.laden'] = 'admin',
|
|
['wirtschaft.laden'] = 'admin',
|
|
['fraktionen.laden'] = 'admin',
|
|
['immobilien.laden'] = 'admin',
|
|
['fahrzeuge.laden'] = 'admin',
|
|
['staat.laden'] = 'admin',
|
|
['moderation.laden'] = 'support',
|
|
['reports.laden'] = 'support',
|
|
['settings.laden'] = 'admin',
|
|
['broadcast.laden'] = 'support',
|
|
|
|
-- Spieler: Ansicht & Zustand
|
|
['spieler.goto'] = 'admin',
|
|
['spieler.bring'] = 'admin',
|
|
['spieler.spectate'] = 'admin',
|
|
['spieler.kamera'] = 'admin',
|
|
['spieler.heal'] = 'admin',
|
|
['spieler.revive'] = 'admin',
|
|
['spieler.armor'] = 'admin',
|
|
['spieler.freeze'] = 'admin',
|
|
['spieler.god'] = 'admin',
|
|
['spieler.mute'] = 'support',
|
|
['spieler.notiz'] = 'support',
|
|
|
|
-- Spieler: Geben & Setzen
|
|
['spieler.geld'] = 'admin',
|
|
['spieler.item'] = 'admin',
|
|
['spieler.fahrzeug'] = 'admin',
|
|
['spieler.job'] = 'admin',
|
|
|
|
-- Moderation
|
|
['spieler.warn'] = 'support',
|
|
['spieler.kick'] = 'admin',
|
|
['spieler.ban'] = 'admin',
|
|
['moderation.unban'] = 'admin',
|
|
['moderation.warnWeg'] = 'support',
|
|
['moderation.banManuell']= 'admin',
|
|
|
|
-- Reports
|
|
['reports.claim'] = 'support',
|
|
['reports.antwort'] = 'support',
|
|
['reports.status'] = 'support',
|
|
|
|
-- Welt
|
|
['welt.zeit'] = 'admin',
|
|
['welt.wetter'] = 'admin',
|
|
['welt.blackout'] = 'admin',
|
|
['welt.cleanup'] = 'admin',
|
|
['broadcast.senden'] = 'admin',
|
|
|
|
-- Fahrzeuge
|
|
['fahrzeuge.spawn'] = 'admin',
|
|
['fahrzeuge.reparieren'] = 'admin',
|
|
['fahrzeuge.herholen'] = 'admin',
|
|
['fahrzeuge.loeschen'] = 'admin',
|
|
['fahrzeuge.aufraeumen'] = 'admin',
|
|
|
|
-- Wirtschaft / Fraktionen / Immobilien / Staat
|
|
['wirtschaft.geldAlle'] = 'owner',
|
|
['wirtschaft.kasse'] = 'owner',
|
|
['wirtschaft.steuer'] = 'owner',
|
|
['fraktionen.speichern'] = 'admin',
|
|
['fraktionen.loeschen'] = 'owner',
|
|
['fraktionen.payday'] = 'admin',
|
|
['immobilien.zuweisen'] = 'admin',
|
|
['immobilien.raeumen'] = 'admin',
|
|
['staat.beenden'] = 'admin',
|
|
['staat.aktivieren'] = 'owner',
|
|
['staat.archivieren'] = 'admin',
|
|
|
|
-- System (nur Owner)
|
|
['ressourcen.steuern'] = 'owner',
|
|
['ressourcen.neustart'] = 'owner',
|
|
['settings.speichern'] = 'owner',
|
|
['team.speichern'] = 'owner',
|
|
['team.entfernen'] = 'owner',
|
|
|
|
-- Kameras (WebRTC)
|
|
['kamera.oeffnen'] = 'admin',
|
|
['kamera.schliessen'] = 'admin',
|
|
}
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Sektionen der Seitenleiste · min = ab welcher Gruppe sichtbar
|
|
-- Reihenfolge wie im Panel. `grp` gruppiert nur optisch.
|
|
-- ---------------------------------------------------------------------
|
|
AdminConfig.Sektionen = {
|
|
{ grp = 'Überblick' },
|
|
{ id = 'dashboard', label = 'Dashboard', icon = '📊', min = 'support' },
|
|
{ id = 'weltkarte', label = 'Weltkarte', icon = '🗺️', min = 'support' },
|
|
{ grp = 'Verwaltung' },
|
|
{ id = 'spieler', label = 'Spieler', icon = '👥', min = 'support' },
|
|
{ id = 'fahrzeuge', label = 'Fahrzeuge', icon = '🚗', min = 'admin' },
|
|
{ id = 'immobilien', label = 'Immobilien', icon = '🏠', min = 'admin' },
|
|
{ id = 'fraktionen', label = 'Fraktionen', icon = '🚔', min = 'admin' },
|
|
{ id = 'wirtschaft', label = 'Wirtschaft', icon = '💰', min = 'admin' },
|
|
{ id = 'staat', label = 'Staatsprojekte', icon = '🏛️', min = 'admin' },
|
|
{ grp = 'Überwachung' },
|
|
{ id = 'cams', label = 'Live-Kameras', icon = '📹', min = 'admin' },
|
|
{ grp = 'Welt' },
|
|
{ id = 'welt', label = 'Weltsteuerung', icon = '🌍', min = 'admin' },
|
|
{ id = 'broadcast', label = 'Ankündigungen', icon = '📢', min = 'support' },
|
|
{ grp = 'Moderation' },
|
|
{ id = 'moderation', label = 'Bans & Warns', icon = '🔨', min = 'support' },
|
|
{ id = 'reports', label = 'Reports', icon = '🎫', min = 'support' },
|
|
{ grp = 'System' },
|
|
{ id = 'ressourcen', label = 'Ressourcen', icon = '🧩', min = 'admin' },
|
|
{ id = 'logs', label = 'Audit-Log', icon = '📜', min = 'admin' },
|
|
{ id = 'team', label = 'Admin-Team', icon = '⭐', min = 'support' },
|
|
{ id = 'settings', label = 'Einstellungen', icon = '⚙️', min = 'owner' },
|
|
}
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Live-Kameras (WebRTC)
|
|
--
|
|
-- Öffentliche Angaben. Das gemeinsame Geheimnis für die Token-Signatur
|
|
-- liegt NICHT hier, sondern serverseitig in der Convar `aether_admin_media_secret`
|
|
-- — sonst könnte jeder Client es aus dem geteilten Code lesen.
|
|
-- ---------------------------------------------------------------------
|
|
AdminConfig.Media = {
|
|
-- Ist die WebRTC-Kamera aktiv? Bei false zeigt das Panel nur den Hinweis.
|
|
aktiv = true,
|
|
-- WebSocket-Adresse des Media-Servers (Signaling + SFU), vom NUI erreichbar.
|
|
-- Auf den öffentlichen Host/Port des Media-Servers zeigen lassen.
|
|
url = 'ws://127.0.0.1:8787',
|
|
-- Wie lange ein ausgestelltes Zugangstoken gilt (Sekunden)
|
|
tokenGueltig = 30,
|
|
}
|
|
|
|
--- Rechnet den Rang einer Gruppe aus (unbekannt = 0)
|
|
--- @param gruppe string|nil
|
|
--- @return number
|
|
function AdminConfig.Rang(gruppe)
|
|
return AdminConfig.Gruppen[gruppe or 'user'] or 0
|
|
end
|
|
|
|
--- Erfüllt `gruppe` mindestens `benoetigt`?
|
|
--- @param gruppe string|nil Gruppe des Spielers
|
|
--- @param benoetigt string|nil Geforderte Gruppe
|
|
--- @return boolean
|
|
function AdminConfig.Erfuellt(gruppe, benoetigt)
|
|
return AdminConfig.Rang(gruppe) >= AdminConfig.Rang(benoetigt)
|
|
end
|
|
|
|
--- Welche Gruppe braucht eine Aktion?
|
|
--- @param schluessel string 'modul.aktion'
|
|
--- @return string
|
|
function AdminConfig.RechtFuer(schluessel)
|
|
return AdminConfig.Rechte[schluessel] or AdminConfig.StandardRecht
|
|
end
|