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; }