Overview
TheKickPlayer function allows staff members to remove players from the server immediately. All kicks are logged and can trigger webhook notifications if configured.
KickPlayer
Remove a player from the server with a specified reason.Syntax
Copy
local success, status = exports['zyrix_admin']:KickPlayer(staffId, targetId, reason)
Parameters
staffId(number) - Server ID of the staff member performing the kicktargetId(number) - Server ID of the player to kickreason(string) - Reason for the kick (minimum 3 characters)
Returns
success(boolean) - Whether the kick was successfulstatus(string) - Status code:'success','no_permission','player_not_found','invalid_target','invalid_reason'
Example
Copy
-- Kick player for AFK
local success, status = exports['zyrix_admin']:KickPlayer(source, targetId, "AFK for extended period")
if success then
TriggerClientEvent('chat:addMessage', -1, {
color = {255, 165, 0},
multiline = false,
args = {"[Kick]", string.format("%s was kicked: %s", GetPlayerName(targetId), reason)}
})
else
TriggerClientEvent('notification', source, "Kick failed: " .. status)
end
Advanced Examples
Kick with Warning Integration
Copy
local function kickWithWarning(staffId, targetId, reason, issueWarning)
-- Optional: Issue warning before kick
if issueWarning then
local warnSuccess = exports['zyrix_admin']:WarnPlayer(staffId, targetId, "Kicked: " .. reason)
if warnSuccess then
print(string.format("Warning issued to %s before kick", GetPlayerName(targetId)))
end
end
-- Proceed with kick
local success, status = exports['zyrix_admin']:KickPlayer(staffId, targetId, reason)
if success then
-- Notify remaining players
TriggerClientEvent('chat:addMessage', -1, {
color = {255, 140, 0},
multiline = false,
args = {"[Admin]", string.format("Player kicked for: %s", reason)}
})
-- Log detailed information
print(string.format("[KICK] Staff: %s | Target: %s | Reason: %s | Warning: %s",
GetPlayerName(staffId), GetPlayerName(targetId), reason, issueWarning and "Yes" or "No"))
end
return success, status
end
-- Command with warning option
RegisterCommand('kickwarn', function(source, args)
if #args < 2 then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Usage]", "/kickwarn <player_id> <reason>"}
})
return
end
local targetId = tonumber(args[1])
local reason = table.concat(args, " ", 2)
if not targetId or not GetPlayerName(targetId) then
TriggerClientEvent('notification', source, "Player not found")
return
end
kickWithWarning(source, targetId, reason, true)
end, true)
Scheduled Kick System
Copy
local scheduledKicks = {}
local function scheduleKick(staffId, targetId, reason, delaySeconds, notifyPlayer)
-- Check if player already has scheduled kick
if scheduledKicks[targetId] then
return false, "Player already has a scheduled kick"
end
-- Notify target player if requested
if notifyPlayer then
TriggerClientEvent('chat:addMessage', targetId, {
color = {255, 0, 0},
multiline = false,
args = {"[Warning]", string.format("You will be kicked in %d seconds: %s", delaySeconds, reason)}
})
end
-- Store kick info
scheduledKicks[targetId] = {
staffId = staffId,
reason = reason,
scheduleTime = os.time(),
delaySeconds = delaySeconds
}
-- Schedule the kick
SetTimeout(delaySeconds * 1000, function()
-- Check if player is still online and kick is still scheduled
if GetPlayerName(targetId) and scheduledKicks[targetId] then
local success, status = exports['zyrix_admin']:KickPlayer(staffId, targetId, reason)
if success then
print(string.format("[SCHEDULED KICK] %s kicked %s after %d second delay",
GetPlayerName(staffId), GetPlayerName(targetId), delaySeconds))
end
scheduledKicks[targetId] = nil
end
end)
-- Notify staff member
TriggerClientEvent('notification', staffId,
string.format("Kick scheduled for %s in %d seconds", GetPlayerName(targetId), delaySeconds)
)
return true, "success"
end
local function cancelScheduledKick(staffId, targetId)
if not scheduledKicks[targetId] then
return false, "No scheduled kick found for player"
end
scheduledKicks[targetId] = nil
TriggerClientEvent('notification', staffId,
string.format("Cancelled scheduled kick for %s", GetPlayerName(targetId))
)
TriggerClientEvent('notification', targetId, "Your scheduled kick has been cancelled")
return true, "success"
end
-- Commands for scheduled kicks
RegisterCommand('skick', function(source, args)
if #args < 3 then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Usage]", "/skick <player_id> <seconds> <reason>"}
})
return
end
local targetId = tonumber(args[1])
local delay = tonumber(args[2])
local reason = table.concat(args, " ", 3)
if not targetId or not GetPlayerName(targetId) then
TriggerClientEvent('notification', source, "Player not found")
return
end
if not delay or delay <= 0 or delay > 300 then
TriggerClientEvent('notification', source, "Delay must be between 1-300 seconds")
return
end
scheduleKick(source, targetId, reason, delay, true)
end, true)
RegisterCommand('cancelkick', function(source, args)
if #args < 1 then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Usage]", "/cancelkick <player_id>"}
})
return
end
local targetId = tonumber(args[1])
if not targetId then
TriggerClientEvent('notification', source, "Invalid player ID")
return
end
cancelScheduledKick(source, targetId)
end, true)
-- Clean up on player disconnect
AddEventHandler('playerDropped', function()
local playerId = source
if scheduledKicks[playerId] then
scheduledKicks[playerId] = nil
end
end)
Mass Kick System
Copy
local function massKick(staffId, criteria, reason, excludeStaff)
local playersToKick = {}
local players = GetPlayers()
-- Determine which players to kick based on criteria
for _, playerId in ipairs(players) do
local shouldKick = false
-- Skip the staff member performing the action
if playerId == staffId then
goto continue
end
-- Skip staff if requested
if excludeStaff and exports['zyrix_admin']:IsStaffMember(playerId) then
goto continue
end
-- Apply criteria
if criteria.type == "all" then
shouldKick = true
elseif criteria.type == "ping" and criteria.threshold then
local playerPing = GetPlayerPing(playerId)
shouldKick = playerPing > criteria.threshold
elseif criteria.type == "playtime" and criteria.maxMinutes then
-- Assuming you have a playtime tracking system
local playtime = GetPlayerPlaytime(playerId) or 0
shouldKick = playtime < (criteria.maxMinutes * 60)
elseif criteria.type == "warnings" and criteria.minWarnings then
local warnSuccess, _, warnings = exports['zyrix_admin']:FetchWarnings(playerId)
if warnSuccess and warnings then
shouldKick = #warnings >= criteria.minWarnings
end
end
if shouldKick then
table.insert(playersToKick, playerId)
end
::continue::
end
-- Execute kicks
local kickedCount = 0
for _, playerId in ipairs(playersToKick) do
local success = exports['zyrix_admin']:KickPlayer(staffId, playerId, reason)
if success then
kickedCount = kickedCount + 1
end
end
-- Notify staff and server
TriggerClientEvent('notification', staffId,
string.format("Mass kick completed: %d players kicked", kickedCount)
)
if kickedCount > 0 then
TriggerClientEvent('chat:addMessage', -1, {
color = {255, 0, 0},
multiline = false,
args = {"[Server]", string.format("Mass kick executed: %s", reason)}
})
end
return kickedCount
end
-- Commands for mass kicks
RegisterCommand('masskick', function(source, args)
if #args < 1 then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Usage]", "/masskick <reason>"}
})
return
end
local reason = table.concat(args, " ")
local kickedCount = massKick(source, {type = "all"}, reason, true)
print(string.format("[MASS KICK] %s kicked %d players: %s",
GetPlayerName(source), kickedCount, reason))
end, true)
RegisterCommand('kickhighping', function(source, args)
local threshold = tonumber(args[1]) or 200
local reason = #args > 1 and table.concat(args, " ", 2) or "High ping"
local kickedCount = massKick(source, {type = "ping", threshold = threshold}, reason, true)
TriggerClientEvent('notification', source,
string.format("Kicked %d players with ping > %dms", kickedCount, threshold)
)
end, true)
Kick Prevention System
Copy
local kickProtection = {
immunePlayers = {}, -- Player IDs with temporary immunity
vipProtection = true, -- Protect VIP players
newPlayerProtection = 30, -- Minutes of protection for new players
}
-- Check if player should be protected from kicks
local function isPlayerProtected(playerId, staffId)
-- Check immunity list
if kickProtection.immunePlayers[playerId] then
local immunity = kickProtection.immunePlayers[playerId]
if os.time() < immunity.expireTime then
return true, string.format("Player has immunity until %s",
os.date("%H:%M:%S", immunity.expireTime))
else
kickProtection.immunePlayers[playerId] = nil
end
end
-- Check VIP protection
if kickProtection.vipProtection and IsPlayerVIP(playerId) then
-- Only higher staff can kick VIP players
local staffRank = GetStaffRank(staffId)
if staffRank < 3 then -- Assuming rank 3+ can kick VIPs
return true, "VIP players can only be kicked by senior staff"
end
end
-- Check new player protection
if kickProtection.newPlayerProtection > 0 then
local joinTime = GetPlayerJoinTime(playerId)
if joinTime and (os.time() - joinTime) < (kickProtection.newPlayerProtection * 60) then
return true, string.format("New player protection active for %d more minutes",
math.ceil((kickProtection.newPlayerProtection * 60 - (os.time() - joinTime)) / 60))
end
end
return false, nil
end
-- Enhanced kick function with protection
local function protectedKick(staffId, targetId, reason)
local isProtected, protectionReason = isPlayerProtected(targetId, staffId)
if isProtected then
TriggerClientEvent('notification', staffId, "Cannot kick player: " .. protectionReason)
return false, "player_protected"
end
return exports['zyrix_admin']:KickPlayer(staffId, targetId, reason)
end
-- Grant temporary immunity
local function grantKickImmunity(staffId, targetId, minutes, reason)
kickProtection.immunePlayers[targetId] = {
grantedBy = staffId,
reason = reason,
expireTime = os.time() + (minutes * 60)
}
TriggerClientEvent('notification', targetId,
string.format("You have been granted %d minutes of kick immunity", minutes)
)
TriggerClientEvent('notification', staffId,
string.format("Granted %d minutes kick immunity to %s", minutes, GetPlayerName(targetId))
)
end
-- Commands for protection system
RegisterCommand('immunity', function(source, args)
if #args < 2 then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Usage]", "/immunity <player_id> <minutes> [reason]"}
})
return
end
local targetId = tonumber(args[1])
local minutes = tonumber(args[2])
local reason = #args > 2 and table.concat(args, " ", 3) or "Administrative protection"
if not targetId or not GetPlayerName(targetId) then
TriggerClientEvent('notification', source, "Player not found")
return
end
if not minutes or minutes <= 0 or minutes > 120 then
TriggerClientEvent('notification', source, "Minutes must be between 1-120")
return
end
grantKickImmunity(source, targetId, minutes, reason)
end, true)
Kick Analytics and Reporting
Copy
local kickAnalytics = {
dailyKicks = {},
staffActivity = {},
reasonFrequency = {}
}
-- Record kick for analytics
local function recordKick(staffId, targetId, reason)
local today = os.date("%Y-%m-%d")
local hour = tonumber(os.date("%H"))
-- Daily kick tracking
if not kickAnalytics.dailyKicks[today] then
kickAnalytics.dailyKicks[today] = {}
end
if not kickAnalytics.dailyKicks[today][hour] then
kickAnalytics.dailyKicks[today][hour] = 0
end
kickAnalytics.dailyKicks[today][hour] = kickAnalytics.dailyKicks[today][hour] + 1
-- Staff activity tracking
local staffName = GetPlayerName(staffId)
if not kickAnalytics.staffActivity[staffName] then
kickAnalytics.staffActivity[staffName] = 0
end
kickAnalytics.staffActivity[staffName] = kickAnalytics.staffActivity[staffName] + 1
-- Reason frequency tracking
local lowerReason = reason:lower()
if not kickAnalytics.reasonFrequency[lowerReason] then
kickAnalytics.reasonFrequency[lowerReason] = 0
end
kickAnalytics.reasonFrequency[lowerReason] = kickAnalytics.reasonFrequency[lowerReason] + 1
end
-- Hook into kick function
local originalKick = exports['zyrix_admin'].KickPlayer
local function analyticsKick(staffId, targetId, reason)
local success, status = originalKick(staffId, targetId, reason)
if success then
recordKick(staffId, targetId, reason)
end
return success, status
end
-- Replace the export with analytics version
exports('KickPlayer', analyticsKick)
-- Generate kick report
RegisterCommand('kickreport', function(source, args)
local today = os.date("%Y-%m-%d")
local todayKicks = kickAnalytics.dailyKicks[today]
if todayKicks then
local totalToday = 0
for hour, count in pairs(todayKicks) do
totalToday = totalToday + count
end
TriggerClientEvent('chat:addMessage', source, {
args = {"[Kick Report]", string.format("Today: %d kicks", totalToday)}
})
-- Show most active staff
local topStaff = {}
for staff, count in pairs(kickAnalytics.staffActivity) do
table.insert(topStaff, {name = staff, count = count})
end
table.sort(topStaff, function(a, b) return a.count > b.count end)
if topStaff[1] then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Most Active]", string.format("%s: %d kicks", topStaff[1].name, topStaff[1].count)}
})
end
-- Show most common reasons
local topReasons = {}
for reason, count in pairs(kickAnalytics.reasonFrequency) do
table.insert(topReasons, {reason = reason, count = count})
end
table.sort(topReasons, function(a, b) return a.count > b.count end)
if topReasons[1] then
TriggerClientEvent('chat:addMessage', source, {
args = {"[Top Reason]", string.format("%s: %d times", topReasons[1].reason, topReasons[1].count)}
})
end
else
TriggerClientEvent('notification', source, "No kicks recorded today")
end
end, true)
Error Handling
Handle common scenarios when kicking players:Copy
local function safeKickPlayer(staffId, targetId, reason)
-- Validate reason
if not reason or string.len(reason) < 3 then
return false, "Kick reason must be at least 3 characters"
end
if string.len(reason) > 200 then
return false, "Kick reason too long (max 200 characters)"
end
-- Check if player exists
if not GetPlayerName(targetId) then
return false, "Target player not found"
end
-- Prevent self-kick
if staffId == targetId then
return false, "Cannot kick yourself"
end
-- Check for protection
local isProtected, protectionReason = isPlayerProtected(targetId, staffId)
if isProtected then
return false, protectionReason
end
-- Attempt kick
local success, status = exports['zyrix_admin']:KickPlayer(staffId, targetId, reason)
if not success then
local errorMessages = {
no_permission = "You don't have permission to kick players",
player_not_found = "Target player not found",
invalid_target = "Invalid player ID",
invalid_reason = "Invalid kick reason"
}
local message = errorMessages[status] or ("Kick failed: " .. status)
TriggerClientEvent('notification', staffId, message)
else
-- Log successful kick
print(string.format("[KICK] %s kicked %s: %s",
GetPlayerName(staffId), GetPlayerName(targetId), reason))
end
return success, status
end
Kicks immediately remove players from the server. Always ensure you have proper justification and consider using warnings for minor infractions.
Implement kick protection systems for VIP players or new players to prevent accidental removals and improve server experience.