1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-08-06 17:33:26 +02:00
parent 7592bef869
commit dad50e73dd
5 changed files with 443 additions and 0 deletions

View file

@ -0,0 +1,260 @@
local QBCore = exports['qb-core']:GetCoreObject()
local trackedVehicles = {}
local playerVehicles = {}
-- 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
-- Prüfe ob Fahrzeug einem Spieler gehört
local function DoesVehicleBelongToPlayer(plate)
-- Verwende jg-advanced-garage Export
local vehicleData = exports['jg-advancedgarages']:GetVehicleByPlate(plate)
return vehicleData ~= nil
end
-- Hauptloop für Fahrzeugtracking
CreateThread(function()
while true do
Wait(Config.SaveInterval)
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
-- Finde alle Fahrzeuge in der Nähe
local vehicles = GetGamePool('CVehicle')
for _, vehicle in pairs(vehicles) do
if DoesEntityExist(vehicle) and IsVehicleClassAllowed(vehicle) then
local plate = QBCore.Functions.GetPlate(vehicle)
local vehicleCoords = GetEntityCoords(vehicle)
local distance = #(playerCoords - vehicleCoords)
-- Prüfe ob Fahrzeug einem Spieler gehört
if DoesVehicleBelongToPlayer(plate) then
-- Prüfe ob Fahrzeug nicht zu nah an einer Garage ist
local nearGarage = exports['jg-advancedgarages']:IsNearGarage(vehicleCoords, Config.MinGarageDistance)
if not nearGarage then
-- Speichere Fahrzeugdaten
local vehicleData = {
plate = plate,
model = GetDisplayNameFromVehicleModel(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 = exports['LegacyFuel']:GetFuel(vehicle) or 100, -- Anpassen je nach Fuel System
mods = GetVehicleMods(vehicle)
}
TriggerServerEvent('vehicle-persistence:server:saveVehiclePosition', vehicleData)
trackedVehicles[plate] = vehicle
-- Verhindere Despawn
SetEntityAsMissionEntity(vehicle, true, true)
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
if Config.Debug then
print(string.format("Tracking vehicle: %s at distance: %.2f", plate, distance))
end
end
end
end
end
end
end)
-- Spawne gespeicherte Fahrzeuge
RegisterNetEvent('vehicle-persistence:client:spawnSavedVehicles', function(vehicles)
for _, vehicleData in pairs(vehicles) do
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
-- Prüfe ob Position nicht in einer Garage ist
local nearGarage = exports['jg-advancedgarages']:IsNearGarage(vector3(position.x, position.y, position.z), Config.MinGarageDistance)
if not nearGarage then
-- Spawne Fahrzeug
local modelHash = GetHashKey(vehicleData.model)
RequestModel(modelHash)
while not HasModelLoaded(modelHash) do
Wait(100)
end
local vehicle = CreateVehicle(modelHash, position.x, position.y, position.z, rotation.z, true, false)
if DoesEntityExist(vehicle) then
-- Setze Fahrzeugdaten
SetVehicleNumberPlateText(vehicle, vehicleData.plate)
SetVehicleEngineHealth(vehicle, vehicleData.engine_health)
SetVehicleBodyHealth(vehicle, vehicleData.body_health)
-- Setze Fuel (anpassen je nach System)
if exports['LegacyFuel'] then
exports['LegacyFuel']:SetFuel(vehicle, vehicleData.fuel)
end
-- Setze Mods
if vehicleData.mods then
local mods = json.decode(vehicleData.mods)
SetVehicleMods(vehicle, mods)
end
-- Verhindere Despawn
SetEntityAsMissionEntity(vehicle, true, true)
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
trackedVehicles[vehicleData.plate] = vehicle
if Config.Debug then
print(string.format("Spawned saved vehicle: %s", vehicleData.plate))
end
end
SetModelAsNoLongerNeeded(modelHash)
else
-- Entferne aus Datenbank da es zu nah an einer Garage ist
TriggerServerEvent('vehicle-persistence:server:removeVehicle', 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()
Wait(5000) -- Warte bis alles geladen ist
TriggerServerEvent('vehicle-persistence:server:loadVehicles')
end)
-- jg-advanced-garage Events
RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data)
-- Entferne aus Tracking wenn Fahrzeug gespeichert wird
if data and data.plate and trackedVehicles[data.plate] then
trackedVehicles[data.plate] = nil
if Config.Debug then
print(string.format("Vehicle stored, removed from tracking: %s", data.plate))
end
end
end)
RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data)
-- Entferne aus Tracking da Fahrzeug jetzt über Garage gespawnt wurde
if data and data.plate and trackedVehicles[data.plate] then
trackedVehicles[data.plate] = nil
if Config.Debug then
print(string.format("Vehicle spawned from garage, removed from tracking: %s", data.plate))
end
end
end)
-- Cleanup beim Disconnect
AddEventHandler('onResourceStop', function(resourceName)
if resourceName == GetCurrentResourceName() then
-- Cleanup Code hier falls nötig
trackedVehicles = {}
end
end)

