From 549b84b0f8815737c93913b200dde3821a062cb0 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Sat, 16 May 2026 19:51:40 -0500 Subject: mo2: catch up to upstream 2.5.3 Betas 3-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 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 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) --- .../src/games/starfield/starfieldgameplugins.cpp | 74 +++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) (limited to 'libs/game_bethesda/src/games/starfield/starfieldgameplugins.cpp') diff --git a/libs/game_bethesda/src/games/starfield/starfieldgameplugins.cpp b/libs/game_bethesda/src/games/starfield/starfieldgameplugins.cpp index 6b4e6ab..efd1bad 100644 --- a/libs/game_bethesda/src/games/starfield/starfieldgameplugins.cpp +++ b/libs/game_bethesda/src/games/starfield/starfieldgameplugins.cpp @@ -1,5 +1,9 @@ #include "starfieldgameplugins.h" +#include +#include +#include + using namespace MOBase; StarfieldGamePlugins::StarfieldGamePlugins(MOBase::IOrganizer* organizer) @@ -19,10 +23,76 @@ bool StarfieldGamePlugins::blueprintPluginsAreSupported() void StarfieldGamePlugins::writePluginList(const IPluginList* pluginList, const QString& filePath) { - if (m_Organizer->managedGame()->loadOrderMechanism() == + if (m_Organizer->managedGame()->loadOrderMechanism() != MOBase::IPluginGame::LoadOrderMechanism::PluginsTxt) { - CreationGamePlugins::writePluginList(pluginList, filePath); + return; + } + + SafeWriteFile file(filePath); + + QStringEncoder encoder(QStringConverter::Encoding::System); + + file->resize(0); + + file->write(encoder.encode( + "# This file was automatically generated by Mod Organizer.\r\n")); + + bool invalidFileNames = false; + int writtenCount = 0; + + QStringList plugins = pluginList->pluginNames(); + std::sort(plugins.begin(), plugins.end(), + [pluginList](const QString& lhs, const QString& rhs) { + return pluginList->priority(lhs) < pluginList->priority(rhs); + }); + + QStringList PrimaryPlugins = organizer()->managedGame()->primaryPlugins(); + QStringList DLCPlugins = organizer()->managedGame()->DLCPlugins(); + QSet ManagedMods = + QSet(PrimaryPlugins.begin(), PrimaryPlugins.end()); + QSet DLCSet = QSet(DLCPlugins.begin(), DLCPlugins.end()); + ManagedMods.subtract(DLCSet); + PrimaryPlugins.append(QList(ManagedMods.begin(), ManagedMods.end())); + + // TODO: do not write plugins in OFFICIAL_FILES container + for (const QString& pluginName : plugins) { + if (!PrimaryPlugins.contains(pluginName, Qt::CaseInsensitive) && + !pluginList->isBlueprintFlagged(pluginName) && + !pluginName.startsWith(m_Organizer->managedGame()->blueprintPrefix(), + Qt::CaseInsensitive)) { + if (pluginList->state(pluginName) == IPluginList::STATE_ACTIVE) { + auto result = encoder.encode(pluginName); + if (encoder.hasError()) { + invalidFileNames = true; + qCritical("invalid plugin name %s", qUtf8Printable(pluginName)); + } else { + file->write("*"); + file->write(result); + } + file->write("\r\n"); + ++writtenCount; + } else { + auto result = encoder.encode(pluginName); + if (encoder.hasError()) { + invalidFileNames = true; + qCritical("invalid plugin name %s", qUtf8Printable(pluginName)); + } else { + file->write(result); + } + file->write("\r\n"); + ++writtenCount; + } + } } + + if (invalidFileNames) { + reportError(QObject::tr("Some of your plugins have invalid names! These " + "plugins can not be loaded by the game. Please see " + "mo_interface.log for a list of affected plugins " + "and rename them.")); + } + + file->commit(); } QStringList StarfieldGamePlugins::readPluginList(MOBase::IPluginList* pluginList) -- cgit v1.3.1