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:
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!
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.
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?
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
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:
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)
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
Completely reworked the system now using custom types, and fixed some silly mistakes I made. A new post will be created regarding the new system, as this one is practically just filled with stuff from the old version, I also plan to create a an update log, along with better documents on what all the features do. So stay tuned for that to be released