aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-15 05:44:36 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-15 05:44:36 -0500
commit4e41d1c7b789cae96441f98d51fcc7428488768d (patch)
treed8e70a3fdf5ce460bf60e3d581e883fdc86c5246 /src
parent1b4dd1b718d543a2b6bf29e3209629542744babf (diff)
Fix NXM handler rejecting nexusmods.com/site tool downloads
Tools like BethINI Pie use the "site" game domain on Nexus, which has no matching game plugin. Previously this triggered the "Wrong Game" error. Now "site" (and any other domain with no plugin) is allowed: - downloadmanager: detect "site" NXM links and allow download using managed game as context; propagate raw game name ("site") through pending tracking and API requests for correct Nexus API URLs - downloadmanager: in nxmFileInfoAvailable, default info->gameName to the raw game name before plugin lookup so "site" is preserved when no matching plugin is found - nexusinterface: override m_GameName with raw game name in both requestFileInfo and requestDownloadURL when the plugin is a fallback (i.e. doesn't actually match the requested game domain) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src')
-rw-r--r--src/src/downloadmanager.cpp43
-rw-r--r--src/src/nexusinterface.cpp11
2 files changed, 41 insertions, 13 deletions
diff --git a/src/src/downloadmanager.cpp b/src/src/downloadmanager.cpp
index 457a58e..3e2bbb3 100644
--- a/src/src/downloadmanager.cpp
+++ b/src/src/downloadmanager.cpp
@@ -700,21 +700,34 @@ void DownloadManager::addNXMDownload(const QString& url)
}
}
log::debug("add nxm download: {}", url);
+ // The Nexus API game name to use for requests (may differ from foundGame's short name
+ // for special domains like "site" that have no matching game plugin).
+ QString apiGameName;
if (foundGame == nullptr) {
- log::debug("download requested for wrong game (game: {}, url: {})",
- m_ManagedGame->gameShortName(), nxmInfo.game());
- QMessageBox::information(
- m_ParentWidget, 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(m_ManagedGame->gameShortName()),
- QMessageBox::Ok);
- return;
+ // "site" is Nexus Mods' game-agnostic domain for tools/utilities (e.g. BethINI Pie).
+ // Allow these downloads using the current managed game's API context.
+ if (nxmInfo.game().compare("site", Qt::CaseInsensitive) == 0) {
+ log::debug("NXM link is for nexusmods.com/site (game-agnostic tool), allowing download");
+ foundGame = m_ManagedGame;
+ apiGameName = nxmInfo.game(); // keep "site" for correct API URLs
+ } else {
+ log::debug("download requested for wrong game (game: {}, url: {})",
+ m_ManagedGame->gameShortName(), nxmInfo.game());
+ QMessageBox::information(
+ m_ParentWidget, 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(m_ManagedGame->gameShortName()),
+ QMessageBox::Ok);
+ return;
+ }
+ } else {
+ apiGameName = foundGame->gameShortName();
}
for (auto tuple : m_PendingDownloads) {
- if (std::get<0>(tuple).compare(foundGame->gameShortName(), Qt::CaseInsensitive) ==
+ if (std::get<0>(tuple).compare(apiGameName, Qt::CaseInsensitive) ==
0,
std::get<1>(tuple) == nxmInfo.modId() &&
std::get<2>(tuple) == nxmInfo.fileId()) {
@@ -785,7 +798,7 @@ void DownloadManager::addNXMDownload(const QString& url)
emit aboutToUpdate();
m_PendingDownloads.append(
- std::make_tuple(foundGame->gameShortName(), nxmInfo.modId(), nxmInfo.fileId()));
+ std::make_tuple(apiGameName, nxmInfo.modId(), nxmInfo.fileId()));
emit update(-1);
emit downloadAdded();
@@ -797,7 +810,7 @@ void DownloadManager::addNXMDownload(const QString& url)
QObject* test = info;
m_RequestIDs.insert(m_NexusInterface->requestFileInfo(
- foundGame->gameShortName(), nxmInfo.modId(), nxmInfo.fileId(), this,
+ apiGameName, nxmInfo.modId(), nxmInfo.fileId(), this,
QVariant::fromValue(test), ""));
}
@@ -1929,6 +1942,9 @@ void DownloadManager::nxmFileInfoAvailable(QString gameName, int modID, int file
info->repository = "Nexus";
+ // Default to the raw game name; overridden below if a matching plugin is found.
+ // This preserves special domains like "site" that have no game plugin.
+ info->gameName = gameName;
QStringList games(m_ManagedGame->validShortNames());
games += m_ManagedGame->gameShortName();
for (auto game : games) {
@@ -1936,6 +1952,7 @@ void DownloadManager::nxmFileInfoAvailable(QString gameName, int modID, int file
if (gamePlugin != nullptr &&
gamePlugin->gameNexusName().compare(gameName, Qt::CaseInsensitive) == 0) {
info->gameName = gamePlugin->gameShortName();
+ break;
}
}
diff --git a/src/src/nexusinterface.cpp b/src/src/nexusinterface.cpp
index 3dd1030..ff0a58c 100644
--- a/src/src/nexusinterface.cpp
+++ b/src/src/nexusinterface.cpp
@@ -625,6 +625,12 @@ int NexusInterface::requestFileInfo(QString gameName, int modID, int fileID,
NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData,
subModule, gamePlugin);
+ // If the game plugin was a fallback (managed game), the NXM game name may be a
+ // different domain (e.g. "site" for Nexus tools). Override so the API URL is correct.
+ if (gamePlugin->gameShortName().compare(gameName, Qt::CaseInsensitive) != 0 &&
+ gamePlugin->gameNexusName().compare(gameName, Qt::CaseInsensitive) != 0) {
+ requestInfo.m_GameName = gameName.toLower();
+ }
m_RequestQueue.enqueue(requestInfo);
connect(
@@ -648,6 +654,11 @@ int NexusInterface::requestDownloadURL(QString gameName, int modID, int fileID,
{
NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData,
subModule, game);
+ // Override game name if the plugin was a fallback (e.g. "site" has no game plugin)
+ if (game && game->gameShortName().compare(gameName, Qt::CaseInsensitive) != 0 &&
+ game->gameNexusName().compare(gameName, Qt::CaseInsensitive) != 0) {
+ requestInfo.m_GameName = gameName.toLower();
+ }
m_RequestQueue.enqueue(requestInfo);
connect(this,