1
0
Эх сурвалжийг харах

Added chanset 'capsflood' (#8)

Mark 15 жил өмнө
parent
commit
83e2c8fbaf

+ 2 - 0
doc/UPDATES

@@ -1,3 +1,5 @@
+* Add chanset 'capslimit' to handle % of message that can be in caps before kick (#8)
+
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
   * Change +bitch reaction to use normal queue for deopping opper/opped clients

+ 1 - 0
src/chan.h

@@ -175,6 +175,7 @@ struct chanset_t {
   interval_t flood_mjoin_time;
   int flood_mjoin_thr;
   int limitraise;
+  int capslimit;
   int checklimit;
   int closed_ban;
   int closed_private;

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

@@ -422,6 +422,20 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan->invite_time = atoi(item[i]);
+    } else if (!strcmp(item[i], "capslimit") || !strcmp(item[i], "caps-limit")) {
+      i++;
+      if (i >= items) {
+        if (result)
+          strlcpy(result, "channel capslimit needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      int capslimit = atoi(item[i]);
+      if (capslimit > 100 || capslimit < 0 || item[i][0] == '-') {
+        if (result)
+          strlcpy(result, "channel capslimit out of range (0-100)", RESULT_LEN);
+        return ERROR;
+      }
+      chan->capslimit = capslimit;
     } else if (!strcmp(item[i], "closed-ban")) {
       i++;
       if (i >= items) {
@@ -1039,6 +1053,7 @@ int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan->flood_nick_time = gfld_nick_time;
     chan->flood_mjoin_thr = 6;
     chan->flood_mjoin_time = 1;
+    chan->capslimit = 0;
     chan->limitraise = 20;
     chan->ban_time = global_ban_time;
     chan->exempt_time = global_exempt_time;

+ 1 - 0
src/mod/channels.mod/cmdschan.c

@@ -1243,6 +1243,7 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Exempt-time: ", chan->exempt_time, NULL, "Forever");
     SHOW_INT("Flood-exempt: ", chan->flood_exempt_mode, F_STR(chan->flood_exempt_mode), "None");
     SHOW_INT("Flood-lock-time: ", chan->flood_lock_time, NULL, "Don't");
+    SHOW_INT("Caps-Limit(%): ", chan->capslimit, NULL, "None");
     SHOW_INT("Invite-time: ", chan->invite_time, NULL, "Forever");
     SHOW_INT("Knock: ", chan->knock_flags, F_STR(chan->knock_flags), "None");
     SHOW_INT("Limit raise (limit): ", chan->limitraise, NULL, "Disabled");

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

@@ -717,7 +717,7 @@ bd::String channel_to_string(struct chanset_t* chan, bool force_inactive) {
 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-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 \
+capslimit %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 \
 flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 %cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch %cfloodban \
@@ -744,6 +744,7 @@ flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
         chan->flood_deop_thr, chan->flood_deop_time,
 	chan->flood_nick_thr, chan->flood_nick_time,
 	chan->flood_mjoin_thr, chan->flood_mjoin_time,
+        chan->capslimit,
         chan->closed_ban,
 /* Chanint template
  *      chan->temp,
@@ -833,7 +834,7 @@ void write_chans_compat(bd::Stream& stream, int idx)
 bad-cookie %d manop %d mdop %d mop %d limit %d \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
-closed-ban %d closed-invite %d closed-private %d ban-time %d \
+capslimit %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 \
 %cenforcebans %cdynamicbans %cuserbans %cbitch \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
@@ -854,6 +855,7 @@ exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
         chan->flood_kick_thr, chan->flood_kick_time,
         chan->flood_deop_thr, chan->flood_deop_time,
 	chan->flood_nick_thr, chan->flood_nick_time,
+        chan->capslimit,
         chan->closed_ban,
         chan->closed_invite,
         chan->closed_private,

+ 5 - 5
src/mod/irc.mod/chan.c

@@ -3250,10 +3250,11 @@ static int gotmsg(char *from, char *msg)
     int botmatch = 0;
     char *my_msg = NULL, *my_ptr = NULL, *fword = NULL;
 
-#ifdef unfinished
-    if (me_op(chan) && doflood(chan))
-      detect_offense(m, chan, msg);
-#endif
+    if (me_op(chan) && doflood(chan)) {
+      if (detect_offense(m, chan, msg)) {
+        dprintf(DP_MODE, "KICK %s %s :%s (capsflood)\n", chan->name, nick, response(RES_FLOOD));
+      }
+    }
 
     /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */
     detect_chan_flood(nick, uhost, from, chan, FLOOD_PRIVMSG, NULL);
@@ -3268,7 +3269,6 @@ static int gotmsg(char *from, char *msg)
       /* is it a cmd? */
       if (auth_prefix[0] && fword && fword[0] && fword[1] && ((botmatch && fword[0] != auth_prefix[0]) || (fword[0] == auth_prefix[0]))) {
         Auth *auth = Auth::Find(uhost);
-
         if (auth && auth->Authed()) {
           if (fword[0] == auth_prefix[0])
             fword++;

+ 16 - 24
src/mod/irc.mod/irc.c

@@ -61,6 +61,8 @@
 
 #include <stdarg.h>
 
+#include <math.h>
+
 #define PRIO_DEOP 1
 #define PRIO_KICK 2
 
@@ -112,39 +114,29 @@ voice_ok(memberlist *m, struct chanset_t *chan)
 #include "cmdsirc.c"
 #include "msgcmds.c"
 
-#ifdef unfinished
-static void
+static int
 detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
 {
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   struct userrec *u = m->user ? m->user : get_user_by_host(m->userhost);
+  int tot = (int)strlen(msg);
   int i = 0;
-
-  //size_t tot = strlen(msg);
-
   get_user_flagrec(u, &fr, chan->dname, chan);
 
-  for (; *msg; ++msg) {
-    if (egg_isupper(*msg))
-      i++;
-  }
-
-/*  if ((chan->capslimit)) { */
-  while (((msg) && *msg)) {
-    if (egg_isupper(*msg))
-      i++;
-    msg++;
-  }
-
-/*
-  if (chan->capslimit && ((i / tot) >= chan->capslimit)) {
-dprintf(DP_MODE, "PRIVMSG %s :flood stats for %s: %d/%d are CAP, percentage: %d\n", chan->name, nick, i, tot, (i/tot)*100);
-  if ((((i / tot) * 100) >= 50)) {
-dprintf(DP_HELP, "PRIVMSG %s :cap flood.\n", chan->dname);
+  /* caps control. */
+  if (tot > 5 && chan->capslimit) { /* the caller checks for doflood so no need to check again here */
+    while (msg && *msg) {
+      if (egg_isupper(*msg))
+        i++;
+      msg++;
+    }
+    if (i && tot) {
+      if (((float)(i/tot))*100 >= chan->capslimit)
+        return 1;
+    }
   }
-*/
+  return 0;
 }
-#endif
 
 void unlock_chan(struct chanset_t *chan)
 {

+ 1 - 1
src/mod/irc.mod/irc.h

@@ -77,7 +77,7 @@ static void do_protect(struct chanset_t* chan, const char* reason);
 #define resetexempts(chan)  resetmasks((chan), (chan)->channel.exempt, (chan)->exempts, global_exempts, 'e')
 #define resetinvites(chan)  resetmasks((chan), (chan)->channel.invite, (chan)->invites, global_invites, 'I')
 
-//static void detect_offense(memberlist*, struct chanset_t *, char *);
+static int detect_offense(memberlist*, struct chanset_t *, char *);
 /* static int target_priority(struct chanset_t *, memberlist *, int); */
 static bool do_op(char *, struct chanset_t *, bool, bool);
 static void request_op(struct chanset_t *);