Setting values on the client wont kick the player

The only replicated property you can rely on is the Position value of their body parts.

1 Like

on all this mess can my method like this work:

fire a remote function to the client
and the client returns info to the server
check if the value is more then the client what had returned

is that a good method?

1 Like

This can be spoofed by the client as the exploiter can return whatever information they like and remove the original script or modify it.

Better off doing distance checks on the server using something like the method I provided.

1 Like

how would i check it on the other side like jump power? add another if statement?

1 Like

Iā€™m not sure how you would check if the player has changed the jump power but feel free to experiment with the code and make another thread asking for help on how to achieve that!

how would i calculate the jumpheight of the player jump power

Iā€™m not sure but feel free to look around the dev forum and the internet, Iā€™m sure someone has probably asked.

1 Like

@FerbZides
Iā€™d make it so that thereā€™s a ValueObject inside the humanoid that is created on the server whenever you change the WalkSpeed. Delete it after you check for it. This would prevent the client spoofing the WalkSpeed since instances created on the client doesnā€™t replicate.

@FracturedSoftware
FloorMaterial doesnā€™t return as nil when the player isnā€™t on the ground, it returns as Air.

if Player.Character:FindFirstChildOfClass("Humanoid").FloorMaterial ~= Enum.FloorMaterial.Air then

Also, donā€™t kick for something like this. Think about players with slow connections, just make them rubberband which seems to be the optimal solution. Most games do stuff like this to counteract teleportation with slow connections.

Player.Character:FindFirstChildWhichIsA("Humanoid").RootPart.CFrame = CFrame.new(LastData[Player.UserId].Position)

@FerbZides
Hereā€™s the optimal script:

local LastData = {}
while wait(1) do
    for _, Player in pairs(game:GetService("Players"):GetPlayers()) do
        if Player.Character then
            if Player.Character:FindFirstChildOfClass("Humanoid") and Player.Character:FindFirstChild("HumanoidRootPart") then
                if not LastData[Player.UserId] then
                    LastData[Player.UserId] = {
                        CFrame = Player.Character.HumanoidRootPart.CFrame,
                        Tick = tick(),
                    }
                end
                if (LastData[Player.UserId].Position - Player.Character.HumanoidRootPart.Position).Magnitude > Player.Character:FindFirstChildOfClass("Humanoid").WalkSpeed + 1 * (tick() - LastData[Player.UserId].Tick) then
                    Player.Character:FindFirstChildWhichIsA("Humanoid").RootPart.CFrame = LastData[Player.UserId].CFrame
                else
                    LastData[Player.UserId] = {
                        CFrame = Player.Character.HumanoidRootPart.CFrame,
                        Tick = tick(),
                    }
                end
            end
        end
    end
end

It prevents, JumpPower, Flying and WalkSpeed.

Any exploiter could easily delete the Anti-Exploit Script since it is on the Client.

@EpicVault

False, his anti-exploit is serversided, therefore there is no way for them to delete it. Even if they deleted the ModuleScript, it would still exist on the server because it wouldnā€™t replicate.

Anything in StarterCharacterScripts can be deleted by the client since theyā€™ll be descendants of the character which the player has full control of.

You wonā€™t really succeed attempting to kick the player from the client.
Kick them from the server as they can just cancel the kick packet being sent to them.

To reference the player, do:

local Players = game:GetService('Players')
local Player = Players.LocalPlayer

And now, for the actual part:

local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild('Humanoid')

Humanoid:GetPropertyChangedSignal('WalkSpeed'):Connect(function()
   if Humanoid.WalkSpeed > 16 then
   -- Fire a RemoteEvent that tells the server to kick the player.
   -- Please note that they can simply remove this localscript, so it's pretty useless in the end.
   end
end)

The reason why the server cannot detect this is because the WalkSpeed property does not replicate to the server, only the client can detect this change.

Anywho: Their position is automatically replicated to the server.

If you wanted a anti-teleport system, you can check how fast they are travelling every X seconds on the server.

As an alternative, on the server side you can detect when a player runs using the Humanoid.Running event (Humanoid | Documentation - Roblox Creator Hub). You can read off the speed and kick the player if it surpasses a certain value. This would remove the need to fire a remote event from the client which could be bypassed by exploiters or spoofed.

1 Like

never use an anti-exploit on client unless you obfuscate it (and even then some good exploiters can still delete that code). Exploiters can easily remove that portion of code. Instead you could use the server and use PropertySignalChanged to determine when their speed changes then set their walkspeed/kick them.

1 Like

You donā€™t need to obfuscate it, they can simply decompile it and beautify the code.
You only confuse yourself when doing so.

Also, server cannot detect when their walkspeed is changed since it doesnā€™t replicate, you should check their position instead as it is automatically replicated to the server.

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
    plr.CharacterAdded:Connect(function(char)
         local humanoid = char:WaitForChild("Humanoid")
         humanoid.Running:Connect(function(speed)
                   if speed > 16 then
                         plr:Kick()
                   end
         end
   end
end

Havenā€™t tested this, but it should work as long as there arenā€™t specific instances in your game where the speed of a player should surpass 16.

1 Like

anything related to the client wont actually replicate to the server so if the client tries to delete it or decompile it still wouldnt work bc its a server script not a local script

if list.walkspeed is some sort of value then you need to check List.Walkspeed.Value.

its inside a table its a variable not a base value

False. Read this.
https://devforum.roblox.com/t/post-undocumented-client-server-replication-behaviors-here/475432