From 382ce76dedb9e7544c38055e1f3752e8ecc46537 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Aug 2014 17:05:20 +0200 Subject: [PATCH] Add self-message support https://github.com/ircv3/ircv3-specifications/blob/master/extensions/self-message-3.2.md --- include/znc/Client.h | 3 +++ src/Client.cpp | 55 ++++++++++++++++++++------------------------ src/Query.cpp | 11 ++++++++- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/include/znc/Client.h b/include/znc/Client.h index f83ad356..938df057 100644 --- a/include/znc/Client.h +++ b/include/znc/Client.h @@ -95,6 +95,7 @@ public: m_bAway = false; m_bServerTime = false; m_bBatch = false; + m_bSelfMessage = false; EnableReadLine(); // RFC says a line can have 512 chars max, but we are // a little more gentle ;) @@ -116,6 +117,7 @@ public: bool IsAway() const { return m_bAway; } bool HasServerTime() const { return m_bServerTime; } bool HasBatch() const { return m_bBatch; } + bool HasSelfMessage() const { return m_bSelfMessage; } void UserCommand(CString& sLine); void UserPortCommand(CString& sLine); @@ -166,6 +168,7 @@ protected: bool m_bAway; bool m_bServerTime; bool m_bBatch; + bool m_bSelfMessage; CUser* m_pUser; CIRCNetwork* m_pNetwork; CString m_sNick; diff --git a/src/Client.cpp b/src/Client.cpp index bda6f7a1..05cc2e21 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -271,15 +271,11 @@ void CClient::ReadLine(const CString& sData) { } // Relay to the rest of the clients that may be connected to this user - if (m_pNetwork->IsChan(sTarget)) { - const vector& vClients = GetClients(); + const vector& vClients = GetClients(); - for (unsigned int a = 0; a < vClients.size(); a++) { - CClient* pClient = vClients[a]; - - if (pClient != this) { - pClient->PutClient(":" + GetNickMask() + " NOTICE " + sTarget + " :" + sMsg); - } + for (CClient* pClient : vClients) { + if (pClient != this && (m_pNetwork->IsChan(sTarget) || pClient->HasSelfMessage())) { + pClient->PutClient(":" + GetNickMask() + " NOTICE " + sTarget + " :" + sMsg); } } @@ -324,17 +320,6 @@ void CClient::ReadLine(const CString& sData) { if (pChan && (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline())) { pChan->AddBuffer(":" + _NAMEDFMT(GetNickMask()) + " PRIVMSG " + _NAMEDFMT(sTarget) + " :\001ACTION {text}\001", sMessage); } - - // Relay to the rest of the clients that may be connected to this user - const vector& vClients = GetClients(); - - for (unsigned int a = 0; a < vClients.size(); a++) { - CClient* pClient = vClients[a]; - - if (pClient != this) { - pClient->PutClient(":" + GetNickMask() + " PRIVMSG " + sTarget + " :\001" + sCTCP + "\001"); - } - } } else { if (!m_pUser->AutoClearQueryBuffer() || !m_pNetwork->IsUserOnline()) { CQuery* pQuery = m_pNetwork->AddQuery(sTarget); @@ -343,6 +328,15 @@ void CClient::ReadLine(const CString& sData) { } } } + + // Relay to the rest of the clients that may be connected to this user + const vector& vClients = GetClients(); + + for (CClient* pClient : vClients) { + if (pClient != this && (m_pNetwork->IsChan(sTarget) || pClient->HasSelfMessage())) { + pClient->PutClient(":" + GetNickMask() + " PRIVMSG " + sTarget + " :\001" + sCTCP + "\001"); + } + } } else { NETWORKMODULECALL(OnUserCTCP(sTarget, sCTCP), m_pUser, m_pNetwork, this, &bContinue); if (bContinue) continue; @@ -393,16 +387,11 @@ void CClient::ReadLine(const CString& sData) { PutIRC("PRIVMSG " + sTarget + " :" + sMsg); // Relay to the rest of the clients that may be connected to this user + const vector& vClients = GetClients(); - if (m_pNetwork->IsChan(sTarget)) { - const vector& vClients = GetClients(); - - for (unsigned int a = 0; a < vClients.size(); a++) { - CClient* pClient = vClients[a]; - - if (pClient != this) { - pClient->PutClient(":" + GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg); - } + for (CClient* pClient : vClients) { + if (pClient != this && (m_pNetwork->IsChan(sTarget) || pClient->HasSelfMessage())) { + pClient->PutClient(":" + GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg); } } } @@ -877,7 +866,7 @@ void CClient::HandleCap(const CString& sLine) for (SCString::iterator i = ssOfferCaps.begin(); i != ssOfferCaps.end(); ++i) { sRes += *i + " "; } - RespondCap("LS :" + sRes + "userhost-in-names multi-prefix znc.in/server-time-iso znc.in/batch"); + RespondCap("LS :" + sRes + "userhost-in-names multi-prefix znc.in/server-time-iso znc.in/batch znc.in/self-message"); m_bInCap = true; } else if (sSubCmd.Equals("END")) { m_bInCap = false; @@ -899,7 +888,7 @@ void CClient::HandleCap(const CString& sLine) if (sCap.TrimPrefix("-")) bVal = false; - bool bAccepted = ("multi-prefix" == sCap) || ("userhost-in-names" == sCap) || ("znc.in/server-time-iso" == sCap) || ("znc.in/batch" == sCap); + bool bAccepted = ("multi-prefix" == sCap) || ("userhost-in-names" == sCap) || ("znc.in/server-time-iso" == sCap) || ("znc.in/batch" == sCap) || ("znc.in/self-message" == sCap); GLOBALMODULECALL(IsClientCapSupported(this, sCap, bVal), &bAccepted); if (!bAccepted) { @@ -923,6 +912,8 @@ void CClient::HandleCap(const CString& sLine) m_bServerTime = bVal; } else if ("znc.in/batch" == *it) { m_bBatch = bVal; + } else if ("znc.in/self-message" == *it) { + m_bSelfMessage = bVal; } GLOBALMODULECALL(OnClientCapRequest(this, *it, bVal), NOTHING); @@ -966,6 +957,10 @@ void CClient::HandleCap(const CString& sLine) m_bBatch = false; ssRemoved.insert("znc.in/batch"); } + if (m_bSelfMessage) { + m_bSelfMessage = false; + ssRemoved.insert("znc.in/self-message"); + } CString sList = ""; for (SCString::iterator i = ssRemoved.begin(); i != ssRemoved.end(); ++i) { m_ssAcceptedCaps.erase(*i); diff --git a/src/Query.cpp b/src/Query.cpp index c8ee025e..2432e71f 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -53,7 +53,16 @@ void CQuery::SendBuffer(CClient* pClient, const CBuffer& Buffer) { size_t uSize = Buffer.Size(); for (size_t uIdx = 0; uIdx < uSize; uIdx++) { - CString sLine = Buffer.GetLine(uIdx, *pUseClient, msParams); + const CBufLine& BufLine = Buffer.GetBufLine(uIdx); + + if (!pUseClient->HasSelfMessage()) { + CNick Sender(BufLine.GetFormat().Token(0)); + if (Sender.NickEquals(pUseClient->GetNick())) { + continue; + } + } + + CString sLine = BufLine.GetLine(*pUseClient, msParams); if (bBatch) { MCString msBatchTags = CUtils::GetMessageTags(sLine); msBatchTags["batch"] = sBatchName;