X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fchannel.c;h=65d37b22afb8f0b1db2dd003035215827ab10a13;hp=01d25072c95275dc46bbafdbd9bdcc908244764f;hb=1a89d47dcb393c9d68bf1322dfb31e38ac2aa483;hpb=c3727b053aa20cecf3984cc0c9c23b0140edf52c diff --git a/ircd/channel.c b/ircd/channel.c index 01d2507..65d37b2 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -870,6 +870,8 @@ void channel_modes(struct Client *cptr, char *mbuf, char *pbuf, int buflen, *mbuf++ = 'M'; if (chptr->mode.mode & MODE_QUARANTINE) *mbuf++ = 'Q'; + if (chptr->mode.mode & MODE_AUDITORIUM) + *mbuf++ = 'u'; if (chptr->mode.limit) { *mbuf++ = 'l'; ircd_snprintf(0, pbuf, buflen, "%u", chptr->mode.limit); @@ -1577,7 +1579,7 @@ static int modebuf_flush_int(struct ModeBuf *mbuf, int all) { /* we only need the flags that don't take args right now */ - static int flags[] = { + static ulong64 flags[] = { /* MODE_CHANOP, 'o', */ /* MODE_VOICE, 'v', */ MODE_PRIVATE, 'p', @@ -1603,14 +1605,15 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) MODE_NOAMSGS, 'M', MODE_NONOTICE, 'N', MODE_QUARANTINE, 'Q', + MODE_AUDITORIUM, 'u', 0x0, 0x0 }; - static int local_flags[] = { + static ulong64 local_flags[] = { MODE_WASDELJOINS, 'd', 0x0, 0x0 }; int i; - int *flag_p; + ulong64 *flag_p; struct Client *app_source; /* where the MODE appears to come from */ @@ -1633,8 +1636,8 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) char limitbuf[20],accessbuf[20]; /* convert limits to strings */ - unsigned int limitdel = MODE_LIMIT; - unsigned int accessdel = MODE_ACCESS; + ulong64 limitdel = MODE_LIMIT; + ulong64 accessdel = MODE_ACCESS; assert(0 != mbuf); @@ -2032,7 +2035,7 @@ modebuf_init(struct ModeBuf *mbuf, struct Client *source, * @param mode MODE_ADD or MODE_DEL OR'd with MODE_PRIVATE etc. */ void -modebuf_mode(struct ModeBuf *mbuf, unsigned int mode) +modebuf_mode(struct ModeBuf *mbuf, ulong64 mode) { assert(0 != mbuf); assert(0 != (mode & (MODE_ADD | MODE_DEL))); @@ -2040,7 +2043,8 @@ modebuf_mode(struct ModeBuf *mbuf, unsigned int mode) mode &= (MODE_ADD | MODE_DEL | MODE_PRIVATE | MODE_SECRET | MODE_MODERATED | MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS | MODE_REGONLY | MODE_DELJOINS | MODE_WASDELJOINS | MODE_REGISTERED | MODE_PERSIST | - MODE_NOCOLOUR | MODE_NOCTCP | MODE_NOAMSGS | MODE_NONOTICE | MODE_QUARANTINE); + MODE_NOCOLOUR | MODE_NOCTCP | MODE_NOAMSGS | MODE_NONOTICE | + MODE_QUARANTINE | MODE_AUDITORIUM); if (!(mode & ~(MODE_ADD | MODE_DEL))) /* don't add empty modes... */ return; @@ -2054,10 +2058,10 @@ modebuf_mode(struct ModeBuf *mbuf, unsigned int mode) } } -/** Append a mode that takes an int argument to the modebuf +/** Append a mode that takes an ulong64 argument to the modebuf * * This routine adds a mode to be added or deleted that takes a unsigned - * int parameter; mode may *only* be the relevant mode flag ORed with one + * ulong64 parameter; mode may *only* be the relevant mode flag ORed with one * of MODE_ADD or MODE_DEL * * @param mbuf The mode buffer to append to. @@ -2065,7 +2069,7 @@ modebuf_mode(struct ModeBuf *mbuf, unsigned int mode) * @param uint The argument to the mode. */ void -modebuf_mode_uint(struct ModeBuf *mbuf, unsigned int mode, unsigned int uint) +modebuf_mode_uint(struct ModeBuf *mbuf, ulong64 mode, unsigned int uint) { assert(0 != mbuf); assert(0 != (mode & (MODE_ADD | MODE_DEL))); @@ -2098,7 +2102,7 @@ modebuf_mode_uint(struct ModeBuf *mbuf, unsigned int mode, unsigned int uint) * @param free If the string should be free'd later. */ void -modebuf_mode_string(struct ModeBuf *mbuf, unsigned int mode, char *string, +modebuf_mode_string(struct ModeBuf *mbuf, ulong64 mode, char *string, int free) { assert(0 != mbuf); @@ -2124,7 +2128,7 @@ modebuf_mode_string(struct ModeBuf *mbuf, unsigned int mode, char *string, * @param oplevel The oplevel the user had or will have */ void -modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode, +modebuf_mode_client(struct ModeBuf *mbuf, ulong64 mode, struct Client *client, int oplevel) { assert(0 != mbuf); @@ -2192,7 +2196,7 @@ modebuf_flush(struct ModeBuf *mbuf) void modebuf_extract(struct ModeBuf *mbuf, char *buf) { - static int flags[] = { + static ulong64 flags[] = { /* MODE_CHANOP, 'o', */ /* MODE_VOICE, 'v', */ MODE_PRIVATE, 'p', @@ -2218,11 +2222,12 @@ modebuf_extract(struct ModeBuf *mbuf, char *buf) MODE_QUARANTINE, 'Q', MODE_ALTCHAN, 'F', MODE_ACCESS, 'a', + MODE_AUDITORIUM, 'u', 0x0, 0x0 }; - unsigned int add; + ulong64 add; int i, bufpos = 0, len; - int *flag_p; + ulong64 *flag_p; char *key = 0, limitbuf[20], accessbuf[20]; char *apass = 0, *upass = 0, *altchan = 0; @@ -2334,17 +2339,17 @@ struct ParseState { struct Membership *member; int parc; char **parv; - unsigned int flags; - unsigned int dir; - unsigned int done; - unsigned int add; - unsigned int del; + ulong64 flags; + ulong64 dir; + ulong64 done; + ulong64 add; + ulong64 del; int args_used; int max_args; int numbans; struct Ban banlist[MAXPARA]; struct { - unsigned int flag; + ulong64 flag; unsigned short oplevel; struct Client *client; } cli_change[MAXPARA]; @@ -2375,7 +2380,7 @@ send_notoper(struct ParseState *state) * @param flag_p ? */ static void -mode_parse_limit(struct ParseState *state, int *flag_p) +mode_parse_limit(struct ParseState *state, ulong64 *flag_p) { unsigned int t_limit; @@ -2440,7 +2445,7 @@ mode_parse_limit(struct ParseState *state, int *flag_p) static void -mode_parse_access(struct ParseState *state, int *flag_p) +mode_parse_access(struct ParseState *state, ulong64 *flag_p) { unsigned int t_access; @@ -2513,7 +2518,7 @@ mode_parse_access(struct ParseState *state, int *flag_p) static void -mode_parse_altchan(struct ParseState *state, int *flag_p) +mode_parse_altchan(struct ParseState *state, ulong64 *flag_p) { char *t_str; @@ -2597,7 +2602,7 @@ mode_parse_altchan(struct ParseState *state, int *flag_p) } static void -mode_parse_quarantine(struct ParseState *state, int *flag_p) +mode_parse_quarantine(struct ParseState *state, ulong64 *flag_p) { } @@ -2643,7 +2648,7 @@ is_clean_key(struct ParseState *state, char *s, char *command) * Helper function to convert keys */ static void -mode_parse_key(struct ParseState *state, int *flag_p) +mode_parse_key(struct ParseState *state, ulong64 *flag_p) { char *t_str; @@ -2730,7 +2735,7 @@ mode_parse_key(struct ParseState *state, int *flag_p) * Helper function to convert user passes */ static void -mode_parse_upass(struct ParseState *state, int *flag_p) +mode_parse_upass(struct ParseState *state, ulong64 *flag_p) { char *t_str; @@ -2849,7 +2854,7 @@ mode_parse_upass(struct ParseState *state, int *flag_p) * Helper function to convert admin passes */ static void -mode_parse_apass(struct ParseState *state, int *flag_p) +mode_parse_apass(struct ParseState *state, ulong64 *flag_p) { struct Membership *memb; char *t_str; @@ -3102,7 +3107,7 @@ int apply_ban(struct Ban **banlist, struct Ban *newban, int do_free) /* Removes MODE_WASDELJOINS in a channel. * Reveals all hidden users. */ -static void reveal_hidden_chan_users(struct ParseState *state, int *flag_p) { +static void reveal_hidden_chan_users(struct ParseState *state, ulong64 *flag_p) { struct Membership *member; /* If the channel is not +d, do nothing. */ @@ -3116,11 +3121,33 @@ static void reveal_hidden_chan_users(struct ParseState *state, int *flag_p) { } } +/* Handle MODE_AUDITORIUM changes + * set Delayed for all hidden users on MODE_DEL + * part all nonoped users on MODE_ADD + */ +static void audit_chan_users(struct ParseState *state, ulong64 *flag_p) { + struct Membership *member; + if (state->dir == MODE_ADD) { + for(member = state->chptr->members; member; member = member->next_member) { + if(!IsChanOp(member) && !HasVoice(member)) { + sendcmdto_channel_butserv_butone(member->user, CMD_PART, member->channel, member->user, SKIP_OPS, "%H :%s", member->channel, "mode +u set."); + } + } + } else { + for(member = state->chptr->members; member; member = member->next_member) { + if(!IsChanOp(member) && !HasVoice(member)) { + sendcmdto_channel_butserv_butone(member->user, CMD_JOIN, member->channel, member->user, SKIP_OPS, ":%H", member->channel); + } + } + } +} + + /* * Helper function to convert bans */ static void -mode_parse_ban(struct ParseState *state, int *flag_p) +mode_parse_ban(struct ParseState *state, ulong64 *flag_p) { char *t_str, *s; struct Ban *ban, *newban; @@ -3284,7 +3311,7 @@ mode_process_bans(struct ParseState *state) * Helper function to process client changes */ static void -mode_parse_client(struct ParseState *state, int *flag_p) +mode_parse_client(struct ParseState *state, ulong64 *flag_p) { char *t_str; char *colon; @@ -3469,7 +3496,9 @@ mode_process_clients(struct ParseState *state) else SetOpLevel(member, OpLevel(state->member) + 1); } - + + int user_visible = (member->status & CHFL_VOICED_OR_OPPED); + /* actually effect the change */ if (state->flags & MODE_PARSE_SET) { if (state->cli_change[i].flag & MODE_ADD) { @@ -3488,6 +3517,18 @@ mode_process_clients(struct ParseState *state) modebuf_mode_client(state->mbuf, state->cli_change[i].flag, state->cli_change[i].client, state->cli_change[i].oplevel); + + if((member->channel->mode.mode & MODE_AUDITORIUM)) { + //join or part the user + if((member->status & CHFL_VOICED_OR_OPPED) && !user_visible) { + sendcmdto_channel_butserv_butone(member->user, CMD_JOIN, member->channel, member->user, SKIP_OPS, ":%H", member->channel); + } else if(!(member->status & CHFL_VOICED_OR_OPPED) && user_visible) { + sendcmdto_channel_butserv_butone(member->user, CMD_PART, member->channel, member->user, SKIP_OPS, "%H :%s", member->channel, "user deoped/devoiced on a +u channel."); + } + if(MyUser(member->user) && (state->cli_change[i].flag & MODE_CHANOP)) { + do_names(member->user, member->channel, NAMES_ALL|NAMES_EON|((member->status & MODE_CHANOP) ? 0 : NAMES_OPS)); + } + } } /* for (i = 0; state->cli_change[i].flags; i++) */ } @@ -3495,7 +3536,7 @@ mode_process_clients(struct ParseState *state) * Helper function to process the simple modes */ static void -mode_parse_mode(struct ParseState *state, int *flag_p) +mode_parse_mode(struct ParseState *state, ulong64 *flag_p) { /* If they're not an oper, they can't change modes */ if (state->flags & (MODE_PARSE_NOTOPER | MODE_PARSE_NOTMEMBER)) { @@ -3509,6 +3550,9 @@ mode_parse_mode(struct ParseState *state, int *flag_p) /* Local users are not permitted to change registration status */ if (flag_p[0] == MODE_REGISTERED && !(state->flags & MODE_PARSE_FORCE) && MyUser(state->sptr)) return; + + if(flag_p[0] == MODE_AUDITORIUM) + audit_chan_users(state, flag_p); if (state->dir == MODE_ADD) { state->add |= flag_p[0]; @@ -3550,7 +3594,7 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr, struct Channel *chptr, int parc, char *parv[], unsigned int flags, struct Membership* member) { - static int chan_flags[] = { + static ulong64 chan_flags[] = { MODE_CHANOP, 'o', MODE_VOICE, 'v', MODE_PRIVATE, 'p', @@ -3577,13 +3621,14 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr, MODE_QUARANTINE, 'Q', MODE_ALTCHAN, 'F', MODE_ACCESS, 'a', + MODE_AUDITORIUM, 'u', MODE_ADD, '+', MODE_DEL, '-', 0x0, 0x0 }; int i; - int *flag_p; - unsigned int t_mode; + ulong64 *flag_p; + ulong64 t_mode; char *modestr; struct ParseState state; @@ -3871,7 +3916,9 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags) SetUserParting(member); /* Send notification to channel */ - if (!(flags & (CHFL_ZOMBIE | CHFL_DELAYED))) + if((chan->mode.mode & MODE_AUDITORIUM) && !(flags & CHFL_VOICED_OR_OPPED)) { + //do noting here + } else if (!(flags & (CHFL_ZOMBIE | CHFL_DELAYED))) sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_PART, chan, NULL, 0, (flags & CHFL_BANNED || !jbuf->jb_comment) ? ":%H" : "%H :%s", chan, jbuf->jb_comment); @@ -3909,8 +3956,14 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags) "%H %Tu %i", chan, chan->creationtime, 0); } } - - if (!((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_VOICED_OR_OPPED)) && !((flags & CHFL_INVISIBLE) && !(flags & CHFL_VOICED_OR_OPPED))) { + + if((chan->mode.mode & MODE_AUDITORIUM) && !(flags & CHFL_VOICED_OR_OPPED)) { + //we have to send this JOIN event to ops only... + sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_JOIN, chan, NULL, SKIP_NONOPS, "%H", chan); + if(MyUser(jbuf->jb_source)) + sendcmdto_one(jbuf->jb_source, CMD_JOIN, jbuf->jb_source, ":%H", chan); + } + else if (!((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_VOICED_OR_OPPED)) && !((flags & CHFL_INVISIBLE) && !(flags & CHFL_VOICED_OR_OPPED))) { /* Send the notification to the channel */ sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_JOIN, chan, NULL, 0, "%H", chan); @@ -4023,6 +4076,16 @@ void CheckDelayedJoins(struct Channel *chan) } } +void CheckEnableDelayedJoins(struct Channel *chan) { + if (!(chan->mode.mode & MODE_WASDELJOINS) && find_delayed_joins(chan)) { + chan->mode.mode |= MODE_WASDELJOINS; + sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan, NULL, 0, + "%H +d", chan); + sendcmdto_channel_servers_butone(&me, CMD_MODE, chan, NULL, 0, + "%H +d", chan); + } +} + /* checks whether a channel is nonpersistent with no users and deletes it * returns 1 if deleted, otherwise 0 */