diff --git a/include/znc/Client.h b/include/znc/Client.h index 70a31b24..f9ae87c2 100644 --- a/include/znc/Client.h +++ b/include/znc/Client.h @@ -97,6 +97,8 @@ public: m_bInCap(false), m_bCapNotify(false), m_bAwayNotify(false), + m_bAccountNotify(false), + m_bExtendedJoin(false), m_bNamesx(false), m_bUHNames(false), m_bAway(false), @@ -121,6 +123,8 @@ public: {"batch", {false, [this](bool bVal) { m_bBatch = bVal; }}}, {"cap-notify", {false, [this](bool bVal) { m_bCapNotify = bVal; }}}, {"away-notify", {true, [this](bool bVal) { m_bAwayNotify = bVal; }}}, + {"account-notify", {true, [this](bool bVal) { m_bAccountNotify = bVal; }}}, + {"extended-join", {true, [this](bool bVal) { m_bExtendedJoin = bVal; }}}, }) { EnableReadLine(); @@ -148,6 +152,8 @@ public: CString GetIdentifier() const { return m_sIdentifier; } bool HasCapNotify() const { return m_bCapNotify; } bool HasAwayNotify() const { return m_bAwayNotify; } + bool HasAccountNotify() const { return m_bAccountNotify; } + bool HasExtendedJoin() const { return m_bExtendedJoin; } bool HasNamesx() const { return m_bNamesx; } bool HasUHNames() const { return m_bUHNames; } bool IsAway() const { return m_bAway; } @@ -213,6 +219,8 @@ protected: bool m_bInCap; bool m_bCapNotify; bool m_bAwayNotify; + bool m_bAccountNotify; + bool m_bExtendedJoin; bool m_bNamesx; bool m_bUHNames; bool m_bAway; diff --git a/include/znc/IRCSock.h b/include/znc/IRCSock.h index 5ff736a5..a6949529 100644 --- a/include/znc/IRCSock.h +++ b/include/znc/IRCSock.h @@ -102,6 +102,8 @@ public: bool HasNamesx() const { return m_bNamesx; } bool HasUHNames() const { return m_bUHNames; } bool HasAwayNotify() const { return m_bAwayNotify; } + bool HasAccountNotify() const { return m_bAccountNotify; } + bool HasExtendedJoin() const { return m_bExtendedJoin; } const std::set& GetUserModes() const { return m_scUserModes; } // This is true if we are past raw 001 bool IsAuthed() const { return m_bAuthed; } @@ -129,6 +131,8 @@ protected: bool m_bNamesx; bool m_bUHNames; bool m_bAwayNotify; + bool m_bAccountNotify; + bool m_bExtendedJoin; CString m_sPerms; CString m_sPermModes; std::set m_scUserModes; diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index eae144d4..64fd091f 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -61,6 +61,8 @@ CIRCSock::CIRCSock(CIRCNetwork* pNetwork) m_bNamesx(false), m_bUHNames(false), m_bAwayNotify(false), + m_bAccountNotify(false), + m_bExtendedJoin(false), m_sPerms("*!@%+"), m_sPermModes("qaohv"), m_scUserModes(), @@ -590,6 +592,21 @@ void CIRCSock::ReadLine(const CString& sData) { if (pChan->IsDetached()) { return; } + + if (HasExtendedJoin()) { + CString sExtendedLine = sLine; + sLine = ":" + Nick.GetNickMask() + " JOIN " + pChan->GetName(); + + const vector& vClients = m_pNetwork->GetClients(); + for (CClient* pClient : vClients) { + if (pClient->HasExtendedJoin()) { + m_pNetwork->PutUser(sExtendedLine, pClient); + } else { + m_pNetwork->PutUser(sLine, pClient); + } + } + return; + } } } else if (sCmd.Equals("PART")) { CString sChan = sRest.Token(0).TrimPrefix_n(); @@ -805,24 +822,29 @@ void CIRCSock::ReadLine(const CString& sData) { sArgs = sRest.Token(2, true).TrimPrefix_n(); } + std::map> mSupportedCaps = { + {"multi-prefix", [this](bool bVal) { m_bNamesx = bVal; }}, + {"userhost-in-names", [this](bool bVal) { m_bUHNames = bVal; }}, + {"away-notify", [this](bool bVal) { m_bAwayNotify = bVal; }}, + {"account-notify", [this](bool bVal) { m_bAccountNotify = bVal; }}, + {"extended-join", [this](bool bVal) { m_bExtendedJoin = bVal; }}, + }; + if (sSubCmd == "LS") { VCString vsTokens; sArgs.Split(" ", vsTokens, false); for (const CString& sCap : vsTokens) { - if (OnServerCapAvailable(sCap) || sCap == "multi-prefix" || sCap == "userhost-in-names" || sCap == "away-notify") { + if (OnServerCapAvailable(sCap) || mSupportedCaps.count(sCap)) { m_ssPendingCaps.insert(sCap); } } } else if (sSubCmd == "ACK") { sArgs.Trim(); IRCSOCKMODULECALL(OnServerCapResult(sArgs, true), NOTHING); - if ("multi-prefix" == sArgs) { - m_bNamesx = true; - } else if ("userhost-in-names" == sArgs) { - m_bUHNames = true; - } else if ("away-notify" == sArgs) { - m_bAwayNotify = true; + const auto& it = mSupportedCaps.find(sArgs); + if (it != mSupportedCaps.end()) { + it->second(true); } m_ssAcceptedCaps.insert(sArgs); } else if (sSubCmd == "NAK") { @@ -847,6 +869,14 @@ void CIRCSock::ReadLine(const CString& sData) { } } return; + } else if (sCmd.Equals("ACCOUNT")) { + const vector& vClients = m_pNetwork->GetClients(); + for (CClient* pClient : vClients) { + if (pClient->HasAccountNotify()) { + m_pNetwork->PutUser(sLine, pClient); + } + } + return; } }