I see what your saying now thanks for the elaboration. I thought you meant a full client side check.
Ah okay I see, thanks for that. I was just confused as to why @bacionhairmanfur2 was very vague and didn’t provide any help, but just called it “useless.”
Anyhow, how would you all suppose that he go about this then? If he uses a localscript, then exploiters can simply remove/tinker with the localscript to make it really “useless.”
That’s why I proposed using other means of checks. For example, checking the players’ distance from the ground, and their speed.
So @PixelIGPM8 do you have an idea of how you’d want to do other checks, such as checking the distance from the ground/speed? Or would you like some help with that?
And if anyone has any other ideas, please feel free to help and bring them up!
EDIT: So, one idea is to keep what you originally had, but add onto it with the extra checks from the server side. So that you’d have one localscript that would handle those checks, but in the event that exploiters messed with the localscript, you’d still have the server-side checks.
So the server-side script could handle these checks: The players’ distances from the ground, and the speed/velocity the players are traveling at.
And the client-side localscript can handle these checks: If the character has a BodyMover or BodyGyro in it (like you originally did).
And sorry, that was my bad. I didn’t realize that you can’t check BodyMovers or BodyGyros inside of the characters from the server until they mentioned it - that explains it.
Hey dude, don’t this.
First of all, you’re going to have a memory leak problem because you’re creating n (number of players)
connections every 5 seconds. So if anything is ever added to a player’s character, then you’ll have 12 handlers respond to it every minute after the character last spawned.
Second, things like ‘BodyGyro’ objects aren’t replicated from client to server, only the effects are. If you are going to use a server-sided check, then you’ll want to compare the player’s CFrame and velocity.
Oh interesting, I didn’t know that doing GetPlayers() every 5 seconds would cause memory leaks.
And yes, that’s very similar to what I also mentioned above.
Thanks for the input on that - I’m learning as well!
Client side anti exploits are unreliable and exploiters can and will easily bypass your code.
I wrote a fairly detailed article about creating good anti exploits here if you want to take a look at it.
Generally, think of all of your client code like an exploiter can both read, and directly edit it. This is effectively exactly what exploit code does, it just does so in a slightly different way than you’d think.
The specific examples themselves are probably just a little outdated as there are more things I now prefer to use, however, it certainly still holds up perfectly fine.
GetPlayers itself is not the reason for this, it has to do with Connecting things and not Disconnecting them. The example provided creates a ChildAdded connection per player every five seconds. This is bad.
The events would be disconnected when the character respawns since :Destroy()ed objects or GCed instances lose their connections.
Ohh interesting. So is there another way to do this? Could you do :Disconnect on a players death, and limit the connections to once?
So is there a way to modify the given script to where it won’t create a ChildAdded() connection every time, but work as intended, checking all players?
The way it should be done is simply by not :Connecting more than once.
The way I’d do it instead is to :Connect when a player’s character is added:
local Players = game:GetService("Players")
local function playerAdd(player)
player.CharacterAdded:Connect(function(character)
local rootPart = character.PrimaryPart or character:WaitForChild("HumanoidRootPart")
-- Code
end)
end
for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(playerAdd)() -- Create it in a new thread so it doesn't block code from running if wait is used
end
Players.PlayerAdded:Connect(playerAdd)
However, the problem with the above check is that if you implement it on the server, it won’t detect anything. The reason movement exploits work is simply because the player has Network Ownership (physics control) of their character, not that they truly create BodyMovers or change WalkSpeed.
Those types of exploits should be checked for by checking physics manually, like I explain in my article. Personally, I believe that rather than just detecting most exploits you should always simply prevent them, as, especially with movement exploits, false positives can happen.
An example of an exploit you can easily detect is commonly referred to as “FE God Mode” and basically, the exploiter deletes their “Humanoid” and creates a local client sided one. The reason this works is because if their is no Humanoid, they can’t die (this also has the effect of making their Humanoid related items break such as Pants/Shirts/TShirts, animations, and meshes for R6 characters for other players).
As for why they can even delete their Humanoid, any Descendant of the Player’s Character can actually be deleted. That’s just a weird quirk of the engine, and, it includes Tools the player is holding, SimpleMeshes, Clothing items, even server scripts in the character or Tools they hold! Anything in the Character can be deleted by the client. This is the reason why some older games would make vehicles disintegrate if you reset, because they placed those vehicles in the Character, which meant that when you die and Character:BreakJoints is called on the client by the game, the vehicle’s joints would also break.
@NodeSupport has a great way and explanation on how to create a Movement Anti Exploit in the following post: How do I make a good anti teleport system? - #10 by NodeSupport
Some Exploits may not use bodymovers.
Also, like what some other people have said: You shouldn’t put local anti-exploits. Have something like this:
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
— stuff here, make sure its in a server script
end)
end)
This is incorrect completely. Instances added to the character do NOT replicate to the server when an exploiter adds them in via an exploit as exploits are completely client-sided. If you do a server-sided only anti-exploit, you will limit yourself to a few functions that won’t really help your game at all.
@PixelIGPM8 this is a great start however further down the line you will need much more scripts along with server-checks down the line.
Everyone PLEASE stop recommending server-sided only checks. Exploits CANNOT replicate to the server with Instance.new().
Here’s proof, I made a test place and use Instance.new() to add this.
Client :
Server :
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
repeat wait() until char:FindFirstChild("HumanoidRootPart")
char.ChildAdded:Connect(function(c)
if c:IsA("BodyMover") or c:IsA("BodyGyro") or c:IsA("BodyVelocity") or c:IsA("BodyForce") then
pcall(game.ReplicatedStorage.FlyLog:FireServer()) -- Pcall is used in the case an exploiter deletes your remote from their client.
wait(2)
plr:Kick("HACKING NOOB.")
end
end)
Put the code I posted into a LocalScript that’s inside PlayerScripts. Have fun preventing exploiters from ruining your game and have a good day.
That won’t prevent anyone. The client can control anything your localscripts can access (and stop them from running aswell).
An exploiter can simply disable your client side check. They can not disable server side checks.
Server-side only checks are the way to go. Implementing client checks is simply delaying the inevitable. As I said above, think of your client code like an exploiter can both read and edit it. This is pretty much exactly what exploits do, they simply do it in an indirect way by changing little pieces of functionality.
An exploiter could do any of the following to bypass your check in a minimal amount of code (10ish lines) with any modern exploit:
- Make IsA return false for their BodyMovers/BodyGyros
- Override the :Kick function & the :FireServer function
- Disconnect your ChildAdded connection
- Change the event returned by .ChildAdded to a custom one
- Use a function you call (e.g. IsA, FireServer, wait, or Kick) and produce an error or permanently yield
- .Disable the script (and yes, they can hide this easily)
Client anti exploit code is not reliable.
@Sudden_Demise Did you not see our previous replies? I specifically mentioned that @PixelIGPM8 could have both client and server side anti exploit measures. I agree with @Hexcede’s reply above.
If you read earlier, server-side checks are not able to check BodyMovers/BodyGyros, while client-side checks are. The thing is, client side checks, and checking for BodyMovers/BodyGyros is very likely not a sure-fire to prevent expoiters from flying. Reasons? I think @Hexcede covered that well enough.
Here’s, once again, my reply from earlier on what direction I believe @PixelIGPM8 should take:
One of the problems I could see happening with the above, is that someone could mess with the RemoteEvent(s) sent between the localscript and script and potentially error/jam the script if they send it a certain way, and the script isn’t prepared for those situations. So the safest way may be to just have server side checks, as it does most of the “heavy-lifting” anyways, and is more reliable and secure in comparison to client side checks anyways,
Any ideas for the server-side checks?
Not to lie but @Sudden_Demise has a point.
Because IT Will NOT replicate to the server.
Server Sided Anti-Cheats can only stop exploiters that come to ruin your game ‘server sided’
However, as I explained above, physics will replicate to the server. This is why the exploit even works at all, if something is happening for other players it has to be replicating something. Tuning your physics anticheat to your game is extremely important for this, for example, vehicles and such will have their own physics, which I go over in my article a little.
The instances themselves will not replicate, however, introducing client checks is almost never ever worth it. Technically, yes, its true that you can’t stop all exploits from the server easily however physics is by far the hardest but also isn’t particularly much difficulty. The problem is, that even if you check on the client, it can be bypassed far more easily than it was for you to create it, the amount of people it will stop depends on its complexity, and, even then, it will only stop the people with more basic understanding of the exploit they are using.
What about the following?
FPS, WalkSpeed, JumpPower, etc.