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

463 lines
17 KiB
Lua
Raw Normal View History

2025-08-06 17:33:26 +02:00
local QBCore = exports['qb-core']:GetCoreObject()
2025-08-06 18:18:04 +02:00
local trackedVehicles = {}
2025-08-06 18:32:55 +02:00
local lastKnownCoords = {}
2025-08-06 18:50:02 +02:00
local garagePending = {} -- Fahrzeuge, die gerade in die Garage gestellt werden
2025-08-06 18:18:04 +02:00
2025-08-07 13:02:53 +02:00
-- Helper function to count table entries
function tableLength(T)
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
2025-08-06 18:18:04 +02:00
-- Debug Funktion
local function Debug(msg)
if Config.Debug then
print("[AntiDespawn] " .. msg)
end
end
2025-08-06 17:33:26 +02:00
2025-08-07 13:02:53 +02:00
-- Function to check if player owns the vehicle
local function DoesPlayerOwnVehicle(plate)
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
RegisterNetEvent('antidespawn:client:vehicleOwnershipResult')
local eventHandler = AddEventHandler('antidespawn:client:vehicleOwnershipResult', function(result, checkPlate)
if plate == checkPlate then
isOwned = result
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
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)
2025-08-06 18:18:04 +02:00
-- Prüfe Blacklist
for _, blacklistedClass in pairs(Config.BlacklistedVehicleClasses) do
if vehicleClass == blacklistedClass then
return false
end
end
-- Prüfe Whitelist
2025-08-06 17:33:26 +02:00
for _, allowedClass in pairs(Config.AllowedVehicleClasses) do
if vehicleClass == allowedClass then
return true
end
end
2025-08-06 18:18:04 +02:00
2025-08-06 17:33:26 +02:00
return false
end
2025-08-07 13:02:53 +02:00
-- Rest of your functions remain the same...
2025-08-06 18:12:40 +02:00
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()
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-07 12:45:07 +02:00
if currentVehicle ~= 0 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
2025-08-07 12:45:07 +02:00
-- Check if this vehicle is already being tracked
if not trackedVehicles[plate] and not garagePending[plate] then
2025-08-07 13:02:53 +02:00
-- Check if player owns this vehicle
if DoesPlayerOwnVehicle(plate) then
-- Check if maximum tracked vehicles limit is reached
local maxTrackedVehicles = 100 -- Adjust as needed
if tableLength(trackedVehicles) >= maxTrackedVehicles then
Debug("Maximum number of tracked vehicles reached")
-- You could implement logic to remove the oldest vehicle here
else
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
else
Debug("Fahrzeug gehört nicht dem Spieler, wird nicht getrackt: " .. plate)
end
2025-08-06 18:50:02 +02:00
end
2025-08-06 17:53:15 +02:00
end
end
end
end)
2025-08-06 18:12:40 +02:00
-- Kontinuierliche Despawn-Verhinderung für alle getrackten Fahrzeuge
CreateThread(function()
while true do
2025-08-06 18:32:55 +02:00
Wait(5000) -- Alle 5 Sekunden
2025-08-06 18:12:40 +02:00
2025-08-07 13:02:53 +02:00
local playerPed = PlayerPedId()
local playerPos = GetEntityCoords(playerPed)
2025-08-06 18:18:04 +02:00
for plate, vehicle in pairs(trackedVehicles) do
2025-08-06 18:50:02 +02:00
-- 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
2025-08-07 13:02:53 +02:00
-- Check distance to player
local vehiclePos = GetEntityCoords(vehicle)
local distance = #(playerPos - vehiclePos)
2025-08-06 18:32:55 +02:00
2025-08-07 13:02:53 +02:00
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
2025-08-06 17:53:15 +02:00
else
2025-08-06 18:18:04 +02:00
Debug("Fahrzeug existiert nicht mehr: " .. plate)
2025-08-06 18:32:55 +02:00
2025-08-06 18:50:02 +02:00
-- Versuche Fahrzeug wiederherzustellen, aber nur wenn es nicht in die Garage gestellt wird
if lastKnownCoords[plate] and not garagePending[plate] then
2025-08-06 18:32:55 +02:00
Debug("Versuche Fahrzeug wiederherzustellen: " .. plate)
TriggerServerEvent('antidespawn:server:respawnVehicle', plate)
-- Entferne aus lokaler Tracking-Liste, wird nach Respawn wieder hinzugefügt
trackedVehicles[plate] = nil
2025-08-06 18:50:02 +02:00
lastKnownCoords[plate] = nil
else
-- Entferne aus Tracking
trackedVehicles[plate] = nil
lastKnownCoords[plate] = nil
2025-08-06 18:32:55 +02:00
end
2025-08-06 17:49:33 +02:00
end
end
2025-08-06 17:33:26 +02:00
end
end)
2025-08-06 18:18:04 +02:00
-- Lade Fahrzeuge beim Spawn
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
2025-08-06 19:45:59 +02:00
Debug("Spieler geladen, warte vor dem Laden der Fahrzeuge...")
-- Längere Wartezeit, um sicherzustellen, dass alles geladen ist
Wait(15000)
2025-08-06 18:18:04 +02:00
TriggerServerEvent('antidespawn:server:loadVehicles')
end)
2025-08-06 19:45:59 +02:00
-- Automatisches Laden beim Resource Start
2025-08-06 18:50:02 +02:00
CreateThread(function()
2025-08-06 19:45:59 +02:00
-- Längere Wartezeit beim Serverstart
Wait(20000)
2025-08-06 18:50:02 +02:00
2025-08-06 19:45:59 +02:00
-- Prüfe ob Spieler eingeloggt ist
2025-08-06 18:50:02 +02:00
local playerData = QBCore.Functions.GetPlayerData()
if playerData and playerData.citizenid then
Debug("Resource gestartet, lade Fahrzeuge...")
TriggerServerEvent('antidespawn:server:loadVehicles')
2025-08-06 19:45:59 +02:00
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
2025-08-06 18:50:02 +02:00
end
end)
2025-08-06 18:18:04 +02:00
-- 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
2025-08-06 18:32:55 +02:00
lastKnownCoords[data.plate] = GetEntityCoords(existingVehicle)
2025-08-06 18:18:04 +02:00
PreventDespawn(existingVehicle)
return
2025-08-06 17:49:33 +02:00
end
2025-08-06 18:50:02 +02:00
-- 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
2025-08-06 19:16:18 +02:00
-- Konvertiere Modell zu Hash wenn nötig
2025-08-06 18:18:04 +02:00
local modelHash = data.model
2025-08-06 19:16:18 +02:00
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
2025-08-06 18:18:04 +02:00
RequestModel(modelHash)
local timeout = 0
while not HasModelLoaded(modelHash) and timeout < 100 do
Wait(100)
timeout = timeout + 1
2025-08-06 19:16:18 +02:00
Debug("Warte auf Modell: " .. tostring(timeout) .. "/100")
2025-08-06 18:18:04 +02:00
end
if HasModelLoaded(modelHash) then
2025-08-06 19:16:18 +02:00
Debug("Modell geladen, erstelle Fahrzeug...")
2025-08-06 18:32:55 +02:00
-- Verwende CREATE_AUTOMOBILE für bessere Persistenz
local vehicle
if Citizen and Citizen.InvokeNative then
-- OneSync Methode
2025-08-06 19:16:18 +02:00
Debug("Verwende OneSync Methode")
2025-08-06 18:32:55 +02:00
vehicle = Citizen.InvokeNative(0xAF35D0D2583051B0, modelHash, data.coords.x, data.coords.y, data.coords.z, data.heading, true, true)
else
-- Fallback
2025-08-06 19:16:18 +02:00
Debug("Verwende Fallback Methode")
2025-08-06 18:32:55 +02:00
vehicle = CreateVehicle(modelHash, data.coords.x, data.coords.y, data.coords.z, data.heading, true, false)
end
2025-08-06 17:33:26 +02:00
2025-08-06 18:18:04 +02:00
if DoesEntityExist(vehicle) then
2025-08-06 18:32:55 +02:00
-- Warte bis Fahrzeug vollständig geladen ist
Wait(500)
2025-08-06 18:18:04 +02:00
-- Setze Kennzeichen
SetVehicleNumberPlateText(vehicle, data.plate)
2025-08-06 18:07:18 +02:00
2025-08-06 18:50:02 +02:00
-- Setze Mods
if data.mods then
2025-08-06 19:16:18 +02:00
Debug("Setze Fahrzeugmods...")
2025-08-06 18:50:02 +02:00
SetVehicleMods(vehicle, data.mods)
end
2025-08-06 18:18:04 +02:00
-- Setze Fuel
if GetResourceState(Config.FuelSystem) == 'started' then
exports[Config.FuelSystem]:SetFuel(vehicle, data.fuel or 100)
2025-08-06 18:07:18 +02:00
end
2025-08-06 18:18:04 +02:00
-- Verhindere Despawn
PreventDespawn(vehicle)
-- Füge zu getrackten Fahrzeugen hinzu
trackedVehicles[data.plate] = vehicle
2025-08-06 18:32:55 +02:00
lastKnownCoords[data.plate] = GetEntityCoords(vehicle)
-- Registriere beim Server
2025-08-06 18:50:02 +02:00
TriggerServerEvent('antidespawn:server:registerVehicle', data.plate, modelHash, GetEntityCoords(vehicle), GetEntityHeading(vehicle), GetVehicleMods(vehicle))
2025-08-06 18:18:04 +02:00
Debug("Fahrzeug erfolgreich gespawnt: " .. data.plate)
else
Debug("Fehler beim Spawnen des Fahrzeugs: " .. data.plate)
2025-08-06 17:33:26 +02:00
end
2025-08-06 18:18:04 +02:00
SetModelAsNoLongerNeeded(modelHash)
else
2025-08-06 19:16:18 +02:00
Debug("Modell konnte nicht geladen werden: " .. data.plate .. " (Hash: " .. tostring(modelHash) .. ")")
2025-08-06 17:33:26 +02:00
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
2025-08-06 18:50:02 +02:00
-- 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
2025-08-07 13:02:53 +02:00
SetTimeout(10000, function()
if garagePending[plate] then
Debug("Garage storage timeout for vehicle: " .. plate)
garagePending[plate] = nil
end
end)
2025-08-06 18:50:02 +02:00
-- 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)
2025-08-06 17:33:26 +02:00
-- jg-advanced-garage Events
RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data)
2025-08-06 18:50:02 +02:00
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
2025-08-06 19:45:59 +02:00
-- Entferne aus Datenbank
TriggerServerEvent('antidespawn:server:removeVehicle', data.plate)
Debug("Fahrzeug in Garage gespeichert, aus DB entfernt: " .. data.plate)
2025-08-06 17:33:26 +02:00
end
end)
2025-08-06 18:32:55 +02:00
RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data)
if data and data.plate then
2025-08-06 18:50:02 +02:00
-- Entferne Markierung "in Garage"
garagePending[data.plate] = nil
2025-08-06 18:32:55 +02:00
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)
2025-08-07 08:57:28 +02:00
-- Öffnen der Garage
2025-08-06 18:50:02 +02:00
RegisterNetEvent('jg-advancedgarages:client:open-garage', function(garageId, vehicleType, spawnCoords)
Debug("Garage geöffnet: " .. garageId)
2025-08-06 18:32:55 +02:00
2025-08-07 08:57:28 +02:00
-- No need to mark vehicles as potentially being stored here
-- Let the actual store-vehicle event handle this
2025-08-06 18:32:55 +02:00
end)
2025-08-06 19:45:59 +02:00
-- Manuelle Lade-Funktion
RegisterCommand('loadvehicles', function()
Debug("Manuelles Laden der Fahrzeuge...")
TriggerServerEvent('antidespawn:server:loadVehicles')
end, false)
2025-08-06 18:32:55 +02:00
-- Debug Command
RegisterCommand('fixvehicle', function()
local playerPed = PlayerPedId()
local vehicle = GetVehiclePedIsIn(playerPed, false)
if vehicle ~= 0 then
local plate = QBCore.Functions.GetPlate(vehicle)
2025-08-06 18:50:02 +02:00
-- Prüfe ob Fahrzeug gerade in die Garage gestellt wird
if not garagePending[plate] then
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
2025-08-06 18:32:55 +02:00
else
Debug("Du musst in einem Fahrzeug sitzen!")
end
end, false)
2025-08-06 17:33:26 +02:00
AddEventHandler('onResourceStop', function(resourceName)
if resourceName == GetCurrentResourceName() then
2025-08-07 08:57:28 +02:00
Debug("Resource stopping, clearing all data")
2025-08-06 18:18:04 +02:00
trackedVehicles = {}
2025-08-06 18:32:55 +02:00
lastKnownCoords = {}
2025-08-06 18:50:02 +02:00
garagePending = {}
2025-08-06 17:33:26 +02:00
end
end)