+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
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
#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 )
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);
++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])
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';
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
}
/* 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",
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);
}
case 'A':
fields |= WHO_FIELD_ACC;
break;
+ case 'o':
+ case 'O':
+ fields |= WHO_FIELD_OPL;
+ break;
default:
break;
}
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))
{
*(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);