Kicked on teleport part (Anticheat script)

My problem here is that I touch a part, I teleport to another part. In the end I get kicked tho even tho it should only kick me if it detects some malicious stuff like game.Workspace.username.HumanoidRootPart.Position = Vector3.new(0, 100, 0)

But right now its oversensitive. I have tried literally EVERYTHING to get this sorted.

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local TELEPORT_THRESHOLD = 250
local GRACE_DURATION = 3
local POSITION_UPDATE_INTERVAL = 0.1
local KICK_COOLDOWN = 2

local teleportPart = Workspace:WaitForChild("TeleportPart")
local disableACPart = Workspace:WaitForChild("DisableAC")

local function createPlayerAnticheat(player)
	local connections = {}
	local playerData = {
		lastPosition = nil,
		lastPositionUpdate = 0,
		disableACTimeout = 0,
		teleportGraceTimeout = 0,
		touchingSpecialParts = {},
		lastKickTime = 0
	}

	local function updateLastPosition(hrp)
		playerData.lastPosition = hrp.Position
		playerData.lastPositionUpdate = tick()
	end

	local function isInGracePeriod()
		local now = tick()
		return now < playerData.disableACTimeout or now < playerData.teleportGraceTimeout
	end

	local function onSpecialPartTouched(part, hrp)
		if playerData.touchingSpecialParts[part] then return end
		playerData.touchingSpecialParts[part] = true

		if part == teleportPart then
			playerData.teleportGraceTimeout = tick() + GRACE_DURATION
			task.defer(function()
				updateLastPosition(hrp)
			end)
			local humanoid = player.Character and player.Character:FindFirstChild("Humanoid")
			if humanoid then
				humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
			end
		elseif part == disableACPart then
			playerData.disableACTimeout = math.huge
			updateLastPosition(hrp)
		end
	end

	local function onSpecialPartLeft(part, hrp)
		if not playerData.touchingSpecialParts[part] then return end
		playerData.touchingSpecialParts[part] = nil

		if part == teleportPart then
			playerData.teleportGraceTimeout = tick() + GRACE_DURATION
			updateLastPosition(hrp)
		elseif part == disableACPart then
			playerData.disableACTimeout = tick() + GRACE_DURATION
			updateLastPosition(hrp)
		end
	end

	local function checkNoclip(hrp)
		if hrp.CanCollide == false then
			return true
		end
		return false
	end

	local function onCharacterAdded(character)
		for _, conn in ipairs(connections) do conn:Disconnect() end
		connections = {}

		playerData.lastPosition = nil
		playerData.lastPositionUpdate = 0
		playerData.disableACTimeout = 0
		playerData.teleportGraceTimeout = 0
		playerData.touchingSpecialParts = {}
		playerData.lastKickTime = 0

		local hrp = character:WaitForChild("HumanoidRootPart")
		local humanoid = character:WaitForChild("Humanoid")

		updateLastPosition(hrp)

		connections[#connections + 1] = hrp.Touched:Connect(function(hit)
			if hit == teleportPart or hit == disableACPart then
				onSpecialPartTouched(hit, hrp)
			end
		end)

		connections[#connections + 1] = RunService.Heartbeat:Connect(function()
			for part in pairs(playerData.touchingSpecialParts) do
				if not hrp:IsTouching(part) then
					onSpecialPartLeft(part, hrp)
				end
			end
		end)

		connections[#connections + 1] = RunService.Heartbeat:Connect(function()
			if not hrp or not hrp:IsDescendantOf(Workspace) then return end

			local now = tick()
			local pos = hrp.Position

			if isInGracePeriod() then
				if now - playerData.lastPositionUpdate >= POSITION_UPDATE_INTERVAL then
					updateLastPosition(hrp)
				end
				return
			end

			if checkNoclip(hrp) then
				if now - playerData.lastKickTime > KICK_COOLDOWN then
					playerData.lastKickTime = now
					player:Kick("Anticheat: Noclipping detected.")
				end
				return
			end

			if playerData.lastPosition then
				local state = humanoid:GetState()
				local safeStates = {
					[Enum.HumanoidStateType.Freefall] = true,
					[Enum.HumanoidStateType.FallingDown] = true,
					[Enum.HumanoidStateType.Jumping] = true,
					[Enum.HumanoidStateType.Ragdoll] = true,
					[Enum.HumanoidStateType.Climbing] = true,
					[Enum.HumanoidStateType.GettingUp] = true,
					[Enum.HumanoidStateType.Seated] = true,
					[Enum.HumanoidStateType.PlatformStanding] = true,
				}

				if not safeStates[state] then
					local delta = now - playerData.lastPositionUpdate
					local dist = (pos - playerData.lastPosition).Magnitude
					local speed = dist / math.max(delta, 0.001)

					if speed > TELEPORT_THRESHOLD then
						if now - playerData.lastKickTime > KICK_COOLDOWN then
							playerData.lastKickTime = now
							player:Kick("Anticheat: Teleportation detected.")
						end
						return
					end
				end
			end

			if now - playerData.lastPositionUpdate >= POSITION_UPDATE_INTERVAL then
				updateLastPosition(hrp)
			end
		end)
	end

	connections[#connections + 1] = player.CharacterAdded:Connect(onCharacterAdded)
	if player.Character then
		onCharacterAdded(player.Character)
	end

	return function()
		for _, conn in pairs(connections) do
			conn:Disconnect()
		end
	end
end

local playerCleanup = {}

Players.PlayerAdded:Connect(function(player)
	playerCleanup[player] = createPlayerAnticheat(player)
end)

Players.PlayerRemoving:Connect(function(player)
	if playerCleanup[player] then
		playerCleanup[player]()
		playerCleanup[player] = nil
	end
end)

for _, player in ipairs(Players:GetPlayers()) do
	if not playerCleanup[player] then
		playerCleanup[player] = createPlayerAnticheat(player)
	end
end

Can somebody advise me what to do or how to fix this? Any help of any form would be appreciated.

You can experience the bug here: game with bug

For anyone wondering, here is the teleporting script

local part = script.Parent

part.Touched:Connect(function(hit)
	local character = hit.Parent
	if character then
		local player = game.Players:GetPlayerFromCharacter(character)
		if player then
			local hrp = character:FindFirstChild("HumanoidRootPart")
			if hrp then
				print(player.Name, "touched the teleport part")
				hrp.Position = Vector3.new(-2.35, 54.900, 31.499)
			end
		end
	end
end)

Possibly try; Replace this…

if speed > TELEPORT_THRESHOLD then

With this…

if speed > TELEPORT_THRESHOLD and not isInGracePeriod() then

And maybe add a debounce to the touched:Connect

Adding a 0.5 second debounce time to the teleportation script seemed to work. Thank you I didn’t think of that first.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.