diff --git a/include/znc/IRCNetwork.h b/include/znc/IRCNetwork.h index 5d6f2dbc..162a456d 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: @@ -224,6 +229,8 @@ protected: CIRCNetworkPingTimer* m_pPingTimer; CIRCNetworkJoinTimer* m_pJoinTimer; + + unsigned short int m_uJoinDelay; }; #endif // !_IRCNETWORK_H diff --git a/modules/controlpanel.cpp b/modules/controlpanel.cpp index d1b28b51..8ec5a513 100644 --- a/modules/controlpanel.cpp +++ b/modules/controlpanel.cpp @@ -114,6 +114,7 @@ class CAdminMod : public CModule { {"BindHost", str}, {"FloodRate", doublenum}, {"FloodBurst", integer}, + {"JoinDelay", integer}, #ifdef HAVE_ICU {"Encoding", str}, #endif @@ -498,6 +499,8 @@ class CAdminMod : public CModule { PutModule("FloodRate = " + CString(pNetwork->GetFloodRate())); } else if (sVar.Equals("floodburst")) { PutModule("FloodBurst = " + CString(pNetwork->GetFloodBurst())); + } else if (sVar.Equals("joindelay")) { + PutModule("JoinDelay = " + CString(pNetwork->GetJoinDelay())); #ifdef HAVE_ICU } else if (sVar.Equals("encoding")) { PutModule("Encoding = " + pNetwork->GetEncoding()); @@ -587,6 +590,9 @@ class CAdminMod : public CModule { } else if (sVar.Equals("floodburst")) { pNetwork->SetFloodBurst(sValue.ToUShort()); PutModule("FloodBurst = " + CString(pNetwork->GetFloodBurst())); + } else if (sVar.Equals("joindelay")) { + pNetwork->SetJoinDelay(sValue.ToUShort()); + PutModule("JoinDelay = " + CString(pNetwork->GetJoinDelay())); #ifdef HAVE_ICU } else if (sVar.Equals("encoding")) { pNetwork->SetEncoding(sValue); diff --git a/modules/data/webadmin/tmpl/add_edit_network.tmpl b/modules/data/webadmin/tmpl/add_edit_network.tmpl index 0ef92c55..e30b6de5 100644 --- a/modules/data/webadmin/tmpl/add_edit_network.tmpl +++ b/modules/data/webadmin/tmpl/add_edit_network.tmpl @@ -104,6 +104,14 @@ value="" value="4" disabled="disabled" /> lines can be sent immediately + +
+
Channel join delay:
+ seconds +
diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index 15a31d07..455e5586 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -821,6 +821,8 @@ public: Tmpl["FloodRate"] = CString(pNetwork->GetFloodRate()); Tmpl["FloodBurst"] = CString(pNetwork->GetFloodBurst()); + Tmpl["JoinDelay"] = CString(pNetwork->GetJoinDelay()); + Tmpl["IRCConnectEnabled"] = CString(pNetwork->GetIRCConnectEnabled()); const vector& vServers = pNetwork->GetServers(); @@ -863,6 +865,7 @@ public: Tmpl["FloodProtection"] = "true"; Tmpl["FloodRate"] = "1.0"; Tmpl["FloodBurst"] = "4"; + Tmpl["JoinDelay"] = "0"; } FOR_EACH_MODULE(i, make_pair(pUser, pNetwork)) { @@ -946,6 +949,8 @@ public: pNetwork->SetFloodRate(-1); } + pNetwork->SetJoinDelay(WebSock.GetParam("joindelay").ToUShort()); + VCString vsArgs; pNetwork->DelServers(); diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index 1e17cfe3..ea260c13 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -61,22 +61,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; }; @@ -116,6 +125,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); @@ -156,6 +167,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()); @@ -347,6 +359,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]); @@ -489,6 +502,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()) { @@ -1199,6 +1213,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; }