From 8d6c715672023577dca5a6528ff49081dede1052 Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 11 Apr 2018 17:46:59 -0500 Subject: Initial archive conflict parsing Squashed commit: Basic archive conflict parsing - pass 1 Merge fixes for archive parsing Basic archive conflict parsing - pass 1 Merge fixes for archive parsing Should fix conflict detection for archive files --- src/shared/directoryentry.cpp | 114 +++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 36 deletions(-) (limited to 'src/shared/directoryentry.cpp') diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index cebf270e..477f4dad 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -220,12 +220,19 @@ std::vector FilesOrigin::getFiles() const return result; } +bool FilesOrigin::containsArchive(std::wstring archiveName) +{ + for (FileEntry::Index fileIdx : m_Files) + if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx)) + if (p->isFromArchive(archiveName)) return true; + return false; +} // // FileEntry // -void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive) +void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive, int order) { m_LastAccessed = time(nullptr); if (m_Parent != nullptr) { @@ -234,36 +241,36 @@ void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &arc if (m_Origin == -1) { m_Origin = origin; m_FileTime = fileTime; - m_Archive = archive; + m_Archive = std::pair(archive, order); } else if ((m_Parent != nullptr) && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) - && (archive.size() == 0 || m_Archive.size() > 0 )) { - if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) { - m_Alternatives.push_back(std::pair(m_Origin, m_Archive)); + && (archive.size() == 0 || m_Archive.first.size() > 0 )) { + if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) { + m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); } m_Origin = origin; m_FileTime = fileTime; - m_Archive = archive; + m_Archive = std::pair(archive, order); } else { bool found = false; if (m_Origin == origin) { // already an origin return; } - for (std::vector>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { + for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { if (iter->first == origin) { // already an origin return; } if ((m_Parent != nullptr) && (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) { - m_Alternatives.insert(iter, std::pair(origin, archive)); + m_Alternatives.insert(iter, std::pair>(origin, std::pair(archive, order))); found = true; break; } } if (!found) { - m_Alternatives.push_back(std::pair(origin, archive)); + m_Alternatives.push_back(std::pair>(origin, std::pair(archive, order))); } } } @@ -273,8 +280,8 @@ bool FileEntry::removeOrigin(int origin) if (m_Origin == origin) { if (!m_Alternatives.empty()) { // find alternative with the highest priority - std::vector>::iterator currentIter = m_Alternatives.begin(); - for (std::vector>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { + std::vector>>::iterator currentIter = m_Alternatives.begin(); + for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) && (iter->first != origin)) { currentIter = iter; @@ -292,9 +299,9 @@ bool FileEntry::removeOrigin(int origin) if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh // the view to find out - m_Archive = L"bsa?"; + m_Archive = std::pair(L"bsa?", -1); } else { - m_Archive = L""; + m_Archive = std::pair(L"", -1); } ::CloseHandle(file); @@ -304,7 +311,7 @@ bool FileEntry::removeOrigin(int origin) return true; } } else { - std::vector>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair &i) -> bool { return i.first == origin; }); + std::vector>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == origin; }); if (newEnd != m_Alternatives.end()) m_Alternatives.erase(newEnd, m_Alternatives.end()); } @@ -318,7 +325,7 @@ FileEntry::FileEntry() } FileEntry::FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent) - : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L""), m_Parent(parent), m_LastAccessed(time(nullptr)) + : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L"", -1), m_Parent(parent), m_LastAccessed(time(nullptr)) { LEAK_TRACE; } @@ -330,16 +337,23 @@ FileEntry::~FileEntry() void FileEntry::sortOrigins() { - m_Alternatives.push_back(std::pair(m_Origin, m_Archive)); - std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair &LHS, const std::pair &RHS) -> bool { - if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.size())) { + m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); + std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &LHS, const std::pair> &RHS) -> bool { + if (!LHS.second.first.size() && !RHS.second.first.size()) { int l = m_Parent->getOriginByID(LHS.first).getPriority(); if (l < 0) l = INT_MAX; int r = m_Parent->getOriginByID(RHS.first).getPriority(); if (r < 0) r = INT_MAX; return l < r; } - if (RHS.second.size()) return false; + if (LHS.second.first.size() && RHS.second.first.size()) { + int l = LHS.second.second; if (l < 0) l = INT_MAX; + int r = RHS.second.second; if (r < 0) r = INT_MAX; + + return l < r; + } + + if (RHS.second.first.size()) return false; return true; }); if (!m_Alternatives.empty()) { @@ -379,6 +393,16 @@ std::wstring FileEntry::getRelativePath() const return result + L"\\" + m_Name; } +bool FileEntry::isFromArchive(std::wstring archiveName) +{ + if (archiveName.length() == 0) return m_Archive.first.length() != 0; + if (m_Archive.first.compare(archiveName) == 0) return true; + for (auto alternative : m_Alternatives) { + if (alternative.second.first.compare(archiveName) == 0) return true; + } + return false; +} + // // DirectoryEntry @@ -451,7 +475,7 @@ void DirectoryEntry::addFromOrigin(const std::wstring &originName, const std::ws } -void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority) +void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority, int order) { FilesOrigin &origin = createOrigin(originName, directory, priority); @@ -459,23 +483,33 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) { throw windows_error("failed to determine file time"); } + FILETIME now; + ::GetSystemTimeAsFileTime(&now); + + const double clfSecondsPer100ns = 100. * 1.E-9; + + ((ULARGE_INTEGER *)&now)->QuadPart -= ((double)5) / clfSecondsPer100ns; - BSA::Archive archive; - BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false); - if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) { - std::ostringstream stream; - stream << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError(); - throw std::runtime_error(stream.str()); - } size_t namePos = fileName.find_last_of(L"\\/"); if (namePos == std::wstring::npos) { namePos = 0; - } else { + } + else { ++namePos; } - addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos)); - m_Populated = true; + if (!containsArchive(fileName.substr(namePos)) || ::CompareFileTime(&fileData.ftLastWriteTime, &now) > 0) { + BSA::Archive archive; + BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false); + if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) { + std::ostringstream stream; + stream << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError(); + throw std::runtime_error(stream.str()); + } + + addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos), order); + m_Populated = true; + } } void DirectoryEntry::propagateOrigin(int origin) @@ -536,7 +570,7 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf getSubDirectory(findData.cFileName, true, origin.getID())->addFiles(origin, buffer, bufferOffset + offset); } } else { - insert(findData.cFileName, origin, findData.ftLastWriteTime, L""); + insert(findData.cFileName, origin, findData.ftLastWriteTime, L"", -1); } result = ::FindNextFileW(searchHandle, &findData); } @@ -546,12 +580,12 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf } -void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName) +void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName, int order) { // add files for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) { BSA::File::Ptr file = archiveFolder->getFile(fileIdx); - insert(ToWString(file->getName(), true), origin, fileTime, archiveName); + insert(ToWString(file->getName(), true), origin, fileTime, archiveName, order); } // recurse into subdirectories @@ -559,7 +593,7 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolde BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx); DirectoryEntry *folderEntry = getSubDirectoryRecursive(ToWString(folder->getName(), true), true, origin.getID()); - folderEntry->addFiles(origin, folder, fileTime, archiveName); + folderEntry->addFiles(origin, folder, fileTime, archiveName, order); } } @@ -626,7 +660,7 @@ void DirectoryEntry::insertFile(const std::wstring &filePath, FilesOrigin &origi { size_t pos = filePath.find_first_of(L"\\/"); if (pos == std::string::npos) { - this->insert(filePath, origin, fileTime, std::wstring()); + this->insert(filePath, origin, fileTime, std::wstring(), -1); } else { std::wstring dirName = filePath.substr(0, pos); std::wstring rest = filePath.substr(pos + 1); @@ -667,6 +701,14 @@ void DirectoryEntry::removeFiles(const std::set &indices) } } +bool DirectoryEntry::containsArchive(std::wstring archiveName) +{ + for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) { + FileEntry::Ptr entry = m_FileRegister->getFile(iter->second); + if (entry->isFromArchive(archiveName)) return true; + } + return false; +} int DirectoryEntry::anyOrigin() const { @@ -890,7 +932,7 @@ void FileRegister::unregisterFile(FileEntry::Ptr file) // unregister from origin int originID = file->getOrigin(ignore); m_OriginConnection->getByID(originID).removeFile(file->getIndex()); - const std::vector> &alternatives = file->getAlternatives(); + const std::vector>> &alternatives = file->getAlternatives(); for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) { m_OriginConnection->getByID(iter->first).removeFile(file->getIndex()); } -- cgit v1.3.1 From 40c82fc1908a8ca53abeeabdc618e81e941c987c Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 10 Sep 2018 05:58:24 -0500 Subject: Fixed mainwindow.cpp so that Qt Creator does not break it anymore. We should be able to normally use Creator now without having to worry about breaking the build. Partial fix for conflict information getting messd up after opening infodialog or disabling a mod. Icons still get messed up but conflict tab remains consistent at first inspection. Reverted main tab to plugins Changed version of Archive conflicts branch to 2.2.0 pre-alpha. --- src/directoryrefresher.cpp | 12 ++++---- src/mainwindow.cpp | 1 + src/mainwindow.ui | 66 +++++++++++++++++++++---------------------- src/shared/directoryentry.cpp | 31 ++++++++++++++++---- src/version.rc | 4 +-- 5 files changed, 68 insertions(+), 46 deletions(-) (limited to 'src/shared/directoryentry.cpp') diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 5c789049..82eb093b 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -85,17 +85,17 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure int priority, const QString &directory, const QStringList &archives) { std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory)); + //QStringList loadOrder = QStringList(); + IPluginGame *game = qApp->property("managed_game").value(); + + GamePlugins *gamePlugins = game->feature(); QStringList loadOrder = QStringList(); + gamePlugins->getLoadOrder(loadOrder); for (const QString &archive : archives) { QFileInfo fileInfo(archive); if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) { - IPluginGame *game = qApp->property("managed_game").value(); - - GamePlugins *gamePlugins = game->feature(); - QStringList loadOrder = QStringList(); - gamePlugins->getLoadOrder(loadOrder); - + int order = -1; for (auto plugin : loadOrder) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0d3abce5..cdd53dc9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -313,6 +313,7 @@ MainWindow::MainWindow(QSettings &initSettings ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(ui->espList)); ui->espList->installEventFilter(m_OrganizerCore.pluginList()); + //bsaList converted to normal QTreeWidget since we can't sort BSAs anymore. //ui->bsaList->setLocalMoveOnly(true); bool pluginListAdjusted = registerWidgetState(ui->espList->objectName(), ui->espList->header(), "plugin_list_state"); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index fba246f5..eb88a855 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1152,39 +1152,39 @@ p, li { white-space: pre-wrap; } - - - - - - Filters the above list so that only conflicts are displayed. - - - Filters the above list so that only conflicts are displayed. - - - Show only conflicts - - - - - - - Filters the above list so that files from archives are not shown - - - - - - Filters the above list so that files from archives are not shown - - - Show files from Archives - - - - - + + + + + + Filters the above list so that only conflicts are displayed. + + + Filters the above list so that only conflicts are displayed. + + + Show only conflicts + + + + + + + Filters the above list so that files from archives are not shown + + + + + + Filters the above list so that files from archives are not shown + + + Show files from Archives + + + + + diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 477f4dad..602d58c7 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -282,12 +282,32 @@ bool FileEntry::removeOrigin(int origin) // find alternative with the highest priority std::vector>>::iterator currentIter = m_Alternatives.begin(); for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { - if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) && - (iter->first != origin)) { - currentIter = iter; + if (iter->first != origin) { + + //Both files are not from archives. + if (!iter->second.first.size() && !currentIter->second.first.size()) { + if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority())) { + currentIter = iter; + } + } + else { + //Both files are from archives + if (iter->second.first.size() && currentIter->second.first.size()) { + if (iter->second.second > currentIter->second.second) { + currentIter = iter; + } + } + else { + //Only one of the two is an archive, so we change currentIter only if he is the archive one. + if (currentIter->second.first.size()) { + currentIter = iter; + } + } + } } } int currentID = currentIter->first; + m_Archive = currentIter->second; m_Alternatives.erase(currentIter); m_Origin = currentID; @@ -299,15 +319,16 @@ bool FileEntry::removeOrigin(int origin) if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh // the view to find out - m_Archive = std::pair(L"bsa?", -1); + //m_Archive = std::pair(L"bsa?", -1); } else { - m_Archive = std::pair(L"", -1); + //m_Archive = std::pair(L"", -1); } ::CloseHandle(file); } else { m_Origin = -1; + m_Archive = std::pair(L"", -1); return true; } } else { diff --git a/src/version.rc b/src/version.rc index 3f2deab0..e1f80785 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ // If VS_FF_PRERELEASE is not set, MO labels the build as a release and uses VER_FILEVERSION to determine version number. // Otherwise, if letters are used in VER_FILEVERSION_STR, uses the full MOBase::VersionInfo parser // Otherwise, uses the numbers from VER_FILEVERSION and sets the release type as pre-alpha -#define VER_FILEVERSION 2,1,6 -#define VER_FILEVERSION_STR "2.1.6\0" +#define VER_FILEVERSION 2,2,0 +#define VER_FILEVERSION_STR "2.2.0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1 From 858930cb461988adec846bdf96fad6f600b81cd6 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Tue, 1 Jan 2019 00:57:12 -0600 Subject: Change find_if to remove_if --- src/shared/directoryentry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shared/directoryentry.cpp') diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 602d58c7..9f54e526 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -332,7 +332,7 @@ bool FileEntry::removeOrigin(int origin) return true; } } else { - std::vector>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == origin; }); + auto newEnd = std::remove_if(m_Alternatives.begin(), m_Alternatives.end(), [&](auto &i) -> bool { return i.first == origin; }); if (newEnd != m_Alternatives.end()) m_Alternatives.erase(newEnd, m_Alternatives.end()); } -- cgit v1.3.1 From b38a26c2bc731ad123365e7f164d1a9ed0c89b6a Mon Sep 17 00:00:00 2001 From: Al Date: Tue, 12 Feb 2019 23:56:09 +0100 Subject: Performance improvements: * Avoid accessing disk for finding archives if archive parsing is disabled. * Avoid very expensive createFile() call in removeOrigin(), after disabling a mod or closing modinfodialog. --- src/modinforegular.cpp | 4 +++- src/shared/directoryentry.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'src/shared/directoryentry.cpp') diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 15ce56ba..529f20cb 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -47,7 +47,9 @@ ModInfoRegular::ModInfoRegular(PluginContainer *pluginContainer, const IPluginGa //populate m_Archives m_Archives = QStringList(); - archives(true); + if (Settings::instance().archiveParsing()) { + archives(true); + } connect(&m_NexusBridge, SIGNAL(descriptionAvailable(QString,int,QVariant,QVariant)) , this, SLOT(nxmDescriptionAvailable(QString,int,QVariant,QVariant))); diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 9f54e526..8fc63188 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -313,18 +313,18 @@ bool FileEntry::removeOrigin(int origin) m_Origin = currentID; // now we need to update the file time... - std::wstring filePath = getFullPath(); - HANDLE file = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE, - 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { + //std::wstring filePath = getFullPath(); + //HANDLE file = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE, + // 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + //if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh // the view to find out //m_Archive = std::pair(L"bsa?", -1); - } else { + //} else { //m_Archive = std::pair(L"", -1); - } + //} - ::CloseHandle(file); + //::CloseHandle(file); } else { m_Origin = -1; -- cgit v1.3.1 From 6dd246363e538d7730ff0eec3c23338553ca1392 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 22 Mar 2019 21:26:50 -0500 Subject: Fix origin determination for the case of a lower priority, loose files mod being added after a higher priority, archived files mod. --- src/shared/directoryentry.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/shared/directoryentry.cpp') diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 8fc63188..1179110a 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -238,20 +238,30 @@ void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &arc if (m_Parent != nullptr) { m_Parent->propagateOrigin(origin); } + + // If this file has no previous origin, this mod is now the origin with no alternatives if (m_Origin == -1) { m_Origin = origin; m_FileTime = fileTime; m_Archive = std::pair(archive, order); - } else if ((m_Parent != nullptr) - && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) - && (archive.size() == 0 || m_Archive.first.size() > 0 )) { + } + + // If this mod has a higher priority than the origin mod OR + // this mod has a loose file and the origin mod has an archived file, + // this mod is now the origin and the previous origin is the first alternative + else if ((m_Parent != nullptr) + && ((m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) + || (archive.size() == 0 && m_Archive.first.size() > 0 ))) { if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) { m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); } m_Origin = origin; m_FileTime = fileTime; m_Archive = std::pair(archive, order); - } else { + } + + // This mod is just an alternative + else { bool found = false; if (m_Origin == origin) { // already an origin -- cgit v1.3.1