1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-26 03:22:23 +02:00
parent 19928f3c5f
commit 90ab2c2b27
3 changed files with 326 additions and 219 deletions

View file

@ -1,44 +1,64 @@
local QBCore = exports['qb-core']:GetCoreObject()
local spawnedNPCs = {}
local currentRental = nil
local activeRentalVehicles = {}
-- NPCs spawnen
CreateThread(function()
-- Warte kurz, bis die Welt geladen ist
Wait(2000)
for i = 1, #Config.RentalLocations do
local location = Config.RentalLocations[i]
local modelHash = GetHashKey(location.npc.model)
RequestModel(location.npc.model)
while not HasModelLoaded(location.npc.model) do
Wait(1)
-- Modell laden
RequestModel(modelHash)
local timeout = 0
while not HasModelLoaded(modelHash) and timeout < 30 do
Wait(100)
timeout = timeout + 1
end
local npc = CreatePed(4, location.npc.model, location.npc.coords.x, location.npc.coords.y, location.npc.coords.z - 1.0, location.npc.coords.w, false, true)
FreezeEntityPosition(npc, true)
SetEntityInvincible(npc, true)
SetBlockingOfNonTemporaryEvents(npc, true)
spawnedNPCs[location.id] = npc
-- QB-Target für NPC
exports['qb-target']:AddTargetEntity(npc, {
options = {
{
type = "client",
event = "vehiclerental:client:openMenu",
icon = "fas fa-car",
label = "Fahrzeug mieten",
locationId = location.id
if HasModelLoaded(modelHash) then
-- NPC erstellen
local coords = location.npc.coords
local npc = CreatePed(4, modelHash, coords.x, coords.y, coords.z - 1.0, coords.w, false, false)
-- NPC-Eigenschaften setzen
FreezeEntityPosition(npc, true)
SetEntityInvincible(npc, true)
SetBlockingOfNonTemporaryEvents(npc, true)
SetPedDefaultComponentVariation(npc)
-- NPC speichern
spawnedNPCs[location.id] = npc
-- Debug-Info
print("NPC spawned at location: " .. location.name)
-- QB-Target für NPC
exports['qb-target']:AddTargetEntity(npc, {
options = {
{
type = "client",
event = "vehiclerental:client:openMenu",
icon = "fas fa-car",
label = "Fahrzeug mieten",
locationId = location.id
},
{
type = "client",
event = "vehiclerental:client:returnVehicle",
icon = "fas fa-car-side",
label = "Fahrzeug zurückgeben",
locationId = location.id
}
},
{
type = "client",
event = "vehiclerental:client:returnVehicle",
icon = "fas fa-car-side",
label = "Fahrzeug zurückgeben",
locationId = location.id
}
},
distance = 2.0
})
distance = 2.0
})
else
print("Failed to load NPC model for location: " .. location.name)
end
end
end)
@ -130,12 +150,18 @@ function spawnRentalVehicle(model, spawnPoint, plate)
TriggerEvent("vehiclekeys:client:SetOwner", plate)
SetModelAsNoLongerNeeded(model)
-- Registriere das Fahrzeug im Parking-System
TriggerEvent('vehiclerental:client:vehicleRented', vehicle, plate)
-- Speichere das Fahrzeug lokal
activeRentalVehicles[plate] = vehicle
-- Speichere die initiale Position
local pos = GetEntityCoords(vehicle)
local rot = GetEntityRotation(vehicle)
TriggerServerEvent('vehiclerental:server:updatePosition', plate, pos, rot)
print("Neues Mietfahrzeug erstellt: " .. plate)
end
-- Fahrzeug zurückgeben (KORRIGIERT - ohne im Auto zu sitzen)
-- Fahrzeug zurückgeben
RegisterNetEvent('vehiclerental:client:returnVehicle', function(data)
-- Hole alle aktiven Mietverhältnisse des Spielers
QBCore.Functions.TriggerCallback('vehiclerental:server:getPlayerRentals', function(rentals)
@ -171,17 +197,33 @@ end)
-- Spezifisches Fahrzeug zurückgeben
function returnSpecificVehicle(plate, locationId)
-- Finde die Location-Daten
local location = nil
for i = 1, #Config.RentalLocations do
if Config.RentalLocations[i].id == locationId then
location = Config.RentalLocations[i]
break
end
end
if not location then
QBCore.Functions.Notify('Fehler beim Finden des Rückgabeorts!', 'error')
return
end
-- Definiere den Rückgabeort
local returnPoint = vector3(location.returnPoint.x, location.returnPoint.y, location.returnPoint.z)
-- Finde das Fahrzeug in der Nähe
local playerPos = GetEntityCoords(PlayerPedId())
local vehicle = nil
local closestDistance = 50.0 -- Maximale Entfernung
local closestDistance = 50.0 -- Maximale Suchentfernung
-- Suche nach dem Fahrzeug mit dem Kennzeichen
for veh in EnumerateVehicles() do
local vehPlate = GetVehicleNumberPlateText(veh)
if string.gsub(vehPlate, "%s+", "") == string.gsub(plate, "%s+", "") then
local vehPos = GetEntityCoords(veh)
local distance = #(playerPos - vehPos)
local distance = #(returnPoint - vehPos)
if distance < closestDistance then
vehicle = veh
@ -191,38 +233,137 @@ function returnSpecificVehicle(plate, locationId)
end
if not vehicle then
QBCore.Functions.Notify('Fahrzeug nicht in der Nähe gefunden! Bringe es zum Mietort zurück.', 'error')
QBCore.Functions.Notify('Fahrzeug nicht in der Nähe des Rückgabeorts gefunden!', 'error')
return
end
-- Prüfe ob das Fahrzeug am richtigen Ort ist
local location = nil
for i = 1, #Config.RentalLocations do
if Config.RentalLocations[i].id == locationId then
location = Config.RentalLocations[i]
break
end
end
if location then
local returnPos = vector3(location.returnPoint.x, location.returnPoint.y, location.returnPoint.z)
local vehPos = GetEntityCoords(vehicle)
local distance = #(returnPos - vehPos)
if distance > 10.0 then
QBCore.Functions.Notify('Bringe das Fahrzeug näher zum Rückgabeort!', 'error')
return
end
-- Prüfe ob das Fahrzeug nahe genug am Rückgabeort ist
local vehPos = GetEntityCoords(vehicle)
local distance = #(returnPoint - vehPos)
if distance > Config.MaxReturnDistance then
QBCore.Functions.Notify('Das Fahrzeug muss näher am Rückgabeort sein! (Max. ' .. Config.MaxReturnDistance .. 'm)', 'error')
return
end
-- Fahrzeug zurückgeben
QBCore.Functions.TriggerCallback('vehiclerental:server:returnVehicle', function(success)
if success then
DeleteVehicle(vehicle)
activeRentalVehicles[plate] = nil
QBCore.Functions.Notify('Fahrzeug erfolgreich zurückgegeben!', 'success')
end
end, plate)
end
-- Lade alle aktiven Mietfahrzeuge
RegisterNetEvent('vehiclerental:client:loadRentals')
AddEventHandler('vehiclerental:client:loadRentals', function(rentals)
-- Lösche alle vorhandenen Mietfahrzeuge
for plate, vehicle in pairs(activeRentalVehicles) do
if DoesEntityExist(vehicle) then
DeleteVehicle(vehicle)
end
end
activeRentalVehicles = {}
-- Spawne alle aktiven Mietfahrzeuge
for _, rental in ipairs(rentals) do
-- Prüfe, ob das Fahrzeug dem aktuellen Spieler gehört
local playerCitizenId = QBCore.Functions.GetPlayerData().citizenid
if rental.citizenid == playerCitizenId then
-- Spawne das Fahrzeug nur, wenn es eine Position hat
if rental.posX ~= 0 or rental.posY ~= 0 or rental.posZ ~= 0 then
Citizen.CreateThread(function()
local model = rental.vehicle_model
local plate = rental.vehicle_plate
-- Lade das Modell
RequestModel(model)
while not HasModelLoaded(model) do
Citizen.Wait(10)
end
-- Spawne das Fahrzeug
local vehicle = CreateVehicle(model,
rental.posX, rental.posY, rental.posZ,
rental.rotZ or 0.0, true, false)
-- Setze Eigenschaften
SetVehicleNumberPlateText(vehicle, plate)
SetEntityAsMissionEntity(vehicle, true, true)
SetVehicleDoorsLocked(vehicle, 2) -- Abgeschlossen
-- Setze Rotation
SetEntityRotation(vehicle,
rental.rotX or 0.0,
rental.rotY or 0.0,
rental.rotZ or 0.0,
2, true)
-- Gib dem Spieler die Schlüssel
TriggerEvent("vehiclekeys:client:SetOwner", plate)
-- Speichere das Fahrzeug lokal
activeRentalVehicles[plate] = vehicle
print("Mietfahrzeug geladen: " .. plate)
end)
end
end
end
end)
-- Fahrzeug zurückgegeben
RegisterNetEvent('vehiclerental:client:vehicleReturned')
AddEventHandler('vehiclerental:client:vehicleReturned', function(plate)
-- Lösche das Fahrzeug, wenn es existiert
if activeRentalVehicles[plate] and DoesEntityExist(activeRentalVehicles[plate]) then
DeleteVehicle(activeRentalVehicles[plate])
activeRentalVehicles[plate] = nil
print("Mietfahrzeug gelöscht: " .. plate)
end
end)
-- Regelmäßiges Update der Fahrzeugpositionen
Citizen.CreateThread(function()
while true do
Citizen.Wait(30000) -- Alle 30 Sekunden
-- Update alle aktiven Mietfahrzeuge
for plate, vehicle in pairs(activeRentalVehicles) do
if DoesEntityExist(vehicle) then
local pos = GetEntityCoords(vehicle)
local rot = GetEntityRotation(vehicle)
TriggerServerEvent('vehiclerental:server:updatePosition', plate, pos, rot)
end
end
end
end)
-- Wenn der Spieler das Fahrzeug verlässt, aktualisiere die Position
Citizen.CreateThread(function()
while true do
Citizen.Wait(500)
local playerPed = PlayerPedId()
local vehicle = GetVehiclePedIsIn(playerPed, true)
if vehicle ~= 0 then
local plate = GetVehicleNumberPlateText(vehicle)
-- Wenn es ein Mietfahrzeug ist und der Spieler es gerade verlassen hat
if activeRentalVehicles[plate] and not IsPedInVehicle(playerPed, vehicle, false) then
local pos = GetEntityCoords(vehicle)
local rot = GetEntityRotation(vehicle)
TriggerServerEvent('vehiclerental:server:updatePosition', plate, pos, rot)
end
end
end
end)
-- Fahrzeug-Enumerator
function EnumerateVehicles()
return coroutine.wrap(function()
@ -236,7 +377,7 @@ function EnumerateVehicles()
end)
end
-- Kennzeichen generieren (GEÄNDERT - RENTAL + 3 zufällige Zeichen)
-- Kennzeichen generieren (RENT + 4 zufällige Zeichen)
function GeneratePlate()
local plate = "RENT"
for i = 1, 4 do
@ -258,24 +399,10 @@ AddEventHandler('onResourceStop', function(resourceName)
DeleteEntity(npc)
end
end
end)
-- Integration mit mh_Parking
RegisterNetEvent('vehiclerental:client:vehicleRented')
AddEventHandler('vehiclerental:client:vehicleRented', function(vehicle, plate)
-- Warte kurz, bis das Fahrzeug vollständig gespawnt ist
Citizen.Wait(1000)
-- Aktualisiere das Fahrzeug im Parking-System
if DoesEntityExist(vehicle) then
TriggerEvent("mh_Parking:updateVehicle", vehicle)
print("Mietfahrzeug im Parking-System registriert: " .. plate)
for plate, vehicle in pairs(activeRentalVehicles) do
if DoesEntityExist(vehicle) then
DeleteVehicle(vehicle)
end
end
end)
-- Wenn ein Mietfahrzeug zurückgegeben wird
RegisterNetEvent('vehiclerental:client:vehicleReturned')
AddEventHandler('vehiclerental:client:vehicleReturned', function(plate)
-- Entferne das Fahrzeug aus dem Parking-System
TriggerServerEvent("mh_Parking:deleteVehicle", plate, true)
print("Mietfahrzeug aus dem Parking-System entfernt: " .. plate)
end)

View file

@ -3,7 +3,8 @@ Config = {}
Config.MaxRentalTime = 24 -- Maximale Mietdauer in Stunden
Config.PenaltyPerHour = 100 -- Strafe pro Stunde Verspätung
Config.UseOkokBanking = false -- true für okokBanking, false für Bargeld
Config.MaxReturnDistance = 10.0 -- Maximale Entfernung zum Rückgabepunkt in Metern
Config.MaxReturnDistance = 20.0 -- Maximale Entfernung zum Rückgabepunkt in Metern
Config.MaxOverdueHours = 24 -- Nach wie vielen Stunden überfällige Fahrzeuge automatisch zurückgegeben werden
Config.RentalLocations = {
{

View file

@ -1,23 +1,46 @@
local QBCore = exports['qb-core']:GetCoreObject()
-- Datenbank Tabelle erstellen
MySQL.ready(function()
MySQL.Async.execute([[
CREATE TABLE IF NOT EXISTS vehicle_rentals (
id INT AUTO_INCREMENT PRIMARY KEY,
citizenid VARCHAR(50) NOT NULL,
vehicle_model VARCHAR(50) NOT NULL,
vehicle_plate VARCHAR(10) NOT NULL,
rental_location VARCHAR(50) NOT NULL,
start_time BIGINT NOT NULL,
end_time BIGINT NOT NULL,
price_per_hour INT NOT NULL,
returned BOOLEAN DEFAULT FALSE,
penalty_paid BOOLEAN DEFAULT FALSE,
INDEX(citizenid),
INDEX(vehicle_plate)
)
]])
local QBCore = exports['qb-core']:GetCoreObject()
local activeRentals = {}
-- Lade alle aktiven Mietfahrzeuge beim Serverstart
Citizen.CreateThread(function()
Wait(5000) -- Warte, bis die Datenbank bereit ist
MySQL.Async.fetchAll('SELECT * FROM vehicle_rentals WHERE returned = FALSE', {}, function(results)
if results and #results > 0 then
print("Lade " .. #results .. " aktive Mietfahrzeuge...")
for _, rental in ipairs(results) do
activeRentals[rental.vehicle_plate] = rental
end
-- Benachrichtige alle Clients, dass sie die Fahrzeuge spawnen sollen
TriggerClientEvent('vehiclerental:client:loadRentals', -1, results)
end
end)
end)
-- Aktualisiere die Position eines Mietfahrzeugs
RegisterServerEvent('vehiclerental:server:updatePosition')
AddEventHandler('vehiclerental:server:updatePosition', function(plate, position, rotation)
if not plate or not position then return end
-- Aktualisiere in der Datenbank
MySQL.Async.execute('UPDATE vehicle_rentals SET posX = ?, posY = ?, posZ = ?, rotX = ?, rotY = ?, rotZ = ?, lastUpdated = CURRENT_TIMESTAMP WHERE vehicle_plate = ? AND returned = FALSE', {
position.x, position.y, position.z,
rotation.x, rotation.y, rotation.z,
plate
})
-- Aktualisiere im Cache
if activeRentals[plate] then
activeRentals[plate].posX = position.x
activeRentals[plate].posY = position.y
activeRentals[plate].posZ = position.z
activeRentals[plate].rotX = rotation.x
activeRentals[plate].rotY = rotation.y
activeRentals[plate].rotZ = rotation.z
end
end)
-- Fahrzeug mieten
@ -57,10 +80,23 @@ QBCore.Functions.CreateCallback('vehiclerental:server:rentVehicle', function(sou
currentTime,
endTime,
data.pricePerHour
})
TriggerClientEvent('QBCore:Notify', source, 'Fahrzeug erfolgreich gemietet für $' .. totalCost, 'success')
cb(true)
}, function(rentalId)
-- Füge das Fahrzeug zum aktiven Cache hinzu
activeRentals[data.plate] = {
id = rentalId,
citizenid = Player.PlayerData.citizenid,
vehicle_model = data.vehicleModel,
vehicle_plate = data.plate,
rental_location = data.locationId,
start_time = currentTime,
end_time = endTime,
price_per_hour = data.pricePerHour,
returned = false
}
TriggerClientEvent('QBCore:Notify', source, 'Fahrzeug erfolgreich gemietet für $' .. totalCost, 'success')
cb(true)
end)
end)
-- Fahrzeug zurückgeben
@ -115,39 +151,48 @@ QBCore.Functions.CreateCallback('vehiclerental:server:returnVehicle', function(s
penalty > 0,
rental.id
})
-- Aus dem aktiven Cache entfernen
activeRentals[plate] = nil
-- Benachrichtige alle Clients, dass das Fahrzeug zurückgegeben wurde
TriggerClientEvent('vehiclerental:client:vehicleReturned', -1, plate)
TriggerClientEvent('QBCore:Notify', source, 'Fahrzeug erfolgreich zurückgegeben!', 'success')
cb(true)
end)
end)
-- Mietzeit abfragen
QBCore.Functions.CreateCallback('vehiclerental:server:getRentalInfo', function(source, cb)
-- Spieler Mietverhältnisse abrufen
QBCore.Functions.CreateCallback('vehiclerental:server:getPlayerRentals', function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
if not Player then return cb(nil) end
MySQL.Async.fetchAll('SELECT * FROM vehicle_rentals WHERE citizenid = ? AND returned = FALSE', {
Player.PlayerData.citizenid
}, function(result)
if not result[1] then
if not result or #result == 0 then
return cb(nil)
end
local rentals = {}
local currentTime = os.time()
for i = 1, #result do
local rental = result[i]
local currentTime = os.time()
local timeLeft = rental.end_time - currentTime
-- Berechne verbleibende Zeit auf dem Server
result[i].timeLeft = result[i].end_time - currentTime
result[i].isOverdue = result[i].timeLeft < 0
table.insert(rentals, {
vehicleModel = rental.vehicle_model,
plate = rental.vehicle_plate,
timeLeft = timeLeft,
isOverdue = timeLeft < 0
})
-- Formatiere die Zeit für die Anzeige
if result[i].isOverdue then
local hoursOverdue = math.ceil(math.abs(result[i].timeLeft) / 3600)
result[i].timeText = "(Überfällig um " .. hoursOverdue .. " Stunden)"
else
local hoursLeft = math.floor(result[i].timeLeft / 3600)
local minutesLeft = math.floor((result[i].timeLeft % 3600) / 60)
result[i].timeText = "(" .. hoursLeft .. "h " .. minutesLeft .. "m verbleibend)"
end
end
cb(rentals)
cb(result)
end)
end)
@ -184,115 +229,49 @@ QBCore.Commands.Add('mietzeit', 'Zeige deine aktuelle Mietzeit an', {}, false, f
end)
end)
-- Spieler Mietverhältnisse abrufen (VERBESSERT)
QBCore.Functions.CreateCallback('vehiclerental:server:getPlayerRentals', function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
if not Player then return cb(nil) end
-- Regelmäßige Überprüfung auf überfällige Fahrzeuge
Citizen.CreateThread(function()
while true do
Citizen.Wait(60000) -- Überprüfe jede Minute
local currentTime = os.time()
local overdueVehicles = {}
-- Überprüfe alle aktiven Mietfahrzeuge
for plate, rental in pairs(activeRentals) do
if currentTime > rental.end_time + (Config.MaxOverdueHours * 3600) then
-- Fahrzeug ist zu lange überfällig, markiere es als zurückgegeben
MySQL.Async.execute('UPDATE vehicle_rentals SET returned = TRUE, penalty_paid = TRUE WHERE vehicle_plate = ? AND returned = FALSE', {
plate
})
-- Füge es zur Liste der zu entfernenden Fahrzeuge hinzu
table.insert(overdueVehicles, plate)
end
end
-- Entferne überfällige Fahrzeuge aus dem Cache
for _, plate in ipairs(overdueVehicles) do
activeRentals[plate] = nil
-- Benachrichtige alle Clients, dass das Fahrzeug entfernt werden soll
TriggerClientEvent('vehiclerental:client:vehicleReturned', -1, plate)
end
end
end)
-- Spieler verbindet sich
RegisterNetEvent('QBCore:Server:PlayerLoaded')
AddEventHandler('QBCore:Server:PlayerLoaded', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
-- Sende dem Spieler seine aktiven Mietfahrzeuge
MySQL.Async.fetchAll('SELECT * FROM vehicle_rentals WHERE citizenid = ? AND returned = FALSE', {
Player.PlayerData.citizenid
}, function(result)
if not result or #result == 0 then
return cb(nil)
end
local currentTime = os.time()
for i = 1, #result do
-- Berechne verbleibende Zeit auf dem Server
result[i].timeLeft = result[i].end_time - currentTime
result[i].isOverdue = result[i].timeLeft < 0
-- Formatiere die Zeit für die Anzeige
if result[i].isOverdue then
local hoursOverdue = math.ceil(math.abs(result[i].timeLeft) / 3600)
result[i].timeText = "(Überfällig um " .. hoursOverdue .. " Stunden)"
else
local hoursLeft = math.floor(result[i].timeLeft / 3600)
local minutesLeft = math.floor((result[i].timeLeft % 3600) / 60)
result[i].timeText = "(" .. hoursLeft .. "h " .. minutesLeft .. "m verbleibend)"
end
end
cb(result)
end)
end)
-- Funktion zum Entfernen von Mietfahrzeugen aus dem Parking-System
function RemoveRentalFromParking(plate)
-- Entferne das Fahrzeug aus dem mh_Parking System
TriggerEvent("mh_Parking:removeVehicle", plate)
-- Lösche es auch aus der Datenbank des Parking-Systems
MySQL.Async.execute("DELETE FROM vehicle_parking WHERE plate = @plate", {
["@plate"] = plate
})
end
-- Wenn ein Fahrzeug zurückgegeben wird, entferne es aus dem Parking-System
RegisterNetEvent('vehiclerental:server:vehicleReturned')
AddEventHandler('vehiclerental:server:vehicleReturned', function(plate)
RemoveRentalFromParking(plate)
end)
-- Modifiziere die bestehende returnVehicle Callback-Funktion
local originalReturnCallback = QBCore.Functions.CreateCallback('vehiclerental:server:returnVehicle')
QBCore.Functions.CreateCallback('vehiclerental:server:returnVehicle', function(source, cb, plate)
-- Wenn das Fahrzeug erfolgreich zurückgegeben wurde
MySQL.Async.fetchAll('SELECT * FROM vehicle_rentals WHERE vehicle_plate = ? AND returned = FALSE', {
plate
}, function(result)
if result[1] then
-- Führe die normale Rückgabe durch
local Player = QBCore.Functions.GetPlayer(source)
local rental = result[1]
local currentTime = os.time()
local penalty = 0
-- Strafe berechnen wenn verspätet
if currentTime > rental.end_time then
local hoursLate = math.ceil((currentTime - rental.end_time) / 3600)
penalty = hoursLate * Config.PenaltyPerHour
end
-- Strafe abziehen falls vorhanden
if penalty > 0 then
local penaltyPaid = false
if Config.UseOkokBanking then
local bankMoney = exports['okokBanking']:GetAccount(Player.PlayerData.citizenid)
if bankMoney and bankMoney >= penalty then
exports['okokBanking']:RemoveMoney(Player.PlayerData.citizenid, penalty)
penaltyPaid = true
end
else
if Player.Functions.RemoveMoney('cash', penalty) then
penaltyPaid = true
end
end
if penaltyPaid then
TriggerClientEvent('QBCore:Notify', source, 'Verspätungsstrafe von $' .. penalty .. ' wurde abgezogen!', 'error')
else
TriggerClientEvent('QBCore:Notify', source, 'Nicht genug Geld für Verspätungsstrafe!', 'error')
return cb(false)
end
end
-- Mietverhältnis als zurückgegeben markieren
MySQL.Async.execute('UPDATE vehicle_rentals SET returned = TRUE, penalty_paid = ? WHERE id = ?', {
penalty > 0,
rental.id
})
-- Entferne das Fahrzeug aus dem Parking-System
RemoveRentalFromParking(plate)
-- Benachrichtige alle Clients
TriggerClientEvent('vehiclerental:client:vehicleReturned', -1, plate)
TriggerClientEvent('QBCore:Notify', source, 'Fahrzeug erfolgreich zurückgegeben!', 'success')
cb(true)
else
TriggerClientEvent('QBCore:Notify', source, 'Kein aktives Mietverhältnis für dieses Fahrzeug gefunden!', 'error')
cb(false)
}, function(results)
if results and #results > 0 then
TriggerClientEvent('vehiclerental:client:loadRentals', src, results)
end
end)
end)