+
+ /*
+ * If the user has invites for this channel, remove them now
+ * after a successful join so they don't build up.
+ */
+ if (invited)
+ {
+ user->RemoveInvite(Ptr->name.c_str());
+ }
+ }
+ }
+ }
+
+ if (created_by_local)
+ {
+ /* As spotted by jilles, dont bother to set this on remote users */
+ Ptr->SetDefaultModes();
+ }
+
+ return Channel::ForceChan(Instance, Ptr, user, privs, bursting);
+}
+
+Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const std::string &privs, bool bursting)
+{
+ std::string nick = user->nick;
+ bool silent = false;
+
+ Ptr->AddUser(user);
+
+ /* Just in case they have no permissions */
+ user->chans[Ptr] = 0;
+
+ for (std::string::const_iterator x = privs.begin(); x != privs.end(); x++)
+ {
+ const char status = *x;
+ ModeHandler* mh = Instance->Modes->FindPrefix(status);
+ if (mh)
+ {
+ /* Set, and make sure that the mode handler knows this mode was now set */
+ Ptr->SetPrefix(user, status, mh->GetPrefixRank(), true);
+ mh->OnModeChange(Instance->FakeClient, Instance->FakeClient, Ptr, nick, true);
+
+ switch (mh->GetPrefix())
+ {
+ /* These logic ops are SAFE IN THIS CASE because if the entry doesnt exist,
+ * addressing operator[] creates it. If they do exist, it points to it.
+ * At all other times where we dont want to create an item if it doesnt exist, we
+ * must stick to ::find().
+ */
+ case '@':
+ user->chans[Ptr] |= UCMODE_OP;
+ break;
+ case '%':
+ user->chans[Ptr] |= UCMODE_HOP;
+ break;
+ case '+':
+ user->chans[Ptr] |= UCMODE_VOICE;
+ break;