aether-framework/resources/[aether]/aether-admin/server/module/fahrzeuge.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

86 lines
3.6 KiB
Lua

-- =====================================================================
-- aether-admin / Modul: Fahrzeuge
--
-- Die Fahrzeuge in der Welt — serverseitig über GetAllVehicles erfasst,
-- also echt und nicht simuliert. Löschen und Aufräumen geschehen direkt
-- serverseitig; Reparieren und Herholen brauchen einen Client in der
-- Nähe und werden dorthin weitergereicht.
-- =====================================================================
Admin = Admin or {}
Admin.Kern.Registriere('fahrzeuge', 'laden', function(handelnder, daten)
local liste = {}
for _, veh in ipairs(GetAllVehicles() or {}) do
local pos = GetEntityCoords(veh)
local leer = GetVehicleNumberOfPassengers(veh) == 0 and IsVehicleSeatFree(veh, -1)
liste[#liste + 1] = {
netId = NetworkGetNetworkIdFromEntity(veh),
plate = (GetVehicleNumberPlateText(veh) or ''):gsub('%s+$', ''),
x = pos.x, y = pos.y, z = pos.z,
leer = leer,
}
if #liste >= 300 then break end
end
-- Online-Spieler als mögliche Empfänger eines Spawns
local online = {}
for _, sid in ipairs(GetPlayers() or {}) do
online[#online + 1] = { id = tonumber(sid), name = GetPlayerName(tonumber(sid)) }
end
return { fahrzeuge = liste, anzahl = #liste, spieler = online,
rechte = Admin.Kern.RechteAbbild(handelnder.quelle) }
end)
Admin.Kern.Registriere('fahrzeuge', 'spawn', function(handelnder, daten)
local modell = tostring(daten.modell or ''):gsub('%s', '')
if modell == '' then return nil, 'Kein Modell gewählt.' end
local ziel = tonumber(daten.ziel) or handelnder.quelle
if not GetPlayerName(ziel) then return nil, 'Ziel ist offline.' end
TriggerClientEvent('aether-admin:client:fahrzeug', ziel, modell)
Admin.Log.Schreibe(handelnder, 'Fahrzeug gespawnt', GetPlayerName(ziel), modell)
return { ok = true }
end)
Admin.Kern.Registriere('fahrzeuge', 'loeschen', function(handelnder, daten)
local netId = tonumber(daten.netId)
if not netId then return nil, 'Ungültige Kennung.' end
local veh = NetworkGetEntityFromNetworkId(netId)
if not veh or veh == 0 or not DoesEntityExist(veh) then
return nil, 'Fahrzeug existiert nicht mehr.'
end
DeleteEntity(veh)
Admin.Log.Schreibe(handelnder, 'Fahrzeug gelöscht', nil, 'net ' .. netId)
return { ok = true }
end)
Admin.Kern.Registriere('fahrzeuge', 'reparieren', function(handelnder, daten)
local netId = tonumber(daten.netId)
if not netId then return nil, 'Ungültige Kennung.' end
-- Der Client des Admins repariert, sobald das Fahrzeug in Reichweite ist
TriggerClientEvent('aether-admin:client:fahrzeugFix', handelnder.quelle, netId)
Admin.Log.Schreibe(handelnder, 'Fahrzeug repariert', nil, 'net ' .. netId)
return { ok = true }
end)
Admin.Kern.Registriere('fahrzeuge', 'herholen', function(handelnder, daten)
local netId = tonumber(daten.netId)
if not netId then return nil, 'Ungültige Kennung.' end
TriggerClientEvent('aether-admin:client:fahrzeugHer', handelnder.quelle, netId)
Admin.Log.Schreibe(handelnder, 'Fahrzeug hergeholt', nil, 'net ' .. netId)
return { ok = true }
end)
Admin.Kern.Registriere('fahrzeuge', 'aufraeumen', function(handelnder, daten)
local entfernt = 0
for _, veh in ipairs(GetAllVehicles() or {}) do
if GetVehicleNumberOfPassengers(veh) == 0 and IsVehicleSeatFree(veh, -1) then
DeleteEntity(veh); entfernt = entfernt + 1
end
end
Admin.Log.Schreibe(handelnder, 'Fahrzeuge aufgeräumt', nil, entfernt .. ' entfernt')
return { ok = true, entfernt = entfernt }
end)