- 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>
69 lines
2.8 KiB
Lua
69 lines
2.8 KiB
Lua
-- =====================================================================
|
|
-- aether-admin / Modul: Ressourcen
|
|
--
|
|
-- Zeigt die Serverressourcen und erlaubt Start/Stopp/Neustart. Ein
|
|
-- vollständiger Server-Neustart wird angekündigt und protokolliert,
|
|
-- aber NICHT blind ausgeführt — das Beenden des Prozesses überlässt
|
|
-- das Panel bewusst der Server-/txAdmin-Ebene.
|
|
-- =====================================================================
|
|
|
|
Admin = Admin or {}
|
|
|
|
Admin.Kern.Registriere('ressourcen', 'laden', function(handelnder, daten)
|
|
local anzahl = GetNumResources() or 0
|
|
local liste = {}
|
|
for i = 0, anzahl - 1 do
|
|
local name = GetResourceByFindIndex(i)
|
|
if name then
|
|
liste[#liste + 1] = {
|
|
name = name,
|
|
status = GetResourceState(name),
|
|
version = GetResourceMetadata(name, 'version', 0) or '—',
|
|
}
|
|
end
|
|
end
|
|
table.sort(liste, function(a, b) return a.name < b.name end)
|
|
return { ressourcen = liste, rechte = Admin.Kern.RechteAbbild(handelnder.quelle) }
|
|
end)
|
|
|
|
Admin.Kern.Registriere('ressourcen', 'steuern', function(handelnder, daten)
|
|
local name = tostring(daten.name or '')
|
|
local aktion = tostring(daten.aktion or '')
|
|
if GetResourceState(name) == 'missing' then return nil, 'Ressource unbekannt.' end
|
|
if name == GetCurrentResourceName() then
|
|
return nil, 'Das Admin-Panel kann sich nicht selbst steuern.'
|
|
end
|
|
|
|
if aktion == 'start' then StartResource(name)
|
|
elseif aktion == 'stop' then StopResource(name)
|
|
elseif aktion == 'restart' then
|
|
StopResource(name); Wait(150); StartResource(name)
|
|
else
|
|
return nil, 'Unbekannte Aktion.'
|
|
end
|
|
|
|
Admin.Log.Schreibe(handelnder, 'Ressource ' .. aktion, name)
|
|
return { ok = true, status = GetResourceState(name) }
|
|
end)
|
|
|
|
Admin.Kern.Registriere('ressourcen', 'neustart', function(handelnder, daten)
|
|
local minuten = math.max(0, math.floor(tonumber(daten.minuten) or 5))
|
|
local grund = tostring(daten.grund or ''):sub(1, 120)
|
|
|
|
TriggerClientEvent('aether-admin:client:broadcast', -1, {
|
|
typ = 'Neustart',
|
|
text = ('Server-Neustart in %d Minute(n)%s')
|
|
:format(minuten, grund ~= '' and (' — ' .. grund) or ''),
|
|
})
|
|
Admin.Log.Schreibe(handelnder, 'Neustart angekündigt', nil, minuten .. ' min ' .. grund)
|
|
-- Bewusst kein automatisches `quit`: das entscheidet die Betriebsebene.
|
|
return { ok = true, hinweis = 'Angekündigt und protokolliert. Der eigentliche Neustart läuft über die Server-/txAdmin-Ebene.' }
|
|
end)
|
|
|
|
Admin.Kern.Registriere('ressourcen', 'speichern', function(handelnder, daten)
|
|
-- Andere Module können darauf hören und ihren Stand sichern
|
|
TriggerEvent('aether-admin:speichereAlle')
|
|
Admin.Log.Schreibe(handelnder, 'Speichern ausgelöst')
|
|
return { ok = true }
|
|
end)
|