From 453401eef463525c6967a7e066691954f3ce4a9b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 2 Sep 2015 00:08:43 +0200 Subject: [PATCH 1/3] Implement CClient::HandleCap() using CMessage (ref #1013) --- include/znc/Client.h | 2 +- src/Client.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/znc/Client.h b/include/znc/Client.h index 95691af9..f76fdbd1 100644 --- a/include/znc/Client.h +++ b/include/znc/Client.h @@ -246,7 +246,7 @@ public: CIRCSock* GetIRCSock(); CString GetFullName() const; private: - void HandleCap(const CString& sLine); + void HandleCap(const CMessage& Message); void RespondCap(const CString& sResponse); void ParsePass(const CString& sAuthLine); void ParseUser(const CString& sAuthLine); diff --git a/src/Client.cpp b/src/Client.cpp index 3f70c35f..726ed424 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -159,7 +159,7 @@ void CClient::ReadLine(const CString& sData) { } if (sCommand.Equals("CAP")) { - HandleCap(sLine); + HandleCap(Message); // Don't let the client talk to the server directly about CAP, // we don't want anything enabled that ZNC does not support. @@ -865,10 +865,9 @@ void CClient::RespondCap(const CString& sResponse) PutClient(":irc.znc.in CAP " + GetNick() + " " + sResponse); } -void CClient::HandleCap(const CString& sLine) +void CClient::HandleCap(const CMessage& Message) { - // This is not exactly correct, but this is protection from "CAP :END" - CString sSubCmd = sLine.Token(1).TrimPrefix_n(":"); + CString sSubCmd = Message.GetParam(0); if (sSubCmd.Equals("LS")) { SCString ssOfferCaps; @@ -881,7 +880,7 @@ void CClient::HandleCap(const CString& sLine) CString sRes = CString(" ").Join(ssOfferCaps.begin(), ssOfferCaps.end()); RespondCap("LS :" + sRes); m_bInCap = true; - if (sLine.Token(2).ToInt() >= 302) { + if (Message.GetParam(1).ToInt() >= 302) { m_bCapNotify = true; } } else if (sSubCmd.Equals("END")) { @@ -895,7 +894,7 @@ void CClient::HandleCap(const CString& sLine) } } else if (sSubCmd.Equals("REQ")) { VCString vsTokens; - sLine.Token(2, true).TrimPrefix_n(":").Split(" ", vsTokens, false); + Message.GetParam(1).Split(" ", vsTokens, false); for (const CString& sToken : vsTokens) { bool bVal = true; @@ -913,7 +912,7 @@ void CClient::HandleCap(const CString& sLine) if (!bAccepted) { // Some unsupported capability is requested - RespondCap("NAK :" + sLine.Token(2, true).TrimPrefix_n(":")); + RespondCap("NAK :" + Message.GetParam(1)); return; } } @@ -939,7 +938,7 @@ void CClient::HandleCap(const CString& sLine) } } - RespondCap("ACK :" + sLine.Token(2, true).TrimPrefix_n(":")); + RespondCap("ACK :" + Message.GetParam(1)); } else if (sSubCmd.Equals("LIST")) { CString sList = CString(" ").Join(m_ssAcceptedCaps.begin(), m_ssAcceptedCaps.end()); RespondCap("LIST :" + sList); From a79acacfad21bac3e4dfb6efb5a10c53475ab24e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 1 Sep 2015 23:51:41 +0200 Subject: [PATCH 2/3] Add missing CModules::OnCTCPReplyMessage() --- include/znc/IRCSock.h | 2 +- include/znc/Modules.h | 2 ++ src/IRCSock.cpp | 13 ++++--------- src/Modules.cpp | 7 +++++++ test/ModulesTest.cpp | 12 ++++++++++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/znc/IRCSock.h b/include/znc/IRCSock.h index 2c47bade..0e32f599 100644 --- a/include/znc/IRCSock.h +++ b/include/znc/IRCSock.h @@ -49,7 +49,7 @@ public: } EChanModeArgs; // Message Handlers - bool OnCTCPReply(CNick& Nick, CString& sMessage); + bool OnCTCPReply(CMessage& Message); bool OnPrivCTCP(CMessage& Message); bool OnChanCTCP(CMessage& Message); bool OnGeneralCTCP(CMessage& Message); diff --git a/include/znc/Modules.h b/include/znc/Modules.h index 183d6e05..7f9b7cd3 100644 --- a/include/znc/Modules.h +++ b/include/znc/Modules.h @@ -762,6 +762,7 @@ public: * @return See CModule::EModRet. */ virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage); + virtual EModRet OnCTCPReplyMessage(CCTCPMessage& Message); /** Called when we receive a private CTCP request from IRC. * @param Nick The nick the CTCP request is from. * @param sMessage The CTCP request message. @@ -1263,6 +1264,7 @@ public: bool OnUserQuitMessage(CQuitMessage& Message); bool OnCTCPReply(CNick& Nick, CString& sMessage); + bool OnCTCPReplyMessage(CCTCPMessage& Message); bool OnPrivCTCP(CNick& Nick, CString& sMessage); bool OnPrivCTCPMessage(CCTCPMessage& Message); bool OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage); diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index 8c016b66..097d077c 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -707,17 +707,11 @@ void CIRCSock::ReadLine(const CString& sData) { CString sMsg = Message.GetParam(1); if (sMsg.WildCmp("\001*\001")) { - sMsg.LeftChomp(); - sMsg.RightChomp(); - if (sTarget.Equals(GetNick())) { - if (OnCTCPReply(Nick, sMsg)) { + if (OnCTCPReply(Message)) { return; } } - - m_pNetwork->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :\001" + sMsg + "\001"); - return; } else { if (sTarget.Equals(GetNick())) { if (OnPrivNotice(Message)) { @@ -909,9 +903,10 @@ bool CIRCSock::OnServerCapAvailable(const CString& sCap) { return bResult; } -bool CIRCSock::OnCTCPReply(CNick& Nick, CString& sMessage) { +bool CIRCSock::OnCTCPReply(CMessage& Message) { + CCTCPMessage& CTCP = static_cast(Message); bool bResult = false; - IRCSOCKMODULECALL(OnCTCPReply(Nick, sMessage), &bResult); + IRCSOCKMODULECALL(OnCTCPReplyMessage(CTCP), &bResult); return bResult; } diff --git a/src/Modules.cpp b/src/Modules.cpp index 48f47937..638d1566 100644 --- a/src/Modules.cpp +++ b/src/Modules.cpp @@ -766,6 +766,12 @@ CModule::EModRet CModule::OnUserQuitMessage(CQuitMessage& Message) { } CModule::EModRet CModule::OnCTCPReply(CNick& Nick, CString& sMessage) { return CONTINUE; } +CModule::EModRet CModule::OnCTCPReplyMessage(CCTCPMessage& Message) { + CString sText = Message.GetText(); + EModRet ret = OnCTCPReply(Message.GetNick(), sText); + Message.SetText(sText); + return ret; +} CModule::EModRet CModule::OnPrivCTCP(CNick& Nick, CString& sMessage) { return CONTINUE; } CModule::EModRet CModule::OnPrivCTCPMessage(CCTCPMessage& Message) { CString sText = Message.GetText(); @@ -1011,6 +1017,7 @@ bool CModules::OnPrivBufferPlayLine(CClient& Client, CString& sLine) { MODHALTCH bool CModules::OnChanBufferPlayMessage(CMessage& Message) { MODHALTCHK(OnChanBufferPlayMessage(Message)); } bool CModules::OnPrivBufferPlayMessage(CMessage& Message) { MODHALTCHK(OnPrivBufferPlayMessage(Message)); } bool CModules::OnCTCPReply(CNick& Nick, CString& sMessage) { MODHALTCHK(OnCTCPReply(Nick, sMessage)); } +bool CModules::OnCTCPReplyMessage(CCTCPMessage& Message) { MODHALTCHK(OnCTCPReplyMessage(Message)); } bool CModules::OnPrivCTCP(CNick& Nick, CString& sMessage) { MODHALTCHK(OnPrivCTCP(Nick, sMessage)); } bool CModules::OnPrivCTCPMessage(CCTCPMessage& Message) { MODHALTCHK(OnPrivCTCPMessage(Message)); } bool CModules::OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) { MODHALTCHK(OnChanCTCP(Nick, Channel, sMessage)); } diff --git a/test/ModulesTest.cpp b/test/ModulesTest.cpp index eba24f6e..1eed6e9a 100644 --- a/test/ModulesTest.cpp +++ b/test/ModulesTest.cpp @@ -38,6 +38,7 @@ public: EModRet OnUserTopic(CString& sChannel, CString& sTopic) override { sChannel = "#legacy"; sTopic = "CLegacyModule::OnUserTopic"; return eAction; } EModRet OnUserQuit(CString& sMessage) override { sMessage = "CLegacyModule::OnUserQuit"; return eAction; } + EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { Nick.Parse("legacy!znc@znc.in"); sMessage = "CLegacyModule::OnCTCPReply"; return eAction; } EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { Nick.Parse("legacy!znc@znc.in"); sMessage = "CLegacyModule::OnPrivCTCP"; return eAction; } EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override { Nick.Parse("legacy!znc@znc.in"); sMessage = "CLegacyModule::OnChanCTCP"; return eAction; } EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { Nick.Parse("legacy!znc@znc.in"); sMessage = "CLegacyModule::OnPrivAction"; return eAction; } @@ -65,6 +66,7 @@ public: EModRet OnUserTopicMessage(CTopicMessage& Message) override { Message.SetTarget("#target"); Message.SetTopic("CMessageModule::OnUserTopicMessage"); return eAction; } EModRet OnUserQuitMessage(CQuitMessage& Message) override { Message.SetReason("CMessageModule::OnUserQuitMessage"); return eAction; } + EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetText("CMessageModule::OnCTCPReplyMessage"); return eAction; } EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetText("CMessageModule::OnPrivCTCPMessage"); return eAction; } EModRet OnChanCTCPMessage(CCTCPMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetText("CMessageModule::OnChanCTCPMessage"); return eAction; } EModRet OnPrivActionMessage(CActionMessage& Message) override { Message.GetNick().SetNick("nick"); Message.SetText("CMessageModule::OnPrivActionMessage"); return eAction; } @@ -175,6 +177,16 @@ TEST_F(ModulesTest, Hooks) { Modules.OnUserQuitMessage(UserQuitMsg); EXPECT_EQ("CMessageModule::OnUserQuitMessage", UserQuitMsg.GetReason()); + CCTCPMessage CTCPReply; + LegacyMod.eAction = CModule::HALT; + Modules.OnCTCPReplyMessage(CTCPReply); + EXPECT_EQ("legacy", CTCPReply.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnCTCPReply", CTCPReply.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnCTCPReplyMessage(CTCPReply); + EXPECT_EQ("nick", CTCPReply.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnCTCPReplyMessage", CTCPReply.GetText()); + CCTCPMessage PrivCTCP; LegacyMod.eAction = CModule::HALT; Modules.OnPrivCTCPMessage(PrivCTCP); From 2a40c355f499e1e87a4e066bd82c003106560269 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 2 Sep 2015 20:08:24 +0200 Subject: [PATCH 3/3] Fix #1022: Status and module commands not echoed back to client --- src/Client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Client.cpp b/src/Client.cpp index 3f70c35f..28ae534f 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -324,6 +324,7 @@ void CClient::ReadLine(const CString& sData) { } else { CALLMOD(sTarget, this, m_pUser, m_pNetwork, OnModCommand(TextMsg.GetText())); } + EchoMessage(Message); continue; }