New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to limit client triggered events (via triggerServerEvent) #3251
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I didn't try my code. But i can simply implement token bucket in Lua: local UPDATE_INTERVAL = 100
local LIMIT_PER_SECOND = 100
local REFRESH_COUNT = LIMIT_PER_SECOND / 1000 * UPDATE_INTERVAL
local limitsData = {}
local function update()
for player, count in pairs(limitsData) do
local newCount = count + REFRESH_COUNT
if newCount > LIMIT_PER_SECOND then
limitsData[player] = LIMIT_PER_SECOND
else
limitsData[player] = newCount
end
end
end
setTimer(update, UPDATE_INTERVAL, 0)
local function init()
for _, player in pairs(getElementsByType("player")) do
limitsData[player] = LIMIT_PER_SECOND
end
end
init()
addEventHandler("onPlayerJoin", root, function()
limitsData[source] = LIMIT_PER_SECOND
end)
addEventHandler("onPlayerQuit", root, function()
limitsData[source] = nil
end)
addDebugHook("postEvent", function(sourceResource, eventName, eventSource, eventClient)
if eventClient then
local newCount = limitsData[eventClient] - 1
if newCount >= 0 then
limitsData[eventClient] = newCount
else
outputDebugString("Kick player during event spam. Latest event: " .. eventName, 3)
kickPlayer(eventClient, "Event spam")
end
end
end) |
You still have the problem that unregistered events and non-remotely triggerable events will not be caught by your code. |
tederis
reviewed
Nov 27, 2023
tederis
reviewed
Nov 27, 2023
tederis
reviewed
Nov 27, 2023
Dutchman101
pushed a commit
that referenced
this pull request
Nov 27, 2023
MTABot
pushed a commit
that referenced
this pull request
Nov 27, 2023
Dutchman101
pushed a commit
that referenced
this pull request
Nov 29, 2023
TracerDS
pushed a commit
to TracerDS/mtasa-blue
that referenced
this pull request
Feb 2, 2024
TracerDS
pushed a commit
to TracerDS/mtasa-blue
that referenced
this pull request
Feb 2, 2024
TracerDS
pushed a commit
to TracerDS/mtasa-blue
that referenced
this pull request
Feb 2, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently, one of the only ways to limit the amount of events being sent from the client to server (via triggerServerEvent) is to track the calls manually for every event handler you add (in Lua) which results in a valid
client
variable being set, upon the handler function being executed.That's fine for registered events (although a bit of a pain to add for every single event). However, unregistered events cannot be tracked this way. The only way to track unregistered events being called is by using
onDebugMessage
and catching a log entry such as below, which isn't ideal:This is also the same for events which do exist, but aren't remotely triggerable:
A client spamming serverside events can cause lag, so I've added a way to deal with this in MTA itself.
This PR adds a new serverside event,
onPlayerTriggerEventThreshold
, as well as two new mtaserver.conf settings:player_triggered_event_interval
max_player_triggered_events_per_interval
These options can be set using
setServerConfigSetting
in Lua, or directly via mtaserver.conf before server startup.Providing the player has triggered more than
max_player_triggered_events_per_interval
events perplayer_triggered_event_interval
time (in milliseconds), the event will be fired, giving full control to the server how they deal with such players (log, kick, ban, etc).This event counts ALL events triggered by the client, whether they are registered, unregistered or not remotely triggerable. Basically any usage of
triggerServerEvent
by the client will be counted.Usage is fairly self-explanatory:
I've also changed the way mtaserver.conf.template is loaded in the code, as adding these options took it over the 16,384 char string literal limit. That file will now be copied into the server deathmatch directory and read as XML directly, instead of
const char* szTemplateText = #include MTA_SERVER_CONF_TEMPLATE;
shiversAs it's currently possible for a client to abuse this event spamming, it's important that all server owners become aware of this and take necessary measures to implement (atleast) the example script above, once this PR has been merged.
Until then, I have attached a Lua script which will prevent unregistered events from being spammed (default max 10 per 500 ms). Feel free to export the
registerEventUsage
function and track your own registered events in other resources too.Download the resource/script here: events.zip