diff --git a/help/opers/cmode b/help/opers/cmode index 751c1a0..0bef5f6 100644 --- a/help/opers/cmode +++ b/help/opers/cmode @@ -33,6 +33,8 @@ NO PARAMETERS: +T - Disable notice. All notices to the channel are disallowed. +E - No kicks. Chanops will not be able to use /kick on this channel. + +N - No nickchanges. People on the channel will not be able to + change nick. WITH PARAMETERS: +f - Forward. Forwards users who cannot join because of +i, diff --git a/include/channel.h b/include/channel.h index 4939ff9..c7a6ecf 100644 --- a/include/channel.h +++ b/include/channel.h @@ -175,6 +175,7 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p, #define MODE_NONOTICE 0x16000 /* Block notices directed to this channel */ #define MODE_NOACTION 0x32000 /* Block CTCP ACTION directed to this channel */ #define MODE_NOKICK 0x64000 /* Disable /kick on this channel */ +#define MODE_NONICK 0x128000 /* Disable /nick for anyone on this channel */ #define CHFL_BAN 0x10000000 /* ban channel flag */ #define CHFL_EXCEPTION 0x20000000 /* exception to ban channel flag */ @@ -243,6 +244,8 @@ const char *channel_modes(struct Channel *chptr, struct Client *who); extern struct Channel *find_bannickchange_channel(struct Client *client_p); +extern struct Channel *find_nonickchange_channel(struct Client *client_p); + extern void check_spambot_warning(struct Client *source_p, const char *name); extern void check_splitmode(void *); diff --git a/include/numeric.h b/include/numeric.h index e8cc0f2..3b9f30f 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -264,6 +264,8 @@ extern const char *form_str(int); #define ERR_NOINVITE 447 +#define ERR_NONICK 449 + #define ERR_NOTREGISTERED 451 #define ERR_ACCEPTFULL 456 diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c index 4deeed6..eec78fa 100644 --- a/modules/core/m_nick.c +++ b/modules/core/m_nick.c @@ -691,6 +691,16 @@ change_local_nick(struct Client *client_p, struct Client *source_p, nick, chptr->chname); return; } + + chptr = find_nonickchange_channel(source_p); + if (chptr != NULL) + { + sendto_one_numeric(source_p, ERR_NONICK, + form_str(ERR_NONICK), + chptr->chname); + return; + } + if((source_p->localClient->last_nick_change + ConfigFileEntry.max_nick_time) < rb_current_time()) source_p->localClient->number_of_nick_changes = 0; diff --git a/src/channel.c b/src/channel.c index 9134b57..1e35f3d 100644 --- a/src/channel.c +++ b/src/channel.c @@ -904,6 +904,32 @@ find_bannickchange_channel(struct Client *client_p) return NULL; } +/* find_nonickchange_channel() + * Input: client to check + * Output: channel preventing nick change + */ +struct Channel * +find_nonickchange_channel(struct Client *client_p) +{ + struct Channel *chptr; + struct membership *msptr; + rb_dlink_node *ptr; + + if (!MyClient(client_p)) + return NULL; + + RB_DLINK_FOREACH(ptr, client_p->user->channel.head) + { + msptr = ptr->data; + chptr = msptr->chptr; + if (is_chanop_voiced(msptr)) + continue; + if (chptr->mode.mode & MODE_NONICK) + return chptr; + } + return NULL; +} + /* void check_spambot_warning(struct Client *source_p) * Input: Client to check, channel name or NULL if this is a part. * Output: none diff --git a/src/chmode.c b/src/chmode.c index a1fbbce..49c5704 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -1410,7 +1410,7 @@ struct ChannelMode chmode_table[256] = {chm_nosuch, 0 }, /* K */ {chm_staff, MODE_EXLIMIT }, /* L */ {chm_nosuch, 0 }, /* M */ - {chm_nosuch, 0 }, /* N */ + {chm_simple, MODE_NONICK }, /* N */ {chm_nosuch, 0 }, /* O */ {chm_staff, MODE_PERMANENT }, /* P */ {chm_simple, MODE_DISFORWARD }, /* Q */ diff --git a/src/messages.tab b/src/messages.tab index c24ebd2..2ce9399 100644 --- a/src/messages.tab +++ b/src/messages.tab @@ -470,7 +470,7 @@ static const char * replies[] = { /* 446 ERR_USERSDISABLED, */ NULL, /* 447 ERR_NOINVITE */ ":Can't send invite to %s (+V set)", /* 448 */ NULL, -/* 449 */ NULL, +/* 449 ERR_NONICK */ "%s :Cannot change nickname while on channel (+N set)", /* 450 */ NULL, /* 451 ERR_NOTREGISTERED, */ ":%s 451 * :You have not registered", /* 452 */ NULL,