Przeglądaj źródła

Merge branch 'maint'

* maint:
  Fix backwards logic for applying invites in -dynamicinvites channels.
  Fix bot not auto-opping after just connecting.
  do_op: Don't try (and fail) to op right away with a delay.
  add_mode: Pass memberlist pointer if possible
Bryan Drewery 10 lat temu
rodzic
commit
205c13b488

+ 2 - 0
doc/UPDATES.md

@@ -11,6 +11,8 @@
   * Fix binary compat issue causing ptrace permission errors on Linux 3.4+
   * Fix ban/exempt/invite masking not working with 10-char idents.
   * Fallback to ISON if the server falsely claims to support MONITOR.
+  * Fix bot not auto-opping after just connecting.
+  * Fix invites not being applied in -dynamicinvites channels when +i is set.
 
 # 1.4.6
   * Disable demo TCL support by default to prevent confusion during build.

+ 6 - 6
src/mod/irc.mod/chan.cc

@@ -447,7 +447,7 @@ static void priority_do(struct chanset_t * chan, bool opsonly, int action, bool
             if ((action == PRIO_DEOP) && !chan_sentdeop(m)) {
               ++actions;
               ++sent;
-              add_mode(chan, '-', 'o', m->nick);
+              add_mode(chan, '-', 'o', m);
               if (!floodless && (actions >= ct || (n == 1 && sent > 20))) {
                 if (flush)
                   flush_mode(chan, QUICK);
@@ -893,7 +893,7 @@ static void refresh_ban_kick(struct chanset_t* chan, memberlist *m, const char *
     for (maskrec* b = cycle ? chan->bans : global_bans; b; b = b->next) {
       if (wild_match(b->mask, user) || match_cidr(b->mask, user)) {
         if (role == 1 && chan_hasop(m))
-  	  add_mode(chan, '-', 'o', m->nick);	/* Guess it can't hurt.	*/
+          add_mode(chan, '-', 'o', m);	/* Guess it can't hurt.	*/
 	check_exemptlist(chan, user);
 	do_mask(chan, chan->channel.ban, b->mask, 'b');
 	b->lastactive = now;
@@ -1038,7 +1038,7 @@ static void recheck_invites(struct chanset_t *chan)
        * only) or invite is sticky.
        */
       if (!isinvited(chan, ir->mask) && ((!channel_dynamicinvites(chan) &&
-          !(chan->channel.mode & CHANINV)) || ir->flags & MASKREC_STICKY))
+          (chan->channel.mode & CHANINV)) || ir->flags & MASKREC_STICKY))
 	add_mode(chan, '+', 'I', ir->mask);
 	/* do_mask(chan, chan->channel.invite, ir->mask, 'I');*/
     }
@@ -1221,7 +1221,7 @@ static void check_this_member(struct chanset_t *chan, char *nick, struct flag_re
       (chk_deop(*fr, chan) ||
        (!loading && userlist && chan_bitch(chan) && !chk_op(*fr, chan)) ) ) {
     /* if (target_priority(chan, m, 1)) */
-      add_mode(chan, '-', 'o', m->nick);
+      add_mode(chan, '-', 'o', m);
   } else if (!chan_hasop(m) && dovoice(chan) && m->user && !u_pass_match(m->user, "-") && chk_autoop(*fr, chan)) {
     do_op(m, chan, 1, 0);
   }
@@ -1229,11 +1229,11 @@ static void check_this_member(struct chanset_t *chan, char *nick, struct flag_re
     if (chan_hasvoice(m) && !chan_hasop(m)) {
       /* devoice +q users .. */
       if (chk_devoice(*fr) || (channel_voicebitch(chan) && !chk_voice(*fr, chan)))
-        add_mode(chan, '-', 'v', m->nick);
+        add_mode(chan, '-', 'v', m);
     } else if (!chan_hasvoice(m) && !chan_hasop(m)) {
       /* voice +v users */
       if (chk_voice(*fr, chan)) {
-        add_mode(chan, '+', 'v', m->nick);
+        add_mode(chan, '+', 'v', m);
         if (m->flags & EVOICE)
           m->flags &= ~EVOICE;
       }

+ 5 - 5
src/mod/irc.mod/cmdsirc.cc

@@ -305,8 +305,8 @@ static void cmd_kickban(int idx, char *par)
       dprintf(idx, "%s is permanently exempted!\n", nick);
       return;
     }
-    if (m->flags & CHANOP)
-      add_mode(chan, '-', 'o', m->nick);
+    if (chan_hasop(m))
+      add_mode(chan, '-', 'o', m);
     check_exemptlist(chan, s);
     switch (bantype) {
       case '@':
@@ -396,7 +396,7 @@ static void cmd_voice(int idx, char *par)
       dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
       return;
     }
-    add_mode(chan, '+', 'v', nick);
+    add_mode(chan, '+', 'v', m);
     dprintf(idx, "Gave voice to %s on %s\n", nick, chan->dname);
     next:;
     if (!all)
@@ -459,7 +459,7 @@ static void cmd_devoice(int idx, char *par)
     return;
   }
 
-  add_mode(chan, '-', 'v', nick);
+  add_mode(chan, '-', 'v', m);
   dprintf(idx, "Devoiced %s on %s\n", nick, chan->dname);
   next:;
   if (!all)
@@ -1041,7 +1041,7 @@ static void cmd_deop(int idx, char *par)
       if (all) goto next;  
       return;
     }
