#define MODE_ALTCHAN 0x8000000 /**< Alternative channel */
#define MODE_DEL 0x20000000
#define MODE_ADD 0x40000000
-#define MODE_ACCESS 0x100000000LLU /**< ChanServ access */
+#define MODE_ACCESS 0x100000000LLU /**< ChanServ access */
+#define MODE_AUDITORIUM 0x200000000LLU /**< +u Auditorium */
/** mode flags which take another parameter (With PARAmeterS)
*/
#define MODE_WPARAS (MODE_CHANOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS|MODE_EXCEPTION|MODE_ALTCHAN|MODE_ACCESS)
/** Available Channel modes */
-#define infochanmodes feature_bool(FEAT_OPLEVELS) ? "AcCbiklmMnNopstUvrDRzQ" : "cCbiklmMnNopstvrDRzQ"
+#define infochanmodes feature_bool(FEAT_OPLEVELS) ? "AcCbiklmMnNopstuUvrDRzQu" : "cCbiklmMnNopstuvrDRzQu"
/** Available Channel modes that take parameters */
#define infochanmodeswithparams feature_bool(FEAT_OPLEVELS) ? "AbkloUvFa" : "bklovFa"
extern void RevealDelayedJoinIfNeeded(struct Client *sptr, struct Channel *chptr);
extern void RevealDelayedJoin(struct Membership *member);
extern void CheckDelayedJoins(struct Channel *chan);
+extern void CheckEnableDelayedJoins(struct Channel *chan);
extern void modebuf_init(struct ModeBuf *mbuf, struct Client *source,
struct Client *connect, struct Channel *chan,
*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);
MODE_NOAMSGS, 'M',
MODE_NONOTICE, 'N',
MODE_QUARANTINE, 'Q',
+ MODE_AUDITORIUM, 'u',
0x0, 0x0
};
static ulong64 local_flags[] = {
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;
MODE_QUARANTINE, 'Q',
MODE_ALTCHAN, 'F',
MODE_ACCESS, 'a',
+ MODE_AUDITORIUM, 'u',
0x0, 0x0
};
ulong64 add;
}
}
+/* 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
*/
MODE_QUARANTINE, 'Q',
MODE_ALTCHAN, 'F',
MODE_ACCESS, 'a',
+ MODE_AUDITORIUM, 'u',
MODE_ADD, '+',
MODE_DEL, '-',
0x0, 0x0
case 'l': /* deal with limits */
mode_parse_limit(&state, flag_p);
break;
+ case 'u': /* deal with not oped members */
+ audit_chan_users(&state, flag_p);
+ mode_parse_mode(&state, flag_p);
+ break;
case 'a': /* deal with limits */
mode_parse_access(&state, flag_p);
break;
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);
"%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_DELJOINS) && !(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);
}
}
+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
*/
|| IsZombie(member)
|| (skip & SKIP_DEAF && IsDeaf(member->user))
|| (skip & SKIP_NONOPS && !IsChanOp(member))
+ || (skip & SKIP_OPS && IsChanOp(member))
|| (skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member)))
continue;
send_buffer(member->user, mb, 0);
|| cli_fd(cli_from(member->user)) < 0
|| cli_sentalong(member->user) == sentalong_marker
|| (skip & SKIP_NONOPS && !IsChanOp(member))
+ || (skip & SKIP_OPS && IsChanOp(member))
|| (skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member)))
continue;
cli_sentalong(member->user) = sentalong_marker;
if (IsZombie(member) ||
(skip & SKIP_DEAF && IsDeaf(member->user)) ||
(skip & SKIP_NONOPS && !IsChanOp(member)) ||
+ (skip & SKIP_OPS && IsChanOp(member)) ||
(skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member)) ||
(skip & SKIP_BURST && IsBurstOrBurstAck(cli_from(member->user))) ||
cli_fd(cli_from(member->user)) < 0 ||