1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-08-06 18:50:02 +02:00
parent 9520ad1b07
commit 0be79cdd60
2 changed files with 321 additions and 66 deletions

View file

@ -1,6 +1,7 @@
local QBCore = exports['qb-core']:GetCoreObject()
local trackedVehicles = {}
local lastKnownCoords = {}
local garagePending = {} -- Fahrzeuge, die gerade in die Garage gestellt werden
-- Debug Funktion
local function Debug(msg)
@ -30,6 +31,184 @@ local function IsVehicleClassAllowed(vehicle)
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
}
-- 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)
-- 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
-- Rad Typ
if mods.wheelType then
SetVehicleWheelType(vehicle, mods.wheelType)
end
-- Rauch Farbe
if mods.tyreSmokeColor then
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
end
-- Extrem starke Anti-Despawn Funktion
local function PreventDespawn(vehicle)
if not DoesEntityExist(vehicle) then return false end
@ -79,6 +258,9 @@ CreateThread(function()
-- Nur wenn Spieler der Fahrer ist (Seat -1)
if driver == playerPed and IsVehicleClassAllowed(currentVehicle) then
local plate = QBCore.Functions.GetPlate(currentVehicle)
-- Prüfe ob Fahrzeug gerade in die Garage gestellt wird
if not garagePending[plate] then
trackedVehicles[plate] = currentVehicle
-- Speichere letzte bekannte Position
@ -89,12 +271,18 @@ CreateThread(function()
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)
TriggerServerEvent('antidespawn:server:registerVehicle', plate, vehicleModel, vehicleCoords, vehicleHeading, vehicleMods)
else
Debug("Fahrzeug wird gerade in Garage gestellt, nicht tracken: " .. plate)
end
end
end
@ -108,29 +296,43 @@ CreateThread(function()
Wait(5000) -- Alle 5 Sekunden
for plate, vehicle in pairs(trackedVehicles) do
if DoesEntityExist(vehicle) then
-- 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
PreventDespawn(vehicle)
-- Aktualisiere letzte bekannte Position
lastKnownCoords[plate] = GetEntityCoords(vehicle)
-- Hole Fahrzeugmods
local vehicleMods = GetVehicleMods(vehicle)
-- Aktualisiere Position
local vehicleCoords = GetEntityCoords(vehicle)
local vehicleHeading = GetEntityHeading(vehicle)
TriggerServerEvent('antidespawn:server:updateVehicle', plate, vehicleCoords, vehicleHeading)
TriggerServerEvent('antidespawn:server:updateVehicle', plate, vehicleCoords, vehicleHeading, vehicleMods)
Debug("Aktualisiere Fahrzeug: " .. plate)
else
Debug("Fahrzeug existiert nicht mehr: " .. plate)
-- Versuche Fahrzeug wiederherzustellen
if lastKnownCoords[plate] then
-- 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
end
@ -144,6 +346,17 @@ RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
TriggerServerEvent('antidespawn:server:loadVehicles')
end)
-- Lade Fahrzeuge auch beim Resource Start
CreateThread(function()
Wait(15000) -- Warte bis alles geladen ist
local playerData = QBCore.Functions.GetPlayerData()
if playerData and playerData.citizenid then
Debug("Resource gestartet, lade Fahrzeuge...")
TriggerServerEvent('antidespawn:server:loadVehicles')
end
end)
-- Spawne ein Fahrzeug
RegisterNetEvent('antidespawn:client:spawnVehicle', function(data)
Debug("Spawne Fahrzeug: " .. data.plate)
@ -158,6 +371,12 @@ RegisterNetEvent('antidespawn:client:spawnVehicle', function(data)
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
-- Spawne Fahrzeug
local modelHash = data.model
@ -187,6 +406,11 @@ RegisterNetEvent('antidespawn:client:spawnVehicle', function(data)
-- Setze Kennzeichen
SetVehicleNumberPlateText(vehicle, data.plate)
-- Setze Mods
if data.mods then
SetVehicleMods(vehicle, data.mods)
end
-- Setze Fuel
if GetResourceState(Config.FuelSystem) == 'started' then
exports[Config.FuelSystem]:SetFuel(vehicle, data.fuel or 100)
@ -200,10 +424,7 @@ RegisterNetEvent('antidespawn:client:spawnVehicle', function(data)
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))
TriggerServerEvent('antidespawn:server:registerVehicle', data.plate, modelHash, GetEntityCoords(vehicle), GetEntityHeading(vehicle), GetVehicleMods(vehicle))
Debug("Fahrzeug erfolgreich gespawnt: " .. data.plate)
else
@ -227,18 +448,49 @@ function GetVehicleByPlate(plate)
return nil
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
-- 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 and trackedVehicles[data.plate] then
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
TriggerServerEvent('antidespawn:server:removeVehicle', data.plate)
Debug("Fahrzeug in Garage gespeichert, entferne aus Tracking: " .. data.plate)
end
Debug("Fahrzeug in Garage gespeichert: " .. 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
@ -260,8 +512,8 @@ RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data)
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")
RegisterNetEvent('jg-advancedgarages:client:open-garage', function(garageId, vehicleType, spawnCoords)
Debug("Garage geöffnet: " .. garageId)
local playerPos = GetEntityCoords(PlayerPedId())
@ -271,12 +523,11 @@ RegisterNetEvent('jg-advancedgarages:client:open-garage', function()
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
-- Wenn Fahrzeug in der Nähe ist (50m), markiere als "wird möglicherweise in Garage gestellt"
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
Debug("Fahrzeug in Garagennähe: " .. plate)
-- Nicht komplett entfernen, nur markieren
-- Das Event jg-advancedgarages:client:store-vehicle wird ausgelöst wenn es eingelagert wird
end
end
end
@ -289,6 +540,9 @@ RegisterCommand('fixvehicle', function()
if vehicle ~= 0 then
local plate = QBCore.Functions.GetPlate(vehicle)
-- Prüfe ob Fahrzeug gerade in die Garage gestellt wird
if not garagePending[plate] then
PreventDespawn(vehicle)
trackedVehicles[plate] = vehicle
lastKnownCoords[plate] = GetEntityCoords(vehicle)
@ -297,10 +551,14 @@ RegisterCommand('fixvehicle', function()
local vehicleCoords = GetEntityCoords(vehicle)
local vehicleHeading = GetEntityHeading(vehicle)
local vehicleModel = GetEntityModel(vehicle)
local vehicleMods = GetVehicleMods(vehicle)
TriggerServerEvent('antidespawn:server:registerVehicle', plate, vehicleModel, vehicleCoords, vehicleHeading)
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
@ -311,5 +569,6 @@ AddEventHandler('onResourceStop', function(resourceName)
if resourceName == GetCurrentResourceName() then
trackedVehicles = {}
lastKnownCoords = {}
garagePending = {}
end
end)

View file

@ -18,6 +18,7 @@ CreateThread(function()
`coords` longtext NOT NULL,
`heading` float NOT NULL,
`fuel` int(11) DEFAULT 100,
`mods` longtext DEFAULT NULL,
`last_updated` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `plate` (`plate`)
@ -37,6 +38,7 @@ CreateThread(function()
coords = json.decode(vehicle.coords),
heading = vehicle.heading,
fuel = vehicle.fuel,
mods = json.decode(vehicle.mods),
last_updated = vehicle.last_updated
}
end
@ -45,7 +47,7 @@ CreateThread(function()
end)
-- Registriere ein Fahrzeug
RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, coords, heading)
RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, coords, heading, mods)
local src = source
if not plate or not model or not coords then
@ -65,15 +67,17 @@ RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, co
coords = coords,
heading = heading,
fuel = 100,
mods = mods,
last_updated = os.time()
}
MySQL.query("INSERT INTO vehicle_antidespawn (plate, model, coords, heading, fuel) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE coords = VALUES(coords), heading = VALUES(heading), last_updated = CURRENT_TIMESTAMP", {
MySQL.query("INSERT INTO vehicle_antidespawn (plate, model, coords, heading, fuel, mods) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE coords = VALUES(coords), heading = VALUES(heading), mods = VALUES(mods), last_updated = CURRENT_TIMESTAMP", {
plate,
model,
json.encode(coords),
heading,
100
100,
json.encode(mods)
})
Debug("Fahrzeug registriert: " .. plate)
@ -81,7 +85,7 @@ RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, co
end)
-- Aktualisiere ein Fahrzeug
RegisterNetEvent('antidespawn:server:updateVehicle', function(plate, coords, heading)
RegisterNetEvent('antidespawn:server:updateVehicle', function(plate, coords, heading, mods)
if not vehicles[plate] then return end
-- Prüfe ob Fahrzeug in der Garage ist
@ -98,11 +102,13 @@ RegisterNetEvent('antidespawn:server:updateVehicle', function(plate, coords, hea
vehicles[plate].coords = coords
vehicles[plate].heading = heading
vehicles[plate].mods = mods
vehicles[plate].last_updated = os.time()
MySQL.query("UPDATE vehicle_antidespawn SET coords = ?, heading = ?, last_updated = CURRENT_TIMESTAMP WHERE plate = ?", {
MySQL.query("UPDATE vehicle_antidespawn SET coords = ?, heading = ?, mods = ?, last_updated = CURRENT_TIMESTAMP WHERE plate = ?", {
json.encode(coords),
heading,
json.encode(mods),
plate
})
@ -110,19 +116,6 @@ RegisterNetEvent('antidespawn:server:updateVehicle', function(plate, coords, hea
end)
end)
-- Entferne ein Fahrzeug
RegisterNetEvent('antidespawn:server:removeVehicle', function(plate)
if not vehicles[plate] then return end
vehicles[plate] = nil
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
plate
})
Debug("Fahrzeug entfernt: " .. plate)
end)
-- Respawn ein Fahrzeug
RegisterNetEvent('antidespawn:server:respawnVehicle', function(plate)
local src = source
@ -152,7 +145,8 @@ RegisterNetEvent('antidespawn:server:respawnVehicle', function(plate)
model = vehicles[plate].model,
coords = vehicles[plate].coords,
heading = vehicles[plate].heading,
fuel = vehicles[plate].fuel
fuel = vehicles[plate].fuel,
mods = vehicles[plate].mods
})
Debug("Fahrzeug Respawn angefordert: " .. plate)
@ -192,7 +186,8 @@ RegisterNetEvent('antidespawn:server:loadVehicles', function()
model = vehicle.model,
coords = vehicle.coords,
heading = vehicle.heading,
fuel = vehicle.fuel
fuel = vehicle.fuel,
mods = vehicle.mods
})
Debug("Fahrzeug für Spieler geladen: " .. plate)
@ -201,6 +196,7 @@ RegisterNetEvent('antidespawn:server:loadVehicles', function()
end
end)
-- Cleanup alte Einträge (älter als 24 Stunden)
CreateThread(function()
while true do