+ }
+
+ 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;
+ }
+ }
+ }
+
+ FOREACH_MOD_I(Instance,I_OnUserJoin,OnUserJoin(user, Ptr, bursting, silent));
+
+ if (!silent)
+ Ptr->WriteChannel(user,"JOIN :%s",Ptr->name.c_str());
+
+ /* Theyre not the first ones in here, make sure everyone else sees the modes we gave the user */
+ std::string ms = Instance->Modes->ModeString(user, Ptr);
+ if ((Ptr->GetUserCounter() > 1) && (ms.length()))
+ Ptr->WriteAllExceptSender(user, true, 0, "MODE %s +%s", Ptr->name.c_str(), ms.c_str());
+
+ /* Major improvement by Brain - we dont need to be calculating all this pointlessly for remote users */
+ if (IS_LOCAL(user))
+ {
+ if (Ptr->topicset)
+ {
+ user->WriteNumeric(RPL_TOPIC, "%s %s :%s", user->nick.c_str(), Ptr->name.c_str(), Ptr->topic.c_str());
+ user->WriteNumeric(RPL_TOPICTIME, "%s %s %s %lu", user->nick.c_str(), Ptr->name.c_str(), Ptr->setby.c_str(), (unsigned long)Ptr->topicset);
+ }