Fixing problems updating and maintaining internal member lists triggered by JOIN, PART, QUIT, KICK.

master
Tomatix 5 years ago
parent 89f2b86be7
commit 9e9a7bb9dc
  1. 68
      IRCClient/IRCBase.cpp
  2. 20
      IRCClient/IRCChannel.cpp
  3. 5
      IRCClient/IRCMember.cpp
  4. 17
      IdealIRC/IRC.cpp

@ -360,24 +360,43 @@ struct IRCBasePriv
{
auto member = super.getMember(prefix.nickname());
auto chanentry = super.getChannel(channel);
if (member && chanentry) {
member->delChannel(chanentry);
chanentry->delMember(member);
/* If not us and the member isn't known on any channels anymore, remove it. */
if (prefix.nickname() != nickname && member->channels().empty()) {
auto it = std::find(allMembers.begin(), allMembers.end(), member);
allMembers.erase(it);
}
if (member && chanentry) {
member->delChannel(chanentry);
/* Delete only if not us. */
if (member->channels().empty() && prefix.nickname() != nickname) {
chanentry->delMember(member);
auto it = std::find_if(allMembers.begin(), allMembers.end(),
[&prefix](auto mem) {
return prefix == mem->prefix();
});
if (it != allMembers.end())
allMembers.erase(it);
}
/* If us, delete everything we know about this channel */
else if (prefix.nickname() == nickname)
channels.erase(
std::find_if(channels.begin(), channels.end(),
[&channel](std::weak_ptr<IRCChannel> cptr) {
return channel == cptr.lock()->name();
}
));
/* If us, delete everything we know about this channel. */
if (prefix.nickname() == nickname) {
/* We also need to remove this channel from every member in that channel. */
for (auto m : chanentry->members()) {
IRCPrefix mp = m.member()->prefix();
if (mp.nickname() == nickname)
continue;
delMemberFromChannel(mp, channel);
}
chanentry->delMember(member);
/* Erase this channel */
auto it = std::find_if(channels.begin(), channels.end(),
[&channel](auto cptr) {
return channel == cptr->name();
});
if (it != channels.end())
channels.erase(it);
}
}
}
@ -527,16 +546,6 @@ struct IRCBasePriv
}
}
void delChannel(const std::string& name)
{
auto iter = std::remove_if(channels.begin(), channels.end(),
[name](const auto& ptr){
return ptr->name() == name;
});
channels.erase(iter, channels.end());
}
void parseIncoming(const std::string& line);
}; // IRCBasePriv
@ -1237,8 +1246,6 @@ void IRCBasePriv::parseIncoming(const std::string& line)
else if (command == PART) {
super.onMsgPart(sender, args[0], msg);
delMemberFromChannel(sender, args[0]);
if (sender.toString() == nickname)
delChannel(args[0]);
}
else if (command == TOPIC) {
@ -1251,9 +1258,8 @@ void IRCBasePriv::parseIncoming(const std::string& line)
else if (command == KICK) {
super.onMsgKick(sender, args[0], args[1], msg);
delMemberFromChannel(sender, args[0]);
if (args[1] == nickname)
delChannel(args[0]);
auto prefix = IRCPrefix::fromNickname(args[1]);
delMemberFromChannel(prefix, args[0]);
}
else if (command == PRIVMSG) {

@ -26,15 +26,25 @@ std::optional<IRCMemberEntryRef> IRCChannel::getMember(const std::string& nickna
IRCMemberEntry& IRCChannel::addMember(std::shared_ptr<IRCMember> member)
{
m_members.emplace_back(member, *m_owner);
return m_members.back();
auto it = std::find_if(m_members.begin(), m_members.end(),
[member](const IRCMemberEntry& entry){
return entry.member()->prefix() == member->prefix();
});
if (it == m_members.end()) {
m_members.emplace_back(member, *m_owner);
return m_members.back();
}
else
return *it;
}
void IRCChannel::delMember(std::shared_ptr<IRCMember> member)
{
auto newEnd = std::remove_if(m_members.begin(), m_members.end(), [&member](const IRCMemberEntry& e){
return member.get() == e.member().get();
});
auto newEnd = std::remove_if(m_members.begin(), m_members.end(),
[&member](const IRCMemberEntry& e){
return member->prefix() == e.member()->prefix();
});
m_members.erase(newEnd, m_members.end());
}

@ -1,4 +1,5 @@
#include "IRCMember.h"
#include "IRCChannel.h"
#include <algorithm>
IRCMember::IRCMember(const IRCPrefix& prefix)
@ -28,7 +29,7 @@ void IRCMember::addChannel(std::weak_ptr<IRCChannel> channel)
{
auto it = std::find_if(m_channels.begin(), m_channels.end(),
[channel](const std::weak_ptr<IRCChannel>& p){
return p.lock() == channel.lock();
return p.lock()->name() == channel.lock()->name();
});
if (it == m_channels.end())
@ -39,7 +40,7 @@ void IRCMember::delChannel(std::weak_ptr<IRCChannel> channel)
{
auto newEnd = std::remove_if(m_channels.begin(), m_channels.end(),
[channel](const std::weak_ptr<IRCChannel>& p){
return p.lock() == channel.lock();
return p.lock()->name() == channel.lock()->name();
});
m_channels.erase(newEnd, m_channels.end());

@ -389,13 +389,18 @@ void IRC::onMsgPrivmsg(const IRCPrefix& sender, const std::string& target, const
auto& conf = ConfigMgr::instance();
std::string msg;
if (conf.common("ShowModeInMessage").toInt()) {
auto& member = getChannel(target)->getMember(sender.toString())->get();
if (member.modes().empty())
msg = fmt::format("<{}> {}", sender.toString(), message);
else {
std::string symbols = toMemberPrefix(member.modes());
msg = fmt::format("<{}{}> {}", symbols[0], sender.toString(), message);
auto memberOpt = getChannel(target)->getMember(sender.toString());
if (memberOpt) {
auto& member = memberOpt->get();
if (member.modes().empty())
msg = fmt::format("<{}> {}", sender.toString(), message);
else {
std::string symbols = toMemberPrefix(member.modes());
msg = fmt::format("<{}{}> {}", symbols[0], sender.toString(), message);
}
}
else
msg = fmt::format("<{}> {}", sender.toString(), message);
}
else
msg = fmt::format("<{}> {}", sender.toString(), message);

Loading…
Cancel
Save