From fa104b342f440a4fc1c80426e2b5e2c5905d4151 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 15 Apr 2018 02:54:16 +0200 Subject: Moved the Changelog to the detailed text to avoid the msgbox going below the scree. The readability is not graeat as QMessageBox does not allow resizing for some petty reason. --- src/selfupdater.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/selfupdater.cpp') diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 8f962ba4..9706e1fb 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -170,10 +170,10 @@ void SelfUpdater::startUpdate() QMessageBox query(QMessageBox::Question, tr("New update available (%1)") - .arg(m_UpdateCandidate["tag_name"].toString()), - BBCode::convertToHTML(m_UpdateCandidate["body"].toString()), + .arg(m_UpdateCandidate["tag_name"].toString()), tr("Do you want to install update? All your mods and setup will be left untouched.\nSelect Show Details option to see the full change-log."), QMessageBox::Yes | QMessageBox::Cancel, m_Parent); - + + query.setDetailedText(m_UpdateCandidate["body"].toString()); query.button(QMessageBox::Yes)->setText(tr("Install")); int res = query.exec(); -- cgit v1.3.1 From 30c177cb371e92fe5e4cfc600cf27586402cf0a8 Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 16 Apr 2018 12:47:17 -0500 Subject: Support for multi-game downloads --- src/downloadlistwidget.cpp | 4 +- src/downloadlistwidgetcompact.cpp | 4 +- src/downloadmanager.cpp | 76 ++++++++------- src/downloadmanager.h | 23 +++-- src/installationmanager.cpp | 18 +++- src/installationmanager.h | 2 +- src/main.cpp | 3 +- src/mainwindow.cpp | 62 ++++++------ src/mainwindow.h | 6 +- src/modinfo.cpp | 56 +++++++---- src/modinfo.h | 24 +++-- src/modinfobackup.cpp | 4 +- src/modinfobackup.h | 2 +- src/modinfodialog.cpp | 4 +- src/modinfoforeign.cpp | 5 +- src/modinfoforeign.h | 3 +- src/modinfooverwrite.cpp | 2 +- src/modinfooverwrite.h | 3 +- src/modinforegular.cpp | 32 ++++--- src/modinforegular.h | 17 +++- src/modinfowithconflictinfo.cpp | 4 +- src/modinfowithconflictinfo.h | 2 +- src/modlist.cpp | 23 ++++- src/modlist.h | 7 +- src/nexusinterface.cpp | 194 ++++++++++++++++++++++---------------- src/nexusinterface.h | 108 +++++++++------------ src/organizercore.cpp | 51 ++++++---- src/organizercore.h | 2 +- src/organizerproxy.cpp | 6 +- src/organizerproxy.h | 4 +- src/plugincontainer.cpp | 3 +- src/plugincontainer.h | 6 +- src/profile.cpp | 1 + src/selfupdater.cpp | 6 ++ src/selfupdater.h | 3 + src/settings.cpp | 4 +- src/settings.h | 3 +- src/settingsdialog.cpp | 6 +- src/settingsdialog.h | 6 +- 39 files changed, 466 insertions(+), 323 deletions(-) (limited to 'src/selfupdater.cpp') diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp index 9a8ef572..cb7a49c3 100644 --- a/src/downloadlistwidget.cpp +++ b/src/downloadlistwidget.cpp @@ -88,8 +88,8 @@ void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOption void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const { - std::pair nexusids = m_Manager->getPendingDownload(downloadIndex); - m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second)); + std::tuple nexusids = m_Manager->getPendingDownload(downloadIndex); + m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids))); m_SizeLabel->setText("???"); m_InstallLabel->setVisible(true); m_InstallLabel->setText(tr("Pending")); diff --git a/src/downloadlistwidgetcompact.cpp b/src/downloadlistwidgetcompact.cpp index f7975150..b390bff4 100644 --- a/src/downloadlistwidgetcompact.cpp +++ b/src/downloadlistwidgetcompact.cpp @@ -88,8 +88,8 @@ void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyl void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const { - std::pair nexusids = m_Manager->getPendingDownload(downloadIndex); - m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second)); + std::tuple nexusids = m_Manager->getPendingDownload(downloadIndex); + m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids))); if (m_SizeLabel != nullptr) { m_SizeLabel->setText("???"); } diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 569a7d31..d54d6f24 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include "nexusinterface.h" #include "nxmaccessmanager.h" #include "iplugingame.h" +#include "downloadmanager.h" #include #include #include "utility.h" @@ -113,15 +114,17 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con info->m_Urls = metaFile.value("url", "").toString().split(";"); info->m_Tries = 0; info->m_TaskProgressId = TaskProgressManager::instance().getId(); + QString gameName = metaFile.value("gameName", "").toString(); int modID = metaFile.value("modID", 0).toInt(); int fileID = metaFile.value("fileID", 0).toInt(); - info->m_FileInfo = new ModRepositoryFileInfo(modID, fileID); + info->m_FileInfo = new ModRepositoryFileInfo(gameName, modID, fileID); info->m_FileInfo->name = metaFile.value("name", "").toString(); if (info->m_FileInfo->name == "0") { // bug in earlier version info->m_FileInfo->name = ""; } info->m_FileInfo->modName = metaFile.value("modName", "").toString(); + info->m_FileInfo->gameName = gameName; info->m_FileInfo->modID = modID; info->m_FileInfo->fileID = fileID; info->m_FileInfo->description = metaFile.value("description").toString(); @@ -260,6 +263,11 @@ void DownloadManager::setShowHidden(bool showHidden) refreshList(); } +void DownloadManager::setPluginContainer(PluginContainer *pluginContainer) +{ + m_NexusInterface->setPluginContainer(pluginContainer); +} + void DownloadManager::refreshList() { try { @@ -329,7 +337,7 @@ void DownloadManager::refreshList() } -bool DownloadManager::addDownload(const QStringList &URLs, +bool DownloadManager::addDownload(const QStringList &URLs, QString gameName, int modID, int fileID, const ModRepositoryFileInfo *fileInfo) { QString fileName = QFileInfo(URLs.first()).fileName(); @@ -340,7 +348,7 @@ bool DownloadManager::addDownload(const QStringList &URLs, QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit()); qDebug("selected download url: %s", qPrintable(preferredUrl.toString())); QNetworkRequest request(preferredUrl); - return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, fileInfo); + return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, gameName, modID, fileID, fileInfo); } @@ -351,12 +359,12 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const ModRepositoryFileI fileName = "unknown"; } - return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->modID, fileInfo->fileID, fileInfo); + return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->gameName, fileInfo->modID, fileInfo->fileID, fileInfo); } bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, - int modID, int fileID, const ModRepositoryFileInfo *fileInfo) + QString gameName, int modID, int fileID, const ModRepositoryFileInfo *fileInfo) { // download invoked from an already open network reply (i.e. download link in the browser) DownloadInfo *newDownload = DownloadInfo::createNew(fileInfo, URLs); @@ -375,7 +383,7 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, (QMessageBox::question(nullptr, tr("Download again?"), tr("A file with the same name has already been downloaded. " "Do you want to download it again? The new file will receive a different name."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) { - removePending(modID, fileID); + removePending(gameName, modID, fileID); delete newDownload; return false; } @@ -387,12 +395,12 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, } -void DownloadManager::removePending(int modID, int fileID) +void DownloadManager::removePending(QString gameName, int modID, int fileID) { emit aboutToUpdate(); - for (auto iter = m_PendingDownloads.begin(); iter != m_PendingDownloads.end(); ++iter) { - if ((iter->first == modID) && (iter->second == fileID)) { - m_PendingDownloads.erase(iter); + for (auto iter : m_PendingDownloads) { + if (gameName.compare(std::get<0>(iter), Qt::CaseInsensitive) == 0 && (std::get<1>(iter) == modID) && (std::get<2>(iter) == fileID)) { + m_PendingDownloads.removeAt(m_PendingDownloads.indexOf(iter)); break; } } @@ -431,7 +439,7 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl if (!resume) { newDownload->m_PreResumeSize = newDownload->m_Output.size(); - removePending(newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID); + removePending(newDownload->m_FileInfo->gameName, newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID); emit aboutToUpdate(); m_ActiveDownloads.append(newDownload); @@ -451,17 +459,19 @@ void DownloadManager::addNXMDownload(const QString &url) { NXMUrl nxmInfo(url); - QString managedGame = m_ManagedGame->gameShortName(); + QStringList validGames; + validGames.append(m_ManagedGame->gameShortName()); + validGames.append(m_ManagedGame->validShortNames()); qDebug("add nxm download: %s", qPrintable(url)); - if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) { - qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game())); + if (!validGames.contains(nxmInfo.game(), Qt::CaseInsensitive)) { + qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(m_ManagedGame->gameShortName()), qPrintable(nxmInfo.game())); QMessageBox::information(nullptr, tr("Wrong Game"), tr("The download link is for a mod for \"%1\" but this instance of MO " - "has been set up for \"%2\".").arg(nxmInfo.game()).arg(managedGame), QMessageBox::Ok); + "has been set up for \"%2\".").arg(nxmInfo.game()).arg(m_ManagedGame->gameShortName()), QMessageBox::Ok); return; } - for (auto pair : m_PendingDownloads) { - if (pair.first == nxmInfo.modId() && pair.second == nxmInfo.fileId()) { + for (auto tuple : m_PendingDownloads) { + if (std::get<0>(tuple).compare(nxmInfo.game(), Qt::CaseInsensitive) == 0, std::get<1>(tuple) == nxmInfo.modId() && std::get<2>(tuple) == nxmInfo.fileId()) { qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(QString(nxmInfo.modId())), qPrintable(QString(nxmInfo.fileId()))); QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been queued."), QMessageBox::Ok); return; @@ -483,11 +493,11 @@ void DownloadManager::addNXMDownload(const QString &url) emit aboutToUpdate(); - m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId())); + m_PendingDownloads.append(std::make_tuple(nxmInfo.game(), nxmInfo.modId(), nxmInfo.fileId())); emit update(-1); emit downloadAdded(); - m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), "")); + m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.game(), nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), "")); } @@ -743,7 +753,7 @@ int DownloadManager::numPendingDownloads() const return m_PendingDownloads.size(); } -std::pair DownloadManager::getPendingDownload(int index) +std::tuple DownloadManager::getPendingDownload(int index) { if ((index < 0) || (index >= m_PendingDownloads.size())) { throw MyException(tr("get pending: invalid download index %1").arg(index)); @@ -1003,10 +1013,10 @@ void DownloadManager::setState(DownloadManager::DownloadInfo *info, DownloadMana info->m_Reply->abort(); } break; case STATE_FETCHINGMODINFO: { - m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_FileInfo->modID, this, info->m_DownloadID, QString())); + m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_FileInfo->gameName, info->m_FileInfo->modID, this, info->m_DownloadID, QString())); } break; case STATE_FETCHINGFILEINFO: { - m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_FileInfo->modID, this, info->m_DownloadID, QString())); + m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_FileInfo->gameName, info->m_FileInfo->modID, this, info->m_DownloadID, QString())); } break; case STATE_READY: { createMetaFile(info); @@ -1080,6 +1090,7 @@ void DownloadManager::downloadReadyRead() void DownloadManager::createMetaFile(DownloadInfo *info) { QSettings metaFile(QString("%1.meta").arg(info->m_Output.fileName()), QSettings::IniFormat); + metaFile.setValue("gameName", info->m_FileInfo->gameName); metaFile.setValue("modID", info->m_FileInfo->modID); metaFile.setValue("fileID", info->m_FileInfo->fileID); metaFile.setValue("url", info->m_Urls.join(";")); @@ -1108,7 +1119,7 @@ void DownloadManager::createMetaFile(DownloadInfo *info) } -void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmDescriptionAvailable(QString, int, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1157,7 +1168,7 @@ static EFileCategory convertFileCategory(int id) } -void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmFilesAvailable(QString, int, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1237,7 +1248,7 @@ void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultD } -void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1260,11 +1271,12 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD info->description = BBCode::convertToHTML(result["description"].toString()); info->repository = "Nexus"; + info->gameName = gameName; info->modID = modID; info->fileID = fileID; QObject *test = info; - m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(test), QString())); + m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(gameName, modID, fileID, this, qVariantFromValue(test), QString())); } static int evaluateFileInfoMap(const QVariantMap &map, const std::map &preferredServers) @@ -1300,7 +1312,7 @@ bool DownloadManager::ServerByPreference(const std::map &preferred int DownloadManager::startDownloadURLs(const QStringList &urls) { ModRepositoryFileInfo info; - addDownload(urls, -1, -1, &info); + addDownload(urls, "", -1, -1, &info); return m_ActiveDownloads.size() - 1; } @@ -1326,7 +1338,7 @@ int DownloadManager::indexByName(const QString &fileName) const return -1; } -void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1338,7 +1350,7 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u ModRepositoryFileInfo *info = qobject_cast(qvariant_cast(userData)); QVariantList resultList = resultData.toList(); if (resultList.length() == 0) { - removePending(modID, fileID); + removePending(gameName, modID, fileID); emit showMessage(tr("No download server available. Please try again later.")); return; } @@ -1352,11 +1364,11 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u foreach (const QVariant &server, resultList) { URLs.append(server.toMap()["URI"].toString()); } - addDownload(URLs, modID, fileID, info); + addDownload(URLs, gameName, modID, fileID, info); } -void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString) +void DownloadManager::nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1381,7 +1393,7 @@ void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, } } - removePending(modID, fileID); + removePending(gameName, modID, fileID); emit showMessage(tr("Failed to request file info from nexus: %1").arg(errorString)); } diff --git a/src/downloadmanager.h b/src/downloadmanager.h index a6d3b20c..780aeb5c 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -38,6 +38,7 @@ along with Mod Organizer. If not, see . namespace MOBase { class IPluginGame; } class NexusInterface; +class PluginContainer; /*! * \brief manages downloading of files and provides progress information for gui elements @@ -162,6 +163,8 @@ public: */ void setShowHidden(bool showHidden); + void setPluginContainer(PluginContainer *pluginContainer); + /** * @brief download from an already open network connection * @@ -179,7 +182,7 @@ public: * @param fileInfo information previously retrieved from the nexus network * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again **/ - bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo()); + bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, QString gameName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo()); /** * @brief start a download using a nxm-link @@ -209,7 +212,7 @@ public: * @param index index of the pending download (index in the range [0, numPendingDownloads()[) * @return pair of modid, fileid */ - std::pair getPendingDownload(int index); + std::tuple getPendingDownload(int index); /** * @brief retrieve the full path to the download specified by index @@ -411,15 +414,15 @@ public slots: void queryInfo(int index); - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID); + void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID); + void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmDownloadURLsAvailable(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 nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString); + void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString); void managedGameChanged(MOBase::IPluginGame const *gamePlugin); @@ -462,7 +465,7 @@ private: * @param fileInfo information previously retrieved from the mod page * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again **/ - bool addDownload(const QStringList &URLs, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo); + bool addDownload(const QStringList &URLs, QString gameName, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo); // important: the caller has to lock the list-mutex, otherwise the DownloadInfo-pointer might get invalidated at any time DownloadInfo *findDownload(QObject *reply, int *index = nullptr) const; @@ -481,7 +484,7 @@ private: QDateTime matchDate(const QString &timeString); - void removePending(int modID, int fileID); + void removePending(QString gameName, int modID, int fileID); static QString getFileTypeString(int fileType); @@ -493,7 +496,7 @@ private: NexusInterface *m_NexusInterface; - QVector > m_PendingDownloads; + QVector> m_PendingDownloads; QVector m_ActiveDownloads; diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 9a70f8bd..6785bf67 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -537,7 +537,7 @@ bool InstallationManager::ensureValidModName(GuessedValue &name) const return true; } -bool InstallationManager::doInstall(GuessedValue &modName, int modID, +bool InstallationManager::doInstall(GuessedValue &modName, QString gameName, int modID, const QString &version, const QString &newestVersion, int categoryID, const QString &repository) { @@ -582,6 +582,9 @@ bool InstallationManager::doInstall(GuessedValue &modName, int modID, QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat); // overwrite settings only if they are actually are available or haven't been set before + if ((gameName != "") || !settingsFile.contains("gameName")) { + settingsFile.setValue("gameName", gameName); + } if ((modID != 0) || !settingsFile.contains("modid")) { settingsFile.setValue("modid", modID); } @@ -662,6 +665,7 @@ bool InstallationManager::install(const QString &fileName, modName.update(QFileInfo(fileName).completeBaseName(), GUESS_FALLBACK); // read out meta information from the download if available + QString gameName = ""; int modID = 0; QString version = ""; QString newestVersion = ""; @@ -671,6 +675,7 @@ bool InstallationManager::install(const QString &fileName, QString metaName = fileName + ".meta"; if (QFile(metaName).exists()) { QSettings metaFile(metaName, QSettings::IniFormat); + gameName = metaFile.value("gameName", "").toString(); modID = metaFile.value("modID", 0).toInt(); QTextDocument doc; doc.setHtml(metaFile.value("name", "").toString()); @@ -759,7 +764,7 @@ bool InstallationManager::install(const QString &fileName, mapToArchive(filesTree.data()); // the simple installer only prepares the installation, the rest // works the same for all installers - if (!doInstall(modName, modID, version, newestVersion, categoryID, + if (!doInstall(modName, gameName, modID, version, newestVersion, categoryID, repository)) { installResult = IPluginInstaller::RESULT_FAILED; } @@ -780,6 +785,15 @@ bool InstallationManager::install(const QString &fileName, if (installerExt.find(fileInfo.suffix()) != installerExt.end()) { installResult = installerCustom->install(modName, fileName, version, modID); + if (installResult == IPluginInstaller::RESULT_SUCCESS) { + mapToArchive(filesTree.data()); + // the simple installer only prepares the installation, the rest + // works the same for all installers + if (!doInstall(modName, gameName, modID, version, newestVersion, categoryID, + repository)) { + installResult = IPluginInstaller::RESULT_FAILED; + } + } unsigned int idx = ModInfo::getIndex(modName); if (idx != UINT_MAX) { ModInfo::Ptr info = ModInfo::getByIndex(idx); diff --git a/src/installationmanager.h b/src/installationmanager.h index e1ebb519..bdf71a8d 100644 --- a/src/installationmanager.h +++ b/src/installationmanager.h @@ -168,7 +168,7 @@ private: bool isSimpleArchiveTopLayer(const MOBase::DirectoryTree::Node *node, bool bainStyle); MOBase::DirectoryTree::Node *getSimpleArchiveBase(MOBase::DirectoryTree *dataTree); - bool doInstall(MOBase::GuessedValue &modName, + bool doInstall(MOBase::GuessedValue &modName, QString gameName, int modID, const QString &version, const QString &newestVersion, int categoryID, const QString &repository); QString generateBackupName(const QString &directoryName) const; diff --git a/src/main.cpp b/src/main.cpp index fc332fe7..d67c2673 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,7 @@ along with Mod Organizer. If not, see . #include "nxmaccessmanager.h" #include "instancemanager.h" #include "moshortcut.h" +#include "organizercore.h" #include #include @@ -602,7 +603,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, QSplashScreen splash(pixmap); splash.show(); - NexusInterface::instance()->getAccessManager()->startLoginCheck(); + NexusInterface::instance(&pluginContainer)->getAccessManager()->startLoginCheck(); qDebug("initializing tutorials"); TutorialManager::init( diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6cbe364e..171026cf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -266,6 +266,7 @@ MainWindow::MainWindow(QSettings &initSettings // hide these columns by default ui->modList->header()->setSectionHidden(ModList::COL_CONTENT, true); ui->modList->header()->setSectionHidden(ModList::COL_MODID, true); + ui->modList->header()->setSectionHidden(ModList::COL_GAME, true); ui->modList->header()->setSectionHidden(ModList::COL_INSTALLTIME, true); } @@ -343,11 +344,11 @@ MainWindow::MainWindow(QSettings &initSettings connect(m_OrganizerCore.updater(), SIGNAL(updateAvailable()), this, SLOT(updateAvailable())); connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString))); - connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); - connect(NexusInterface::instance(), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int))); - connect(NexusInterface::instance(), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin())); - connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); - connect(NexusInterface::instance()->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), + connect(NexusInterface::instance(&pluginContainer), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); + connect(NexusInterface::instance(&pluginContainer), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int))); + connect(NexusInterface::instance(&pluginContainer), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin())); + connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); + connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), this, SLOT(updateWindowTitle(const QString&, bool))); connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString))); @@ -2347,7 +2348,7 @@ void MainWindow::reinstallMod_clicked() void MainWindow::resumeDownload(int downloadIndex) { - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { m_OrganizerCore.downloadManager()->resumeDownload(downloadIndex); } else { QString username, password; @@ -2355,7 +2356,7 @@ void MainWindow::resumeDownload(int downloadIndex) m_OrganizerCore.doAfterLogin([this, downloadIndex] () { this->resumeDownload(downloadIndex); }); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this); } @@ -2365,13 +2366,13 @@ void MainWindow::resumeDownload(int downloadIndex) void MainWindow::endorseMod(ModInfo::Ptr mod) { - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { mod->endorse(true); } else { QString username, password; if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_OrganizerCore.doAfterLogin(boost::bind(&MainWindow::endorseMod, this, mod)); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this); } @@ -2393,12 +2394,12 @@ void MainWindow::dontendorse_clicked() void MainWindow::unendorse_clicked() { QString username, password; - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { ModInfo::getByIndex(m_ContextRow)->endorse(false); } else { if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_OrganizerCore.doAfterLogin([this] () { this->unendorse_clicked(); }); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this); } @@ -2574,8 +2575,9 @@ void MainWindow::ignoreMissingData_clicked() void MainWindow::visitOnNexus_clicked() { int modID = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt(); + QString gameName = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole + 4).toString(); if (modID > 0) { - nexusLinkActivated(NexusInterface::instance()->getModURL(modID)); + nexusLinkActivated(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName)); } else { MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this); } @@ -2921,18 +2923,18 @@ void MainWindow::saveArchiveList() void MainWindow::checkModsForUpdates() { statusBar()->show(); - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { - m_ModsToUpdate = ModInfo::checkAllForUpdate(this); + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { + m_ModsToUpdate = ModInfo::checkAllForUpdate(&m_PluginContainer, this); m_RefreshProgress->setRange(0, m_ModsToUpdate); } else { QString username, password; if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_OrganizerCore.doAfterLogin([this] () { this->checkModsForUpdates(); }); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { // otherwise there will be no endorsement info MessageDialog::showMessage(tr("Not logged in, endorsement information will be wrong"), this, true); - m_ModsToUpdate = ModInfo::checkAllForUpdate(this); + m_ModsToUpdate = ModInfo::checkAllForUpdate(&m_PluginContainer, this); } } } @@ -3207,7 +3209,7 @@ void MainWindow::exportModListCSV() if (nexus_ID->isChecked()) builder.setRowField("#Nexus_ID", info->getNexusID()); if (mod_Nexus_URL->isChecked()) - builder.setRowField("#Mod_Nexus_URL",(info->getNexusID()>0)? NexusInterface::instance()->getModURL(info->getNexusID()) : ""); + builder.setRowField("#Mod_Nexus_URL",(info->getNexusID()>0)? NexusInterface::instance(&m_PluginContainer)->getModURL(info->getNexusID(), info->getGameName()) : ""); if (mod_Version->isChecked()) builder.setRowField("#Mod_Version", info->getVersion().canonicalString()); if (install_Date->isChecked()) @@ -3629,7 +3631,7 @@ void MainWindow::on_actionSettings_triggered() bool oldDisplayForeign(settings.displayForeign()); bool proxy = settings.useProxy(); - settings.query(this); + settings.query(&m_PluginContainer, this); InstallationManager *instManager = m_OrganizerCore.installationManager(); instManager->setModsDirectory(settings.getModDirectory()); @@ -3661,14 +3663,14 @@ void MainWindow::on_actionSettings_triggered() } if (settings.getCacheDirectory() != oldCacheDirectory) { - NexusInterface::instance()->setCacheDirectory(settings.getCacheDirectory()); + NexusInterface::instance(&m_PluginContainer)->setCacheDirectory(settings.getCacheDirectory()); } if (proxy != settings.useProxy()) { activateProxy(settings.useProxy()); } - NexusInterface::instance()->setNMMVersion(settings.getNMMVersion()); + NexusInterface::instance(&m_PluginContainer)->setNMMVersion(settings.getNMMVersion()); updateDownloadListDelegate(); @@ -3680,7 +3682,7 @@ void MainWindow::on_actionSettings_triggered() void MainWindow::on_actionNexus_triggered() { ::ShellExecuteW(nullptr, L"open", - NexusInterface::instance()->getGameURL().toStdWString().c_str(), + NexusInterface::instance(&m_PluginContainer)->getGameURL(m_OrganizerCore.managedGame()->gameShortName()).toStdWString().c_str(), nullptr, nullptr, SW_SHOWNORMAL); } @@ -4099,10 +4101,10 @@ void MainWindow::on_actionEndorseMO_triggered() { if (QMessageBox::question(this, tr("Endorse Mod Organizer"), tr("Do you want to endorse Mod Organizer on %1 now?").arg( - NexusInterface::instance()->getGameURL()), + NexusInterface::instance(&m_PluginContainer)->getGameURL(m_OrganizerCore.managedGame()->gameShortName())), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - NexusInterface::instance()->requestToggleEndorsement( - m_OrganizerCore.managedGame()->nexusModOrganizerID(), true, this, QVariant(), QString()); + NexusInterface::instance(&m_PluginContainer)->requestToggleEndorsement( + m_OrganizerCore.managedGame()->gameShortName(), m_OrganizerCore.managedGame()->nexusModOrganizerID(), true, this, QVariant(), QString()); } } @@ -4174,7 +4176,7 @@ void MainWindow::nxmUpdatesAvailable(const std::vector &modIDs, QVariant us for (auto iter = info.begin(); iter != info.end(); ++iter) { (*iter)->setNewestVersion(result["version"].toString()); (*iter)->setNexusDescription(result["description"].toString()); - if (NexusInterface::instance()->getAccessManager()->loggedIn() && + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn() && result.contains("voted_by_user")) { // don't use endorsement info if we're not logged in or if the response doesn't contain it (*iter)->setIsEndorsed(result["voted_by_user"].toBool()); @@ -4197,20 +4199,20 @@ void MainWindow::nxmUpdatesAvailable(const std::vector &modIDs, QVariant us } } -void MainWindow::nxmEndorsementToggled(int, QVariant, QVariant resultData, int) +void MainWindow::nxmEndorsementToggled(QString, int, QVariant, QVariant resultData, int) { if (resultData.toBool()) { ui->actionEndorseMO->setVisible(false); QMessageBox::question(this, tr("Thank you!"), tr("Thank you for your endorsement!")); } - if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(int, QVariant, QVariant, int)), - this, SLOT(nxmEndorsementToggled(int, QVariant, QVariant, int)))) { + if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)), + this, SLOT(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)))) { qCritical("failed to disconnect endorsement slot"); } } -void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int) +void MainWindow::nxmDownloadURLs(QString, int, int, QVariant, QVariant resultData, int) { QVariantList serverList = resultData.toList(); @@ -4229,7 +4231,7 @@ void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int) } -void MainWindow::nxmRequestFailed(int modID, int, QVariant, int, const QString &errorString) +void MainWindow::nxmRequestFailed(QString, int modID, int, QVariant, int, const QString &errorString) { if (modID == -1) { // must be the update-check that failed diff --git a/src/mainwindow.h b/src/mainwindow.h index ef6eb262..d684dbc0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -461,9 +461,9 @@ private slots: void modInstalled(const QString &modName); void nxmUpdatesAvailable(const std::vector &modIDs, QVariant userData, QVariant resultData, int requestID); - void nxmEndorsementToggled(int, QVariant, QVariant resultData, int); - void nxmDownloadURLs(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString); + void nxmEndorsementToggled(QString, int, QVariant, QVariant resultData, int); + void nxmDownloadURLs(QString, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmRequestFailed(QString, int modID, int fileID, QVariant userData, int requestID, const QString &errorString); void editCategories(); void deselectFilters(); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index d80c636b..2cd3aec7 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -61,16 +61,16 @@ bool ModInfo::ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS) } -ModInfo::Ptr ModInfo::createFrom(const QDir &dir, DirectoryEntry **directoryStructure) +ModInfo::Ptr ModInfo::createFrom(PluginContainer *pluginContainer, QString gameName, const QDir &dir, DirectoryEntry **directoryStructure) { QMutexLocker locker(&s_Mutex); // int id = s_NextID++; static QRegExp backupExp(".*backup[0-9]*"); ModInfo::Ptr result; if (backupExp.exactMatch(dir.dirName())) { - result = ModInfo::Ptr(new ModInfoBackup(dir, directoryStructure)); + result = ModInfo::Ptr(new ModInfoBackup(pluginContainer, gameName, dir, directoryStructure)); } else { - result = ModInfo::Ptr(new ModInfoRegular(dir, directoryStructure)); + result = ModInfo::Ptr(new ModInfoRegular(pluginContainer, gameName, dir, directoryStructure)); } s_Collection.push_back(result); return result; @@ -80,10 +80,11 @@ ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, - DirectoryEntry **directoryStructure) { + DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer) { QMutexLocker locker(&s_Mutex); ModInfo::Ptr result = ModInfo::Ptr( - new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure)); + new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure, pluginContainer)); s_Collection.push_back(result); return result; } @@ -105,11 +106,11 @@ QString ModInfo::getContentTypeName(int contentType) } } -void ModInfo::createFromOverwrite() +void ModInfo::createFromOverwrite(PluginContainer *pluginContainer) { QMutexLocker locker(&s_Mutex); - s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite)); + s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite(pluginContainer))); } unsigned int ModInfo::getNumMods() @@ -207,6 +208,7 @@ unsigned int ModInfo::findMod(const boost::function &filter void ModInfo::updateFromDisc(const QString &modDirectory, DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer, bool displayForeign, MOBase::IPluginGame const *game) { @@ -219,7 +221,7 @@ void ModInfo::updateFromDisc(const QString &modDirectory, mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QDirIterator modIter(mods); while (modIter.hasNext()) { - createFrom(QDir(modIter.next()), directoryStructure); + createFrom(pluginContainer, game->gameShortName(), QDir(modIter.next()), directoryStructure); } } @@ -233,11 +235,12 @@ void ModInfo::updateFromDisc(const QString &modDirectory, unmanaged->referenceFile(modName).absoluteFilePath(), unmanaged->secondaryFiles(modName), modType, - directoryStructure); + directoryStructure, + pluginContainer); } } - createFromOverwrite(); + createFromOverwrite(pluginContainer); std::sort(s_Collection.begin(), s_Collection.end(), ModInfo::ByName); @@ -259,21 +262,21 @@ void ModInfo::updateIndices() } -ModInfo::ModInfo() +ModInfo::ModInfo(PluginContainer *pluginContainer) : m_Valid(false), m_PrimaryCategory(-1) { } -void ModInfo::checkChunkForUpdate(const std::vector &modIDs, QObject *receiver) +void ModInfo::checkChunkForUpdate(PluginContainer *pluginContainer, const std::vector &modIDs, QObject *receiver, QString gameName) { if (modIDs.size() != 0) { - NexusInterface::instance()->requestUpdates(modIDs, receiver, QVariant(), QString()); + NexusInterface::instance(pluginContainer)->requestUpdates(modIDs, receiver, QVariant(), gameName, QString()); } } -int ModInfo::checkAllForUpdate(QObject *receiver) +int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver) { // technically this should be 255 but those requests can take nexus fairly long, produce // large output and may have been the cause of issue #1166 @@ -284,20 +287,33 @@ int ModInfo::checkAllForUpdate(QObject *receiver) //I ought to store this, it's used elsewhere IPluginGame const *game = qApp->property("managed_game").value(); - modIDs.push_back(game->nexusModOrganizerID()); + checkChunkForUpdate(pluginContainer, modIDs, receiver, game->gameShortName()); - for (const ModInfo::Ptr &mod : s_Collection) { + std::multimap> organizedGames; + for (auto mod : s_Collection) { if (mod->canBeUpdated()) { - modIDs.push_back(mod->getNexusID()); - if (modIDs.size() >= chunkSize) { - checkChunkForUpdate(modIDs, receiver); + organizedGames.insert(std::pair>(mod->getGameName(), mod)); + } + } + + QString currentGame = ""; + for (auto game : organizedGames) { + if (currentGame != game.first) { + if (currentGame != "") { + checkChunkForUpdate(pluginContainer, modIDs, receiver, currentGame); modIDs.clear(); } + currentGame = game.first; + } + modIDs.push_back(game.second->getNexusID()); + if (modIDs.size() >= chunkSize) { + checkChunkForUpdate(pluginContainer, modIDs, receiver, currentGame); + modIDs.clear(); } } - checkChunkForUpdate(modIDs, receiver); + checkChunkForUpdate(pluginContainer, modIDs, receiver, currentGame); return result; } diff --git a/src/modinfo.h b/src/modinfo.h index 1ceb8e1f..f321f068 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -23,6 +23,8 @@ along with Mod Organizer. If not, see . #include "imodinterface.h" #include "versioninfo.h" +class PluginContainer; + class QDateTime; class QDir; #include @@ -115,6 +117,7 @@ public: **/ static void updateFromDisc(const QString &modDirectory, MOShared::DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer, bool displayForeign, MOBase::IPluginGame const *game); @@ -176,19 +179,19 @@ public: * @param modIDs list of mods (Nexus Mod IDs) to check for updates * @return */ - static void checkChunkForUpdate(const std::vector &modIDs, QObject *receiver); + static void checkChunkForUpdate(PluginContainer *pluginContainer, const std::vector &modIDs, QObject *receiver, QString gameName); /** * @brief query nexus information for every mod and update the "newest version" information **/ - static int checkAllForUpdate(QObject *receiver); + static int checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver); /** * @brief create a new mod from the specified directory and add it to the collection * @param dir directory to create from * @return pointer to the info-structure of the newly created/added mod */ - static ModInfo::Ptr createFrom(const QDir &dir, MOShared::DirectoryEntry **directoryStructure); + static ModInfo::Ptr createFrom(PluginContainer *pluginContainer, QString gameName, const QDir &dir, MOShared::DirectoryEntry **directoryStructure); /** * @brief create a new "foreign-managed" mod from a tuple of plugin and archives @@ -196,7 +199,7 @@ public: * @param bsaNames names of archives * @return a new mod */ - static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure); + static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); /** * @brief retieve a name for one of the CONTENT_ enums @@ -408,7 +411,14 @@ public: * * @return the nexus mod id. may be 0 if the mod id isn't known or doesn't exist **/ - virtual int getNexusID() const = 0; + virtual int getNexusID() const = 0; + + /** + * @brief getter for the source game repository + * + * @return the source game repository. should default to the active game. + **/ + virtual QString getGameName() const = 0; /** * @return the fixed priority of mods of this type or INT_MIN if the priority of mods @@ -596,14 +606,14 @@ signals: protected: - ModInfo(); + ModInfo(PluginContainer *pluginContainer); static void updateIndices(); static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS); private: - static void createFromOverwrite(); + static void createFromOverwrite(PluginContainer *pluginContainer); protected: diff --git a/src/modinfobackup.cpp b/src/modinfobackup.cpp index a57b84fe..b779dca1 100644 --- a/src/modinfobackup.cpp +++ b/src/modinfobackup.cpp @@ -14,7 +14,7 @@ QString ModInfoBackup::getDescription() const } -ModInfoBackup::ModInfoBackup(const QDir &path, MOShared::DirectoryEntry **directoryStructure) - : ModInfoRegular(path, directoryStructure) +ModInfoBackup::ModInfoBackup(PluginContainer *pluginContainer, QString gameName, const QDir &path, MOShared::DirectoryEntry **directoryStructure) + : ModInfoRegular(pluginContainer, gameName, path, directoryStructure) { } diff --git a/src/modinfobackup.h b/src/modinfobackup.h index adbac783..aa59dda4 100644 --- a/src/modinfobackup.h +++ b/src/modinfobackup.h @@ -32,7 +32,7 @@ public: private: - ModInfoBackup(const QDir &path, MOShared::DirectoryEntry **directoryStructure); + ModInfoBackup(PluginContainer *pluginContainer, QString gameName, const QDir &path, MOShared::DirectoryEntry **directoryStructure); }; diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 6a53d915..31ffe82d 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -714,7 +714,7 @@ void ModInfoDialog::linkClicked(const QUrl &url) { //Ideally we'd ask the mod for the game and the web service then pass the game //and URL to the web service - if (NexusInterface::instance()->isURLGameRelated(url)) { + if (NexusInterface::instance(m_PluginContainer)->isURLGameRelated(url)) { this->close(); emit nexusLinkActivated(url.toString()); } else { @@ -860,7 +860,7 @@ void ModInfoDialog::activateNexusTab() QLineEdit *modIDEdit = findChild("modIDEdit"); int modID = modIDEdit->text().toInt(); if (modID != 0) { - QString nexusLink = NexusInterface::instance()->getModURL(modID); + QString nexusLink = NexusInterface::instance(m_PluginContainer)->getModURL(modID, m_ModInfo->getGameName()); QLabel *visitNexusLabel = findChild("visitNexusLabel"); visitNexusLabel->setText(tr("Visit on Nexus").arg(nexusLink)); visitNexusLabel->setToolTip(nexusLink); diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp index 6ac66c67..b599d4eb 100644 --- a/src/modinfoforeign.cpp +++ b/src/modinfoforeign.cpp @@ -51,8 +51,9 @@ ModInfoForeign::ModInfoForeign(const QString &modName, const QString &referenceFile, const QStringList &archives, ModInfo::EModType modType, - DirectoryEntry **directoryStructure) - : ModInfoWithConflictInfo(directoryStructure), + DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer) + : ModInfoWithConflictInfo(pluginContainer, directoryStructure), m_ReferenceFile(referenceFile), m_Archives(archives) { m_CreationTime = QFileInfo(referenceFile).created(); switch (modType) { diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h index d60064f0..23500df8 100644 --- a/src/modinfoforeign.h +++ b/src/modinfoforeign.h @@ -37,6 +37,7 @@ public: virtual QString absolutePath() const; virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } + virtual QString getGameName() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } virtual std::vector getFlags() const; @@ -53,7 +54,7 @@ public: protected: ModInfoForeign(const QString &modName, const QString &referenceFile, const QStringList &archives, ModInfo::EModType modType, - MOShared::DirectoryEntry **directoryStructure); + MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); private: QString m_Name; diff --git a/src/modinfooverwrite.cpp b/src/modinfooverwrite.cpp index 360212c0..742ae384 100644 --- a/src/modinfooverwrite.cpp +++ b/src/modinfooverwrite.cpp @@ -6,7 +6,7 @@ #include #include -ModInfoOverwrite::ModInfoOverwrite() +ModInfoOverwrite::ModInfoOverwrite(PluginContainer *pluginContainer) : ModInfo(pluginContainer) { testValid(); } diff --git a/src/modinfooverwrite.h b/src/modinfooverwrite.h index b6cdfb43..360c7335 100644 --- a/src/modinfooverwrite.h +++ b/src/modinfooverwrite.h @@ -40,6 +40,7 @@ public: virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } virtual int getFixedPriority() const { return INT_MAX; } + virtual QString getGameName() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } virtual std::vector getFlags() const; @@ -52,7 +53,7 @@ public: private: - ModInfoOverwrite(); + ModInfoOverwrite(PluginContainer *pluginContainer); }; diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 4572f5bf..69718705 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -24,26 +24,27 @@ namespace { } } -ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStructure) - : ModInfoWithConflictInfo(directoryStructure) +ModInfoRegular::ModInfoRegular(PluginContainer *pluginContainer, QString gameName, const QDir &path, DirectoryEntry **directoryStructure) + : ModInfoWithConflictInfo(pluginContainer, directoryStructure) + , m_GameName(gameName) , m_Name(path.dirName()) , m_Path(path.absolutePath()) , m_Repository() , m_MetaInfoChanged(false) , m_EndorsedState(ENDORSED_UNKNOWN) - , m_NexusBridge() + , m_NexusBridge(pluginContainer) { testValid(); m_CreationTime = QFileInfo(path.absolutePath()).created(); // read out the meta-file for information readMeta(); - connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int,QVariant,QVariant)) - , this, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant))); - connect(&m_NexusBridge, SIGNAL(endorsementToggled(int,QVariant,QVariant)) - , this, SLOT(nxmEndorsementToggled(int,QVariant,QVariant))); - connect(&m_NexusBridge, SIGNAL(requestFailed(int,int,QVariant,QString)) - , this, SLOT(nxmRequestFailed(int,int,QVariant,QString))); + connect(&m_NexusBridge, SIGNAL(descriptionAvailable(QString,int,QVariant,QVariant)) + , this, SLOT(nxmDescriptionAvailable(QString,int,QVariant,QVariant))); + connect(&m_NexusBridge, SIGNAL(endorsementToggled(QString,int,QVariant,QVariant)) + , this, SLOT(nxmEndorsementToggled(QString,int,QVariant,QVariant))); + connect(&m_NexusBridge, SIGNAL(requestFailed(QString,int,int,QVariant,QString)) + , this, SLOT(nxmRequestFailed(QString,int,int,QVariant,QString))); } @@ -71,6 +72,8 @@ void ModInfoRegular::readMeta() { QSettings metaFile(m_Path + "/meta.ini", QSettings::IniFormat); m_Notes = metaFile.value("notes", "").toString(); + QString tempGameName = metaFile.value("gameName", m_GameName).toString(); + if (tempGameName != "") m_GameName = tempGameName; m_NexusID = metaFile.value("modid", -1).toInt(); m_Version.parse(metaFile.value("version", "").toString()); m_NewestVersion = metaFile.value("newestVersion", "").toString(); @@ -135,6 +138,7 @@ void ModInfoRegular::saveMeta() metaFile.setValue("version", m_Version.canonicalString()); metaFile.setValue("installationFile", m_InstallationFile); metaFile.setValue("repository", m_Repository); + metaFile.setValue("gameName", m_GameName); metaFile.setValue("modid", m_NexusID); metaFile.setValue("notes", m_Notes); metaFile.setValue("nexusDescription", m_NexusDescription); @@ -185,7 +189,7 @@ bool ModInfoRegular::downgradeAvailable() const } -void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData) +void ModInfoRegular::nxmDescriptionAvailable(QString, int, QVariant, QVariant resultData) { QVariantMap result = resultData.toMap(); setNewestVersion(VersionInfo(result["version"].toString())); @@ -201,7 +205,7 @@ void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData) } -void ModInfoRegular::nxmEndorsementToggled(int, QVariant, QVariant resultData) +void ModInfoRegular::nxmEndorsementToggled(QString, int, QVariant, QVariant resultData) { m_EndorsedState = resultData.toBool() ? ENDORSED_TRUE : ENDORSED_FALSE; m_MetaInfoChanged = true; @@ -210,7 +214,7 @@ void ModInfoRegular::nxmEndorsementToggled(int, QVariant, QVariant resultData) } -void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString &errorMessage) +void ModInfoRegular::nxmRequestFailed(QString, int, int, QVariant userData, const QString &errorMessage) { QString fullMessage = errorMessage; if (userData.canConvert() && (userData.toInt() == 1)) { @@ -226,7 +230,7 @@ void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString bool ModInfoRegular::updateNXMInfo() { if (m_NexusID > 0) { - m_NexusBridge.requestDescription(m_NexusID, QVariant()); + m_NexusBridge.requestDescription(m_GameName, m_NexusID, QVariant()); return true; } return false; @@ -387,7 +391,7 @@ bool ModInfoRegular::remove() void ModInfoRegular::endorse(bool doEndorse) { if (doEndorse != (m_EndorsedState == ENDORSED_TRUE)) { - m_NexusBridge.requestToggleEndorsement(getNexusID(), doEndorse, QVariant(1)); + m_NexusBridge.requestToggleEndorsement(m_GameName, getNexusID(), doEndorse, QVariant(1)); } } diff --git a/src/modinforegular.h b/src/modinforegular.h index a94d0363..7a6f4827 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -206,6 +206,14 @@ public: * @return file used to install this mod from */ virtual QString getInstallationFile() const { return m_InstallationFile; } + + /** + * @brief getter for the source game repository + * + * @return the source game repository. should default to the active game. + **/ + QString getGameName() const { return m_GameName; } + /** * @brief getter for the nexus mod id * @@ -308,13 +316,13 @@ private: private slots: - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData); - void nxmEndorsementToggled(int, QVariant userData, QVariant resultData); - void nxmRequestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage); + void nxmDescriptionAvailable(QString, int modID, QVariant userData, QVariant resultData); + void nxmEndorsementToggled(QString, int, QVariant userData, QVariant resultData); + void nxmRequestFailed(QString, int modID, int fileID, QVariant userData, const QString &errorMessage); protected: - ModInfoRegular(const QDir &path, MOShared::DirectoryEntry **directoryStructure); + ModInfoRegular(PluginContainer *pluginContainer, QString gameName, const QDir &path, MOShared::DirectoryEntry **directoryStructure); private: @@ -325,6 +333,7 @@ private: QString m_NexusDescription; QString m_Repository; QString m_URL; + QString m_GameName; QDateTime m_CreationTime; QDateTime m_LastNexusQuery; diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index b8ece783..e88ba29d 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -6,8 +6,8 @@ using namespace MOBase; using namespace MOShared; -ModInfoWithConflictInfo::ModInfoWithConflictInfo(DirectoryEntry **directoryStructure) - : m_DirectoryStructure(directoryStructure) {} +ModInfoWithConflictInfo::ModInfoWithConflictInfo(PluginContainer *pluginContainer, DirectoryEntry **directoryStructure) + : ModInfo(pluginContainer), m_DirectoryStructure(directoryStructure) {} void ModInfoWithConflictInfo::clearCaches() { diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index be31f20f..6c1591c5 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -10,7 +10,7 @@ class ModInfoWithConflictInfo : public ModInfo public: - ModInfoWithConflictInfo(MOShared::DirectoryEntry **directoryStructure); + ModInfoWithConflictInfo(PluginContainer *pluginContainer, MOShared::DirectoryEntry **directoryStructure); std::vector getFlags() const; diff --git a/src/modlist.cpp b/src/modlist.cpp index 7b2ad1f9..c8fd4b3e 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -53,13 +53,14 @@ along with Mod Organizer. If not, see . using namespace MOBase; -ModList::ModList(QObject *parent) +ModList::ModList(PluginContainer *pluginContainer, QObject *parent) : QAbstractItemModel(parent) , m_Profile(nullptr) , m_NexusInterface(nullptr) , m_Modified(false) , m_FontMetrics(QFont()) , m_DropOnItems(false) + , m_PluginContainer(pluginContainer) { m_ContentIcons[ModInfo::CONTENT_PLUGIN] = std::make_tuple(":/MO/gui/content/plugin", tr("Game Plugins (ESP/ESM/ESL)")); m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(":/MO/gui/content/interface", tr("Interface")); @@ -219,9 +220,18 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const int modID = modInfo->getNexusID(); if (modID >= 0) { return modID; - } else { + } + else { return QVariant(); } + } else if (column == COL_GAME) { + if (m_PluginContainer != nullptr) { + for (auto game : m_PluginContainer->plugins()) { + if (game->gameShortName() == modInfo->getGameName()) + return game->gameName(); + } + } + return modInfo->getGameName(); } else if (column == COL_CATEGORY) { if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) { return tr("Non-MO"); @@ -309,6 +319,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const } } else if (role == Qt::UserRole + 3) { return contentsToIcons(modInfo->getContents()); + } else if (role == Qt::UserRole + 4) { + return modInfo->getGameName(); } else if (role == Qt::FontRole) { QFont result; if (column == COL_NAME) { @@ -659,6 +671,11 @@ void ModList::setOverwriteMarkers(const std::set &overwrite, const notifyChange(0, rowCount() - 1); } +void ModList::setPluginContainer(PluginContainer *pluginContianer) +{ + m_PluginContainer = pluginContianer; +} + bool ModList::modInfoAboutToChange(ModInfo::Ptr info) { if (m_ChangeInfo.name.isEmpty()) { @@ -1051,6 +1068,7 @@ QString ModList::getColumnName(int column) case COL_VERSION: return tr("Version"); case COL_PRIORITY: return tr("Priority"); case COL_CATEGORY: return tr("Category"); + case COL_GAME: return tr("Source Game"); case COL_MODID: return tr("Nexus ID"); case COL_INSTALLTIME: return tr("Installation"); default: return tr("unknown"); @@ -1066,6 +1084,7 @@ QString ModList::getColumnToolTip(int column) case COL_PRIORITY: return tr("Installation priority of your mod. The higher, the more \"important\" it is and thus " "overwrites files from mods with lower priority."); case COL_CATEGORY: return tr("Category of the mod."); + case COL_GAME: return tr("The source game which was the origin of this mod."); case COL_MODID: return tr("Id of the mod as used on Nexus."); case COL_FLAGS: return tr("Emblemes to highlight things that might require attention."); case COL_CONTENT: return tr("Depicts the content of the mod:
" diff --git a/src/modlist.h b/src/modlist.h index bd715107..b5f18e98 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -42,6 +42,7 @@ along with Mod Organizer. If not, see . class QSortFilterProxyModel; +class PluginContainer; /** * Model presenting an overview of the installed mod @@ -60,6 +61,7 @@ public: COL_CONTENT, COL_CATEGORY, COL_MODID, + COL_GAME, COL_VERSION, COL_INSTALLTIME, COL_PRIORITY, @@ -76,7 +78,7 @@ public: * @brief constructor * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order **/ - ModList(QObject *parent = nullptr); + ModList(PluginContainer *pluginContainer, QObject *parent = nullptr); ~ModList(); @@ -106,6 +108,7 @@ public: void changeModPriority(int sourceIndex, int newPriority); void setOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); + void setPluginContainer(PluginContainer *pluginContainer); bool modInfoAboutToChange(ModInfo::Ptr info); void modInfoChanged(ModInfo::Ptr info); @@ -329,6 +332,8 @@ private: QTime m_LastCheck; + PluginContainer *m_PluginContainer; + }; #endif // MODLIST_H diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 97186e8b..434c0334 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -36,48 +36,48 @@ using namespace MOBase; using namespace MOShared; -NexusBridge::NexusBridge(const QString &subModule) - : m_Interface(NexusInterface::instance()) +NexusBridge::NexusBridge(PluginContainer *pluginContainer, const QString &subModule) + : m_Interface(NexusInterface::instance(pluginContainer)) , m_SubModule(subModule) { } -void NexusBridge::requestDescription(int modID, QVariant userData) +void NexusBridge::requestDescription(QString gameName, int modID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestDescription(gameName, modID, this, userData, m_SubModule)); } -void NexusBridge::requestFiles(int modID, QVariant userData) +void NexusBridge::requestFiles(QString gameName, int modID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestFiles(gameName, modID, this, userData, m_SubModule)); } -void NexusBridge::requestFileInfo(int modID, int fileID, QVariant userData) +void NexusBridge::requestFileInfo(QString gameName, int modID, int fileID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestFileInfo(gameName, modID, fileID, this, userData, m_SubModule)); } -void NexusBridge::requestDownloadURL(int modID, int fileID, QVariant userData) +void NexusBridge::requestDownloadURL(QString gameName, int modID, int fileID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestDownloadURL(gameName, modID, fileID, this, userData, m_SubModule)); } -void NexusBridge::requestToggleEndorsement(int modID, bool endorse, QVariant userData) +void NexusBridge::requestToggleEndorsement(QString gameName, int modID, bool endorse, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestToggleEndorsement(gameName, modID, endorse, this, userData, m_SubModule)); } -void NexusBridge::nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit descriptionAvailable(modID, userData, resultData); + emit descriptionAvailable(gameName, modID, userData, resultData); } } -void NexusBridge::nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { @@ -100,43 +100,43 @@ void NexusBridge::nxmFilesAvailable(int modID, QVariant userData, QVariant resul fileInfoList.append(temp); } - emit filesAvailable(modID, userData, fileInfoList); + emit filesAvailable(gameName, modID, userData, fileInfoList); } } -void NexusBridge::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit fileInfoAvailable(modID, fileID, userData, resultData); + emit fileInfoAvailable(gameName, modID, fileID, userData, resultData); } } -void NexusBridge::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit downloadURLsAvailable(modID, fileID, userData, resultData); + emit downloadURLsAvailable(gameName, modID, fileID, userData, resultData); } } -void NexusBridge::nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit endorsementToggled(modID, userData, resultData); + emit endorsementToggled(gameName, modID, userData, resultData); } } -void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage) +void NexusBridge::nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit requestFailed(modID, fileID, userData, errorMessage); + emit requestFailed(gameName, modID, fileID, userData, errorMessage); } } @@ -144,8 +144,8 @@ void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0); -NexusInterface::NexusInterface() - : m_NMMVersion() +NexusInterface::NexusInterface(PluginContainer *pluginContainer) + : m_NMMVersion(), m_PluginContainer(pluginContainer) { VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath())); m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16, @@ -167,9 +167,9 @@ NexusInterface::~NexusInterface() cleanup(); } -NexusInterface *NexusInterface::instance() +NexusInterface *NexusInterface::instance(PluginContainer *pluginContainer) { - static NexusInterface s_Instance; + static NexusInterface s_Instance(pluginContainer); return &s_Instance; } @@ -246,12 +246,16 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo bool NexusInterface::isURLGameRelated(const QUrl &url) const { QString const name(url.toString()); - return name.startsWith(getGameURL() + "/") || + return name.startsWith(getGameURL("") + "/") || name.startsWith(getOldModsURL() + "/"); } -QString NexusInterface::getGameURL() const +QString NexusInterface::getGameURL(QString gameName) const { + IPluginGame *game = getGame(gameName); + if (game != nullptr) { + return "http://www.nexusmods.com/" + game->gameNexusName().toLower(); + } return "http://www.nexusmods.com/" + m_Game->gameNexusName().toLower(); } @@ -261,9 +265,9 @@ QString NexusInterface::getOldModsURL() const } -QString NexusInterface::getModURL(int modID) const +QString NexusInterface::getModURL(int modID, QString gameName = "") const { - return QString("%1/mods/%2").arg(getGameURL()).arg(modID); + return QString("%1/mods/%2").arg(getGameURL(gameName)).arg(modID); } bool NexusInterface::isModURL(int modID, const QString &url) const @@ -276,17 +280,22 @@ bool NexusInterface::isModURL(int modID, const QString &url) const return QUrl(alt) == QUrl(url); } -int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant userData, +void NexusInterface::setPluginContainer(PluginContainer *pluginContainer) +{ + m_PluginContainer = pluginContainer; +} + +int NexusInterface::requestDescription(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_DESCRIPTION, userData, subModule, game); m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmDescriptionAvailable(int,QVariant,QVariant,int)), - receiver, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmDescriptionAvailable(QString,int,QVariant,QVariant,int)), + receiver, SLOT(nxmDescriptionAvailable(QString,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; @@ -294,19 +303,25 @@ int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant us int NexusInterface::requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, - const QString &subModule, MOBase::IPluginGame const *game) + QString gameName, const QString &subModule) { - NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game); - m_RequestQueue.enqueue(requestInfo); + IPluginGame *game = getGame(gameName); - connect(this, SIGNAL(nxmUpdatesAvailable(std::vector,QVariant,QVariant,int)), - receiver, SLOT(nxmUpdatesAvailable(std::vector,QVariant,QVariant,int)), Qt::UniqueConnection); + if (game != nullptr) { + NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game); + m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmUpdatesAvailable(std::vector, QVariant, QVariant, int)), + receiver, SLOT(nxmUpdatesAvailable(std::vector, QVariant, QVariant, int)), Qt::UniqueConnection); - nextRequest(); - return requestInfo.m_ID; + connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QString)), + receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QString)), Qt::UniqueConnection); + + nextRequest(); + return requestInfo.m_ID; + } + + return -1; } @@ -325,72 +340,75 @@ void NexusInterface::fakeFiles() fileMap["size"] = "512"; result.append(fileMap); - emit nxmFilesAvailable(1234, "fake", result, id++); + emit nxmFilesAvailable("fakeGame", 1234, "fake", result, id++); } -int NexusInterface::requestFiles(int modID, QObject *receiver, QVariant userData, +int NexusInterface::requestFiles(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_FILES, userData, subModule, game); m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmFilesAvailable(int,QVariant,QVariant,int)), - receiver, SLOT(nxmFilesAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmFilesAvailable(QString,int,QVariant,QVariant,int)), + receiver, SLOT(nxmFilesAvailable(QString,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; } -int NexusInterface::requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, - MOBase::IPluginGame const *game) +int NexusInterface::requestFileInfo(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) { - NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, game); - m_RequestQueue.enqueue(requestInfo); + IPluginGame *gamePlugin = getGame(gameName); + if (gamePlugin != nullptr) { + NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, gamePlugin); + m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)), - receiver, SLOT(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmFileInfoAvailable(QString, int, int, QVariant, QVariant, int)), + receiver, SLOT(nxmFileInfoAvailable(QString, int, int, QVariant, QVariant, int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QString)), + receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QString)), Qt::UniqueConnection); - nextRequest(); - return requestInfo.m_ID; + nextRequest(); + return requestInfo.m_ID; + } + return -1; } -int NexusInterface::requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, +int NexusInterface::requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData, subModule, game); m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), - receiver, SLOT(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmDownloadURLsAvailable(QString,int,int,QVariant,QVariant,int)), + receiver, SLOT(nxmDownloadURLsAvailable(QString,int,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; } -int NexusInterface::requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, +int NexusInterface::requestToggleEndorsement(QString gameName, int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game); requestInfo.m_Endorse = endorse; m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmEndorsementToggled(int,QVariant,QVariant,int)), - receiver, SLOT(nxmEndorsementToggled(int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmEndorsementToggled(QString,int,QVariant,QVariant,int)), + receiver, SLOT(nxmEndorsementToggled(QString,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; @@ -402,6 +420,19 @@ bool NexusInterface::requiresLogin(const NXMRequestInfo &info) || (info.m_Type == NXMRequestInfo::TYPE_DOWNLOADURL); } +IPluginGame* NexusInterface::getGame(QString gameName) const +{ + auto gamePlugins = m_PluginContainer->plugins(); + IPluginGame *gamePlugin = nullptr; + for (auto plugin : gamePlugins) { + if (plugin->gameShortName().compare(gameName, Qt::CaseInsensitive) == 0) { + gamePlugin = plugin; + break; + } + } + return gamePlugin; +} + void NexusInterface::cleanup() { // delete m_AccessManager; @@ -492,7 +523,7 @@ void NexusInterface::requestFinished(std::list::iterator iter) if (reply->error() != QNetworkReply::NoError) { qWarning("request failed: %s", reply->errorString().toUtf8().constData()); - emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->errorString()); + emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->errorString()); } else { int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (statusCode == 301) { @@ -510,33 +541,33 @@ void NexusInterface::requestFinished(std::list::iterator iter) nexusError = tr("empty response"); } qDebug("nexus error: %s", qPrintable(nexusError)); - emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError); + emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError); } else { bool ok; QVariant result = QtJson::parse(data, ok); if (result.isValid() && ok) { switch (iter->m_Type) { case NXMRequestInfo::TYPE_DESCRIPTION: { - emit nxmDescriptionAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID); + emit nxmDescriptionAvailable(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_FILES: { - emit nxmFilesAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID); + emit nxmFilesAvailable(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_FILEINFO: { - emit nxmFileInfoAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); + emit nxmFileInfoAvailable(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_DOWNLOADURL: { - emit nxmDownloadURLsAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); + emit nxmDownloadURLsAvailable(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_GETUPDATES: { emit nxmUpdatesAvailable(iter->m_ModIDList, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: { - emit nxmEndorsementToggled(iter->m_ModID, iter->m_UserData, result, iter->m_ID); + emit nxmEndorsementToggled(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); } break; } } else { - emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, tr("invalid response")); + emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, tr("invalid response")); } } } @@ -620,6 +651,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID , m_URL(get_management_url(game)) , m_SubModule(subModule) , m_NexusGameID(game->nexusGameID()) + , m_GameName(game->gameShortName()) , m_Endorse(false) {} @@ -641,6 +673,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector modIDList , m_URL(get_management_url(game)) , m_SubModule(subModule) , m_NexusGameID(game->nexusGameID()) + , m_GameName(game->gameShortName()) , m_Endorse(false) {} @@ -662,5 +695,6 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID , m_URL(get_management_url(game)) , m_SubModule(subModule) , m_NexusGameID(game->nexusGameID()) + , m_GameName(game->gameShortName()) , m_Endorse(false) {} diff --git a/src/nexusinterface.h b/src/nexusinterface.h index 9e7f3642..9a01c5c5 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include @@ -53,7 +54,7 @@ class NexusBridge : public MOBase::IModRepositoryBridge public: - NexusBridge(const QString &subModule = ""); + NexusBridge(PluginContainer *pluginContainer, const QString &subModule = ""); /** * @brief request description for a mod @@ -62,7 +63,7 @@ public: * @param userData user data to be returned with the result * @param url the url to request from **/ - virtual void requestDescription(int modID, QVariant userData); + virtual void requestDescription(QString gameName, int modID, QVariant userData); /** * @brief request a list of the files belonging to a mod @@ -70,7 +71,7 @@ public: * @param modID id of the mod caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestFiles(int modID, QVariant userData); + virtual void requestFiles(QString gameName, int modID, QVariant userData); /** * @brief request info about a single file of a mod @@ -79,7 +80,7 @@ public: * @param fileID id of the file the caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestFileInfo(int modID, int fileID, QVariant userData); + virtual void requestFileInfo(QString gameName, int modID, int fileID, QVariant userData); /** * @brief request the download url of a file @@ -88,23 +89,23 @@ public: * @param fileID id of the file the caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestDownloadURL(int modID, int fileID, QVariant userData); + virtual void requestDownloadURL(QString gameName, int modID, int fileID, QVariant userData); /** * @brief requestToggleEndorsement * @param modID id of the mod caller is interested in * @param userData user data to be returned with the result */ - virtual void requestToggleEndorsement(int modID, bool endorse, QVariant userData); + virtual void requestToggleEndorsement(QString gameName, int modID, bool endorse, QVariant userData); public slots: - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage); + void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + 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 nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage); private: @@ -130,7 +131,7 @@ public: ~NexusInterface(); - static NexusInterface *instance(); + static NexusInterface *instance(PluginContainer *pluginContainer); /** * @return the access manager object used to connect to nexus @@ -155,9 +156,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule) + int requestDescription(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule) { - return requestDescription(modID, receiver, userData, subModule, m_Game); + return requestDescription(gameName, modID, receiver, userData, subModule, getGame(gameName)); } /** @@ -169,21 +170,9 @@ public: * @param game Game with which the mod is associated * @return int an id to identify the request **/ - int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule, + int requestDescription(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); - /** - * @brief request nexus descriptions for multiple mods at once - * @param modIDs a list of ids of mods the caller is interested in (assumed to be for the current game) - * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable) - * @param userData user data to be returned with the result - * @return int an id to identify the request - */ - int requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, const QString &subModule) - { - return requestUpdates(modIDs, receiver, userData, subModule, m_Game); - } - /** * @brief request nexus descriptions for multiple mods at once * @param modIDs a list of ids of mods the caller is interested in @@ -192,8 +181,7 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request */ - int requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, const QString &subModule, - MOBase::IPluginGame const *game); + int requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, QString gameName, const QString &subModule); /** * @brief request a list of the files belonging to a mod @@ -203,9 +191,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule) + int requestFiles(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule) { - return requestFiles(modID, receiver, userData, subModule, m_Game); + return requestFiles(gameName, modID, receiver, userData, subModule, getGame(gameName)); } @@ -218,35 +206,20 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request **/ - int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule, + int requestFiles(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); /** * @brief request info about a single file of a mod * + * @param game name of the game short name to request the download from * @param modID id of the mod caller is interested in (assumed to be for the current game) * @param fileID id of the file the caller is interested in * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable) * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) - { - return requestFileInfo(modID, fileID, receiver, userData, subModule, m_Game); - } - - /** - * @brief request info about a single file of a mod - * - * @param modID id of the mod caller is interested in (assumed to be for the current game) - * @param fileID id of the file the caller is interested in - * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable) - * @param userData user data to be returned with the result - * @param game the game with which the mods are associated - * @return int an id to identify the request - **/ - int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, - MOBase::IPluginGame const *game); + int requestFileInfo(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule); /** * @brief request the download url of a file @@ -257,9 +230,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) + int requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) { - return requestDownloadURL(modID, fileID, receiver, userData, subModule, m_Game); + return requestDownloadURL(gameName, modID, fileID, receiver, userData, subModule, getGame(gameName)); } /** @@ -272,7 +245,7 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request **/ - int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); + int requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); /** * @brief toggle endorsement state of the mod @@ -282,9 +255,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request */ - int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule) + int requestToggleEndorsement(QString gameName, int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule) { - return requestToggleEndorsement(modID, endorse, receiver, userData, subModule, m_Game); + return requestToggleEndorsement(gameName, modID, endorse, receiver, userData, subModule, getGame(gameName)); } /** @@ -296,7 +269,7 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request */ - int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule, + int requestToggleEndorsement(QString gameName, int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); /** @@ -342,13 +315,13 @@ public: * * Arguably, this should optionally take a gameplugin pointer */ - QString getGameURL() const; + QString getGameURL(QString gameName) const; /** * @brief Get the URL for the mod web page * @param modID */ - QString getModURL(int modID) const; + QString getModURL(int modID, QString gameName) const; /** * @brief Checks if the specified URL might correspond to a nexus mod @@ -358,19 +331,21 @@ public: */ bool isModURL(int modID, QString const &url) const; + void setPluginContainer(PluginContainer *pluginContainer); + signals: void requestNXMDownload(const QString &url); void needLogin(); - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID); + void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); void nxmUpdatesAvailable(const std::vector &modIDs, QVariant userData, QVariant resultData, int requestID); - void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString); + 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 nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString); public slots: void managedGameChanged(MOBase::IPluginGame const *game); @@ -404,6 +379,7 @@ private: QTimer *m_Timeout; QString m_URL; QString m_SubModule; + QString m_GameName; int m_NexusGameID; bool m_Reroute; int m_ID; @@ -421,10 +397,11 @@ private: private: - NexusInterface(); + NexusInterface(PluginContainer *pluginContainer); void nextRequest(); void requestFinished(std::list::iterator iter); bool requiresLogin(const NXMRequestInfo &info); + MOBase::IPluginGame *getGame(QString gameName) const; QString getOldModsURL() const; private: @@ -440,6 +417,7 @@ private: QString m_NMMVersion; MOBase::IPluginGame const *m_Game; + PluginContainer *m_PluginContainer; }; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 999c7732..3248a8e0 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -192,15 +192,15 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) , m_GameName() , m_CurrentProfile(nullptr) , m_Settings(initSettings) - , m_Updater(NexusInterface::instance()) + , m_Updater(NexusInterface::instance(m_PluginContainer)) , m_AboutToRun() , m_FinishedRun() , m_ModInstalled() - , m_ModList(this) + , m_ModList(m_PluginContainer, this) , m_PluginList(this) , m_DirectoryRefresher() , m_DirectoryStructure(new DirectoryEntry(L"data", nullptr, 0)) - , m_DownloadManager(NexusInterface::instance(), this) + , m_DownloadManager(NexusInterface::instance(m_PluginContainer), this) , m_InstallationManager() , m_RefresherThread() , m_AskForNexusPW(false) @@ -211,8 +211,8 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory()); m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers()); - NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory()); - NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion()); + NexusInterface::instance(m_PluginContainer)->setCacheDirectory(m_Settings.getCacheDirectory()); + NexusInterface::instance(m_PluginContainer)->setNMMVersion(m_Settings.getNMMVersion()); MOBase::QuestionBoxMemory::init(initSettings.fileName()); @@ -227,9 +227,9 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString))); - connect(NexusInterface::instance()->getAccessManager(), + connect(NexusInterface::instance(m_PluginContainer)->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool))); - connect(NexusInterface::instance()->getAccessManager(), + connect(NexusInterface::instance(m_PluginContainer)->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); // This seems awfully imperative @@ -241,7 +241,7 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), &m_PluginList, SLOT(managedGameChanged(MOBase::IPluginGame const *))); connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), - NexusInterface::instance(), + NexusInterface::instance(m_PluginContainer), SLOT(managedGameChanged(MOBase::IPluginGame const *))); connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter, @@ -454,7 +454,7 @@ void OrganizerCore::updateExecutablesList(QSettings &settings) // TODO this has nothing to do with executables list move to an appropriate // function! ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_Settings.displayForeign(), managedGame()); + m_PluginContainer, m_Settings.displayForeign(), managedGame()); } void OrganizerCore::setUserInterface(IUserInterface *userInterface, @@ -504,6 +504,9 @@ void OrganizerCore::connectPlugins(PluginContainer *container) m_DownloadManager.setSupportedExtensions( m_InstallationManager.getSupportedExtensions()); m_PluginContainer = container; + m_Updater.setPluginContainer(m_PluginContainer); + m_DownloadManager.setPluginContainer(m_PluginContainer); + m_ModList.setPluginContainer(m_PluginContainer); if (!m_GameName.isEmpty()) { m_GamePlugin = m_PluginContainer->managedGame(m_GameName); @@ -518,6 +521,9 @@ void OrganizerCore::disconnectPlugins() m_ModInstalled.disconnect_all_slots(); m_ModList.disconnectSlots(); m_PluginList.disconnectSlots(); + m_Updater.setPluginContainer(nullptr); + m_DownloadManager.setPluginContainer(nullptr); + m_ModList.setPluginContainer(nullptr); m_Settings.clearPlugins(); m_GamePlugin = nullptr; @@ -540,7 +546,7 @@ Settings &OrganizerCore::settings() bool OrganizerCore::nexusLogin(bool retry) { NXMAccessManager *accessManager - = NexusInterface::instance()->getAccessManager(); + = NexusInterface::instance(m_PluginContainer)->getAccessManager(); if ((accessManager->loginAttempted() || accessManager->loggedIn()) && !retry) { @@ -612,12 +618,12 @@ void OrganizerCore::externalMessage(const QString &message) } } -void OrganizerCore::downloadRequested(QNetworkReply *reply, int modID, +void OrganizerCore::downloadRequested(QNetworkReply *reply, QString gameName, int modID, const QString &fileName) { try { - if (m_DownloadManager.addDownload(reply, QStringList(), fileName, modID, 0, - new ModRepositoryFileInfo(modID))) { + if (m_DownloadManager.addDownload(reply, QStringList(), fileName, gameName, modID, 0, + new ModRepositoryFileInfo(gameName, modID))) { MessageDialog::showMessage(tr("Download started"), qApp->activeWindow()); } } catch (const std::exception &e) { @@ -739,7 +745,7 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const { - return new NexusBridge(); + return new NexusBridge(m_PluginContainer); } QString OrganizerCore::profileName() const @@ -813,7 +819,7 @@ MOBase::IModInterface *OrganizerCore::createMod(GuessedValue &name) settingsFile.endArray(); } - return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure) + return ModInfo::createFrom(m_PluginContainer, m_GamePlugin->gameShortName(), QDir(targetDirectory), &m_DirectoryStructure) .data(); } @@ -1552,7 +1558,7 @@ void OrganizerCore::refreshModList(bool saveChanges) m_CurrentProfile->writeModlistNow(true); } ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_Settings.displayForeign(), managedGame()); + m_PluginContainer, m_Settings.displayForeign(), managedGame()); m_CurrentProfile->refreshModStatus(); @@ -1719,8 +1725,13 @@ void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply) // no mod found that could handle the download. Is it a nexus mod? if (url.host() == "www.nexusmods.com") { + QString gameName = ""; int modID = 0; int fileID = 0; + QRegExp nameExp("www\.nexusmods\.com/(\\a+)/"); + if (nameExp.indexIn(url.toString()) != -1) { + gameName = nameExp.cap(1); + } QRegExp modExp("mods/(\\d+)"); if (modExp.indexIn(url.toString()) != -1) { modID = modExp.cap(1).toInt(); @@ -1730,7 +1741,7 @@ void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply) fileID = fileExp.cap(1).toInt(); } m_DownloadManager.addDownload(reply, - new ModRepositoryFileInfo(modID, fileID)); + new ModRepositoryFileInfo(gameName, modID, fileID)); } else { if (QMessageBox::question(qApp->activeWindow(), tr("Download?"), tr("A download has been started but no installed " @@ -1827,7 +1838,7 @@ void OrganizerCore::profileRefresh() // have to refresh mods twice (again in refreshModList), otherwise the refresh // isn't complete. Not sure why ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_Settings.displayForeign(), managedGame()); + m_PluginContainer, m_Settings.displayForeign(), managedGame()); m_CurrentProfile->refreshModStatus(); refreshModList(); @@ -1885,7 +1896,7 @@ void OrganizerCore::loginSuccessful(bool necessary) } m_PostLoginTasks.clear(); - NexusInterface::instance()->loginCompleted(); + NexusInterface::instance(m_PluginContainer)->loginCompleted(); } void OrganizerCore::loginSuccessfulUpdate(bool necessary) @@ -1920,7 +1931,7 @@ void OrganizerCore::loginFailed(const QString &message) qApp->activeWindow()); m_PostLoginTasks.clear(); } - NexusInterface::instance()->loginCompleted(); + NexusInterface::instance(m_PluginContainer)->loginCompleted(); } void OrganizerCore::loginFailedUpdate(const QString &message) diff --git a/src/organizercore.h b/src/organizercore.h index 54d9dd6d..76c286be 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -285,7 +285,7 @@ private: private slots: void directory_refreshed(); - void downloadRequested(QNetworkReply *reply, int modID, const QString &fileName); + void downloadRequested(QNetworkReply *reply, QString gameName, int modID, const QString &fileName); void removeOrigin(const QString &name); void downloadSpeed(const QString &serverName, int bytesPerSecond); void loginSuccessful(bool necessary); diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index cf2e29e3..77d61a52 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -2,6 +2,7 @@ #include "appconfig.h" #include "organizercore.h" +#include "plugincontainer.h" #include @@ -9,15 +10,16 @@ using namespace MOBase; using namespace MOShared; -OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, const QString &pluginName) +OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, const QString &pluginName) : m_Proxied(organizer) + , m_PluginContainer(pluginContainer) , m_PluginName(pluginName) { } IModRepositoryBridge *OrganizerProxy::createNexusBridge() const { - return new NexusBridge(m_PluginName); + return new NexusBridge(m_PluginContainer, m_PluginName); } QString OrganizerProxy::profileName() const diff --git a/src/organizerproxy.h b/src/organizerproxy.h index 7004db14..cebb98ac 100644 --- a/src/organizerproxy.h +++ b/src/organizerproxy.h @@ -5,13 +5,14 @@ #include class OrganizerCore; +class PluginContainer; class OrganizerProxy : public MOBase::IOrganizer { public: - OrganizerProxy(OrganizerCore *organizer, const QString &pluginName); + OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, const QString &pluginName); virtual MOBase::IModRepositoryBridge *createNexusBridge() const; virtual QString profileName() const; @@ -55,6 +56,7 @@ public: private: OrganizerCore *m_Proxied; + PluginContainer *m_PluginContainer; const QString &m_PluginName; diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 60d1130c..f6376496 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -1,4 +1,5 @@ #include "plugincontainer.h" +#include "organizercore.h" #include "organizerproxy.h" #include "report.h" #include @@ -67,7 +68,7 @@ bool PluginContainer::verifyPlugin(IPlugin *plugin) { if (plugin == nullptr) { return false; - } else if (!plugin->init(new OrganizerProxy(m_Organizer, plugin->name()))) { + } else if (!plugin->init(new OrganizerProxy(m_Organizer, this, plugin->name()))) { qWarning("plugin failed to initialize"); return false; } diff --git a/src/plugincontainer.h b/src/plugincontainer.h index 70392d0b..172dbd09 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -1,9 +1,11 @@ #ifndef PLUGINCONTAINER_H #define PLUGINCONTAINER_H - -#include "organizercore.h" #include "previewgenerator.h" + +class OrganizerCore; +class IUserInterface; + #include #include #include diff --git a/src/profile.cpp b/src/profile.cpp index bbb5b814..7f10bd02 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -753,6 +753,7 @@ bool Profile::enableLocalSettings(bool enable) QString backupFile = getIniFileName() + "_"; if (enable) { if (m_Directory.exists(backupFile)) { + shellRename(backupFile, getIniFileName()); } else { IPluginGame *game = qApp->property("managed_game").value(); diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 8f962ba4..debf9106 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -30,6 +30,7 @@ along with Mod Organizer. If not, see . #include "nxmaccessmanager.h" #include "settings.h" #include "bbcode.h" +#include "plugincontainer.h" #include #include #include @@ -120,6 +121,11 @@ void SelfUpdater::setUserInterface(QWidget *widget) m_Parent = widget; } +void SelfUpdater::setPluginContainer(PluginContainer *pluginContainer) +{ + m_Interface->setPluginContainer(pluginContainer); +} + void SelfUpdater::testForUpdate() { // TODO: if prereleases are disabled we could just request the latest release diff --git a/src/selfupdater.h b/src/selfupdater.h index 4743f6a4..bce49495 100644 --- a/src/selfupdater.h +++ b/src/selfupdater.h @@ -26,6 +26,7 @@ along with Mod Organizer. If not, see . class Archive; class NexusInterface; +class PluginContainer; namespace MOBase { class IPluginGame; } #include @@ -77,6 +78,8 @@ public: void setUserInterface(QWidget *widget); + void setPluginContainer(PluginContainer *pluginContainer); + /** * @brief start the update process * @note this should not be called if there is no update available diff --git a/src/settings.cpp b/src/settings.cpp index d1130e05..9510999d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -584,9 +584,9 @@ void Settings::resetDialogs() } -void Settings::query(QWidget *parent) +void Settings::query(PluginContainer *pluginContainer, QWidget *parent) { - SettingsDialog dialog(parent); + SettingsDialog dialog(pluginContainer, parent); connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs())); diff --git a/src/settings.h b/src/settings.h index ae38223f..76ab55da 100644 --- a/src/settings.h +++ b/src/settings.h @@ -51,6 +51,7 @@ namespace MOBase { } class SettingsDialog; +class PluginContainer; /** * manages the settings for Mod Organizer. The settings are not cached @@ -88,7 +89,7 @@ public: * displays a SettingsDialog that allows the user to change settings. If the * user accepts the changes, the settings are immediately written **/ - void query(QWidget *parent); + void query(PluginContainer *pluginContainer, QWidget *parent); /** * set up the settings for the specified plugins diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index fb9433a6..a4071c26 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -27,6 +27,7 @@ along with Mod Organizer. If not, see . #include "settings.h" #include "instancemanager.h" #include "nexusinterface.h" +#include "plugincontainer.h" #include #include @@ -40,9 +41,10 @@ along with Mod Organizer. If not, see . using namespace MOBase; -SettingsDialog::SettingsDialog(QWidget *parent) +SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, QWidget *parent) : TutorableDialog("SettingsDialog", parent) , ui(new Ui::SettingsDialog) + , m_PluginContainer(pluginContainer) { ui->setupUi(this); @@ -252,6 +254,6 @@ void SettingsDialog::on_associateButton_clicked() void SettingsDialog::on_clearCacheButton_clicked() { QDir(Settings::instance().getCacheDirectory()).removeRecursively(); - NexusInterface::instance()->clearCache(); + NexusInterface::instance(m_PluginContainer)->clearCache(); } diff --git a/src/settingsdialog.h b/src/settingsdialog.h index e9d995d3..32a8d0c5 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -25,6 +25,8 @@ along with Mod Organizer. If not, see . #include #include +class PluginContainer; + namespace Ui { class SettingsDialog; } @@ -39,7 +41,7 @@ class SettingsDialog : public MOBase::TutorableDialog Q_OBJECT public: - explicit SettingsDialog(QWidget *parent = 0); + explicit SettingsDialog(PluginContainer *pluginContainer, QWidget *parent = 0); ~SettingsDialog(); void addPlugins(const std::vector &plugins); @@ -87,7 +89,7 @@ private slots: private: Ui::SettingsDialog *ui; - + PluginContainer *m_PluginContainer; }; -- cgit v1.3.1