diff --git a/resources/[carscripts]/nordi_rental/client.lua b/resources/[carscripts]/nordi_rental/client.lua index f441a0d97..e9ba94b98 100644 --- a/resources/[carscripts]/nordi_rental/client.lua +++ b/resources/[carscripts]/nordi_rental/client.lua @@ -249,7 +249,21 @@ function returnSpecificVehicle(plate, locationId) -- Fahrzeug zurückgeben QBCore.Functions.TriggerCallback('vehiclerental:server:returnVehicle', function(success) if success then - DeleteVehicle(vehicle) + -- Make sure the vehicle is properly deleted + if DoesEntityExist(vehicle) then + -- First try native deletion + SetEntityAsMissionEntity(vehicle, true, true) + DeleteEntity(vehicle) + DeleteVehicle(vehicle) + + -- If AdvancedParking is available, also use its deletion method + if GetResourceState('AdvancedParking') == 'started' then + exports["AdvancedParking"]:DeleteVehicle(vehicle, false) + print("[VehicleRental] Using AdvancedParking to delete vehicle with plate: " .. plate) + end + end + + -- Remove from local tracking activeRentalVehicles[plate] = nil QBCore.Functions.Notify('Fahrzeug erfolgreich zurückgegeben!', 'success') end @@ -320,10 +334,36 @@ end) 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]) + if activeRentalVehicles[plate] then + local vehicle = activeRentalVehicles[plate] + + if DoesEntityExist(vehicle) then + -- Versuche verschiedene Methoden zum Löschen + SetEntityAsMissionEntity(vehicle, true, true) + DeleteVehicle(vehicle) + + -- Wenn AdvancedParking verfügbar ist, nutze auch dessen Löschmethode + if GetResourceState('AdvancedParking') == 'started' then + exports["AdvancedParking"]:DeleteVehicle(vehicle, false) + end + + print("[VehicleRental] Mietfahrzeug gelöscht: " .. plate) + else + print("[VehicleRental] Mietfahrzeug nicht gefunden für Löschung: " .. plate) + end + activeRentalVehicles[plate] = nil - print("Mietfahrzeug gelöscht: " .. plate) + end + + -- Suche nach dem Fahrzeug in der Welt anhand des Kennzeichens + for veh in EnumerateVehicles() do + local vehPlate = GetVehicleNumberPlateText(veh) + if string.gsub(vehPlate, "%s+", "") == string.gsub(plate, "%s+", "") then + SetEntityAsMissionEntity(veh, true, true) + DeleteVehicle(veh) + print("[VehicleRental] Zusätzliches Mietfahrzeug mit Kennzeichen gelöscht: " .. plate) + break + end end end) @@ -364,6 +404,57 @@ Citizen.CreateThread(function() end end) +-- Regelmäßige Überprüfung auf "Ghost"-Mietfahrzeuge +Citizen.CreateThread(function() + while true do + Citizen.Wait(300000) -- Alle 5 Minuten + + -- Hole alle aktiven Mietverhältnisse des Spielers + QBCore.Functions.TriggerCallback('vehiclerental:server:getPlayerRentals', function(rentals) + if not rentals or #rentals == 0 then return end + + local playerPos = GetEntityCoords(PlayerPedId()) + local plateList = {} + + -- Erstelle Liste der gemieteten Kennzeichen + for _, rental in ipairs(rentals) do + table.insert(plateList, rental.vehicle_plate) + end + + -- Suche nach allen Fahrzeugen in der Nähe + for veh in EnumerateVehicles() do + local vehPlate = GetVehicleNumberPlateText(veh) + local vehPos = GetEntityCoords(veh) + + -- Wenn das Fahrzeug nicht in der Liste der gemieteten Fahrzeuge ist und ein RENT-Kennzeichen hat + if string.find(vehPlate, "RENT") and not activeRentalVehicles[vehPlate] then + local isRented = false + + -- Prüfe, ob es in der Liste der gemieteten Fahrzeuge ist + for _, plate in ipairs(plateList) do + if string.gsub(vehPlate, "%s+", "") == string.gsub(plate, "%s+", "") then + isRented = true + activeRentalVehicles[plate] = veh -- Aktualisiere die lokale Tracking-Liste + break + end + end + + -- Wenn es nicht gemietet ist, aber ein RENT-Kennzeichen hat, lösche es + if not isRented and #(playerPos - vehPos) > 100.0 then + print("[VehicleRental] Lösche Ghost-Mietfahrzeug: " .. vehPlate) + SetEntityAsMissionEntity(veh, true, true) + DeleteVehicle(veh) + + if GetResourceState('AdvancedParking') == 'started' then + exports["AdvancedParking"]:DeleteVehicle(veh, false) + end + end + end + end + end) + end +end) + -- Fahrzeug-Enumerator function EnumerateVehicles() return coroutine.wrap(function() diff --git a/resources/[carscripts]/nordi_rental/server.lua b/resources/[carscripts]/nordi_rental/server.lua index c4ef7025b..0993884dd 100644 --- a/resources/[carscripts]/nordi_rental/server.lua +++ b/resources/[carscripts]/nordi_rental/server.lua @@ -196,6 +196,14 @@ QBCore.Functions.CreateCallback('vehiclerental:server:returnVehicle', function(s -- Entferne den Schlüssel für das Mietfahrzeug RemoveRentalKey(Player.PlayerData.citizenid, plate) + -- Check if AdvancedParking is available and delete the vehicle from its system + local advancedParkingSuccess = false + if GetResourceState('AdvancedParking') == 'started' then + -- Try to delete using AdvancedParking exports + advancedParkingSuccess = exports["AdvancedParking"]:DeleteVehicleUsingData(nil, nil, plate, false) + print("[VehicleRental] AdvancedParking vehicle deletion: " .. (advancedParkingSuccess and "successful" or "failed") .. " for plate " .. plate) + end + -- Benachrichtige alle Clients, dass das Fahrzeug zurückgegeben wurde TriggerClientEvent('vehiclerental:client:vehicleReturned', -1, plate) @@ -291,6 +299,12 @@ Citizen.CreateThread(function() -- Füge es zur Liste der zu entfernenden Fahrzeuge hinzu table.insert(overdueVehicles, plate) + + -- Versuche, das Fahrzeug mit AdvancedParking zu löschen + if GetResourceState('AdvancedParking') == 'started' then + exports["AdvancedParking"]:DeleteVehicleUsingData(nil, nil, plate, false) + print("[VehicleRental] Auto-deleted overdue vehicle with AdvancedParking: " .. plate) + end end end @@ -372,3 +386,42 @@ AddEventHandler('vehiclerental:server:checkRentalKeys', function() end end) end) + +-- Funktion zum Löschen aller Mietfahrzeuge eines Spielers (z.B. bei Charakter-Löschung) +exports('DeleteAllPlayerRentals', function(citizenid) + if not citizenid then return false end + + -- Hole alle aktiven Mietverhältnisse des Spielers + MySQL.Async.fetchAll('SELECT * FROM vehicle_rentals WHERE citizenid = ? AND returned = FALSE', { + citizenid + }, function(rentals) + if rentals and #rentals > 0 then + for _, rental in ipairs(rentals) do + -- Markiere als zurückgegeben + MySQL.Async.execute('UPDATE vehicle_rentals SET returned = TRUE WHERE id = ?', { + rental.id + }) + + -- Entferne den Schlüssel + RemoveRentalKey(citizenid, rental.vehicle_plate) + + -- Entferne aus dem Cache + activeRentals[rental.vehicle_plate] = nil + + -- Versuche, das Fahrzeug mit AdvancedParking zu löschen + if GetResourceState('AdvancedParking') == 'started' then + exports["AdvancedParking"]:DeleteVehicleUsingData(nil, nil, rental.vehicle_plate, false) + end + + -- Benachrichtige alle Clients + TriggerClientEvent('vehiclerental:client:vehicleReturned', -1, rental.vehicle_plate) + end + + print("[VehicleRental] Deleted all rental vehicles for player: " .. citizenid) + return true + end + + return false + end) +end) +