Help with anti cheat: doesn't detect my walkspeed that changes

I’m making a anticheat for a game I’m a developer on and whenever I change my walkspeed it’s just won’t send the webhook or kick me (the webhook works I tested it)

local DSS = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")

function sendWebhook(action,reason,plr)
	local data = {
		["embeds"] = {{
			["title"] = "Potential Exploiter Found",
			["color"] = "16726022",
			["description"] = "```Exploiter Found```\nA exploiter has been found: our moderation team will review this log and determine if this is a true/false positive.\n\n**Username:** "..plr.Name.."\n**User ID:** "..plr.UserId.."\n**Reason:** "..reason.."\n**Action:** "..action,
			["thumbnail"] = {url="http://www.roblox.com/Thumbs/Avatar.ashx?x=100&y=100&Format=Png&userId="..plr.UserId},


		}
		}}

	local finaldata = HttpService:JSONEncode(data)
	HttpService:PostAsync("no webhook for u", finaldata)
end

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		-- Character Related Exploits
		local hum = char:FindFirstChildOfClass("Humanoid")
		local CheckClientWalkspeed = game:GetService("ReplicatedStorage"):FindFirstChild("Remotes2").CheckClientWalkspeed:FireClient(hum,"WalkSpeed")
		-- WS Exploit
		while wait(0.1) do
		if CheckClientWalkspeed ~= 16 then
			if CheckClientWalkspeed == 14 or CheckClientWalkspeed == 18 then return end
			plr:Kick("AntiExploit | Speed Hacks (Increased/Decreased WalkSpeed)")
				sendWebhook("[KICK+LOG]","Speed Hacks", plr)
			end	
		end
	end)
end)

i assume this code is on the server…
if you change the walkspeed with client mode or with actual cheats the server doesnt know… only the client knows

( so the best thing to do is get the position of the character every time you can and make sure it isnt too fast )

1 Like

I’m using a event if you read the code to get the player’s walkspeed via the client, the client’s code is this:

game.ReplicatedStorage.Remotes2.CheckClientWalkspeed.OnClientEvent:Connect(function(hum,propertytocheck)
	return hum[propertytocheck]
end)

okay thats good, but you know players with cheats can just delete the script

1 Like

No, it’s parented to nil at the start of it and another local script hidden very well is checking every 0.1 seconds if it’s disabled or destroyed

nil is basically deleted it doesnt run code. also whats checking the checker

1 Like

if you parent it to nil it’s still here, just not under “game” so its harder to find

You only call the RemoteFunction once, meaning you only get the value once so even if they changed your code will still show as the old value

this is untrue, code that is simply parented to nil but not destroyed still runs.

1 Like

the issue here is you’re not invoking the client

fixed server code (I cut out the webhook because I don’t have the full code, add it back)

local CheckClientWalkspeed = game:GetService("ReplicatedStorage").CheckClientWalkspeed

local function GetWalkSpeed(plr, hum)
	return CheckClientWalkspeed:InvokeClient(plr, hum, "WalkSpeed")
end


game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		-- Character Related Exploits
		local hum = char:WaitForChild("Humanoid", 9e9)
		
		-- WS Exploit
		while wait(0.1) do
			local CheckClientWalkspeed = GetWalkSpeed(plr, hum)
			
			print(CheckClientWalkspeed)
			if CheckClientWalkspeed ~= 16 then
				if CheckClientWalkspeed == 14 or CheckClientWalkspeed == 18 then return end
				plr:Kick("AntiExploit | Speed Hacks (Increased/Decreased WalkSpeed)")
			end	
		end
	end)
end)

fixed client code

game:GetService("ReplicatedStorage"):WaitForChild("CheckClientWalkspeed").OnClientInvoke = function(Hum, Property)
	return Hum[Property]
end

You have to replace the remoteevent with a remotefunction as well

This method for detecting walkspeed is also extremely flawed, you should use a magnitude check on the server so you aren’t relying on the client to not lie.

2 Likes