diff --git a/include/znc/Modules.h b/include/znc/Modules.h index 7f9b7cd3..32a83407 100644 --- a/include/znc/Modules.h +++ b/include/znc/Modules.h @@ -563,6 +563,12 @@ public: virtual EModRet OnRaw(CString& sLine); virtual EModRet OnRawMessage(CMessage& Message); + /** Called when a numeric message is received from the IRC server. + * @param Message The received message. + * @return See CModule::EModRet. + */ + virtual EModRet OnNumericMessage(CNumericMessage& Message); + /** Called when a command to *status is sent. * @param sCommand The command sent. * @return See CModule::EModRet. @@ -1211,6 +1217,7 @@ public: bool OnRaw(CString& sLine); bool OnRawMessage(CMessage& Message); + bool OnNumericMessage(CNumericMessage& Message); bool OnStatusCommand(CString& sCommand); bool OnModCommand(const CString& sCommand); diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index cb0e6da1..d92a0a7d 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -652,6 +652,10 @@ bool CIRCSock::OnNumericMessage(CNumericMessage& Message) { CString sRest = Message.GetParams(1); CString sTmp; + bool bResult = false; + IRCSOCKMODULECALL(OnNumericMessage(Message), &bResult); + if (bResult) return true; + switch (uRaw) { case 1: { // :irc.server.com 001 nick :Welcome to the Internet Relay Network nick if (m_bAuthed && sServer == "irc.znc.in") { diff --git a/src/Modules.cpp b/src/Modules.cpp index 638d1566..634e1fdf 100644 --- a/src/Modules.cpp +++ b/src/Modules.cpp @@ -618,6 +618,7 @@ void CModule::OnMode(const CNick& pOpNick, CChan& Channel, char uMode, const CSt CModule::EModRet CModule::OnRaw(CString& sLine) { return CONTINUE; } CModule::EModRet CModule::OnRawMessage(CMessage& Message) { return CONTINUE; } +CModule::EModRet CModule::OnNumericMessage(CNumericMessage& Message) { return CONTINUE; } CModule::EModRet CModule::OnStatusCommand(CString& sCommand) { return CONTINUE; } void CModule::OnModNotice(const CString& sMessage) {} @@ -971,6 +972,7 @@ bool CModules::OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, const C bool CModules::OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange) { MODUNLOADCHK(OnMode(OpNick, Channel, uMode, sArg, bAdded, bNoChange)); return false; } bool CModules::OnRaw(CString& sLine) { MODHALTCHK(OnRaw(sLine)); } bool CModules::OnRawMessage(CMessage& Message) { MODHALTCHK(OnRawMessage(Message)); } +bool CModules::OnNumericMessage(CNumericMessage& Message) { MODHALTCHK(OnNumericMessage(Message)); } bool CModules::OnClientLogin() { MODUNLOADCHK(OnClientLogin()); return false; } bool CModules::OnClientDisconnect() { MODUNLOADCHK(OnClientDisconnect()); return false; } diff --git a/test/IRCSockTest.cpp b/test/IRCSockTest.cpp index 5b42ed4e..f2b024f6 100644 --- a/test/IRCSockTest.cpp +++ b/test/IRCSockTest.cpp @@ -58,6 +58,7 @@ public: EModRet OnPrivNoticeMessage(CNoticeMessage& msg) override { vsHooks.push_back("OnPrivNoticeMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); return eAction; } EModRet OnChanNoticeMessage(CNoticeMessage& msg) override { vsHooks.push_back("OnChanNoticeMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); return eAction; } EModRet OnTopicMessage(CTopicMessage& msg) override { vsHooks.push_back("OnTopicMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); return eAction; } + EModRet OnNumericMessage(CNumericMessage& msg) override { vsHooks.push_back("OnNumericMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); return eAction; } void OnJoinMessage(CJoinMessage& msg) override { vsHooks.push_back("OnJoinMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); } void OnKickMessage(CKickMessage& msg) override { vsHooks.push_back("OnKickMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); } void OnNickMessage(CNickMessage& msg, const std::vector& vChans) override { vsHooks.push_back("OnNickMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); } @@ -325,6 +326,23 @@ TEST_F(IRCSockTest, OnNoticeMessage) { EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } +TEST_F(IRCSockTest, OnNumericMessage) { + CMessage msg(":irc.server.com 372 nick :motd"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); + + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnNumericMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); + + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); +} + TEST_F(IRCSockTest, OnPartMessage) { CMessage msg(":nick PART #chan :reason"); m_pTestSock->ReadLine(msg.ToString()); diff --git a/test/ModulesTest.cpp b/test/ModulesTest.cpp index 1eed6e9a..688c35bd 100644 --- a/test/ModulesTest.cpp +++ b/test/ModulesTest.cpp @@ -76,6 +76,7 @@ public: EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetText("CMessageModule::OnPrivNoticeMessage"); return eAction; } EModRet OnChanNoticeMessage(CNoticeMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetText("CMessageModule::OnChanNoticeMessage"); return eAction; } EModRet OnTopicMessage(CTopicMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetTopic("CMessageModule::OnTopicMessage"); return eAction; } + EModRet OnNumericMessage(CNumericMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetCommand("123"); return eAction; } EModRet eAction = CONTINUE; }; @@ -277,5 +278,10 @@ TEST_F(ModulesTest, Hooks) { EXPECT_EQ("nick", TopicMsg.GetNick().GetNick()); EXPECT_EQ("CMessageModule::OnTopicMessage", TopicMsg.GetTopic()); + CNumericMessage NumericMsg; + Modules.OnNumericMessage(NumericMsg); + EXPECT_EQ("nick", TopicMsg.GetNick().GetNick()); + EXPECT_EQ(123u, NumericMsg.GetCode()); + Modules.clear(); }