TEST(MessageTest, PrivCTCP) { CCTCPMessage msg; msg.Parse(":sender PRIVMSG receiver :\001text\001"); EXPECT_EQ("sender", msg.GetNick().GetNick()); EXPECT_EQ("PRIVMSG", msg.GetCommand()); EXPECT_EQ("receiver", msg.GetTarget()); EXPECT_EQ("text", msg.GetText()); EXPECT_FALSE(msg.IsReply()); EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); msg.SetText("foo bar"); EXPECT_EQ("foo bar", msg.GetText()); EXPECT_EQ(":sender PRIVMSG receiver :\001foo bar\001", msg.ToString()); }
TEST(MessageTest, CTCPReply) { CCTCPMessage msg; msg.Parse(":sender NOTICE nick :\001FOO bar\001"); EXPECT_EQ("sender", msg.GetNick().GetNick()); EXPECT_EQ("NOTICE", msg.GetCommand()); EXPECT_EQ("nick", msg.GetTarget()); EXPECT_EQ("FOO bar", msg.GetText()); EXPECT_TRUE(msg.IsReply()); EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); msg.SetText("BAR foo"); EXPECT_EQ("BAR foo", msg.GetText()); EXPECT_EQ(":sender NOTICE nick :\001BAR foo\001", msg.ToString()); }
bool CIRCSock::OnCTCPMessage(CCTCPMessage& Message) { bool bResult = false; CChan* pChan = nullptr; CString sTarget = Message.GetTarget(); if (sTarget.Equals(GetNick())) { if (Message.IsReply()) { IRCSOCKMODULECALL(OnCTCPReplyMessage(Message), &bResult); return bResult; } else { IRCSOCKMODULECALL(OnPrivCTCPMessage(Message), &bResult); if (bResult) return true; } } else { pChan = m_pNetwork->FindChan(sTarget); if (pChan) { Message.SetChan(pChan); FixupChanNick(Message.GetNick(), pChan); IRCSOCKMODULECALL(OnChanCTCPMessage(Message), &bResult); if (bResult) return true; } } const CNick& Nick = Message.GetNick(); const CString& sMessage = Message.GetText(); const MCString& mssCTCPReplies = m_pNetwork->GetUser()->GetCTCPReplies(); CString sQuery = sMessage.Token(0).AsUpper(); MCString::const_iterator it = mssCTCPReplies.find(sQuery); bool bHaveReply = false; CString sReply; if (it != mssCTCPReplies.end()) { sReply = m_pNetwork->ExpandString(it->second); bHaveReply = true; if (sReply.empty()) { return true; } } if (!bHaveReply && !m_pNetwork->IsUserAttached()) { if (sQuery == "VERSION") { sReply = CZNC::GetTag(false); } else if (sQuery == "PING") { sReply = sMessage.Token(1, true); } } if (!sReply.empty()) { time_t now = time(nullptr); // If the last CTCP is older than m_uCTCPFloodTime, reset the counter if (m_lastCTCP + m_uCTCPFloodTime < now) m_uNumCTCP = 0; m_lastCTCP = now; // If we are over the limit, don't reply to this CTCP if (m_uNumCTCP >= m_uCTCPFloodCount) { DEBUG("CTCP flood detected - not replying to query"); return true; } m_uNumCTCP++; PutIRC("NOTICE " + Nick.GetNick() + " :\001" + sQuery + " " + sReply + "\001"); return true; } return (pChan && pChan->IsDetached()); }