View file

@ -0,0 +1,40 @@
Config = {}
-- Speicherintervall in Millisekunden (5000 = 5 Sekunden)
Config.SaveInterval = 5000
-- Maximale Distanz zum Fahrzeug bevor es als "verlassen" gilt
Config.MaxDistance = 100.0
-- Debug Modus
Config.Debug = false
-- Fahrzeugklassen die gespeichert werden sollen
Config.AllowedVehicleClasses = {
0, -- Compacts
1, -- Sedans
2, -- SUVs
3, -- Coupes
4, -- Muscle
5, -- Sports Classics
6, -- Sports
7, -- Super
8, -- Motorcycles
9, -- Off-road
10, -- Industrial
11, -- Utility
12, -- Vans
13, -- Cycles
14, -- Boats
15, -- Helicopters
16, -- Planes
17, -- Service
18, -- Emergency
19, -- Military
20, -- Commercial
21, -- Trains
22, -- Open Wheel
}
-- Mindestdistanz zu Garagen um Fahrzeuge zu tracken
Config.MinGarageDistance = 50.0

View file

@ -0,0 +1,25 @@
fx_version 'cerulean'
game 'gta5'
author 'YourName'
description 'Vehicle Persistence System for jg-advanced-garage'
version '1.0.0'
shared_scripts {
'config.lua'
}
server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/main.lua'
}
client_scripts {
'client/main.lua'
}
dependencies {
'qb-core',
'jg-advancedgarages',
'oxmysql'
}

View file

@ -0,0 +1,116 @@
local QBCore = exports['qb-core']:GetCoreObject()
-- Erstelle Tabelle bei Serverstart
CreateThread(function()
MySQL.query([[
CREATE TABLE IF NOT EXISTS `vehicle_positions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`plate` varchar(50) NOT NULL,
`citizenid` varchar(50) NOT NULL,
`model` varchar(50) NOT NULL,
`position` longtext NOT NULL,
`rotation` longtext NOT NULL,
`engine_health` float DEFAULT 1000.0,
`body_health` float DEFAULT 1000.0,
`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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
]])
end)
-- Speichere Fahrzeugposition
RegisterNetEvent('vehicle-persistence:server:saveVehiclePosition', function(vehicleData)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local query = [[
INSERT INTO vehicle_positions (plate, citizenid, model, position, rotation, engine_health, body_health, fuel, mods)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
position = VALUES(position),
rotation = VALUES(rotation),
engine_health = VALUES(engine_health),
body_health = VALUES(body_health),
fuel = VALUES(fuel),
mods = VALUES(mods),
last_updated = CURRENT_TIMESTAMP
]]
MySQL.insert(query, {
vehicleData.plate,
Player.PlayerData.citizenid,
vehicleData.model,
json.encode(vehicleData.position),
json.encode(vehicleData.rotation),
vehicleData.engineHealth,
vehicleData.bodyHealth,
vehicleData.fuel,
json.encode(vehicleData.mods)
})
if Config.Debug then
print(string.format("Saved vehicle position for plate: %s", vehicleData.plate))
end
end)
-- Lade gespeicherte Fahrzeuge beim Serverstart
RegisterNetEvent('vehicle-persistence:server:loadVehicles', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
MySQL.query('SELECT * FROM vehicle_positions WHERE citizenid = ?', {
Player.PlayerData.citizenid
}, function(result)
if result and #result > 0 then
TriggerClientEvent('vehicle-persistence:client:spawnSavedVehicles', src, result)
end
end)
end)
-- Entferne Fahrzeug aus Datenbank
RegisterNetEvent('vehicle-persistence:server:removeVehicle', function(plate)
MySQL.execute('DELETE FROM vehicle_positions WHERE plate = ?', {plate})
if Config.Debug then
print(string.format("Removed vehicle from persistence: %s", plate))
end
end)
-- Cleanup alte Einträge (älter als 24 Stunden)
CreateThread(function()
while true do
Wait(3600000) -- 1 Stunde
MySQL.execute('DELETE FROM vehicle_positions WHERE last_updated < DATE_SUB(NOW(), INTERVAL 24 HOUR)')
if Config.Debug then
print("Cleaned up old vehicle positions")
end
end
end)
-- jg-advanced-garage Events
RegisterNetEvent('jg-advancedgarages:server:vehicle-stored', function(data)
-- Entferne Fahrzeug aus Persistence wenn es in Garage gespeichert wird
if data and data.plate then
TriggerEvent('vehicle-persistence:server:removeVehicle', data.plate)
if Config.Debug then
print(string.format("Vehicle stored in garage, removed from persistence: %s", data.plate))
end
end
end)
RegisterNetEvent('jg-advancedgarages:server:vehicle-spawned', function(data)
-- Entferne aus Persistence da Fahrzeug jetzt über Garage gespawnt wurde
if data and data.plate then
TriggerEvent('vehicle-persistence:server:removeVehicle', data.plate)
if Config.Debug then
print(string.format("Vehicle spawned from garage, removed from persistence: %s", data.plate))
end
end
end)