From 5769638d5c2a32d452610319e0488d3af35fefc3 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Wed, 11 Mar 2026 16:51:28 -0500 Subject: Fix LOOT disabling plugins: handle Bethesda asterisk format in plugins.txt LOOT writes plugins.txt in Bethesda format where *Plugin.esp = enabled and Plugin.esp (no prefix) = disabled. MO2's reader didn't strip the asterisk, so it tried to find plugins literally named "*Plugin.esp", failed to match, and marked them all as inactive. Two-pass approach: detect whether file uses asterisks. If yes (LOOT/Bethesda format), only *-prefixed plugins are active. If no (MO2's own format), all listed plugins are active. Co-Authored-By: Claude Opus 4.6 --- .../src/gamebryo/gamebryogameplugins.cpp | 36 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'libs/game_bethesda/src/*.cpp') diff --git a/libs/game_bethesda/src/gamebryo/gamebryogameplugins.cpp b/libs/game_bethesda/src/gamebryo/gamebryogameplugins.cpp index 1accc4f..78535a1 100644 --- a/libs/game_bethesda/src/gamebryo/gamebryogameplugins.cpp +++ b/libs/game_bethesda/src/gamebryo/gamebryogameplugins.cpp @@ -218,16 +218,40 @@ QStringList GamebryoGamePlugins::readPluginList(MOBase::IPluginList* pluginList) QStringList activePlugins; if (pluginsTxtExists) { + // Two-pass read: first detect whether the file uses the Bethesda/LOOT + // asterisk format (*Plugin.esp = enabled, Plugin.esp = disabled) vs + // MO2's own format (only active plugins listed, no asterisks). + struct PluginEntry { + QString name; + bool hadAsterisk; + }; + QList entries; + bool hasAsterisks = false; + while (!file.atEnd()) { QByteArray line = file.readLine(); - QString pluginName; - if ((line.size() > 0) && (line.at(0) != '#')) { + if (line.size() > 0 && line.at(0) != '#') { QStringEncoder encoder(QStringConverter::Encoding::System); - pluginName = encoder.encode(line.trimmed().constData()); + QString pluginName = encoder.encode(line.trimmed().constData()); + bool asterisk = false; + if (pluginName.startsWith('*')) { + pluginName = pluginName.mid(1); + asterisk = true; + hasAsterisks = true; + } + if (!pluginName.isEmpty()) { + entries.append({pluginName, asterisk}); + } } - if (pluginName.size() > 0) { - pluginList->setState(pluginName, IPluginList::STATE_ACTIVE); - activePlugins.push_back(pluginName); + } + + // If file uses asterisks (LOOT/Bethesda format): only *-prefixed are active. + // If no asterisks (MO2 format): all listed plugins are active. + for (const auto& entry : entries) { + bool isActive = hasAsterisks ? entry.hadAsterisk : true; + if (isActive) { + pluginList->setState(entry.name, IPluginList::STATE_ACTIVE); + activePlugins.push_back(entry.name); } } -- cgit v1.3.1