diff options
| -rw-r--r-- | src/mainwindow.cpp | 54 | ||||
| -rw-r--r-- | src/mainwindow.h | 4 | ||||
| -rw-r--r-- | src/modinfo.cpp | 42 | ||||
| -rw-r--r-- | src/modinfo.h | 2 | ||||
| -rw-r--r-- | src/nexusinterface.cpp | 30 | ||||
| -rw-r--r-- | src/nexusinterface.h | 2 | ||||
| -rw-r--r-- | src/nxmaccessmanager.cpp | 4 |
7 files changed, 71 insertions, 67 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3a341298..fecf8704 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -439,10 +439,6 @@ MainWindow::MainWindow(QSettings &initSettings connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas())); m_SaveMetaTimer.start(5000); - m_ModUpdateTimer.setSingleShot(false); - connect(&m_ModUpdateTimer, SIGNAL(timeout()), this, SLOT(modUpdateCheck())); - m_ModUpdateTimer.start(300 * 1000); - setCategoryListVisible(initSettings.value("categorylist_visible", true).toBool()); FileDialogMemory::restore(initSettings); @@ -495,8 +491,6 @@ MainWindow::MainWindow(QSettings &initSettings updatePluginCount(); updateModCount(); - - modUpdateCheck(); } @@ -4056,6 +4050,22 @@ void MainWindow::ignoreUpdate() { } } +void MainWindow::checkModUpdates_clicked() +{ + std::multimap<QString, int> IDs; + QItemSelectionModel *selection = ui->modList->selectionModel(); + if (selection->hasSelection() && selection->selectedRows().count() > 1) { + for (QModelIndex idx : selection->selectedRows()) { + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + IDs.insert(std::make_pair<QString, int>(info->getGameName(), info->getNexusID())); + } + } else { + ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); + IDs.insert(std::make_pair<QString, int>(info->getGameName(), info->getNexusID())); + } + modUpdateCheck(IDs); +} + void MainWindow::unignoreUpdate() { QItemSelectionModel *selection = ui->modList->selectionModel(); @@ -4411,7 +4421,7 @@ void MainWindow::initModListContextMenu(QMenu *menu) menu->addAction(tr("Enable all visible"), this, SLOT(enableVisibleMods())); menu->addAction(tr("Disable all visible"), this, SLOT(disableVisibleMods())); - menu->addAction(tr("Force update check"), this, SLOT(checkModsForUpdates())); + menu->addAction(tr("Check for updates"), this, SLOT(checkModsForUpdates())); menu->addAction(tr("Refresh"), &m_OrganizerCore, SLOT(profileRefresh())); menu->addAction(tr("Export to csv..."), this, SLOT(exportModListCSV())); } @@ -4518,10 +4528,11 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Change versioning scheme"), this, SLOT(changeVersioningScheme())); } + if (info->getNexusID() > 0) + menu->addAction(tr("Force-check updates"), this, SLOT(checkModUpdates_clicked())); if (info->updateIgnored()) { menu.addAction(tr("Un-ignore update"), this, SLOT(unignoreUpdate())); - } - else { + } else { if (info->updateAvailable() || info->downgradeAvailable()) { menu.addAction(tr("Ignore update"), this, SLOT(ignoreUpdate())); } @@ -5447,15 +5458,15 @@ void MainWindow::modDetailsUpdated(bool) } } -void MainWindow::modUpdateCheck() +void MainWindow::modUpdateCheck(std::multimap<QString, int> IDs) { if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->validated()) { - m_ModsToUpdate += ModInfo::autoUpdateCheck(&m_PluginContainer, this); + m_ModsToUpdate += ModInfo::manualUpdateCheck(&m_PluginContainer, this, IDs); m_RefreshProgress->setRange(0, m_ModsToUpdate); } else { QString apiKey; if (m_OrganizerCore.settings().getNexusApiKey(apiKey)) { - m_OrganizerCore.doAfterLogin([this]() { this->modUpdateCheck(); }); + m_OrganizerCore.doAfterLogin([=]() { this->modUpdateCheck(IDs); }); NexusInterface::instance(&m_PluginContainer)->getAccessManager()->apiCheck(apiKey); } else { qWarning("You are not currently authenticated with Nexus. Please do so under Settings -> Nexus."); @@ -5506,19 +5517,20 @@ void MainWindow::nxmUpdatesAvailable(QString gameName, int modID, QVariant userD if (currentUpdate == updateScanData["old_file_id"].toInt()) { currentUpdate = updateScanData["new_file_id"].toInt(); finalUpdate = false; + // Apply the version data from the latest file + for (auto file : files) { + QVariantMap fileData = file.toMap(); + if (fileData["file_id"].toInt() == currentUpdate) { + if (fileData["category_id"].toInt() != 6) { + mod->setNewestVersion(fileData["version"].toString()); + foundUpdate = true; + } + } + } break; } } } - // Apply the version data from the latest file - for (auto file : files) { - QVariantMap fileData = file.toMap(); - if (fileData["file_id"].toInt() == currentUpdate) { - mod->setNewestVersion(fileData["version"].toString()); - foundUpdate = true; - } - } - break; } else if (installedFile == updateData["new_file_name"].toString()) { // This is a safety mechanism if this is the latest update file so we don't use the mod version diff --git a/src/mainwindow.h b/src/mainwindow.h index 3f3a5457..59be9800 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -348,7 +348,6 @@ private: QTimer m_CheckBSATimer; QTimer m_SaveMetaTimer; QTimer m_UpdateProblemsTimer; - QTimer m_ModUpdateTimer; QFuture<void> m_MetaSave; @@ -509,7 +508,7 @@ private slots: void modInstalled(const QString &modName); - void modUpdateCheck(); + void modUpdateCheck(std::multimap<QString, int> IDs); void nxmUpdatesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); void nxmModInfoAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); @@ -590,6 +589,7 @@ private slots: void overwriteClosed(int); void changeVersioningScheme(); + void checkModUpdates_clicked(); void ignoreUpdate(); void unignoreUpdate(); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index e9cfd77b..a5b240c8 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -148,8 +148,7 @@ std::vector<ModInfo::Ptr> ModInfo::getByModID(QString game, int modID) for (auto iter : s_ModsByModID) { if (iter.first.second == modID) { if (iter.first.first.compare(game, Qt::CaseInsensitive) == 0) { - match = iter.second; - break; + match.insert(match.end(), iter.second.begin(), iter.second.end()); } } } @@ -303,6 +302,9 @@ int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiv } result = organizedGames.size(); + + if (organizedGames.empty()) + qWarning("All of your mods have been checked recently. We restrict update checks to help preserve your available API requests."); for (auto game : organizedGames) { NexusInterface::instance(pluginContainer)->requestUpdates(game.second, receiver, QVariant(), game.first, QString()); @@ -312,32 +314,28 @@ int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiv } -int ModInfo::autoUpdateCheck(PluginContainer *pluginContainer, QObject *receiver) +int ModInfo::manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiver, std::multimap<QString, int> IDs) { - qInfo("Initializing periodic update check."); - int result = 0; - - std::vector<QSharedPointer<ModInfo>> sortedMods; + std::vector<QSharedPointer<ModInfo>> mods; std::multimap<QString, int> organizedGames; - for (auto mod : s_Collection) { - if (mod->canBeUpdated()) { - sortedMods.push_back(mod); - } + + for (auto ID : IDs) { + auto matchedMods = getByModID(ID.first, ID.second); + mods.insert(mods.end(), matchedMods.begin(), matchedMods.end()); } + mods.erase( + std::remove_if(mods.begin(), mods.end(), [](ModInfo::Ptr mod) -> bool { return !mod->canBeUpdated(); }), + mods.end() + ); - std::sort(sortedMods.begin(), sortedMods.end(), [](QSharedPointer<ModInfo> a, QSharedPointer<ModInfo> b) -> bool { + std::sort(mods.begin(), mods.end(), [](QSharedPointer<ModInfo> a, QSharedPointer<ModInfo> b) -> bool { return a->getLastNexusUpdate() < b->getLastNexusUpdate(); }); - if (sortedMods.size() > 10) - sortedMods.resize(10); - - result = sortedMods.size(); + if (mods.size()) { + qInfo("Checking updates for %d mods...", mods.size()); - if (sortedMods.size()) { - qInfo("Checking updates for %d mods...", sortedMods.size()); - - for (auto mod : sortedMods) { + for (auto mod : mods) { organizedGames.insert(std::make_pair<QString, int>(mod->getGameName(), mod->getNexusID())); } @@ -345,10 +343,10 @@ int ModInfo::autoUpdateCheck(PluginContainer *pluginContainer, QObject *receiver NexusInterface::instance(pluginContainer)->requestUpdates(game.second, receiver, QVariant(), game.first, QString()); } } else { - qInfo("No mods require updates at this time."); + qInfo("None of the selected mods can be updated."); } - return result; + return organizedGames.size(); } diff --git a/src/modinfo.h b/src/modinfo.h index ae9dd1f3..9343a98c 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -188,7 +188,7 @@ public: /** * @brief run a limited batch of mod update checks for "newest version" information */ - static int autoUpdateCheck(PluginContainer *pluginContainer, QObject *receiver); + static int manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiver, std::multimap<QString, int> IDs); /** * @brief query nexus information for every mod and update the "newest version" information diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 1d6d2015..130a87b1 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -155,10 +155,6 @@ NexusInterface::NexusInterface(PluginContainer *pluginContainer) m_AccessManager = new NXMAccessManager(this, m_MOVersion.displayString(3)); m_DiskCache = new QNetworkDiskCache(this); connect(m_AccessManager, SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString))); - - m_RetryTimer.setSingleShot(true); - m_RetryTimer.setInterval(2000); - m_RetryTimer.callOnTimeout(this, &NexusInterface::nextRequest); } NXMAccessManager *NexusInterface::getAccessManager() @@ -468,8 +464,6 @@ IPluginGame* NexusInterface::getGame(QString gameName) const void NexusInterface::cleanup() { -// delete m_AccessManager; -// delete m_DiskCache; m_AccessManager = nullptr; m_DiskCache = nullptr; } @@ -487,19 +481,6 @@ void NexusInterface::nextRequest() return; } - if (m_RemainingDailyRequests + m_RemainingHourlyRequests <= 0) { - if (!m_RetryTimer.isActive()) { - QTime time = QTime::currentTime(); - QTime targetTime; - targetTime.setHMS((time.hour() + 1) % 23, 0, 5); - m_RetryTimer.start(time.msecsTo(targetTime)); - QString warning("You've exceeded the Nexus API rate limit and requests are now being throttled. " - "Your next batch of requests will be available in approximately %1 minutes and %2 seconds."); - qWarning() << warning.arg(time.secsTo(targetTime) / 60).arg(time.secsTo(targetTime) % 60); - } - return; - } - if (requiresLogin(m_RequestQueue.head()) && !getAccessManager()->validated()) { if (!getAccessManager()->validateAttempted()) { emit needLogin(); @@ -509,6 +490,17 @@ void NexusInterface::nextRequest() } } + if (m_RemainingDailyRequests + m_RemainingHourlyRequests <= 0) { + m_RequestQueue.clear(); + QTime time = QTime::currentTime(); + QTime targetTime; + targetTime.setHMS((time.hour() + 1) % 23, 5, 0); + QString warning("You've exceeded the Nexus API rate limit and requests are now being throttled. " + "Your next batch of requests will be available in approximately %1 minutes and %2 seconds."); + qWarning() << warning.arg(time.secsTo(targetTime) / 60).arg(time.secsTo(targetTime) % 60); + return; + } + NXMRequestInfo info = m_RequestQueue.dequeue(); info.m_Timeout = new QTimer(this); info.m_Timeout->setInterval(60000); diff --git a/src/nexusinterface.h b/src/nexusinterface.h index 64f15961..db4ebfd6 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -460,8 +460,6 @@ private: PluginContainer *m_PluginContainer; - QTimer m_RetryTimer; - int m_RemainingDailyRequests; int m_RemainingHourlyRequests; int m_MaxDailyRequests; diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index d1720c76..7ab474a7 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -268,9 +268,13 @@ void NXMAccessManager::validateFinished() m_ValidateState = VALIDATE_VALID; emit validateSuccessful(true); } else { + m_ApiKey.clear(); + m_ValidateState = VALIDATE_NOT_VALID; emit validateFailed(tr("Validation failed, please reauthenticate in the Settings -> Nexus tab: %1").arg(credentialsData.value("message").toString())); } } else { + m_ApiKey.clear(); + m_ValidateState = VALIDATE_NOT_CHECKED; emit validateFailed(tr("unknown error")); } } |
