Aeroiqz V2 | Anti-Exploit | Review

code --[[

place me in startergui or startercharacterscripts
made by scriptednate

–]]

local blacklisted = {

"BodyGyro";
"BodyPosition";
"BodyVelocity";
"BodyAngularVelocity";
"RocketPropulsion";
"BodyThrust"

}

local player = game.Players.LocalPlayer;

local character = player.Character or player.CharacterAdded:Wait()

local humanoid = character:WaitForChild(“Humanoid”);

local backpack = player:WaitForChild(“Backpack”);

local torso = character:FindFirstChild(“Torso”) or character:FindFirstChild(“UpperTorso”)

local root = character:FindFirstChild(“HumanoidRootPart”);

local function destroy()
player:Kick(“Nice try exploiter, say good bye!!”)
player.Character:BreakJoints()
humanoid.Health = 0
root.CFrame = CFrame.new(1,-10000,1)
end

coroutine.resume(coroutine.create(function()

game:GetService("RunService").RenderStepped:Connect(function()
	local exploiters = {}
	# humanoid.Changed:Connect(function(t)
		if t == "WalkSpeed" then
			table.insert(exploiters,player.Name)
			print('exploiter added')
			humanoid.WalkSpeed = 16
			destroy()
		else
			if t == "JumpPower" then
				table.insert(exploiters,player.Name)
				print('exploiter added')
				humanoid.JumpPower = 50
				destroy()
			else
				if t == "HipHeight" then
					table.insert(exploiters,player.Name)
					print('exploiter added')
					humanoid.HipHeight = 0
					destroy()
				else
					if t == "Name" then
						table.insert(exploiters,player.Name)
						humanoid.Name = "Humanoid"
						print('exploiter added')
						destroy()
					end
				end
			end
		end
	end)
	backpack.ChildAdded:Connect(function(obj)
		if obj:IsA("HopperBin") then
			obj:Destroy()
			table.insert(exploiters,player.Name)
			print('exploiter added')
			destroy()
		end
	end)
	character.ChildAdded:Connect(function(obj)
		if obj:IsA("HopperBin") then
			obj:Destroy()
			table.insert(exploiters,player.Name)
			print('exploiter added')
			destroy()
		end
	end)
	humanoid.StateChanged:Connect(function(oldstate,newstate)
		if newstate == Enum.HumanoidStateType.StrafingNoPhysics then
			humanoid:ChangeState(Enum.HumanoidStateType.RunningNoPhysics)
			table.insert(exploiters,player.Name)
			print('exploiter added')
			destroy()
		end
	end)
	humanoid.Running:Connect(function(speed)
		if speed > 17 then
			table.insert(exploiters,player.Name)
			print('exploiter added')
			destroy()
		end
	end)
	root.DescendantAdded:Connect(function(t)
		for z,x in ipairs(blacklisted) do
			if string.find(x,t.ClassName) then
				table.insert(exploiters,player.Name)
				print('exploiter added')
				wait()
				t:Destroy()
				destroy()
			end
		end
	end)
	torso.DescendantAdded:Connect(function(t)
		for z,x in ipairs(blacklisted) do
			if string.find(blacklisted,t.ClassName) then
				table.insert(exploiters,player.Name)
				print('exploiter added')
				wait()
				t:Destroy()
				destroy()
			end
		end
	end)
	character.ChildRemoved:Connect(function(obj)
		if obj.Name == "Humanoid" and root ~= nil then
			table.insert(exploiters,player.Name)
			print('exploiter added')
			destroy()
		end
	end)
	character.DescendantAdded:Connect(function(t)
		local tool1 = character:FindFirstChildOfClass("Tool")
		if tool1 ~= nil and tool1 ~= t then
			table.insert(exploiters,player.Name)
			print('exploiter added')
			destroy()
			tool1:Destroy()
			t:Destroy()
		end
	end)
	repeat wait()

until game.Players.LocalPlayer and game.Players.LocalPlayer.Character and # game.Players.LocalPlayer.Character.Humanoid

local plr = game.Players.LocalPlayer

local char = plr.Character

local hum = char.Humanoid

hum.StateChanged:Connect(function(oldstate,newstate)

if newstate == Enum.HumanoidStateType.StrafingNoPhysics then
	plr:Kick("You've been kicked for noclipping")
# end

end)

	# return exploiters
# end)

end))

There’s the script. Any suggestions to add on. You may use it if you want to

Anyway I can upgrade any system to implement.

16 Likes

Format code in a code block.

~~~~~
– # code
~~~~~
I escaped the tildes with backslashes.

Without the back slashes:

-- # code
7 Likes

Also this is fe

It should kick the exploiters if I am right. I have tried it.

2 Likes

But as already mentioned by @Amitean

Personally, I find anti exploits to be pointless. Proper remote communication is key. Do sanity checks on the server side.

2 Likes

Okay, I will implement server-side checks.

Anti exploits are definitely important. Sanity checks on your remotes won’t save you from all exploits.

2 Likes

There’s no need to distinguish this anymore. All games have the same protection now, since experimental mode is gone.

As for the script, I didn’t read the whole thing since I could tell by the start of it that it will only work from the client. It isn’t a very strong anti exploit at all since anything on an exploiter’s client can be modified to suit their own malicious needs, but since you already have it I would just keep it as an extra layer. It’ll almost definitely catch some exploiters, but you really need an anti exploit that runs entirely on the server.

2 Likes

First of all please format this in a code block.

Now, sorry to disappoint you but this is almost equal to no protection at all :stuck_out_tongue:

