The complete source code of IdealIRC http://www.idealirc.org/
 
 
 
 
idealirc/IRCClient/IRCMemberEntry.cpp

64 lines
1.7 KiB

#include "IRCMemberEntry.h"
#include "IRCBase.h"
#include <algorithm>
IRCMemberEntry::IRCMemberEntry(std::shared_ptr<IRCMember> member, IRCBase& owner)
: m_member(member)
, m_owner(&owner)
{}
std::shared_ptr<IRCMember> IRCMemberEntry::member() const
{
return m_member;
}
const std::string& IRCMemberEntry::modes() const
{
return m_modes;
}
void IRCMemberEntry::addMode(char m)
{
// Note: "PREFIX" is always present.
// Value example: (ohv)@%+
// Value is ordered with most significant first.
const std::string& prefix = m_owner->isupport().find("PREFIX")->second;
// Just interested in the mode letters (ie. ohv)
const std::string validModes(prefix.begin() + 1, std::find(prefix.begin(), prefix.end(), ')'));
auto order = [validModes](const char m) -> int {
auto ret = validModes.find(m);
return ret != std::string::npos ? static_cast<int>(ret)
: -1;
};
auto mOrd = order(m);
if (mOrd < 0)
return;
auto it = m_modes.begin();
for (auto& mode : m_modes) {
if (mode == m)
return;
else if (order(mode) >= mOrd)
break;
else
++it;
}
m_modes.insert(it, m);
}
void IRCMemberEntry::delMode(char m)
{
auto pos = m_modes.find_first_of(m);
/*
* Out-of-bounds can happen due to an IRC protocol bug. For example, where you join a channel which has
* members that got both op (@) and voice (+) but only one of the symbols is visible from NAMES message
* meaning that the client only picks up the "most significant" mode.
* IRCv3 implements a fix for this which this client support, but not all servers do.
* When a member then removes the unknown mode, we get this situation below;
*/
if (pos != std::string::npos)
m_modes.erase(pos, 1);
}