diff --git a/include/znc/Client.h b/include/znc/Client.h index b7aed570..99ee9859 100644 --- a/include/znc/Client.h +++ b/include/znc/Client.h @@ -94,6 +94,7 @@ public: m_bUHNames = false; m_bAway = false; m_bServerTime = false; + m_bBatch = false; EnableReadLine(); // RFC says a line can have 512 chars max, but we are // a little more gentle ;) @@ -114,6 +115,7 @@ public: bool HasUHNames() const { return m_bUHNames; } bool IsAway() const { return m_bAway; } bool HasServerTime() const { return m_bServerTime; } + bool HasBatch() const { return m_bBatch; } void UserCommand(CString& sLine); void UserPortCommand(CString& sLine); @@ -163,6 +165,7 @@ protected: bool m_bUHNames; bool m_bAway; bool m_bServerTime; + bool m_bBatch; CUser* m_pUser; CIRCNetwork* m_pNetwork; CString m_sNick; diff --git a/src/Chan.cpp b/src/Chan.cpp index 8c1250a4..2fd226e0 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -560,9 +560,21 @@ void CChan::SendBuffer(CClient* pClient, const CBuffer& Buffer) { m_pNetwork->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + " :Buffer Playback...", pUseClient); } + bool bBatch = pUseClient->HasBatch(); + CString sBatchName = GetName().MD5(); + + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH +" + sBatchName + " znc.in/playback " + GetName(), pUseClient); + } + size_t uSize = Buffer.Size(); for (size_t uIdx = 0; uIdx < uSize; uIdx++) { CString sLine = Buffer.GetLine(uIdx, *pUseClient); + if (bBatch) { + MCString msBatchTags = CUtils::GetMessageTags(sLine); + msBatchTags["batch"] = sBatchName; + CUtils::SetMessageTags(sLine, msBatchTags); + } bool bNotShowThisLine = false; NETWORKMODULECALL(OnChanBufferPlayLine(*this, *pUseClient, sLine), m_pNetwork->GetUser(), m_pNetwork, NULL, &bNotShowThisLine); if (bNotShowThisLine) continue; @@ -575,6 +587,10 @@ void CChan::SendBuffer(CClient* pClient, const CBuffer& Buffer) { m_pNetwork->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + " :Playback Complete.", pUseClient); } + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH -" + sBatchName, pUseClient); + } + if (pClient) break; } diff --git a/src/Client.cpp b/src/Client.cpp index cf9d8e4b..90373218 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -860,7 +860,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"); + RespondCap("LS :" + sRes + "userhost-in-names multi-prefix znc.in/server-time-iso znc.in/batch"); m_bInCap = true; } else if (sSubCmd.Equals("END")) { m_bInCap = false; @@ -882,7 +882,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); + bool bAccepted = ("multi-prefix" == sCap) || ("userhost-in-names" == sCap) || ("znc.in/server-time-iso" == sCap) || ("znc.in/batch" == sCap); GLOBALMODULECALL(IsClientCapSupported(this, sCap, bVal), &bAccepted); if (!bAccepted) { @@ -904,6 +904,8 @@ void CClient::HandleCap(const CString& sLine) m_bUHNames = bVal; } else if ("znc.in/server-time-iso" == *it) { m_bServerTime = bVal; + } else if ("znc.in/batch" == *it) { + m_bBatch = bVal; } GLOBALMODULECALL(OnClientCapRequest(this, *it, bVal), NOTHING); @@ -943,6 +945,10 @@ void CClient::HandleCap(const CString& sLine) m_bServerTime = false; ssRemoved.insert("znc.in/server-time-iso"); } + if (m_bBatch) { + m_bBatch = false; + ssRemoved.insert("znc.in/batch"); + } 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 500e89e6..c8ee025e 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -44,15 +44,31 @@ void CQuery::SendBuffer(CClient* pClient, const CBuffer& Buffer) { for (size_t uClient = 0; uClient < vClients.size(); ++uClient) { CClient * pUseClient = (pClient ? pClient : vClients[uClient]); + bool bBatch = pUseClient->HasBatch(); + CString sBatchName = m_sName.MD5(); + + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH +" + sBatchName + " znc.in/playback " + m_sName, pUseClient); + } + size_t uSize = Buffer.Size(); for (size_t uIdx = 0; uIdx < uSize; uIdx++) { CString sLine = Buffer.GetLine(uIdx, *pUseClient, msParams); + if (bBatch) { + MCString msBatchTags = CUtils::GetMessageTags(sLine); + msBatchTags["batch"] = sBatchName; + CUtils::SetMessageTags(sLine, msBatchTags); + } bool bContinue = false; NETWORKMODULECALL(OnPrivBufferPlayLine(*pUseClient, sLine), m_pNetwork->GetUser(), m_pNetwork, NULL, &bContinue); if (bContinue) continue; m_pNetwork->PutUser(sLine, pUseClient); } + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH -" + sBatchName, pUseClient); + } + if (pClient) break; }