-- {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