forked from Simnation/Main
600 lines
22 KiB
Lua
600 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)
|