Browse Source

Merge branch '35-speedup-request' into next

* 35-speedup-request:
  Only request_op() every few minutes if not already opped, and bots are opped (#35)
  Avoid unused cycling code
  Unset channel.do_opreq after first try
  Inline me_op()
  If another bot is opped, ask them for ops (#35)
  Avoid looping in any_ops() at end of /WHO to request ops (#35)
  Only reop if the victim was already an op
  No reason to request op in an opless channel (#35)
  Only reop if role 3 (#35)
  Don't auto reop if another bot deopped the victim (#35)
  Auto reop bots to speedup opping (#35)
  Cleanup reversing check
  No need to request_op every 5 seconds (#35)

Conflicts:
	doc/UPDATES
Bryan Drewery 14 years ago
parent
commit
7942bfe624
5 changed files with 65 additions and 56 deletions
  1. 2 0
      doc/UPDATES
  2. 7 1
      src/mod/irc.mod/chan.c
  3. 21 47
      src/mod/irc.mod/irc.c
  4. 9 1
      src/mod/irc.mod/irc.h
  5. 26 7
      src/mod/irc.mod/mode.c

+ 2 - 0
doc/UPDATES

@@ -3,6 +3,8 @@ next
   * Properly honor exemptions when kicking matched RBL clients
   * Fix LASTON not being shared
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
+  * Bots now auto-reop other bots that get deopped
+  * Bots now ask for ops quicker if another bot is opped
 
 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.

+ 7 - 1
src/mod/irc.mod/chan.c

@@ -1961,6 +1961,11 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
       resolve_to_rbl(chan, m->userip);
   }
 
+  // If there's an opped bot, queue op to request_op
+  if (m->user && m->user->bot && chan_hasop(m)) {
+    chan->channel.do_opreq = 1;
+  }
+
   return 0;
 }
 
@@ -2075,8 +2080,9 @@ static int got315(char *from, char *msg)
       recheck_channel(chan, 2);
     else if (chan->channel.members == 1)
       chan->ircnet_status |= CHAN_STOP_CYCLE;
-    else if (any_ops(chan))
+    else if (chan->channel.do_opreq) {
       request_op(chan);
+    }
   }
   /* do not check for i-lines here. */
   return 0;

+ 21 - 47
src/mod/irc.mod/irc.c

@@ -816,8 +816,10 @@ getin_request(char *botnick, char *code, char *par)
 static void
 request_op(struct chanset_t *chan)
 {
-  if (!chan || (chan && (channel_pending(chan) || !shouldjoin(chan) || !channel_active(chan) || me_op(chan))))
+  if (!chan || (chan && (channel_pending(chan) || !shouldjoin(chan) || !channel_active(chan) || me_op(chan)))) {
+    chan->channel.do_opreq = 0;
     return;
+  }
 
   if (chan->channel.no_op) {
     if (chan->channel.no_op > now)      /* dont op until this time has passed */
@@ -826,7 +828,6 @@ request_op(struct chanset_t *chan)
       chan->channel.no_op = 0;
   }
 
-  chan->channel.do_opreq = 0;
   /* check server lag */
   if (server_lag > lag_threshold) {
     putlog(LOG_GETIN, "*", "Not asking for ops on %s - I'm too lagged", chan->dname);
@@ -1276,21 +1277,6 @@ killmember(struct chanset_t *chan, char *nick)
   return 1;
 }
 
-/* Check if I am a chanop. Returns boolean 1 or 0.
- */
-bool
-me_op(const struct chanset_t *chan)
-{
-  memberlist *mx = ismember(chan, botname);
-
-  if (!mx)
-    return 0;
-  if (chan_hasop(mx))
-    return 1;
-  else
-    return 0;
-}
-
 /* Check whether I'm voice. Returns boolean 1 or 0.
  */
 bool
@@ -1423,8 +1409,6 @@ check_lonely_channel(struct chanset_t *chan)
       !shouldjoin(chan) || (chan->channel.mode & CHANANON))
     return;
 
-  memberlist *m = NULL;
-  char s[UHOSTLEN] = "";
   static int whined = 0;
 
   if ((chan->channel.members - chan->channel.splitmembers) == 1 && channel_cycle(chan) && !channel_stop_cycle(chan)) {
@@ -1436,15 +1420,10 @@ check_lonely_channel(struct chanset_t *chan)
     }
   } else if (any_ops(chan)) {
     whined = 0;
-    request_op(chan);
-/* need: op */
   } else {
     /* Other people here, but none are ops. If there are other bots make
      * them LEAVE!
      */
-    bool ok = 1;
-    struct userrec *u = NULL;
-
     if (!whined) {
       /* + is opless. Complaining about no ops when without special
        * help(services), we cant get them - Raist
@@ -1453,10 +1432,14 @@ check_lonely_channel(struct chanset_t *chan)
         putlog(LOG_MISC, "*", "%s is active but has no ops :(", chan->dname);
       whined = 1;
     }
+#ifdef disabled
+    memberlist *m = NULL;
+    bool ok = 1;
+
     for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
-      simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
-      u = get_user_by_host(s);
-      if (!m->is_me && (!u || !u->bot)) {
+      member_getuser(m, 0);
+
+      if (!m->is_me && (!m->user || !m->user->bot)) {
         ok = 0;
         break;
       }
@@ -1468,11 +1451,8 @@ check_lonely_channel(struct chanset_t *chan)
 	if (!m->is_me)
 	  dprintf(DP_SERVER, "PRIVMSG %s :go %s\n", m->nick, chan->dname);
 */
-    } else {
-      /* Some humans on channel, but still op-less */
-      request_op(chan);
-/* need: op */
     }
+#endif
   }
 }
 
@@ -1622,10 +1602,11 @@ check_expired_chanstuff(struct chanset_t *chan)
       }
     } /* me_op */
 
