Event Tracker | A quick little module

So someone was trying to tell if a remote event is triggered, then track how many times it was triggered, and if its above a certain amount, then kick the person who was triggering it.

Now that sounds complicated. So I’ve come to save the day! (Ig idk man)

Disclaimer

This may not be the most optimized possible, so any ideas on how to improve it are greatly appreciated!


Get It

The module

So lets talk about the module!

Properties

  • Enum: Custom enums that come along with the module

Methods

  • Track: Tracks the provided remote event. Returns a Tracker
  • CreateAutoTracker: Creates an AutoTracker, which will track any remote events that are in, or are added to the provided instance. Returns the AutoTracker.

Events

  • AutoTrackerCreated: Triggers when a AutoTracker is created. Parameters {AutoTracker}
  • AutoTrackerRemoved: Triggers when a AutoTracker is removed/Destroyed. Parameters {}
  • OnTrackerCreated: Triggers when a Tracker is created. Returns the Tracker created. Parameters {Tracker, TrackerType:Enum}
  • OnTrackerRemoved: Triggers when a Tracker is removed/Destroyed. Parameters {RemoteEvent}

Trackers

Properties

  • RemoteEvent: The remote event used for the Tracker
  • EventsPerSecondLimit: The amount of events that can be triggered from the player per second.
  • LimitExceededCooldown: The cooldown between a limit being exceeded.
  • TrackerType: The type of tracker the tracker is, Ex: Automatic, Manual

Methods

  • Disable: Disables the Tracker
  • Enable: Enables the Tracker
  • Destroy: Destroys the Tracker

Events

  • EventTriggered: This is triggered whenever the RemoteEvent is fired on the server. Parameters {Player,Any…}
  • OnLimitExceeded: Triggered when a player has fired a remote event too many times over the limit. Parameters {Player}

Note
Trackers wont do anything if a player exceeds the limit, so if you wish to take action against the player, use the Tracker.OnLimitExceeded Event

AutoTrackers

Methods

  • Destroy: Destroys the AutoTracker
  • Disable: Disables the AutoTracker
  • Enable: Enables the AutoTracker
  • DisableAllTrackers: Disables any Trackers that were created via the AutoTracker
  • EnableAllTrackers: Enables any Trackers that were created via the AutoTracker

Examples

Using the EventTrackerModule is pretty easy, all you need to do is:

local EventTracker = require(PathToEventTrackerModule)

An example for when you want to know when a Tracker or AutoTracker is created:

EventTracker.OnTrackerCreated:Connect(function(Tracker,TrackerType)
	print('Tracker created:',Tracker,TrackerType)
end)

EventTracker.OnTrackerRemoved:Connect(function(Event:RemoteEvent)
	print('Tracker Removed for event:',event)
end)

EventTracker.AutoTrackerCreated:Connect(function(Tracker)
	print('AutoTracker Enabled:',Tracker)
end)

EventTracker.AutoTrackerRemoved:Connect(function()
	print('AutoTracker removed')
end)

Creating Trackers:

local AutoTracker = EventTracker:CreateAutoTracker(game:GetService('ReplicatedStorage')) -- Tracks any remote events in ReplicatedStorage
local Tracker = EventTracker:Track(event) -- tracks a single RemoteEvent

