599 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			599 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local QBCore = exports['qb-core']:GetCoreObject()
 | |
| local Races = {}
 | |
| local AvailableRaces = {}
 | |
| local LastRaces = {}
 | |
| local NotFinished = {}
 | |
| 
 | |
| -- Functions
 | |
| 
 | |
| local function SecondsToClock(seconds)
 | |
|     seconds = tonumber(seconds)
 | |
|     local retval
 | |
|     if seconds <= 0 then
 | |
|         retval = "00:00:00";
 | |
|     else
 | |
|         local hours = string.format("%02.f", math.floor(seconds / 3600));
 | |
|         local mins = string.format("%02.f", math.floor(seconds / 60 - (hours * 60)));
 | |
|         local secs = string.format("%02.f", math.floor(seconds - hours * 3600 - mins * 60));
 | |
|         retval = hours .. ":" .. mins .. ":" .. secs
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function IsWhitelisted(CitizenId)
 | |
|     local retval = false
 | |
|     for _, cid in pairs(Config.WhitelistedCreators) do
 | |
|         if cid == CitizenId then
 | |
|             retval = true
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     local Player = QBCore.Functions.GetPlayerByCitizenId(CitizenId)
 | |
|     local Perms = QBCore.Functions.GetPermission(Player.PlayerData.source)
 | |
|     if Perms == "admin" or Perms == "god" then
 | |
|         retval = true
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function IsNameAvailable(RaceName)
 | |
|     local retval = true
 | |
|     for RaceId, _ in pairs(Races) do
 | |
|         if Races[RaceId].RaceName == RaceName then
 | |
|             retval = false
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function HasOpenedRace(CitizenId)
 | |
|     local retval = false
 | |
|     for _, v in pairs(AvailableRaces) do
 | |
|         if v.SetupCitizenId == CitizenId then
 | |
|             retval = true
 | |
|         end
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function GetOpenedRaceKey(RaceId)
 | |
|     local retval = nil
 | |
|     for k, v in pairs(AvailableRaces) do
 | |
|         if v.RaceId == RaceId then
 | |
|             retval = k
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function GetCurrentRace(MyCitizenId)
 | |
|     local retval = nil
 | |
|     for RaceId, _ in pairs(Races) do
 | |
|         for cid, _ in pairs(Races[RaceId].Racers) do
 | |
|             if cid == MyCitizenId then
 | |
|                 retval = RaceId
 | |
|                 break
 | |
|             end
 | |
|         end
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function GetRaceId(name)
 | |
|     local retval = nil
 | |
|     for k, v in pairs(Races) do
 | |
|         if v.RaceName == name then
 | |
|             retval = k
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function GenerateRaceId()
 | |
|     local RaceId = "LR-" .. math.random(1111, 9999)
 | |
|     while Races[RaceId] ~= nil do
 | |
|         RaceId = "LR-" .. math.random(1111, 9999)
 | |
|     end
 | |
|     return RaceId
 | |
| end
 | |
| 
 | |
| -- Events
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:FinishPlayer', function(RaceData, TotalTime, TotalLaps, BestLap)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(src)
 | |
|     local AvailableKey = GetOpenedRaceKey(RaceData.RaceId)
 | |
|     local PlayersFinished = 0
 | |
|     local AmountOfRacers = 0
 | |
|     for _, v in pairs(Races[RaceData.RaceId].Racers) do
 | |
|         if v.Finished then
 | |
|             PlayersFinished = PlayersFinished + 1
 | |
|         end
 | |
|         AmountOfRacers = AmountOfRacers + 1
 | |
|     end
 | |
|     local BLap
 | |
|     if TotalLaps < 2 then
 | |
|         BLap = TotalTime
 | |
|     else
 | |
|         BLap = BestLap
 | |
|     end
 | |
|     if LastRaces[RaceData.RaceId] ~= nil then
 | |
