The reason I made this Custom Kick System, was because I didn’t like the default Kick Design, so I decided to make a different one that works differently.
First, you need to import the module in the script:
local KickModule = require(script:WaitForChild("KickModule"))
Second, you need to use the “kick” function of the module:
local KickModule = require(script:WaitForChild("KickModule"))
local Players = game:GetService("Players")
local kickReason = "This is a test" -- This would be your kick reason, the "You were kicked for:" is in the reason by default
local HasKickSound = true -- This chooses whether you want a kick sound that plays on the player's client, change this to false if you don't want any sound
-- HasKickSound = true (This would play a sound on the player's client)
-- HasKickSound = false (This wouldn't play anything)
Players.PlayerAdded:Connect(function(Plr) -- Plr = Player To Kick
KickModule.kick(Plr,kickReason,HasKickSound)
end)
Full Code using chat commands:
local KickModule = require(script:WaitForChild("KickModule"))
local Players = game:GetService("Players")
local CommandPrefix = "-" -- The default prefix is -
local AdminPerms = false -- Is Free Admin Disabled (Free Admin is Enabled By Default, make it true to disable Free Admin)
local AdminsList = {game.CreatorId} -- Example {34235423,12311,675467} (UserId,UserId,UserId)
local function HandleCommands(msgImport)
local Args = msgImport:split(";")
if #Args >= 4 then
-- Command Example: -kick;plr;reason;HasKickSound
-- Actual Command Example: -kick;crownkingpown;This is a test, please don't worry about you being kicked for doing something bad;true
local plr = Args[2]:lower() -- Example: crownkingpown
local kickReason = Args[3] -- Example "This is a test, please don't worry about you being kicked for doing something bad"
local HasKickSound = Args[4] -- Example "true" (true would mean kick sound "On"), Example "false" (false would mean kick sound "Off")
local PlayerFound = nil
for Index,PlayersGet in pairs(Players:GetPlayers()) do
if PlayersGet.Name:lower() == plr then -- If Current Player Name In lowercase is equal to the plr variable
PlayerFound = PlayersGet
end
end
if PlayerFound ~= nil then
if HasKickSound == "true" then -- Converts String to Boolean
HasKickSound = true
else
HasKickSound = false
end
KickModule.kick(PlayerFound,kickReason,HasKickSound) -- Example: KickModule.kick(Players:FindFirstChild("CrownKingPown"), "This is a test", true)
end
end
end
Players.PlayerAdded:Connect(function(Plr) -- Plr = Player To Kick
Plr.Chatted:Connect(function(msg)
if msg:lower():find(CommandPrefix.."kick") then -- if the player used the kick command (-kick ...)
if AdminPerms == true then -- If Free Admin Is Disabled, it will check whether the player using the command is in the Admin List
if table.find(AdminsList,Plr.UserId) then
HandleCommands(msg) -- Makes the code more optimized
end
else -- If Free Admin Is Enabled, it won't check if player is in the Admins List
HandleCommands(msg) -- Makes the code more optimized
end
end
end)
end)
Just for the record, this shouldn’t be used for the purposes of removing exploiters from the game. The official kick system disconnects the user from the server so that it’s not possible for them to interact with it after being kicked (ie cause more harm), whereas this is just a UI which can be trivially removed.
It’s a nice concept, but in reality it wouldn’t play out well.
You should check the actual inside of the gui, I made it so that if the exploiter disables or does anything that stops the interactions between server and client of the localscript in the gui will result in him getting kicked using roblox’s kick system.
I also made it delete all objects from replicatedstorage, workspace… to prevent them from interacting with the game further.
That’s still easy to circumvent. My point was that you should always use Roblox’s kick system in the case of removing exploiters so that they can no longer cause harm to the server.
As you can see, if the gui is removed or the client script is disabled/removed, it will result in “nil” which will be detected as a bypass attempt.
The exploiter cannot fool the server script that uses InvokeClient to get the info.
And even if the exploiter were to remove the gui, it wouldn’t matter since the official kick gui by roblox can be deleted in under 2 seconds due to it having no checks at all.
The point of doing what? I’m not sure what you’re referring to.
The point of an exploiter doing it would be so that they can continue to play without being kicked. The point of this custom kick system is, well, I’m not sure.
Well, in the Module, there is a character loop check, if the exploiter somehow reset his character (Which is probably not possible without using LoadCharacter() which only works ServerSided, it will kick him due to the server finding his character inside the workspace.
If he is able to bypass the client script, he will prob be able to change his camera position, but that wouldn’t cause any harm.
Couldn’t I just move the UI into say, SSS or a different area where I don’t see the UI? Roblox’s kick system is much safer, and your kick system only makes the UI look better, not the functionality better.
I know that, I never said that people should use mine, I was just releasing it for those who wanted a better looking one, and also, even if you move the UI, it won’t change the fact that everything in the player’s client has been deleted completly.
Bug Fix: When someone other than yourself gets kicked from the game using the module, will no longer be in the playerlist, this was a bug before and has now been fixed.
I don’t exactly see a purpose of this? This system shouldn’t be used where you actually need a player to be kicked - due to the fact that any exploiter worth their salt will be able to get around this with no sweat.
The exploiter doesn’t need that specific local script to respond to your invokes. They can use any script they want to respond, and send whatever parameters they want in the return. An exploiter could just use their own scripts to simply reply to the checks. Even if they delete the blur effect or whatever, they can just say that they didn’t. This is such an unreliable method to kick people and I don’t think anyone here sees this as a reason to use it over the normal :Kick() functionality.
Highly would not recommend this. There are many problems with it, such as the weird way it is structured and the use of :InvokeClient() when it should be using a remote event, not a remote function, but the worst of it all is the unfixable security flaws.
Because of the use of :InvokeClient() (the usage of it that actually makes sense), this is super easy to break via an exploit. Some simple code as such would completely bypass all anti-exploit measures:
local Players = game:GetService("Players")
local PlayerGui = Players:WaitForChild("PlayerGui")
local Threads = {} --So the threads don't get garbage collected. Not sure if this matters.
PlayerGui.ChildAdded:Connect(function(child)
if child.Name == "KickClient" and child:IsA("LocalScript") then
child.Disabled = true
local checkClient = child:WaitForChild("CheckClient")
checkClient.OnClientInvoke = function()
table.insert(Threads, coroutine.running())
coroutine.yield()
end
elseif child.Name == "KickGui" and child:IsA("ScreenGui") then
child.Enabled = false
end
end)
This is why you should NEVER use :InvokeClient(). Even if the client’s response doesn’t matter that much, they could still make it yield forever, causing a potential memory leak.
Yes, this is fixable, but even if you do fix it, it will always be possible to bypass. Really the only way around this would be to check all events on the server to make sure that the player sending the request wasn’t kicked, but this is more trouble than it’s worth, as you would have to modify not only your own code but also would have to fork a bunch of other default roblox code that uses remote events/functions.
Even then, “kicked” players will still appear in the player list, settings menu, and take up server slots. It just isn’t worth it for a bit of a fancier ui.
I agree, I’m gonna make the server kick the player using roblox’s default kick after 10 seconds of being kicked from the custom kick to prevent bypassing.