First of all, if anyone in the server changed their walkspeed, every single player would get kicked, because you don’t distinguish players in your RenderStepped.

Second of all, you kick from the client. An exploiter can hook the kick function with 10 lines of code and disable your kick. So yea.

My tips:

  1. Prioritize server-sided checks. Feel free to add client-sided ones afterwards, though don’t fully rely on them, but rather have them as a little “extra” thing. But only if you know what you’re doing!!! If you don’t know how to set up client-sided checks properly, then you should rather refrain from implementing them.
  2. Never trust the client. This is something you will always hear when it comes to securing your games. Check most, if not all imput from the client.
  3. Don’t make the client tell the server what to do! Don’t make some SetCash remote events or such. Don’t make the client tell the server the price of the thing you’re buying.
2 Likes

You don’t seem to use the exploiters table in your script (although it makes sense as Player:Kick() only works on the local player in a localscript) so all the insert lines should probably be removed. Also, I believe that a lot of speed exploiting done recently doesn’t actually change WalkSpeed, so that protection won’t protect from those specifically either.

2 Likes

A common Antikick will make this Antiexploit useless by simply changing the __namecall metamethod from DataModel/game slightly. (As Kiriot22 mentioned)

Also, since you index WalkSpeed, JumpPower etc. exploiters can just check if you index those properties and return a valid value, while they are changed.

Of course the simplest solution would be to just delete or disable the script.

3 Likes

You can always replace the coroutine wrap with the keyword “spawn” Although if you need to pause the routine and add a new input then do keep using it.

Another point to make is that, if you absolutely need a client script, make sure the server is constantly checking it exists. Using a remotefunction is a great way to check, but be sure to make the call a pcalled function with a delay (use the delay keyword to not pause the entire thread) so as to both make sure lag is accounted for and that it will still kick if there is an error.

Your feedback request is incomplete. Code Review is not a venue for open-ended asking of suggestions and showcasing code. Please read the category guidelines.

You are missing:

  • Explanation of code (it’s blatantly obvious, I’m aware, but one would be appreciated)
  • What is unsatisfying about this code to you
  • What improvements you have already attempted to apply
  • What specific improvements you seek in your code

Also, how come you have not corrected your code block? It’s been explained to you how to do so yet you have not corrected the code block above trying to reply to posts. It’s harder to read what you’re trying to post without proper formatting. Please fix your code block as soon as possible.

5 Likes

I’m making a hex-based multi-player, RTS wargame with Fog Of War.
The full map on the Server.
On the client you can see any action going on in a hex next to any hex, one of your units is in.

If you move your unit away; I Destroy any hex you can’t see; on your client, but a hacker, could stop the Destroy.

How do check this exploit on the Server?
Is anything replicated from Client to Server, which could piggy-back some useful information?
(i won’t kick him; just degrade his abilities enough, so he always loses)

[I don’t think any dev should Kick. Don’t we want the hacker in the dark, and him to spread a useless hack?! I hate them more than most do.]

The way I would approach this, probably not the most efficient:

  • Store the actual game data on the server, i.e. unit position’s, unit type, research, whatever is hidden by default
  • When client1 moves a unit/reveals a tile, tell the server that the unit has moved, check that they can, and once you’ve done that, the server should tell client1 any data revealed from the moving of the unit and to remove the stuff that’s been moved out of range. The server should tell all players that can see the unit that it has moved and to act accordingly.

This has the benefit that even if the client doesn’t destroy the unit on their screen, they won’t know where it’s going, so it doesn’t really have an advantage.

Well… This is done:

game.Players.LocalPlayer:WaitForChild("ClearTile").OnClientEvent:connect
(function(Obj, NegObj)
	-- object is a list of Tile .Names to reveal
	
for i = 1, #Obj do -- reveal these Tiles	
	local cloud = container[Obj[i].Name]
-- container is a local model of the globe and all Tile model shells.
-- It only holds the initial cloud cover
-- or current placeholder graphic of old snapsot
	cloud.OldInfo:ClearAllChildren() -- remove old snapsot
		if cloud:FindFirstChild("Mesh") then cloud.Transparency = 1
			cloud.Mesh:Destroy()
		end
	Obj[i].Parent = workspace.globe --Flip "lightswitch" to On
	end
wait(.5)
	for i = 1, #NegObj do -- Erase these Tiles

	 	NegObj[i]:clone().Parent = container[NegObj[i].Name].OldInfo -- take snapsot
		greyOut(container[NegObj[i].Name].OldInfo[NegObj[i].Name]) -- Turn B/W
		
		NegObj[i].Parent = nil -- Flip switch to Off
		-- This is the line which could be bypassed. But how can I check?
	end	
end)

So...?

Simply put, you don’t, because there is no need to, as long as you are following my instructions. The exploiter may still be able to see the unit, but they won’t see where it moves or what it does. This is not really an unfair advantage, since anyone can remember where a unit was or note it down on aper.

Sorry, did not mention: For this to work automatically a unit is Parented to the Tile it is in,
so Local Player could see if a Unit moved out of a Tile it is not supposed to see, or a unit oved into a Tile…

Unfortunately, I think the only way to make exploiter proof is to do the replication manually. I would create the actual model of the unit on the client, and have the unit’s position on the server. The server only sends remote events to the clients that can actually see it.

I hear you but there is no way I’m going to do that… That is:
100s of Parts > 1 Tile.Name(Oh, I want every unit to be an individual. People love that…)
Sent to 5 more Clients > 1 Client
for each Unit moved from one Tile to another

I just need a sanity check every once in a while on the Server, that a Client isn’t seeing a Hex which it isn’t supposed to…

There is ALWAYS a way…