163 lines
4.8 KiB
C++
163 lines
4.8 KiB
C++
#include "self_thread.hpp"
|
|
|
|
#include <boost/log/trivial.hpp>
|
|
|
|
#include "connection.hpp"
|
|
#include "ircmsg.hpp"
|
|
#include "irc_parse_thread.hpp"
|
|
|
|
auto SelfThread::start(Connection& connection) -> std::shared_ptr<SelfThread>
|
|
{
|
|
auto thread = std::make_shared<SelfThread>(connection);
|
|
|
|
connection.add_listener<IrcMsgEvent>([thread](IrcMsgEvent& event)
|
|
{
|
|
switch (event.command)
|
|
{
|
|
// Learn nickname from 001
|
|
case IrcCommand::RPL_WELCOME:
|
|
if (event.irc.args.size() < 1)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "RPL_WELCOME has too few arguments";
|
|
break;
|
|
}
|
|
thread->nickname_ = event.irc.args[0];
|
|
break;
|
|
|
|
// Track changes to our nickname
|
|
case IrcCommand::NICK:
|
|
{
|
|
if (event.irc.args.size() < 1) {
|
|
BOOST_LOG_TRIVIAL(debug) << "NICK has too few arguments";
|
|
break;
|
|
}
|
|
|
|
if (thread->is_my_mask(event.irc.source))
|
|
{
|
|
thread->nickname_ = event.irc.args[0];
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Re-establish user modes
|
|
case IrcCommand::RPL_UMODEIS:
|
|
if (event.irc.args.size() < 1)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "RPL_UMODEIS has too few arguments";
|
|
break;
|
|
}
|
|
|
|
thread->mode_ = event.irc.args[1];
|
|
break;
|
|
|
|
case IrcCommand::JOIN: {
|
|
if (event.irc.args.size() < 1)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "JOIN has too few arguments";
|
|
break;
|
|
}
|
|
|
|
if (thread->is_my_mask(event.irc.source))
|
|
{
|
|
thread->channels_.insert(std::string{event.irc.args[0]});
|
|
}
|
|
break;
|
|
}
|
|
case IrcCommand::KICK: {
|
|
if (event.irc.args.size() < 2)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "PART has too few arguments";
|
|
break;
|
|
}
|
|
|
|
if (thread->is_my_nick(event.irc.args[1]))
|
|
{
|
|
thread->channels_.erase(std::string{event.irc.args[0]});
|
|
}
|
|
break;
|
|
}
|
|
case IrcCommand::PART: {
|
|
if (event.irc.args.size() < 1)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "PART has too few arguments";
|
|
break;
|
|
}
|
|
|
|
if (thread->is_my_mask(event.irc.source))
|
|
{
|
|
thread->channels_.erase(std::string{event.irc.args[0]});
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Interpret self mode changes
|
|
case IrcCommand::MODE:
|
|
if (event.irc.args.size() < 2)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "MODE has too few arguments";
|
|
break;
|
|
}
|
|
|
|
if (thread->is_my_nick(event.irc.args[0]))
|
|
{
|
|
auto polarity = true;
|
|
for (char const c : event.irc.args[1])
|
|
{
|
|
switch (c)
|
|
{
|
|
case '+':
|
|
polarity = true;
|
|
break;
|
|
case '-':
|
|
polarity = false;
|
|
break;
|
|
default:
|
|
if (polarity)
|
|
{
|
|
thread->mode_ += c;
|
|
}
|
|
else
|
|
{
|
|
auto const ix = thread->mode_.find(c);
|
|
if (ix != std::string::npos)
|
|
{
|
|
thread->mode_.erase(ix, 1);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
default: break;
|
|
}
|
|
});
|
|
|
|
return thread;
|
|
}
|
|
|
|
auto SelfThread::get_my_nickname() const -> std::string const&
|
|
{
|
|
return nickname_;
|
|
}
|
|
|
|
auto SelfThread::get_my_mode() const -> std::string const&
|
|
{
|
|
return mode_;
|
|
}
|
|
|
|
auto SelfThread::get_my_channels() const -> std::unordered_set<std::string> const&
|
|
{
|
|
return channels_;
|
|
}
|
|
|
|
auto SelfThread::is_my_nick(std::string_view nick) const -> bool
|
|
{
|
|
return nick == nickname_;
|
|
}
|
|
|
|
auto SelfThread::is_my_mask(std::string_view mask) const -> bool
|
|
{
|
|
auto const bang = mask.find('!');
|
|
return bang != std::string_view::npos && nickname_ == mask.substr(0, bang);
|
|
}
|