diff options
-rw-r--r-- | docs/inspircd.conf.example | 8 | ||||
-rw-r--r-- | include/configreader.h | 8 | ||||
-rw-r--r-- | include/mode.h | 10 | ||||
-rw-r--r-- | src/configreader.cpp | 3 | ||||
-rw-r--r-- | src/mode.cpp | 25 | ||||
-rw-r--r-- | src/modes/cmode_h.cpp | 2 | ||||
-rw-r--r-- | src/modes/cmode_o.cpp | 2 | ||||
-rw-r--r-- | src/modes/cmode_v.cpp | 3 | ||||
-rw-r--r-- | src/users.cpp | 16 |
9 files changed, 70 insertions, 7 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index 3cd1536e5..b7dcec7ad 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -522,6 +522,13 @@ # used in unreal. This is only useful on networks # # running the m_chanprotect module # # # +# cyclehosts - If this is set to true, yes or 1, then when a # +# user's hostname changes, they will appear to quit # +# and then rejoin with their new host. This prevents # +# clients from being confused by host changes, # +# especially in the case of bots, and it is # +# recommended that this option is enabled. # +# # # netbuffersize - size of the buffer used to receive data from # # clients. The ircd may only read() this amount # # of text in one go at any time. (OPTIONAL) # @@ -638,6 +645,7 @@ hideulines="no" nouserdns="no" syntaxhints="no" + cyclehosts="yes" allowhalfop="yes"> diff --git a/include/configreader.h b/include/configreader.h index 467b5bde3..5c8a66307 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -361,10 +361,14 @@ class ServerConfig : public Extensible */ bool SyntaxHints; + /** If set to true, users appear to quit then rejoin when their hosts change. + * This keeps clients synchronized properly. + */ + bool CycleHosts; + ServerConfig(InspIRCd* Instance); - /** Clears the include stack in preperation for - * a Read() call. + /** Clears the include stack in preperation for a Read() call. */ void ClearStack(); diff --git a/include/mode.h b/include/mode.h index b26c0d9c3..4cdab2884 100644 --- a/include/mode.h +++ b/include/mode.h @@ -445,6 +445,16 @@ class ModeParser : public classbase /** This returns the PREFIX=(ohv)@%+ section of the 005 numeric. */ std::string BuildPrefixes(); + + /** This returns the privilages of a user upon a channel, in the format of a mode change. + * For example, if a user has privilages +avh, this will return the string "avh nick nick nick". + * This is used by the core when cycling a user to refresh their hostname. You may use it for + * similar purposes. + * @param user The username to look up + * @param channel The channel name to look up the privilages of the user for + * @return The mode string. + */ + std::string ModeString(userrec* user, chanrec* channel); }; /** Command handler class for the MODE command. diff --git a/src/configreader.cpp b/src/configreader.cpp index a9e34a716..d8651766d 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -37,7 +37,7 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance) *OperOnlyStats = *ModPath = *MyExecutable = *DisabledCommands = *PID = '\0'; log_file = NULL; NoUserDns = forcedebug = OperSpyWhois = nofork = HideBans = HideSplits = false; - writelog = AllowHalfop = true; + CycleHosts = writelog = AllowHalfop = true; dns_timeout = DieDelay = 5; MaxTargets = 20; NetBufferSize = 10240; @@ -560,6 +560,7 @@ void ServerConfig::Read(bool bail, userrec* user) {"options", "tempdir", &this->TempDir, DT_CHARPTR, ValidateTempDir}, {"options", "nouserdns", &this->NoUserDns, DT_BOOLEAN, NoValidation}, {"options", "syntaxhints", &this->SyntaxHints, DT_BOOLEAN, NoValidation}, + {"options", "cyclehosts", &this->CycleHosts, DT_BOOLEAN, NoValidation}, {"pid", "file", &this->PID, DT_CHARPTR, NoValidation}, {NULL} }; diff --git a/src/mode.cpp b/src/mode.cpp index 8351ab2e0..5ae457b68 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -666,6 +666,31 @@ ModeHandler* ModeParser::FindPrefix(unsigned const char pfxletter) return NULL; } +std::string ModeParser::ModeString(userrec* user, chanrec* channel) +{ + std::string types; + std::string pars; + + for (unsigned char mode = 'A'; mode <= 'z'; mode++) + { + unsigned char pos = (mode-65) | MASK_CHANNEL; + ModeHandler* mh = modehandlers[pos]; + if ((mh) && (mh->GetNumParams(true)) && (mh->GetNumParams(false))) + { + ModePair ret; + ret = mh->ModeSet(NULL, user, channel, user->nick); + if (ret.first) + { + pars.append(" "); + pars.append(user->nick); + types.push_back(mh->GetModeChar()); + } + } + } + + return types+pars; +} + std::string ModeParser::ChanModes() { std::string type1; /* Listmodes EXCEPT those with a prefix */ diff --git a/src/modes/cmode_h.cpp b/src/modes/cmode_h.cpp index 1b0370439..d58fb94c9 100644 --- a/src/modes/cmode_h.cpp +++ b/src/modes/cmode_h.cpp @@ -28,7 +28,7 @@ ModePair ModeChannelHalfOp::ModeSet(userrec* source, userrec* dest, chanrec* cha userrec* x = ServerInstance->FindNick(parameter); if (x) { - if (channel->GetStatus(x) == STATUS_HOP) + if (channel->GetStatusFlags(x) & UCMODE_HOP) { return std::make_pair(true, x->nick); } diff --git a/src/modes/cmode_o.cpp b/src/modes/cmode_o.cpp index c631ec779..bed7da615 100644 --- a/src/modes/cmode_o.cpp +++ b/src/modes/cmode_o.cpp @@ -28,7 +28,7 @@ ModePair ModeChannelOp::ModeSet(userrec* source, userrec* dest, chanrec* channel userrec* x = ServerInstance->FindNick(parameter); if (x) { - if (channel->GetStatus(x) == STATUS_OP) + if (channel->GetStatusFlags(x) & UCMODE_OP) { return std::make_pair(true, x->nick); } diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp index 7b14d84d4..f12d9f9cf 100644 --- a/src/modes/cmode_v.cpp +++ b/src/modes/cmode_v.cpp @@ -7,7 +7,6 @@ #include "mode.h" #include "channels.h" #include "users.h" - #include "commands.h" #include "modules.h" #include "inspstring.h" @@ -28,7 +27,7 @@ ModePair ModeChannelVoice::ModeSet(userrec* source, userrec* dest, chanrec* chan userrec* x = ServerInstance->FindNick(parameter); if (x) { - if (channel->GetStatus(x) == STATUS_VOICE) + if (channel->GetStatusFlags(x) & UCMODE_VOICE) { return std::make_pair(true, x->nick); } diff --git a/src/users.cpp b/src/users.cpp index 085440367..031333dfc 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1632,8 +1632,24 @@ bool userrec::ChangeDisplayedHost(const char* host) return false; FOREACH_MOD(I_OnChangeHost,OnChangeHost(this,host)); } + if (this->ServerInstance->Config->CycleHosts) + this->WriteCommonExcept("QUIT :Changing hosts"); + strlcpy(this->dhost,host,63); + if (this->ServerInstance->Config->CycleHosts) + { + for (std::vector<ucrec*>::const_iterator i = this->chans.begin(); i != this->chans.end(); i++) + { + if ((*i)->channel) + { + (*i)->channel->WriteAllExceptSender(this, 0, "JOIN %s", (*i)->channel->name); + (*i)->channel->WriteChannelWithServ(this->ServerInstance->Config->ServerName, "MODE %s +%s", + (*i)->channel->name, this->ServerInstance->Modes->ModeString(this, (*i)->channel).c_str()); + } + } + } + if (IS_LOCAL(this)) this->WriteServ("396 %s %s :is now your hidden host",this->nick,this->dhost); |