-    add_mode(chan, '-', 'o', nick);
+    add_mode(chan, '-', 'o', m);
     dprintf(idx, "Deopped %s on %s.\n", nick, chan->dname);
     next:;
     if (!all)

+ 4 - 4
src/mod/irc.mod/irc.cc

@@ -212,7 +212,7 @@ void set_devoice(struct chanset_t *chan, memberlist* m) {
 const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason) {
   if (channel_voice(chan) && chan->voice_moderate) {
     if (!chan_sentdevoice(m)) {
-      add_mode(chan, '-', 'v', m->nick);
+      add_mode(chan, '-', 'v', m);
       m->flags |= SENTDEVOICE;
       set_devoice(chan, m);
       return "devoicing";
@@ -1599,11 +1599,11 @@ check_expired_chanstuff(struct chanset_t *chan)
                      (!channel_voice(chan) && !privchan(fr, chan, PRIV_VOICE) && chk_voice(fr, chan))
                     )
                    ) {
-                  add_mode(chan, '+', 'v', m->nick);
+                  add_mode(chan, '+', 'v', m);
                 }
               }
             } else if (!m->user && channel_voice(chan) && !channel_voicebitch(chan) && voice_ok(m, chan)) {
-              add_mode(chan, '+', 'v', m->nick);
+              add_mode(chan, '+', 'v', m);
             }
           }
         }
@@ -1698,7 +1698,7 @@ flush_modes()
         }
         if (chan_sentvoice(m)) {
           m->flags &= ~SENTVOICE;
-          add_mode(chan, '+', 'v', m->nick);
+          add_mode(chan, '+', 'v', m);
         }
       }
     }

+ 12 - 3
src/mod/irc.mod/irc.h

@@ -119,9 +119,18 @@ void join_chan(struct chanset_t* chan, int idx = DP_MODE);
 
 int check_bind_authc(char *, Auth *, char *, char *);
 void notice_invite(struct chanset_t *, char *, char *, char *, bool);
-void real_add_mode(struct chanset_t *, const char, const char, const char *, bool);
-#define add_mode(chan, pls, mode, nick) real_add_mode(chan, pls, mode, nick, 0)
-#define add_cookie(chan, nick) real_add_mode(chan, '+', 'o', nick, 1)
+void real_add_mode(struct chanset_t *, const char, const char, const char *, bool, memberlist *);
+inline void add_mode(struct chanset_t *chan, const char plus, const char mode,
+    const char *op)
+{
+  real_add_mode(chan, plus, mode, op, 0, NULL);
+}
+inline void add_mode(struct chanset_t *chan, const char plus, const char mode,
+    memberlist *m)
+{
+  real_add_mode(chan, plus, mode, m->nick, 0, m);
+}
+#define add_cookie(chan, member) real_add_mode(chan, '+', 'o', member->nick, 1, member)
 /* Check if I am a chanop. Returns boolean 1 or 0.
  */
 inline bool me_op(const struct chanset_t *chan)

+ 17 - 14
src/mod/irc.mod/mode.cc

