Initial commit
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
-- {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
|
||||
Reference in New Issue
Block a user