Clientsided anti-exploits can be bypassed, exploiters use metatables to make the client think that the WalkSpeed is set to 16 (default walkspeed) and sometimes bypass kicks if it was done on the client.
You can’t kick a player on the client due to FilteringEnabled. You have to fire a remote event to the server and then pick it up there and kick the user from there. Also, you should probably say :Kick() instead of :kick().
Like all the replies below, this would be useless against cheaters.
They can easily bypass this by deleting the script or something else.
Here’s an example, you can make a server script instead that checks the player’s HumanoidRootPart’s position every few seconds or frames.
If the position is too far from the previous position, then kick them.
This wouldn’t work. If the client changes their walkspeed it won’t replicate to the server. You’re also polling for no reason, there’s an event for this!
Doing this is effectively useless, all an exploiter has to do is type one command and the Local Script is deleted. You should aim to do this on the server, not the client. You can achieve this my doing magnitude checks. You can refer to these posts:
This is just as bad. The best solution for anti-walkspeed exploits is checking the player’s position on the server end, and comparing it to an older position.
Here’s a method I use in pretty much all of my games. Put this in a server script.
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
char:WaitForChild('Humanoid').Running:Connect(function(speed)
if speed > 20 then
player:Kick("Exploiting")
end
end)
end)
end)
Again, that’s false, the one thing that Roblox allows players to have complete control over is there “character” movement, which does replicate to the server.
no. the character is owned by the player so if the player has high ping it could cause their speed to change in slow but big intervals that normaly wouldnt be possible.
You’re using game.Player…
The service is called ‘Players’. You can access it via game:GetService(“Players”) or game.Players.
(Unrelated to the problem) While I do believe :kick() still works, :Kick() is kind of what Roblox intends to be used universally. It’s kind of like how you can use :connect, but :Connect is the standard.
So here’s a quick fix to get my point across a bit better.
--[[
if game.Player.LocalPlayer.Character.Humanoid.WalkSpeed ~= 16 then
game.Player.LocalPlayer:Kick()
end
]]--
local Player = game:GetService'Players'.LocalPlayer; -- Notice "Players", not "Player".
if (Player.Character.Humanoid.WalkSpeed ~= 16) then
Player:Kick() -- Uppercase Kick is the standard.
end
I hope you find my code useful, it isn’t very reliable for you to depend on the client to check the player’s walk speed. Instead; consider checking the magnitude at which the player is moving at (real-time walking speed).
-- Server scripts should be used more often as a method to patching exploits.
local Players = game:GetService("Players")
local FindFirstChildWhichIsA = game["FindFirstChildWhichIsA"]
local WaitForChild = game["WaitForChild"]
local OnCharacterAdded; OnCharacterAdded = function(Character)
local Humanoid =
FindFirstChildWhichIsA(Character, "Humanoid")
WaitForChild(Character, "Humanoid")
local RootPart = Humanoid.RootPart or WaitForChild(Character, "HumanoidRootPart")
local RBXScriptConnection; RBXScriptConnection = Humanoid.StateChanged:Connect(function(LastState, CurrentState)
if CurrentState == Enum.HumanoidStateType.Running then
local MovementSpeed = (RootPart.AssemblyLinearVelocity * Vector3.new(1, 0, 1)).Magnitude
if MovementSpeed >= 80 then
-- Potentially cheating?
-- This could be faulty, so I would recommend only checking for absurd numbers.
return RBXScriptConnection.Disconnect(RBXScriptConnection)
end
end
end)
end
local OnPlayerAdded; OnPlayerAdded = function(Player)
Player.CharacterAdded:Connect(OnCharacterAdded)
end
Edit: Humanoids do take a brief moment to accelerate, so it wouldn’t be a biggie to give a shot at lower numbers.