1
0
Fork 0
forked from Simnation/Main
Main/resources/[carscripts]/nordi_antidespawn/server/main.lua

400 lines
14 KiB
Lua
Raw Normal View History

2025-08-06 17:33:26 +02:00
local QBCore = exports['qb-core']:GetCoreObject()
2025-08-06 18:18:04 +02:00
local vehicles = {}
-- Debug Funktion
local function Debug(msg)
if Config.Debug then
print("[AntiDespawn] " .. msg)
end
end
2025-08-06 17:33:26 +02:00
-- Erstelle Tabelle bei Serverstart
CreateThread(function()
2025-08-06 19:45:59 +02:00
-- Prüfe ob die Tabelle existiert
MySQL.query("SHOW TABLES LIKE 'vehicle_antidespawn'", {}, function(result)
if result and #result > 0 then
-- Tabelle existiert, prüfe ob das mods-Feld existiert
MySQL.query("SHOW COLUMNS FROM vehicle_antidespawn LIKE 'mods'", {}, function(columns)
if columns and #columns == 0 then
-- mods-Feld existiert nicht, füge es hinzu
Debug("Füge mods-Feld zur Tabelle hinzu...")
MySQL.query("ALTER TABLE vehicle_antidespawn ADD COLUMN mods LONGTEXT DEFAULT NULL", {})
end
end)
else
-- Tabelle existiert nicht, erstelle sie
Debug("Erstelle Datenbank-Tabelle...")
MySQL.query([[
CREATE TABLE IF NOT EXISTS `vehicle_antidespawn` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`plate` varchar(50) NOT NULL,
`model` varchar(50) NOT NULL,
`coords` longtext NOT NULL,
`heading` float NOT NULL,
`fuel` int(11) DEFAULT 100,
`mods` longtext DEFAULT NULL,
`last_updated` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `plate` (`plate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
]])
end
end)
2025-08-06 18:18:04 +02:00
Debug("Datenbank initialisiert")
2025-08-06 19:45:59 +02:00
-- Warte kurz, bis die Tabelle aktualisiert wurde
Wait(1000)
2025-08-06 18:18:04 +02:00
-- Lade alle Fahrzeuge aus der Datenbank
MySQL.query("SELECT * FROM vehicle_antidespawn", {}, function(results)
if results and #results > 0 then
Debug("Lade " .. #results .. " Fahrzeuge aus der Datenbank")
for _, vehicle in pairs(results) do
vehicles[vehicle.plate] = {
model = vehicle.model,
coords = json.decode(vehicle.coords),
heading = vehicle.heading,
fuel = vehicle.fuel,
2025-08-06 19:45:59 +02:00
mods = vehicle.mods and json.decode(vehicle.mods) or nil,
2025-08-06 18:18:04 +02:00
last_updated = vehicle.last_updated
}
end
end
end)
2025-08-06 17:33:26 +02:00
end)
2025-08-06 18:18:04 +02:00
-- Registriere ein Fahrzeug
2025-08-06 18:50:02 +02:00
RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, coords, heading, mods)
2025-08-06 17:33:26 +02:00
local src = source
2025-08-06 18:18:04 +02:00
if not plate or not model or not coords then
Debug("Ungültige Daten beim Registrieren eines Fahrzeugs")
return
end
2025-08-06 17:33:26 +02:00
2025-08-06 19:16:18 +02:00
-- Stelle sicher, dass das Modell als Zahl gespeichert wird
if type(model) == "string" then
model = tonumber(model) or model
end
2025-08-06 18:32:55 +02:00
-- Prüfe ob Fahrzeug in der Garage ist
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND state = ?', {plate, 1}, function(result)
if result and #result > 0 then
Debug("Fahrzeug ist in der Garage, nicht registrieren: " .. plate)
2025-08-06 19:45:59 +02:00
-- Entferne aus Anti-Despawn Datenbank falls vorhanden
if vehicles[plate] then
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
Debug("Fahrzeug aus Anti-Despawn entfernt: " .. plate)
end
2025-08-06 18:32:55 +02:00
return
end
vehicles[plate] = {
model = model,
coords = coords,
heading = heading,
fuel = 100,
2025-08-06 18:50:02 +02:00
mods = mods,
2025-08-06 18:32:55 +02:00
last_updated = os.time()
}
2025-08-06 19:47:17 +02:00
MySQL.query("INSERT INTO vehicle_antidespawn (plate, model, coords, heading, fuel, mods) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE coords = VALUES(coords), heading = VALUES(heading), mods = VALUES(mods), last_updated = CURRENT_TIMESTAMP", {
plate,
tostring(model), -- Speichere als String in der Datenbank
json.encode(coords),
heading,
100,
json.encode(mods)
})
2025-08-06 18:32:55 +02:00
2025-08-06 19:47:17 +02:00
Debug("Fahrzeug registriert: " .. plate .. " (Modell: " .. tostring(model) .. ")")
end)
end)
-- Aktualisiere ein Fahrzeug
RegisterNetEvent('antidespawn:server:updateVehicle', function(plate, coords, heading, mods)
if not vehicles[plate] then return end
-- Prüfe ob Fahrzeug in der Garage ist
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND state = ?', {plate, 1}, function(result)
if result and #result > 0 then
Debug("Fahrzeug ist in der Garage, entferne aus Tracking: " .. plate)
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
plate
})
return
end
vehicles[plate].coords = coords
vehicles[plate].heading = heading
vehicles[plate].mods = mods
vehicles[plate].last_updated = os.time()
MySQL.query("UPDATE vehicle_antidespawn SET coords = ?, heading = ?, mods = ?, last_updated = CURRENT_TIMESTAMP WHERE plate = ?", {
json.encode(coords),
heading,
json.encode(mods),
plate
})
Debug("Fahrzeug aktualisiert: " .. plate)
end)
end)
-- Entferne ein Fahrzeug
RegisterNetEvent('antidespawn:server:removeVehicle', function(plate)
if not vehicles[plate] then return end
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
plate
})
Debug("Fahrzeug entfernt: " .. plate)
end)
-- Respawn ein Fahrzeug
RegisterNetEvent('antidespawn:server:respawnVehicle', function(plate)
local src = source
if not vehicles[plate] then
Debug("Fahrzeug nicht in Datenbank: " .. plate)
return
end
-- Prüfe ob Fahrzeug in der Garage ist
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND state = ?', {plate, 1}, function(result)
if result and #result > 0 then
Debug("Fahrzeug ist in der Garage, nicht respawnen: " .. plate)
-- Entferne aus Anti-Despawn Datenbank
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
plate
})
return
end
-- Sende Spawn-Event zurück an den Client
TriggerClientEvent('antidespawn:client:spawnVehicle', src, {
plate = plate,
model = vehicles[plate].model,
coords = vehicles[plate].coords,
heading = vehicles[plate].heading,
fuel = vehicles[plate].fuel,
mods = vehicles[plate].mods
})
Debug("Fahrzeug Respawn angefordert: " .. plate)
end)
end)
-- Lade Fahrzeuge für einen Spieler
RegisterNetEvent('antidespawn:server:loadVehicles', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then
Debug("Spieler nicht gefunden")
return
end
Debug("Lade Fahrzeuge für Spieler: " .. Player.PlayerData.citizenid)
local playerCoords = GetEntityCoords(GetPlayerPed(src))
local loadedCount = 0
local vehiclesToLoad = {}
-- Sammle alle Fahrzeuge, die geladen werden sollen
for plate, vehicle in pairs(vehicles) do
-- Prüfe ob das Fahrzeug in der Garage ist
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ?', {plate}, function(result)
-- Prüfe ob das Fahrzeug überhaupt existiert
if not result or #result == 0 then
Debug("Fahrzeug existiert nicht in player_vehicles: " .. plate)
-- Entferne aus Anti-Despawn Datenbank
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
return
end
-- Prüfe ob das Fahrzeug in der Garage ist (state = 1)
local inGarage = false
for _, veh in ipairs(result) do
if veh.state == 1 then
inGarage = true
break
end
end
if inGarage then
Debug("Fahrzeug ist in der Garage, nicht laden: " .. plate)
-- Entferne aus Anti-Despawn Datenbank
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
return
end
-- Lade nur Fahrzeuge in der Nähe des Spielers
local distance = #(playerCoords - vector3(vehicle.coords.x, vehicle.coords.y, vehicle.coords.z))
if distance < 100.0 then
-- Stelle sicher, dass das Modell als Zahl gespeichert ist
local model = vehicle.model
if type(model) == "string" then
model = tonumber(model) or model
end
table.insert(vehiclesToLoad, {
plate = plate,
model = model,
coords = vehicle.coords,
heading = vehicle.heading,
fuel = vehicle.fuel,
mods = vehicle.mods
})
loadedCount = loadedCount + 1
end
end)
end
-- Warte kurz und lade dann die Fahrzeuge
SetTimeout(3000, function()
for _, vehicleData in ipairs(vehiclesToLoad) do
TriggerClientEvent('antidespawn:client:spawnVehicle', src, vehicleData)
Debug("Fahrzeug für Spieler geladen: " .. vehicleData.plate)
end
Debug("Fahrzeugladung abgeschlossen. " .. loadedCount .. " Fahrzeuge geladen.")
end)
end)
-- Cleanup alte Einträge (älter als 24 Stunden)
CreateThread(function()
while true do
Wait(3600000) -- 1 Stunde
MySQL.query("DELETE FROM vehicle_antidespawn WHERE last_updated < DATE_SUB(NOW(), INTERVAL 24 HOUR)")
Debug("Alte Fahrzeugeinträge bereinigt")
end
end)
-- Registriere jg-advancedgarages Events
RegisterNetEvent('jg-advancedgarages:server:vehicle-stored', function(data)
if data and data.plate then
Debug("Fahrzeug in Garage gespeichert: " .. data.plate)
-- Entferne aus Anti-Despawn Datenbank
if vehicles[data.plate] then
vehicles[data.plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
data.plate
})
Debug("Fahrzeug aus Anti-Despawn entfernt: " .. data.plate)
end
end
end)
RegisterNetEvent('jg-advancedgarages:server:vehicle-spawned', function(data)
if data and data.plate then
Debug("Fahrzeug aus Garage gespawnt: " .. data.plate)
-- Entferne aus Anti-Despawn Datenbank, da es jetzt von der Garage verwaltet wird
if vehicles[data.plate] then
vehicles[data.plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
data.plate
})
Debug("Fahrzeug aus Anti-Despawn entfernt: " .. data.plate)
end
end
end)
-- Befehl zum Anzeigen aller gespeicherten Fahrzeuge
RegisterCommand('listvehicles', function(source, args, rawCommand)
if source == 0 then -- Nur über Konsole ausführbar
Debug("Gespeicherte Fahrzeuge:")
local count = 0
for plate, vehicle in pairs(vehicles) do
Debug(plate .. " - Modell: " .. tostring(vehicle.model) .. " - Position: " ..
tostring(vehicle.coords.x) .. ", " .. tostring(vehicle.coords.y) .. ", " .. tostring(vehicle.coords.z))
count = count + 1
end
Debug("Insgesamt " .. count .. " Fahrzeuge gespeichert.")
end
end, true)
-- Befehl zum Prüfen des Garage-Status eines Fahrzeugs
RegisterCommand('checkgarage', function(source, args, rawCommand)
if source == 0 and args[1] then -- Nur über Konsole ausführbar
local plate = args[1]
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ?', {plate}, function(result)
if result and #result > 0 then
for _, veh in ipairs(result) do
Debug("Fahrzeug " .. plate .. " - State: " .. veh.state .. " - Owner: " .. veh.citizenid)
end
else
Debug("Fahrzeug " .. plate .. " nicht in player_vehicles gefunden.")
end
end)
end
end, true)
-- Befehl zum manuellen Entfernen eines Fahrzeugs
RegisterCommand('removevehicle', function(source, args, rawCommand)
if source == 0 and args[1] then -- Nur über Konsole ausführbar
local plate = args[1]
if vehicles[plate] then
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
Debug("Fahrzeug " .. plate .. " aus Anti-Despawn entfernt.")
else
Debug("Fahrzeug " .. plate .. " nicht in Anti-Despawn gefunden.")
end
end
end, true)
-- Befehl zum Bereinigen der Datenbank
RegisterCommand('clearvehicles', function(source, args, rawCommand)
if source == 0 then -- Nur über Konsole ausführbar
local count = 0
for plate, vehicle in pairs(vehicles) do
local model = vehicle.model
-- Prüfe ob das Modell gültig ist
if type(model) == "string" and not tonumber(model) then
-- Ungültiges Modell, entferne aus Datenbank
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
vehicles[plate] = nil
count = count + 1
Debug("Ungültiges Modell entfernt: " .. plate .. " (Modell: " .. tostring(model) .. ")")
end
end
Debug("Bereinigung abgeschlossen. " .. count .. " Fahrzeuge entfernt.")
end
end, true)
-- Befehl zum Leeren der Datenbank
RegisterCommand('clearalldespawn', function(source, args, rawCommand)
if source == 0 then -- Nur über Konsole ausführbar
MySQL.query("DELETE FROM vehicle_antidespawn", {})
vehicles = {}
Debug("Alle Fahrzeuge aus der Datenbank entfernt.")
end
end, true)