2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
5 * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
7 * This file is part of InspIRCd. InspIRCd is free software: you can
8 * redistribute it and/or modify it under the terms of the GNU General Public
9 * License as published by the Free Software Foundation, version 2.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 class ModuleHostCycle : public Module
25 /** Send fake quit/join/mode messages for host or ident cycle.
27 static void DoHostCycle(User* user, const std::string& newident, const std::string& newhost, const char* quitmsg)
29 // GetFullHost() returns the original data at the time this function is called
30 const std::string quitline = ":" + user->GetFullHost() + " QUIT :" + quitmsg;
32 already_sent_t silent_id = ++LocalUser::already_sent_id;
33 already_sent_t seen_id = ++LocalUser::already_sent_id;
35 IncludeChanList include_chans(user->chans.begin(), user->chans.end());
36 std::map<User*,bool> exceptions;
38 FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions));
40 for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
42 LocalUser* u = IS_LOCAL(i->first);
43 if (u && !u->quitting)
47 u->already_sent = seen_id;
52 u->already_sent = silent_id;
57 std::string newfullhost = user->nick + "!" + newident + "@" + newhost;
59 for (IncludeChanList::const_iterator i = include_chans.begin(); i != include_chans.end(); ++i)
61 Membership* memb = *i;
62 Channel* c = memb->chan;
63 const std::string joinline = ":" + newfullhost + " JOIN " + c->name;
66 if (!memb->modes.empty())
68 modeline = ":" + (ServerInstance->Config->CycleHostsFromUser ? newfullhost : ServerInstance->Config->ServerName)
69 + " MODE " + c->name + " +" + memb->modes;
71 for (size_t j = 0; j < memb->modes.length(); j++)
72 modeline.append(" ").append(user->nick);
75 const Channel::MemberMap& ulist = c->GetUsers();
76 for (Channel::MemberMap::const_iterator j = ulist.begin(); j != ulist.end(); ++j)
78 LocalUser* u = IS_LOCAL(j->first);
79 if (u == NULL || u == user)
81 if (u->already_sent == silent_id)
84 if (u->already_sent != seen_id)
87 u->already_sent = seen_id;
91 if (!memb->modes.empty())
98 void OnChangeIdent(User* user, const std::string& newident) CXX11_OVERRIDE
100 DoHostCycle(user, newident, user->dhost, "Changing ident");
103 void OnChangeHost(User* user, const std::string& newhost) CXX11_OVERRIDE
105 DoHostCycle(user, user->ident, newhost, "Changing host");
108 Version GetVersion() CXX11_OVERRIDE
110 return Version("Cycles users in all their channels when their host or ident changes", VF_VENDOR);
114 MODULE_INIT(ModuleHostCycle)