len -= banlen;
} else {
if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) &&
+ !(state->mbuf->mb_dest & MODEBUF_DEST_OPMODE) &&
(len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) ||
count > feature_int(FEAT_MAXBANS))) {
send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname,
if (colon != NULL) {
*colon++ = '\0';
req_oplevel = atoi(colon);
- if (!(state->flags & MODE_PARSE_FORCE)
+ if (*flag_p == CHFL_VOICE || state->dir == MODE_DEL) {
+ /* Ignore the colon and its argument. */
+ } else if (!(state->flags & MODE_PARSE_FORCE)
&& state->member
&& (req_oplevel < OpLevel(state->member)
|| (req_oplevel == OpLevel(state->member)
&& OpLevel(state->member) < MAXOPLEVEL)
- || req_oplevel > MAXOPLEVEL))
+ || req_oplevel > MAXOPLEVEL)) {
send_reply(state->sptr, ERR_NOTLOWEROPLEVEL,
t_str, state->chptr->chname,
OpLevel(state->member), req_oplevel, "op",
OpLevel(state->member) == req_oplevel ? "the same" : "a higher");
- else if (req_oplevel <= MAXOPLEVEL)
+ } else if (req_oplevel <= MAXOPLEVEL)
oplevel = req_oplevel;
}
/* find client we're manipulating */
(state->add & (MODE_SECRET | MODE_PRIVATE)));
}
-/*
+/**
* This routine is intended to parse MODE or OPMODE commands and effect the
- * changes (or just build the bounce buffer). We pass the starting offset
- * as a
+ * changes (or just build the bounce buffer).
+ *
+ * \param[out] mbuf Receives parsed representation of mode change.
+ * \param[in] cptr Connection that sent the message to this server.
+ * \param[in] sptr Original source of the message.
+ * \param[in] chptr Channel whose modes are being changed.
+ * \param[in] parc Number of valid strings in \a parv.
+ * \param[in] parv Text arguments representing mode change, with the
+ * zero'th element containing a string like "+m" or "-o".
+ * \param[in] flags Set of bitwise MODE_PARSE_* flags.
+ * \param[in] member If non-null, the channel member attempting to change the modes.
*/
int
mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr,
} else {
/* Server is desynced; bounce the mode and deop the source
* to fix it. */
- state.mbuf->mb_dest &= ~MODEBUF_DEST_CHANNEL;
+ state.flags &= ~MODE_PARSE_SET;
+ state.flags |= MODE_PARSE_BOUNCE;
+ state.mbuf->mb_dest &= ~(MODEBUF_DEST_CHANNEL | MODEBUF_DEST_HACK4);
state.mbuf->mb_dest |= MODEBUF_DEST_BOUNCE | MODEBUF_DEST_HACK2;
if (!IsServer(state.cptr))
state.mbuf->mb_dest |= MODEBUF_DEST_DEOP;
"%H -d", chan);
}
}
+
+/** Send a join for the user if (s)he is a hidden member of the channel.
+ */
+void RevealDelayedJoinIfNeeded(struct Client *sptr, struct Channel *chptr)
+{
+ struct Membership *member = find_member_link(chptr, sptr);
+ if (member && IsDelayedJoin(member))
+ RevealDelayedJoin(member);
+}