+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)
+ {
+ LocalUser* u = IS_LOCAL(i->first);
+ if (u && !u->quitting)
+ {
+ if (i->second)
+ {
+ already_sent[u->GetFd()] = seen_id;
+ u->Write(quitline);
+ }
+ else
+ {
+ already_sent[u->GetFd()] = 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);
+ Membership* memb = c->GetUser(this);
+ std::string modeline = memb->modes;
+ if (modeline.length() > 0)
+ {
+ for(unsigned int i=0; i < memb->modes.length(); i++)
+ modeline.append(" ").append(nick);
+ 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++)
+ {
+ LocalUser* u = IS_LOCAL(i->first);
+ if (u == NULL || u == this)
+ continue;
+ if (already_sent[u->GetFd()] == silent_id)
+ continue;
+
+ if (already_sent[u->GetFd()] != seen_id)
+ {
+ u->Write(quitline);
+ already_sent[u->GetFd()] = seen_id;
+ }
+ u->Write(joinline);
+ if (modeline.length() > 0)
+ u->Write(modeline);
+ }
+ }
+}
+