diff --git a/include/znc/IRCNetwork.h b/include/znc/IRCNetwork.h index 8b06069d..f9319691 100644 --- a/include/znc/IRCNetwork.h +++ b/include/znc/IRCNetwork.h @@ -45,6 +45,7 @@ public: ~CIRCNetwork(); enum { + JOIN_FREQUENCY = 30, /** How long must an IRC connection be idle before ZNC sends a ping */ PING_FREQUENCY = 270, /** Time between checks if PINGs need to be sent */ @@ -136,6 +137,7 @@ public: */ bool IsIRCConnected() const; void SetIRCSocket(CIRCSock* pIRCSock); + void IRCConnected(); void IRCDisconnected(); void CheckIRCConnect(); @@ -178,6 +180,9 @@ public: void SetFloodRate(double fFloodRate) { m_fFloodRate = fFloodRate; } void SetFloodBurst(unsigned short int uFloodBurst) { m_uFloodBurst = uFloodBurst; } + unsigned short int GetJoinDelay() const { return m_uJoinDelay; } + void SetJoinDelay(unsigned short int uJoinDelay) { m_uJoinDelay = uJoinDelay; } + CString ExpandString(const CString& sStr) const; CString& ExpandString(const CString& sStr, CString& sRet) const; private: @@ -223,6 +228,8 @@ protected: CIRCNetworkPingTimer* m_pPingTimer; CIRCNetworkJoinTimer* m_pJoinTimer; + + unsigned short int m_uJoinDelay; }; #endif // !_IRCNETWORK_H diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index ae3f6809..4e02e628 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -60,22 +60,31 @@ private: class CIRCNetworkJoinTimer : public CCron { public: - CIRCNetworkJoinTimer(CIRCNetwork *pNetwork) : CCron() { - m_pNetwork = pNetwork; + CIRCNetworkJoinTimer(CIRCNetwork *pNetwork) : CCron(), m_bDelayed(false), m_pNetwork(pNetwork) { SetName("CIRCNetworkJoinTimer::" + m_pNetwork->GetUser()->GetUserName() + "::" + m_pNetwork->GetName()); - Start(30); + Start(CIRCNetwork::JOIN_FREQUENCY); } virtual ~CIRCNetworkJoinTimer() {} + void Delay(unsigned short int uDelay) { + m_bDelayed = true; + Start(uDelay); + } + protected: virtual void RunJob() { + if (m_bDelayed) { + m_bDelayed = false; + Start(CIRCNetwork::JOIN_FREQUENCY); + } if (m_pNetwork->IsIRCConnected()) { m_pNetwork->JoinChans(); } } private: + bool m_bDelayed; CIRCNetwork* m_pNetwork; }; @@ -115,6 +124,8 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CString& sName) { m_fFloodRate = 1; m_uFloodBurst = 4; + m_uJoinDelay = 0; + m_RawBuffer.SetLineCount(100, true); // This should be more than enough raws, especially since we are buffering the MOTD separately m_MotdBuffer.SetLineCount(200, true); // This should be more than enough motd lines m_NoticeBuffer.SetLineCount(250, true); @@ -155,6 +166,7 @@ void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneName) { m_fFloodRate = Network.GetFloodRate(); m_uFloodBurst = Network.GetFloodBurst(); + m_uJoinDelay = Network.GetJoinDelay(); SetNick(Network.GetNick()); SetAltNick(Network.GetAltNick()); @@ -346,6 +358,7 @@ bool CIRCNetwork::ParseConfig(CConfig *pConfig, CString& sError, bool bUpgrade) size_t numDoubleOptions = sizeof(DoubleOptions) / sizeof(DoubleOptions[0]); TOption SUIntOptions[] = { { "floodburst", &CIRCNetwork::SetFloodBurst }, + { "joindelay", &CIRCNetwork::SetJoinDelay }, }; size_t numSUIntOptions = sizeof(SUIntOptions) / sizeof(SUIntOptions[0]); @@ -480,6 +493,7 @@ CConfig CIRCNetwork::ToConfig() const { config.AddKeyValuePair("IRCConnectEnabled", CString(GetIRCConnectEnabled())); config.AddKeyValuePair("FloodRate", CString(GetFloodRate())); config.AddKeyValuePair("FloodBurst", CString(GetFloodBurst())); + config.AddKeyValuePair("JoinDelay", CString(GetJoinDelay())); config.AddKeyValuePair("Encoding", m_sEncoding); if (!m_sQuitMsg.empty()) { @@ -1190,6 +1204,14 @@ void CIRCNetwork::SetIRCSocket(CIRCSock* pIRCSock) { m_pIRCSock = pIRCSock; } +void CIRCNetwork::IRCConnected() { + if (m_uJoinDelay > 0) { + m_pJoinTimer->Delay(m_uJoinDelay); + } else { + JoinChans(); + } +} + void CIRCNetwork::IRCDisconnected() { m_pIRCSock = NULL; diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index 0fdde95d..6d9609fd 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -200,9 +200,7 @@ void CIRCSock::ReadLine(const CString& sData) { m_pNetwork->ClearRawBuffer(); m_pNetwork->AddRawBuffer(":" + _NAMEDFMT(sServer) + " " + sCmd + " {target} " + _NAMEDFMT(sRest)); - // Join the first set of channels as soon as we are connected - // and let the CIRCNetworkJoinTimer join the rest. - m_pNetwork->JoinChans(); + m_pNetwork->IRCConnected(); break; }