diff --git a/extensions/m_okick.c b/extensions/m_okick.c index 86da046..c09c42a 100644 --- a/extensions/m_okick.c +++ b/extensions/m_okick.c @@ -138,5 +138,10 @@ mo_okick(struct Client *client_p, struct Client *source_p, int parc, const char ":%s KICK %s %s :%s", me.id, chptr->chname, who->id, comment); remove_user_from_channel(msptr); + rb_sprintf(text, "K%s", who->id); + + /* we don't need to track NOREJOIN stuff unless it's our client being kicked */ + if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN) + channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN"); return 0; } diff --git a/include/channel.h b/include/channel.h index b9932be..6896a2e 100644 --- a/include/channel.h +++ b/include/channel.h @@ -186,8 +186,9 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p, #define MODE_NOKICK 0x40000 /* Disable /kick on this channel */ #define MODE_NONICK 0x80000 /* Disable /nick for anyone on this channel */ #define MODE_NOCAPS 0x100000 /* Block messages in all capital letters */ -#define MODE_NOREPEAT 0x200000 /* Block repeat messages */ -#define MODE_NOOPERKICK 0x400000 /* disallow kicking opers */ +#define MODE_NOREJOIN 0x200000 /* Block rejoin immediately after kick */ +#define MODE_NOREPEAT 0x400000 /* Block repeat messages */ +#define MODE_NOOPERKICK 0x800000 /* disallow kicking opers */ #define CHFL_BAN 0x10000000 /* ban channel flag */ #define CHFL_EXCEPTION 0x20000000 /* exception to ban channel flag */ diff --git a/include/numeric.h b/include/numeric.h index 816c07e..a85c17e 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -307,6 +307,8 @@ extern const char *form_str(int); #define ERR_NOCTCP 492 +#define ERR_KICKNOREJOIN 495 + #define ERR_UMODEUNKNOWNFLAG 501 #define ERR_USERSDONTMATCH 502 diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c index 77b58f6..572e911 100644 --- a/modules/core/m_kick.c +++ b/modules/core/m_kick.c @@ -235,6 +235,11 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p use_id(source_p), chptr->chname, use_id(who), comment); remove_user_from_channel(msptr); + rb_sprintf(text, "K%s", who->id); + + /* we don't need to track NOREJOIN stuff unless it's our client being kicked */ + if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN) + channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN"); } else if (MyClient(source_p)) sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, diff --git a/src/channel.c b/src/channel.c index 8152b5f..74767f4 100644 --- a/src/channel.c +++ b/src/channel.c @@ -857,6 +857,17 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) if((is_banned(chptr, source_p, NULL, src_host, src_iphost)) == CHFL_BAN) return (ERR_BANNEDFROMCHAN); + rb_sprintf(text, "K%s", source_p->id); + + DICTIONARY_FOREACH(md, &iter, chptr->metadata) + { + if(!strcmp(md->value, "KICKNOREJOIN") && !strcmp(md->name, text) && (md->timevalue + ConfigChannel.kick_no_rejoin_time > rb_current_time())) + return ERR_KICKNOREJOIN; + /* cleanup any stale KICKNOREJOIN metadata we find while we're at it */ + if(!strcmp(md->value, "KICKNOREJOIN") && !(md->timevalue + ConfigChannel.kick_no_rejoin_time > rb_current_time())) + channel_metadata_delete(chptr, md->name, 0); + } + if(chptr->mode.mode & MODE_INVITEONLY) { RB_DLINK_FOREACH(invite, source_p->user->invited.head) diff --git a/src/chmode.c b/src/chmode.c index 8797a79..c2fd63c 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -555,6 +555,14 @@ chm_simple(struct Client *source_p, struct Channel *chptr, else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type)) { /* cleanup metadata when the related mode is removed */ + if(c == 'J') + { + DICTIONARY_FOREACH(md, &iter, chptr->metadata) + { + if(!strcmp(md->value, "KICKNOREJOIN")) + channel_metadata_delete(chptr, md->name, 0); + } + } if(c == 'K') channel_metadata_delete(chptr, "NOREPEAT", 0); @@ -1827,7 +1835,7 @@ struct ChannelMode chmode_table[256] = {chm_simple, MODE_NOCAPS }, /* G */ {chm_nosuch, 0 }, /* H */ {chm_ban, CHFL_INVEX }, /* I */ - {chm_simple, 0 }, /* J */ + {chm_simple, MODE_NOREJOIN }, /* J */ {chm_simple, MODE_NOREPEAT }, /* K */ {chm_staff, MODE_EXLIMIT }, /* L */ {chm_hidden, MODE_NOOPERKICK }, /* M */ diff --git a/src/messages.tab b/src/messages.tab index debeeda..b8fc7d7 100644 --- a/src/messages.tab +++ b/src/messages.tab @@ -516,7 +516,7 @@ static const char * replies[] = { /* 492 ERR_NOCTCP */ ":Can't send CTCP to %s (+C set)", /* 493 */ NULL, /* 494 */ NULL, -/* 495 */ NULL, +/* 495 ERR_KICKNOREJOIN */ ":%s 495 %s %s :Cannot rejoin channel so soon after being kicked (+J set)", /* 496 */ NULL, /* 497 */ NULL, /* 498 */ NULL,