From 0dcfc5eedc580e134206df0910cd1d7ad1589a01 Mon Sep 17 00:00:00 2001 From: blue Date: Sun, 21 Jun 2020 01:26:30 +0300 Subject: [PATCH] some better cleanup and restore state on connect disconnect, workaround for that wired undefined condition error on every other reconnection --- core/account.cpp | 42 ++++++++++++++++++++++++--------- core/account.h | 3 ++- core/handlers/rosterhandler.cpp | 10 ++++++-- core/handlers/rosterhandler.h | 2 +- core/rosteritem.cpp | 19 ++++++++++++++- core/rosteritem.h | 1 + 6 files changed, 61 insertions(+), 16 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index 59a05fd..5ed8873 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -25,7 +25,7 @@ using namespace Core; Account::Account(const QString& p_login, const QString& p_server, const QString& p_password, const QString& p_name, NetworkAccess* p_net, QObject* parent): QObject(parent), name(p_name), - achiveQueries(), + archiveQueries(), client(), config(), presence(), @@ -137,7 +137,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& } reconnectTimer->setSingleShot(true); - QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::connect); + QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::onReconnectTimer); // QXmppLogger* logger = new QXmppLogger(this); // logger->setLoggingType(QXmppLogger::SignalLogging); @@ -178,6 +178,10 @@ Shared::ConnectionState Core::Account::getState() const void Core::Account::connect() { + if (reconnectScheduled) { + reconnectScheduled = false; + reconnectTimer->stop(); + } if (state == Shared::ConnectionState::disconnected) { qDebug() << presence.availableStatusType(); client.connectToServer(config, presence); @@ -186,6 +190,14 @@ void Core::Account::connect() } } +void Core::Account::onReconnectTimer() +{ + if (reconnectScheduled) { + reconnectScheduled = false; + connect(); + } +} + void Core::Account::disconnect() { if (reconnectScheduled) { @@ -193,7 +205,7 @@ void Core::Account::disconnect() reconnectTimer->stop(); } if (state != Shared::ConnectionState::disconnected) { - rh->clearConferences(); + //rh->clearConferences(); client.disconnectFromServer(); } } @@ -397,8 +409,8 @@ void Core::Account::sendMessage(const Shared::Message& data, const QString& path void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMessage& msg) { if (msg.id().size() > 0 && (msg.body().size() > 0 || msg.outOfBandUrl().size() > 0)) { - std::map::const_iterator itr = achiveQueries.find(queryId); - if (itr != achiveQueries.end()) { + std::map::const_iterator itr = archiveQueries.find(queryId); + if (itr != archiveQueries.end()) { QString jid = itr->second; RosterItem* item = rh->getRosterItem(jid); @@ -469,15 +481,15 @@ void Core::Account::onContactNeedHistory(const QString& before, const QString& a } QString q = am->retrieveArchivedMessages(to, "", with, start, QDateTime(), query); - achiveQueries.insert(std::make_pair(q, contact->jid)); + archiveQueries.insert(std::make_pair(q, contact->jid)); } void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResultSetReply& resultSetReply, bool complete) { - std::map::const_iterator itr = achiveQueries.find(queryId); - if (itr != achiveQueries.end()) { + std::map::const_iterator itr = archiveQueries.find(queryId); + if (itr != archiveQueries.end()) { QString jid = itr->second; - achiveQueries.erase(itr); + archiveQueries.erase(itr); RosterItem* ri = rh->getRosterItem(jid); @@ -570,6 +582,8 @@ void Core::Account::onClientError(QXmppClient::Error err) break; case QXmppStanza::Error::UndefinedCondition: errorText = "Undefined condition"; + reconnectScheduled = true; + reconnectTimer->start(500); //let's reconnect here just for now, it seems to be something broken in QXMPP break; case QXmppStanza::Error::UnexpectedRequest: errorText = "Unexpected request"; @@ -882,7 +896,13 @@ void Core::Account::onDiscoveryInfoReceived(const QXmppDiscoveryIq& info) void Core::Account::cancelHistoryRequests() { - rh->cancelHistoryRequests(); - achiveQueries.clear(); + rh->handleOffline(); + archiveQueries.clear(); + pendingVCardRequests.clear(); + Shared::VCard vCard; //just to show, that there is now more pending request + for (const QString& jid : pendingVCardRequests) { + emit receivedVCard(jid, vCard); //need to show it better in the future, like with an error + } + ownVCardRequestInProgress = false; } diff --git a/core/account.h b/core/account.h index 9af4d7b..d7ca113 100644 --- a/core/account.h +++ b/core/account.h @@ -138,7 +138,7 @@ signals: private: QString name; - std::map achiveQueries; + std::map archiveQueries; QXmppClient client; QXmppConfiguration config; QXmppPresence presence; @@ -186,6 +186,7 @@ private slots: private: void cancelHistoryRequests(); + void onReconnectTimer(); }; void initializeVCard(Shared::VCard& vCard, const QXmppVCardIq& card); diff --git a/core/handlers/rosterhandler.cpp b/core/handlers/rosterhandler.cpp index ea1812d..44b2bda 100644 --- a/core/handlers/rosterhandler.cpp +++ b/core/handlers/rosterhandler.cpp @@ -421,7 +421,11 @@ void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks) if (cItr == conferences.end()) { addNewRoom(jid, c.nickName(), c.name(), c.autoJoin()); } else { - qDebug() << "Received a bookmark to a MUC " << jid << " which is already booked by another bookmark, skipping"; + if (c.autoJoin()) { + cItr->second->setJoined(true); + } else { + cItr->second->setAutoJoin(false); + } } } } @@ -572,12 +576,14 @@ void Core::RosterHandler::onContactAvatarChanged(Shared::Avatar type, const QStr emit acc->changeContact(item->jid, cData); } -void Core::RosterHandler::cancelHistoryRequests() +void Core::RosterHandler::handleOffline() { for (const std::pair& pair : conferences) { pair.second->clearArchiveRequests(); + pair.second->downgradeDatabaseState(); } for (const std::pair& pair : contacts) { pair.second->clearArchiveRequests(); + pair.second->downgradeDatabaseState(); } } diff --git a/core/handlers/rosterhandler.h b/core/handlers/rosterhandler.h index c8eeafa..c01f396 100644 --- a/core/handlers/rosterhandler.h +++ b/core/handlers/rosterhandler.h @@ -55,7 +55,7 @@ public: void removeRoomRequest(const QString& jid); void addRoomRequest(const QString& jid, const QString& nick, const QString& password, bool autoJoin); - void cancelHistoryRequests(); + void handleOffline(); Core::Contact* getContact(const QString& jid); Core::Conference* getConference(const QString& jid); diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp index 9163994..5275993 100644 --- a/core/rosteritem.cpp +++ b/core/rosteritem.cpp @@ -523,8 +523,25 @@ void Core::RosterItem::clearArchiveRequests() syncronizing = false; requestedCount = 0; requestedBefore = ""; + for (const std::pair& pair : requestCache) { + if (pair.first != -1) { + emit historyResponse(responseCache); //just to notify those who still waits with whatever happened to be left in caches yet + } + responseCache.clear(); + } hisoryCache.clear(); - responseCache.clear(); + responseCache.clear(); //in case the cycle never runned appendCache.clear(); requestCache.clear(); } + +void Core::RosterItem::downgradeDatabaseState() +{ + if (archiveState == ArchiveState::complete) { + archiveState = ArchiveState::beginning; + } + + if (archiveState == ArchiveState::end) { + archiveState = ArchiveState::chunk; + } +} diff --git a/core/rosteritem.h b/core/rosteritem.h index f38e189..4113b37 100644 --- a/core/rosteritem.h +++ b/core/rosteritem.h @@ -76,6 +76,7 @@ public: bool changeMessage(const QString& id, const QMap& data); void clearArchiveRequests(); + void downgradeDatabaseState(); signals: void nameChanged(const QString& name);