Anti-Exploit that detects "spin & fling" exploits

Since this seems to be physics based, setting collision groups is an option. This would cause the characters to be unable of colliding with each other.

As long as the client doesn’t hold there right click down nor have shift lock turned on they shouldn’t be able to rotate with the along with the camera.

4 Likes

Alright, these are very good ideas, except I have a few issues.

  • My characters in my game I would prefer to have them collide with each other.
  • Exploiters can enable shiftlock or hold right click and still perform the exploit. Also it is relatively easy to spin using WASD at a relatively high speed close to the speed of the exploit, so relying on shiftlock or firstperson to see if they should be spinning or not would lead to a lot of inaccurate detection.

You can create a server script that will loop through all characters and check if the Humanoid root part is going faster than a certain speed. Another issue you are doing is kicking players, you shouldn’t be kicking players just because they go faster than your set limit. Roblox physics is unpredictable so you may end up with false positives. Just set the velocity of the character to 0 rather than kicking, you’ll lose player count easily by kicking players.

5 Likes

You could try using the Orientation property of the character’s torso to see if it is rotating too quickly.

You can attach a callback to the server heartbeat (so that it will happen along with physics calculations) and follow @wevetments’s idea with looping through players.

You can then record the rotation of the torso each heartbeat and compare it to the previous value. If it is over a set amount, return it to zero. You may also want to display feedback to the user to warn them to stop.

This is a very good point. Never kick players based on an exploit detection. Only give feedback and take non-offensive action.

6 Likes

These are great ideas and great points, thank you for the help @wevetments @CodeNinja16

2 Likes

Sorry I know this is an old topic, but I feel that I need to clarify how I finally ended up solving it.

Problems while creating the anti-exploit.

Almost all “spin fling” exploits I have seen use Body objects. (such as BodyForce, BodyVelocity, etc…). What I found was that using orientation of the character is extremely unreliable as a normal user can rotate themselves at very high speeds with relative ease. As I have tested, the fast rotation of the body alone does not usually cause flinging. The assistance of body forces is what actually ends up being the problem.

The Solution

What I did as a solution was to locally check the character for any descendants added, and also scan the character every small amount of time to check for BodyForces. If any BodyForce is inside or added to the character, it sends a message to the server using a RemoteFunction to check whether or not the force exists on the server. If it doesn’t, the force is simply removed.

If no message can be sent to the server, or no response is given, the script tries again. After a few attempts the anti-exploit will assume that the communication was manually interfered with, and will remove the BodyForce. In order to prevent the local part of the anti-exploit from being disabled, I just write the anti-exploit in a ModuleScript, then require it in a LocalScript. Since code still runs after a ModuleScript is deleted, there is no reasonable way to disable this anti-exploit.

This solution seems to have worked flawlessly for me and I actually don’t experience this exploit in my game anymore. I hope this helped anyone who was experiencing the same issue as me, sorry for bumping an old thread.

23 Likes

The local routine can still be disabled, irregardless of ‘ModuleScript’ or not. Trusting the client is not a very secure form of detection. You should be checking player behavior server side, in order to prevent any reasonable form of tampering.

4 Likes

@jody7777 I have other ways to make sure the local routine stays in tact, and other ways to check for this exploit which are unrealistic for even some advanced exploiters to be able to stop on the client. This is the simplest way I can explain and 95% of exploiters will not have a clue how to get around this. It’s not full-proof, but it is accomplishing it’s task.

@Tynezz Each player has their own local script that makes the anti-exploit run, it works fine with 30 chars.

Thinking that exploiters can’t breach your code’s protocol when the server isn’t involved is an unsafe delusion. Nothing is unrealistic to an exploiter.

2 Likes

To expand on that, someone who makes exploits could just change how it works so instead of using BodyMovers, they could just change the part’s RotVelocity or something like that - also, they could literally just remove the script which checks it. Checking only on the client side is not a great approach.

2 Likes

This is a quite a commonly seen exploit now, the user is completely invisible and flings people.

4 Likes

How would I resolve this issue?

2 Likes

Hmmmm very clever was looking for this myself does your’s look somewhat like this?

StaterPlayerScripts

local player = game.Players.LocalPlayer 
local char = player.Character or player.CharacterAdded:Wait()
game:GetService('RunService').RenderStepped:Connect(function(dt)
    for _, v in pairs(char:GetDescendants()) do 
       if v:IsA('BodyForce') then
              local IsForceInServer =  game.ReplicatedStorage.Function:InvokeServer(v)
                 
             if IsForceInServer then
             else
                  v:Destroy()
             end 
        end 
   end  

end)

2 Likes

Hate to bump this, but once they are able to fire the correct key to the server, then what happens when they simply autoexecute a hookfunction(getgenv().require, function(…) if not checkcaller() then return end end)

Basically, once they know the key to send to the server, they can simply hook require via getting the global environment and check for the ModuleScript’s getscripthash()'s hash to then prevent your localscript from requiring the anticheat, while allowing other scripts to run.

1 Like

Well, I have a special function that can detect getconnection and disconnect things.

Most fling scripts involve spinning characters to an otherworldly fast speed, a speed that is nigh impossible to be achieved under normal circumstances. I mean, seriously. If you use .Magnitude on the assemlby angular velocity of a flinging player, it goes up into the millions. This property replicates to the server, so you don’t need to rely on anything local. Just check this property, and if it goes over a certain threshold, you can handle it from there.

As for invis fling scripts, what they do is delete every body part except for the root part. This is an easy check because the character’s humanoid is classified as “dead,” but doesn’t initiate the respawn count down. Also, it’d be an unlikely scenario that every part in a character is removed except for the root part, and that root part would also be spinning with a magnitude of 312983120 or something.

No need for local checks like some have proposed here, just check replicated properties and flinging should not be an issue.

2 Likes

oh let’s see that anticheat, let’s test that ay?

You can go in first person and turn up your sensitivity to achieve the same effect. Also, sometimes there are physics bugs that cause you to be flung and reach enormous velocities. If you are using this method, due to the large possibility for false positives, anything in retaliation for a detection shouldn’t be any more than a respawn. (And I have found lots of false positives in my testing)

I think you’re greatly overestimating how much speed you’re able to generate without the external assistance of scripts. No amount of physics bugs or first person spinning in my testing was able to even crack 10,000. I won’t say it’s impossible, but it is exceptionally rare for this to be natural. My anti-fling measures only involve respawning the player because they’d be dead anyways if they were rotating at 99999999 degrees per frame.

Let’s test that, this is nearly impossible! I would be surprised if it works.