|         LastRaces[RaceData.RaceId][#LastRaces[RaceData.RaceId]+1] =  {
 | |
|             TotalTime = TotalTime,
 | |
|             BestLap = BLap,
 | |
|             Holder = {
 | |
|                 [1] = Player.PlayerData.charinfo.firstname,
 | |
|                 [2] = Player.PlayerData.charinfo.lastname
 | |
|             }
 | |
|         }
 | |
|     else
 | |
|         LastRaces[RaceData.RaceId] = {}
 | |
|         LastRaces[RaceData.RaceId][#LastRaces[RaceData.RaceId]+1] =  {
 | |
|             TotalTime = TotalTime,
 | |
|             BestLap = BLap,
 | |
|             Holder = {
 | |
|                 [1] = Player.PlayerData.charinfo.firstname,
 | |
|                 [2] = Player.PlayerData.charinfo.lastname
 | |
|             }
 | |
|         }
 | |
|     end
 | |
|     if Races[RaceData.RaceId].Records ~= nil and next(Races[RaceData.RaceId].Records) ~= nil then
 | |
|         if BLap < Races[RaceData.RaceId].Records.Time then
 | |
|             Races[RaceData.RaceId].Records = {
 | |
|                 Time = BLap,
 | |
|                 Holder = {
 | |
|                     [1] = Player.PlayerData.charinfo.firstname,
 | |
|                     [2] = Player.PlayerData.charinfo.lastname
 | |
|                 }
 | |
|             }
 | |
|             MySQL.update('UPDATE lapraces SET records = ? WHERE raceid = ?',
 | |
|                 {json.encode(Races[RaceData.RaceId].Records), RaceData.RaceId})
 | |
|             TriggerClientEvent('qb-phone:client:RaceNotify', src, 'You have won the WR from ' .. RaceData.RaceName ..
 | |
|                 ' disconnected with a time of: ' .. SecondsToClock(BLap) .. '!')
 | |
|         end
 | |
|     else
 | |
|         Races[RaceData.RaceId].Records = {
 | |
|             Time = BLap,
 | |
|             Holder = {
 | |
|                 [1] = Player.PlayerData.charinfo.firstname,
 | |
|                 [2] = Player.PlayerData.charinfo.lastname
 | |
|             }
 | |
|         }
 | |
|         MySQL.update('UPDATE lapraces SET records = ? WHERE raceid = ?',
 | |
|             {json.encode(Races[RaceData.RaceId].Records), RaceData.RaceId})
 | |
|         TriggerClientEvent('qb-phone:client:RaceNotify', src, 'You have won the WR from ' .. RaceData.RaceName ..
 | |
|             ' put down with a time of: ' .. SecondsToClock(BLap) .. '!')
 | |
|     end
 | |
|     AvailableRaces[AvailableKey].RaceData = Races[RaceData.RaceId]
 | |
|     TriggerClientEvent('qb-lapraces:client:PlayerFinishs', -1, RaceData.RaceId, PlayersFinished, Player)
 | |
|     if PlayersFinished == AmountOfRacers then
 | |
|         if NotFinished ~= nil and next(NotFinished) ~= nil and NotFinished[RaceData.RaceId] ~= nil and
 | |
|             next(NotFinished[RaceData.RaceId]) ~= nil then
 | |
|             for _, v in pairs(NotFinished[RaceData.RaceId]) do
 | |
|                 LastRaces[RaceData.RaceId][#LastRaces[RaceData.RaceId]+1] = {
 | |
|                     TotalTime = v.TotalTime,
 | |
|                     BestLap = v.BestLap,
 | |
|                     Holder = {
 | |
|                         [1] = v.Holder[1],
 | |
|                         [2] = v.Holder[2]
 | |
|                     }
 | |
|                 }
 | |
|             end
 | |
|         end
 | |
|         Races[RaceData.RaceId].LastLeaderboard = LastRaces[RaceData.RaceId]
 | |
|         Races[RaceData.RaceId].Racers = {}
 | |
|         Races[RaceData.RaceId].Started = false
 | |
