+void User::DoHostCycle(const std::string &quitline)
+{
+ char buffer[MAXBUF];
+
+ if (!ServerInstance->Config->CycleHosts)
+ return;
+
+ uniq_id_t silent_id = ++already_sent;
+ uniq_id_t seen_id = ++already_sent;
+
+ UserChanList include_c(chans);
+ std::map<User*,bool> exceptions;
+
+ FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions));
+
+ for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
+ {
+ User* u = i->first;
+ if (IS_LOCAL(u) && !u->quitting)
+ {
+ if (i->second)
+ {
+ already_sent[u->fd] = seen_id;
+ u->Write(quitline);
+ }
+ else
+ {
+ already_sent[u->fd] = silent_id;
+ }
+ }
+ }
+ for (UCListIter v = include_c.begin(); v != include_c.end(); ++v)
+ {
+ Channel* c = *v;
+ snprintf(buffer, MAXBUF, ":%s JOIN %s", GetFullHost().c_str(), c->name.c_str());
+ std::string joinline(buffer);
+ std::string modeline = ServerInstance->Modes->ModeString(this, c);
+ if (modeline.length() > 0)
+ {
+ snprintf(buffer, MAXBUF, ":%s MODE %s +%s", GetFullHost().c_str(), c->name.c_str(), modeline.c_str());
+ modeline = buffer;
+ }
+
+ const UserMembList *ulist = c->GetUsers();
+ for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
+ {
+ User* u = i->first;
+ if (u == this || !IS_LOCAL(u))
+ continue;
+ if (already_sent[u->fd] == silent_id)
+ continue;
+
+ if (already_sent[u->fd] != seen_id)
+ {
+ u->Write(quitline);
+ already_sent[i->first->fd] = seen_id;
+ }
+ u->Write(joinline);
+ if (modeline.length() > 0)
+ u->Write(modeline);
+ }
+ }
+}
+