diff --git a/include/znc/Modules.h b/include/znc/Modules.h
index c7dde8ee..f9ea0983 100644
--- a/include/znc/Modules.h
+++ b/include/znc/Modules.h
@@ -720,6 +720,10 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnUserTopicRequest(CString& sChannel);
+ /** This module hook is called when a user requests to quit from network.
+ * @param sMessage The quit message the client sent.
+ */
+ virtual void OnUserQuit(CString& sMessage);
/** Called when we receive a CTCP reply from IRC.
* @param Nick The nick the CTCP reply is from.
@@ -1190,6 +1194,7 @@ public:
bool OnUserPart(CString& sChannel, CString& sMessage);
bool OnUserTopic(CString& sChannel, CString& sTopic);
bool OnUserTopicRequest(CString& sChannel);
+ bool OnUserQuit(CString& sMessage);
bool OnCTCPReply(CNick& Nick, CString& sMessage);
bool OnPrivCTCP(CNick& Nick, CString& sMessage);
diff --git a/modules/modperl/functions.in b/modules/modperl/functions.in
index 64ed0b41..babfae5a 100644
--- a/modules/modperl/functions.in
+++ b/modules/modperl/functions.in
@@ -47,6 +47,7 @@ EModRet OnUserJoin(CString& sChannel, CString& sKey)
EModRet OnUserPart(CString& sChannel, CString& sMessage)
EModRet OnUserTopic(CString& sChannel, CString& sTopic)
EModRet OnUserTopicRequest(CString& sChannel)
+void OnUserQuit(CString& sMessage)
EModRet OnCTCPReply(CNick& Nick, CString& sMessage)
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage)
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage)
diff --git a/modules/modperl/module.h b/modules/modperl/module.h
index 28574708..a2c36cee 100644
--- a/modules/modperl/module.h
+++ b/modules/modperl/module.h
@@ -86,6 +86,7 @@ public:
virtual EModRet OnUserJoin(CString& sChannel, CString& sKey) override;
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage) override;
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) override;
+ virtual void OnUserQuit(CString& sMessage) override;
virtual EModRet OnUserTopicRequest(CString& sChannel) override;
virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override;
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override;
diff --git a/modules/modperl/startup.pl b/modules/modperl/startup.pl
index f47a465d..55d095ea 100644
--- a/modules/modperl/startup.pl
+++ b/modules/modperl/startup.pl
@@ -356,6 +356,7 @@ sub OnUserJoin {}
sub OnUserPart {}
sub OnUserTopic {}
sub OnUserTopicRequest {}
+sub OnUserQuit {}
sub OnCTCPReply {}
sub OnPrivCTCP {}
sub OnChanCTCP {}
diff --git a/modules/modpython/functions.in b/modules/modpython/functions.in
index 5bf893d2..264dd327 100644
--- a/modules/modpython/functions.in
+++ b/modules/modpython/functions.in
@@ -47,6 +47,7 @@ EModRet OnUserJoin(CString& sChannel, CString& sKey)
EModRet OnUserPart(CString& sChannel, CString& sMessage)
EModRet OnUserTopic(CString& sChannel, CString& sTopic)
EModRet OnUserTopicRequest(CString& sChannel)
+void OnUserQuit(CString& sMessage)
EModRet OnCTCPReply(CNick& Nick, CString& sMessage)
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage)
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage)
diff --git a/modules/modpython/module.h b/modules/modpython/module.h
index 97ed8230..0e3c9ce2 100644
--- a/modules/modpython/module.h
+++ b/modules/modpython/module.h
@@ -103,6 +103,7 @@ public:
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage) override;
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) override;
virtual EModRet OnUserTopicRequest(CString& sChannel) override;
+ virtual void OnUserQuit(CString& sMessage) override;
virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override;
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override;
virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override;
diff --git a/modules/modpython/znc.py b/modules/modpython/znc.py
index 81650f10..cd4de4b3 100644
--- a/modules/modpython/znc.py
+++ b/modules/modpython/znc.py
@@ -339,6 +339,9 @@ class Module:
def OnUserTopicRequest(self, sChannel):
pass
+ def OnUserQuit(self, sMessage):
+ pass
+
def OnCTCPReply(self, Nick, sMessage):
pass
diff --git a/src/Client.cpp b/src/Client.cpp
index fce77421..4c0c2a58 100644
--- a/src/Client.cpp
+++ b/src/Client.cpp
@@ -198,6 +198,8 @@ void CClient::ReadLine(const CString& sData) {
// Block PONGs, we already responded to the pings
return;
} else if (sCommand.Equals("QUIT")) {
+ CString sMsg = sLine.Token(1, true).TrimPrefix_n();
+ NETWORKMODULECALL(OnUserQuit(sMsg), m_pUser, m_pNetwork, this, NOTHING);
Close(Csock::CLT_AFTERWRITE); // Treat a client quit as a detach
return; // Don't forward this msg. We don't want the client getting us disconnected.
} else if (sCommand.Equals("PROTOCTL")) {
diff --git a/src/Modules.cpp b/src/Modules.cpp
index f7e9992b..30d94f50 100644
--- a/src/Modules.cpp
+++ b/src/Modules.cpp
@@ -693,6 +693,7 @@ CModule::EModRet CModule::OnUserJoin(CString& sChannel, CString& sKey) { return
CModule::EModRet CModule::OnUserPart(CString& sChannel, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnUserTopic(CString& sChannel, CString& sTopic) { return CONTINUE; }
CModule::EModRet CModule::OnUserTopicRequest(CString& sChannel) { return CONTINUE; }
+void CModule::OnUserQuit(CString& sMessage) {}
CModule::EModRet CModule::OnCTCPReply(CNick& Nick, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnPrivCTCP(CNick& Nick, CString& sMessage) { return CONTINUE; }
@@ -854,6 +855,7 @@ bool CModules::OnUserJoin(CString& sChannel, CString& sKey) { MODHALTCHK(OnUserJ
bool CModules::OnUserPart(CString& sChannel, CString& sMessage) { MODHALTCHK(OnUserPart(sChannel, sMessage)); }
bool CModules::OnUserTopic(CString& sChannel, CString& sTopic) { MODHALTCHK(OnUserTopic(sChannel, sTopic)); }
bool CModules::OnUserTopicRequest(CString& sChannel) { MODHALTCHK(OnUserTopicRequest(sChannel)); }
+bool CModules::OnUserQuit(CString& sMessage) { MODUNLOADCHK(OnUserQuit(sMessage)); return false; }
bool CModules::OnQuit(const CNick& Nick, const CString& sMessage, const vector& vChans) { MODUNLOADCHK(OnQuit(Nick, sMessage, vChans)); return false; }
bool CModules::OnNick(const CNick& Nick, const CString& sNewNick, const vector& vChans) { MODUNLOADCHK(OnNick(Nick, sNewNick, vChans)); return false; }