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 @@
IF FloodProtection ?> value=" VAR FloodBurst ?>" ELSE ?> value="4" disabled="disabled" ENDIF ?>
/> 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;
}