Anti exploit kicking me 300+ times

i want to prevent this from happening like kicking them more then 200 times

here is the code

while true do
	RunService.Heartbeat:wait()
	for _, Player in pairs(game.Players:GetPlayers()) do
		if Player then
			local character = Player.Character
			if character then
				local Humanoid = character.Humanoid
				if Humanoid then
					Humanoid.StateChanged:Connect(function()
						if Humanoid:GetState() == Enum.HumanoidStateType.StrafingNoPhysics then
							Player:Kick("Exploiting yeet!")
						elseif Humanoid:GetState() == Enum.HumanoidStateType.Flying then
							Player:Kick("Exploiting yeet!")
						end
					end)
				end
			end
		end
	end
end

Try adding waits, because it currently just is a infinite loop.

RunService.Heartbeat:wait()

is my wait system

Maybe try doing something like

wait(1)

Or play around with the timing

Oh I found the problem. The wait is in the while loop but not the for loop. Try moving your wait function to be inside the for loop and change the while to while wait(.1) do

You should entirely get rid of the loop, to my understanding you are just kicking players when the humanoid is in one of those two state types.

game.Players.PlayerAdded:Connect(function(pl))
	pl.CharacterAdded:Connect(function(ch))
		local hum = ch:WaitForChild("Humanoid")
		if hum then
			hum.StateChanged:Connect(function(_, newState)
				if newState == Enum.HumanoidStateType.StrafingNoPhysics or newState == Enum.HumanoidStateType.Flying then
					Player:Kick("Exploiting yeet!")
				end
			end)
		end
	end)
end)

Not tested, but here’s roughly what I would expect your code to look like.

2 Likes

it doesnt work bc it only fires when we are added as a character

I’m not really sure what you mean by that…what is the problem?

when i tried to fly it didnt kick me

It’s not a good idea to nest :Connect statements inside repeating loops. You would be creating new event listeners every frame.

1 Like

so what i can do just to prevent this from happening

You could simply break the for loop from running any further once the player is kicked, or you can use coroutine and yield the loop.

1 Like
local function KickPlayer()
	Player:Kick("Exploiting yeet!")
	return
end

while true do
	RunService.Heartbeat:wait()
	for _, Player in pairs(game.Players:GetPlayers()) do
		if Player then
			local character = Player.Character
			if character then
				local Humanoid = character.Humanoid
				if Humanoid then
					Humanoid.StateChanged:Connect(function()
						if Humanoid:GetState() == Enum.HumanoidStateType.StrafingNoPhysics then
							KickPlayer()
						elseif Humanoid:GetState() == Enum.HumanoidStateType.Flying then
							KickPlayer()
						end
					end)
				end
			end
		end
	end
end

That returns out of the KickPlayer function, not in the event listener. Also, all Lua functions have an either implicit or explicit return statement at the end, so that is effectively pointless.

1 Like

You can change the player state after kicking them so they don’t get kicked a ton of times.

If you want to kick players when their humanoid state changes to one of those two states, you don’t need the while loop at all.
This code sample here is entirely event-based:

local players = game:GetService("Players")

local bannedStates = {
	[Enum.HumanoidStateType.StrafingNoPhysics] = true,
	[Enum.HumanoidStateType.Flying] = true
}

-- the main listener
local function listenForHumanoidChange(character)
	local humanoid = character:WaitForChild("Humanoid")
	if (humanoid ~= nil) then
		humanoid.StateChanged:Connect(function(_, currentState)
			if (bannedStates[currentState]) then
				players:GetPlayerFromCharacter(character):Kick("Exploiting yeet!")
			end
		end)
	end
end

-- bind the listener to a player
local function setUpPlayer(player)
	-- check if a character already exists...
	if (player.Character ~= nil) then
		listenForHumanoidChange(player.Character)
	end
	-- then bind for future respawns
	player.CharacterAdded:Connect(listenForHumanoidChange)
end

-- bind players who are already in the game when the script runs...
for _, player in ipairs(players:GetPlayers()) do
	setUpPlayer(player)
end

-- then bind players who join later
players.PlayerAdded:Connect(setUpPlayer)

Just saying “it didn’t work” won’t address your problem. Try to do some basic debugging:

  • Is there any output?
  • Is the script executing?
  • Are the events firing? What data is returned to the events?