Animation failed to load exploit spam

The client is using some sort of injector to spam animations and lag my game. I’ve looked sky high through google and the devforum for multiple days and could only find one post that wasn’t locked for my membership status. https://devforum.roblox.com/t/server-crashing-animation-exploit/233651

I’ve tried using the code provided but have had no luck in combating all exploits linked to this.
I have no plugins that could be causing this issue and I’ve looked through them all.
There was a mention of ScriptContext but I’m heavily confused on how I can use that.

The code I’m currently using:

local Players = game:GetService("Players")
local ScriptContext  = game:GetService('ScriptContext')

local bans = {}

local function isBanned(id)
    for _,v in next, bans do
        if v == id then
            return true
        end
    end
    
    return false
end

Players.PlayerAdded:connect(function(player)
    if isBanned(player.UserId) then
        player:Kick("Banned from server")
    end
    
    player.CharacterAdded:connect(function(character)
        character:WaitForChild("Humanoid").AnimationPlayed:connect(function(a)
            local id = a.Animation.AnimationId
            
            if id:len() >= 50 then
                table.insert(bans, id)
                
                spawn(function()
                    pcall(function()
						warn(player.Name.. " banned for animation overflood")
                        player:Kick("Animation overflood")
                    end)
                end)
                
                
                player.Parent = nil
            end
        end)
    end)
end)

If anyone has any ideas or solutions, I’ll heavily appreciate it!
Thank you.

3 Likes

Hello! Exploiters are terrible as they force us devs to have to do much more work than intended.

So I see one of either two things happening: a backdoor or flawed admin commands. For the first, I recommend you use Kronos to scan your place. An article about it is found here:

My other suspicion is that, if you have admin commands, exploiters may have found a way to access a vulnerability in these. If you have any admin commands, I recommend updating them or completely removing them from your game and seeing what happens.

Hopefully you can find your solution!

Edit: Just read the other article and it states it’s not a backdoor… Hold on…

1 Like

Hey, I’m 100% sure it’s not a backdoor. I use an admin script called Adonis which is fairly popular and quite sure it isn’t that else it would affect others.

I constantly test my maps to check if any virus scripts get added, it’s an exploiter injecting animations constantly to lag it. This is a rare occasion as my game is more towards clans rather than a straight up game.

2 Likes

Just did some research and this is a REALLY annoying exploit.

I honestly think the ball is in Roblox’s court, but then again it would be hard to fix this as many scripts would break (many old tools and modern games run animations client-side).
Did some research and there are MANY vulnerabilities that, with some work, allow a dedicated person to ruin your game.

Sorry I couldn’t assist more,
Random

1 Like

Nonetheless thank you for the response and attempted help.

1 Like

This has already been noted and reported before.

https://devforum.roblox.com/t/loadanimation-error-spamming/225109

There’s not much you can do about it right now, really. I wouldn’t try to fight it either, since clients can also produce the same errors when an exploit isn’t used. False positives may go off.

1 Like

In my post I stated that there was only one with an answer (that did not work) that I could view.
The answer was shared from that post which did not completely solve the issue.

Just read the last part of your post, I’ll probably just live with it for now until a complete solution is out

This is not releated to backdoor or viruses, they are simply doing Humanoid:LoadAnimation(‘hi’) which will cause errors for everyone on the client.

As you may know, you can load animations on the client and other people will be able to see your animation, which means they can see if your animation loaded or not.

I will try to find a way to patch this, beside LogService (which is a bad method), I don’t know what else could help rn.

1 Like

You could try something like this; it’s just an idea so feel free to point out any flaws if anyone sees any.

local Players = game:GetService('Players')
local maxNumberOfAnims = 60
local playedAnimations = 0

Players.PlayerAdded:Connect(function(Player)
    Player.CharacterAdded:Connect(function(Character)
        Character.Humanoid.AnimationPlayed:Connect(function(Animation)
            playedAnimations = playedAnimations + 1
            if playedAnimations > maxNumberOfAnims then
                Player:Kick("Kicked for animation spam")
                return
            end
        end)
    end)

    spawn(function()
        repeat
            wait(2)
            playedAnimations = 0
        until not Player
    end)
end)
4 Likes

Well you declare a max animations variable at the top but you don’t proceed to use it when checking for spam :stuck_out_tongue:

Also, I can see is the use of spawn and not coroutines (but that’s a little thing), but other than that it’s great! I would like to have a table so each player has their own animation spam counter, but, unless the game has animations that play intentionally, I don’t think it’s reasonable. (Because there would be a low chance a spammer spams 59 times and on the 60th time it’s just a regular user using a floss animation or something.)

I may try later to make an OOP version where each person has own own counter but for now I don’t think it’s needed.

Great work Hammy! We appreciate the time and effort you put into this :smiley:

Edit: Also noticed that you used :connect and not :Connect, but now I’m just getting picky!

2 Likes

Thank you. I’ll edit this so each player has their own counter!
I really appreciate it.

Quick question, would AnimationPlayed run animations that errored/failed to load?

1 Like

I believe AnimationPlayed doesn’t fire when an animation fails to load, since then it isn’t really Played.

1 Like

Is there a function or a way to tell when the Player loads the animation like AnimationLoaded or no?

It’s inside of a CharacterAdded event which means that it accounts for each character that’s added, not as a general thing for all players in the server. (Atleast I was under that impression, maybe I’m wrong.)

As for spawn, there’s nothing really wrong with it but you can use coroutines if you prefer. I’ve fixed the connect issue too.


@SovereignFrost I’m not sure, you might have to test it for yourself and find out. Just have a Localscript somewhere that purposely spam loads animations with incorrect ids and see if it kicks you.

1 Like

I’m seeing some false positives now that I added the script.
I’ll probably make a table for whitelisted animations and I’ll post the source code once I’m done with it

1 Like

Yeah it’s not guaranteed to fit everyone’s games since your game might have quite a bit of animations playing. Move the variables inside the CharacterAdded event and see if that fixes it. Since they’re global variables it’s not accounting for individual players.

I changed it to account for each player
I had it on 50 and we only have a maximum of 6 animations in each gun and so the guy told me he switched guns quickly and got kicked. Quite confused on that

Instead of kicking you should have a less severe punishment. Also try printing the playedAnimations to see if anything’s going wrong.

I’m having to kick them else they could still lag the game anyway if I didn’t. Doing so can mean the main server crashing (resulting in loss of activity [clan group]) and having a functional game.

For now I’ll boost up the maxAnimations and see what happens.
I’ve only had one case of this happening so it may be a ton of switching at once between multiple guns.

Most people don’t get more than one weapon so it should be fine for now.
Cheers

2 Likes

Well the counter is global; every player can increment it. If you move the variable inside the PlayerAdded event (not the AnimationPlayed event, or else it will get redeclared every time an animation plays), it would be local to each player.

By the way, thanks for implementing my suggestions!!

Edit: Just read that you already suggested moving that counter inside the event… Sorry I missed that!

1 Like