[MIRROR] ports topic and click limiting from tg (#9952)

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-01-26 15:21:23 -07:00
committed by GitHub
parent d6f7fd8ff4
commit 071e2c22a1
4 changed files with 128 additions and 0 deletions

View File

@@ -166,6 +166,22 @@
if(.) if(.)
Holiday = config_entry_value Holiday = config_entry_value
/datum/config_entry/number/minute_topic_limit
config_entry_value = 250
min_val = 0
/datum/config_entry/number/second_topic_limit
config_entry_value = 15
min_val = 0
/datum/config_entry/number/minute_click_limit
config_entry_value = 400
min_val = 0
/datum/config_entry/number/second_click_limit
config_entry_value = 15
min_val = 0
/datum/config_entry/number/fps /datum/config_entry/number/fps
default = 20 default = 20
integer = FALSE integer = FALSE

View File

@@ -82,6 +82,10 @@
var/mute_irc = 0 var/mute_irc = 0
var/ip_reputation = 0 //Do we think they're using a proxy/vpn? Only if IP Reputation checking is enabled in config. var/ip_reputation = 0 //Do we think they're using a proxy/vpn? Only if IP Reputation checking is enabled in config.
///Used for limiting the rate of topic sends by the client to avoid abuse
var/list/topiclimiter
///Used for limiting the rate of clicks sends by the client to avoid abuse
var/list/clicklimiter
//////////////////////////////////// ////////////////////////////////////
//things that require the database// //things that require the database//

View File

@@ -4,9 +4,21 @@
#define UPLOAD_LIMIT 10485760 //Restricts client uploads to the server to 10MB //Boosted this thing. What's the worst that can happen? #define UPLOAD_LIMIT 10485760 //Restricts client uploads to the server to 10MB //Boosted this thing. What's the worst that can happen?
#define MIN_CLIENT_VERSION 0 //Just an ambiguously low version for now, I don't want to suddenly stop people playing. #define MIN_CLIENT_VERSION 0 //Just an ambiguously low version for now, I don't want to suddenly stop people playing.
//I would just like the code ready should it ever need to be used. //I would just like the code ready should it ever need to be used.
#define LIMITER_SIZE 12
#define CURRENT_SECOND 1
#define SECOND_COUNT 2
#define CURRENT_MINUTE 3
#define MINUTE_COUNT 4
#define ADMINSWARNED_AT 5
//# define TOPIC_DEBUGGING 1 //# define TOPIC_DEBUGGING 1
/client/proc/reduce_minute_count()
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
if(topiclimiter[MINUTE_COUNT] > 0)
topiclimiter[MINUTE_COUNT] -= 1
/* /*
When somebody clicks a link in game, this Topic is called first. When somebody clicks a link in game, this Topic is called first.
It does the stuff in this proc and then is redirected to the Topic() proc for the src=[0xWhatever] It does the stuff in this proc and then is redirected to the Topic() proc for the src=[0xWhatever]
@@ -41,6 +53,38 @@
if (!asset_cache_job) if (!asset_cache_job)
return return
// Rate limiting
var/mtl = CONFIG_GET(number/minute_topic_limit)
if (!holder && mtl)
var/minute = round(world.time, 600)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
if (minute != topiclimiter[CURRENT_MINUTE])
topiclimiter[CURRENT_MINUTE] = minute
topiclimiter[MINUTE_COUNT] = 0
topiclimiter[MINUTE_COUNT] += 1
if (topiclimiter[MINUTE_COUNT] > mtl)
var/msg = "Your previous action was ignored because you've done too many in a minute."
if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
topiclimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
log_and_message_admins("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute", src)
to_chat(src, span_danger("[msg]"))
return
var/stl = CONFIG_GET(number/second_topic_limit)
if (!holder && stl && href_list["window_id"] != "statbrowser")
var/second = round(world.time, 10)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
if (second != topiclimiter[CURRENT_SECOND])
topiclimiter[CURRENT_SECOND] = second
topiclimiter[SECOND_COUNT] = 0
topiclimiter[SECOND_COUNT] += 1
if (topiclimiter[SECOND_COUNT] > stl)
to_chat(src, span_danger("Your previous action was ignored because you've done too many in a second"))
return
//search the href for script injection //search the href for script injection
if( findtext(href,"<script",1,0) ) if( findtext(href,"<script",1,0) )
to_world_log("Attempted use of scripts within a topic call, by [src]") to_world_log("Attempted use of scripts within a topic call, by [src]")
@@ -745,5 +789,50 @@
// Mouse stuff // Mouse stuff
/client/Click(atom/object, atom/location, control, params) /client/Click(atom/object, atom/location, control, params)
var/mcl = CONFIG_GET(number/minute_click_limit)
if (!holder && mcl)
var/minute = round(world.time, 600)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
if (minute != clicklimiter[CURRENT_MINUTE])
clicklimiter[CURRENT_MINUTE] = minute
clicklimiter[MINUTE_COUNT] = 0
clicklimiter[MINUTE_COUNT] += 1
if (clicklimiter[MINUTE_COUNT] > mcl)
var/msg = "Your previous click was ignored because you've done too many in a minute."
if (minute != clicklimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
clicklimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
log_and_message_admins("Has hit the per-minute click limit of [mcl] clicks in a given game minute", src)
to_chat(src, span_danger("[msg]"))
return
var/scl = CONFIG_GET(number/second_click_limit)
if (!holder && scl)
var/second = round(world.time, 10)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
if (second != clicklimiter[CURRENT_SECOND])
clicklimiter[CURRENT_SECOND] = second
clicklimiter[SECOND_COUNT] = 0
clicklimiter[SECOND_COUNT] += 1
if (clicklimiter[SECOND_COUNT] > scl)
to_chat(src, span_danger("Your previous click was ignored because you've done too many in a second"))
return
SEND_SIGNAL(src, COMSIG_CLIENT_CLICK, object, location, control, params, usr) SEND_SIGNAL(src, COMSIG_CLIENT_CLICK, object, location, control, params, usr)
. = ..() . = ..()
#undef ADMINSWARNED_AT
#undef CURRENT_MINUTE
#undef CURRENT_SECOND
#undef LIMITER_SIZE
#undef MINUTE_COUNT
#undef SECOND_COUNT

View File

@@ -243,6 +243,25 @@ SERVER your.domain:6000
## Remove the # to allow special 'Easter-egg' events on special holidays such as seasonal holidays and stuff like 'Talk Like a Pirate Day' :3 YAARRR ## Remove the # to allow special 'Easter-egg' events on special holidays such as seasonal holidays and stuff like 'Talk Like a Pirate Day' :3 YAARRR
ALLOW_HOLIDAYS ALLOW_HOLIDAYS
## TOPIC RATE LIMITING
## This allows you to limit how many topic calls (clicking on an interface window) the client can do in any given game second and/or game minute.
## Admins are exempt from these limits.
## Hitting the minute limit notifies admins.
## Set to 0 or comment out to disable.
SECOND_TOPIC_LIMIT 10
MINUTE_TOPIC_LIMIT 200
## CLICK RATE LIMITING
## Same as above, but applies to clicking on objects in the game window.
## This should be a higher then the interface limit to allow for the spam clickly nature of most battles.
## Admins are exempt from these limits.
## Hitting the minute limit notifies admins.
## Set to 0 to disable.
SECOND_CLICK_LIMIT 15
MINUTE_CLICK_LIMIT 400
##Defines the ticklag for the world. Ticklag is the amount of time between game ticks (aka byond ticks) (in 1/10ths of a second). ##Defines the ticklag for the world. Ticklag is the amount of time between game ticks (aka byond ticks) (in 1/10ths of a second).
## This also controls the client network update rate, as well as the default client fps ## This also controls the client network update rate, as well as the default client fps
TICKLAG 0.25 TICKLAG 0.25