From 27d6cf2bfd1e714eaed34c4b29e763606cbd3211 Mon Sep 17 00:00:00 2001 From: fourtf Date: Wed, 18 Sep 2019 08:05:51 +0200 Subject: [PATCH] reconnect for irc + show errors + nickRequired --- src/common/Channel.cpp | 9 +++ src/common/Channel.hpp | 7 ++- src/providers/irc/IrcChannel2.cpp | 11 ++++ src/providers/irc/IrcChannel2.hpp | 4 ++ src/providers/irc/IrcServer.cpp | 85 ++++++++++++++++++++++++++ src/providers/twitch/TwitchChannel.cpp | 10 +++ src/providers/twitch/TwitchChannel.hpp | 2 + src/widgets/splits/SplitHeader.cpp | 5 +- 8 files changed, 130 insertions(+), 3 deletions(-) diff --git a/src/common/Channel.cpp b/src/common/Channel.cpp index b8247e88b..1c13b6db4 100644 --- a/src/common/Channel.cpp +++ b/src/common/Channel.cpp @@ -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::getEmpty() { static std::shared_ptr channel(new Channel("", Type::None)); diff --git a/src/common/Channel.hpp b/src/common/Channel.hpp index e8bfc29f6..f484235ac 100644 --- a/src/common/Channel.hpp +++ b/src/common/Channel.hpp @@ -44,9 +44,9 @@ public: explicit Channel(const QString &name, Type type); virtual ~Channel(); + // SIGNALS pajlada::Signals::Signal sendMessageSignal; - pajlada::Signals::Signal messageRemovedFromStart; pajlada::Signals::Signal> messageAppended; @@ -61,6 +61,7 @@ public: virtual bool isEmpty() const; LimitedQueueSnapshot 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 getEmpty(); diff --git a/src/providers/irc/IrcChannel2.cpp b/src/providers/irc/IrcChannel2.cpp index 8db724e30..13c9d11b8 100644 --- a/src/providers/irc/IrcChannel2.cpp +++ b/src/providers/irc/IrcChannel2.cpp @@ -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 diff --git a/src/providers/irc/IrcChannel2.hpp b/src/providers/irc/IrcChannel2.hpp index 8b89346a6..4e2753f91 100644 --- a/src/providers/irc/IrcChannel2.hpp +++ b/src/providers/irc/IrcChannel2.hpp @@ -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); diff --git a/src/providers/irc/IrcServer.cpp b/src/providers/irc/IrcServer.cpp index a9f7dd5da..928796128 100644 --- a/src/providers/irc/IrcServer.cpp +++ b/src/providers/irc/IrcServer.cpp @@ -1,6 +1,7 @@ #include "IrcServer.hpp" #include +#include #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 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(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(shared.get())) + c->addJoinedUser(x->nick()); + } + } + } + return; + } + + case Communi::IrcMessage::Part: + { + auto x = static_cast(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(shared.get())) + c->addPartedUser(x->nick()); + } + } + } + return; + } + + case Communi::IrcMessage::Pong: + return; + + default:; + } + +#ifdef QT_DEBUG MessageBuilder builder; builder.emplace(); @@ -145,6 +229,7 @@ void IrcServer::readConnectionMessageReceived(Communi::IrcMessage *message) if (auto shared = weak.lock()) shared->addMessage(msg); } +#endif } } // namespace chatterino diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index d9c0417b2..51d103510 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -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(); diff --git a/src/providers/twitch/TwitchChannel.hpp b/src/providers/twitch/TwitchChannel.hpp index 933e7ab90..ec3ffc606 100644 --- a/src/providers/twitch/TwitchChannel.hpp +++ b/src/providers/twitch/TwitchChannel.hpp @@ -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(); diff --git a/src/widgets/splits/SplitHeader.cpp b/src/widgets/splits/SplitHeader.cpp index 009f8031d..d50fe0716 100644 --- a/src/widgets/splits/SplitHeader.cpp +++ b/src/widgets/splits/SplitHeader.cpp @@ -343,7 +343,8 @@ std::unique_ptr SplitHeader::createMainMenu() } moreMenu->addSeparator(); - moreMenu->addAction("Reconnect", this, SLOT(reconnect())); + if (this->split_->getChannel()->canReconnect()) + moreMenu->addAction("Reconnect", this, SLOT(reconnect())); if (dynamic_cast(this->split_->getChannel().get())) { @@ -740,7 +741,7 @@ void SplitHeader::reloadSubscriberEmotes() void SplitHeader::reconnect() { - getApp()->twitch.server->connect(); + this->split_->getChannel()->reconnect(); } } // namespace chatterino