How to check humanoid walkspeed changes from Server?

I’m creating a walkspeed checker (in case someone decides to change their walkspeed locally). Is there a way to do so with the “:GetPropertyChangedSignal” event on their humanoids?

Here is what I’m trying:

local players = game:GetService("Players")

-- Anti-Speed Walk Hack
local function antiWalkSpeedExploitCheck()
	print("TEST")
end

players.Character.Humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(antiWalkSpeedExploitCheck)

It says that Character is not a valid member of Players.

2 Likes

You can’t detect changes made on the client from the server, my advice is to make this script you made a local script inside of StarterPlayerScripts, if the script detects a walkspeed change, fire a remote event to the server to kick the player, or stay on the client and change the walkspeed back to 16. Unfortunately, the exploiter can find the script and delete it so it can’t change their walkspeed back, however, you can make ANOTHER script to detect if that script was deleted.

1 Like

It really depends if you want it to be on the local script or server script.

As @beatpeat mentioned above, local scripts can be modified. If you put a server script, you can put this in:

local function check()
    -- Hacks Detected
end

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
    plr.CharacterAdded:Connect(function(chr)
        chr.Humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(check)
    end)
end)
1 Like

Like I said before, you can’t check if the walkspeed on the server if its been changed on the client, on the server it will still show 16, on the client it shows something different.

1 Like

Is there a way to pass the player’s username with this?

Kicking and changes like this can be done from the client.


You can ban them if the script is deleted. It should be in ReplicatedFirst.

For anti-exploits walk-speed changes won’t be detected on the server since most exploits run on the client. The best way you could achieve an anti-exploit for speed changes is by checking the position of every player’s HumanoidRootPart and compare it with it’s previous position every few seconds, if the changes are incredibly significant you could try teleporting the player back to it’s old position. If anyone does have a more efficient way to solve this do feel free to fix me.

(Also it’s not recommended to use local scripts for anti-exploits either since exploiters can easily delete the script, and since it won’t be deleted on the server you can’t check whether your local script anti-cheat gets deleted on a different server script. Terribly sorry for being 13 hours late to reply this post.)

he can make a server script which clone the local script to the client every second, if he deletes the anti exploit, the new one will come.

i did that one time, thats not so hard.

But the client can listen for the ChildAdded event/signal and destroy the ‘Child’ instance.

yes i know that, i already tried that, and that event is not that fast, and he can do something where when he put the local script in the client, he sends a fire to a remote event, and if that remote event fire doesnt come, this means the script is deleted.

It fires as soon as the child replicates to the client (meaning that it can be destroyed immediately). That ‘RemoteEvent’ object can be fired externally too.

It’s a huge waste of memory to constantly create a new local script, you can also just manipulate the anti-exploit on the local script instead of deleting it. You need to remember that exploiters can easily manipulate local scripts, and can do whatever they want with it just detecting the deletion of the local script won’t be enough you’d have to listen for script changes

This can be done by detecting how fast your position changes. Heres how I did it in the past!

local died = false

local maxSpeed = 30

game.Players.PlayerAdded:Connect(function(plr)
	coroutine.wrap(function()
		local ps = false
		local pastPos = Vector3.new(0, 0, 0) -- Old position
		workspace:WaitForChild(plr.Name).Humanoid.Died:Connect(function()
			died = true
			plr.CharacterAdded:Connect(function()
				pastPos = plr.Character:WaitForChild("HumanoidRootPart").Position
				died = false
			end)
		end)
		while true do
			task.wait(1)
				print("NOT TELEPORTING!")
				local pos = plr.Character.HumanoidRootPart.Position -- Grabs current position
				if ps == false then
					ps = true
				else
					local data = "*"..plr.Name.."* was **kicked** by Anti-Cheat for exceeding the Walk Speed limit. Severity: Medium."
					if pos.X < 0 then
						if pos.X - pastPos.X > maxSpeed or pastPos.X - pos.X > maxSpeed then
							plr:Kick("Exploiting.")
						else
						if pos.Z - pastPos.Z > config.maxSpeed or pastPos.Z - pos.Z > maxSpeed then
								plr:Kick("Exploiting.")
							end
						end
					else
					if pos.X - pastPos.X > -maxSpeed or pastPos.X - pos.X > -maxSpeed then
							plr:Kick("Exploiting.")
						else
						if pos.Z - pastPos.Z > -maxSpeed or pastPos.Z - pos.Z > -maxSpeed then
								plr:Kick("Exploiting.")
							end
						end
				end
				pastPos = pos
			end
		end
	end)()
end)

Ignore the “data” variable, just delete it. I used to log when someone is super speedy on discord.

EDIT: I JUST REALIZED THIS IS 2 YEARS OLD