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

351 lines
13 KiB
Lua
Raw Normal View History

2025-08-06 17:33:26 +02:00
local QBCore = exports['qb-core']:GetCoreObject()
2025-08-06 17:59:00 +02:00
local playerDrivenVehicles = {} -- Nur Fahrzeuge die der Spieler gefahren hat
2025-08-06 17:33:26 +02:00
-- 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
2025-08-06 17:59:00 +02:00
-- Event Handler für Fahrzeug betreten (nur Fahrersitz)
2025-08-06 17:53:15 +02:00
CreateThread(function()
local lastVehicle = 0
while true do
Wait(1000)
local playerPed = PlayerPedId()
local currentVehicle = GetVehiclePedIsIn(playerPed, false)
2025-08-06 17:59:00 +02:00
-- Spieler ist als Fahrer in ein Fahrzeug eingestiegen
2025-08-06 17:53:15 +02:00
if currentVehicle ~= 0 and currentVehicle ~= lastVehicle then
2025-08-06 18:01:54 +02:00
-- Prüfe ob Spieler auf Fahrersitz ist
local driver = GetPedInVehicleSeat(currentVehicle, -1)
2025-08-06 17:59:00 +02:00
2025-08-06 18:01:54 +02:00
-- Nur wenn Spieler der Fahrer ist (Seat -1)
if driver == playerPed and IsVehicleClassAllowed(currentVehicle) then
2025-08-06 17:53:15 +02:00
local plate = QBCore.Functions.GetPlate(currentVehicle)
2025-08-06 17:59:00 +02:00
playerDrivenVehicles[plate] = currentVehicle
-- Verhindere sofort Despawn
SetEntityAsMissionEntity(currentVehicle, true, true)
SetVehicleHasBeenOwnedByPlayer(currentVehicle, true)
2025-08-06 17:53:15 +02:00
if Config.Debug then
2025-08-06 17:59:00 +02:00
print(string.format("Player started driving vehicle: %s", plate))
2025-08-06 17:53:15 +02:00
end
end
end
lastVehicle = currentVehicle
end
end)
2025-08-06 17:59:00 +02:00
-- Hauptloop für Fahrzeugtracking (nur für vom Spieler gefahrene Fahrzeuge)
2025-08-06 17:33:26 +02:00
CreateThread(function()
while true do
Wait(Config.SaveInterval)
2025-08-06 17:59:00 +02:00
-- Tracke nur Fahrzeuge die der Spieler gefahren hat
for plate, vehicle in pairs(playerDrivenVehicles) do
2025-08-06 17:53:15 +02:00
if DoesEntityExist(vehicle) then
2025-08-06 17:33:26 +02:00
local vehicleCoords = GetEntityCoords(vehicle)
2025-08-06 17:53:15 +02:00
-- Verhindere Despawn
2025-08-06 17:59:00 +02:00
SetEntityAsMissionEntity(vehicle, true, true)
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
2025-08-06 17:53:15 +02:00
-- 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),
2025-08-06 17:59:00 +02:00
fuel = 100,
2025-08-06 17:53:15 +02:00
mods = GetVehicleMods(vehicle)
}
2025-08-06 17:49:33 +02:00
2025-08-06 17:53:15 +02:00
-- 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
2025-08-06 17:49:33 +02:00
end
2025-08-06 17:53:15 +02:00
TriggerServerEvent('vehicle-persistence:server:saveVehiclePosition', vehicleData)
if Config.Debug then
2025-08-06 17:59:00 +02:00
print(string.format("Saving player driven vehicle: %s", plate))
2025-08-06 17:53:15 +02:00
end
else
-- Fahrzeug existiert nicht mehr, entferne aus Liste
2025-08-06 17:59:00 +02:00
playerDrivenVehicles[plate] = nil
2025-08-06 17:53:15 +02:00
if Config.Debug then
2025-08-06 17:59:00 +02:00
print(string.format("Player driven vehicle no longer exists: %s", plate))
2025-08-06 17:49:33 +02:00
end
end
end
2025-08-06 17:33:26 +02:00
end
end)
-- Spawne gespeicherte Fahrzeuge
RegisterNetEvent('vehicle-persistence:client:spawnSavedVehicles', function(vehicles)
2025-08-06 17:49:33 +02:00
if Config.Debug then
2025-08-06 18:07:18 +02:00
print(string.format("Received %d vehicles to spawn", #vehicles))
2025-08-06 17:49:33 +02:00
end
2025-08-06 17:33:26 +02:00
for _, vehicleData in pairs(vehicles) do
2025-08-06 18:07:18 +02:00
if Config.Debug then
print(string.format("Processing vehicle: %s", vehicleData.plate))
end
2025-08-06 17:33:26 +02:00
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
2025-08-06 17:49:33 +02:00
CreateThread(function()
local modelHash = vehicleData.model
if type(modelHash) == "string" then
modelHash = GetHashKey(modelHash)
2025-08-06 17:33:26 +02:00
end
2025-08-06 18:07:18 +02:00
if Config.Debug then
print(string.format("Requesting model: %s (Hash: %s)", vehicleData.model, modelHash))
end
2025-08-06 17:49:33 +02:00
RequestModel(modelHash)
local timeout = 0
2025-08-06 18:07:18 +02:00
while not HasModelLoaded(modelHash) and timeout < 100 do
2025-08-06 17:49:33 +02:00
Wait(100)
timeout = timeout + 1
2025-08-06 17:33:26 +02:00
end
2025-08-06 17:49:33 +02:00
if HasModelLoaded(modelHash) then
2025-08-06 18:07:18 +02:00
if Config.Debug then
print(string.format("Model loaded, creating vehicle at: %.2f, %.2f, %.2f", position.x, position.y, position.z))
end
2025-08-06 17:49:33 +02:00
local vehicle = CreateVehicle(modelHash, position.x, position.y, position.z, rotation.z, true, false)
if DoesEntityExist(vehicle) then
2025-08-06 18:07:18 +02:00
Wait(1000) -- Längere Wartezeit
2025-08-06 17:49:33 +02:00
-- 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
2025-08-06 18:07:18 +02:00
local success, mods = pcall(json.decode, vehicleData.mods)
if success then
SetVehicleMods(vehicle, mods)
end
2025-08-06 17:49:33 +02:00
end
-- Verhindere Despawn
2025-08-06 17:59:00 +02:00
SetEntityAsMissionEntity(vehicle, true, true)
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
2025-08-06 18:07:18 +02:00
SetVehicleOnGroundProperly(vehicle)
2025-08-06 17:49:33 +02:00
2025-08-06 17:59:00 +02:00
playerDrivenVehicles[vehicleData.plate] = vehicle
2025-08-06 17:49:33 +02:00
if Config.Debug then
print(string.format("Successfully spawned saved vehicle: %s", vehicleData.plate))
end
2025-08-06 18:07:18 +02:00
else
if Config.Debug then
print(string.format("Failed to create vehicle: %s", vehicleData.plate))
end
2025-08-06 17:49:33 +02:00
end
SetModelAsNoLongerNeeded(modelHash)
2025-08-06 18:07:18 +02:00
else
if Config.Debug then
print(string.format("Failed to load model for vehicle: %s", vehicleData.plate))
end
2025-08-06 17:44:39 +02:00
end
2025-08-06 17:49:33 +02:00
end)
else
2025-08-06 17:59:00 +02:00
-- Fahrzeug existiert bereits, füge zu Liste hinzu
playerDrivenVehicles[vehicleData.plate] = existingVehicle
SetEntityAsMissionEntity(existingVehicle, true, true)
SetVehicleHasBeenOwnedByPlayer(existingVehicle, true)
2025-08-06 18:07:18 +02:00
if Config.Debug then
print(string.format("Vehicle already exists: %s", vehicleData.plate))
end
2025-08-06 17:33:26 +02:00
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()
2025-08-06 18:07:18 +02:00
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
2025-08-06 17:33:26 +02:00
TriggerServerEvent('vehicle-persistence:server:loadVehicles')
end)
2025-08-06 18:07:18 +02:00
-- 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)
2025-08-06 17:33:26 +02:00
-- jg-advanced-garage Events
RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data)
2025-08-06 17:59:00 +02:00
if data and data.plate and playerDrivenVehicles[data.plate] then
playerDrivenVehicles[data.plate] = nil
2025-08-06 17:33:26 +02:00
if Config.Debug then
2025-08-06 17:49:33 +02:00
print(string.format("Vehicle stored in garage, removed from tracking: %s", data.plate))
2025-08-06 17:33:26 +02:00
end
end
end)
RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data)
2025-08-06 17:59:00 +02:00
if data and data.plate and playerDrivenVehicles[data.plate] then
playerDrivenVehicles[data.plate] = nil
2025-08-06 17:33:26 +02:00
if Config.Debug then
print(string.format("Vehicle spawned from garage, removed from tracking: %s", data.plate))
end
end
end)
2025-08-06 18:07:18 +02:00
-- 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)
2025-08-06 17:33:26 +02:00
-- Cleanup beim Disconnect
AddEventHandler('onResourceStop', function(resourceName)
if resourceName == GetCurrentResourceName() then
2025-08-06 17:59:00 +02:00
playerDrivenVehicles = {}
2025-08-06 17:33:26 +02:00
end
end)