@@ -101,12 +101,16 @@ do_op(memberlist *m, struct chanset_t *chan, bool delay, bool force)
   if (delay) {
     m->delay = now + chan->auto_delay;
     m->flags |= SENTOP;
+    return 1;
   }
 
   if (channel_fastop(chan) || channel_take(chan) || cookies_disabled) {
-    add_mode(chan, '+', 'o', m->nick);
+    add_mode(chan, '+', 'o', m);
   } else if (!connect_bursting) {
-    add_cookie(chan, m->nick);
+    add_cookie(chan, m);
+  } else {
+    /* Failed to give the mode, so requeue it. */
+    do_op(m, chan, 1, 0);
   }
   return 1;
 }
@@ -332,15 +336,14 @@ flush_mode(struct chanset_t *chan, int pri)
 /* Queue a channel mode change
  */
 void
-real_add_mode(struct chanset_t *chan, const char plus, const char mode, const char *op, bool cookie)
+real_add_mode(struct chanset_t *chan, const char plus, const char mode, const char *op, bool cookie, memberlist *mx)
 {
   if (!me_op(chan))
     return;
 
-  memberlist *mx = NULL;
-
   if (mode == 'o' || mode == 'v') {
-    mx = ismember(chan, op);
+    if (!mx)
+      mx = ismember(chan, op);
     if (!mx)
       return;
     if (plus == '-' && mode == 'o') {
@@ -599,7 +602,7 @@ got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
         m->flags |= SENTDEOP;
 #endif
       if (num == 5) {
-        add_mode(chan, '-', 'o', m->nick);
+        add_mode(chan, '-', 'o', m);
       } else if (bitch && num == 6) {
         len = simple_snprintf(outbuf, sizeof(outbuf), "KICK %s %s :%s\r\n", chan->name, mv->nick, response(RES_BITCHOPPED));
         mv->flags |= SENTKICK;
@@ -607,7 +610,7 @@ got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
         len = simple_snprintf(outbuf, sizeof(outbuf), "KICK %s %s :%s\r\n", chan->name, m->nick, response(RES_BITCHOP));
         m->flags |= SENTKICK;
       } else
-        add_mode(chan, '-', 'o', mv->nick);
+        add_mode(chan, '-', 'o', mv);
 
       if (len)
         dprintf_real(DP_MODE_NEXT, outbuf, len, sizeof(outbuf));
@@ -615,13 +618,13 @@ got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
 
 
   } else if (reversing && !me_opped)
-    add_mode(chan, '-', 'o', mv->nick);
+    add_mode(chan, '-', 'o', mv);
 
   /* server op */
   if (!m && meop && !me_opped) {
     if (chk_deop(victim, chan) || (chan_bitch(chan) && !chk_op(victim, chan))) {
       mv->flags |= FAKEOP;
-      add_mode(chan, '-', 'o', mv->nick);
+      add_mode(chan, '-', 'o', mv);
     } 
   }
   mv->flags |= WASOP;
@@ -1487,9 +1490,9 @@ gotmode(char *from, char *msg)
                 mv->flags |= CHANVOICE;
                 if (channel_active(chan) && dovoice(chan)) {
                   if (dv || chk_devoice(victim) || (channel_voicebitch(chan) && !chk_voice(victim, chan))) {
-                    add_mode(chan, '-', 'v', mparam);
+                    add_mode(chan, '-', 'v', mv);
                   } else if (reversing) {
-                    add_mode(chan, '-', 'v', mparam);
+                    add_mode(chan, '-', 'v', mv);
                   }
                 }
               } else if (msign == '-') {
@@ -1498,9 +1501,9 @@ gotmode(char *from, char *msg)
                 if (channel_active(chan) && dovoice(chan) && !chan_hasop(mv)) {
                   /* revoice +v users */
                   if (chk_voice(victim, chan)) {
-                    add_mode(chan, '+', 'v', mparam);
+                    add_mode(chan, '+', 'v', mv);
                   } else if (reversing) {
-                    add_mode(chan, '+', 'v', mparam);
+                    add_mode(chan, '+', 'v', mv);
                     /* if they arent +v|v and VOICER is m+ then EVOICE them */
                   } else {
                     if (!match_my_nick(nick) && channel_voice(chan) &&