From d3ebaa4b31bf4fc58150bed0afb33259f9530fa2 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Sat, 4 Nov 2006 21:35:28 +0000 Subject: [PATCH] Allow -A channels to have oplevels as well. Allow showing oplevels in /who. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1727 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 18 ++++++++++++++++++ doc/readme.who | 1 + include/whocmds.h | 1 + ircd/channel.c | 16 +++++++++------- ircd/m_who.c | 4 ++++ ircd/whocmds.c | 19 +++++++++++++++++++ 6 files changed, 52 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9504969..9c55084 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-11-04 Michael Poole + + * 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 * ircd/convert-conf.c (finish_connects): Fix error display for diff --git a/doc/readme.who b/doc/readme.who index bb16581..5520f0a 100644 --- a/doc/readme.who +++ b/doc/readme.who @@ -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 , 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 diff --git a/include/whocmds.h b/include/whocmds.h index 3a30796..1e87750 100644 --- a/include/whocmds.h +++ b/include/whocmds.h @@ -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 ) diff --git a/ircd/channel.c b/ircd/channel.c index d7e3145..e591dda 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -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); } diff --git a/ircd/m_who.c b/ircd/m_who.c index ffc78f7..9ee0f07 100644 --- a/ircd/m_who.c +++ b/ircd/m_who.c @@ -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; } diff --git a/ircd/whocmds.c b/ircd/whocmds.c index 1388238..08e500f 100644 --- a/ircd/whocmds.c +++ b/ircd/whocmds.c @@ -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); -- 2.20.1