ed
This commit is contained in:
		
							parent
							
								
									19928f3c5f
								
							
						
					
					
						commit
						90ab2c2b27
					
				
					 3 changed files with 326 additions and 219 deletions
				
			
		|  | @ -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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nordi98
						Nordi98