-//    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
-    int splitmembers = 0;
+    size_t splitmembers = 0, bot_ops = 0;
+    const bool im_opped = me_op(chan);
     for (m = chan->channel.member; m && m->nick[0]; m = n) {
       n = m->next;
+      // Update split members
       if (m->split) {
         ++splitmembers;
         if (now - m->split > wait_split) {
@@ -1648,7 +1629,7 @@ check_expired_chanstuff(struct chanset_t *chan)
         }
       }
 
-      if (me_op(chan)) {
+      if (im_opped) {
         if (dovoice(chan) && !loading) {      /* autovoice of +v users if bot is +y */
           if (!chan_hasop(m) && !chan_hasvoice(m) && !chan_sentvoice(m)) {
             member_getuser(m, 1);
@@ -1673,11 +1654,17 @@ check_expired_chanstuff(struct chanset_t *chan)
           }
         }
       }
+      if (m->user && m->user->bot) {
+        ++bot_ops;
+      }
       m = n;
     }
     // Update minutely
     chan->channel.splitmembers = splitmembers;
     check_lonely_channel(chan);
+    if (bot_ops && !im_opped) {
+      request_op(chan);
+    }
   }
 }
 
@@ -1801,23 +1788,10 @@ static cmd_t irc_bot[] = {
   {NULL, NULL, NULL, NULL, 0}
 };
 
-static void
-getin_5secondly()
-{
-  if (!server_online)
-    return;
-
-  for (register struct chanset_t *chan = chanset; chan; chan = chan->next) {
-    if ((!channel_pending(chan) && channel_active(chan)) && !me_op(chan))
-      request_op(chan);
-  }
-}
-
 void
 irc_init()
 {
   timer_create_secs(60, "irc_minutely", (Function) irc_minutely);
-  timer_create_secs(5, "getin_5secondly", (Function) getin_5secondly);
 
   /* Add our commands to the imported tables. */
   add_builtins("dcc", irc_dcc);

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

@@ -7,6 +7,7 @@
 #define _EGG_MOD_IRC_IRC_H
 
 #include "src/auth.h"
+#include "src/chanprog.h"
 
 enum { BC_NOCOOKIE = 1, BC_SLACK, BC_HASH, BC_COUNTER };
 
@@ -117,7 +118,14 @@ 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)
-bool me_op(const struct chanset_t *);
+/* Check if I am a chanop. Returns boolean 1 or 0.
+ */
+inline bool me_op(const struct chanset_t *chan)
+{
+  const memberlist *mx = ismember(chan, botname);
+  return mx && chan_hasop(mx);
+}
+
 bool me_voice(const struct chanset_t *);
 
 void check_this_ban(struct chanset_t *, char *, bool);

+ 26 - 7
src/mod/irc.mod/mode.c

@@ -557,7 +557,14 @@ got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
     meop = 1;
   }
 
-  get_user_flagrec(mv->user, &victim, chan->dname, chan);
+  if (mv->user) {
+    get_user_flagrec(mv->user, &victim, chan->dname, chan);
+
+    // Did some other bot just get opped, and I'm not opped yet?
+    if (mv->user->bot && !me_opped && !meop) {
+      chan->channel.do_opreq = 1;
+    }
+  }
   /* Flags need to be set correctly right from the beginning now, so that
    * add_mode() doesn't get irritated.
    */
@@ -647,11 +654,14 @@ got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
 
   if (mdop_reversing && !was_op)
     return;
-  
+
+  /* m is NULL if a server made the change */
   if (m)
     simple_snprintf(s1, sizeof(s1), "%s!%s", m->nick, m->userhost);
 
-  get_user_flagrec(mv->user, &victim, chan->dname, chan);
+  if (mv->user) {
+    get_user_flagrec(mv->user, &victim, chan->dname, chan);
+  }
 
   /* Flags need to be set correctly right from the beginning now, so that
    * add_mode() doesn't get irritated.
@@ -666,12 +676,21 @@ got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
   /* Deop'd someone on my oplist? */
   if (me_op(chan)) {
     /* do we want to reop victim? */
-    if ((reversing) && 
-        ((m && !m->is_me && rfc_casecmp(mv->nick, m->nick)) || (!m)) &&
-        !mv->is_me &&
-        (chk_op(victim, chan) || !chan_bitch(chan)))
+    if (
+        /* I didn't deop them, another bot didn't deop them and they didn't deop themselves. */
+        (was_op && ((m && !m->is_me && mv != m && !(m->user && m->user->bot)) || (!m))) && (
+          /*
+           * reversing
+           * They are either an op or this chan is -bitch
+           */
+          (reversing && (!chan_bitch(chan) || chk_op(victim, chan))) ||
+          /* Reop bots to avoid them needing to ask */
+          (role == 3 && mv->user && mv->user->bot && chk_op(victim, chan))
+        )
+       ) {
       /* Then we'll bless the victim */
       do_op(mv->nick, chan, 0, 0);
+    }
   }
 
   if (isserver[0])		/* !m */