Files
Elite-Gaming-FiveM/resources/Server-Queue/server.lua
T
2021-12-03 01:05:09 +00:00

356 lines
7.3 KiB
Lua

-- {steamID, points, source}
local players = {}
-- {steamID}
local waiting = {}
-- {steamID}
local connecting = {}
-- Points initiaux (prioritaires ou négatifs)
local prePoints = Config.Points;
-- Emojis pour la loterie
local EmojiList = Config.EmojiList
StopResource('hardcap')
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() then
if GetResourceState('hardcap') == 'stopped' then
StartResource('hardcap')
end
end
end)
-- Connexion d'un client
AddEventHandler("playerConnecting", function(name, reject, def)
local source = source
local steamID = GetSteamID(source)
-- pas de steam ? ciao
if not steamID then
reject(Config.NoSteam)
CancelEvent()
return
end
-- Lancement de la rocade,
-- si cancel du client : CancelEvent() pour ne pas tenter de co.
if not Rocade(steamID, def, source) then
CancelEvent()
end
end)
-- Fonction principale, utilise l'objet "deferrals" transmis par l'evenement "playerConnecting"
function Rocade(steamID, def, source)
-- retarder la connexion
def.defer()
-- faire patienter un peu pour laisser le temps aux listes de s'actualiser
AntiSpam(def)
-- retirer notre ami d'une éventuelle liste d'attente ou connexion
Purge(steamID)
-- l'ajouter aux players
-- ou actualiser la source
AddPlayer(steamID, source)
-- le mettre en file d'attente
table.insert(waiting, steamID)
-- tant que le steamID n'est pas en connexion
local stop = false
repeat
for i,p in ipairs(connecting) do
if p == steamID then
stop = true
break
end
end
-- Hypothèse: Quand un joueur en file d'attente a un ping = 0, ça signifie que la source est perdue
-- Détecter si l'user clique sur "cancel"
-- Le retirer de la liste d'attente / connexion
-- Le message d'accident ne devrait j'amais s'afficher
for j,sid in ipairs(waiting) do
for i,p in ipairs(players) do
-- Si un joueur en file d'attente a un ping = 0
if sid == p[1] and p[1] == steamID and (GetPlayerPing(p[3]) == 0) then
-- le purger
Purge(steamID)
-- comme il a annulé, def.done ne sert qu'à identifier un cas non géré
def.done(Config.Accident)
return false
end
end
end
-- Mettre à jour le message d'attente
def.update(GetMessage(steamID))
Citizen.Wait(Config.TimerRefreshClient * 1000)
until stop
-- quand c'est fini, lancer la co
def.done()
return true
end
-- Vérifier si une place se libère pour le premier de la file
Citizen.CreateThread(function()
local maxServerSlots = GetConvarInt('sv_maxclients', 32)
while true do
Citizen.Wait(Config.TimerCheckPlaces * 1000)
CheckConnecting()
-- si une place est demandée et disponible
if #waiting > 0 and #connecting + #GetPlayers() < maxServerSlots then
ConnectFirst()
end
end
end)
-- Mettre régulièrement les points à jour
Citizen.CreateThread(function()
while true do
UpdatePoints()
Citizen.Wait(Config.TimerUpdatePoints * 1000)
end
end)
-- Lorsqu'un joueur est kick
-- lui retirer le nombre de points fourni en argument
RegisterServerEvent("rocademption:playerKicked")
AddEventHandler("rocademption:playerKicked", function(src, points)
local sid = GetSteamID(src)
Purge(sid)
for i,p in ipairs(prePoints) do
if p[1] == sid then
p[2] = p[2] - points
return
end
end
local initialPoints = GetInitialPoints(sid)
table.insert(prePoints, {sid, initialPoints - points})
end)
-- Quand un joueur spawn, le purger
RegisterServerEvent("rocademption:playerConnected")
AddEventHandler("rocademption:playerConnected", function()
local sid = GetSteamID(source)
Purge(sid)
end)
-- Quand un joueur drop, le purger
AddEventHandler("playerDropped", function(reason)
local steamID = GetSteamID(source)
Purge(steamID)
end)
-- si le ping d'un joueur en connexion semble partir en couille, le retirer de la file
-- Pour éviter un fantome en connexion
function CheckConnecting()
for i,sid in ipairs(connecting) do
for j,p in ipairs(players) do
if p[1] == sid and (GetPlayerPing(p[3]) == 500) then
table.remove(connecting, i)
break
end
end
end
end
-- ... connecte le premier de la file
function ConnectFirst()
if #waiting == 0 then return end
local maxPoint = 0
local maxSid = waiting[1][1]
local maxWaitId = 1
for i,sid in ipairs(waiting) do
local points = GetPoints(sid)
if points > maxPoint then
maxPoint = points
maxSid = sid
maxWaitId = i
end
end
table.remove(waiting, maxWaitId)
table.insert(connecting, maxSid)
end
-- retourne le nombre de kilomètres parcourus par un steamID
function GetPoints(steamID)
for i,p in ipairs(players) do
if p[1] == steamID then
return p[2]
end
end
end
-- Met à jour les points de tout le monde
function UpdatePoints()
for i,p in ipairs(players) do
local found = false
for j,sid in ipairs(waiting) do
if p[1] == sid then
p[2] = p[2] + Config.AddPoints
found = true
break
end
end
if not found then
for j,sid in ipairs(connecting) do
if p[1] == sid then
found = true
break
end
end
if not found then
p[2] = p[2] - Config.RemovePoints
if p[2] < GetInitialPoints(p[1]) - Config.RemovePoints then
Purge(p[1])
table.remove(players, i)
end
end
end
end
end
function AddPlayer(steamID, source)
for i,p in ipairs(players) do
if steamID == p[1] then
players[i] = {p[1], p[2], source}
return
end
end
local initialPoints = GetInitialPoints(steamID)
table.insert(players, {steamID, initialPoints, source})
end
function GetInitialPoints(steamID)
local points = Config.RemovePoints + 1
for n,p in ipairs(prePoints) do
if p[1] == steamID then
points = p[2]
break
end
end
return points
end
function GetPlace(steamID)
local points = GetPoints(steamID)
local place = 1
for i,sid in ipairs(waiting) do
for j,p in ipairs(players) do
if p[1] == sid and p[2] > points then
place = place + 1
end
end
end
return place
end
function GetMessage(steamID)
local msg = ""
if GetPoints(steamID) ~= nil then
msg = Config.EnRoute .. " " .. GetPoints(steamID) .." " .. Config.PointsRP ..".\n"
msg = msg .. Config.Position .. GetPlace(steamID) .. "/".. #waiting .. " " .. ".\n"
msg = msg .. "[ " .. Config.EmojiMsg
local e1 = RandomEmojiList()
local e2 = RandomEmojiList()
local e3 = RandomEmojiList()
local emojis = e1 .. e2 .. e3
if( e1 == e2 and e2 == e3 ) then
emojis = emojis .. Config.EmojiBoost
LoterieBoost(steamID)
end
-- avec les jolis emojis
msg = msg .. emojis .. " ]"
else
msg = Config.Error
end
return msg
end
function LoterieBoost(steamID)
for i,p in ipairs(players) do
if p[1] == steamID then
p[2] = p[2] + Config.LoterieBonusPoints
return
end
end
end
function Purge(steamID)
for n,sid in ipairs(connecting) do
if sid == steamID then
table.remove(connecting, n)
end
end
for n,sid in ipairs(waiting) do
if sid == steamID then
table.remove(waiting, n)
end
end
end
function AntiSpam(def)
for i=Config.AntiSpamTimer,0,-1 do
def.update(Config.PleaseWait_1 .. i .. Config.PleaseWait_2)
Citizen.Wait(1000)
end
end
function RandomEmojiList()
randomEmoji = EmojiList[math.random(#EmojiList)]
return randomEmoji
end
-- Helper pour récupérer le steamID or false
function GetSteamID(src)
local sid = GetPlayerIdentifiers(src)[1] or false
if (sid == false or sid:sub(1,5) ~= "steam") then
return false
end
return sid
end