summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSilarn <jrim@rimpo.org>2019-02-11 16:51:47 -0600
committerSilarn <jrim@rimpo.org>2019-02-18 21:31:21 -0600
commit2b9d2f32fbbc576c9367a24c0347e5870ff20117 (patch)
treef13f20f95dc2dda2dab1cd90a73e957e6ddb3a16 /src
parent5a7d0243c69d5194ee1a4d0be05d2bcaec18aeac (diff)
Endorsement and efficiency updates
* Reduce update timeout to 5 minutes * Introduce bulk endorsement check replacing global mod info check * Fine tune performance of bulk update info query * Thread the update processing to prevent lockups
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cpp162
-rw-r--r--src/mainwindow.h13
-rw-r--r--src/modinfo.cpp37
-rw-r--r--src/modinfo.h4
-rw-r--r--src/modinforegular.cpp3
-rw-r--r--src/nexusinterface.cpp70
-rw-r--r--src/nexusinterface.h9
7 files changed, 203 insertions, 95 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 5e97a959..7592bd1e 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -261,7 +261,8 @@ MainWindow::MainWindow(QSettings &initSettings
actionToToolButton(ui->actionEndorseMO);
createEndorseWidget();
- ui->actionEndorseMO->setVisible(false);
+
+ toggleMO2EndorseState();
for (QAction *action : ui->toolBar->actions()) {
if (action->isSeparator()) {
@@ -752,7 +753,7 @@ void MainWindow::createEndorseWidget()
buttonMenu->addAction(endorseAction);
QAction *wontEndorseAction = new QAction(tr("Won't Endorse"), buttonMenu);
- connect(wontEndorseAction, SIGNAL(triggered()), this, SLOT(wontEndorse()));
+ connect(wontEndorseAction, SIGNAL(triggered()), this, SLOT(on_actionWontEndorseMO_triggered()));
buttonMenu->addAction(wontEndorseAction);
}
@@ -3983,8 +3984,8 @@ void MainWindow::checkModsForUpdates()
{
statusBar()->show();
if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->validated()) {
- m_ModsToUpdate = ModInfo::checkAllForUpdate(&m_PluginContainer, this);
- m_RefreshProgress->setRange(0, m_ModsToUpdate);
+ ModInfo::checkAllForUpdate(&m_PluginContainer, this);
+ NexusInterface::instance(&m_PluginContainer)->requestEndorsementInfo(this, QVariant(), QString());
} else {
QString apiKey;
if (m_OrganizerCore.settings().getNexusApiKey(apiKey)) {
@@ -5318,26 +5319,8 @@ void MainWindow::motdReceived(const QString &motd)
m_OrganizerCore.settings().setMotDHash(hash);
}
}
-
- ui->actionEndorseMO->setVisible(false);
-}
-
-
-void MainWindow::notEndorsedYet()
-{
- if (!Settings::instance().directInterface().value("wont_endorse_MO", false).toBool()) {
- ui->actionEndorseMO->setVisible(true);
- }
}
-
-void MainWindow::wontEndorse()
-{
- Settings::instance().directInterface().setValue("wont_endorse_MO", true);
- ui->actionEndorseMO->setVisible(false);
-}
-
-
void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos)
{
QTreeWidget *dataTree = findChild<QTreeWidget*>("dataTree");
@@ -5398,6 +5381,21 @@ void MainWindow::on_actionEndorseMO_triggered()
}
}
+void MainWindow::on_actionWontEndorseMO_triggered()
+{
+ // Normally this would be the managed game but MO2 is only uploaded to the Skyrim SE site right now
+ IPluginGame * game = m_OrganizerCore.getGame("skyrimse");
+ if (!game) return;
+
+ if (QMessageBox::question(this, tr("Abstain from Endorsing Mod Organizer"),
+ tr("Are you sure you want to abstain from endorsing Mod Organizer 2?\n"
+ "You will have to visit the mod page on the %1 Nexus site to change your mind.").arg(
+ NexusInterface::instance(&m_PluginContainer)->getGameURL(game->gameShortName())),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ NexusInterface::instance(&m_PluginContainer)->requestToggleEndorsement(
+ game->gameShortName(), game->nexusModOrganizerID(), m_OrganizerCore.getVersion().canonicalString(), false, this, QVariant(), QString());
+ }
+}
void MainWindow::initDownloadView()
{
@@ -5448,21 +5446,10 @@ void MainWindow::updateDownloadView()
m_OrganizerCore.downloadManager()->refreshList();
}
-void MainWindow::modDetailsUpdated(bool)
-{
- if (m_ModsToUpdate <= 0) {
- statusBar()->hide();
- m_RefreshProgress->setVisible(false);
- } else {
- m_RefreshProgress->setValue(m_RefreshProgress->maximum() - m_ModsToUpdate);
- }
-}
-
void MainWindow::modUpdateCheck(std::multimap<QString, int> IDs)
{
if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->validated()) {
- m_ModsToUpdate += ModInfo::manualUpdateCheck(&m_PluginContainer, this, IDs);
- m_RefreshProgress->setRange(0, m_ModsToUpdate);
+ ModInfo::manualUpdateCheck(&m_PluginContainer, this, IDs);
} else {
QString apiKey;
if (m_OrganizerCore.settings().getNexusApiKey(apiKey)) {
@@ -5473,6 +5460,80 @@ void MainWindow::modUpdateCheck(std::multimap<QString, int> IDs)
}
}
+void MainWindow::toggleMO2EndorseState()
+{
+ QToolButton *toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionEndorseMO));
+ if (Settings::instance().endorsementIntegration()) {
+ ui->actionEndorseMO->setVisible(true);
+ if (Settings::instance().directInterface().contains("endorse_state")) {
+ ui->actionEndorseMO->setEnabled(false);
+ if (Settings::instance().directInterface().value("endorse_state").toString() == "Endorsed") {
+ ui->actionEndorseMO->setToolTip(tr("Thank you for endorsing MO2! :)"));
+ toolBtn->setToolTip(tr("Thank you for endorsing MO2! :)"));
+ } else if (Settings::instance().directInterface().value("endorse_state").toString() == "Abstained") {
+ ui->actionEndorseMO->setToolTip(tr("Please reconsider endorsing MO2 on Nexus!"));
+ toolBtn->setToolTip(tr("Please reconsider endorsing MO2 on Nexus!"));
+ }
+ } else {
+ ui->actionEndorseMO->setEnabled(true);
+ }
+ } else
+ ui->actionEndorseMO->setVisible(false);
+}
+
+void MainWindow::nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int)
+{
+ QVariantList data = resultData.toList();
+ std::multimap<QString, std::pair<int, QString>> sorted;
+ QStringList games = m_OrganizerCore.managedGame()->validShortNames();
+ games += m_OrganizerCore.managedGame()->gameShortName();
+ bool searchedMO2NexusGame = false;
+ for (auto endorsementData : data) {
+ QVariantMap endorsement = endorsementData.toMap();
+ std::pair<int, QString> data = std::make_pair<int, QString>(endorsement["mod_id"].toInt(), endorsement["status"].toString());
+ sorted.insert(std::pair<QString, std::pair<int, QString>>(endorsement["domain_name"].toString(), data));
+ }
+ for (auto game : games) {
+ IPluginGame *gamePlugin = m_OrganizerCore.getGame(game);
+ if (gamePlugin->gameShortName().compare("SkyrimSE", Qt::CaseInsensitive) == 0)
+ searchedMO2NexusGame = true;
+ auto iter = sorted.equal_range(gamePlugin->gameNexusName());
+ for (auto result = iter.first; result != iter.second; ++result) {
+ std::vector<ModInfo::Ptr> modsList = ModInfo::getByModID(result->first, result->second.first);
+
+ for (auto mod : modsList) {
+ if (result->second.second == "Endorsed")
+ mod->setIsEndorsed(true);
+ else if (result->second.second == "Abstained")
+ mod->setNeverEndorse();
+ else
+ mod->setIsEndorsed(false);
+ }
+
+ if (Settings::instance().endorsementIntegration()) {
+ if (result->first == "skyrimspecialedition" && result->second.first == gamePlugin->nexusModOrganizerID()) {
+ Settings::instance().directInterface().setValue("endorse_state", result->second.second);
+ toggleMO2EndorseState();
+ }
+ }
+ }
+ }
+
+ if (!searchedMO2NexusGame && Settings::instance().endorsementIntegration()) {
+ auto gamePlugin = m_OrganizerCore.getGame("SkyrimSE");
+ if (gamePlugin) {
+ auto iter = sorted.equal_range(gamePlugin->gameNexusName());
+ for (auto result = iter.first; result != iter.second; ++result) {
+ if (result->second.first == gamePlugin->nexusModOrganizerID()) {
+ Settings::instance().directInterface().setValue("endorse_state", result->second.second);
+ toggleMO2EndorseState();
+ break;
+ }
+ }
+ }
+ }
+}
+
void MainWindow::nxmUpdateInfoAvailable(QString gameName, QVariant userData, QVariant resultData, int)
{
QString gameNameReal;
@@ -5483,7 +5544,20 @@ void MainWindow::nxmUpdateInfoAvailable(QString gameName, QVariant userData, QVa
}
}
QVariantList resultList = resultData.toList();
- std::set<QSharedPointer<ModInfo>> finalMods = ModInfo::filteredMods(gameNameReal, resultList, userData.toBool(), true);
+
+ QFutureWatcher<std::set<QSharedPointer<ModInfo>>> *watcher = new QFutureWatcher<std::set<QSharedPointer<ModInfo>>>();
+ QObject::connect(watcher, &QFutureWatcher<std::set<QSharedPointer<ModInfo>>>::finished, this, &MainWindow::finishUpdateInfo);
+ QFuture<std::set<QSharedPointer<ModInfo>>> future = QtConcurrent::run([=]() -> std::set<QSharedPointer<ModInfo>> {
+ return ModInfo::filteredMods(gameNameReal, resultList, userData.toBool(), true);
+ });
+ watcher->setFuture(future);
+}
+
+void MainWindow::finishUpdateInfo()
+{
+ QFutureWatcher<std::set<QSharedPointer<ModInfo>>> *watcher = static_cast<QFutureWatcher<std::set<QSharedPointer<ModInfo>>> *>(sender());
+
+ auto finalMods = watcher->result();
if (finalMods.empty()) {
qInfo("None of your mods appear to have had recent file updates.");
@@ -5501,6 +5575,9 @@ void MainWindow::nxmUpdateInfoAvailable(QString gameName, QVariant userData, QVa
for (auto game : organizedGames)
NexusInterface::instance(&m_PluginContainer)->requestUpdates(game.second, this, QVariant(), game.first, QString());
+
+ disconnect(sender());
+ delete sender();
}
void MainWindow::nxmUpdatesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID)
@@ -5508,7 +5585,6 @@ void MainWindow::nxmUpdatesAvailable(QString gameName, int modID, QVariant userD
QVariantMap resultInfo = resultData.toMap();
QList files = resultInfo["files"].toList();
QList fileUpdates = resultInfo["file_updates"].toList();
- m_ModsToUpdate--;
QString gameNameReal;
for (IPluginGame *game : m_PluginContainer.plugins<IPluginGame>()) {
if (game->gameNexusName() == gameName) {
@@ -5578,19 +5654,10 @@ void MainWindow::nxmUpdatesAvailable(QString gameName, int modID, QVariant userD
// Scrape mod data here so we can use the mod version if no file update was located
requiresInfo = true;
}
-
- if (mod->getLastNexusQuery().addDays(1) <= QDateTime::currentDateTimeUtc())
- requiresInfo = true;
}
if (requiresInfo)
NexusInterface::instance(&m_PluginContainer)->requestModInfo(gameName, modID, this, QVariant(), QString());
-
- if (--m_ModsToUpdate <= 0) {
- statusBar()->hide();
- } else {
- m_RefreshProgress->setValue(m_RefreshProgress->maximum() - m_ModsToUpdate);
- }
}
void MainWindow::nxmModInfoAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID)
@@ -5663,11 +5730,6 @@ void MainWindow::nxmDownloadURLs(QString, int, int, QVariant, QVariant resultDat
void MainWindow::nxmRequestFailed(QString gameName, int modID, int, QVariant, int, QNetworkReply::NetworkError error, const QString &errorString)
{
- if (modID == -1) {
- // must be the update-check that failed
- m_ModsToUpdate = 0;
- statusBar()->hide();
- }
if (error == QNetworkReply::ContentAccessDenied || error == QNetworkReply::ContentNotFoundError) {
QString gameNameReal;
for (IPluginGame *game : m_PluginContainer.plugins<IPluginGame>()) {
diff --git a/src/mainwindow.h b/src/mainwindow.h
index d2704b72..a0c043a1 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -64,6 +64,7 @@ namespace MOShared { class DirectoryEntry; }
#include <QVariant>
#include <Qt>
#include <QtConcurrent/QtConcurrentRun>
+#include <QFutureWatcher>
class QAction;
class QAbstractItemModel;
@@ -303,6 +304,8 @@ private:
void sendSelectedModsToPriority(int newPriority);
void sendSelectedPluginsToPriority(int newPriority);
+ void toggleMO2EndorseState();
+
private:
static const char *PATTERN_BACKUP_GLOB;
@@ -341,8 +344,6 @@ private:
CategoryFactory &m_CategoryFactory;
- int m_ModsToUpdate;
-
bool m_LoginAttempted;
QTimer m_CheckBSATimer;
@@ -494,8 +495,6 @@ private slots:
void updateAvailable();
void motdReceived(const QString &motd);
- void notEndorsedYet();
- void wontEndorse();
void originModified(int originID);
@@ -504,12 +503,13 @@ private slots:
void addPrimaryCategoryCandidates();
- void modDetailsUpdated(bool success);
-
void modInstalled(const QString &modName);
void modUpdateCheck(std::multimap<QString, int> IDs);
+ void finishUpdateInfo();
+
+ void nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int);
void nxmUpdateInfoAvailable(QString gameName, QVariant userData, QVariant resultData, int requestID);
void nxmUpdatesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmModInfoAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
@@ -622,6 +622,7 @@ private slots: // ui slots
void on_actionSettings_triggered();
void on_actionUpdate_triggered();
void on_actionEndorseMO_triggered();
+ void on_actionWontEndorseMO_triggered();
void on_bsaList_customContextMenuRequested(const QPoint &pos);
void on_clearFiltersButton_clicked();
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index 3e694baf..938a6418 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -284,16 +284,8 @@ ModInfo::ModInfo(PluginContainer *pluginContainer)
}
-int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver)
+void ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver)
{
- int result = 0;
-
- // MO2 endorsement status is no longer available via this method - an alternative must be found
- //IPluginGame const *game = pluginContainer->managedGame("Skyrim Special Edition");
- //if (game && game->nexusModOrganizerID()) {
- // NexusInterface::instance(pluginContainer)->requestUpdates(game->nexusModOrganizerID(), receiver, QVariant(), game->gameShortName(), QString());
- //}
-
QDateTime earliest = QDateTime::currentDateTimeUtc();
QDateTime latest;
std::set<QString> games;
@@ -315,8 +307,6 @@ 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.");
@@ -336,8 +326,6 @@ int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiv
for (auto gameName : games)
NexusInterface::instance(pluginContainer)->requestUpdateInfo(gameName, NexusInterface::UpdatePeriod::DAY, receiver, QVariant(false), QString());
}
-
- return result;
}
std::set<QSharedPointer<ModInfo>> ModInfo::filteredMods(QString gameName, QVariantList updateData, bool addOldMods, bool markUpdated)
@@ -345,10 +333,12 @@ std::set<QSharedPointer<ModInfo>> ModInfo::filteredMods(QString gameName, QVaria
std::set<QSharedPointer<ModInfo>> finalMods;
for (QVariant result : updateData) {
QVariantMap update = result.toMap();
- for (auto mod : s_Collection)
- if (mod->getNexusID() == update["mod_id"].toInt() && mod->getGameName().compare(gameName, Qt::CaseInsensitive) == 0)
- if (mod->getLastNexusUpdate() > QDateTime::fromSecsSinceEpoch(update["latest_file_update"].toInt(), Qt::UTC))
- finalMods.insert(mod);
+ std::copy_if(s_Collection.begin(), s_Collection.end(), std::inserter(finalMods, finalMods.end()), [=](QSharedPointer<ModInfo> info) -> bool {
+ if (info->getNexusID() == update["mod_id"].toInt() && info->getGameName().compare(gameName, Qt::CaseInsensitive) == 0)
+ if (info->getLastNexusUpdate() > QDateTime::fromSecsSinceEpoch(update["latest_file_update"].toInt(), Qt::UTC))
+ return true;
+ return false;
+ });
}
if (addOldMods)
@@ -358,20 +348,21 @@ std::set<QSharedPointer<ModInfo>> ModInfo::filteredMods(QString gameName, QVaria
if (markUpdated) {
std::set<QSharedPointer<ModInfo>> updates;
- for (auto mod : s_Collection)
- if (mod->getGameName().compare(gameName, Qt::CaseInsensitive) == 0 && mod->canBeUpdated())
- updates.insert(mod);
+ std::copy_if(s_Collection.begin(), s_Collection.end(), std::inserter(updates, updates.end()), [=](QSharedPointer<ModInfo> info) -> bool {
+ if (info->getGameName().compare(gameName, Qt::CaseInsensitive) == 0 && info->canBeUpdated())
+ return true;
+ return false;
+ });
std::set<QSharedPointer<ModInfo>> diff;
std::set_difference(updates.begin(), updates.end(), finalMods.begin(), finalMods.end(), std::inserter(diff, diff.end()));
for (auto skipped : diff) {
skipped->setLastNexusUpdate(QDateTime::currentDateTimeUtc());
- skipped->updateNXMInfo();
}
}
return finalMods;
}
-int ModInfo::manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiver, std::multimap<QString, int> IDs)
+void ModInfo::manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiver, std::multimap<QString, int> IDs)
{
std::vector<QSharedPointer<ModInfo>> mods;
std::set<std::pair<QString, int>> organizedGames;
@@ -402,8 +393,6 @@ int ModInfo::manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiv
} else {
qInfo("None of the selected mods can be updated.");
}
-
- return organizedGames.size();
}
diff --git a/src/modinfo.h b/src/modinfo.h
index 8c234225..c3115685 100644
--- a/src/modinfo.h
+++ b/src/modinfo.h
@@ -188,12 +188,12 @@ public:
/**
* @brief run a limited batch of mod update checks for "newest version" information
*/
- static int manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiver, std::multimap<QString, int> IDs);
+ static void manualUpdateCheck(PluginContainer *pluginContainer, QObject *receiver, std::multimap<QString, int> IDs);
/**
* @brief query nexus information for every mod and update the "newest version" information
**/
- static int checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver);
+ static void checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver);
static std::set<QSharedPointer<ModInfo>> filteredMods(QString gameName, QVariantList updateData, bool addOldMods = false, bool markUpdated = false);
diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp
index 9532bf6d..ac1c46d6 100644
--- a/src/modinforegular.cpp
+++ b/src/modinforegular.cpp
@@ -507,6 +507,8 @@ bool ModInfoRegular::canBeUpdated() const
QDateTime ModInfoRegular::getExpires() const
{
+ return m_LastNexusUpdate.addSecs(300);
+ /*
switch (Settings::instance().nexusUpdateStrategy()) {
case Settings::NexusUpdateStrategy::Flexible: {
qint64 diff = m_NexusLastModified.msecsTo(QDateTime::currentDateTimeUtc());
@@ -530,6 +532,7 @@ QDateTime ModInfoRegular::getExpires() const
return m_LastNexusUpdate.addSecs(86400);
} break;
}
+ */
}
std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index abddbd3e..e657dfc1 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -125,6 +125,15 @@ void NexusBridge::nxmDownloadURLsAvailable(QString gameName, int modID, int file
}
}
+void NexusBridge::nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
+ emit endorsementsAvailable(userData, resultData);
+ }
+}
+
void NexusBridge::nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID)
{
std::set<int>::iterator iter = m_RequestIDs.find(requestID);
@@ -455,6 +464,21 @@ int NexusInterface::requestDownloadURL(QString gameName, int modID, int fileID,
return requestInfo.m_ID;
}
+int NexusInterface::requestEndorsementInfo(QObject *receiver, QVariant userData, const QString &subModule)
+{
+ NXMRequestInfo requestInfo(NXMRequestInfo::TYPE_ENDORSEMENTS, userData, subModule);
+ m_RequestQueue.enqueue(requestInfo);
+
+ connect(this, SIGNAL(nxmEndorsementsAvailable(QVariant, QVariant, int)),
+ receiver, SLOT(nxmEndorsementsAvailable(QVariant, QVariant, int)), Qt::UniqueConnection);
+
+ connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
+ receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
+}
+
int NexusInterface::requestToggleEndorsement(QString gameName, int modID, QString modVersion, bool endorse, QObject *receiver, QVariant userData,
const QString &subModule, MOBase::IPluginGame const *game)
@@ -478,12 +502,6 @@ int NexusInterface::requestToggleEndorsement(QString gameName, int modID, QStrin
return -1;
}
-bool NexusInterface::requiresLogin(const NXMRequestInfo &info)
-{
- return (info.m_Type == NXMRequestInfo::TYPE_TOGGLEENDORSEMENT)
- || (info.m_Type == NXMRequestInfo::TYPE_DOWNLOADURL);
-}
-
IPluginGame* NexusInterface::getGame(QString gameName) const
{
auto gamePlugins = m_PluginContainer->plugins<IPluginGame>();
@@ -516,7 +534,7 @@ void NexusInterface::nextRequest()
return;
}
- if (requiresLogin(m_RequestQueue.head()) && !getAccessManager()->validated()) {
+ if (!getAccessManager()->validated()) {
if (!getAccessManager()->validateAttempted()) {
emit needLogin();
return;
@@ -581,6 +599,9 @@ void NexusInterface::nextRequest()
else
url = QString("%1/games/%2/mods/%3/files/%4/download_link").arg(info.m_URL).arg(info.m_GameName).arg(info.m_ModID).arg(info.m_FileID);
} break;
+ case NXMRequestInfo::TYPE_ENDORSEMENTS: {
+ url = QString("%1/user/endorsements").arg(info.m_URL);
+ } break;
case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: {
QString endorse = info.m_Endorse ? "endorse" : "abstain";
url = QString("%1/games/%2/mods/%3/%4").arg(info.m_URL).arg(info.m_GameName).arg(info.m_ModID).arg(endorse);
@@ -674,6 +695,9 @@ void NexusInterface::requestFinished(std::list<NXMRequestInfo>::iterator iter)
case NXMRequestInfo::TYPE_DOWNLOADURL: {
emit nxmDownloadURLsAvailable(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID);
} break;
+ case NXMRequestInfo::TYPE_ENDORSEMENTS: {
+ emit nxmEndorsementsAvailable(iter->m_UserData, result, iter->m_ID);
+ } break;
case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: {
emit nxmEndorsementToggled(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID);
} break;
@@ -747,7 +771,7 @@ void NexusInterface::requestTimeout()
}
namespace {
- QString get_management_url(MOBase::IPluginGame const *game)
+ QString get_management_url()
{
return "https://api.nexusmods.com/v1";
}
@@ -769,7 +793,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(get_management_url(game))
+ , m_URL(get_management_url())
, m_SubModule(subModule)
, m_NexusGameID(game->nexusGameID())
, m_GameName(game->gameNexusName())
@@ -794,7 +818,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(get_management_url(game))
+ , m_URL(get_management_url())
, m_SubModule(subModule)
, m_NexusGameID(game->nexusGameID())
, m_GameName(game->gameNexusName())
@@ -818,13 +842,35 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(get_management_url(game))
+ , m_URL(get_management_url())
, m_SubModule(subModule)
, m_NexusGameID(game->nexusGameID())
, m_GameName(game->gameNexusName())
, m_Endorse(false)
{}
+NexusInterface::NXMRequestInfo::NXMRequestInfo(Type type
+ , QVariant userData
+ , const QString &subModule
+)
+ : m_ModID(0)
+ , m_ModVersion("0")
+ , m_FileID(0)
+ , m_Reply(nullptr)
+ , m_Type(type)
+ , m_UpdatePeriod(UpdatePeriod::NONE)
+ , m_UserData(userData)
+ , m_Timeout(nullptr)
+ , m_Reroute(false)
+ , m_ID(s_NextID.fetchAndAddAcquire(1))
+ , m_URL(get_management_url())
+ , m_SubModule(subModule)
+ , m_NexusGameID(0)
+ , m_GameName("")
+ , m_Endorse(false)
+{}
+
+
NexusInterface::NXMRequestInfo::NXMRequestInfo(UpdatePeriod period
, NexusInterface::NXMRequestInfo::Type type
, QVariant userData
@@ -841,7 +887,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(UpdatePeriod period
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(get_management_url(game))
+ , m_URL(get_management_url())
, m_SubModule(subModule)
, m_NexusGameID(game->nexusGameID())
, m_GameName(game->gameNexusName())
diff --git a/src/nexusinterface.h b/src/nexusinterface.h
index 06b19947..ac9e466b 100644
--- a/src/nexusinterface.h
+++ b/src/nexusinterface.h
@@ -104,6 +104,7 @@ public slots:
void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int requestID);
void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorMessage);
@@ -298,6 +299,10 @@ public:
**/
int requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+
+ int requestEndorsementInfo(QObject *receiver, QVariant userData, const QString &subModule);
+
+
/**
* @param gameName the game short name to support multiple game sources
* @brief toggle endorsement state of the mod
@@ -401,6 +406,7 @@ signals:
void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int requestID);
void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString);
void requestsChanged(int queueCount, std::tuple<int,int,int,int> requestsRemaining);
@@ -433,6 +439,7 @@ private:
TYPE_FILES,
TYPE_FILEINFO,
TYPE_DOWNLOADURL,
+ TYPE_ENDORSEMENTS,
TYPE_TOGGLEENDORSEMENT,
TYPE_GETUPDATES,
TYPE_CHECKUPDATES
@@ -451,6 +458,7 @@ private:
NXMRequestInfo(int modID, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
NXMRequestInfo(int modID, QString modVersion, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
NXMRequestInfo(int modID, int fileID, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+ NXMRequestInfo(Type type, QVariant userData, const QString &subModule);
NXMRequestInfo(UpdatePeriod period, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
private:
@@ -464,7 +472,6 @@ private:
NexusInterface(PluginContainer *pluginContainer);
void nextRequest();
void requestFinished(std::list<NXMRequestInfo>::iterator iter);
- bool requiresLogin(const NXMRequestInfo &info);
MOBase::IPluginGame *getGame(QString gameName) const;
QString getOldModsURL(QString gameName) const;