Просмотр исходного кода

Merge branch '48-voice-updates' into next

* 48-voice-updates:
  Allow any user op (+o) to enable/disable EVOICE (#48)
  Properly log response to flood (#48)
  Document 'voice-moderate' (#48)
  Respect devoices from other bots (#48)
  Set EVOICE on abusive clients (#48)
  Implement devoicing on flood (#48)
  DRY flood punishment (#48)
  Auto set +m when 'voice-moderate' is set (#48)
  Auto unset 'voice-moderate' if 'chanmode -m' is set (#48)
  Add chanset 'voice-moderate' (#48)

Conflicts:
	doc/UPDATES
Bryan Drewery 14 лет назад
Родитель
Сommit
dd7965a0f2

+ 4 - 0
doc/UPDATES

@@ -2,6 +2,10 @@ next
   * Bot will now jump from the server it's on if it is removed from the server list. (fixes a changing network bug)
   * Bot will now jump from the server it's on if it is removed from the server list. (fixes a changing network bug)
   * Properly honor exemptions when kicking matched RBL clients
   * Properly honor exemptions when kicking matched RBL clients
   * Fix LASTON not being shared
   * Fix LASTON not being shared
+  * Bots now again respect devoices made by other bots and will not revoice those users.
+  * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
+  * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
+    This used to use +m to enforce/allowed revoicing.
 
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
 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.
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.

+ 2 - 0
doc/help.txt

@@ -437,6 +437,8 @@ See also: link%{+a}, newhub%{-}
                           channel is +protect.
                           channel is +protect.
         $bvoice-non-ident$b   If channel is +voice, clients without an ident will 
         $bvoice-non-ident$b   If channel is +voice, clients without an ident will 
                           be voiced. Set to 0 to not voice clients without ident.
                           be voiced. Set to 0 to not voice clients without ident.
+        $bvoice-moderate$b    If channel is +voice, auto set +m and devoice flooders
+                          instead of kicking them. Set to 0 to disable.
  
  
    The following options choose how to respond to specific events.
    The following options choose how to respond to specific events.
         Each can be set as any of the specified options.
         Each can be set as any of the specified options.

+ 1 - 0
src/chan.h

@@ -197,6 +197,7 @@ struct chanset_t {
   int closed_private;
   int closed_private;
   int closed_invite;
   int closed_invite;
   int closed_exempt_mode;
   int closed_exempt_mode;
+  int voice_moderate;
   deflag_t bad_cookie;
   deflag_t bad_cookie;
   deflag_t manop;
   deflag_t manop;
   deflag_t mdop;
   deflag_t mdop;

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

@@ -452,6 +452,16 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
         return ERROR;
       }
       }
       chan->closed_ban = atoi(item[i]);
       chan->closed_ban = atoi(item[i]);
+    } else if (!strcmp(item[i], "voice-moderate")) {
+      i++;
+      if (i >= items) {
+        if (result)
+          strlcpy(result, "channel voice-moderate needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan->voice_moderate = atoi(item[i]);
+      if (chan->mode_mns_prot & CHANMODER && chan->voice_moderate)
+        chan->voice_moderate = 0;
     } else if (!strcmp(item[i], "closed-invite")) {
     } else if (!strcmp(item[i], "closed-invite")) {
       i++;
       i++;
       if (i >= items) {
       if (i >= items) {
@@ -1082,6 +1092,7 @@ int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan->closed_ban = 0;
     chan->closed_ban = 0;
     chan->closed_private = 1;
     chan->closed_private = 1;
     chan->closed_invite = 1;
     chan->closed_invite = 1;
+    chan->voice_moderate = 1;
     chan->voice_non_ident = 1;
     chan->voice_non_ident = 1;
     chan->auto_delay = 5;
     chan->auto_delay = 5;
     chan->ban_type = 3;
     chan->ban_type = 3;

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

@@ -567,6 +567,9 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
 
 
   if (chan->mode_mns_prot & CHANINV && chan->closed_invite)
   if (chan->mode_mns_prot & CHANINV && chan->closed_invite)
     chan->closed_invite = 0;
     chan->closed_invite = 0;
+
+  if (chan->mode_mns_prot & CHANMODER && chan->voice_moderate)
+    chan->voice_moderate = 0;
 }
 }
 
 
 static void get_mode_protect(struct chanset_t *chan, char *s, size_t ssiz)
 static void get_mode_protect(struct chanset_t *chan, char *s, size_t ssiz)
@@ -790,6 +793,9 @@ void channels_report(int idx, int details)
         if (chan->closed_private)
         if (chan->closed_private)
           strlcat(s2, "p", sizeof(s2));
           strlcat(s2, "p", sizeof(s2));
       }
       }
+      if (channel_voice(chan) && chan->voice_moderate) {
+        strlcat(s2, "m", sizeof(s2));
+      }
 
 
       if (conf.bot->hub || shouldjoin(chan)) {
       if (conf.bot->hub || shouldjoin(chan)) {
 	if (channel_active(chan)) {
 	if (channel_active(chan)) {

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

@@ -1258,6 +1258,7 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Revenge: ", chan->revenge, DEFLAG_STR, "Ignore");
     SHOW_INT("Revenge: ", chan->revenge, DEFLAG_STR, "Ignore");
     SHOW_INT("Protect-backup: ", chan->protect_backup, "Do!", "Don't!");
     SHOW_INT("Protect-backup: ", chan->protect_backup, "Do!", "Don't!");
     SHOW_INT("Voice-non-ident: ", chan->voice_non_ident, "Do!", "Don't!");
     SHOW_INT("Voice-non-ident: ", chan->voice_non_ident, "Do!", "Don't!");
+    SHOW_INT("Voice-moderate:", chan->voice_moderate, NULL, "Don't!");
 
 
     dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n");
     dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n");
     dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d   %3d  %3d   %4d   %3d\n",
     dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d   %3d  %3d   %4d   %3d\n",

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

@@ -719,7 +719,7 @@ 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 \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 flood-mpub %d:%d flood-mbytes %d:%d flood-mctcp %d:%d \
 flood-mpub %d:%d flood-mbytes %d:%d flood-mctcp %d:%d \
 capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d closed-exempt %d ban-time %d \
 capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d closed-exempt %d ban-time %d \
-exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
+exempt-time %d invite-time %d voice-non-ident %d voice-moderate %d auto-delay %d \
 flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 %cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch %cfloodban \
 %cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch %cfloodban \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
@@ -763,6 +763,7 @@ flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
         chan->exempt_time,
         chan->exempt_time,
         chan->invite_time,
         chan->invite_time,
         chan->voice_non_ident,
         chan->voice_non_ident,
+        chan->voice_moderate,
         chan->auto_delay,
         chan->auto_delay,
         chan->flood_exempt_mode,
         chan->flood_exempt_mode,
         chan->flood_lock_time,
         chan->flood_lock_time,

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

@@ -738,9 +738,8 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
           char *s1 = quickban(chan, from);
           char *s1 = quickban(chan, from);
           u_addmask('b', chan, s1, conf.bot->nick, "channel flood", now + (60 * chan->ban_time), 0);
           u_addmask('b', chan, s1, conf.bot->nick, "channel flood", now + (60 * chan->ban_time), 0);
         } else {
         } else {
-          putlog(LOG_MODES, chan->dname, "Channel flood from %s -- kicking", m->nick);
-          dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, response(RES_FLOOD));
-          m->flags |= SENTKICK;
+          const char *response = punish_flooder(chan, m);
+          putlog(LOG_MODES, chan->dname, "Channel flood from %s -- %s", m->nick, response);
         }
         }
       }
       }
       return 1;
       return 1;
@@ -1129,6 +1128,10 @@ void recheck_channel_modes(struct chanset_t *chan)
       mns &= ~CHANPRIV;
       mns &= ~CHANPRIV;
     }
     }
   }
   }
+  if (channel_voice(chan) && chan->voice_moderate) {
+    pls |= CHANMODER;
+    mns &= ~CHANMODER;
+  }
 
 
   if (!(chan->ircnet_status & CHAN_ASKEDMODES)) {
   if (!(chan->ircnet_status & CHAN_ASKEDMODES)) {
     if (pls & CHANINV && !(cur & CHANINV))
     if (pls & CHANINV && !(cur & CHANINV))

+ 25 - 6
src/mod/irc.mod/irc.c

@@ -184,22 +184,41 @@ detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
   if (chan->capslimit && caps_count && tot >= 6) {
   if (chan->capslimit && caps_count && tot >= 6) {
     caps_percentage = (caps_count)/(double(tot));
     caps_percentage = (caps_count)/(double(tot));
     if (caps_percentage >= caps_limit) {
     if (caps_percentage >= caps_limit) {
-      putlog(LOG_MODES, chan->name, "Caps flood (%d%%) from %s -- kicking", int(caps_percentage * 100), m->nick);
-      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, response(RES_FLOOD));
-      m->flags |= SENTKICK;
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan->name, "Caps flood (%d%%) from %s -- %s", int(caps_percentage * 100), m->nick, response);
       return 1;
       return 1;
     }
     }
   } else if (chan->colorlimit && color_count) {
   } else if (chan->colorlimit && color_count) {
     if (color_count >= chan->colorlimit) {
     if (color_count >= chan->colorlimit) {
-      putlog(LOG_MODES, chan->name, "Color flood (%d) from %s -- kicking", color_count, m->nick);
-      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, response(RES_FLOOD));
-      m->flags |= SENTKICK;
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan->name, "Color flood (%d) from %s -- %s", color_count, m->nick, response);
       return 1;
       return 1;
     }
     }
   }
   }
   return 0;
   return 0;
 }
 }
 
 