|         Races[RaceData.RaceId].Waiting = false
 | |
|         table.remove(AvailableRaces, AvailableKey)
 | |
|         LastRaces[RaceData.RaceId] = nil
 | |
|         NotFinished[RaceData.RaceId] = nil
 | |
|     end
 | |
|     TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:CreateLapRace', function(RaceName)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(src)
 | |
| 
 | |
|     if IsWhitelisted(Player.PlayerData.citizenid) then
 | |
|         if IsNameAvailable(RaceName) then
 | |
|             TriggerClientEvent('qb-lapraces:client:StartRaceEditor', source, RaceName)
 | |
|         else
 | |
|             TriggerClientEvent('QBCore:Notify', source, 'There is already a race with this name.', 'error')
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent('QBCore:Notify', source, 'You have not been authorized to race\'s to create.', 'error')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:JoinRace', function(RaceData)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(src)
 | |
|     local RaceId = RaceData.RaceId
 | |
|     local AvailableKey = GetOpenedRaceKey(RaceId)
 | |
|     local CurrentRace = GetCurrentRace(Player.PlayerData.citizenid)
 | |
|     if CurrentRace ~= nil then
 | |
|         local AmountOfRacers = 0
 | |
|         local PreviousRaceKey = GetOpenedRaceKey(CurrentRace)
 | |
|         for _, _ in pairs(Races[CurrentRace].Racers) do
 | |
|             AmountOfRacers = AmountOfRacers + 1
 | |
|         end
 | |
|         Races[CurrentRace].Racers[Player.PlayerData.citizenid] = nil
 | |
|         if (AmountOfRacers - 1) == 0 then
 | |
|             Races[CurrentRace].Racers = {}
 | |
|             Races[CurrentRace].Started = false
 | |
|             Races[CurrentRace].Waiting = false
 | |
|             table.remove(AvailableRaces, PreviousRaceKey)
 | |
|             TriggerClientEvent('QBCore:Notify', src, 'You were the only one in the race, the race had ended', 'error')
 | |
|             TriggerClientEvent('qb-lapraces:client:LeaveRace', src, Races[CurrentRace])
 | |
|         else
 | |
|             AvailableRaces[PreviousRaceKey].RaceData = Races[CurrentRace]
 | |
|             TriggerClientEvent('qb-lapraces:client:LeaveRace', src, Races[CurrentRace])
 | |
|         end
 | |
|         TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|     end
 | |
|     Races[RaceId].Waiting = true
 | |
|     Races[RaceId].Racers[Player.PlayerData.citizenid] = {
 | |
|         Checkpoint = 0,
 | |
|         Lap = 1,
 | |
|         Finished = false
 | |
|     }
 | |
|     AvailableRaces[AvailableKey].RaceData = Races[RaceId]
 | |
|     TriggerClientEvent('qb-lapraces:client:JoinRace', src, Races[RaceId], AvailableRaces[AvailableKey].Laps)
 | |
|     TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|     local creatorsource = QBCore.Functions.GetPlayerByCitizenId(AvailableRaces[AvailableKey].SetupCitizenId).PlayerData
 | |
|                               .source
 | |
|     if creatorsource ~= Player.PlayerData.source then
 | |
|         TriggerClientEvent('qb-phone:client:RaceNotify', creatorsource,
 | |
|             string.sub(Player.PlayerData.charinfo.firstname, 1, 1) .. '. ' .. Player.PlayerData.charinfo.lastname ..
 | |
|                 ' the race has been joined!')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:LeaveRace', function(RaceData)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(src)
 | |
|     local RaceName
 | |
|     if RaceData.RaceData ~= nil then
 | |
|         RaceName = RaceData.RaceData.RaceName
 | |
|     else
 | |
|         RaceName = RaceData.RaceName
 | |
|     end
 | |
|     local RaceId = GetRaceId(RaceName)
 | |
|     local AvailableKey = GetOpenedRaceKey(RaceData.RaceId)
 | |
