Procházet zdrojové kódy

Merge branch '42-flood-chan-bytes'

* 42-flood-chan-bytes:
  Implement chanset 'flood-bytes' (#42)
  Add chanset 'flood-bytes' (#42)

Conflicts:
	doc/UPDATES
Bryan Drewery před 14 roky
rodič
revize
5cd0f27149

+ 1 - 0
doc/UPDATES

@@ -38,6 +38,7 @@
   * Bots now request/join +ilk channels much quicker
   * Add 'chanset revenge' which will react/kick/ban/remove users who kick/ban/deop bots.
   * Fix flood kicking not properly tracking multiple clients at once (#43)
+  * Add chanset 'flood-bytes' to count how many bytes:second a user sends before getting kicked for flood. (#42)
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
   * Fix various compile warnings with newer GCC

+ 3 - 0
doc/help.txt

@@ -541,6 +541,9 @@ See also: link%{+a}, newhub%{-}
         $bflood-chan$b  Set here how many channel messages in how many seconds
                     from one host constitutes a flood. Setting this to 0 or 0:0
                     disables text flood protection for the channel.
+        $bflood-bytes$b  Set here how many bytes in how many seconds from one
+                    host constitutes a flood. Setting this to 0 or 0:0
+                    disables text flood protection for the channel.
         $bflood-ctcp$b  Set here how many channel ctcps in how many seconds from
                     one host constitutes a flood. Setting this to 0 or 0:0
                     disables ctcp flood protection for the channel.

+ 2 - 0
src/chan.h

@@ -168,6 +168,8 @@ struct chanset_t {
   uint32_t ircnet_status;
   int flood_pub_thr;
   interval_t flood_pub_time;
+  int flood_bytes_thr;
+  interval_t flood_bytes_time;
   int flood_join_thr;
   interval_t flood_join_time;
   int flood_deop_thr;

+ 3 - 2
src/eggdrop.h

@@ -135,7 +135,8 @@ enum flood_t {
   FLOOD_JOIN     = 4,
   FLOOD_KICK     = 5,
   FLOOD_DEOP     = 6,
-  FLOOD_PART     = 7
+  FLOOD_PART     = 7,
+  FLOOD_BYTES    = 8
 };
 
 
@@ -151,7 +152,7 @@ template<>
   };
 BDLIB_NS_END
 
-#define FLOOD_CHAN_MAX   8
+#define FLOOD_CHAN_MAX   9
 #define FLOOD_GLOBAL_MAX 3
 
 #define FEATURE_1		BIT0

+ 7 - 0
src/mod/channels.mod/chanmisc.c

@@ -767,6 +767,8 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
 
         chan->flood_pub_thr = thr;
         chan->flood_pub_time = time;
+        chan->flood_bytes_thr = thr;
+        chan->flood_bytes_time = time;
         chan->flood_join_thr = thr;
         chan->flood_join_time = time;
         chan->flood_ctcp_thr = thr;
@@ -782,6 +784,9 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       } else if (!strcmp(item[i] + 6, "chan")) {
 	pthr = &chan->flood_pub_thr;
 	ptime = &chan->flood_pub_time;
+      } else if (!strcmp(item[i] + 6, "bytes")) {
+	pthr = &chan->flood_bytes_thr;
+	ptime = &chan->flood_bytes_time;
       } else if (!strcmp(item[i] + 6, "join")) {
 	pthr = &chan->flood_join_thr;
 	ptime = &chan->flood_join_time;
@@ -1037,6 +1042,8 @@ int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan->flood_exempt_mode = 0;
     chan->flood_pub_thr = gfld_chan_thr;
     chan->flood_pub_time = gfld_chan_time;
+    chan->flood_bytes_thr = gfld_bytes_thr;
+    chan->flood_bytes_time = gfld_bytes_time;
     chan->flood_ctcp_thr = gfld_ctcp_thr;
     chan->flood_ctcp_time = gfld_ctcp_time;
     chan->flood_join_thr = gfld_join_thr;

+ 2 - 0
src/mod/channels.mod/channels.c

@@ -64,6 +64,8 @@ static char *lastdeletedmask = NULL;
 /* Global flood settings */
 static int 			gfld_chan_thr;
 static interval_t 		gfld_chan_time;
+static int 			gfld_bytes_thr;
+static interval_t 		gfld_bytes_time;
 static int 			gfld_deop_thr = 8;
 static interval_t 		gfld_deop_time = 10;
 static int 			gfld_kick_thr;

+ 5 - 5
src/mod/channels.mod/cmdschan.c

@@ -1257,14 +1257,14 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Protect-backup: ", chan->protect_backup, "Do!", "Don't!");
     SHOW_INT("Voice-non-ident: ", chan->voice_non_ident, "Do!", "Don't!");
 
-    dprintf(idx, "Flood settings:   chan ctcp join kick deop nick mjoin\n");
-    dprintf(idx, "  number:          %3d  %3d  %3d  %3d  %3d  %3d  %3d\n",
-	    chan->flood_pub_thr, chan->flood_ctcp_thr,
+    dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin\n");
+    dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d  %3d\n",
+	    chan->flood_pub_thr, chan->flood_bytes_thr, chan->flood_ctcp_thr,
 	    chan->flood_join_thr, chan->flood_kick_thr,
 	    chan->flood_deop_thr, chan->flood_nick_thr,
             chan->flood_mjoin_thr);
-    dprintf(idx, "  time  :          %3u  %3u  %3u  %3u  %3u  %3u  %3u\n",
-	    chan->flood_pub_time, chan->flood_ctcp_time,
+    dprintf(idx, "  time  :          %3u  %4u  %3u  %3u  %3u  %3u  %3u  %3u\n",
+	    chan->flood_pub_time, chan->flood_bytes_time, chan->flood_ctcp_time,
 	    chan->flood_join_time, chan->flood_kick_time,
 	    chan->flood_deop_time, chan->flood_nick_time,
             chan->flood_mjoin_time);

+ 2 - 1
src/mod/channels.mod/userchan.c

@@ -715,7 +715,7 @@ bd::String channel_to_string(struct chanset_t* chan, bool force_inactive) {
   get_mode_protect(chan, w, sizeof(w));
   return bd::String::printf("\
 chanmode { %s } groups { %s } bad-cookie %d manop %d mdop %d mop %d limit %d revenge %d ban-type %d \
-flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
+flood-chan %d:%d flood-bytes %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 closed-ban %d closed-invite %d closed-private %d ban-time %d \
 exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
@@ -738,6 +738,7 @@ flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
         chan->limitraise,
         chan->ban_type,
 	chan->flood_pub_thr, chan->flood_pub_time,
+	chan->flood_bytes_thr, chan->flood_bytes_time,
         chan->flood_ctcp_thr, chan->flood_ctcp_time,
         chan->flood_join_thr, chan->flood_join_time,
         chan->flood_kick_thr, chan->flood_kick_time,

+ 19 - 6
src/mod/irc.mod/chan.c

@@ -574,8 +574,9 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
       )))
     return 0;
 
-  char h[UHOSTLEN] = "", ftype[12] = "", *p = NULL;
+  char h[UHOSTLEN] = "", ftype[14] = "", *p = NULL;
   int thr = 0;
+  int increment = 1;
   time_t lapse = 0;
 
   /* Determine how many are necessary to make a flood. */
@@ -586,6 +587,12 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
     lapse = chan->flood_pub_time;
     strlcpy(ftype, "pub", sizeof(ftype));
     break;
+  case FLOOD_BYTES:
+    thr = chan->flood_bytes_thr;
+    lapse = chan->flood_bytes_time;
+    strlcpy(ftype, "bytes", sizeof(ftype));
+    increment = static_cast<int>(strlen(msg));
+    break;
   case FLOOD_CTCP:
     thr = chan->flood_ctcp_thr;
     lapse = chan->flood_ctcp_time;
@@ -637,7 +644,7 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
       // If not found, add them and start the count for next iteration
       if (!chan->channel.floodtime->contains(m->userhost)) {
         (*chan->channel.floodtime)[m->userhost][which] = now;
-        (*chan->channel.floodnum)[m->userhost][which] = 1;
+        (*chan->channel.floodnum)[m->userhost][which] = increment;
         return 0;
       } else {
         floodtime = &(*chan->channel.floodtime)[m->userhost];
@@ -649,7 +656,7 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
       // If not found, add them and start the count for next iteration
       if (!m->floodtime->contains(which)) {
         (*m->floodtime)[which] = now;
-        (*m->floodnum)[which] = 1;
+        (*m->floodnum)[which] = increment;
         return 0;
       } else {
         floodtime = m->floodtime;
@@ -661,10 +668,11 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
   if ((*floodtime)[which] < now - lapse) {
     /* Flood timer expired, reset it */
     (*floodtime)[which] = now;
-    (*floodnum)[which] = 1;
+    (*floodnum)[which] = increment;
     return 0;
   }
-  (*floodnum)[which]++;
+  (*floodnum)[which] += increment;
+
   if ((*floodnum)[which] >= thr) {	/* FLOOD */
     /* Reset counters */
     (*floodnum).remove(which);
@@ -673,6 +681,7 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
     case FLOOD_PRIVMSG:
     case FLOOD_NOTICE:
     case FLOOD_CTCP:
+    case FLOOD_BYTES:
       /* Flooding chan! either by public or notice */
       if (!chan_sentkick(m) && me_op(chan)) {
         if (channel_floodban(chan)) {
@@ -705,7 +714,7 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
 	putlog(LOG_MISC | LOG_JOIN, chan->dname, "JOIN flood from @%s!  Banning.", p);
       else
 	putlog(LOG_MISC | LOG_JOIN, chan->dname, "NICK flood from @%s!  Banning.", p);
-      strlcpy(ftype + 4, " flood", sizeof(ftype) - 4);
+      strlcat(ftype, " flood", sizeof(ftype));
       u_addmask('b', chan, h, conf.bot->nick, ftype, now + (60 * chan->ban_time), 0);
       if (which == FLOOD_PART)
         add_mode(chan, '+', 'b', h);
@@ -3203,6 +3212,7 @@ static int gotmsg(char *from, char *msg)
       strcpy(p1 - 1, p + 1);
       if (m) {
         detect_chan_flood(m, from, chan, strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
+        detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
       }
 
       /* Respond to the first answer_ctcp */
@@ -3254,6 +3264,7 @@ static int gotmsg(char *from, char *msg)
 
     if (m) {
       detect_chan_flood(m, from, chan, FLOOD_PRIVMSG);
+      detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
     }
     
     if (auth_chan) {
@@ -3350,6 +3361,7 @@ static int gotnotice(char *from, char *msg)
       p = strchr(msg, 1);
       if (m) {
         detect_chan_flood(m, from, chan, strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
+        detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
       }
 
       if (ctcp[0] != ' ') {
@@ -3369,6 +3381,7 @@ static int gotnotice(char *from, char *msg)
   if (msg[0]) {
     if (m) {
       detect_chan_flood(m, from, chan, FLOOD_NOTICE);
+      detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
     }
 
     update_idle(chan->dname, nick);