diff --git a/include/channels.h b/include/channels.h index 15b66e928..bdc273415 100644 --- a/include/channels.h +++ b/include/channels.h @@ -102,9 +102,10 @@ class CoreExport Channel : public Base, public Extensible /** Join a user internally to the channel * @param u The user + * @param status The status to give the user, if any * @return The UserContainer for the user */ - ChanUserContainer* JoinUser(User *u); + ChanUserContainer* JoinUser(User *u, const ChannelStatus *status); /** Remove a user internally from the channel * @param u The user diff --git a/include/modules.h b/include/modules.h index 286ba5246..c430767db 100644 --- a/include/modules.h +++ b/include/modules.h @@ -462,7 +462,10 @@ class CoreExport Module : public Extensible */ virtual void OnLeaveChannel(User *u, Channel *c) { throw NotImplementedException(); } - /** Called when a user joins a channel + /** Called after a user joins a channel + * If this event triggers the user is allowed to be in the channel, and will + * not be kicked for restricted/akick/forbidden, etc. If you want to kick the user, + * use the CheckKick event instead. * @param u The user * @param channel The channel */ diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index 116d5a5ac..a6871189c 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -288,17 +288,14 @@ class ChanServCore : public Module, public ChanServService { this->Hold(c); } - if (c->ci) - { - c->CheckModes(); - if (Me && Me->IsSynced()) + c->CheckModes(); + if (Me && Me->IsSynced() && c->ci) + { + /* Update channel topic */ + if ((c->ci->HasExt("KEEPTOPIC") || c->ci->HasExt("TOPICLOCK")) && c->ci->last_topic != c->topic) { - /* Update channel topic */ - if ((c->ci->HasExt("KEEPTOPIC") || c->ci->HasExt("TOPICLOCK")) && c->ci->last_topic != c->topic) - { - c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime); - } + c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime); } } } diff --git a/src/bots.cpp b/src/bots.cpp index 74cf0d9e4..e2c346837 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -176,7 +176,7 @@ void BotInfo::Join(Channel *c, ChannelStatus *status) if (c->FindUser(this) != NULL) return; - c->JoinUser(this); + c->JoinUser(this, status); if (IRCD) IRCD->SendJoin(this, c, status); } diff --git a/src/channels.cpp b/src/channels.cpp index ff060dce9..9fdc44a49 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -93,7 +93,7 @@ void Channel::Sync() void Channel::CheckModes() { - if (this->bouncy_modes) + if (this->bouncy_modes || this->syncing) return; /* Check for mode bouncing */ @@ -170,7 +170,7 @@ bool Channel::CheckDelete() return MOD_RESULT != EVENT_STOP && this->users.empty(); } -ChanUserContainer* Channel::JoinUser(User *user) +ChanUserContainer* Channel::JoinUser(User *user, const ChannelStatus *status) { if (user->server && user->server->IsSynced()) Log(user, this, "join"); @@ -178,8 +178,8 @@ ChanUserContainer* Channel::JoinUser(User *user) ChanUserContainer *cuc = new ChanUserContainer(user, this); user->chans[this] = cuc; this->users[user] = cuc; - - FOREACH_MOD(OnJoinChannel, (user, this)); + if (status) + cuc->status = *status; return cuc; } @@ -732,7 +732,7 @@ void Channel::KickInternal(MessageSource &source, const Anope::string &nick, con User *target = User::Find(nick); if (!target) { - Log() << "Channel::KickInternal got a nonexistent user " << nick << " on " << this->name << ": " << reason; + Log(LOG_DEBUG) << "Channel::KickInternal got a nonexistent user " << nick << " on " << this->name << ": " << reason; return; } @@ -746,7 +746,7 @@ void Channel::KickInternal(MessageSource &source, const Anope::string &nick, con ChanUserContainer *cu = target->FindChannel(this); if (cu == NULL) { - Log() << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name; + Log(LOG_DEBUG) << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name; return; } diff --git a/src/messages.cpp b/src/messages.cpp index ce92841e6..fcaeffa43 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -128,18 +128,18 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co User *u = it->second; /* Add the user to the channel */ - ChanUserContainer *cc = c->JoinUser(u); + c->JoinUser(u, keep_their_modes ? &status : NULL); - /* Update their status internally on the channel */ - if (keep_their_modes) - cc->status = status; + /* Check if the user is allowed to join */ + if (c->CheckKick(u)) + continue; /* Set whatever modes the user should have, and remove any that * they aren't allowed to have (secureops etc). */ c->SetCorrectModes(u, true); - - c->CheckKick(u); + + FOREACH_MOD(OnJoinChannel, (u, c)); } /* Channel is done syncing */