Display detailed usercounts in !peek (ops/voices/regulars)
[srvx.git] / src / chanserv.c
index be5d739ccf6ddfa412d543ca8704679733cb2efb..e0ec5200d9a980cce6b453ee1ec062b25f48a85e 100644 (file)
@@ -404,7 +404,7 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_PEEK_INFO", "$b%s$b Status:" },
     { "CSMSG_PEEK_TOPIC", "$bTopic:          $b%s" },
     { "CSMSG_PEEK_MODES", "$bModes:          $b%s" },
-    { "CSMSG_PEEK_USERS", "$bTotal users:    $b%d" },
+    { "CSMSG_PEEK_USERS", "$bTotal users:    $b%d (%d ops, %d voices, %d regulars)" },
     { "CSMSG_PEEK_OPS", "$bOps:$b" },
     { "CSMSG_PEEK_NO_OPS", "$bOps:            $bNone present" },
 
@@ -1382,7 +1382,7 @@ expire_channels(UNUSED_ARG(void *data))
 
         /* Make sure there are no high-ranking users still in the channel. */
         for(user=channel->users; user; user=user->next)
-            if(user->present && (user->access >= UL_PRESENT))
+            if(user->present && (user->access >= UL_PRESENT) && !HANDLE_FLAGGED(user->handle, BOT))
                 break;
         if(user)
             continue;
@@ -3151,6 +3151,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
     else if(!is_ircmask(argv[1]) && (*argv[1] == '*'))
     {
         struct handle_info *hi;
+        extern const char *titlehost_suffix;
         char banmask[NICKLEN + USERLEN + HOSTLEN + 3];
         const char *accountname = argv[1] + 1;
 
@@ -3160,7 +3161,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
             return 0;
         }
 
-        snprintf(banmask, sizeof(banmask), "*!*@%s.*", hi->handle);
+        snprintf(banmask, sizeof(banmask), "*!*@%s.*.%s", hi->handle, titlehost_suffix);
         victims = alloca(sizeof(victims[0]) * channel->members.used);
 
         if(bad_channel_ban(channel, user, banmask, &victimCount, victims))
@@ -3963,6 +3964,8 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg
             ary[3] = "Suspended";
         else if(HANDLE_FLAGGED(uData->handle, FROZEN))
             ary[3] = "Vacation";
+        else if(HANDLE_FLAGGED(uData->handle, BOT))
+            ary[3] = "Bot";
         else
             ary[3] = "Normal";
     }
@@ -4506,13 +4509,13 @@ static CHANSERV_FUNC(cmd_peek)
     char modes[MODELEN];
     unsigned int n;
     struct helpfile_table table;
+    int opcount = 0, voicecount = 0, srvcount = 0;
 
     irc_make_chanmode(channel, modes);
 
     reply("CSMSG_PEEK_INFO", channel->name);
     reply("CSMSG_PEEK_TOPIC", channel->topic);
     reply("CSMSG_PEEK_MODES", modes);
-    reply("CSMSG_PEEK_USERS", channel->members.used);
 
     table.length = 0;
     table.width = 1;
@@ -4521,12 +4524,23 @@ static CHANSERV_FUNC(cmd_peek)
     for(n = 0; n < channel->members.used; n++)
     {
         mn = channel->members.list[n];
+        if(IsLocal(mn->user))
+            srvcount++;
+        else if(mn->modes & MODE_CHANOP)
+            opcount++;
+        else if(mn->modes & MODE_VOICE)
+            voicecount++;
+
         if(!(mn->modes & MODE_CHANOP) || IsLocal(mn->user))
             continue;
         table.contents[table.length] = alloca(sizeof(**table.contents));
         table.contents[table.length][0] = mn->user->nick;
         table.length++;
     }
+
+    reply("CSMSG_PEEK_USERS", channel->members.used, opcount, voicecount,
+          (channel->members.used - opcount - voicecount - srvcount));
+
     if(table.length)
     {
         reply("CSMSG_PEEK_OPS");
@@ -6563,7 +6577,7 @@ handle_join(struct modeNode *mNode)
                 else if(uData->access >= cData->lvlOpts[lvlGiveVoice])
                     modes |= MODE_VOICE;
             }
-            if(uData->access >= UL_PRESENT)
+            if(uData->access >= UL_PRESENT && !HANDLE_FLAGGED(uData->handle, BOT))
                 cData->visited = now;
             if(cData->user_greeting)
                 greeting = cData->user_greeting;
@@ -6631,7 +6645,7 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
             continue;
         }
 
-        if(channel->access >= UL_PRESENT)
+        if(channel->access >= UL_PRESENT && !HANDLE_FLAGGED(channel->handle, BOT))
             channel->channel->visited = now;
 
         if(IsUserAutoOp(channel))
@@ -6718,7 +6732,7 @@ handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason))
     {
         scan_user_presence(uData, mn->user);
         uData->seen = now;
-        if (uData->access >= UL_PRESENT)
+        if (uData->access >= UL_PRESENT && !HANDLE_FLAGGED(uData->handle, BOT))
             cData->visited = now;
     }
 
@@ -7526,7 +7540,7 @@ chanserv_write_users(struct saxdb_context *ctx, struct userData *uData)
     saxdb_start_record(ctx, KEY_USERS, 1);
     for(; uData; uData = uData->next)
     {
-        if((uData->access >= UL_PRESENT) && uData->present)
+        if((uData->access >= UL_PRESENT) && uData->present && !HANDLE_FLAGGED(uData->handle, BOT))
             high_present = 1;
         saxdb_start_record(ctx, uData->handle->handle, 0);
         saxdb_write_int(ctx, KEY_LEVEL, uData->access);