From 083d1078753698b5ff347d91aa17219fd1e1cb5a Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Wed, 13 Dec 2017 03:11:03 -0600 Subject: A number of improvements and fixes * Move diagnostics tab to un-break tutorials targeting tab 3 * Restrict order locking for force-enabled plugins * Cascade locked positions in the case of a conflict * Should remove existing invalid locks * Add some info to primary plugins in plugin list * Differentiate plugin names for DLC and CC content --- src/modinfo.cpp | 7 +- src/modinfo.h | 9 +- src/modinfoforeign.cpp | 12 +- src/modinfoforeign.h | 2 +- src/pluginlist.cpp | 30 +++- src/settingsdialog.ui | 364 ++++++++++++++++++++++++------------------------- 6 files changed, 235 insertions(+), 189 deletions(-) (limited to 'src') diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 77df6216..4f74086f 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -79,10 +79,11 @@ ModInfo::Ptr ModInfo::createFrom(const QDir &dir, DirectoryEntry **directoryStru ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, + ModInfo::EModType modType, DirectoryEntry **directoryStructure) { QMutexLocker locker(&s_Mutex); ModInfo::Ptr result = ModInfo::Ptr( - new ModInfoForeign(modName, espName, bsaNames, directoryStructure)); + new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure)); s_Collection.push_back(result); return result; } @@ -224,9 +225,13 @@ void ModInfo::updateFromDisc(const QString &modDirectory, UnmanagedMods *unmanaged = game->feature(); if (unmanaged != nullptr) { for (const QString &modName : unmanaged->mods(!displayForeign)) { + ModInfo::EModType modType = game->DLCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive) ? ModInfo::EModType::MOD_DLC : + (game->CCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive) ? ModInfo::EModType::MOD_CC : ModInfo::EModType::MOD_DEFAULT); + createFromPlugin(unmanaged->displayName(modName), unmanaged->referenceFile(modName).absoluteFilePath(), unmanaged->secondaryFiles(modName), + modType, directoryStructure); } } diff --git a/src/modinfo.h b/src/modinfo.h index c62df549..0bdf6e43 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -101,6 +101,13 @@ public: ENDORSED_NEVER }; + enum EModType { + MOD_DEFAULT, + MOD_DLC, + MOD_CC + }; + + public: /** @@ -189,7 +196,7 @@ public: * @param bsaNames names of archives * @return a new mod */ - static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, MOShared::DirectoryEntry **directoryStructure); + static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure); /** * @brief retieve a name for one of the CONTENT_ enums diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp index 6ad8b6d8..0bde2c30 100644 --- a/src/modinfoforeign.cpp +++ b/src/modinfoforeign.cpp @@ -50,9 +50,19 @@ QString ModInfoForeign::getDescription() const ModInfoForeign::ModInfoForeign(const QString &modName, const QString &referenceFile, const QStringList &archives, + ModInfo::EModType modType, DirectoryEntry **directoryStructure) : ModInfoWithConflictInfo(directoryStructure), m_ReferenceFile(referenceFile), m_Archives(archives) { m_CreationTime = QFileInfo(referenceFile).created(); - m_Name = "Unmanaged: " + modName; + switch (modType) { + case ModInfo::EModType::MOD_DLC: + m_Name = "DLC: " + modName; + break; + case ModInfo::EModType::MOD_CC: + m_Name = "Creation Club: " + modName; + break; + default: + m_Name = "Unmanaged: " + modName; + } } diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h index 839bcdce..d60064f0 100644 --- a/src/modinfoforeign.h +++ b/src/modinfoforeign.h @@ -52,7 +52,7 @@ public: protected: ModInfoForeign(const QString &modName, const QString &referenceFile, - const QStringList &archives, + const QStringList &archives, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure); private: diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 61d33fe9..6392d44b 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -347,7 +347,26 @@ void PluginList::readLockedOrderFrom(const QString &fileName) if ((line.size() > 0) && (line.at(0) != '#')) { QList fields = line.split('|'); if (fields.count() == 2) { - m_LockedOrder[QString::fromUtf8(fields.at(0))] = fields.at(1).trimmed().toInt(); + int priority = fields.at(1).trimmed().toInt(); + QString name = QString::fromUtf8(fields.at(0)); + // Avoid locking a force-enabled plugin + if (!m_ESPs[m_ESPsByName.at(name)].m_ForceEnabled) { + // Is this an open and unclaimed priority? + if (m_ESPs[m_ESPsByPriority.at(priority)].m_ForceEnabled || + std::find_if(m_LockedOrder.begin(), m_LockedOrder.end(), [&](const std::pair &a) { return a.second == priority; }) != m_LockedOrder.end()) { + // Attempt to find a priority but step over force-enabled plugins and already-set locks + int calcPriority = priority; + do { + ++calcPriority; + } while (calcPriority < m_ESPsByPriority.size() || (m_ESPs[m_ESPsByPriority.at(calcPriority)].m_ForceEnabled && + std::find_if(m_LockedOrder.begin(), m_LockedOrder.end(), [&](const std::pair &a) { return a.second == calcPriority; }) != m_LockedOrder.end())); + // If we have a match, we can reassign the priority... + if (calcPriority < m_ESPsByPriority.size()) + m_LockedOrder[name] = calcPriority; + } else { + m_LockedOrder[name] = priority; + } + } } else { reportError(tr("The file containing locked plugin indices is broken")); break; @@ -467,7 +486,10 @@ bool PluginList::isESPLocked(int index) const void PluginList::lockESPIndex(int index, bool lock) { if (lock) { - m_LockedOrder[getName(index).toLower()] = m_ESPs.at(index).m_LoadOrder; + if (!m_ESPs.at(index).m_ForceEnabled) + m_LockedOrder[getName(index).toLower()] = m_ESPs.at(index).m_LoadOrder; + else + return; } else { auto iter = m_LockedOrder.find(getName(index).toLower()); if (iter != m_LockedOrder.end()) { @@ -817,7 +839,9 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const } } if (m_ESPs[index].m_ForceEnabled) { - toolTip += tr("This plugin can't be disabled (enforced by the game)"); + QString text = tr("Origin: %1").arg(m_ESPs[index].m_OriginName); + text += tr("
This plugin can't be disabled (enforced by the game)."); + toolTip += text; } else { QString text = tr("Origin: %1").arg(m_ESPs[index].m_OriginName); if (m_ESPs[index].m_Author.size() > 0) { diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 7a902748..3c47d226 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -336,188 +336,6 @@ If you use pre-releases, never contact me directly by e-mail or via private mess - - - Diagnostics - - - - - - - - Log Level - - - - - - - Decides the amount of data printed to "ModOrganizer.log" - - - - Decides the amount of data printed to "ModOrganizer.log". - "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regluar use. On the "Error" level the log file usually remains empty. - - - - - Debug - - - - - Info (recommended) - - - - - Warning - - - - - Error - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Crash Dumps - - - - - - - Decides which type of crash dumps are collected when injected processes crash. - - - - Decides which type of crash dumps are collected when injected processes crash. - "None" Disables the generation of crash dumps by MO. - "Mini" Default level which generates small dumps (only stack traces). - "Data" Much larger dumps with additional information which may be need (also data segments). - "Full" Even larger dumps with a full memory dump of the process. - - - - - None - - - - - Mini (recommended) - - - - - Data - - - - - Full - - - - - - - - - - - - Max Dumps To Keep - - - - - - - Qt::Horizontal - - - - 60 - 20 - - - - - - - - Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - - - - Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - Set "Crash Dumps" above to None to disable crash dump collection. - - - - - - - - - - - Logs and crash dumps are stored under your current instance in the <a href="LOGS_FULL_PATH">LOGS_DIR</a> - and <a href="DUMPS_FULL_PATH">DUMPS_DIR</a> folders. - Sending logs and/or crash dumps to the developers can help investigate issues. - It is recommended to compress large log and dmp files before sending. - - - - true - - - Hint: right click link and copy link location - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 232 - - - - - - Nexus @@ -1164,6 +982,188 @@ For the other games this is not a sufficient replacement for AI! + + + Diagnostics + + + + + + + + Log Level + + + + + + + Decides the amount of data printed to "ModOrganizer.log" + + + + Decides the amount of data printed to "ModOrganizer.log". + "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regluar use. On the "Error" level the log file usually remains empty. + + + + + Debug + + + + + Info (recommended) + + + + + Warning + + + + + Error + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Crash Dumps + + + + + + + Decides which type of crash dumps are collected when injected processes crash. + + + + Decides which type of crash dumps are collected when injected processes crash. + "None" Disables the generation of crash dumps by MO. + "Mini" Default level which generates small dumps (only stack traces). + "Data" Much larger dumps with additional information which may be need (also data segments). + "Full" Even larger dumps with a full memory dump of the process. + + + + + None + + + + + Mini (recommended) + + + + + Data + + + + + Full + + + + + + + + + + + + Max Dumps To Keep + + + + + + + Qt::Horizontal + + + + 60 + 20 + + + + + + + + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. + + + + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. + Set "Crash Dumps" above to None to disable crash dump collection. + + + + + + + + + + + Logs and crash dumps are stored under your current instance in the <a href="LOGS_FULL_PATH">LOGS_DIR</a> + and <a href="DUMPS_FULL_PATH">DUMPS_DIR</a> folders. + Sending logs and/or crash dumps to the developers can help investigate issues. + It is recommended to compress large log and dmp files before sending. + + + + true + + + Hint: right click link and copy link location + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 232 + + + + + + -- cgit v1.3.1