local QBCore = exports['qb-core']:GetCoreObject() local trackedVehicles = {} local lastKnownCoords = {} -- Debug Funktion local function Debug(msg) if Config.Debug then print("[AntiDespawn] " .. msg) end end -- Funktion um zu prüfen ob Fahrzeugklasse erlaubt ist local function IsVehicleClassAllowed(vehicle) local vehicleClass = GetVehicleClass(vehicle) -- Prüfe Blacklist for _, blacklistedClass in pairs(Config.BlacklistedVehicleClasses) do if vehicleClass == blacklistedClass then return false end end -- Prüfe Whitelist for _, allowedClass in pairs(Config.AllowedVehicleClasses) do if vehicleClass == allowedClass then return true end end return false end -- Extrem starke Anti-Despawn Funktion local function PreventDespawn(vehicle) if not DoesEntityExist(vehicle) then return false end -- Grundlegende Persistenz SetEntityAsMissionEntity(vehicle, true, true) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) -- Zusätzliche Flags SetEntityLoadCollisionFlag(vehicle, true) SetVehicleIsStolen(vehicle, false) SetVehicleIsWanted(vehicle, false) -- Verhindere dass das Fahrzeug als "abandoned" markiert wird if DecorIsRegisteredAsType("IgnoredByQuickSave", 2) then DecorSetBool(vehicle, "IgnoredByQuickSave", false) end -- Setze Fahrzeug auf Boden SetVehicleOnGroundProperly(vehicle) -- Verhindere dass das Fahrzeug gelöscht wird NetworkRegisterEntityAsNetworked(vehicle) local netID = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdExistsOnAllMachines(netID, true) SetNetworkIdCanMigrate(netID, true) return true end -- Event Handler für Fahrzeug betreten (nur Fahrersitz) CreateThread(function() local lastVehicle = 0 while true do Wait(1000) local playerPed = PlayerPedId() local currentVehicle = GetVehiclePedIsIn(playerPed, false) -- Spieler ist als Fahrer in ein Fahrzeug eingestiegen if currentVehicle ~= 0 and currentVehicle ~= lastVehicle then -- Prüfe ob Spieler auf Fahrersitz ist local driver = GetPedInVehicleSeat(currentVehicle, -1) -- Nur wenn Spieler der Fahrer ist (Seat -1) if driver == playerPed and IsVehicleClassAllowed(currentVehicle) then local plate = QBCore.Functions.GetPlate(currentVehicle) trackedVehicles[plate] = currentVehicle -- Speichere letzte bekannte Position lastKnownCoords[plate] = GetEntityCoords(currentVehicle) -- Sofort starke Despawn-Verhinderung PreventDespawn(currentVehicle) Debug("Fahrzeug wird nun getrackt: " .. plate) -- Registriere Fahrzeug beim Server local vehicleCoords = GetEntityCoords(currentVehicle) local vehicleHeading = GetEntityHeading(currentVehicle) local vehicleModel = GetEntityModel(currentVehicle) TriggerServerEvent('antidespawn:server:registerVehicle', plate, vehicleModel, vehicleCoords, vehicleHeading) end end lastVehicle = currentVehicle end end) -- Kontinuierliche Despawn-Verhinderung für alle getrackten Fahrzeuge CreateThread(function() while true do Wait(5000) -- Alle 5 Sekunden for plate, vehicle in pairs(trackedVehicles) do if DoesEntityExist(vehicle) then PreventDespawn(vehicle) -- Aktualisiere letzte bekannte Position lastKnownCoords[plate] = GetEntityCoords(vehicle) -- Aktualisiere Position local vehicleCoords = GetEntityCoords(vehicle) local vehicleHeading = GetEntityHeading(vehicle) TriggerServerEvent('antidespawn:server:updateVehicle', plate, vehicleCoords, vehicleHeading) Debug("Aktualisiere Fahrzeug: " .. plate) else Debug("Fahrzeug existiert nicht mehr: " .. plate) -- Versuche Fahrzeug wiederherzustellen if lastKnownCoords[plate] then Debug("Versuche Fahrzeug wiederherzustellen: " .. plate) TriggerServerEvent('antidespawn:server:respawnVehicle', plate) -- Entferne aus lokaler Tracking-Liste, wird nach Respawn wieder hinzugefügt trackedVehicles[plate] = nil end end end end end) -- Lade Fahrzeuge beim Spawn RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() Debug("Spieler geladen, lade Fahrzeuge...") Wait(10000) -- Warte bis alles geladen ist TriggerServerEvent('antidespawn:server:loadVehicles') end) -- Spawne ein Fahrzeug RegisterNetEvent('antidespawn:client:spawnVehicle', function(data) Debug("Spawne Fahrzeug: " .. data.plate) -- Prüfe ob Fahrzeug bereits existiert local existingVehicle = GetVehicleByPlate(data.plate) if existingVehicle then Debug("Fahrzeug existiert bereits: " .. data.plate) trackedVehicles[data.plate] = existingVehicle lastKnownCoords[data.plate] = GetEntityCoords(existingVehicle) PreventDespawn(existingVehicle) return end -- Spawne Fahrzeug local modelHash = data.model RequestModel(modelHash) local timeout = 0 while not HasModelLoaded(modelHash) and timeout < 100 do Wait(100) timeout = timeout + 1 end if HasModelLoaded(modelHash) then -- Verwende CREATE_AUTOMOBILE für bessere Persistenz local vehicle if Citizen and Citizen.InvokeNative then -- OneSync Methode vehicle = Citizen.InvokeNative(0xAF35D0D2583051B0, modelHash, data.coords.x, data.coords.y, data.coords.z, data.heading, true, true) else -- Fallback vehicle = CreateVehicle(modelHash, data.coords.x, data.coords.y, data.coords.z, data.heading, true, false) end if DoesEntityExist(vehicle) then -- Warte bis Fahrzeug vollständig geladen ist Wait(500) -- Setze Kennzeichen SetVehicleNumberPlateText(vehicle, data.plate) -- Setze Fuel if GetResourceState(Config.FuelSystem) == 'started' then exports[Config.FuelSystem]:SetFuel(vehicle, data.fuel or 100) end -- Verhindere Despawn PreventDespawn(vehicle) -- Füge zu getrackten Fahrzeugen hinzu trackedVehicles[data.plate] = vehicle lastKnownCoords[data.plate] = GetEntityCoords(vehicle) -- Registriere beim Server TriggerServerEvent('antidespawn:server:registerVehicle', data.plate, modelHash, GetEntityCoords(vehicle), GetEntityHeading(vehicle)) -- Registriere bei jg-advancedgarages als "draußen" TriggerEvent("jg-advancedgarages:server:register-vehicle-outside", data.plate, NetworkGetNetworkIdFromEntity(vehicle)) Debug("Fahrzeug erfolgreich gespawnt: " .. data.plate) else Debug("Fehler beim Spawnen des Fahrzeugs: " .. data.plate) end SetModelAsNoLongerNeeded(modelHash) else Debug("Modell konnte nicht geladen werden: " .. data.plate) end end) -- Hilfsfunktion um Fahrzeug anhand Kennzeichen zu finden function GetVehicleByPlate(plate) local vehicles = GetGamePool('CVehicle') for _, vehicle in pairs(vehicles) do if QBCore.Functions.GetPlate(vehicle) == plate then return vehicle end end return nil end -- jg-advanced-garage Events RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data) if data and data.plate and trackedVehicles[data.plate] then trackedVehicles[data.plate] = nil lastKnownCoords[data.plate] = nil TriggerServerEvent('antidespawn:server:removeVehicle', data.plate) Debug("Fahrzeug in Garage gespeichert, entferne aus Tracking: " .. data.plate) end end) RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data) if data and data.plate then Debug("Fahrzeug aus Garage gespawnt: " .. data.plate) -- Warte kurz bis das Fahrzeug vollständig gespawnt ist Wait(1000) -- Finde das Fahrzeug local vehicle = GetVehicleByPlate(data.plate) if vehicle then -- Füge zu getrackten Fahrzeugen hinzu trackedVehicles[data.plate] = vehicle lastKnownCoords[data.plate] = GetEntityCoords(vehicle) -- Verhindere Despawn PreventDespawn(vehicle) Debug("Fahrzeug aus Garage zum Tracking hinzugefügt: " .. data.plate) end end end) -- Öffnen der Garage - entferne Tracking für Fahrzeuge in der Nähe RegisterNetEvent('jg-advancedgarages:client:open-garage', function() Debug("Garage geöffnet, prüfe Fahrzeuge in der Nähe") local playerPos = GetEntityCoords(PlayerPedId()) -- Prüfe alle getrackten Fahrzeuge for plate, vehicle in pairs(trackedVehicles) do if DoesEntityExist(vehicle) then local vehiclePos = GetEntityCoords(vehicle) local distance = #(playerPos - vehiclePos) -- Wenn Fahrzeug in der Nähe ist (50m), entferne aus Tracking -- da es wahrscheinlich in die Garage gestellt wird if distance < 50.0 then Debug("Fahrzeug in Garagennähe, entferne temporär aus Tracking: " .. plate) -- Nicht komplett entfernen, nur temporär ignorieren -- Das Event jg-advancedgarages:client:vehicle-stored wird ausgelöst wenn es eingelagert wird end end end end) -- Debug Command RegisterCommand('fixvehicle', function() local playerPed = PlayerPedId() local vehicle = GetVehiclePedIsIn(playerPed, false) if vehicle ~= 0 then local plate = QBCore.Functions.GetPlate(vehicle) PreventDespawn(vehicle) trackedVehicles[plate] = vehicle lastKnownCoords[plate] = GetEntityCoords(vehicle) -- Registriere Fahrzeug beim Server local vehicleCoords = GetEntityCoords(vehicle) local vehicleHeading = GetEntityHeading(vehicle) local vehicleModel = GetEntityModel(vehicle) TriggerServerEvent('antidespawn:server:registerVehicle', plate, vehicleModel, vehicleCoords, vehicleHeading) Debug("Anti-Despawn für Fahrzeug aktiviert: " .. plate) else Debug("Du musst in einem Fahrzeug sitzen!") end end, false) -- Cleanup beim Disconnect AddEventHandler('onResourceStop', function(resourceName) if resourceName == GetCurrentResourceName() then trackedVehicles = {} lastKnownCoords = {} end end)