Allow -A channels to have oplevels as well. Allow showing oplevels in /who.
authorMichael Poole <mdpoole@troilus.org>
Sat, 4 Nov 2006 21:35:28 +0000 (21:35 +0000)
committerMichael Poole <mdpoole@troilus.org>
Sat, 4 Nov 2006 21:35:28 +0000 (21:35 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1727 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
doc/readme.who
include/whocmds.h
ircd/channel.c
ircd/m_who.c
ircd/whocmds.c

index 9504969ac15aa56e99ff1e34aef4c7d8d872d55a..9c550849397f2ec623c49772e7ddf0d6d101ae2f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-11-04  Michael Poole <mdpoole@troilus.org>
+
+       * doc/readme.who: Document new 'o' field flag.
+
+       * include/whocmds.h (WHO_FIELD_OPL): New flag.
+
+       * ircd/channel.c (send_channel_modes): Rename feat_oplevels to
+       send_oplevels and determine it automatically.
+       (modebuf_flush_int): Pass along oplevel if it's less than
+       MAXOPLEVEL.
+       (mode_process_clients): Allow oplevels to be inherited for -A
+       channels.  Inherit the opper's oplevel if >= MAXOPLEVEL.
+
+       * ircd/m_who.c (m_who): Recognize 'o' flag as WHO_FIELD_OPL.
+
+       * ircd/whocmds.c (do_who): Send oplevel for WHO_FIELD_OPL, but
+       only show up to the requester's own oplevel.
+
 2006-10-21  Michael Poole <mdpoole@troilus.org>
 
        * ircd/convert-conf.c (finish_connects): Fix error display for
index bb1658127c65c8a1975f77cfb08c3f3cba9bb40a..5520f0a18d1a72822dd52705a1ea9b6ebebb2bf4 100644 (file)
@@ -99,6 +99,7 @@ in which:
    t : Include the querytype in the reply
    u : Include userID with eventual ~
    a : Include account name
+   o : Include oplevel (shows 999 to users without ops in the channel)
 
 And the ,<querytype> final option can be used to specify what you want the
 server to say in the querytype field of the output, useful to filter the
index 3a30796ba7d07051d9c2d7ed5d4fea5107ce9821..1e87750bc70301bdb2d8227f79935a77c8446c9c 100644 (file)
@@ -37,6 +37,7 @@ struct Channel;
 #define WHO_FIELD_REN 512  /**< Show realname (info). */
 #define WHO_FIELD_IDL 1024 /**< Show idle time. */
 #define WHO_FIELD_ACC 2048 /**< Show account name. */
+#define WHO_FIELD_OPL 4096 /**< Show oplevel. */
 
 /** Default fields for /WHO */
 #define WHO_FIELD_DEF ( WHO_FIELD_NIC | WHO_FIELD_UID | WHO_FIELD_HOS | WHO_FIELD_SER )
index d7e3145845d957b00d56e02cf603871dd49d7822..e591dda3a524cff95e8f7ce74e2fc2e4f51e5f8e 100644 (file)
@@ -914,7 +914,7 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
   int                 opped_members_index = 0;
   struct Membership** opped_members = NULL;
   int                 last_oplevel = 0;
-  int                 feat_oplevels = (chptr->mode.apass[0]) != '\0';
+  int                 send_oplevels = 0;
 
   assert(0 != cptr);
   assert(0 != chptr); 
@@ -972,6 +972,9 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
            ++number_of_ops;
          else
            opped_members[opped_members_index++] = member;
+          /* We also send oplevels if anyone is below the weakest level.  */
+          if (OpLevel(member) < MAXOPLEVEL)
+            send_oplevels = 1;
        }
        /* Only handle the members with the flags that we are interested in. */
         if ((member->status & CHFL_VOICED_OR_OPPED) == current_flags[flag_cnt])
@@ -1012,7 +1015,7 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
            if (IsChanOp(member))       /* flag_cnt == 2 or 3 */
            {
               /* append the absolute value of the oplevel */
-              if (feat_oplevels)
+              if (send_oplevels)
                 loc += ircd_snprintf(0, tbuf + loc, sizeof(tbuf) - loc, "%u", last_oplevel = member->oplevel);
               else
                 tbuf[loc++] = 'o';
@@ -1021,7 +1024,7 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
            msgq_append(&me, mb, tbuf);
            new_mode = 0;
          }
-         else if (feat_oplevels && flag_cnt > 1 && last_oplevel != member->oplevel)
+         else if (send_oplevels && flag_cnt > 1 && last_oplevel != member->oplevel)
          {
            /*
             * This can't be the first member of a (continued) BURST
@@ -1806,8 +1809,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
       }
 
       /* if we're changing oplevels and we know the oplevel, pass it on */
-      if (mbuf->mb_channel->mode.apass[0]
-          && (MB_TYPE(mbuf, i) & MODE_CHANOP)
+      if ((MB_TYPE(mbuf, i) & MODE_CHANOP)
           && MB_OPLEVEL(mbuf, i) < MAXOPLEVEL)
           *strptr_i += ircd_snprintf(0, strptr + *strptr_i, BUFSIZE - *strptr_i,
                                      " %s%s:%d",
@@ -3083,8 +3085,8 @@ mode_process_clients(struct ParseState *state)
         SetOpLevel(member, state->cli_change[i].oplevel);
       else if (!state->member)
         SetOpLevel(member, MAXOPLEVEL);
-      else if (!state->chptr->mode.apass[0] || OpLevel(state->member) == MAXOPLEVEL)
-        SetOpLevel(member, MAXOPLEVEL);
+      else if (OpLevel(state->member) >= MAXOPLEVEL)
+          SetOpLevel(member, OpLevel(state->member));
       else
         SetOpLevel(member, OpLevel(state->member) + 1);
     }
index ffc78f716a3aee829734fa0899a6a4ec21d6272d..9ee0f074d0bdddc9fa69443e51b231fb09491575 100644 (file)
@@ -271,6 +271,10 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           case 'A':
             fields |= WHO_FIELD_ACC;
             break;
+          case 'o':
+          case 'O':
+            fields |= WHO_FIELD_OPL;
+            break;
           default:
             break;
         }
index 1388238b33b077e649ac10baeb6c45b05ba4c8d9..08e500faccd468f3217e73635a3701801e88a015 100644 (file)
@@ -86,7 +86,9 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
      that there are no common channels, thus use PubChannel and not
      SeeChannel */
   if (repchan)
+  {
     chan = find_channel_member(acptr, repchan);
+  }
   else if ((!fields || (fields & (WHO_FIELD_CHA | WHO_FIELD_FLA)))
            && !IsChannelService(acptr))
   {
@@ -242,6 +244,23 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
       *(p1++) = '0';
   }
 
+  if (fields & WHO_FIELD_OPL)
+  {
+      if (!chan || !IsChanOp(chan))
+      {
+        strcpy(p1, " n/a");
+        p1 += 4;
+      }
+      else
+      {
+        int vis_level = MAXOPLEVEL;
+        if ((IsGlobalChannel(chan->channel->chname) ? IsOper(sptr) : IsAnOper(sptr))
+            || is_chan_op(sptr, chan->channel))
+          vis_level = OpLevel(chan);
+        p1 += ircd_snprintf(0, p1, 5, " %d", vis_level);
+      }
+  }
+
   if (!fields || (fields & WHO_FIELD_REN))
   {
     char *p2 = cli_info(acptr);