diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-05-16 19:51:40 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-05-16 19:51:40 -0500 |
| commit | 549b84b0f8815737c93913b200dde3821a062cb0 (patch) | |
| tree | f6bfd96729016847438beda9416c93f447838077 /libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp | |
| parent | a0747cabb420d699be3a1dd4c63f47c5153bd7b9 (diff) | |
mo2: catch up to upstream 2.5.3 Betas 3-11
Multi-area sync against the upstream MO2 2.5.3 beta line. Roughly three
logical sections share the diff:
Catch-up (Betas 3-11):
- nxmaccessmanager: drop "supporter" from validRoles so non-premium
supporters get the right download path (Beta 10)
- mainwindow: disable tutorial triggers at the trigger sites; Qt 6.11
lockup on child windows (Beta 4)
- basic_games: add Kingdom Come Deliverance 2, Slay the Spire 2
(Betas 11, 6)
- uibase: add NXM collections parsing fields/accessors + (?:nxm|modl)
scheme support in NXMUrl (Beta 9)
- Starfield: blueprintPrefix() on IPluginGame; plugins.txt write
suppression for blueprint plugins; hasInvalidBlueprint /
hasUnpairedBlueprint diagnoses; Title-keyed content catalog
consolidation (Betas 3-5)
- downloadmanager + systemtraymanager + organizercore + iuserinterface
+ settings: add Beta 11 "show notifications when downloads complete
or fail" toggle and the showNotification plumbing
- nxmaccessmanager: restore upstream re-entry guard for OAuth refresh
and the styled OAuth response page (Beta 11)
- organizer_en.ts and game-bethesda *_en.ts: pull upstream HEAD strings
Workarounds tab removed:
- Delete settingsdialogworkarounds.{h,cpp}; drop the tab in
settingsdialog.ui; move "Enable archives parsing" into General
- Hardcode GameSettings::forceEnableCoreFiles() to true so the
primary-master toggle-off bug (DLCs unchecked on tab refresh) can't
recur; setter becomes a no-op
- No-op stubs for offlineMode, useProxy, useCustomBrowser, Steam
appID/credentials, executablesBlacklist, skipFileSuffixes,
skipDirectories — UI gone, accessors keep call sites green
- settingsdialognexus drops the custom-browser wiring; spawn drops the
"Change the blacklist" Retry path
Beta 9 download manager port:
- fileID-first match in nxmFilesAvailable and
nxmFileInfoFromMd5Available; filename remains the fallback
- NexusInterface::isActiveFileStatus() helper; rewrite of
nxmUpdatesAvailable to use pickNewestVersion /
findUpdateChainSuccessors / resolveInstalledFileId. ARCHIVED_HIDDEN
now correctly treated as inactive
- std::optional<unsigned int> reservedID on DownloadInfo factories and
on the three addDownload overloads; startDownloadURLs and
startDownloadURLWithMeta return the canonical DownloadID instead of
m_ActiveDownloads.size()-1 (which was the index, not an ID)
- QHash<unsigned int, DownloadInfo*> m_ByID maintained alongside
m_ActiveDownloads at every mutation site; downloadInfoByID is now
O(1) via m_ByID.value(id, nullptr)
LOOT remains intentionally stripped (lootcli build cruft cleaned up
separately). BSA wide-path skipped — Linux UTF-8 paths already work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp')
| -rw-r--r-- | libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp b/libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp index 30abb38..82207c3 100644 --- a/libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp +++ b/libs/game_bethesda/src/games/starfield/starfieldunmanagedmods.cpp @@ -9,7 +9,7 @@ StarfieldUnmanagedMods::StarfieldUnmanagedMods(const GameStarfield* game, const QString& appDataFolder) - : GamebryoUnmangedMods(game), m_AppDataFolder(appDataFolder) + : GamebryoUnmangedMods(game), m_Game(game), m_AppDataFolder(appDataFolder) {} StarfieldUnmanagedMods::~StarfieldUnmanagedMods() {} @@ -25,29 +25,52 @@ QStringList StarfieldUnmanagedMods::mods(bool onlyOfficial) const pluginList.removeAll(plugin); } QMap<QString, QDir> directories = {{"data", game()->dataDirectory()}}; + auto contentCatalog = parseContentCatalog(); directories.insert(game()->secondaryDataDirectories()); for (QDir directory : directories) { for (const QString& fileName : directory.entryList({"*.esp", "*.esl", "*.esm"})) { if (!pluginList.contains(fileName, Qt::CaseInsensitive)) { if (!onlyOfficial || pluginList.contains(fileName, Qt::CaseInsensitive)) { - result.append(fileName.chopped(4)); // trims the extension off + bool found = false; + for (const auto& mod : contentCatalog) { + if (mod.second.files.contains(fileName, Qt::CaseInsensitive)) { + result.append(mod.second.name); + found = true; + } + } + if (!found && !fileName.startsWith("blueprintships-", Qt::CaseInsensitive)) { + result.append(fileName.chopped(4)); // trims the extension off + } } } } } - + result.removeDuplicates(); return result; } QFileInfo StarfieldUnmanagedMods::referenceFile(const QString& modName) const { - QFileInfoList files; + QStringList modFiles; + auto contentCatalog = parseContentCatalog(); + if (contentCatalog.contains(modName)) { + modFiles = contentCatalog[modName].files; + } + QDir dataDir = m_Game->secondaryDataDirectories().first(); + QStringList plugins = modFiles.filter( + QRegularExpression("\\.es(m|p|l)$", QRegularExpression::CaseInsensitiveOption)); QMap<QString, QDir> directories = {{"data", game()->dataDirectory()}}; directories.insert(game()->secondaryDataDirectories()); + QFileInfoList pluginFiles; + QFileInfoList files; for (QDir directory : directories) { + if (!plugins.isEmpty()) + pluginFiles += dataDir.entryInfoList(plugins); files += directory.entryInfoList(QStringList() << modName + ".es*"); } - if (files.size() > 0) { + if (!pluginFiles.isEmpty()) { + return pluginFiles.at(0); + } else if (!files.isEmpty()) { return files.at(0); } else { return QFileInfo(); @@ -86,11 +109,10 @@ StarfieldUnmanagedMods::parseContentCatalog() const pluginList.append(fileName); } } - for (const auto& plugin : pluginList) { - contentCatalog[plugin] = ContentCatalog(); - contentCatalog[plugin].files = files; - contentCatalog[plugin].name = modInfo.value("Title").toString(); - } + QString name = modInfo.value("Title").toString(); + contentCatalog[name] = ContentCatalog(); + contentCatalog[name].files = files; + contentCatalog[name].name = name; } } } @@ -101,17 +123,16 @@ QStringList StarfieldUnmanagedMods::secondaryFiles(const QString& modName) const { QStringList files; auto contentCatalog = parseContentCatalog(); - for (const auto& mod : contentCatalog) { - if (mod.first.startsWith(modName, Qt::CaseInsensitive)) { - files += mod.second.files; - break; - } + if (contentCatalog.contains(modName)) { + return contentCatalog[modName].files; } // file extension in FO4 is .ba2 instead of bsa QMap<QString, QDir> directories = {{"data", game()->dataDirectory()}}; directories.insert(game()->secondaryDataDirectories()); for (QDir directory : directories) { - for (const QString& archiveName : directory.entryList({modName + "*.ba2"})) { + for (const QString& archiveName : + directory.entryList({modName + "*.ba2", "blueprintships-" + modName + ".esm", + "blueprintships-" + modName + "*.ba2"})) { files.append(directory.absoluteFilePath(archiveName)); } } @@ -121,12 +142,12 @@ QStringList StarfieldUnmanagedMods::secondaryFiles(const QString& modName) const QString StarfieldUnmanagedMods::displayName(const QString& modName) const { auto contentCatalog = parseContentCatalog(); - for (const auto& mod : contentCatalog) { - if (mod.first.startsWith(modName, Qt::CaseInsensitive)) { - return mod.second.name; - } + if (contentCatalog.contains(modName)) { + return contentCatalog[modName].name; } - // unlike in earlier games, in fallout 4 the file name doesn't correspond to - // the public name + if (modName == "ShatteredSpace") + return "Shattered Space"; + else if (modName == "SFBGS050") + return "Terran Armada"; return modName; } |
