reconnect for irc + show errors + nickRequired

This commit is contained in:
fourtf 2019-09-18 08:05:51 +02:00
parent 96dac0fd3d
commit 27d6cf2bfd
8 changed files with 130 additions and 3 deletions

View file

@ -280,6 +280,15 @@ bool Channel::shouldIgnoreHighlights() const
this->type_ == Type::TwitchWhispers;
}
bool Channel::canReconnect() const
{
return false;
}
void Channel::reconnect()
{
}
std::shared_ptr<Channel> Channel::getEmpty()
{
static std::shared_ptr<Channel> channel(new Channel("", Type::None));

View file

@ -44,9 +44,9 @@ public:
explicit Channel(const QString &name, Type type);
virtual ~Channel();
// SIGNALS
pajlada::Signals::Signal<const QString &, const QString &, bool &>
sendMessageSignal;
pajlada::Signals::Signal<MessagePtr &> messageRemovedFromStart;
pajlada::Signals::Signal<MessagePtr &, boost::optional<MessageFlags>>
messageAppended;
@ -61,6 +61,7 @@ public:
virtual bool isEmpty() const;
LimitedQueueSnapshot<MessagePtr> getMessageSnapshot();
// MESSAGES
// overridingFlags can be filled in with flags that should be used instead
// of the message's flags. This is useful in case a flag is specific to a
// type of split
@ -72,9 +73,11 @@ public:
void disableAllMessages();
void replaceMessage(MessagePtr message, MessagePtr replacement);
void deleteMessage(QString messageID);
void clearMessages();
QStringList modList;
// CHANNEL INFO
virtual bool canSendMessage() const;
virtual void sendMessage(const QString &message);
virtual bool isMod() const;
@ -83,6 +86,8 @@ public:
virtual bool hasHighRateLimit() const;
virtual bool isLive() const;
virtual bool shouldIgnoreHighlights() const;
virtual bool canReconnect() const;
virtual void reconnect();
static std::shared_ptr<Channel> getEmpty();

View file

@ -42,4 +42,15 @@ void IrcChannel::setServer(IrcServer *server)
this->server_ = server;
}
bool IrcChannel::canReconnect() const
{
return true;
}
void IrcChannel::reconnect()
{
if (this->server())
this->server()->connect();
}
} // namespace chatterino

View file

@ -18,6 +18,10 @@ public:
// server may be nullptr
IrcServer *server();
// Channel methods
virtual bool canReconnect() const override;
virtual void reconnect() override;
private:
void setServer(IrcServer *server);

View file

@ -1,6 +1,7 @@
#include "IrcServer.hpp"
#include <cassert>
#include <cstdlib>
#include "messages/MessageBuilder.hpp"
#include "providers/irc/Irc2.hpp"
@ -84,6 +85,28 @@ void IrcServer::initializeConnection(IrcConnection *connection,
default:
this->open(Both);
}
QObject::connect(
connection, &Communi::IrcConnection::socketError, this,
[this](QAbstractSocket::SocketError error) {
static int index =
QAbstractSocket::staticMetaObject.indexOfEnumerator(
"SocketError");
std::lock_guard lock(this->channelMutex);
for (auto &&weak : this->channels)
if (auto shared = weak.lock())
shared->addMessage(makeSystemMessage(
QStringLiteral("Socket error: ") +
QAbstractSocket::staticMetaObject.enumerator(index)
.valueToKey(error)));
});
QObject::connect(connection, &Communi::IrcConnection::nickNameRequired,
this, [](const QString &reserved, QString *result) {
*result = reserved + (std::rand() % 100);
});
}
std::shared_ptr<Channel> IrcServer::createChannel(const QString &channelName)
@ -133,6 +156,67 @@ void IrcServer::readConnectionMessageReceived(Communi::IrcMessage *message)
{
AbstractIrcServer::readConnectionMessageReceived(message);
switch (message->type())
{
case Communi::IrcMessage::Join:
{
auto x = static_cast<Communi::IrcJoinMessage *>(message);
if (auto it =
this->channels.find(this->cleanChannelName(x->channel()));
it != this->channels.end())
{
if (auto shared = it->lock())
{
if (message->nick() == this->data_->nick)
{
shared->addMessage(
MessageBuilder(systemMessage, "joined").release());
}
else
{
if (auto c =
dynamic_cast<ChannelChatters *>(shared.get()))
c->addJoinedUser(x->nick());
}
}
}
return;
}
case Communi::IrcMessage::Part:
{
auto x = static_cast<Communi::IrcPartMessage *>(message);
if (auto it =
this->channels.find(this->cleanChannelName(x->channel()));
it != this->channels.end())
{
if (auto shared = it->lock())
{
if (message->nick() == this->data_->nick)
{
shared->addMessage(
MessageBuilder(systemMessage, "parted").release());
}
else
{
if (auto c =
dynamic_cast<ChannelChatters *>(shared.get()))
c->addPartedUser(x->nick());
}
}
}
return;
}
case Communi::IrcMessage::Pong:
return;
default:;
}
#ifdef QT_DEBUG
MessageBuilder builder;
builder.emplace<TimestampElement>();
@ -145,6 +229,7 @@ void IrcServer::readConnectionMessageReceived(Communi::IrcMessage *message)
if (auto shared = weak.lock())
shared->addMessage(msg);
}
#endif
}
} // namespace chatterino

View file

@ -276,6 +276,16 @@ bool TwitchChannel::hasHighRateLimit() const
return this->isMod() || this->isBroadcaster() || this->isVIP();
}
bool TwitchChannel::canReconnect() const
{
return true;
}
void TwitchChannel::reconnect()
{
getApp()->twitch.server->connect();
}
QString TwitchChannel::roomId() const
{
return *this->roomID_.access();

View file

@ -67,6 +67,8 @@ public:
bool isStaff() const;
virtual bool isBroadcaster() const override;
virtual bool hasHighRateLimit() const override;
virtual bool canReconnect() const override;
virtual void reconnect() override;
// Data
const QString &subscriptionUrl();

View file

@ -343,6 +343,7 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
}
moreMenu->addSeparator();
if (this->split_->getChannel()->canReconnect())
moreMenu->addAction("Reconnect", this, SLOT(reconnect()));
if (dynamic_cast<TwitchChannel *>(this->split_->getChannel().get()))
@ -740,7 +741,7 @@ void SplitHeader::reloadSubscriberEmotes()
void SplitHeader::reconnect()
{
getApp()->twitch.server->connect();
this->split_->getChannel()->reconnect();
}
} // namespace chatterino