forked from Simnation/Main
ed
This commit is contained in:
parent
b1ab09bb49
commit
950ae04a0f
2 changed files with 469 additions and 264 deletions
|
@ -1,5 +1,6 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
local vehicles = {}
|
||||
local activeSpawns = {} -- Track active spawn requests to prevent duplicates
|
||||
|
||||
-- Debug Funktion
|
||||
local function Debug(msg)
|
||||
|
@ -65,26 +66,63 @@ CreateThread(function()
|
|||
end)
|
||||
end)
|
||||
|
||||
-- Registriere ein Fahrzeug
|
||||
-- Check if a player owns a vehicle
|
||||
RegisterNetEvent('antidespawn:server:checkVehicleOwnership', function(plate)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not Player then
|
||||
TriggerClientEvent('antidespawn:client:vehicleOwnershipResult', src, false, plate)
|
||||
return
|
||||
end
|
||||
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND citizenid = ?', {plate, Player.PlayerData.citizenid}, function(result)
|
||||
local isOwned = result and #result > 0
|
||||
TriggerClientEvent('antidespawn:client:vehicleOwnershipResult', src, isOwned, plate)
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Enhanced anti-duplication for vehicle registration
|
||||
RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, coords, heading, mods)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not plate or not model or not coords then
|
||||
Debug("Ungültige Daten beim Registrieren eines Fahrzeugs")
|
||||
return
|
||||
end
|
||||
if not Player then return end
|
||||
|
||||
-- Stelle sicher, dass das Modell als Zahl gespeichert wird
|
||||
if type(model) == "string" then
|
||||
model = tonumber(model) or model
|
||||
end
|
||||
|
||||
-- Prüfe ob Fahrzeug in der Garage ist
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND state = ?', {plate, 1}, function(result)
|
||||
if result and #result > 0 then
|
||||
-- Verify ownership before registering
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ?', {plate}, function(result)
|
||||
if not result or #result == 0 then
|
||||
Debug("Vehicle not found in database: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if player owns the vehicle
|
||||
local isOwner = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.citizenid == Player.PlayerData.citizenid then
|
||||
isOwner = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not isOwner then
|
||||
Debug("Player does not own vehicle: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if vehicle is in garage
|
||||
local inGarage = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.state == 1 then
|
||||
inGarage = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if inGarage then
|
||||
Debug("Fahrzeug ist in der Garage, nicht registrieren: " .. plate)
|
||||
|
||||
-- Entferne aus Anti-Despawn Datenbank falls vorhanden
|
||||
-- Remove from Anti-Despawn database if present
|
||||
if vehicles[plate] then
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
|
@ -93,6 +131,7 @@ RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, co
|
|||
return
|
||||
end
|
||||
|
||||
-- Continue with registration as before
|
||||
vehicles[plate] = {
|
||||
model = model,
|
||||
coords = coords,
|
||||
|
@ -101,9 +140,10 @@ RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, co
|
|||
mods = mods,
|
||||
last_updated = os.time()
|
||||
}
|
||||
|
||||
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,
|
||||
tostring(model), -- Speichere als String in der Datenbank
|
||||
tostring(model),
|
||||
json.encode(coords),
|
||||
heading,
|
||||
100,
|
||||
|
@ -116,11 +156,43 @@ end)
|
|||
|
||||
-- Aktualisiere ein Fahrzeug
|
||||
RegisterNetEvent('antidespawn:server:updateVehicle', function(plate, coords, heading, mods)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not Player then return end
|
||||
if not vehicles[plate] then return end
|
||||
|
||||
-- Prüfe ob Fahrzeug in der Garage ist
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND state = ?', {plate, 1}, function(result)
|
||||
if result and #result > 0 then
|
||||
-- Verify ownership before updating
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ?', {plate}, function(result)
|
||||
if not result or #result == 0 then
|
||||
Debug("Vehicle not found in database: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if player owns the vehicle
|
||||
local isOwner = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.citizenid == Player.PlayerData.citizenid then
|
||||
isOwner = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not isOwner then
|
||||
Debug("Player does not own vehicle: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if vehicle is in garage
|
||||
local inGarage = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.state == 1 then
|
||||
inGarage = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if inGarage then
|
||||
Debug("Fahrzeug ist in der Garage, entferne aus Tracking: " .. plate)
|
||||
vehicles[plate] = nil
|
||||
|
||||
|
@ -148,6 +220,7 @@ end)
|
|||
|
||||
-- Entferne ein Fahrzeug
|
||||
RegisterNetEvent('antidespawn:server:removeVehicle', function(plate)
|
||||
local src = source
|
||||
if not vehicles[plate] then return end
|
||||
|
||||
vehicles[plate] = nil
|
||||
|
@ -159,30 +232,76 @@ RegisterNetEvent('antidespawn:server:removeVehicle', function(plate)
|
|||
Debug("Fahrzeug entfernt: " .. plate)
|
||||
end)
|
||||
|
||||
-- Respawn ein Fahrzeug
|
||||
-- Enhanced anti-duplication for vehicle respawning
|
||||
RegisterNetEvent('antidespawn:server:respawnVehicle', function(plate)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not vehicles[plate] then
|
||||
Debug("Fahrzeug nicht in Datenbank: " .. plate)
|
||||
return
|
||||
if not Player then return end
|
||||
|
||||
-- Anti-Duplication: Check if there's already an active spawn request for this plate
|
||||
if activeSpawns[plate] then
|
||||
Debug("Anti-Dupe: Already processing spawn request for: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Prüfe ob Fahrzeug in der Garage ist
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND state = ?', {plate, 1}, function(result)
|
||||
if result and #result > 0 then
|
||||
Debug("Fahrzeug ist in der Garage, nicht respawnen: " .. plate)
|
||||
|
||||
-- Entferne aus Anti-Despawn Datenbank
|
||||
vehicles[plate] = nil
|
||||
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {
|
||||
plate
|
||||
})
|
||||
-- Mark as active spawn
|
||||
activeSpawns[plate] = true
|
||||
|
||||
-- Set a timeout to clear the active spawn status
|
||||
SetTimeout(10000, function()
|
||||
activeSpawns[plate] = nil
|
||||
end)
|
||||
|
||||
-- Verify ownership before respawning
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ?', {plate}, function(result)
|
||||
if not result or #result == 0 then
|
||||
Debug("Vehicle not found in database: " .. plate)
|
||||
activeSpawns[plate] = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Sende Spawn-Event zurück an den Client
|
||||
-- Check if player owns the vehicle
|
||||
local isOwner = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.citizenid == Player.PlayerData.citizenid then
|
||||
isOwner = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not isOwner then
|
||||
Debug("Player does not own vehicle: " .. plate)
|
||||
activeSpawns[plate] = nil
|
||||
return
|
||||
end
|
||||
|
||||
if not vehicles[plate] then
|
||||
Debug("Fahrzeug nicht in Datenbank: " .. plate)
|
||||
activeSpawns[plate] = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if vehicle is in garage
|
||||
local inGarage = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.state == 1 then
|
||||
inGarage = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if inGarage then
|
||||
Debug("Fahrzeug ist in der Garage, nicht respawnen: " .. plate)
|
||||
|
||||
-- Remove from Anti-Despawn database
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
activeSpawns[plate] = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Send spawn event back to client
|
||||
TriggerClientEvent('antidespawn:client:spawnVehicle', src, {
|
||||
plate = plate,
|
||||
model = vehicles[plate].model,
|
||||
|
@ -212,68 +331,83 @@ RegisterNetEvent('antidespawn:server:loadVehicles', function()
|
|||
local loadedCount = 0
|
||||
local vehiclesToLoad = {}
|
||||
|
||||
-- Sammle alle Fahrzeuge, die geladen werden sollen
|
||||
for plate, vehicle in pairs(vehicles) do
|
||||
-- Prüfe ob das Fahrzeug in der Garage ist
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ?', {plate}, function(result)
|
||||
-- Prüfe ob das Fahrzeug überhaupt existiert
|
||||
if not result or #result == 0 then
|
||||
Debug("Fahrzeug existiert nicht in player_vehicles: " .. plate)
|
||||
-- Entferne aus Anti-Despawn Datenbank
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
return
|
||||
end
|
||||
|
||||
-- Prüfe ob das Fahrzeug in der Garage ist (state = 1)
|
||||
local inGarage = false
|
||||
for _, veh in ipairs(result) do
|
||||
if veh.state == 1 then
|
||||
inGarage = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if inGarage then
|
||||
Debug("Fahrzeug ist in der Garage, nicht laden: " .. plate)
|
||||
-- Entferne aus Anti-Despawn Datenbank
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
return
|
||||
end
|
||||
|
||||
-- Lade nur Fahrzeuge in der Nähe des Spielers
|
||||
local distance = #(playerCoords - vector3(vehicle.coords.x, vehicle.coords.y, vehicle.coords.z))
|
||||
|
||||
if distance < 100.0 then
|
||||
-- Stelle sicher, dass das Modell als Zahl gespeichert ist
|
||||
local model = vehicle.model
|
||||
if type(model) == "string" then
|
||||
model = tonumber(model) or model
|
||||
end
|
||||
|
||||
table.insert(vehiclesToLoad, {
|
||||
plate = plate,
|
||||
model = model,
|
||||
coords = vehicle.coords,
|
||||
heading = vehicle.heading,
|
||||
fuel = vehicle.fuel,
|
||||
mods = vehicle.mods
|
||||
})
|
||||
|
||||
loadedCount = loadedCount + 1
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Warte kurz und lade dann die Fahrzeuge
|
||||
SetTimeout(3000, function()
|
||||
for _, vehicleData in ipairs(vehiclesToLoad) do
|
||||
TriggerClientEvent('antidespawn:client:spawnVehicle', src, vehicleData)
|
||||
Debug("Fahrzeug für Spieler geladen: " .. vehicleData.plate)
|
||||
-- Get all vehicles owned by this player
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE citizenid = ?', {Player.PlayerData.citizenid}, function(ownedVehicles)
|
||||
if not ownedVehicles or #ownedVehicles == 0 then
|
||||
Debug("Spieler besitzt keine Fahrzeuge")
|
||||
return
|
||||
end
|
||||
|
||||
Debug("Fahrzeugladung abgeschlossen. " .. loadedCount .. " Fahrzeuge geladen.")
|
||||
-- Create a lookup table for owned vehicles
|
||||
local ownedPlates = {}
|
||||
for _, veh in ipairs(ownedVehicles) do
|
||||
ownedPlates[veh.plate] = veh.state
|
||||
end
|
||||
|
||||
-- Sammle alle Fahrzeuge, die geladen werden sollen
|
||||
for plate, vehicle in pairs(vehicles) do
|
||||
-- Check if player owns this vehicle
|
||||
if ownedPlates[plate] then
|
||||
-- Skip if vehicle is in garage (state = 1)
|
||||
if ownedPlates[plate] == 1 then
|
||||
Debug("Fahrzeug ist in der Garage, nicht laden: " .. plate)
|
||||
-- Remove from Anti-Despawn database
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
goto continue
|
||||
end
|
||||
|
||||
-- Lade nur Fahrzeuge in der Nähe des Spielers
|
||||
local distance = #(playerCoords - vector3(vehicle.coords.x, vehicle.coords.y, vehicle.coords.z))
|
||||
|
||||
if distance < 100.0 then
|
||||
-- Stelle sicher, dass das Modell als Zahl gespeichert ist
|
||||
local model = vehicle.model
|
||||
if type(model) == "string" then
|
||||
model = tonumber(model) or model
|
||||
end
|
||||
|
||||
table.insert(vehiclesToLoad, {
|
||||
plate = plate,
|
||||
model = model,
|
||||
coords = vehicle.coords,
|
||||
heading = vehicle.heading,
|
||||
fuel = vehicle.fuel,
|
||||
mods = vehicle.mods
|
||||
})
|
||||
|
||||
loadedCount = loadedCount + 1
|
||||
end
|
||||
else
|
||||
-- Vehicle not owned by this player, remove from tracking
|
||||
Debug("Fahrzeug gehört nicht dem Spieler, entferne aus Tracking: " .. plate)
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
||||
-- Warte kurz und lade dann die Fahrzeuge
|
||||
SetTimeout(3000, function()
|
||||
for _, vehicleData in ipairs(vehiclesToLoad) do
|
||||
-- Anti-Duplication: Check if there's already an active spawn request for this plate
|
||||
if not activeSpawns[vehicleData.plate] then
|
||||
activeSpawns[vehicleData.plate] = true
|
||||
|
||||
-- Set a timeout to clear the active spawn status
|
||||
SetTimeout(10000, function()
|
||||
activeSpawns[vehicleData.plate] = nil
|
||||
end)
|
||||
|
||||
TriggerClientEvent('antidespawn:client:spawnVehicle', src, vehicleData)
|
||||
Debug("Fahrzeug für Spieler geladen: " .. vehicleData.plate)
|
||||
else
|
||||
Debug("Anti-Dupe: Already processing spawn request for: " .. vehicleData.plate)
|
||||
end
|
||||
end
|
||||
|
||||
Debug("Fahrzeugladung abgeschlossen. " .. loadedCount .. " Fahrzeuge geladen.")
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
@ -387,116 +521,6 @@ RegisterCommand('clearvehicles', function(source, args, rawCommand)
|
|||
end
|
||||
end, true)
|
||||
|
||||
|
||||
-- Check if a player owns a vehicle
|
||||
RegisterNetEvent('antidespawn:server:checkVehicleOwnership', function(plate)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not Player then return end
|
||||
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND citizenid = ?', {plate, Player.PlayerData.citizenid}, function(result)
|
||||
local isOwned = result and #result > 0
|
||||
TriggerClientEvent('antidespawn:client:vehicleOwnershipResult', src, isOwned, plate)
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Modified registerVehicle function to verify ownership
|
||||
RegisterNetEvent('antidespawn:server:registerVehicle', function(plate, model, coords, heading, mods)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not Player then return end
|
||||
|
||||
-- Verify ownership before registering
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND citizenid = ?', {plate, Player.PlayerData.citizenid}, function(result)
|
||||
if not result or #result == 0 then
|
||||
Debug("Player does not own vehicle: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if vehicle is in garage
|
||||
if result[1].state == 1 then
|
||||
Debug("Fahrzeug ist in der Garage, nicht registrieren: " .. plate)
|
||||
|
||||
-- Remove from Anti-Despawn database if present
|
||||
if vehicles[plate] then
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
Debug("Fahrzeug aus Anti-Despawn entfernt: " .. plate)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Continue with registration as before
|
||||
vehicles[plate] = {
|
||||
model = model,
|
||||
coords = coords,
|
||||
heading = heading,
|
||||
fuel = 100,
|
||||
mods = mods,
|
||||
last_updated = os.time()
|
||||
}
|
||||
|
||||
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,
|
||||
tostring(model),
|
||||
json.encode(coords),
|
||||
heading,
|
||||
100,
|
||||
json.encode(mods)
|
||||
})
|
||||
|
||||
Debug("Fahrzeug registriert: " .. plate .. " (Modell: " .. tostring(model) .. ")")
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Also modify respawnVehicle to verify ownership
|
||||
RegisterNetEvent('antidespawn:server:respawnVehicle', function(plate)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if not Player then return end
|
||||
|
||||
-- Verify ownership before respawning
|
||||
MySQL.query('SELECT * FROM player_vehicles WHERE plate = ? AND citizenid = ?', {plate, Player.PlayerData.citizenid}, function(result)
|
||||
if not result or #result == 0 then
|
||||
Debug("Player does not own vehicle: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
if not vehicles[plate] then
|
||||
Debug("Fahrzeug nicht in Datenbank: " .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if vehicle is in garage
|
||||
if result[1].state == 1 then
|
||||
Debug("Fahrzeug ist in der Garage, nicht respawnen: " .. plate)
|
||||
|
||||
-- Remove from Anti-Despawn database
|
||||
vehicles[plate] = nil
|
||||
MySQL.query("DELETE FROM vehicle_antidespawn WHERE plate = ?", {plate})
|
||||
return
|
||||
end
|
||||
|
||||
-- Send spawn event back to client
|
||||
TriggerClientEvent('antidespawn:client:spawnVehicle', src, {
|
||||
plate = plate,
|
||||
model = vehicles[plate].model,
|
||||
coords = vehicles[plate].coords,
|
||||
heading = vehicles[plate].heading,
|
||||
fuel = vehicles[plate].fuel,
|
||||
mods = vehicles[plate].mods
|
||||
})
|
||||
|
||||
Debug("Fahrzeug Respawn angefordert: " .. plate)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
|
||||
-- Befehl zum Leeren der Datenbank
|
||||
RegisterCommand('clearalldespawn', function(source, args, rawCommand)
|
||||
if source == 0 then -- Nur über Konsole ausführbar
|
||||
|
@ -505,5 +529,24 @@ RegisterCommand('clearalldespawn', function(source, args, rawCommand)
|
|||
Debug("Alle Fahrzeuge aus der Datenbank entfernt.")
|
||||
end
|
||||
end, true)
|
||||
|
||||
|
||||
-- Debug command to check active spawns
|
||||
RegisterCommand('activespawns', function(source, args, rawCommand)
|
||||
if source == 0 then -- Nur über Konsole ausführbar
|
||||
local count = 0
|
||||
for plate, _ in pairs(activeSpawns) do
|
||||
Debug("Active spawn: " .. plate)
|
||||
count = count + 1
|
||||
end
|
||||
Debug("Total active spawns: " .. count)
|
||||
end
|
||||
end, true)
|
||||
|
||||
-- Clean up when resource stops
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if resourceName == GetCurrentResourceName() then
|
||||
Debug("Resource stopping, clearing all data")
|
||||
vehicles = {}
|
||||
activeSpawns = {}
|
||||
end
|
||||
end)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue