Hey, you can find the code here for “ignore staff”
-- if not lib.checkDependency('ox_lib', '3.30.0', true) then return end
---@class Config
local Config = {
GuildID = "956998102479405077",
DiscordBotToken = "YOUR DISCORD TOKEN",
VoiceChannels = lib.table.freeze({
"1376905746603708528",
"1296207068088373330"
}),
BypassRoles = lib.table.freeze({
"1295864051674513503"--,
--""
}),
Messages = {
checking = "Vérification des autorisations...",
voiceRequired = "^1Vous devez être dans le salon [ Présence IG ] pour rejoindre le serveur",
noDiscord = "^1Impossible de vérifier votre compte Discord",
invalidPlayer = "^1Erreur de vérification du joueur"
},
CheckInterval = 3 * 60000 -- 3 minutes
}
---@type table<number, boolean>
local playerChecks = {}
---@type table<number, boolean>
local bypassCache = {}
---@param source number
---@return boolean
local function IsPlayerValid(source)
if not source then
lib.print.info('Source invalide')
return false
end
if not DoesPlayerExist(source) then
lib.print.warn('Joueur inexistant:', source)
return false
end
return true
end
---@param source number
---@return string|nil
local function GetDiscordId(source)
if not IsPlayerValid(source) then return nil end
local discordId = GetPlayerIdentifierByType(source, "discord")
if not discordId then
lib.print.warn('Discord non trouvé pour:', source)
return nil
end
local cleanId = discordId:gsub("discord:", "")
lib.print.info('Discord ID:', source, '->', cleanId)
return cleanId
end
---@param source number
---@return boolean
local function CheckVoiceChannel(source)
if not IsPlayerValid(source) then return false end
local discordId = GetDiscordId(source)
if not discordId then return false end
local endpoint = string.format("https://discord.com/api/v9/guilds/%s/voice-states/%s", Config.GuildID, discordId)
local headers = {["Authorization"] = "Bot " .. Config.DiscordBotToken, ["Content-Type"] = "application/json"}
local statusCode, response = PerformHttpRequestAwait(endpoint, 'GET', "", headers)
if not statusCode == 200 or not response then
lib.print.error('Erreur API Discord:', source, 'Status:', statusCode)
return false
end
local success, data = pcall(json.decode, response)
if not success then
lib.print.error('Erreur decode JSON:', source)
return false
end
local isInChannel = lib.table.contains(Config.VoiceChannels, data.channel_id)
lib.print.info('Vérif vocal:', source, '->', isInChannel)
return isInChannel
end
---@param source number
---@return boolean
local function HasBypassRole(source)
if not IsPlayerValid(source) then return false end
if bypassCache[source] ~= nil then
lib.print.info('Cache bypass:', source, '->', bypassCache[source])
return bypassCache[source]
end
local discordId = GetDiscordId(source)
if not discordId then return false end
local endpoint = string.format("https://discord.com/api/v9/guilds/%s/members/%s", Config.GuildID, discordId)
local headers = {["Authorization"] = "Bot " .. Config.DiscordBotToken, ["Content-Type"] = "application/json"}
local statusCode, response = PerformHttpRequestAwait(endpoint, 'GET', "", headers)
if not statusCode == 200 or not response then
lib.print.error('Erreur API Discord:', source, 'Status:', statusCode)
return false
end
local success, data = pcall(json.decode, response)
if not success then
lib.print.error('Erreur decode JSON:', source)
return false
end
local hasRole = false
for _, roleId in ipairs(Config.BypassRoles) do
if lib.table.contains(data.roles or {}, roleId) then
hasRole = true
break
end
end
bypassCache[source] = hasRole
lib.print.info('Vérif bypass:', source, '->', hasRole)
return hasRole
end
AddEventHandler('playerConnecting', function(name, _, deferrals)
local source = source
deferrals.defer()
Wait(0)
if not IsPlayerValid(source) then
lib.print.error('Connexion invalide:', source)
return deferrals.done(Config.Messages.invalidPlayer)
end
lib.print.info('Connexion:', name, '(ID:', source, ')')
deferrals.update(Config.Messages.checking)
if not GetDiscordId(source) then
lib.print.warn('Pas de Discord:', source)
return deferrals.done(Config.Messages.noDiscord)
end
if HasBypassRole(source) then
lib.print.info('Bypass autorisé:', source)
return deferrals.done()
end
playerChecks[source] = true
if CheckVoiceChannel(source) then
lib.print.info('Vocal vérifié:', source)
deferrals.done()
else
lib.print.warn('Vocal requis:', source)
deferrals.done(Config.Messages.voiceRequired)
end
playerChecks[source] = nil
end)
AddEventHandler('playerDropped', function()
local source = source
if not IsPlayerValid(source) then return end
playerChecks[source] = nil
bypassCache[source] = nil
lib.print.info('Cache nettoyé:', source)
end)
CreateThread(function()
local arr = {}
local num = 0
while true do
Wait(Config.CheckInterval)
lib.print.info('Début vérification périodique')
for _, playerId in ipairs(GetPlayers()) do
if IsPlayerValid(playerId) and not playerChecks[playerId] then
if not HasBypassRole(playerId) and not CheckVoiceChannel(playerId) then
num += 1
arr[num] = playerId
lib.print.warn('Joueur Ă expulser:', playerId)
end
end
end
if num > 0 then
lib.print.info('Expulsion de', num, 'joueurs')
for i = 1, num do
if IsPlayerValid(arr[i]) then
DropPlayer(arr[i], Config.Messages.voiceRequired)
end
end
table.wipe(arr)
num = 0
end
end
end)