From a2470b3dd32f03970b7d27472ec54ffa012d5951 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 10 Feb 2018 15:49:53 +0000 Subject: [PATCH] Make chan modes and permissions to be char instead of unsigned char. Deprecate old module hooks which accept mode as unsigned char. SWIG handles unsigned char as int, but char as a string. Before this commit, usage of HasPerm from perl modules required this: either $chan->HasPerm(ord('@')) or $chan->HasPerm(ord($ZNC::CChan::Op)). Now ord() is not necessary, and these calls work too: $chan->HasPerm('@') and $chan->HasPerm($ZNC::CChan::Op). Fix #1486 --- include/znc/Chan.h | 24 ++++++++------ include/znc/IRCSock.h | 14 ++++---- include/znc/Modules.h | 10 +++++- include/znc/Nick.h | 13 +++++--- modules/q.cpp | 2 +- src/Chan.cpp | 77 +++++++++++++++++++++---------------------- src/IRCNetwork.cpp | 4 +-- src/IRCSock.cpp | 50 ++++++++++++++-------------- src/Modules.cpp | 12 +++++++ src/Nick.cpp | 20 +++++------ 10 files changed, 127 insertions(+), 99 deletions(-) diff --git a/include/znc/Chan.h b/include/znc/Chan.h index 8ecd6f6f..699a740d 100644 --- a/include/znc/Chan.h +++ b/include/znc/Chan.h @@ -77,8 +77,8 @@ class CChan { // Modes void SetModes(const CString& s); void ModeChange(const CString& sModes, const CNick* OpNick = nullptr); - bool AddMode(unsigned char uMode, const CString& sArg); - bool RemMode(unsigned char uMode); + bool AddMode(char cMode, const CString& sArg); + bool RemMode(char cMode); CString GetModeString() const; CString GetModeArg(CString& sArgs) const; CString GetModeForNames() const; @@ -120,10 +120,14 @@ class CChan { // !Buffer // m_Nick wrappers + /// e.g. '@' for chanop. CString GetPermStr() const { return m_Nick.GetPermStr(); } - bool HasPerm(unsigned char uPerm) const { return m_Nick.HasPerm(uPerm); } - bool AddPerm(unsigned char uPerm) { return m_Nick.AddPerm(uPerm); } - bool RemPerm(unsigned char uPerm) { return m_Nick.RemPerm(uPerm); } + /// e.g. '@' for chanop. + bool HasPerm(char cPerm) const { return m_Nick.HasPerm(cPerm); } + /// e.g. '@' for chanop. + bool AddPerm(char cPerm) { return m_Nick.AddPerm(cPerm); } + /// e.g. '@' for chanop. + bool RemPerm(char cPerm) { return m_Nick.RemPerm(cPerm); } // !wrappers // Setters @@ -154,14 +158,14 @@ class CChan { // Getters CIRCNetwork* GetNetwork() const { return m_pNetwork; } bool IsModeKnown() const { return m_bModeKnown; } - bool HasMode(unsigned char uMode) const; + bool HasMode(char cMode) const; CString GetOptions() const; - CString GetModeArg(unsigned char uMode) const; + CString GetModeArg(char cMode) const; std::map GetPermCounts() const; bool IsOn() const { return m_bIsOn; } const CString& GetName() const { return m_sName; } - const std::map& GetModes() const { - return m_musModes; + const std::map& GetModes() const { + return m_mcsModes; } const CString& GetKey() const { return m_sKey; } const CString& GetTopic() const { return m_sTopic; } @@ -204,7 +208,7 @@ class CChan { CBuffer m_Buffer; bool m_bModeKnown; - std::map m_musModes; + std::map m_mcsModes; }; #endif // !ZNC_CHAN_H diff --git a/include/znc/IRCSock.h b/include/znc/IRCSock.h index 19799142..5c748af2 100644 --- a/include/znc/IRCSock.h +++ b/include/znc/IRCSock.h @@ -78,10 +78,10 @@ class CIRCSock : public CIRCSocket { // Getters unsigned int GetMaxNickLen() const { return m_uMaxNickLen; } - EChanModeArgs GetModeType(unsigned char uMode) const; - unsigned char GetPermFromMode(unsigned char uMode) const; - const std::map& GetChanModes() const { - return m_mueChanModes; + EChanModeArgs GetModeType(char cMode) const; + char GetPermFromMode(char cMode) const; + const std::map& GetChanModes() const { + return m_mceChanModes; } bool IsPermChar(const char c) const { return (c != '\0' && GetPerms().find(c) != CString::npos); @@ -101,7 +101,7 @@ class CIRCSock : public CIRCSocket { bool HasAccountNotify() const { return m_bAccountNotify; } bool HasExtendedJoin() const { return m_bExtendedJoin; } bool HasServerTime() const { return m_bServerTime; } - const std::set& GetUserModes() const { + const std::set& GetUserModes() const { return m_scUserModes; } // This is true if we are past raw 001 @@ -160,8 +160,8 @@ class CIRCSock : public CIRCSocket { bool m_bServerTime; CString m_sPerms; CString m_sPermModes; - std::set m_scUserModes; - std::map m_mueChanModes; + std::set m_scUserModes; + std::map m_mceChanModes; CIRCNetwork* m_pNetwork; CNick m_Nick; CString m_sPass; diff --git a/include/znc/Modules.h b/include/znc/Modules.h index d9b03010..b8d5f71e 100644 --- a/include/znc/Modules.h +++ b/include/znc/Modules.h @@ -575,16 +575,21 @@ class CModule { * @param pOpNick The nick who sent the mode change, or nullptr if set by server. * @param Nick The nick whose channel mode changes. * @param Channel The channel on which the user mode is changed. - * @param uMode The mode character that is changed, e.g. '@' for op. + * @param cMode The mode character that is changed, e.g. '@' for op. * @param bAdded True if the mode is added, else false. * @param bNoChange true if this mode change doesn't change anything * because the nick already had this permission. * @see CIRCSock::GetModeType() for converting uMode into a mode (e.g. * 'o' for op). */ + virtual void OnChanPermission3(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, char cMode, + bool bAdded, bool bNoChange); + /// @deprecated. Use OnChanPermission3. virtual void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange); + /// @deprecated. Use OnChanPermission3. virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange); @@ -1404,6 +1409,9 @@ class CModules : public std::vector { CString& sRealName); bool OnBroadcast(CString& sMessage); + bool OnChanPermission3(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, char cMode, bool bAdded, + bool bNoChange); bool OnChanPermission2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange); diff --git a/include/znc/Nick.h b/include/znc/Nick.h index c0a9bd1d..ecd94732 100644 --- a/include/znc/Nick.h +++ b/include/znc/Nick.h @@ -47,14 +47,19 @@ class CNick { void SetNick(const CString& s); void SetIdent(const CString& s); void SetHost(const CString& s); - bool AddPerm(unsigned char uPerm); - bool RemPerm(unsigned char uPerm); + /// e.g. '@' for chanop. + bool AddPerm(char cPerm); + /// e.g. '@' for chanop. + bool RemPerm(char cPerm); // !Setters // Getters + /// e.g. '@' for chanop. CString GetPermStr() const; - unsigned char GetPermChar() const; - bool HasPerm(unsigned char uPerm) const; + /// e.g. '@' for chanop. + char GetPermChar() const; + /// e.g. '@' for chanop. + bool HasPerm(char cPerm) const; const CString& GetNick() const; const CString& GetIdent() const; const CString& GetHost() const; diff --git a/modules/q.cpp b/modules/q.cpp index 2dd8db29..1343bfab 100644 --- a/modules/q.cpp +++ b/modules/q.cpp @@ -61,7 +61,7 @@ class CQModule : public CModule { if (IsIRCConnected()) { // check for usermode +x if we are already connected - set scUserModes = + set scUserModes = GetNetwork()->GetIRCSock()->GetUserModes(); if (scUserModes.find('x') != scUserModes.end()) m_bCloaked = true; diff --git a/src/Chan.cpp b/src/Chan.cpp index ae8e2904..aae7e7f6 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -48,7 +48,7 @@ CChan::CChan(const CString& sName, CIRCNetwork* pNetwork, bool bInConfig, m_msNicks(), m_Buffer(), m_bModeKnown(false), - m_musModes() { + m_mcsModes() { if (!m_pNetwork->IsChan(m_sName)) { m_sName = "#" + m_sName; } @@ -85,7 +85,7 @@ CChan::~CChan() { ClearNicks(); } void CChan::Reset() { m_bIsOn = false; m_bModeKnown = false; - m_musModes.clear(); + m_mcsModes.clear(); m_sTopic = ""; m_sTopicOwner = ""; m_ulTopicDate = 0; @@ -231,7 +231,7 @@ void CChan::DetachUser() { CString CChan::GetModeString() const { CString sModes, sArgs; - for (const auto& it : m_musModes) { + for (const auto& it : m_mcsModes) { sModes += it.first; if (it.second.size()) { sArgs += " " + it.second; @@ -244,7 +244,7 @@ CString CChan::GetModeString() const { CString CChan::GetModeForNames() const { CString sMode; - for (const auto& it : m_musModes) { + for (const auto& it : m_mcsModes) { if (it.first == 's') { sMode = "@"; } else if ((it.first == 'p') && sMode.empty()) { @@ -256,7 +256,7 @@ CString CChan::GetModeForNames() const { } void CChan::SetModes(const CString& sModes) { - m_musModes.clear(); + m_mcsModes.clear(); ModeChange(sModes); } @@ -313,42 +313,42 @@ void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); for (unsigned int a = 0; a < sModeArg.size(); a++) { - const unsigned char& uMode = sModeArg[a]; + const char& cMode = sModeArg[a]; - if (uMode == '+') { + if (cMode == '+') { bAdd = true; - } else if (uMode == '-') { + } else if (cMode == '-') { bAdd = false; - } else if (m_pNetwork->GetIRCSock()->IsPermMode(uMode)) { + } else if (m_pNetwork->GetIRCSock()->IsPermMode(cMode)) { CString sArg = GetModeArg(sArgs); CNick* pNick = FindNick(sArg); if (pNick) { - unsigned char uPerm = - m_pNetwork->GetIRCSock()->GetPermFromMode(uMode); + char cPerm = + m_pNetwork->GetIRCSock()->GetPermFromMode(cMode); - if (uPerm) { - bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); + if (cPerm) { + bool bNoChange = (pNick->HasPerm(cPerm) == bAdd); if (bAdd) { - pNick->AddPerm(uPerm); + pNick->AddPerm(cPerm); if (pNick->NickEquals(m_pNetwork->GetCurNick())) { - AddPerm(uPerm); + AddPerm(cPerm); } } else { - pNick->RemPerm(uPerm); + pNick->RemPerm(cPerm); if (pNick->NickEquals(m_pNetwork->GetCurNick())) { - RemPerm(uPerm); + RemPerm(cPerm); } } - NETWORKMODULECALL(OnChanPermission2(pOpNick, *pNick, *this, - uMode, bAdd, bNoChange), + NETWORKMODULECALL(OnChanPermission3(pOpNick, *pNick, *this, + cMode, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); - if (uMode == CChan::M_Op) { + if (cMode == CChan::M_Op) { if (bAdd) { NETWORKMODULECALL( OnOp2(pOpNick, *pNick, *this, bNoChange), @@ -360,7 +360,7 @@ void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); } - } else if (uMode == CChan::M_Voice) { + } else if (cMode == CChan::M_Voice) { if (bAdd) { NETWORKMODULECALL( OnVoice2(pOpNick, *pNick, *this, bNoChange), @@ -379,7 +379,7 @@ void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { bool bList = false; CString sArg; - switch (m_pNetwork->GetIRCSock()->GetModeType(uMode)) { + switch (m_pNetwork->GetIRCSock()->GetModeType(cMode)) { case CIRCSock::ListArg: bList = true; sArg = GetModeArg(sArgs); @@ -401,22 +401,22 @@ void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { if (bList) { bNoChange = false; } else if (bAdd) { - bNoChange = HasMode(uMode) && GetModeArg(uMode) == sArg; + bNoChange = HasMode(cMode) && GetModeArg(cMode) == sArg; } else { - bNoChange = !HasMode(uMode); + bNoChange = !HasMode(cMode); } NETWORKMODULECALL( - OnMode2(pOpNick, *this, uMode, sArg, bAdd, bNoChange), + OnMode2(pOpNick, *this, cMode, sArg, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); if (!bList) { - (bAdd) ? AddMode(uMode, sArg) : RemMode(uMode); + (bAdd) ? AddMode(cMode, sArg) : RemMode(cMode); } // This is called when we join (ZNC requests the channel modes // on join) *and* when someone changes the channel keys. // We ignore channel key "*" because of some broken nets. - if (uMode == M_Key && !bNoChange && bAdd && sArg != "*") { + if (cMode == M_Key && !bNoChange && bAdd && sArg != "*") { SetKey(sArg); } } @@ -441,11 +441,11 @@ CString CChan::GetOptions() const { return CString(", ").Join(vsRet.begin(), vsRet.end()); } -CString CChan::GetModeArg(unsigned char uMode) const { - if (uMode) { - map::const_iterator it = m_musModes.find(uMode); +CString CChan::GetModeArg(char cMode) const { + if (cMode) { + map::const_iterator it = m_mcsModes.find(cMode); - if (it != m_musModes.end()) { + if (it != m_mcsModes.end()) { return it->second; } } @@ -453,21 +453,21 @@ CString CChan::GetModeArg(unsigned char uMode) const { return ""; } -bool CChan::HasMode(unsigned char uMode) const { - return (uMode && m_musModes.find(uMode) != m_musModes.end()); +bool CChan::HasMode(char cMode) const { + return (cMode && m_mcsModes.find(cMode) != m_mcsModes.end()); } -bool CChan::AddMode(unsigned char uMode, const CString& sArg) { - m_musModes[uMode] = sArg; +bool CChan::AddMode(char cMode, const CString& sArg) { + m_mcsModes[cMode] = sArg; return true; } -bool CChan::RemMode(unsigned char uMode) { - if (!HasMode(uMode)) { +bool CChan::RemMode(char cMode) { + if (!HasMode(cMode)) { return false; } - m_musModes.erase(uMode); + m_mcsModes.erase(cMode); return true; } @@ -556,7 +556,6 @@ map CChan::GetPermCounts() const { bool CChan::RemNick(const CString& sNick) { map::iterator it; - set::iterator it2; it = m_msNicks.find(sNick); if (it == m_msNicks.end()) { diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index 38932eec..afa8bf89 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -667,8 +667,8 @@ void CIRCNetwork::ClientConnected(CClient* pClient) { if (GetIRCSock() != nullptr) { CString sUserMode(""); - const set& scUserModes = GetIRCSock()->GetUserModes(); - for (unsigned char cMode : scUserModes) { + const set& scUserModes = GetIRCSock()->GetUserModes(); + for (char cMode : scUserModes) { sUserMode += cMode; } if (!sUserMode.empty()) { diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index 45e10f77..a8de9343 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -72,7 +72,7 @@ CIRCSock::CIRCSock(CIRCNetwork* pNetwork) m_sPerms("*!@%+"), m_sPermModes("qaohv"), m_scUserModes(), - m_mueChanModes(), + m_mceChanModes(), m_pNetwork(pNetwork), m_Nick(), m_sPass(""), @@ -94,16 +94,16 @@ CIRCSock::CIRCSock(CIRCNetwork* pNetwork) m_Nick.SetHost(m_pNetwork->GetBindHost()); SetEncoding(m_pNetwork->GetEncoding()); - m_mueChanModes['b'] = ListArg; - m_mueChanModes['e'] = ListArg; - m_mueChanModes['I'] = ListArg; - m_mueChanModes['k'] = HasArg; - m_mueChanModes['l'] = ArgWhenSet; - m_mueChanModes['p'] = NoArg; - m_mueChanModes['s'] = NoArg; - m_mueChanModes['t'] = NoArg; - m_mueChanModes['i'] = NoArg; - m_mueChanModes['n'] = NoArg; + m_mceChanModes['b'] = ListArg; + m_mceChanModes['e'] = ListArg; + m_mceChanModes['I'] = ListArg; + m_mceChanModes['k'] = HasArg; + m_mceChanModes['l'] = ArgWhenSet; + m_mceChanModes['p'] = NoArg; + m_mceChanModes['s'] = NoArg; + m_mceChanModes['t'] = NoArg; + m_mceChanModes['i'] = NoArg; + m_mceChanModes['n'] = NoArg; pNetwork->SetIRCSocket(this); @@ -566,17 +566,17 @@ bool CIRCSock::OnModeMessage(CModeMessage& Message) { m_pNetwork->GetUser(), nullptr, ); */ for (unsigned int a = 0; a < sModeArg.size(); a++) { - const unsigned char& uMode = sModeArg[a]; + const char& cMode = sModeArg[a]; - if (uMode == '+') { + if (cMode == '+') { bAdd = true; - } else if (uMode == '-') { + } else if (cMode == '-') { bAdd = false; } else { if (bAdd) { - m_scUserModes.insert(uMode); + m_scUserModes.insert(cMode); } else { - m_scUserModes.erase(uMode); + m_scUserModes.erase(cMode); } } } @@ -1230,7 +1230,7 @@ void CIRCSock::Disconnected() { // otherwise, on reconnect, it might think it still // had user modes that it actually doesn't have. CString sUserMode; - for (unsigned char cMode : m_scUserModes) { + for (char cMode : m_scUserModes) { sUserMode += cMode; } if (!sUserMode.empty()) { @@ -1357,13 +1357,13 @@ void CIRCSock::ParseISupport(const CMessage& Message) { } } else if (sName.Equals("CHANMODES")) { if (!sValue.empty()) { - m_mueChanModes.clear(); + m_mceChanModes.clear(); for (unsigned int a = 0; a < 4; a++) { CString sModes = sValue.Token(a, false, ","); for (unsigned int b = 0; b < sModes.size(); b++) { - m_mueChanModes[sModes[b]] = (EChanModeArgs)a; + m_mceChanModes[sModes[b]] = (EChanModeArgs)a; } } } @@ -1445,10 +1445,10 @@ void CIRCSock::SendAltNick(const CString& sBadNick) { m_Nick.SetNick(sNewNick); } -unsigned char CIRCSock::GetPermFromMode(unsigned char uMode) const { +char CIRCSock::GetPermFromMode(char cMode) const { if (m_sPermModes.size() == m_sPerms.size()) { for (unsigned int a = 0; a < m_sPermModes.size(); a++) { - if (m_sPermModes[a] == uMode) { + if (m_sPermModes[a] == cMode) { return m_sPerms[a]; } } @@ -1457,11 +1457,11 @@ unsigned char CIRCSock::GetPermFromMode(unsigned char uMode) const { return 0; } -CIRCSock::EChanModeArgs CIRCSock::GetModeType(unsigned char uMode) const { - map::const_iterator it = - m_mueChanModes.find(uMode); +CIRCSock::EChanModeArgs CIRCSock::GetModeType(char cMode) const { + map::const_iterator it = + m_mceChanModes.find(cMode); - if (it == m_mueChanModes.end()) { + if (it == m_mceChanModes.end()) { return NoArg; } diff --git a/src/Modules.cpp b/src/Modules.cpp index 98c0931f..f763386c 100644 --- a/src/Modules.cpp +++ b/src/Modules.cpp @@ -617,6 +617,11 @@ CModule::EModRet CModule::OnIRCRegistration(CString& sPass, CString& sNick, } CModule::EModRet CModule::OnBroadcast(CString& sMessage) { return CONTINUE; } +void CModule::OnChanPermission3(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, char cMode, + bool bAdded, bool bNoChange) { + OnChanPermission2(pOpNick, Nick, Channel, cMode, bAdded, bNoChange); +} void CModule::OnChanPermission2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange) { @@ -1144,6 +1149,13 @@ bool CModules::OnIRCDisconnected() { return false; } +bool CModules::OnChanPermission3(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, char cMode, + bool bAdded, bool bNoChange) { + MODUNLOADCHK( + OnChanPermission3(pOpNick, Nick, Channel, cMode, bAdded, bNoChange)); + return false; +} bool CModules::OnChanPermission2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange) { diff --git a/src/Nick.cpp b/src/Nick.cpp index ddb2485a..241f6e53 100644 --- a/src/Nick.cpp +++ b/src/Nick.cpp @@ -91,22 +91,22 @@ void CNick::SetNick(const CString& s) { m_sNick = s; } void CNick::SetIdent(const CString& s) { m_sIdent = s; } void CNick::SetHost(const CString& s) { m_sHost = s; } -bool CNick::HasPerm(unsigned char uPerm) const { - return (uPerm && m_sChanPerms.find(uPerm) != CString::npos); +bool CNick::HasPerm(char cPerm) const { + return (cPerm && m_sChanPerms.find(cPerm) != CString::npos); } -bool CNick::AddPerm(unsigned char uPerm) { - if (!uPerm || HasPerm(uPerm)) { +bool CNick::AddPerm(char cPerm) { + if (!cPerm || HasPerm(cPerm)) { return false; } - m_sChanPerms.append(1, uPerm); + m_sChanPerms.append(1, cPerm); return true; } -bool CNick::RemPerm(unsigned char uPerm) { - CString::size_type uPos = m_sChanPerms.find(uPerm); +bool CNick::RemPerm(char cPerm) { + CString::size_type uPos = m_sChanPerms.find(cPerm); if (uPos == CString::npos) { return false; } @@ -116,12 +116,12 @@ bool CNick::RemPerm(unsigned char uPerm) { return true; } -unsigned char CNick::GetPermChar() const { +char CNick::GetPermChar() const { CIRCSock* pIRCSock = (!m_pNetwork) ? nullptr : m_pNetwork->GetIRCSock(); const CString& sChanPerms = (!pIRCSock) ? "@+" : pIRCSock->GetPerms(); for (unsigned int a = 0; a < sChanPerms.size(); a++) { - const unsigned char& c = sChanPerms[a]; + const char& c = sChanPerms[a]; if (HasPerm(c)) { return c; } @@ -136,7 +136,7 @@ CString CNick::GetPermStr() const { CString sRet; for (unsigned int a = 0; a < sChanPerms.size(); a++) { - const unsigned char& c = sChanPerms[a]; + const char& c = sChanPerms[a]; if (HasPerm(c)) { sRet += c;