local QBCore = exports['qb-core']:GetCoreObject() local playerDrivenVehicles = {} -- Nur Fahrzeuge die der Spieler gefahren hat -- Funktion um zu prüfen ob Fahrzeugklasse erlaubt ist local function IsVehicleClassAllowed(vehicle) local vehicleClass = GetVehicleClass(vehicle) for _, allowedClass in pairs(Config.AllowedVehicleClasses) do if vehicleClass == allowedClass then return true end end return false 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 } -- 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} return mods end -- Funktion um Fahrzeugmods zu setzen local function SetVehicleMods(vehicle, mods) if not mods then return end -- Basis Mods for i = 0, 49 do if mods[tostring(i)] 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 -- 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 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) playerDrivenVehicles[plate] = currentVehicle -- Verhindere sofort Despawn SetEntityAsMissionEntity(currentVehicle, true, true) SetVehicleHasBeenOwnedByPlayer(currentVehicle, true) if Config.Debug then print(string.format("Player started driving vehicle: %s", plate)) end end end lastVehicle = currentVehicle end end) -- Hauptloop für Fahrzeugtracking (nur für vom Spieler gefahrene Fahrzeuge) CreateThread(function() while true do Wait(Config.SaveInterval) -- Tracke nur Fahrzeuge die der Spieler gefahren hat for plate, vehicle in pairs(playerDrivenVehicles) do if DoesEntityExist(vehicle) then local vehicleCoords = GetEntityCoords(vehicle) -- Verhindere Despawn SetEntityAsMissionEntity(vehicle, true, true) SetVehicleHasBeenOwnedByPlayer(vehicle, true) -- Speichere Fahrzeugdaten local vehicleData = { plate = plate, model = GetEntityModel(vehicle), position = {x = vehicleCoords.x, y = vehicleCoords.y, z = vehicleCoords.z}, rotation = {x = 0.0, y = 0.0, z = GetEntityHeading(vehicle)}, engineHealth = GetVehicleEngineHealth(vehicle), bodyHealth = GetVehicleBodyHealth(vehicle), fuel = 100, mods = GetVehicleMods(vehicle) } -- Versuche Fuel zu bekommen if GetResourceState('LegacyFuel') == 'started' then vehicleData.fuel = exports['LegacyFuel']:GetFuel(vehicle) or 100 elseif GetResourceState('ps-fuel') == 'started' then vehicleData.fuel = exports['ps-fuel']:GetFuel(vehicle) or 100 end TriggerServerEvent('vehicle-persistence:server:saveVehiclePosition', vehicleData) if Config.Debug then print(string.format("Saving player driven vehicle: %s", plate)) end else -- Fahrzeug existiert nicht mehr, entferne aus Liste playerDrivenVehicles[plate] = nil if Config.Debug then print(string.format("Player driven vehicle no longer exists: %s", plate)) end end end end end) -- Spawne gespeicherte Fahrzeuge RegisterNetEvent('vehicle-persistence:client:spawnSavedVehicles', function(vehicles) if Config.Debug then print(string.format("Received %d vehicles to spawn", #vehicles)) end for _, vehicleData in pairs(vehicles) do if Config.Debug then print(string.format("Processing vehicle: %s", vehicleData.plate)) end local position = json.decode(vehicleData.position) local rotation = json.decode(vehicleData.rotation) -- Prüfe ob Fahrzeug bereits existiert local existingVehicle = GetVehicleByPlate(vehicleData.plate) if not existingVehicle then CreateThread(function() local modelHash = vehicleData.model if type(modelHash) == "string" then modelHash = GetHashKey(modelHash) end if Config.Debug then print(string.format("Requesting model: %s (Hash: %s)", vehicleData.model, modelHash)) end RequestModel(modelHash) local timeout = 0 while not HasModelLoaded(modelHash) and timeout < 100 do Wait(100) timeout = timeout + 1 end if HasModelLoaded(modelHash) then if Config.Debug then print(string.format("Model loaded, creating vehicle at: %.2f, %.2f, %.2f", position.x, position.y, position.z)) end local vehicle = CreateVehicle(modelHash, position.x, position.y, position.z, rotation.z, true, false) if DoesEntityExist(vehicle) then Wait(1000) -- Längere Wartezeit -- Setze Fahrzeugdaten SetVehicleNumberPlateText(vehicle, vehicleData.plate) SetVehicleEngineHealth(vehicle, vehicleData.engine_health or 1000.0) SetVehicleBodyHealth(vehicle, vehicleData.body_health or 1000.0) -- Setze Fuel if GetResourceState('LegacyFuel') == 'started' then exports['LegacyFuel']:SetFuel(vehicle, vehicleData.fuel or 100) elseif GetResourceState('ps-fuel') == 'started' then exports['ps-fuel']:SetFuel(vehicle, vehicleData.fuel or 100) end -- Setze Mods if vehicleData.mods then local success, mods = pcall(json.decode, vehicleData.mods) if success then SetVehicleMods(vehicle, mods) end end -- Verhindere Despawn SetEntityAsMissionEntity(vehicle, true, true) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleOnGroundProperly(vehicle) playerDrivenVehicles[vehicleData.plate] = vehicle if Config.Debug then print(string.format("Successfully spawned saved vehicle: %s", vehicleData.plate)) end else if Config.Debug then print(string.format("Failed to create vehicle: %s", vehicleData.plate)) end end SetModelAsNoLongerNeeded(modelHash) else if Config.Debug then print(string.format("Failed to load model for vehicle: %s", vehicleData.plate)) end end end) else -- Fahrzeug existiert bereits, füge zu Liste hinzu playerDrivenVehicles[vehicleData.plate] = existingVehicle SetEntityAsMissionEntity(existingVehicle, true, true) SetVehicleHasBeenOwnedByPlayer(existingVehicle, true) if Config.Debug then print(string.format("Vehicle already exists: %s", vehicleData.plate)) end end 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 -- Lade Fahrzeuge beim Spawn RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() if Config.Debug then print("Player loaded, waiting before loading vehicles...") end Wait(15000) -- Längere Wartezeit if Config.Debug then print("Loading vehicles...") end TriggerServerEvent('vehicle-persistence:server:loadVehicles') end) -- Lade Fahrzeuge auch beim Resource Start (falls Spieler bereits online) CreateThread(function() Wait(20000) -- Noch längere Wartezeit beim Resource Start local playerData = QBCore.Functions.GetPlayerData() if playerData and playerData.citizenid then if Config.Debug then print("Resource started, loading vehicles for existing player...") end TriggerServerEvent('vehicle-persistence:server:loadVehicles') end end) -- jg-advanced-garage Events RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data) if data and data.plate and playerDrivenVehicles[data.plate] then playerDrivenVehicles[data.plate] = nil if Config.Debug then print(string.format("Vehicle stored in garage, removed from tracking: %s", data.plate)) end end end) RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data) if data and data.plate and playerDrivenVehicles[data.plate] then playerDrivenVehicles[data.plate] = nil if Config.Debug then print(string.format("Vehicle spawned from garage, removed from tracking: %s", data.plate)) end end end) -- Debug Command zum manuellen Laden RegisterCommand('loadvehicles', function() if Config.Debug then print("Manual vehicle load triggered...") TriggerServerEvent('vehicle-persistence:server:loadVehicles') end end, false) -- Cleanup beim Disconnect AddEventHandler('onResourceStop', function(resourceName) if resourceName == GetCurrentResourceName() then playerDrivenVehicles = {} end end)