summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Rimpo <jeremy.rimpo@servermonkey.com>2024-06-22 01:31:26 -0500
committerGitHub <noreply@github.com>2024-06-22 08:31:26 +0200
commita4f6298111b9b4518d00e6df3a53dd176858dd34 (patch)
tree11d35c88a96c6998eac9b7debb8736ebe907d014
parentd3b647ab2b19626b2f86b5c2af3946c1fcf22068 (diff)
Parse unmanaged file location when creating ModInfoForeign (#2053)
* Parse unmanaged file location when creating ModInfoForeign - Fixes issues with secondaryDataDirectories * Revert SF memory address changes - CCC implementation prevents the need to determine core plugin LO by dependency chains * The light flag wins over the medium flag - I had expected the opposite, but apparently the light flag still wins if both are set. This shouldn't really happen but it's possible, even with the CK * Update display to account for multi-flagged plugins - Show both icons, warn if both set
-rw-r--r--src/modinfoforeign.cpp18
-rw-r--r--src/modinfoforeign.h3
-rw-r--r--src/modinfowithconflictinfo.cpp17
-rw-r--r--src/pluginlist.cpp75
4 files changed, 51 insertions, 62 deletions
diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp
index db90aa41..cfc5ab4e 100644
--- a/src/modinfoforeign.cpp
+++ b/src/modinfoforeign.cpp
@@ -1,6 +1,7 @@
#include "modinfoforeign.h"
#include "iplugingame.h"
+#include "organizercore.h"
#include "utility.h"
#include <QApplication>
@@ -13,13 +14,6 @@ QDateTime ModInfoForeign::creationTime() const
return m_CreationTime;
}
-QString ModInfoForeign::absolutePath() const
-{
- // I ought to store this, it's used elsewhere
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- return game->dataDirectory().absolutePath();
-}
-
std::vector<ModInfo::EFlag> ModInfoForeign::getFlags() const
{
std::vector<ModInfo::EFlag> result = ModInfoWithConflictInfo::getFlags();
@@ -49,7 +43,15 @@ ModInfoForeign::ModInfoForeign(const QString& modName, const QString& referenceF
: ModInfoWithConflictInfo(core), m_ReferenceFile(referenceFile),
m_Archives(archives), m_ModType(modType)
{
- m_CreationTime = QFileInfo(referenceFile).birthTime();
+ m_CreationTime = QFileInfo(referenceFile).birthTime();
+ IPluginGame const* game = core.managedGame();
+ QList<QDir> directories = {game->dataDirectory()};
+ directories.append(game->secondaryDataDirectories().values());
+ for (QDir directory : directories) {
+ if (referenceFile.startsWith(directory.absolutePath(), Qt::CaseInsensitive)) {
+ m_BaseDirectory = directory.absolutePath();
+ }
+ }
switch (modType) {
case ModInfo::EModType::MOD_DLC:
m_Name = tr("DLC: ") + modName;
diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h
index dc66e1b0..fa57e378 100644
--- a/src/modinfoforeign.h
+++ b/src/modinfoforeign.h
@@ -39,7 +39,7 @@ public:
virtual QString comments() const override { return ""; }
virtual QString notes() const override { return ""; }
virtual QDateTime creationTime() const override;
- virtual QString absolutePath() const override;
+ virtual QString absolutePath() const override { return m_BaseDirectory; }
virtual MOBase::VersionInfo newestVersion() const override { return QString(); }
virtual MOBase::VersionInfo ignoredVersion() const override { return QString(); }
virtual QString installationFile() const override { return ""; }
@@ -108,6 +108,7 @@ private:
QString m_Name;
QString m_InternalName;
QString m_ReferenceFile;
+ QString m_BaseDirectory;
QStringList m_Archives;
QDateTime m_CreationTime;
int m_Priority;
diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp
index 2300405a..df2dc7ce 100644
--- a/src/modinfowithconflictinfo.cpp
+++ b/src/modinfowithconflictinfo.cpp
@@ -99,9 +99,15 @@ ModInfoWithConflictInfo::Conflicts ModInfoWithConflictInfo::doConflictCheck() co
bool providesAnything = false;
bool hasHiddenFiles = false;
- int dataID = 0;
+ std::vector<int> dataIDs;
if (m_Core.directoryStructure()->originExists(L"data")) {
- dataID = m_Core.directoryStructure()->getOriginByName(L"data").getID();
+ dataIDs.push_back(m_Core.directoryStructure()->getOriginByName(L"data").getID());
+ }
+ for (const auto& origin : m_Core.managedGame()->secondaryDataDirectories().keys()) {
+ if (m_Core.directoryStructure()->originExists(origin.toStdWString())) {
+ dataIDs.push_back(
+ m_Core.directoryStructure()->getOriginByName(origin.toStdWString()).getID());
+ }
}
std::wstring name = ToWString(this->name());
@@ -145,7 +151,9 @@ ModInfoWithConflictInfo::Conflicts ModInfoWithConflictInfo::doConflictCheck() co
}
auto alternatives = file->getAlternatives();
- if ((alternatives.size() == 0) || (alternatives.back().originID() == dataID)) {
+ if ((alternatives.size() == 0) ||
+ std::find(dataIDs.begin(), dataIDs.end(), alternatives.back().originID()) !=
+ dataIDs.end()) {
// no alternatives -> no conflict
providesAnything = true;
} else {
@@ -181,7 +189,8 @@ ModInfoWithConflictInfo::Conflicts ModInfoWithConflictInfo::doConflictCheck() co
// Sort out the alternatives
for (const auto& altInfo : alternatives) {
- if ((altInfo.originID() != dataID) &&
+ if (!(std::find(dataIDs.begin(), dataIDs.end(),
+ alternatives.back().originID()) != dataIDs.end()) &&
(altInfo.originID() != origin.getID())) {
FilesOrigin& altOrigin =
m_Core.directoryStructure()->getOriginByID(altInfo.originID());
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 9f99ff60..94aee98d 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -1102,14 +1102,7 @@ void PluginList::generatePluginIndexes()
continue;
}
if (mediumPluginsSupported && m_ESPs[i].isMediumFlagged) {
- if (mediumPluginsSupported && m_ESPs[i].forceLoaded) {
- // Starfield core medium plugins are loaded in memory addresses after custom
- // medium plugins
- coreMediumPlugins.push_back(i);
- ++numSkipped;
- continue;
- }
- int ESHpos = 253 + ((numESHs + 1) / 256);
+ int ESHpos = 253 + (numESHs / 256);
m_ESPs[i].index = QString("%1:%2")
.arg(ESHpos, 2, 16, QChar('0'))
.arg(numESHs % 256, 2, 16, QChar('0'))
@@ -1118,15 +1111,7 @@ void PluginList::generatePluginIndexes()
} else if (lightPluginsSupported &&
(m_ESPs[i].hasLightExtension || m_ESPs[i].isLightFlagged)) {
- // Starfield core light plugins are loaded in memory addresses after custom light
- // plugins
- if (mediumPluginsSupported && m_ESPs[i].forceLoaded) {
- coreLightPlugins.push_back(i);
- ++numSkipped;
- continue;
- }
-
- int ESLpos = 254 + ((numESLs + 1) / 4096);
+ int ESLpos = 254 + (numESLs / 4096);
m_ESPs[i].index = QString("%1:%2")
.arg(ESLpos, 2, 16, QChar('0'))
.arg(numESLs % 4096, 3, 16, QChar('0'))
@@ -1138,22 +1123,6 @@ void PluginList::generatePluginIndexes()
.toUpper();
}
}
- for (auto pluginIndex : coreMediumPlugins) {
- int ESHpos = 253 + ((numESHs + 1) / 4096);
- m_ESPs[pluginIndex].index = QString("%1:%2")
- .arg(ESHpos, 2, 16, QChar('0'))
- .arg(numESHs % 256, 2, 16, QChar('0'))
- .toUpper();
- ++numESHs;
- }
- for (auto pluginIndex : coreLightPlugins) {
- int ESLpos = 254 + ((numESLs + 1) / 4096);
- m_ESPs[pluginIndex].index = QString("%1:%2")
- .arg(ESLpos, 2, 16, QChar('0'))
- .arg(numESLs % 4096, 3, 16, QChar('0'))
- .toUpper();
- ++numESLs;
- }
emit esplist_changed();
}
@@ -1283,10 +1252,10 @@ QVariant PluginList::fontData(const QModelIndex& modelIndex) const
if (m_ESPs[index].hasMasterExtension || m_ESPs[index].isMasterFlagged ||
m_ESPs[index].hasLightExtension)
result.setWeight(QFont::Bold);
- if (m_ESPs[index].isMediumFlagged)
- result.setUnderline(true);
if (m_ESPs[index].isLightFlagged || m_ESPs[index].hasLightExtension)
result.setItalic(true);
+ else if (m_ESPs[index].isMediumFlagged)
+ result.setUnderline(true);
return result;
}
@@ -1372,13 +1341,6 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const
"be added to your game settings, overwriting in case of conflicts.");
}
- if (esp.isMediumFlagged && esp.hasMasterExtension) {
- toolTip += "<br><br>" +
- tr("This ESM is flagged as a medium plugin (ESH). It adheres to the ESM "
- "load order but loads records in ESH space (FD). You can have 256 "
- "medium plugins in addition to other plugin types.");
- }
-
if (esp.isLightFlagged && !esp.hasLightExtension) {
QString type = esp.hasMasterExtension ? "ESM" : "ESP";
toolTip +=
@@ -1387,6 +1349,19 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const
"order but the records will be loaded in ESL space (FE/FF). You can have up "
"to 4096 light plugins in addition to other plugin types.")
.arg(type);
+ } else if (esp.isMediumFlagged && esp.hasMasterExtension) {
+ toolTip += "<br><br>" +
+ tr("This ESM is flagged as a medium plugin (ESH). It adheres to the ESM "
+ "load order but loads records in ESH space (FD). You can have 256 "
+ "medium plugins in addition to other plugin types.");
+ }
+
+ if (esp.isLightFlagged && esp.isMediumFlagged) {
+ toolTip +=
+ "<br><br>" +
+ tr("WARNING: This plugin is both light and medium flagged. "
+ "This could indicate that the file was saved improperly "
+ "and may have mismatched record references. Use it at your own risk.");
}
if (esp.hasNoRecords) {
@@ -1515,14 +1490,17 @@ QVariant PluginList::iconData(const QModelIndex& modelIndex) const
result.append(":/MO/gui/archive_conflict_neutral");
}
- if (esp.isMediumFlagged) {
- result.append(":/MO/gui/run");
- }
-
if (esp.isLightFlagged && !esp.hasLightExtension) {
result.append(":/MO/gui/awaiting");
}
+ if (esp.isMediumFlagged) {
+ result.append(":/MO/gui/run");
+ if (esp.isLightFlagged) {
+ result.append(":/MO/gui/warning");
+ }
+ }
+
if (esp.hasNoRecords) {
result.append(":/MO/gui/unchecked-checkbox");
}
@@ -1851,10 +1829,9 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool forceLoaded, bool forceEn
hasMasterExtension = (extension == "esm");
hasLightExtension = (extension == "esl");
isMasterFlagged = file.isMaster();
+ isLightFlagged = lightSupported && file.isLight(mediumSupported);
isMediumFlagged = mediumSupported && file.isMedium();
- isLightFlagged =
- lightSupported && !isMediumFlagged && file.isLight(mediumSupported);
- hasNoRecords = file.isDummy();
+ hasNoRecords = file.isDummy();
author = QString::fromLatin1(file.author().c_str());
description = QString::fromLatin1(file.description().c_str());