local QBCore = exports['qb-core']:GetCoreObject() local trackedVehicles = {} local lastKnownCoords = {} local garagePending = {} -- Fahrzeuge, die gerade in die Garage gestellt werden local spawnedVehicles = {} -- Track recently spawned vehicles to prevent duplication local vehicleOwnership = {} -- Cache vehicle ownership status -- Helper function to count table entries function tableLength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end -- Debug Funktion local function Debug(msg) if Config.Debug then print("[AntiDespawn] " .. msg) end end -- Anti-Duplication: Check if a vehicle with this plate already exists in the world local function DoesVehicleExistInWorld(plate) local vehicles = GetGamePool('CVehicle') local count = 0 for _, vehicle in pairs(vehicles) do local vehPlate = QBCore.Functions.GetPlate(vehicle) if vehPlate == plate then count = count + 1 if count > 1 then -- More than one vehicle with this plate exists! Debug("DUPLICATION DETECTED: Multiple vehicles with plate " .. plate .. " exist!") return true end end end return false end -- Anti-Duplication: Check if vehicle was recently spawned local function WasVehicleRecentlySpawned(plate) if spawnedVehicles[plate] then local timeSinceSpawn = GetGameTimer() - spawnedVehicles[plate] if timeSinceSpawn < 60000 then -- 60 seconds cooldown Debug("Anti-Dupe: Vehicle " .. plate .. " was recently spawned (" .. math.floor(timeSinceSpawn/1000) .. " seconds ago)") return true else -- Reset the timer if it's been more than 60 seconds spawnedVehicles[plate] = nil end end return false end -- Anti-Duplication: Mark vehicle as recently spawned local function MarkVehicleAsSpawned(plate) spawnedVehicles[plate] = GetGameTimer() Debug("Anti-Dupe: Marked vehicle " .. plate .. " as recently spawned") -- Clean up old entries every 5 minutes SetTimeout(300000, function() for p, time in pairs(spawnedVehicles) do if GetGameTimer() - time > 300000 then -- 5 minutes spawnedVehicles[p] = nil end end end) end -- Function to check if player owns the vehicle with caching local function DoesPlayerOwnVehicle(plate) -- Check cache first if vehicleOwnership[plate] ~= nil then -- Cache expires after 5 minutes local timeSinceCheck = GetGameTimer() - vehicleOwnership[plate].timestamp if timeSinceCheck < 300000 then -- 5 minutes return vehicleOwnership[plate].owned end end local playerData = QBCore.Functions.GetPlayerData() if not playerData then return false end -- Trigger server event to check ownership and wait for response local isOwned = nil -- Request ownership check from server TriggerServerEvent('antidespawn:server:checkVehicleOwnership', plate) -- Register one-time event handler for the response local eventHandler = AddEventHandler('antidespawn:client:vehicleOwnershipResult', function(result, checkPlate) if plate == checkPlate then isOwned = result -- Cache the result vehicleOwnership[plate] = { owned = result, timestamp = GetGameTimer() } end end) -- Wait for response with timeout local timeout = 0 while isOwned == nil and timeout < 50 do Wait(10) timeout = timeout + 1 end -- Remove event handler RemoveEventHandler(eventHandler) return isOwned == true 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 -- Funktion um Fahrzeugmods zu erhalten local function GetVehicleMods(vehicle) local mods = {} -- Basis Mods for i = 0, 49 do mods[tostring(i)] = GetVehicleMod(vehicle, i) end -- Extras mods.extras = {} for i = 1, 12 do if DoesExtraExist(vehicle, i) then mods.extras[tostring(i)] = IsVehicleExtraTurnedOn(vehicle, i) end end -- Farben local primaryColor, secondaryColor = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) mods.colors = { primary = primaryColor, secondary = secondaryColor, pearlescent = pearlescentColor, wheels = wheelColor } -- Custom Farben local hasCustomPrimaryColor = GetIsVehiclePrimaryColourCustom(vehicle) if hasCustomPrimaryColor then local r, g, b = GetVehicleCustomPrimaryColour(vehicle) mods.customPrimaryColor = {r = r, g = g, b = b} end local hasCustomSecondaryColor = GetIsVehicleSecondaryColourCustom(vehicle) if hasCustomSecondaryColor then local r, g, b = GetVehicleCustomSecondaryColour(vehicle) mods.customSecondaryColor = {r = r, g = g, b = b} end -- Neon mods.neon = { left = IsVehicleNeonLightEnabled(vehicle, 0), right = IsVehicleNeonLightEnabled(vehicle, 1), front = IsVehicleNeonLightEnabled(vehicle, 2), back = IsVehicleNeonLightEnabled(vehicle, 3) } local r, g, b = GetVehicleNeonLightsColour(vehicle) mods.neonColor = {r = r, g = g, b = b} -- Xenon mods.xenonColor = GetVehicleXenonLightsColour(vehicle) mods.xenonEnabled = IsToggleModOn(vehicle, 22) -- Livery mods.livery = GetVehicleLivery(vehicle) -- Fenster Tint mods.windowTint = GetVehicleWindowTint(vehicle) -- Rad Typ mods.wheelType = GetVehicleWheelType(vehicle) -- Rauch Farbe local r, g, b = GetVehicleTyreSmokeColor(vehicle) mods.tyreSmokeColor = {r = r, g = g, b = b} -- Dashboard & Interior Farbe mods.dashboardColor = GetVehicleDashboardColour(vehicle) mods.interiorColor = GetVehicleInteriorColour(vehicle) -- Toggles mods.bulletProofTires = not GetVehicleTyresCanBurst(vehicle) mods.turbo = IsToggleModOn(vehicle, 18) mods.xeonHeadlights = IsToggleModOn(vehicle, 22) return mods end -- Funktion um Fahrzeugmods zu setzen local function SetVehicleMods(vehicle, mods) if not mods then return end -- 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 SetVehicleMod(vehicle, i, mods[tostring(i)], false) end end -- Extras if mods.extras then for i = 1, 12 do if mods.extras[tostring(i)] ~= nil then SetVehicleExtra(vehicle, i, not mods.extras[tostring(i)]) end end end -- Farben if mods.colors then SetVehicleColours(vehicle, mods.colors.primary or 0, mods.colors.secondary or 0) SetVehicleExtraColours(vehicle, mods.colors.pearlescent or 0, mods.colors.wheels or 0) end -- Custom Farben if mods.customPrimaryColor then SetVehicleCustomPrimaryColour(vehicle, mods.customPrimaryColor.r, mods.customPrimaryColor.g, mods.customPrimaryColor.b) end if mods.customSecondaryColor then SetVehicleCustomSecondaryColour(vehicle, mods.customSecondaryColor.r, mods.customSecondaryColor.g, mods.customSecondaryColor.b) end -- Neon if mods.neon then SetVehicleNeonLightEnabled(vehicle, 0, mods.neon.left or false) SetVehicleNeonLightEnabled(vehicle, 1, mods.neon.right or false) SetVehicleNeonLightEnabled(vehicle, 2, mods.neon.front or false) SetVehicleNeonLightEnabled(vehicle, 3, mods.neon.back or false) end if mods.neonColor then SetVehicleNeonLightsColour(vehicle, mods.neonColor.r, mods.neonColor.g, mods.neonColor.b) end -- Xenon if mods.xenonEnabled then ToggleVehicleMod(vehicle, 22, true) if mods.xenonColor then SetVehicleXenonLightsColour(vehicle, mods.xenonColor) end end -- Livery if mods.livery then SetVehicleLivery(vehicle, mods.livery) end -- Fenster Tint if mods.windowTint then SetVehicleWindowTint(vehicle, mods.windowTint) 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 -- Dashboard & Interior Farbe if mods.dashboardColor then SetVehicleDashboardColour(vehicle, mods.dashboardColor) end if mods.interiorColor then SetVehicleInteriorColour(vehicle, mods.interiorColor) end -- Toggles if mods.bulletProofTires ~= nil then SetVehicleTyresCanBurst(vehicle, not mods.bulletProofTires) end 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 -- 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 -- Event Handler für Fahrzeug betreten (nur Fahrersitz) CreateThread(function() while true do Wait(1000) local playerPed = PlayerPedId() local currentVehicle = GetVehiclePedIsIn(playerPed, false) -- Spieler ist als Fahrer in ein Fahrzeug eingestiegen if currentVehicle ~= 0 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) -- Anti-Duplication: Check if this plate already exists multiple times if DoesVehicleExistInWorld(plate) then Debug("Anti-Dupe: Detected duplicate vehicle with plate " .. plate .. ", not tracking") goto continue end -- Check if this vehicle is already being tracked if not trackedVehicles[plate] and not garagePending[plate] then -- Track all vehicles, regardless of ownership trackedVehicles[plate] = currentVehicle -- Speichere letzte bekannte Position lastKnownCoords[plate] = GetEntityCoords(currentVehicle) -- Sofort starke Despawn-Verhinderung PreventDespawn(currentVehicle) Debug("Fahrzeug wird nun getrackt: " .. plate) -- Hole Fahrzeugmods local vehicleMods = GetVehicleMods(currentVehicle) -- Registriere Fahrzeug beim Server local vehicleCoords = GetEntityCoords(currentVehicle) local vehicleHeading = GetEntityHeading(currentVehicle) local vehicleModel = GetEntityModel(currentVehicle) TriggerServerEvent('antidespawn:server:registerVehicle', plate, vehicleModel, vehicleCoords, vehicleHeading, vehicleMods) end end end ::continue:: end end) -- Kontinuierliche Despawn-Verhinderung für alle getrackten Fahrzeuge CreateThread(function() while true do Wait(5000) -- Alle 5 Sekunden local playerPed = PlayerPedId() local playerPos = GetEntityCoords(playerPed) for plate, vehicle in pairs(trackedVehicles) do -- Anti-Duplication: Check if multiple vehicles with this plate exist if DoesVehicleExistInWorld(plate) then Debug("Anti-Dupe: Detected duplicate during tracking for plate " .. plate .. ", removing from tracking") trackedVehicles[plate] = nil lastKnownCoords[plate] = nil TriggerServerEvent('antidespawn:server:removeVehicle', plate) goto continue end -- Prüfe ob Fahrzeug gerade in die Garage gestellt wird if garagePending[plate] then Debug("Fahrzeug wird gerade in Garage gestellt, entferne aus Tracking: " .. plate) trackedVehicles[plate] = nil lastKnownCoords[plate] = nil TriggerServerEvent('antidespawn:server:removeVehicle', plate) elseif DoesEntityExist(vehicle) then -- Check distance to player local vehiclePos = GetEntityCoords(vehicle) local distance = #(playerPos - vehiclePos) if distance > 500.0 then -- 500 units = about 500 meters Debug("Fahrzeug zu weit entfernt, entferne aus Tracking: " .. plate) trackedVehicles[plate] = nil lastKnownCoords[plate] = nil TriggerServerEvent('antidespawn:server:removeVehicle', plate) else PreventDespawn(vehicle) -- Aktualisiere letzte bekannte Position lastKnownCoords[plate] = vehiclePos -- Hole Fahrzeugmods local vehicleMods = GetVehicleMods(vehicle) -- Aktualisiere Position local vehicleHeading = GetEntityHeading(vehicle) TriggerServerEvent('antidespawn:server:updateVehicle', plate, vehiclePos, vehicleHeading, vehicleMods) Debug("Aktualisiere Fahrzeug: " .. plate) end else Debug("Fahrzeug existiert nicht mehr: " .. plate) -- Anti-Duplication: Check if vehicle was recently spawned before respawning if WasVehicleRecentlySpawned(plate) then Debug("Anti-Dupe: Not respawning recently spawned vehicle: " .. plate) trackedVehicles[plate] = nil lastKnownCoords[plate] = nil goto continue end -- Versuche Fahrzeug wiederherzustellen, aber nur wenn es nicht in die Garage gestellt wird if lastKnownCoords[plate] and not garagePending[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 lastKnownCoords[plate] = nil else -- Entferne aus Tracking trackedVehicles[plate] = nil lastKnownCoords[plate] = nil end end ::continue:: end end end) -- Lade Fahrzeuge beim Spawn RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() 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) -- Automatisches Laden beim Resource Start CreateThread(function() -- 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) -- Spawne ein Fahrzeug RegisterNetEvent('antidespawn:client:spawnVehicle', function(data) Debug("Spawne Fahrzeug: " .. data.plate) -- Anti-Duplication: Check if vehicle was recently spawned if WasVehicleRecentlySpawned(data.plate) then Debug("Anti-Dupe: Blocking respawn of recently spawned vehicle: " .. data.plate) return end -- 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 -- Prüfe ob Fahrzeug gerade in die Garage gestellt wird if garagePending[data.plate] then Debug("Fahrzeug wird gerade in Garage gestellt, nicht spawnen: " .. data.plate) return end -- Allow spawning of all vehicles, not just owned ones -- No ownership check here -- Konvertiere Modell zu Hash wenn nötig local modelHash = data.model if type(modelHash) == "string" then -- Versuche den String als Hash zu interpretieren if tonumber(modelHash) then modelHash = tonumber(modelHash) else -- Versuche den String als Modellnamen zu interpretieren modelHash = GetHashKey(modelHash) end end Debug("Versuche Modell zu laden: " .. tostring(modelHash)) -- Prüfe ob Modell existiert if not IsModelInCdimage(modelHash) then Debug("Modell existiert nicht in CD Image: " .. tostring(modelHash)) return end RequestModel(modelHash) local timeout = 0 while not HasModelLoaded(modelHash) and timeout < 100 do Wait(100) timeout = timeout + 1 Debug("Warte auf Modell: " .. tostring(timeout) .. "/100") end if HasModelLoaded(modelHash) then Debug("Modell geladen, erstelle Fahrzeug...") -- Anti-Duplication: Final check before spawning if GetVehicleByPlate(data.plate) then Debug("Anti-Dupe: Vehicle with plate " .. data.plate .. " appeared during model loading, aborting spawn") SetModelAsNoLongerNeeded(modelHash) return end -- Verwende CREATE_AUTOMOBILE für bessere Persistenz local vehicle if Citizen and Citizen.InvokeNative then -- OneSync Methode Debug("Verwende OneSync Methode") vehicle = Citizen.InvokeNative(0xAF35D0D2583051B0, modelHash, data.coords.x, data.coords.y, data.coords.z, data.heading, true, true) else -- Fallback Debug("Verwende Fallback Methode") vehicle = CreateVehicle(modelHash, data.coords.x, data.coords.y, data.coords.z, data.heading, true, false) end if DoesEntityExist(vehicle) then -- Anti-Duplication: Mark as recently spawned MarkVehicleAsSpawned(data.plate) -- Warte bis Fahrzeug vollständig geladen ist Wait(500) -- Setze Kennzeichen SetVehicleNumberPlateText(vehicle, data.plate) -- Setze Mods if data.mods then Debug("Setze Fahrzeugmods...") SetVehicleMods(vehicle, data.mods) end -- 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), GetVehicleMods(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 .. " (Hash: " .. tostring(modelHash) .. ")") end end) -- Event für Garage Store (wird ausgelöst, wenn der Spieler ein Fahrzeug in die Garage stellen will) RegisterNetEvent('jg-advancedgarages:client:store-vehicle', function(garageId, garageVehicleType) local playerPed = PlayerPedId() local vehicle = GetVehiclePedIsIn(playerPed, false) if vehicle ~= 0 then local plate = QBCore.Functions.GetPlate(vehicle) -- Markiere Fahrzeug als "wird in Garage gestellt" garagePending[plate] = true SetTimeout(10000, function() if garagePending[plate] then Debug("Garage storage timeout for vehicle: " .. plate) garagePending[plate] = nil end end) -- Entferne aus Tracking if trackedVehicles[plate] then Debug("Fahrzeug wird in Garage gestellt, entferne aus Tracking: " .. plate) trackedVehicles[plate] = nil lastKnownCoords[plate] = nil TriggerServerEvent('antidespawn:server:removeVehicle', plate) end end end) -- jg-advanced-garage Events RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data) if data and data.plate then -- Markiere Fahrzeug als "in Garage" garagePending[data.plate] = nil -- Entferne aus Tracking if trackedVehicles[data.plate] then trackedVehicles[data.plate] = nil lastKnownCoords[data.plate] = nil end -- Entferne aus Datenbank TriggerServerEvent('antidespawn:server:removeVehicle', data.plate) Debug("Fahrzeug in Garage gespeichert, aus DB entfernt: " .. data.plate) end end) RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data) if data and data.plate then -- Entferne Markierung "in Garage" garagePending[data.plate] = nil 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 RegisterNetEvent('jg-advancedgarages:client:open-garage', function(garageId, vehicleType, spawnCoords) Debug("Garage geöffnet: " .. garageId) -- No need to mark vehicles as potentially being stored here -- Let the actual store-vehicle event handle this 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() local vehicle = GetVehiclePedIsIn(playerPed, false) if vehicle ~= 0 then local plate = QBCore.Functions.GetPlate(vehicle) -- Anti-Duplication: Check if this plate already exists multiple times if DoesVehicleExistInWorld(plate) then Debug("Anti-Dupe: Detected duplicate vehicle with plate " .. plate .. ", not fixing") return end -- Prüfe ob Fahrzeug gerade in die Garage gestellt wird if not garagePending[plate] then -- Track all vehicles, regardless of ownership 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) local vehicleMods = GetVehicleMods(vehicle) TriggerServerEvent('antidespawn:server:registerVehicle', plate, vehicleModel, vehicleCoords, vehicleHeading, vehicleMods) Debug("Anti-Despawn für Fahrzeug aktiviert: " .. plate) else Debug("Fahrzeug wird gerade in Garage gestellt, kann nicht fixiert werden: " .. plate) end else Debug("Du musst in einem Fahrzeug sitzen!") end end, false) -- Server-side event handler for ownership verification RegisterNetEvent('antidespawn:client:vehicleOwnershipResult', function(result, plate) -- This event is handled by the DoesPlayerOwnVehicle function end) -- Clean up resources when script stops AddEventHandler('onResourceStop', function(resourceName) if resourceName == GetCurrentResourceName() then Debug("Resource stopping, clearing all data") trackedVehicles = {} lastKnownCoords = {} garagePending = {} spawnedVehicles = {} vehicleOwnership = {} end end) -- Debug command to check vehicle duplication RegisterCommand('checkdupes', function() local vehicles = GetGamePool('CVehicle') local plates = {} local dupes = {} for _, vehicle in pairs(vehicles) do local plate = QBCore.Functions.GetPlate(vehicle) if plates[plate] then if not dupes[plate] then dupes[plate] = 2 else dupes[plate] = dupes[plate] + 1 end else plates[plate] = true end end local dupeCount = 0 for plate, count in pairs(dupes) do Debug("Duplicate found: " .. plate .. " (Count: " .. count .. ")") dupeCount = dupeCount + 1 end if dupeCount == 0 then Debug("No duplicate vehicles found") else Debug("Found " .. dupeCount .. " duplicate vehicles") end end, false) -- Debug command to clear recently spawned vehicles list RegisterCommand('clearspawned', function() spawnedVehicles = {} Debug("Cleared recently spawned vehicles list") end, false) -- Debug command to clear ownership cache RegisterCommand('clearownership', function() vehicleOwnership = {} Debug("Cleared vehicle ownership cache") end, false)