|     local creatorsource = QBCore.Functions.GetPlayerByCitizenId(AvailableRaces[AvailableKey].SetupCitizenId).PlayerData
 | |
|                               .source
 | |
|     if creatorsource ~= Player.PlayerData.source then
 | |
|         TriggerClientEvent('qb-phone:client:RaceNotify', creatorsource,
 | |
|             string.sub(Player.PlayerData.charinfo.firstname, 1, 1) .. '. ' .. Player.PlayerData.charinfo.lastname ..
 | |
|                 ' the race has been delivered!')
 | |
|     end
 | |
|     local AmountOfRacers = 0
 | |
|     for _, _ in pairs(Races[RaceData.RaceId].Racers) do
 | |
|         AmountOfRacers = AmountOfRacers + 1
 | |
|     end
 | |
|     if NotFinished[RaceData.RaceId] ~= nil then
 | |
|         NotFinished[RaceData.RaceId][#NotFinished[RaceData.RaceId]+1] = {
 | |
|             TotalTime = "DNF",
 | |
|             BestLap = "DNF",
 | |
|             Holder = {
 | |
|                 [1] = Player.PlayerData.charinfo.firstname,
 | |
|                 [2] = Player.PlayerData.charinfo.lastname
 | |
|             }
 | |
|         }
 | |
|     else
 | |
|         NotFinished[RaceData.RaceId] = {}
 | |
|         NotFinished[RaceData.RaceId][#NotFinished[RaceData.RaceId]+1] = {
 | |
|             TotalTime = "DNF",
 | |
|             BestLap = "DNF",
 | |
|             Holder = {
 | |
|                 [1] = Player.PlayerData.charinfo.firstname,
 | |
|                 [2] = Player.PlayerData.charinfo.lastname
 | |
|             }
 | |
|         }
 | |
|     end
 | |
|     Races[RaceId].Racers[Player.PlayerData.citizenid] = nil
 | |
|     if (AmountOfRacers - 1) == 0 then
 | |
|         if NotFinished ~= nil and next(NotFinished) ~= nil and NotFinished[RaceId] ~= nil and next(NotFinished[RaceId]) ~=
 | |
|             nil then
 | |
|             for _, v in pairs(NotFinished[RaceId]) do
 | |
|                 if LastRaces[RaceId] ~= nil then
 | |
|                     LastRaces[RaceId][#LastRaces[RaceId]+1] = {
 | |
|                         TotalTime = v.TotalTime,
 | |
|                         BestLap = v.BestLap,
 | |
|                         Holder = {
 | |
|                             [1] = v.Holder[1],
 | |
|                             [2] = v.Holder[2]
 | |
|                         }
 | |
|                     }
 | |
|                 else
 | |
|                     LastRaces[RaceId] = {}
 | |
|                     LastRaces[RaceId][#LastRaces[RaceId]+1] = {
 | |
|                         TotalTime = v.TotalTime,
 | |
|                         BestLap = v.BestLap,
 | |
|                         Holder = {
 | |
|                             [1] = v.Holder[1],
 | |
|                             [2] = v.Holder[2]
 | |
|                         }
 | |
|                     }
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|         Races[RaceId].LastLeaderboard = LastRaces[RaceId]
 | |
|         Races[RaceId].Racers = {}
 | |
|         Races[RaceId].Started = false
 | |
|         Races[RaceId].Waiting = false
 | |
|         table.remove(AvailableRaces, AvailableKey)
 | |
|         TriggerClientEvent('QBCore:Notify', src, 'You were the only one in the race.The race had ended.', 'error')
 | |
|         TriggerClientEvent('qb-lapraces:client:LeaveRace', src, Races[RaceId])
 | |
|         LastRaces[RaceId] = nil
 | |
|         NotFinished[RaceId] = nil
 | |
|     else
 | |
|         AvailableRaces[AvailableKey].RaceData = Races[RaceId]
 | |
|         TriggerClientEvent('qb-lapraces:client:LeaveRace', src, Races[RaceId])
 | |
