Ways to teleport players with an anticheat checking their current and previous location magnitude

The anti-cheat I have made uses the basic system of check player’s current and last location every 1 second to see if they have moved extremely fast with loads of different checks in there to make sure they are on the ground, etc., etc. But as I further develop this game, I have realized that I will be teleporting players around. This will cause the anti-cheat to pick up an insane distance traveled depending on where the player teleports from. I do have an “Anti-cheat” setting on players that can disable/enable the player’s anti-cheat. Still, because the loop runs every second, the loop can run past this if statement and still pick the player up as cheating. Any ideas on how I can implement a way for players to teleport WITH an anti-speed hack check?

I thought of either reducing the time between checks to 0.01 and just updating my variables with the fast checks. Still, if it is timed just right the anticheat could pick the player up for cheating, it’s just a smaller chance than with 1-second checks.

Or I can maybe add a strike system? If the player is struck 3 times, teleport them back and reset their strikes? I could then reset the player’s strikes every 30 seconds or so, but if a player teleports 3 times within 30 seconds, they could still be teleported back.

Or just disable the anti-cheat and let speed hackers run free kekw.

Any other ideas? I really appreciate any help you can provide.

2 Likes

I would probably disable this “anti cheat” script since there’s really no point until you really see some one exploiting, plus its unreliable. You may be flinged into the air then it would ban you or if your far away and reset. But again this is just my opinion and a way you can go around it.

1 Like

Well, I made it so it just teleports players back you don’t get punished with a ban or kick or any of that. But there is no PVP in the game so exploiters would kinda just be able to run around the map faster and help themselves which still leaves an “unfairness” in my opinion as they can reach points quicker than the average player. But I don’t want to create an anti-cheat that noticeably affects non-exploiting players.

1 Like

You can check if (current time - last server teleport time) < 1 when the anticheat triggers to see if the player was teleported by the server in the past second

Something like this:

local Players = game:GetService'Players'

local LastTeleport = {}
Players.PlayerAdded:Connect(function(Player)
	LastTeleport[Player.UserId] = 0
	Player.CharacterAdded:Connect(function(Character)
		Character:WaitForChild'Humanoid'.WalkSpeed = 100
		local RootPart = Character:WaitForChild'HumanoidRootPart'
		local LastPosition = RootPart.CFrame.p
		
		while Player and Player.Character and Player.Character == Character do
			if (RootPart.CFrame.p - LastPosition).Magnitude > 30 then
				if tick() - LastTeleport[Player.UserId] < 1 then
					print'player recently teleported by server'
				else
					print'player teleporting'
					-- teleport back
				end
			end
			wait(1)
		end
	end)
	
	Player.Chatted:Connect(function(Message)
		if Message == "tp" then
			LastTeleport[Player.UserId] = tick()
			local RootPart = Player.Character.HumanoidRootPart
			RootPart.CFrame = RootPart.CFrame + Vector3.new(0, 200, 0)
		end
	end)
end)

You can also use Stepped and just disconnect and reconnect the event when a player teleports

local RunService = game:GetService'RunService'
local Players = game:GetService'Players'

local Connections = {}
local function Check(Player, Part)
	local Connection = Connections[Player.UserId]
	if Connection then
		Connection:Disconnect()
		print'reconnecting'
	end
	
	local LastPosition = Part.CFrame.p
	local LastCheck = 0
	Connections[Player.UserId] = RunService.Stepped:Connect(function()
		if tick() - LastCheck > 1 then
			LastCheck = tick()
			if (Part.CFrame.p - LastPosition).Magnitude > 30 then
				print'player teleporting'
				-- teleport back
			end
			LastPosition = Part.CFrame.p
		end
	end)
end

Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local RootPart = Character:WaitForChild'HumanoidRootPart'
		
		Check(Player, RootPart)
		
		Character:WaitForChild'Humanoid'.WalkSpeed = 100
	end)

	Player.Chatted:Connect(function(Message)
		if Message == "tp" then
			local Character = Player.Character
			if Character then
				local RootPart = Character:FindFirstChild'HumanoidRootPart'
				RootPart.CFrame = RootPart.CFrame + Vector3.new(0, 200, 0)
				Check(Player, RootPart)
			end
		end
	end)
end)
3 Likes

Currently out right now, this looks very promising though you got me very excited to go home now!

Adding on to that you can automatically detect if a player is teleporting by the server by using

HumanoidRootPart:GetPropertyChangedSignal("CFrame")

Because when GetPropertyChangedSignal is used on Position or CFrame it is only fired when the property is changed by a script.

Then you can disable the anti-exploit when the signal is fired.

Here’s my anti-exploit. if you want to see how I implemented it.

What I did was I used a table to hold the players last position and if the magnitude of the players position was to big when I teleported them back, now of course this would cause issues if you’re trying to teleport the player from within the game, so i made my own function within this to teleport the player myself and before teleporting the player i set the players last position in the table to thr position they’re getting teleported too, if you don’t understand what I’m saying let me know :sob: