diff --git a/resources/[carscripts]/nordi_antidespawn/client/main.lua b/resources/[carscripts]/nordi_antidespawn/client/main.lua index 06229eb5b..204240ba7 100644 --- a/resources/[carscripts]/nordi_antidespawn/client/main.lua +++ b/resources/[carscripts]/nordi_antidespawn/client/main.lua @@ -119,6 +119,11 @@ local function SetVehicleMods(vehicle, mods) -- Setze Modkit SetVehicleModKit(vehicle, 0) + -- Rad Typ zuerst setzen + if mods.wheelType then + SetVehicleWheelType(vehicle, mods.wheelType) + end + -- Basis Mods for i = 0, 49 do if mods[tostring(i)] ~= nil then @@ -180,13 +185,9 @@ local function SetVehicleMods(vehicle, mods) SetVehicleWindowTint(vehicle, mods.windowTint) end - -- Rad Typ - if mods.wheelType then - SetVehicleWheelType(vehicle, mods.wheelType) - end - -- Rauch Farbe if mods.tyreSmokeColor then + ToggleVehicleMod(vehicle, 20, true) -- Aktiviere Rauch SetVehicleTyreSmokeColor(vehicle, mods.tyreSmokeColor.r, mods.tyreSmokeColor.g, mods.tyreSmokeColor.b) end @@ -207,6 +208,15 @@ local function SetVehicleMods(vehicle, mods) if mods.turbo ~= nil then ToggleVehicleMod(vehicle, 18, mods.turbo) end + + -- Setze Felgen nochmal explizit + if mods["23"] ~= nil then -- Vorderräder + SetVehicleMod(vehicle, 23, mods["23"], false) + end + + if mods["24"] ~= nil then -- Hinterräder + SetVehicleMod(vehicle, 24, mods["24"], false) + end end -- Extrem starke Anti-Despawn Funktion @@ -341,19 +351,34 @@ end) -- Lade Fahrzeuge beim Spawn RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() - Debug("Spieler geladen, lade Fahrzeuge...") - Wait(10000) -- Warte bis alles geladen ist + Debug("Spieler geladen, warte vor dem Laden der Fahrzeuge...") + -- Längere Wartezeit, um sicherzustellen, dass alles geladen ist + Wait(15000) TriggerServerEvent('antidespawn:server:loadVehicles') end) --- Lade Fahrzeuge auch beim Resource Start +-- Automatisches Laden beim Resource Start CreateThread(function() - Wait(15000) -- Warte bis alles geladen ist + -- Längere Wartezeit beim Serverstart + Wait(20000) + -- Prüfe ob Spieler eingeloggt ist local playerData = QBCore.Functions.GetPlayerData() if playerData and playerData.citizenid then Debug("Resource gestartet, lade Fahrzeuge...") TriggerServerEvent('antidespawn:server:loadVehicles') + else + -- Warte auf Login, wenn Spieler noch nicht eingeloggt ist + Debug("Warte auf Spieler-Login...") + while true do + Wait(5000) + playerData = QBCore.Functions.GetPlayerData() + if playerData and playerData.citizenid then + Debug("Spieler jetzt eingeloggt, lade Fahrzeuge...") + TriggerServerEvent('antidespawn:server:loadVehicles') + break + end + end end end) @@ -457,38 +482,9 @@ RegisterNetEvent('antidespawn:client:spawnVehicle', function(data) SetModelAsNoLongerNeeded(modelHash) else Debug("Modell konnte nicht geladen werden: " .. data.plate .. " (Hash: " .. tostring(modelHash) .. ")") - - -- Versuche es mit einem Standard-Fahrzeug als Fallback - local fallbackModel = GetHashKey("adder") - RequestModel(fallbackModel) - - timeout = 0 - while not HasModelLoaded(fallbackModel) and timeout < 50 do - Wait(100) - timeout = timeout + 1 - end - - if HasModelLoaded(fallbackModel) then - Debug("Verwende Fallback-Modell") - local vehicle = CreateVehicle(fallbackModel, data.coords.x, data.coords.y, data.coords.z, data.heading, true, false) - - if DoesEntityExist(vehicle) then - SetVehicleNumberPlateText(vehicle, data.plate) - PreventDespawn(vehicle) - trackedVehicles[data.plate] = vehicle - lastKnownCoords[data.plate] = GetEntityCoords(vehicle) - - Debug("Fahrzeug mit Fallback-Modell gespawnt: " .. data.plate) - end - - SetModelAsNoLongerNeeded(fallbackModel) - else - Debug("Auch Fallback-Modell konnte nicht geladen werden!") - end end end) - -- Hilfsfunktion um Fahrzeug anhand Kennzeichen zu finden function GetVehicleByPlate(plate) local vehicles = GetGamePool('CVehicle') @@ -531,10 +527,12 @@ RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data) if trackedVehicles[data.plate] then trackedVehicles[data.plate] = nil lastKnownCoords[data.plate] = nil - TriggerServerEvent('antidespawn:server:removeVehicle', data.plate) end - Debug("Fahrzeug in Garage gespeichert: " .. data.plate) + -- Entferne aus Datenbank + TriggerServerEvent('antidespawn:server:removeVehicle', data.plate) + + Debug("Fahrzeug in Garage gespeichert, aus DB entfernt: " .. data.plate) end end) @@ -585,6 +583,12 @@ RegisterNetEvent('jg-advancedgarages:client:open-garage', function(garageId, veh end end) +-- Manuelle Lade-Funktion +RegisterCommand('loadvehicles', function() + Debug("Manuelles Laden der Fahrzeuge...") + TriggerServerEvent('antidespawn:server:loadVehicles') +end, false) + -- Debug Command RegisterCommand('fixvehicle', function() local playerPed = PlayerPedId() diff --git a/resources/[carscripts]/nordi_antidespawn/server/main.lua b/resources/[carscripts]/nordi_antidespawn/server/main.lua index 4263cdc19..4973bc4eb 100644 --- a/resources/[carscripts]/nordi_antidespawn/server/main.lua +++ b/resources/[carscripts]/nordi_antidespawn/server/main.lua @@ -10,23 +10,42 @@ end -- Erstelle Tabelle bei Serverstart CreateThread(function() - 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; - ]]) + -- 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) Debug("Datenbank initialisiert") + -- Warte kurz, bis die Tabelle aktualisiert wurde + Wait(1000) + -- Lade alle Fahrzeuge aus der Datenbank MySQL.query("SELECT * FROM vehicle_antidespawn", {}, function(results) if results and #results > 0 then @@ -38,7 +57,7 @@ CreateThread(function() coords = json.decode(vehicle.coords), heading = vehicle.heading, fuel = vehicle.fuel, - mods = json.decode(vehicle.mods), + mods = vehicle.mods and json.decode(vehicle.mods) or nil, last_updated = vehicle.last_updated } end @@ -64,6 +83,13 @@ RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, co 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) + + -- 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 return end @@ -76,195 +102,4 @@ RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, co last_updated = os.time() } - 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) - }) - - 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) - --- 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 return end - - local playerCoords = GetEntityCoords(GetPlayerPed(src)) - - -- Prüfe für jedes Fahrzeug, ob es in der Garage ist - for plate, vehicle in pairs(vehicles) do - 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 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 - TriggerClientEvent('antidespawn:client:spawnVehicle', src, { - plate = plate, - model = vehicle.model, - coords = vehicle.coords, - heading = vehicle.heading, - fuel = vehicle.fuel, - mods = vehicle.mods - }) - - Debug("Fahrzeug für Spieler geladen: " .. plate) - end - end) - 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 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) + MySQL.query("INSERT INTO vehicle_antidespawn (plate, model, coords, heading, fuel