|     end
 | |
|     TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:SetupRace', function(RaceId, Laps)
 | |
|     local Player = QBCore.Functions.GetPlayer(source)
 | |
|     if Races[RaceId] ~= nil then
 | |
|         if not Races[RaceId].Waiting then
 | |
|             if not Races[RaceId].Started then
 | |
|                 Races[RaceId].Waiting = true
 | |
|                 AvailableRaces[#AvailableRaces+1] = {
 | |
|                     RaceData = Races[RaceId],
 | |
|                     Laps = Laps,
 | |
|                     RaceId = RaceId,
 | |
|                     SetupCitizenId = Player.PlayerData.citizenid
 | |
|                 }
 | |
|                 TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|                 SetTimeout(5 * 60 * 1000, function()
 | |
|                     if Races[RaceId].Waiting then
 | |
|                         local AvailableKey = GetOpenedRaceKey(RaceId)
 | |
|                         for cid, _ in pairs(Races[RaceId].Racers) do
 | |
|                             local RacerData = QBCore.Functions.GetPlayerByCitizenId(cid)
 | |
|                             if RacerData ~= nil then
 | |
|                                 TriggerClientEvent('qb-lapraces:client:LeaveRace', RacerData.PlayerData.source,
 | |
|                                     Races[RaceId])
 | |
|                             end
 | |
|                         end
 | |
|                         table.remove(AvailableRaces, AvailableKey)
 | |
|                         Races[RaceId].LastLeaderboard = {}
 | |
|                         Races[RaceId].Racers = {}
 | |
|                         Races[RaceId].Started = false
 | |
|                         Races[RaceId].Waiting = false
 | |
|                         LastRaces[RaceId] = nil
 | |
|                         TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|                     end
 | |
|                 end)
 | |
|             else
 | |
|                 TriggerClientEvent('QBCore:Notify', source, 'The race is already running', 'error')
 | |
|             end
 | |
|         else
 | |
|             TriggerClientEvent('QBCore:Notify', source, 'The race is already running', 'error')
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent('QBCore:Notify', source, 'This race does not exist :(', 'error')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:CancelRace', function(raceId)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(source)
 | |
|     local AvailableKey = GetOpenedRaceKey(raceId)
 | |
| 
 | |
|     TriggerClientEvent('QBCore:Notify', src, 'Stopping the race: ' .. raceId, 'error')
 | |
| 
 | |
|     if AvailableKey ~= nil then
 | |
|         if AvailableRaces[AvailableKey].SetupCitizenId == Player.PlayerData.citizenid then
 | |
|             for cid, _ in pairs(Races[raceId].Racers) do
 | |
|                 local RacerData = QBCore.Functions.GetPlayerByCitizenId(cid)
 | |
|                 if RacerData ~= nil then
 | |
|                     TriggerClientEvent('qb-lapraces:client:LeaveRace', RacerData.PlayerData.source, Races[raceId])
 | |
|                 end
 | |
|             end
 | |
| 
 | |
|             table.remove(AvailableRaces, AvailableKey)
 | |
|             Races[raceId].LastLeaderboard = {}
 | |
|             Races[raceId].Racers = {}
 | |
|             Races[raceId].Started = false
 | |
|             Races[raceId].Waiting = false
 | |
|             LastRaces[raceId] = nil
 | |
|             TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent('QBCore:Notify', src, 'Race not open: ' .. raceId, 'error')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:UpdateRaceState', function(RaceId, Started, Waiting)
 | |
|     Races[RaceId].Waiting = Waiting
 | |
|     Races[RaceId].Started = Started
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:UpdateRacerData', function(RaceId, Checkpoint, Lap, Finished)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(src)
 | |
|     local CitizenId = Player.PlayerData.citizenid
 | |
| 
 | |
|     Races[RaceId].Racers[CitizenId].Checkpoint = Checkpoint
 | |
|     Races[RaceId].Racers[CitizenId].Lap = Lap
 | |
