]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Make cmd and chat anti spam systems work during timeouts and make them work properly...
authorterencehill <piuntn@gmail.com>
Sat, 10 Aug 2024 09:05:51 +0000 (11:05 +0200)
committerterencehill <piuntn@gmail.com>
Sat, 10 Aug 2024 09:15:03 +0000 (11:15 +0200)
Chat anti spam code now works with flood time (.(flood_field)) initialized to 0, matching cmd anti spam code

qcsrc/server/chat.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc

index d37bdca9c060d4efd35eb5e6a3ec95ce767ab4e6..2aad1bcfd94005ff0ee8629f373a39995b62f02d 100644 (file)
@@ -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
index 150d73a6793012f7fcef196f788d022b1d97075c..0fd1442d65d10b86c017531e5e1c87b4bf491b9b 100644 (file)
@@ -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
        }
 
index c446664ec054ebeeeaa3f6ba3c4378d7410f4802..71da040ed31f204ae3be49d7e46696d6b1365b0d 100644 (file)
@@ -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;