Any thoughts on my rewritten Walkspeed detection? (Exploit Speed Detection)

A year ago a wrote this terrible exploit speed detection for the game I was making

So to celebrate the first anniversary of my post, I rewrote it into something more functionable, readable and mostly, the one that doesn’t break programming rules.

The only addition I made in this script is the Kicking, Setting the network owner to the server and Multiplayer support (the fact that the old version only works on single player is ridiculous) but everything else is the same function-wise.

Hopefully, I didn’t create the same mistake before or make any unspeakable errors lol

local PlayerService = game:GetService("Players")
local PlayerList = {}

local function AddPlayerToTable(Player)
	local Character = Player.CharacterAdded:Wait()
	local PlayerVariables = {
		["Character"] = Character,
		["PreviousPosition"] = Vector3.new(),
		["CurrentPosition"] = Vector3.new(),
		["ReturnCFrame"] = CFrame.new(),
		["NetworkOwner"] = "Client",
		["Tickets"] = 0,
		["Flags"] = 0
	}
	
	table.insert(PlayerList, PlayerVariables)
end

local function RemovePlayerFromTable(Player)
	for index, plrval in pairs(PlayerList) do
		if plrval.Character == Player.Character then
			table.remove(PlayerList, index)
		end
	end
end

local function NotTheseHumanoidStateTypes(Humanoid)
	if Humanoid:GetState() ~= Enum.HumanoidStateType.Seated
		or Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing 
		or Humanoid:GetState() ~= Enum.HumanoidStateType.Ragdoll 
		or Humanoid:GetState() ~= Enum.HumanoidStateType.FallingDown then
		return true
		
	else
		return false
	end
end

PlayerService.PlayerAdded:Connect(AddPlayerToTable)
PlayerService.PlayerRemoving:Connect(RemovePlayerFromTable)

while task.wait(1) do
	for index, plrval in pairs(PlayerList) do
		local HumanoidRootPart = plrval.Character.HumanoidRootPart
		local Humanoid = plrval.Character.Humanoid
		PlayerList[index]["CurrentPosition"] = HumanoidRootPart.Position
		
		if plrval.Flags < 5 then
			if NotTheseHumanoidStateTypes(Humanoid) then
				if plrval.NetworkOwner == "Server" then
					PlayerList[index]["NetworkOwner"] = "Client"
					plrval.Character.PrimaryPart:SetNetworkOwner(PlayerService:GetPlayerFromCharacter(plrval.Character))
				end

				if plrval.Tickets == 0 then
					PlayerList[index]["ReturnCFrame"] = HumanoidRootPart.CFrame

				elseif plrval.Tickets >= 3 then
					print("Too many Tickets, Return normal")
					PlayerList[index]["Tickets"] = 0
					PlayerList[index]["Flags"] += 1
					PlayerList[index]["NetworkOwner"] = "Server"

					plrval.Character.PrimaryPart:SetNetworkOwner(nil)
					HumanoidRootPart.CFrame = plrval.ReturnCFrame
				end

				if (plrval.PreviousPosition - PlayerList[index]["CurrentPosition"]).Magnitude > 20 and plrval.NetworkOwner == "Client" then
					print(plrval.Character, "is Overspeeding")
					PlayerList[index]["Tickets"] += 1

				else
					if plrval.Tickets > 0  then
						PlayerList[index]["Tickets"] -= 0.25
					end
				end

				PlayerList[index]["PreviousPosition"] = plrval.CurrentPosition
			end
			
		else
			PlayerService:GetPlayerFromCharacter(plrval.Character):Kick("SpeedHacking")
			table.remove(PlayerList, index)
		end
		
	end
end

Bonus Question: How would I implement this script that includes the platform movement under the character?

I was thinking about detecting the velocity of the part or adding a value on the player that’s standing on it to blacklist it.
If you could think of more ways I can implement this, feel free to reply

And yes feel free to use this anywhere with no limitations

4 Likes

This is interesting, so this is server-sided and detects walkspeed changes? Very impressive, good job.

1 Like

Yep, this is all server-sided. thanks

1 Like

Nice. Is this all open-sourced? I would consider using it if I could.

Yes its open source. feel free to use it

1 Like

oops I just noticed a flaw in this

local PlayerService = game:GetService("Players")
local PlayerList = {}

local function AddPlayerToTable(Player)
	local Character = Player.CharacterAdded:Wait()
	local PlayerVariables = {
		["Character"] = Character,
		["PreviousPosition"] = Vector3.new(),
		["CurrentPosition"] = Vector3.new(),
		["ReturnCFrame"] = CFrame.new(),
		["NetworkOwner"] = "Client",
		["Tickets"] = 0,
		["Flags"] = 0
	}
	
	table.insert(PlayerList, PlayerVariables)
end

local function RemovePlayerFromTable(Player)
	for index, plrval in pairs(PlayerList) do
		if plrval.Character == Player.Character then
			table.remove(PlayerList, index)
		end
	end
end

PlayerService.PlayerAdded:Connect(AddPlayerToTable)
PlayerService.PlayerRemoving:Connect(RemovePlayerFromTable)

while task.wait(1) do
	for index, plrval in pairs(PlayerList) do
		local HumanoidRootPart = plrval.Character.HumanoidRootPart
		local Humanoid = plrval.Character.Humanoid
		PlayerList[index]["CurrentPosition"] = HumanoidRootPart.Position
		
		if plrval.Flags < 5 then
			if plrval.NetworkOwner == "Server" then
				PlayerList[index]["NetworkOwner"] = "Client"
				plrval.Character.PrimaryPart:SetNetworkOwner(PlayerService:GetPlayerFromCharacter(plrval.Character))
			end

			if plrval.Tickets == 0 then
				PlayerList[index]["ReturnCFrame"] = HumanoidRootPart.CFrame

			elseif plrval.Tickets >= 3 then
				print("Too many Tickets, Return normal")
				PlayerList[index]["Tickets"] = 0
				PlayerList[index]["Flags"] += 1
				PlayerList[index]["NetworkOwner"] = "Server"

				plrval.Character.PrimaryPart:SetNetworkOwner(nil)
				HumanoidRootPart.CFrame = plrval.ReturnCFrame
			end

			if (plrval.PreviousPosition - PlayerList[index["CurrentPosition"]).Magnitude > 20 and plrval.NetworkOwner == "Client" then
				print(plrval.Character, "is Overspeeding")
				PlayerList[index]["Tickets"] += 1

			else
				if plrval.Tickets > 0  then
					PlayerList[index]["Tickets"] -= 0.25
				end
			end

			PlayerList[index]["PreviousPosition"] = plrval.CurrentPosition
			
		else
			PlayerService:GetPlayerFromCharacter(plrval.Character):Kick("SpeedHacking")
			table.remove(PlayerList, index)
		end
		
	end
end

I noticed the exploiter can just change the humanoid state type on the client since the server blindly trusts it. So, here’s the new version without it

I guess i’m gonna have to come up a way to detect player seating and other state types. lol

Just curious, what are tickets for?