Infinite jump detection

Hi!

I think @EmeraldLimes gave you an accurate idea. You should check last Y-position of the player. The code I’m posting below involves raycasting to check Y-axis height of the humanoid root part in the world, and is pretty accurate, but is of course not a complete anti-exploit. It doesn’t cover horizontal teleportation, seat flight exploits etc. This is solely intended to prevent high jump. You also have to cover cases where player is, for instance, flying a plane or running fast.

@Boustifail suggested checking jump requests. That’s a reasonable idea, but will rarely work with more advanced exploits, since cheaters can jump without pressing space or setting that property to true. For example, they can insert new BodyVelocity, which will result in their character flying, but without triggering .Jump event.

This case was covered by @ProBaturay, who gave a reasonable idea as well, but script is unfortunately client-sided, meaning exploiters can effortlessly override those checks by disabling the whole script.

Most decent anti-cheat exploits perform server-side checks. Those are of course a little more performance demanding, but work well, and make cheaters’ jobs significantly harder. There are multiple ways one can prevent high jump and other movement exploits. The following, again, uses raycasting, which is pretty solid way to carry out security checks, although humanoid.FloorMaterial checking can also be implemented as an alternative.

local ALLOWED_ADDED_JUMP_HEIGHT = 100 -- studs

local rootParts = {}
local lastMagnitude = {}

local _humanoid

game:GetService("Players").PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		rootParts[player.UserId] = character:WaitForChild("HumanoidRootPart")
	end)
end)
game:GetService("Players").PlayerRemoving:Connect(function(player)
	rootParts[player.UserId] = nil; lastMagnitude[player.UserId] = nil
end)

while (true) do
	for userId, root in pairs(rootParts) do
		_humanoid = root.Parent.Humanoid
		-- Cast a ray with allowed magnitude downwards.
		local raycastResult = workspace:Raycast(
			root.Position,
			Vector3.new(0,-(_humanoid.JumpHeight + _humanoid.HipHeight + ALLOWED_ADDED_JUMP_HEIGHT),0)
		)
		-- If ray didn't hit anything, player is most likely moving too high above the ground.
		if (not raycastResult) then
			-- Last check to see whether player is falling.
			if (root.Position.Y > lastMagnitude[userId]) then
				root.Parent.Head:Destroy() -- Decide yourself what to do here.
			end
		end
		lastMagnitude[userId] = root.Position.Y
	end
	-- More frequent checks are more accurate, but much more demanding as well.
	wait(.7)
end

EDIT Remember, this is a sample code for you to understand, and should be polished as well as modified to cover all cases in order to be actually used in games.

9 Likes