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
This commit is contained in:
Alexey Sokolov
2018-02-10 15:49:53 +00:00
parent 9ff4127e33
commit a2470b3dd3
10 changed files with 127 additions and 99 deletions
+38 -39
View File
@@ -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<unsigned char, CString>::const_iterator it = m_musModes.find(uMode);
CString CChan::GetModeArg(char cMode) const {
if (cMode) {
map<char, CString>::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<char, unsigned int> CChan::GetPermCounts() const {
bool CChan::RemNick(const CString& sNick) {
map<CString, CNick>::iterator it;
set<unsigned char>::iterator it2;
it = m_msNicks.find(sNick);
if (it == m_msNicks.end()) {