|     Races[RaceId].Racers[CitizenId].Finished = Finished
 | |
| 
 | |
|     TriggerClientEvent('qb-lapraces:client:UpdateRaceRacerData', -1, RaceId, Races[RaceId])
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:StartRace', function(RaceId)
 | |
|     local src = source
 | |
|     local MyPlayer = QBCore.Functions.GetPlayer(src)
 | |
|     local AvailableKey = GetOpenedRaceKey(RaceId)
 | |
| 
 | |
|     if RaceId ~= nil then
 | |
|         if AvailableRaces[AvailableKey].SetupCitizenId == MyPlayer.PlayerData.citizenid then
 | |
|             AvailableRaces[AvailableKey].RaceData.Started = true
 | |
|             AvailableRaces[AvailableKey].RaceData.Waiting = false
 | |
|             for CitizenId, _ in pairs(Races[RaceId].Racers) do
 | |
|                 local Player = QBCore.Functions.GetPlayerByCitizenId(CitizenId)
 | |
|                 if Player ~= nil then
 | |
|                     TriggerClientEvent('qb-lapraces:client:RaceCountdown', Player.PlayerData.source)
 | |
|                 end
 | |
|             end
 | |
|             TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|         else
 | |
|             TriggerClientEvent('QBCore:Notify', src, 'You are not the creator of the race..', 'error')
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent('QBCore:Notify', src, 'You are not in a race..', 'error')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('qb-lapraces:server:SaveRace', function(RaceData)
 | |
|     local src = source
 | |
|     local Player = QBCore.Functions.GetPlayer(src)
 | |
|     local RaceId = GenerateRaceId()
 | |
|     local Checkpoints = {}
 | |
|     for k, v in pairs(RaceData.Checkpoints) do
 | |
|         Checkpoints[k] = {
 | |
|             offset = v.offset,
 | |
|             coords = v.coords
 | |
|         }
 | |
|     end
 | |
|     Races[RaceId] = {
 | |
|         RaceName = RaceData.RaceName,
 | |
|         Checkpoints = Checkpoints,
 | |
|         Records = {},
 | |
|         Creator = Player.PlayerData.citizenid,
 | |
|         RaceId = RaceId,
 | |
|         Started = false,
 | |
|         Waiting = false,
 | |
|         Distance = math.ceil(RaceData.RaceDistance),
 | |
|         Racers = {},
 | |
|         LastLeaderboard = {}
 | |
|     }
 | |
|     MySQL.insert('INSERT INTO lapraces (name, checkpoints, creator, distance, raceid) VALUES (?, ?, ?, ?, ?)',
 | |
|         {RaceData.RaceName, json.encode(Checkpoints), Player.PlayerData.citizenid, RaceData.RaceDistance,
 | |
|          GenerateRaceId()})
 | |
| end)
 | |
| 
 | |
| -- Callbacks
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:GetRacingLeaderboards', function(_, cb)
 | |
|     cb(Races)
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:GetRaces', function(_, cb)
 | |
|     cb(AvailableRaces)
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:GetListedRaces', function(_, cb)
 | |
|     cb(Races)
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:GetRacingData', function(_, cb, RaceId)
 | |
|     cb(Races[RaceId])
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:HasCreatedRace', function(source, cb)
 | |
|     cb(HasOpenedRace(QBCore.Functions.GetPlayer(source).PlayerData.citizenid))
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:IsAuthorizedToCreateRaces', function(source, cb, TrackName)
 | |
|     cb(IsWhitelisted(QBCore.Functions.GetPlayer(source).PlayerData.citizenid), IsNameAvailable(TrackName))
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:CanRaceSetup', function(_, cb)
 | |
|     cb(Config.RaceSetupAllowed)
 | |
| end)
 | |
| 
 | |
