diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configreader.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_hostcycle.cpp | 114 | ||||
-rw-r--r-- | src/users.cpp | 77 |
3 files changed, 116 insertions, 79 deletions
diff --git a/src/configreader.cpp b/src/configreader.cpp index d2291556c..047a2b5cd 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -32,7 +32,7 @@ ServerConfig::ServerConfig() { RawLog = HideBans = HideSplits = UndernetMsgPrefix = false; - WildcardIPv6 = CycleHosts = InvBypassModes = true; + WildcardIPv6 = InvBypassModes = true; dns_timeout = 5; MaxTargets = 20; NetBufferSize = 10240; @@ -349,6 +349,7 @@ static const DeprecatedConfig ChangedConfig[] = { { "link", "transport", "", "has been moved to <link:ssl> as of 2.0" }, { "module", "name", "m_chanprotect.so", "has been replaced with m_customprefix as of 2.2" }, { "module", "name", "m_halfop.so", "has been replaced with m_customprefix as of 2.2" }, + { "options", "cyclehosts", "", "has been replaced with m_hostcycle as of 2.2" }, { "performance", "nouserdns", "", "has been moved to <connect:nouserdns> as of 2.2" } }; @@ -405,7 +406,6 @@ void ServerConfig::Fill() RestrictBannedUsers = security->getBool("restrictbannedusers", true); GenericOper = security->getBool("genericoper"); SyntaxHints = options->getBool("syntaxhints"); - CycleHosts = options->getBool("cyclehosts"); CycleHostsFromUser = options->getBool("cyclehostsfromuser"); UndernetMsgPrefix = options->getBool("ircumsgprefix"); FullHostInTopic = options->getBool("hostintopic"); diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp new file mode 100644 index 000000000..79b4169ec --- /dev/null +++ b/src/modules/m_hostcycle.cpp @@ -0,0 +1,114 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com> + * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org> + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "inspircd.h" + +class ModuleHostCycle : public Module +{ + /** Send fake quit/join/mode messages for host or ident cycle. + */ + static void DoHostCycle(User* user, const std::string& newident, const std::string& newhost, const char* quitmsg) + { + // GetFullHost() returns the original data at the time this function is called + const std::string quitline = ":" + user->GetFullHost() + " QUIT :" + quitmsg; + + already_sent_t silent_id = ++LocalUser::already_sent_id; + already_sent_t seen_id = ++LocalUser::already_sent_id; + + UserChanList include_chans(user->chans); + std::map<User*,bool> exceptions; + + FOREACH_MOD(OnBuildNeighborList, (user, include_chans, 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) + { + u->already_sent = seen_id; + u->Write(quitline); + } + else + { + u->already_sent = silent_id; + } + } + } + + std::string newfullhost = user->nick + "!" + newident + "@" + newhost; + + for (UCListIter i = include_chans.begin(); i != include_chans.end(); ++i) + { + Channel* c = *i; + Membership* memb = c->GetUser(user); + const std::string joinline = ":" + newfullhost + " JOIN " + c->name; + std::string modeline; + + if (!memb->modes.empty()) + { + modeline = ":" + (ServerInstance->Config->CycleHostsFromUser ? newfullhost : ServerInstance->Config->ServerName) + + " MODE " + c->name + " +" + memb->modes; + + for (size_t j = 0; j < memb->modes.length(); j++) + modeline.append(" ").append(user->nick); + } + + const UserMembList* ulist = c->GetUsers(); + for (UserMembList::const_iterator j = ulist->begin(); j != ulist->end(); ++j) + { + LocalUser* u = IS_LOCAL(j->first); + if (u == NULL || u == user) + continue; + if (u->already_sent == silent_id) + continue; + + if (u->already_sent != seen_id) + { + u->Write(quitline); + u->already_sent = seen_id; + } + + u->Write(joinline); + if (!memb->modes.empty()) + u->Write(modeline); + } + } + } + + public: + void OnChangeIdent(User* user, const std::string& newident) CXX11_OVERRIDE + { + DoHostCycle(user, newident, user->dhost, "Changing ident"); + } + + void OnChangeHost(User* user, const std::string& newhost) CXX11_OVERRIDE + { + DoHostCycle(user, user->ident, newhost, "Changing host"); + } + + Version GetVersion() CXX11_OVERRIDE + { + return Version("Cycles users in all their channels when their host or ident changes", VF_VENDOR); + } +}; + +MODULE_INIT(ModuleHostCycle) diff --git a/src/users.cpp b/src/users.cpp index 371fa3bb6..bb7588fb2 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1124,72 +1124,6 @@ bool User::ChangeName(const char* gecos) return true; } -void User::DoHostCycle(const std::string &quitline) -{ - if (!ServerInstance->Config->CycleHosts) - return; - - already_sent_t silent_id = ++LocalUser::already_sent_id; - already_sent_t seen_id = ++LocalUser::already_sent_id; - - UserChanList include_c(chans); - std::map<User*,bool> exceptions; - - FOREACH_MOD(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) - { - u->already_sent = seen_id; - u->Write(quitline); - } - else - { - u->already_sent = silent_id; - } - } - } - for (UCListIter v = include_c.begin(); v != include_c.end(); ++v) - { - Channel* c = *v; - Membership* memb = c->GetUser(this); - const std::string joinline = ":" + GetFullHost() + " JOIN " + c->name; - std::string modeline; - - if (!memb->modes.empty()) - { - modeline = ":" + (ServerInstance->Config->CycleHostsFromUser ? GetFullHost() : ServerInstance->Config->ServerName) - + " MODE " + c->name + " +" + memb->modes; - - for (size_t i = 0; i < memb->modes.length(); i++) - modeline.append(" ").append(nick); - } - - 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 (u->already_sent == silent_id) - continue; - - if (u->already_sent != seen_id) - { - u->Write(quitline); - u->already_sent = seen_id; - } - u->Write(joinline); - if (!memb->modes.empty()) - u->Write(modeline); - } - } -} - bool User::ChangeDisplayedHost(const char* shost) { if (dhost == shost) @@ -1205,15 +1139,9 @@ bool User::ChangeDisplayedHost(const char* shost) FOREACH_MOD(OnChangeHost, (this,shost)); - std::string quitstr = ":" + GetFullHost() + " QUIT :Changing host"; - - /* Fix by Om: User::dhost is 65 long, this was truncating some long hosts */ this->dhost.assign(shost, 0, 64); - this->InvalidateCache(); - this->DoHostCycle(quitstr); - if (IS_LOCAL(this)) this->WriteNumeric(RPL_YOURDISPLAYEDHOST, "%s %s :is now your displayed host",this->nick.c_str(),this->dhost.c_str()); @@ -1227,14 +1155,9 @@ bool User::ChangeIdent(const char* newident) FOREACH_MOD(OnChangeIdent, (this,newident)); - std::string quitstr = ":" + GetFullHost() + " QUIT :Changing ident"; - this->ident.assign(newident, 0, ServerInstance->Config->Limits.IdentMax); - this->InvalidateCache(); - this->DoHostCycle(quitstr); - return true; } |