I’m not updating this anti-cheat anymore, so it might be broken. The testing game will also remain closed. Most users on this forum are just wannabe coders that will trashtalk this anti-cheat no matter what and say some features don’t work without even testing them. Overall, this community is dumb and there is no point in continuing to work on this project as the community doesn’t deserve it.
Also I am looking for a project to work on so if anyone needs a scripter please dm me on my discord (Pinha#5428). I don’t need money I’m just doing this stuff for fun.
You could place it inside of StarterPlayer
Sentinel’s client-sided anti-cheat is stored inside a Script in ServerScriptService. Every time a player joins it will get cloned and placed inside his PlayerGui, and then enabled. After getting enabled it will set it’s own parent to nil to make it more difficult for exploiters to find it.
Nice. I suggest giving users the choice to clone the client-side script around every 45 seconds and destroy the old copies in case they decide to delete them. I’m not sure if you should or if it will create lag.
I guess that’s a good idea for protecting the client-side anti-cheat. The server-sided anti-cheat could send new copies of the client-sided anti-cheat to all players every once in a while, which then would check if the old copy still exists and if it is enabled. If not then the player is exploiting. (also delete the old copy)
Yeah, bit unfortunately the old copy will still exist for the server. So delete the clone and then re clone it every 45 second. In case they delete it.
This detection is heavily outdated and doesn’t work. Other than that I would recommend adding sanity checks for connections as well as anything else. For example at the moment if an exploiter wanted to add a ui to PlayerGui for some reason they could disable the ChildAdded connection and do what they want. You could however simulate an Instance being added to PlayerGui in order to verify the connection hasn’t been disabled.
Also instead of firing a remote to the server with the raw values of the humanoid you can use some sort of client server encryption to make it harder to intercept the messages. This also however has faults, as values can easily be spoofed by hooking the __index metamethod and returning false values. It’d be more efficient to check these values on the client and then firing a single remote to flag them than all being compared on the server. Another suggestion to counter that would be checking more unknown properties, what I mean by this is properties such as humanoid root part velocity. Most speed scripts do spoof the humanoid walk speed but don’t manage to take into account that your velocity also increases.
Also quick side note for user id detection, the character appearance id has the same value as the user id so you can compare both of those values on the client and flag them if they aren’t matching.
One final tip would be adding a heartbeat to the client anti cheat. All these detection’s are great and all but what stops someone from hooking the remote from ever firing. By adding a heartbeat to the client script (means the client has to communicate to the server every X seconds) you can then pick up any abnormalities and detect if has tampered with your anti cheat remote.
Thanks, I’ll look into it.
About the HumanoidRootPart velocity, I’ve tried to get that to work for 3 days. I used Humanoid.Running to get the speed and also raycasting from feet to the ground to find the platform the player is standing on, so then I can get the speed of the platform and subtract it from the player’s speed in order to get the ‘real speed’. I also tried using workspace:GetPartsInPart(foot, overlapParams) instead of raycasting or even both at the same time for more accurate results. But I was never able to get it to work without causing false-positives in some situations.
The remote spy you used hooks the __namecall metamethod onlt meaning it only picks up the remotes if they are called like the following :FireServer and :InvokeServer etc. The method you used to fire a remote does help prevent beginner level exploiters from being able to see the remotes being fired however more experienced exploiters/developers will be able to tell that you index and call the function instead.
All remote events have the same functions at the end of the day, to demonstrate if you go into the game and write the following
This means that exploiters can simply also create a remote event instance then hook the fire server function. It would look something like the following
local FS = Instance.new("RemoteEvent").FireServer
local oldFS; oldFS = hookfunction(FS, function(...)
print("Fire server was called.")
return coroutine.yield()
end)