* kicknorejoin (+J in inspircd chmode)
* operoverride umode (+p), steal this from ircd-seven
* immune cmode (+M), steal this from ircd-seven too
-* channel::exemptchanops config option
* host-on-operup: vhost that gets applied to you on oper-up. A surprising number of people want this.
* Anything else we think of between now and release. :P
channel {
autochanmodes = "nt";
+ exemptchanops = "NT";
use_halfop = yes;
use_owner = yes;
use_invex = yes;
*/
autochanmodes = "nt";
+ /* exemptchanops: Channel modes that any form of channel ops (+aoh)
+ * will be exempt from. Even if the mode is set, it will not apply to the
+ * channel ops if it is listed in this option. Valid modes are cCDTNGK.
+ */
+ exemptchanops = "NT";
+
/* halfop: Enable/disable channel mode +h, which adds halfop,
* a channel status below op that has op powers (kick, ban, mode, etc.)
* halfops can only kick/devoice/etc people who are +v or
struct config_channel_entry
{
char * autochanmodes;
+ char * exemptchanops;
int use_halfop;
int use_owner;
int use_except;
int host_in_topic;
int resv_forcepart;
int kick_no_rejoin_time;
+
+ int exempt_cmode_c;
+ int exempt_cmode_C;
+ int exempt_cmode_D;
+ int exempt_cmode_T;
+ int exempt_cmode_N;
+ int exempt_cmode_G;
+ int exempt_cmode_K;
};
struct config_server_hide
int contor;
int caps = 0;
int len = 0;
+ struct membership *msptr = find_channel_membership(chptr, source_p);
if(MyClient(source_p))
{
source_p->localClient->last = rb_current_time();
}
- if(chptr->mode.mode & MODE_NOCOLOR)
+ if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
{
rb_strlcpy(text2, text, BUFSIZE);
strip_colour(text2);
if(result == CAN_SEND_OPV ||
!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
{
- if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS)
+ if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS && (!ConfigChannel.exempt_cmode_G || !is_any_op(msptr)))
{
for(contor=0; contor < strlen(text); contor++)
{
return;
}
}
- if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE)
+ if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE && (!ConfigChannel.exempt_cmode_T || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
return;
}
if (p_or_n != NOTICE && chptr->mode.mode & MODE_NOACTION &&
- !strncasecmp(text + 1, "ACTION", 6))
+ !strncasecmp(text + 1, "ACTION", 6) &&
+ (!ConfigChannel.exempt_cmode_D || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
if (p_or_n != NOTICE && *text == '\001' &&
strncasecmp(text + 1, "ACTION", 6))
{
- if (chptr->mode.mode & MODE_NOCTCP)
+ if (chptr->mode.mode & MODE_NOCTCP && (!ConfigChannel.exempt_cmode_C || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
(source_p->localClient->firsttime +
ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time()))))
{
- if(chptr->mode.mode & MODE_NOCOLOR)
+ if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
{
rb_strlcpy(reason2, reason, BUFSIZE);
strip_colour(reason2);
&ConfigChannel.autochanmodes,
"Channelmodes set on channel creation"
},
+ {
+ "exemptchanops",
+ OUTPUT_STRING,
+ &ConfigChannel.exemptchanops,
+ "Channelmodes that chanops are exempt from"
+ },
{
"nick_delay",
OUTPUT_DECIMAL,
{
msptr = ptr->data;
chptr = msptr->chptr;
- if (is_any_op(msptr))
- continue;
- if (chptr->mode.mode & MODE_NONICK)
+ if (chptr->mode.mode & MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
return chptr;
}
return NULL;
static struct ConfEntry conf_channel_table[] =
{
{ "autochanmodes", CF_QSTRING, NULL, 0, &ConfigChannel.autochanmodes },
+ { "exemptchanops", CF_QSTRING, NULL, 0, &ConfigChannel.exemptchanops },
{ "default_split_user_count", CF_INT, NULL, 0, &ConfigChannel.default_split_user_count },
{ "default_split_server_count", CF_INT, NULL, 0, &ConfigChannel.default_split_server_count },
{ "burst_topicwho", CF_YESNO, NULL, 0, &ConfigChannel.burst_topicwho },
{ "use_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.use_local_channels },
{ "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart },
{ "kick_no_rejoin_time", CF_INT, NULL, 0, &ConfigChannel.kick_no_rejoin_time },
+ { "exempt_cmode_c", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_c },
+ { "exempt_cmode_C", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_C },
+ { "exempt_cmode_D", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_D },
+ { "exempt_cmode_T", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_T },
+ { "exempt_cmode_N", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_N },
+ { "exempt_cmode_G", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_G },
+ { "exempt_cmode_K", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_K },
{ "\0", 0, NULL, 0, NULL }
};
ConfigFileEntry.oper_snomask = SNO_GENERAL;
ConfigChannel.autochanmodes = rb_strdup("nt");
+ ConfigChannel.exemptchanops = rb_strdup("");
ConfigChannel.use_halfop = YES;
ConfigChannel.use_owner = YES;
ConfigChannel.use_except = YES;
ConfigChannel.resv_forcepart = YES;
ConfigChannel.kick_no_rejoin_time = 30;
+ ConfigChannel.exempt_cmode_c = NO;
+ ConfigChannel.exempt_cmode_C = NO;
+ ConfigChannel.exempt_cmode_D = NO;
+ ConfigChannel.exempt_cmode_T = NO;
+ ConfigChannel.exempt_cmode_N = NO;
+ ConfigChannel.exempt_cmode_G = NO;
+ ConfigChannel.exempt_cmode_K = NO;
+
ConfigServerHide.flatten_links = 0;
ConfigServerHide.links_delay = 300;
ConfigServerHide.hidden = 0;
splitmode = 0;
splitchecking = 0;
}
+
+ /* Parse the exemptchanops option and set the internal variables
+ * that we will use. */
+ char * ech;
+
+ for(ech = ConfigChannel.exemptchanops; *ech; ech++)
+ {
+ if(*ech == 'c')
+ {
+ ConfigChannel.exempt_cmode_c = 1;
+ continue;
+ }
+ if(*ech == 'C')
+ {
+ ConfigChannel.exempt_cmode_C = 1;
+ continue;
+ }
+ if(*ech == 'D')
+ {
+ ConfigChannel.exempt_cmode_D = 1;
+ continue;
+ }
+ if(*ech == 'T')
+ {
+ ConfigChannel.exempt_cmode_T = 1;
+ continue;
+ }
+ if(*ech == 'N')
+ {
+ ConfigChannel.exempt_cmode_N = 1;
+ continue;
+ }
+ if(*ech == 'G')
+ {
+ ConfigChannel.exempt_cmode_G = 1;
+ continue;
+ }
+ if(*ech == 'K')
+ ConfigChannel.exempt_cmode_K = 1;
+ }
}
/* add_temp_kline()