Best way to prevent exploiters from spamming RemoteEvent?

You know how most people implement a cooldown system whenever a client fires the remote right? I don’t really see the benefit in this, because if a client wants to literally shut down the server, they’re still able to spam the remote event connection, because that remove event listener is always going to be alive and connected… I don’t want this.

The only solution for this problem I can think of, which isn’t a feasible… (which is why I need to know if there’s a better to do this…) is that every player gets their own remote event listener, and after making the connection, the remote event is disconnected and connected once the cooldown has expired… I REALLY DON’T like this idea, I don’t want to have 50 remote event listeners for a 50 player server.

What kind of solution is there to prevent this? Do I just kick the player?

4 Likes

Sure it can be connected, But its the actual games logic which can cause the Lua scheduler to die.

Just make a simple debounce and return if they’re spamming, Have one of the client and server, so if they do spam then the chances are, they’re an exploiter. so in retaliation just kick them.

However most exploiters abuse the chat API remotes I believe. So it’s best to make your own chat if thats the case.

I thought this was a great question.

Personally I hated adding a debounce to every single event. So I wrote a script that monitors all the events it can. The overhead seems small and it can be modified to suit your purpose.

--From yours truly: DrWhoInTARDIS
local events, playerTotalEvents = {} , {}
local TRACK_TIME_SEC = 10
local SINGLE_EVENT_LIMIT = 10
local TOTAL_EVENT_LIMIT = 30

function setupEvent(re :Instance|RemoteEvent)
    pcall(function()
        assert(re:IsA("RemoteEvent"))

        local e :Event = re.OnServerEvent
        events[e] = {}
        
        local counter = e:Connect(function(player)
            if events[e] ~= nil then
                events[e][player] = events[e][player] and events[e][player] + 1 or 1
                playerTotalEvents[player] = playerTotalEvents[player] and playerTotalEvents[player] +1 or 1

                --print(player,"Fired:",re:GetFullName(),"Single:",events[e][player],"Total:",playerTotalEvents[player])
                if events[e][player] > SINGLE_EVENT_LIMIT then
                    print(player,"Reached Single Event Limit!!!!!!!!!!!")
                end

                if playerTotalEvents[player] > TOTAL_EVENT_LIMIT then
                    print(player,"Reached Total Event Limit!!!!!!!!!!")
                end
            end
        end)

        spawn(function()
            while counter.Connected and wait(TRACK_TIME_SEC) do
                events[e] = {}
            end
        end)
    end)
end

for k,v in ipairs(game:GetDescendants()) do
    setupEvent(v)
end

game.DescendantAdded:Connect(setupEvent)
game.DescendantRemoving:Connect(function(v)
    pcall(function()
        if v:IsA("RemoteEvent") then
            events[v.OnServerEvent] = nil
        end
    end)
end)

spawn(function()
    while wait(TRACK_TIME_SEC) do
        playerTotalEvents = {}
    end
end)
6 Likes

Your a life saver, this helped me find the event that made the game very laggy.

1 Like