| QBCore.Functions.CreateCallback('qb-lapraces:server:GetTrackData', function(_, cb, RaceId)
 | |
|     local result = MySQL.query.await('SELECT * FROM players WHERE citizenid = ?', {Races[RaceId].Creator})
 | |
|     if result[1] ~= nil then
 | |
|         result[1].charinfo = json.decode(result[1].charinfo)
 | |
|         cb(Races[RaceId], result[1])
 | |
|     else
 | |
|         cb(Races[RaceId], {
 | |
|             charinfo = {
 | |
|                 firstname = "Unknown",
 | |
|                 lastname = "Unknown"
 | |
|             }
 | |
|         })
 | |
|     end
 | |
| end)
 | |
| 
 | |
| -- Commands
 | |
| 
 | |
| QBCore.Commands.Add("cancelrace", "Cancel going race..", {}, false, function(source, args)
 | |
|     local Player = QBCore.Functions.GetPlayer(source)
 | |
| 
 | |
|     if IsWhitelisted(Player.PlayerData.citizenid) then
 | |
|         local RaceName = table.concat(args, " ")
 | |
|         if RaceName ~= nil then
 | |
|             local RaceId = GetRaceId(RaceName)
 | |
|             if Races[RaceId].Started then
 | |
|                 local AvailableKey = GetOpenedRaceKey(RaceId)
 | |
|                 for cid, _ in pairs(Races[RaceId].Racers) do
 | |
|                     local RacerData = QBCore.Functions.GetPlayerByCitizenId(cid)
 | |
|                     if RacerData ~= nil then
 | |
|                         TriggerClientEvent('qb-lapraces:client:LeaveRace', RacerData.PlayerData.source, Races[RaceId])
 | |
|                     end
 | |
|                 end
 | |
|                 table.remove(AvailableRaces, AvailableKey)
 | |
|                 Races[RaceId].LastLeaderboard = {}
 | |
|                 Races[RaceId].Racers = {}
 | |
|                 Races[RaceId].Started = false
 | |
|                 Races[RaceId].Waiting = false
 | |
|                 LastRaces[RaceId] = nil
 | |
|                 TriggerClientEvent('qb-phone:client:UpdateLapraces', -1)
 | |
|             else
 | |
|                 TriggerClientEvent('QBCore:Notify', source, 'This race has not started yet.', 'error')
 | |
|             end
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent('QBCore:Notify', source, 'You have not been authorized to do this.', 'error')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| QBCore.Commands.Add("togglesetup", "Turn on / off racing setup", {}, false, function(source, _)
 | |
|     local Player = QBCore.Functions.GetPlayer(source)
 | |
| 
 | |
|     if IsWhitelisted(Player.PlayerData.citizenid) then
 | |
|         Config.RaceSetupAllowed = not Config.RaceSetupAllowed
 | |
|         if not Config.RaceSetupAllowed then
 | |
|             TriggerClientEvent('QBCore:Notify', source, 'No more races can be created!', 'error')
 | |
|         else
 | |
|             TriggerClientEvent('QBCore:Notify', source, 'Races can be created again!', 'success')
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent('QBCore:Notify', source, 'You have not been authorized to do this.', 'error')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| -- Threads
 | |
| 
 | |
| CreateThread(function()
 | |
|     local races = MySQL.query.await('SELECT * FROM lapraces', {})
 | |
|     if races[1] ~= nil then
 | |
|         for _, v in pairs(races) do
 | |
|             local Records = {}
 | |
|             if v.records ~= nil then
 | |
|                 Records = json.decode(v.records)
 | |
|             end
 | |
|             Races[v.raceid] = {
 | |
|                 RaceName = v.name,
 | |
|                 Checkpoints = json.decode(v.checkpoints),
 | |
|                 Records = Records,
 | |
|                 Creator = v.creator,
 | |
|                 RaceId = v.raceid,
 | |
|                 Started = false,
 | |
|                 Waiting = false,
 | |
|                 Distance = v.distance,
 | |
|                 LastLeaderboard = {},
 | |
|                 Racers = {}
 | |
|             }
 | |
|         end
 | |
|     end
 | |
| end)
 | 
