From 9d88ca13b9b6a193dfb17a1ee3ea5e5cbed8a7e9 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Thu, 15 Oct 2015 13:34:01 +0100 Subject: Added functionality to use the web page link in a fomod to supply an optional web page. Also refactored modinfo into multiple files (as the actual types are opaque anyway) and cleaned up the headers a bit I also changed 'visit on nexus' from the menu not to open the downloads tab because it was a little confusing --- src/modinfowithconflictinfo.cpp | 130 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/modinfowithconflictinfo.cpp (limited to 'src/modinfowithconflictinfo.cpp') diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp new file mode 100644 index 00000000..fbf2345f --- /dev/null +++ b/src/modinfowithconflictinfo.cpp @@ -0,0 +1,130 @@ +#include "modinfowithconflictinfo.h" + +#include "directoryentry.h" +#include "utility.h" + +using namespace MOBase; +using namespace MOShared; + +ModInfoWithConflictInfo::ModInfoWithConflictInfo(DirectoryEntry **directoryStructure) + : m_DirectoryStructure(directoryStructure) {} + +void ModInfoWithConflictInfo::clearCaches() +{ + m_LastConflictCheck = QTime(); +} + +std::vector ModInfoWithConflictInfo::getFlags() const +{ + std::vector result; + switch (isConflicted()) { + case CONFLICT_MIXED: { + result.push_back(ModInfo::FLAG_CONFLICT_MIXED); + } break; + case CONFLICT_OVERWRITE: { + result.push_back(ModInfo::FLAG_CONFLICT_OVERWRITE); + } break; + case CONFLICT_OVERWRITTEN: { + result.push_back(ModInfo::FLAG_CONFLICT_OVERWRITTEN); + } break; + case CONFLICT_REDUNDANT: { + result.push_back(ModInfo::FLAG_CONFLICT_REDUNDANT); + } break; + default: { /* NOP */ } + } + return result; +} + + +void ModInfoWithConflictInfo::doConflictCheck() const +{ + m_OverwriteList.clear(); + m_OverwrittenList.clear(); + + bool providesAnything = false; + + int dataID = 0; + if ((*m_DirectoryStructure)->originExists(L"data")) { + dataID = (*m_DirectoryStructure)->getOriginByName(L"data").getID(); + } + + std::wstring name = ToWString(this->name()); + + m_CurrentConflictState = CONFLICT_NONE; + + if ((*m_DirectoryStructure)->originExists(name)) { + FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name); + std::vector files = origin.getFiles(); + // for all files in this origin + for (FileEntry::Ptr file : files) { + const std::vector &alternatives = file->getAlternatives(); + if ((alternatives.size() == 0) || (alternatives[0] == dataID)) { + // no alternatives -> no conflict + providesAnything = true; + } else { + if (file->getOrigin() != origin.getID()) { + FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin()); + unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); + m_OverwrittenList.insert(altIndex); + } else { + providesAnything = true; + } + + // for all non-providing alternative origins + for (int altId : alternatives) { + if ((altId != dataID) && (altId != origin.getID())) { + FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altId); + unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); + if (origin.getPriority() > altOrigin.getPriority()) { + m_OverwriteList.insert(altIndex); + } else { + m_OverwrittenList.insert(altIndex); + } + } + } + } + } + m_LastConflictCheck = QTime::currentTime(); + + if (files.size() != 0) { + if (!providesAnything) + m_CurrentConflictState = CONFLICT_REDUNDANT; + else if (!m_OverwriteList.empty() && !m_OverwrittenList.empty()) + m_CurrentConflictState = CONFLICT_MIXED; + else if (!m_OverwriteList.empty()) + m_CurrentConflictState = CONFLICT_OVERWRITE; + else if (!m_OverwrittenList.empty()) + m_CurrentConflictState = CONFLICT_OVERWRITTEN; + } + } +} + +ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() const +{ + // this is costy so cache the result + QTime now = QTime::currentTime(); + if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) { + doConflictCheck(); + } + + return m_CurrentConflictState; +} + + +bool ModInfoWithConflictInfo::isRedundant() const +{ + std::wstring name = ToWString(this->name()); + if ((*m_DirectoryStructure)->originExists(name)) { + FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name); + std::vector files = origin.getFiles(); + bool ignore = false; + for (auto iter = files.begin(); iter != files.end(); ++iter) { + if ((*iter)->getOrigin(ignore) == origin.getID()) { + return false; + } + } + return true; + } else { + return false; + } +} -- cgit v1.3.1