Add a spam limiter to the goonchat topic calls (#48524)

This commit is contained in:
oranges
2020-01-03 15:21:00 -05:00
committed by Emmett Gaines
parent b4e84ddadf
commit 591eac4367
2 changed files with 41 additions and 11 deletions
+31 -1
View File
@@ -5,9 +5,16 @@ For the main html chat area
//Precaching a bunch of shit
GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output
//Should match the value set in the browser js
#define MAX_COOKIE_LENGTH 5
//On client, created on login
/datum/chatOutput
var/client/owner //client ref
// How many times client data has been checked
var/total_checks = 0
// When to next clear the client data checks counter
var/next_time_to_clear = 0
var/loaded = FALSE // Has the client loaded the browser output area?
var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do
var/cookieSent = FALSE // Has the client sent a cookie for analysis
@@ -172,6 +179,18 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
//Called by client, sent data to investigate (cookie history so far)
/datum/chatOutput/proc/analyzeClientData(cookie = "")
//Spam check
if(world.time > next_time_to_clear)
next_time_to_clear = world.time + (3 SECONDS)
total_checks = 0
total_checks += 1
if(total_checks > SPAM_TRIGGER_AUTOMUTE)
message_admins("[key_name(owner)] kicked for goonchat topic spam")
qdel(owner)
return
if(!cookie)
return
@@ -180,17 +199,26 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if (connData && islist(connData) && connData.len > 0 && connData["connData"])
connectionHistory = connData["connData"] //lol fuck
var/list/found = new()
if(connectionHistory.len > MAX_COOKIE_LENGTH)
message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)")
qdel(owner)
return
for(var/i in connectionHistory.len to 1 step -1)
if(QDELETED(owner))
//he got cleaned up before we were done
return
var/list/row = src.connectionHistory[i]
if (!row || row.len < 3 || (!row["ckey"] || !row["compid"] || !row["ip"])) //Passed malformed history object
return
if (world.IsBanned(row["ckey"], row["ip"], row["compid"], real_bans_only=TRUE))
found = row
break
CHECK_TICK
//Uh oh this fucker has a history of playing on a banned account!!
if (found.len > 0)
//TODO: add a new evasion ban for the CURRENT client details, using the matched row details
message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])")
log_admin_private("[key_name(owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])")
@@ -269,3 +297,5 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
/datum/chatOutput/proc/swaptodarkmode()
owner.force_dark_theme()
#undef MAX_COOKIE_LENGTH
@@ -29,7 +29,7 @@ var opts = {
'scrollSnapTolerance': 10, //If within x pixels of bottom
'clickTolerance': 10, //Keep focus if outside x pixels of mousedown position on mouseup
'imageRetryDelay': 50, //how long between attempts to reload images (in ms)
'imageRetryLimit': 50, //how many attempts should we make?
'imageRetryLimit': 50, //how many attempts should we make?
'popups': 0, //Amount of popups opened ever
'wasd': false, //Is the user in wasd mode?
'priorChatHeight': 0, //Thing for height-resizing detection
@@ -67,7 +67,7 @@ var opts = {
'updatedVolume': 0, //The volume level that is sent to the server
'musicStartAt': 0, //The position the music starts playing
'musicEndAt': 0, //The position the music... stops playing... if null, doesn't apply (so the music runs through)
'defaultMusicVolume': 25,
'messageCombining': true,
@@ -161,7 +161,7 @@ function byondDecode(message) {
// The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b.
// Marvelous.
message = message.replace(/\+/g, "%20");
try {
try {
// This is a workaround for the above not always working when BYOND's shitty url encoding breaks. (byond bug id:2399401)
if (decodeURIComponent) {
message = decodeURIComponent(message);
@@ -494,8 +494,8 @@ function handleClientData(ckey, ip, compid) {
return; //Record already exists
}
}
if (opts.clientData.length >= opts.clientDataLimit) {
//Lets make sure we obey our limit (can connect from server with higher limit)
while (opts.clientData.length >= opts.clientDataLimit) {
opts.clientData.shift();
}
} else {
@@ -784,7 +784,7 @@ $(function() {
else{
$('#adminMusic').prop('volume', opts.defaultMusicVolume / 100);
}
if (savedConfig.smessagecombining) {
if (savedConfig.smessagecombining == 'false') {
opts.messageCombining = false;
@@ -1100,7 +1100,7 @@ $(function() {
$messages.empty();
opts.messageCount = 0;
});
$('#musicVolumeSpan').hover(function() {
$('#musicVolumeText').addClass('hidden');
$('#musicVolume').removeClass('hidden');
@@ -1127,9 +1127,9 @@ $(function() {
});
$('img.icon').error(iconError);
/*****************************************
*