Tracker.OnLimitExceeded:Connect(function(Player:Player)
   Player:Kick('Bad Dog D:')
end

Hopefully this helps out some people! If you would like any features implemented feel free to ask! I’d love to help! Any instructive criticism is accepted!

Yw~
~ Frodev

4 Likes

I thought about how connecting a function to a Tracker for the OnLimitExceeded event might be a bit of a pain to do over and over, especially when using a AutoTracker, so when creating a Tracker or AutoTracker Ill allow you to pass an argument of info you’d like to be applied to the created Tracker(s), such as properties (E.g: LimitExceededCooldown), or a function thats triggered when the OnLimitExceededEvent Is triggered. Stay tuned for that.

I also plan to upload this to Github soon, so yeah

A Roblox-like syntax for Remote debounces! I would recommend a way of middle manning the request entirely on the tracked events. Sometimes if remotes are fired too much it might just be a good idea to drop the request and send the error to the client saying “Limit exceeded, try again in X”, or keep the request moving and silently flag the user for moderators. Also, fine levels of control over them like less than 1 event (per player) per second.

This isn’t a replacement for exploit moderation and should never be fully trusted as being truthy, but can be utilized as a tool to watch over people who may be exploiting. There’s always ways to fire remotes more than expected via things in your game that you didn’t consider, easy oversight locations.

As critical as I sound, this is still a pretty nice resource! The last bit was more of a “People who use this, keep this in mind” and isn’t something for you.

1 Like

Why thank you!
Yeah flagging to moderators is probably a good idea, or sending something to the client. Maybe Ill make some base functions so you wouldnt have to code it in manually, thanks for the feedback though! :3

Of course! Also, those were more of examples of what someone may use them for, I think something like this would be good for the event:

-- example: FroDev1002 fired remote with:
--   "GetStore", "Filter:Skins"

-- this of course wouldn't work and would need its own implementation for the event
event.OnServerEvent:Connect(function(player, method, ...)
    local args = {...}
    if method == "GetStore" then
        local filter = args[1]:split(":")[2]
        event:Fire(player, "Store", stores[filter])
    end
end)

-- of course, this isn't really the best example 
Tracker.OnLimitExceeded:Connect(function(player, request, pass, drop)
    if isAdmin(player) then
        return pass() -- admins shouldn't be affected
    end

    local method = request[1]
    if method == "GetStore" then
        event:Fire(player, "LimitExceeded")
        drop() -- won't run the server response at all
    elseif method == "Ping" then
        pass() -- will then allow the server response to take place
    end
end)

Sorry it took me a bit to write, this was written on mobile. Being able to middleman events would require the server events to be handled by tracker as well, what I put above would not work as both events would still fire no matter what. You could possibly make the “OnServerEvent” method part of the Tracker itself to be able to manage it internally?

1 Like

So what Im getting at is that you would like to know when the RemoteEvent is triggered via the Tracker?

No, I meant more of the limit exceeded event should be able to make the servers response (the OnServerEvent) to not run at all/allow it to pass thru via drop and pass.

This would probably require event.OnServerEvent to be Tracker.OnServerEvent

1 Like

I wasn’t very good at explaining it, so I’ve altered your module script to show what I meant. Also, I changed how triggers are kept track of by turning them from an Array to a Set so they didn’t always stay in memory as that can cause memory leaks. Using Sets made getting the last second worth of triggers way easier. I also noticed you misspelled connections['EventTriggerd'], but that doesn’t seem to have an effect on the module at all. Fixed type-checking and it now uses varadic arguments.

This removes self.EventTriggered in favor of self.OnServerEvent. Used like this:

Tracker.OnServerEvent:Connect(function(player: Player, ...: unknown)
    print(player, table.unpack({...})
end)

Which then is controlled internally with connections.EventTriggered.

This also changes the parameters for self.OnLimitExceeded to this:

-- player: Player
-- arguments: {[number]: unknown}
-- pass: () -> ()
-- totalTriggers: number
Tracker.OnLimitExceeded:Connect(function(player, arguments, pass)
    if isAdmin(player) then
        return pass() -- Fires Tracker.OnServerEvent
    end

    -- If it's not passed, Tracker.OnServerEvent will never fire.
    -- In this case: Nothing will be printed.
end)

EventTracker.rbxm (6.7 KB)

I’ve also uploaded a Gist so you can easily see exactly what has changed!
(gist diff)

1 Like

Just made some changes, the model should be updated now~
Im tired so Ill list the updates later lol

Update


New Properties:

  • ExcludeUsers: Excludes users that the Tracker applies too.
  • IsRemoteFunction: When true that means the Tracker is tracking a RemoteFunction

New Trackers

Remote Function Trackers
Remote function Trackers, similar to event Trackers, allow you to track the amount of times a remote function is fired to the server.

This can be created with:

EventTracker:TrackFunction(RemoteFunction,Params)

After that it acts about the same as a Event Tracker.
There are a couple different things to account for.

Properties

  • RemoteFunction: This is the RemoteFunction that the Tracker is tracking.
  • OnServerInvoke: This property is assigned to a function, which can be changed to a function you wish to be triggered.

Examples

local Tracker = EventTracker:TrackFunction(remoteFunction)

Tracker.OnServerInvoke = function(player:Player)
	return player.UserId
end