+void set_devoice(struct chanset_t *chan, memberlist* m) {
+  if (!(m->flags & EVOICE)) {
+    putlog(LOG_DEBUG, "@", "Giving EVOICE flag to: %s (%s)", m->nick, chan->dname);
+    m->flags |= EVOICE;
+  }
+}
+
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason) {
+  if (channel_voice(chan) && chan->voice_moderate && !chan_sentdevoice(m)) {
+    add_mode(chan, '-', 'v', m->nick);
+    m->flags |= SENTDEVOICE;
+    set_devoice(chan, m);
+    return "devoicing";
+  } else if (!chan_sentkick(m)) {
+    dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, reason ? reason : response(RES_FLOOD));
+    m->flags |= SENTKICK;
+    return "kicking";
+  }
+  return "ignoring";
+}
+
 void unlock_chan(struct chanset_t *chan)
 void unlock_chan(struct chanset_t *chan)
 {
 {
   if (chan->channel.drone_set_mode) {
   if (chan->channel.drone_set_mode) {

+ 2 - 0
src/mod/irc.mod/irc.h

@@ -107,6 +107,8 @@ typedef struct resolvstruct resolv_member;
 void resolve_to_rbl(struct chanset_t *chan, const char *host, struct resolvstruct *r = NULL);
 void resolve_to_rbl(struct chanset_t *chan, const char *host, struct resolvstruct *r = NULL);
 static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode);
 static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode);
 static void get_channel_masks(struct chanset_t* chan);
 static void get_channel_masks(struct chanset_t* chan);
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason = NULL);
+void set_devoice(struct chanset_t* chan, memberlist* m);
 
 
 #endif /* MAKING_IRC */
 #endif /* MAKING_IRC */
 
 

+ 5 - 8
src/mod/irc.mod/mode.c

@@ -1482,8 +1482,7 @@ gotmode(char *from, char *msg)
 
 
               if (msign == '+') {
               if (msign == '+') {
                 if (mv->flags & EVOICE) {
                 if (mv->flags & EVOICE) {
-                  /* FIXME: This is a lame check, we need to expand on this more */
-                  if (!chan_master(user) && !glob_master(user) && !chk_voice(victim, chan)) {
+                  if (!chk_op(user, chan) && !chk_voice(victim, chan)) {
                     dv = 1;
                     dv = 1;
                   } else {
                   } else {
                     mv->flags &= ~EVOICE;
                     mv->flags &= ~EVOICE;
@@ -1509,14 +1508,12 @@ gotmode(char *from, char *msg)
                     add_mode(chan, '+', 'v', mparam);
                     add_mode(chan, '+', 'v', mparam);
                     /* if they arent +v|v and VOICER is m+ then EVOICE them */
                     /* if they arent +v|v and VOICER is m+ then EVOICE them */
                   } else {
                   } else {
-                    /* FIXME: same thing here */
-                    if (!match_my_nick(nick) && channel_voice(chan) && !glob_bot(user) &&
-                        (glob_master(user) || chan_master(user)) &&
+                    if (!match_my_nick(nick) && channel_voice(chan) &&
+                        (chk_op(user, chan) || glob_bot(user)) &&
                         rfc_casecmp(nick, mparam)) {
                         rfc_casecmp(nick, mparam)) {
                       /* if the user is not +q set them norEVOICE. */
                       /* if the user is not +q set them norEVOICE. */
-                      if (!chan_quiet(victim) && !(mv->flags & EVOICE)) {
-                        putlog(LOG_DEBUG, "@", "Giving EVOICE flag to: %s (%s)", mv->nick, chan->dname);
-                        mv->flags |= EVOICE;
+                      if (!chan_quiet(victim)) {
+                        set_devoice(chan, mv);
                       }
                       }
                     }
                     }
                   }
                   }