From 59b16ff6511d719d368199b53472a83a3cb4e573 Mon Sep 17 00:00:00 2001 From: terencehill Date: Sat, 10 Aug 2024 11:05:51 +0200 Subject: [PATCH] Make cmd and chat anti spam systems work during timeouts and make them work properly at different game speed Chat anti spam code now works with flood time (.(flood_field)) initialized to 0, matching cmd anti spam code --- qcsrc/server/chat.qc | 16 ++++++++-------- qcsrc/server/command/cmd.qc | 33 +++++++++++++++------------------ qcsrc/server/command/common.qc | 5 ----- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/qcsrc/server/chat.qc b/qcsrc/server/chat.qc index d37bdca9c..2aad1bcfd 100644 --- a/qcsrc/server/chat.qc +++ b/qcsrc/server/chat.qc @@ -160,6 +160,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc string fullmsgstr = msgstr; string fullcmsgstr = cmsgstr; + float mod_time = 0; // FLOOD CONTROL int flood = 0; @@ -191,6 +192,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc flood_burst = max(0, flood_burst - 1); // to match explanation in default.cfg, a value of 3 must allow three-line bursts and not four! + mod_time = gettime(GETTIME_FRAMESTART) + flood_burst * flood_spl; // do flood control for the default line size if(msgstr != "") { @@ -210,9 +212,9 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc flood = 2; } - if (time >= source.(flood_field)) + if (mod_time >= source.(flood_field)) { - source.(flood_field) = max(time - flood_burst * flood_spl, source.(flood_field)) + lines * flood_spl; + source.(flood_field) = max(gettime(GETTIME_FRAMESTART), source.(flood_field)) + lines * flood_spl; } else { @@ -222,14 +224,11 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc } else { - if (time >= source.(flood_field)) - source.(flood_field) = max(time - flood_burst * flood_spl, source.(flood_field)) + flood_spl; + if (mod_time >= source.(flood_field)) + source.(flood_field) = max(gettime(GETTIME_FRAMESTART), source.(flood_field)) + flood_spl; else flood = 1; } - - if (timeout_status == TIMEOUT_ACTIVE) // when game is paused, no flood protection - source.(flood_field) = flood = 0; } string sourcemsgstr, sourcecmsgstr; @@ -276,7 +275,8 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc { if (autocvar_g_chat_flood_notify_flooder) { - sprint(source, strcat("^3CHAT FLOOD CONTROL: ^7wait ^1", ftos(source.(flood_field) - time), "^3 seconds\n")); + sprint(source, strcat("^3CHAT FLOOD CONTROL: ^7wait ^1", + ftos(source.(flood_field) - mod_time), "^3 seconds\n")); ret = 0; } else diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 150d73a67..0fd1442d6 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -1046,26 +1046,23 @@ void SV_ParseClientCommand(entity this, string command) // else fall through to default: flood control default: LABEL(flood_control) - if (!timeout_status) // not while paused + if(MUTATOR_CALLHOOK(ClientCommand_FloodControl, this, strtolower(argv(0)), argc, command)) + break; // a mutator has prevented flood control + + // this is basically the same as the chat flood control + entity store = IS_CLIENT(this) ? CS(this) : this; // unfortunately, we need to store these on the client initially + // NOTE: using mod_time instead of time here to avoid initializing both this.cmd_floodtime + // and CS(this).cmd_floodtime to -(antispam_count * antispam_time) (or -999999) + float mod_time = gettime(GETTIME_FRAMESTART) + autocvar_sv_clientcommand_antispam_count * autocvar_sv_clientcommand_antispam_time; + if (mod_time < store.cmd_floodtime) { - if(MUTATOR_CALLHOOK(ClientCommand_FloodControl, this, strtolower(argv(0)), argc, command)) - break; // a mutator has prevented flood control - - // this is basically the same as the chat flood control - entity store = IS_CLIENT(this) ? CS(this) : this; // unfortunately, we need to store these on the client initially - // NOTE: using mod_time instead of time here to avoid initializing both this.cmd_floodtime - // and CS(this).cmd_floodtime to -(antispam_count * antispam_time) (or -999999) - float mod_time = time + autocvar_sv_clientcommand_antispam_count * autocvar_sv_clientcommand_antispam_time; - if (mod_time < store.cmd_floodtime) - { - sprint(this, strcat("^3CMD FLOOD CONTROL: wait ^1", ftos(store.cmd_floodtime - mod_time), - "^3 seconds, command was: ", command, "\n")); - return; // too much spam, halt - } - else - // micro-optimization: replaced mod_time - max_delay with time here as they are equal - store.cmd_floodtime = max(time, store.cmd_floodtime) + autocvar_sv_clientcommand_antispam_time; + sprint(this, strcat("^3CMD FLOOD CONTROL: wait ^1", ftos(store.cmd_floodtime - mod_time), + "^3 seconds, command was: ", command, "\n")); + return; // too much spam, halt } + else + // micro-optimization: replaced mod_time - max_delay with time here as they are equal + store.cmd_floodtime = max(gettime(GETTIME_FRAMESTART), store.cmd_floodtime) + autocvar_sv_clientcommand_antispam_time; break; // continue, as we're not flooding yet } diff --git a/qcsrc/server/command/common.qc b/qcsrc/server/command/common.qc index c446664ec..71da040ed 100644 --- a/qcsrc/server/command/common.qc +++ b/qcsrc/server/command/common.qc @@ -244,11 +244,6 @@ void timeout_handler_think(entity this) // set the slowmo value to the timeout default slowmo value cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE)); - // reset all the flood variables - FOREACH_CLIENT(true, { - it.floodcontrol_chat = it.floodcontrol_chatteam = it.floodcontrol_chattell = 0; - }); - // copy .v_angle to .lastV_angle for every player in order to fix their view during pause (see PlayerPreThink) FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { it.lastV_angle = it.v_angle; -- 2.39.2