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/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/Client.cpp b/src/Client.cpp
index 3f70c35f..f49fe303 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.
@@ -324,6 +324,7 @@ void CClient::ReadLine(const CString& sData) {
} else {
CALLMOD(sTarget, this, m_pUser, m_pNetwork, OnModCommand(TextMsg.GetText()));
}
+ EchoMessage(Message);
continue;
}
@@ -865,10 +866,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 +881,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 +895,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 +913,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 +939,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);
diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp
index 450276b8..17ebd545 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);