mirror of
https://github.com/znc/znc.git
synced 2026-05-02 11:32:29 +02:00
Implement message-tags spec
Message tags were supported already, but not arbitrary tags, and not TAGMSG
This commit is contained in:
109
src/Client.cpp
109
src/Client.cpp
@@ -94,6 +94,7 @@ CClient::CClient()
|
||||
m_bBatch(false),
|
||||
m_bEchoMessage(false),
|
||||
m_bSelfMessage(false),
|
||||
m_bMessageTagCap(false),
|
||||
m_bSASLCap(false),
|
||||
m_bPlaybackActive(false),
|
||||
m_pUser(nullptr),
|
||||
@@ -258,6 +259,9 @@ void CClient::ReadLine(const CString& sData) {
|
||||
case CMessage::Type::Quit:
|
||||
bReturn = OnQuitMessage(Message);
|
||||
break;
|
||||
case CMessage::Type::TagMsg:
|
||||
bReturn = OnTagMessage(Message);
|
||||
break;
|
||||
case CMessage::Type::Text:
|
||||
bReturn = OnTextMessage(Message);
|
||||
break;
|
||||
@@ -271,7 +275,7 @@ void CClient::ReadLine(const CString& sData) {
|
||||
|
||||
if (bReturn) return;
|
||||
|
||||
PutIRC(Message.ToString(CMessage::ExcludePrefix | CMessage::ExcludeTags));
|
||||
PutIRCStripping(Message);
|
||||
}
|
||||
|
||||
void CClient::SetNick(const CString& s) { m_sNick = s; }
|
||||
@@ -560,6 +564,16 @@ void CClient::PutIRC(const CString& sLine) {
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::PutIRCStripping(CMessage Message) {
|
||||
if (CIRCSock* pSock = GetIRCSock()) {
|
||||
Message.SetNick(CNick{});
|
||||
if (!pSock->HasMessageTagCap()) {
|
||||
Message.SetTags({});
|
||||
}
|
||||
pSock->PutIRC(Message);
|
||||
}
|
||||
}
|
||||
|
||||
CString CClient::GetFullName() const {
|
||||
if (!m_pUser) return GetRemoteIP();
|
||||
CString sFullName = m_pUser->GetUsername();
|
||||
@@ -578,6 +592,9 @@ bool CClient::PutClient(const CMessage& Message) {
|
||||
} else if (!m_bAccountNotify &&
|
||||
Message.GetType() == CMessage::Type::Account) {
|
||||
return false;
|
||||
} else if (!m_bMessageTagCap &&
|
||||
Message.GetType() == CMessage::Type::TagMsg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CMessage Msg(Message);
|
||||
@@ -643,11 +660,14 @@ bool CClient::PutClient(const CMessage& Message) {
|
||||
}
|
||||
}
|
||||
|
||||
MCString mssTags;
|
||||
MCString mssNewTags;
|
||||
MCString& mssTags = m_bMessageTagCap ? Msg.GetTags() : mssNewTags;
|
||||
|
||||
for (const auto& it : Msg.GetTags()) {
|
||||
if (IsTagEnabled(it.first)) {
|
||||
mssTags[it.first] = it.second;
|
||||
if (!m_bMessageTagCap) {
|
||||
for (const auto& it : Msg.GetTags()) {
|
||||
if (IsTagEnabled(it.first)) {
|
||||
mssTags[it.first] = it.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -816,6 +836,10 @@ CClient::CoreCaps() {
|
||||
[](CClient* pClient, bool bVal) {
|
||||
pClient->m_bEchoMessage = bVal;
|
||||
}},
|
||||
{"message-tags",
|
||||
[](CClient* pClient, bool bVal) {
|
||||
pClient->m_bMessageTagCap = bVal;
|
||||
}},
|
||||
{"server-time",
|
||||
[](CClient* pClient, bool bVal) {
|
||||
pClient->m_bServerTime = bVal;
|
||||
@@ -1037,6 +1061,17 @@ void CClient::NotifyServerDependentCap(const CString& sCap, bool bValue, const C
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename X, class = void>
|
||||
struct message_has_text : std::false_type {};
|
||||
|
||||
template <typename X>
|
||||
struct message_has_text<
|
||||
X, std::void_t<decltype(std::declval<const X&>().GetText()),
|
||||
decltype(std::declval<X&>().SetText(""))>> : std::true_type {
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CClient::AddBuffer(const T& Message) {
|
||||
if (!m_pNetwork) {
|
||||
@@ -1048,18 +1083,27 @@ void CClient::AddBuffer(const T& Message) {
|
||||
Format.Clone(Message);
|
||||
Format.SetNick(CNick(_NAMEDFMT(GetNickMask())));
|
||||
Format.SetTarget(_NAMEDFMT(sTarget));
|
||||
Format.SetText("{text}");
|
||||
if constexpr (message_has_text<T>::value) {
|
||||
Format.SetText("{text}");
|
||||
}
|
||||
|
||||
CString sText;
|
||||
CChan* pChan = m_pNetwork->FindChan(sTarget);
|
||||
if (pChan) {
|
||||
if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline()) {
|
||||
pChan->AddBuffer(Format, Message.GetText());
|
||||
if constexpr (message_has_text<T>::value) {
|
||||
sText = Message.GetText();
|
||||
}
|
||||
pChan->AddBuffer(Format, sText);
|
||||
}
|
||||
} else if (Message.GetType() != CMessage::Type::Notice) {
|
||||
if (!m_pUser->AutoClearQueryBuffer() || !m_pNetwork->IsUserOnline()) {
|
||||
CQuery* pQuery = m_pNetwork->AddQuery(sTarget);
|
||||
if (pQuery) {
|
||||
pQuery->AddBuffer(Format, Message.GetText());
|
||||
if constexpr (message_has_text<T>::value) {
|
||||
sText = Message.GetText();
|
||||
}
|
||||
pQuery->AddBuffer(Format, sText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1134,8 +1178,7 @@ bool CClient::OnActionMessage(CActionMessage& Message) {
|
||||
if (m_pNetwork) {
|
||||
AddBuffer(Message);
|
||||
EchoMessage(Message);
|
||||
PutIRC(Message.ToString(CMessage::ExcludePrefix |
|
||||
CMessage::ExcludeTags));
|
||||
PutIRCStripping(Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,8 +1395,7 @@ bool CClient::OnCTCPMessage(CCTCPMessage& Message) {
|
||||
}
|
||||
|
||||
if (m_pNetwork) {
|
||||
PutIRC(Message.ToString(CMessage::ExcludePrefix |
|
||||
CMessage::ExcludeTags));
|
||||
PutIRCStripping(Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1456,6 +1498,8 @@ bool CClient::OnNoticeMessage(CNoticeMessage& Message) {
|
||||
}
|
||||
|
||||
if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
|
||||
EchoMessage(Message);
|
||||
|
||||
if (!sTarget.Equals("status")) {
|
||||
CALLMOD(sTarget, this, m_pUser, m_pNetwork,
|
||||
OnModNotice(Message.GetText()));
|
||||
@@ -1480,8 +1524,7 @@ bool CClient::OnNoticeMessage(CNoticeMessage& Message) {
|
||||
if (m_pNetwork) {
|
||||
AddBuffer(Message);
|
||||
EchoMessage(Message);
|
||||
PutIRC(Message.ToString(CMessage::ExcludePrefix |
|
||||
CMessage::ExcludeTags));
|
||||
PutIRCStripping(Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1554,6 +1597,41 @@ bool CClient::OnQuitMessage(CQuitMessage& Message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClient::OnTagMessage(CTargetMessage& Message) {
|
||||
CString sTargets = Message.GetTarget();
|
||||
|
||||
VCString vTargets;
|
||||
sTargets.Split(",", vTargets, false);
|
||||
|
||||
for (CString& sTarget : vTargets) {
|
||||
Message.SetTarget(sTarget);
|
||||
if (m_pNetwork) {
|
||||
// May be nullptr.
|
||||
Message.SetChan(m_pNetwork->FindChan(sTarget));
|
||||
}
|
||||
|
||||
if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
|
||||
EchoMessage(Message);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool bContinue = false;
|
||||
NETWORKMODULECALL(OnUserTagMessage(Message), m_pUser, m_pNetwork,
|
||||
this, &bContinue);
|
||||
if (bContinue) continue;
|
||||
|
||||
if (m_pNetwork) {
|
||||
AddBuffer(Message);
|
||||
EchoMessage(Message);
|
||||
if (GetIRCSock()->HasMessageTagCap()) {
|
||||
PutIRCStripping(Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClient::OnTextMessage(CTextMessage& Message) {
|
||||
CString sTargets = Message.GetTarget();
|
||||
|
||||
@@ -1597,8 +1675,7 @@ bool CClient::OnTextMessage(CTextMessage& Message) {
|
||||
if (m_pNetwork) {
|
||||
AddBuffer(Message);
|
||||
EchoMessage(Message);
|
||||
PutIRC(Message.ToString(CMessage::ExcludePrefix |
|
||||
CMessage::ExcludeTags));
|
||||
PutIRCStripping(Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user