From 93876e27f80a63b36c2cce73b014bf031054bb99 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 31 Aug 2023 17:32:55 +0100 Subject: [PATCH] Generalise resource metadata Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 5 +- launcher/QObjectPtr.h | 6 +- launcher/minecraft/MinecraftInstance.cpp | 13 ++-- launcher/minecraft/mod/MetadataHandler.h | 51 ++++++++----- launcher/minecraft/mod/Mod.cpp | 73 +----------------- launcher/minecraft/mod/Mod.h | 15 +--- launcher/minecraft/mod/ModDetails.h | 48 +----------- launcher/minecraft/mod/ModFolderModel.cpp | 46 ++---------- launcher/minecraft/mod/ModFolderModel.h | 14 +--- launcher/minecraft/mod/Resource.cpp | 45 ++++++++++- launcher/minecraft/mod/Resource.h | 28 ++++++- .../minecraft/mod/ResourceFolderModel.cpp | 14 ++-- launcher/minecraft/mod/ResourceFolderModel.h | 11 ++- .../minecraft/mod/ResourcePackFolderModel.cpp | 10 +-- .../minecraft/mod/ResourcePackFolderModel.h | 6 +- .../minecraft/mod/ShaderPackFolderModel.h | 4 +- .../minecraft/mod/TexturePackFolderModel.cpp | 10 +-- .../minecraft/mod/TexturePackFolderModel.h | 5 +- .../minecraft/mod/tasks/BasicFolderLoadTask.h | 74 ------------------- .../minecraft/mod/tasks/LocalModParseTask.h | 5 -- ...oadTask.cpp => ResourceFolderLoadTask.cpp} | 71 +++++++++--------- ...derLoadTask.h => ResourceFolderLoadTask.h} | 12 ++- launcher/modplatform/EnsureMetadataTask.cpp | 2 +- .../modplatform/flame/FlameCheckUpdate.cpp | 4 +- .../modrinth/ModrinthCheckUpdate.cpp | 2 +- .../modrinth/ModrinthPackExportTask.cpp | 2 +- launcher/modplatform/packwiz/Packwiz.h | 1 + launcher/ui/dialogs/ModUpdateDialog.cpp | 2 +- 28 files changed, 209 insertions(+), 370 deletions(-) delete mode 100644 launcher/minecraft/mod/tasks/BasicFolderLoadTask.h rename launcher/minecraft/mod/tasks/{ModFolderLoadTask.cpp => ResourceFolderLoadTask.cpp} (55%) rename launcher/minecraft/mod/tasks/{ModFolderLoadTask.h => ResourceFolderLoadTask.h} (84%) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 18e0acab1..cd4c64dec 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -350,9 +350,8 @@ set(MINECRAFT_SOURCES minecraft/mod/TexturePackFolderModel.h minecraft/mod/TexturePackFolderModel.cpp minecraft/mod/ShaderPackFolderModel.h - minecraft/mod/tasks/BasicFolderLoadTask.h - minecraft/mod/tasks/ModFolderLoadTask.h - minecraft/mod/tasks/ModFolderLoadTask.cpp + minecraft/mod/tasks/ResourceFolderLoadTask.h + minecraft/mod/tasks/ResourceFolderLoadTask.cpp minecraft/mod/tasks/LocalModParseTask.h minecraft/mod/tasks/LocalModParseTask.cpp minecraft/mod/tasks/LocalModUpdateTask.h diff --git a/launcher/QObjectPtr.h b/launcher/QObjectPtr.h index a1c64b433..5f7b64df0 100644 --- a/launcher/QObjectPtr.h +++ b/launcher/QObjectPtr.h @@ -33,11 +33,7 @@ class shared_qobject_ptr : public QSharedPointer { {} void reset() { QSharedPointer::reset(); } - void reset(T*&& other) - { - shared_qobject_ptr t(other); - this->swap(t); - } + void reset(T* other) { QSharedPointer::reset(other); } void reset(const shared_qobject_ptr& other) { shared_qobject_ptr t(other); diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 0e64c46d4..a75d017b7 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1091,7 +1091,7 @@ std::shared_ptr MinecraftInstance::loaderModList() { if (!m_loader_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); - m_loader_mod_list.reset(new ModFolderModel(modsRoot(), this, is_indexed)); + m_loader_mod_list.reset(new ModFolderModel(modsRoot(), this, is_indexed, true)); } return m_loader_mod_list; } @@ -1100,7 +1100,7 @@ std::shared_ptr MinecraftInstance::coreModList() { if (!m_core_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); - m_core_mod_list.reset(new ModFolderModel(coreModsDir(), this, is_indexed)); + m_core_mod_list.reset(new ModFolderModel(coreModsDir(), this, is_indexed, true)); } return m_core_mod_list; } @@ -1117,7 +1117,8 @@ std::shared_ptr MinecraftInstance::nilModList() std::shared_ptr MinecraftInstance::resourcePackList() { if (!m_resource_pack_list) { - m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir(), this)); + bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); + m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir(), this, is_indexed, true)); } return m_resource_pack_list; } @@ -1125,7 +1126,8 @@ std::shared_ptr MinecraftInstance::resourcePackList() std::shared_ptr MinecraftInstance::texturePackList() { if (!m_texture_pack_list) { - m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir(), this)); + bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); + m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir(), this, is_indexed, true)); } return m_texture_pack_list; } @@ -1133,7 +1135,8 @@ std::shared_ptr MinecraftInstance::texturePackList() std::shared_ptr MinecraftInstance::shaderPackList() { if (!m_shader_pack_list) { - m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir(), this)); + bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); + m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir(), this, is_indexed, true)); } return m_shader_pack_list; } diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 88e9ff2b6..747375d3f 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -25,30 +25,41 @@ // launcher/minecraft/mod/Mod.h class Mod; -/* Abstraction file for easily changing the way metadata is stored / handled - * Needs to be a class because of -Wunused-function and no C++17 [[maybe_unused]] - * */ -class Metadata { - public: - using ModStruct = Packwiz::V1::Mod; +namespace Metadata { +using ModStruct = Packwiz::V1::Mod; - static auto create(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> ModStruct - { - return Packwiz::V1::createModFormat(index_dir, mod_pack, mod_version); - } +inline auto create(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> ModStruct +{ + return Packwiz::V1::createModFormat(index_dir, mod_pack, mod_version); +} - static auto create(QDir& index_dir, Mod& internal_mod, QString mod_slug) -> ModStruct - { - return Packwiz::V1::createModFormat(index_dir, internal_mod, mod_slug); - } +inline auto create(QDir& index_dir, Mod& internal_mod, QString mod_slug) -> ModStruct +{ + return Packwiz::V1::createModFormat(index_dir, internal_mod, std::move(mod_slug)); +} - static void update(QDir& index_dir, ModStruct& mod) { Packwiz::V1::updateModIndex(index_dir, mod); } +inline void update(QDir& index_dir, ModStruct& mod) +{ + Packwiz::V1::updateModIndex(index_dir, mod); +} - static void remove(QDir& index_dir, QString mod_slug) { Packwiz::V1::deleteModIndex(index_dir, mod_slug); } +inline void remove(QDir& index_dir, QString mod_slug) +{ + Packwiz::V1::deleteModIndex(index_dir, mod_slug); +} - static void remove(QDir& index_dir, QVariant& mod_id) { Packwiz::V1::deleteModIndex(index_dir, mod_id); } +inline void remove(QDir& index_dir, QVariant& mod_id) +{ + Packwiz::V1::deleteModIndex(index_dir, mod_id); +} - static auto get(QDir& index_dir, QString mod_slug) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_slug); } +inline auto get(QDir& index_dir, QString mod_slug) -> ModStruct +{ + return Packwiz::V1::getIndexForMod(index_dir, std::move(mod_slug)); +} - static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_id); } -}; +inline auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct +{ + return Packwiz::V1::getIndexForMod(index_dir, mod_id); +} +}; // namespace Metadata diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index ae3dea8d8..53f7d72de 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -43,35 +43,16 @@ #include "MTPixmapCache.h" #include "MetadataHandler.h" +#include "Resource.h" #include "Version.h" #include "minecraft/mod/ModDetails.h" #include "minecraft/mod/tasks/LocalModParseTask.h" -static ModPlatform::ProviderCapabilities ProviderCaps; - Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details() { m_enabled = (file.suffix() != "disabled"); } -Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata) : Mod(mods_dir.absoluteFilePath(metadata.filename)) -{ - m_name = metadata.name; - m_local_details.metadata = std::make_shared(std::move(metadata)); -} - -void Mod::setStatus(ModStatus status) -{ - m_local_details.status = status; -} -void Mod::setMetadata(std::shared_ptr&& metadata) -{ - if (status() == ModStatus::NoMetadata) - setStatus(ModStatus::Installed); - - m_local_details.metadata = metadata; -} - void Mod::setDetails(const ModDetails& details) { m_local_details = details; @@ -103,8 +84,7 @@ std::pair Mod::compare(const Resource& other, SortType type) const break; } case SortType::PROVIDER: { - auto compare_result = - QString::compare(provider().value_or("Unknown"), cast_other->provider().value_or("Unknown"), Qt::CaseInsensitive); + auto compare_result = QString::compare(provider(), cast_other->provider(), Qt::CaseInsensitive); if (compare_result != 0) return { compare_result, type == SortType::PROVIDER }; break; @@ -127,22 +107,6 @@ bool Mod::applyFilter(QRegularExpression filter) const return Resource::applyFilter(filter); } -auto Mod::destroy(QDir& index_dir, bool preserve_metadata, bool attempt_trash) -> bool -{ - if (!preserve_metadata) { - qDebug() << QString("Destroying metadata for '%1' on purpose").arg(name()); - - if (metadata()) { - Metadata::remove(index_dir, metadata()->slug); - } else { - auto n = name(); - Metadata::remove(index_dir, n); - } - } - - return Resource::destroy(attempt_trash); -} - auto Mod::details() const -> const ModDetails& { return m_local_details; @@ -154,10 +118,7 @@ auto Mod::name() const -> QString if (!d_name.isEmpty()) return d_name; - if (metadata()) - return metadata()->name; - - return m_name; + return Resource::name(); } auto Mod::version() const -> QString @@ -187,45 +148,17 @@ auto Mod::authors() const -> QStringList return details().authors; } -auto Mod::status() const -> ModStatus -{ - return details().status; -} - -auto Mod::metadata() -> std::shared_ptr -{ - return m_local_details.metadata; -} - -auto Mod::metadata() const -> const std::shared_ptr -{ - return m_local_details.metadata; -} - void Mod::finishResolvingWithDetails(ModDetails&& details) { m_is_resolving = false; m_is_resolved = true; - std::shared_ptr metadata = details.metadata; - if (details.status == ModStatus::Unknown) - details.status = m_local_details.status; - m_local_details = std::move(details); - if (metadata) - setMetadata(std::move(metadata)); if (!iconPath().isEmpty()) { m_pack_image_cache_key.was_read_attempt = false; } } -auto Mod::provider() const -> std::optional -{ - if (metadata()) - return ProviderCaps.readableName(metadata()->provider); - return {}; -} - auto Mod::licenses() const -> const QList& { return details().licenses; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 6dafecfc5..5f82572a2 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -56,7 +56,6 @@ class Mod : public Resource { Mod() = default; Mod(const QFileInfo& file); - Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata); Mod(QString file_path) : Mod(QFileInfo(file_path)) {} auto details() const -> const ModDetails&; @@ -65,11 +64,10 @@ class Mod : public Resource { auto homeurl() const -> QString; auto description() const -> QString; auto authors() const -> QStringList; - auto status() const -> ModStatus; - auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; auto metaurl() const -> QString; + void setDetails(const ModDetails& details); /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; } @@ -78,22 +76,11 @@ class Mod : public Resource { /** Thread-safe. */ void setIcon(QImage new_image) const; - auto metadata() -> std::shared_ptr; - auto metadata() const -> const std::shared_ptr; - - void setStatus(ModStatus status); - void setMetadata(std::shared_ptr&& metadata); - void setMetadata(const Metadata::ModStruct& metadata) { setMetadata(std::make_shared(metadata)); } - void setDetails(const ModDetails& details); - bool valid() const override; [[nodiscard]] auto compare(Resource const& other, SortType type) const -> std::pair override; [[nodiscard]] bool applyFilter(QRegularExpression filter) const override; - // Delete all the files of this mod - auto destroy(QDir& index_dir, bool preserve_metadata = false, bool attempt_trash = true) -> bool; - void finishResolvingWithDetails(ModDetails&& details); protected: diff --git a/launcher/minecraft/mod/ModDetails.h b/launcher/minecraft/mod/ModDetails.h index a00d5a24b..9195c0368 100644 --- a/launcher/minecraft/mod/ModDetails.h +++ b/launcher/minecraft/mod/ModDetails.h @@ -43,13 +43,6 @@ #include "minecraft/mod/MetadataHandler.h" -enum class ModStatus { - Installed, // Both JAR and Metadata are present - NotInstalled, // Only the Metadata is present - NoMetadata, // Only the JAR is present - Unknown, // Default status -}; - struct ModLicense { QString name = {}; QString id = {}; @@ -149,12 +142,6 @@ struct ModDetails { /* Path of mod logo */ QString icon_file = {}; - /* Installation status of the mod */ - ModStatus status = ModStatus::Unknown; - - /* Metadata information, if any */ - std::shared_ptr metadata = nullptr; - ModDetails() = default; /** Metadata should be handled manually to properly set the mod status. */ @@ -169,40 +156,9 @@ struct ModDetails { , issue_tracker(other.issue_tracker) , licenses(other.licenses) , icon_file(other.icon_file) - , status(other.status) {} - ModDetails& operator=(const ModDetails& other) - { - this->mod_id = other.mod_id; - this->name = other.name; - this->version = other.version; - this->mcversion = other.mcversion; - this->homeurl = other.homeurl; - this->description = other.description; - this->authors = other.authors; - this->issue_tracker = other.issue_tracker; - this->licenses = other.licenses; - this->icon_file = other.icon_file; - this->status = other.status; + ModDetails& operator=(const ModDetails& other) = default; - return *this; - } - - ModDetails& operator=(const ModDetails&& other) - { - this->mod_id = other.mod_id; - this->name = other.name; - this->version = other.version; - this->mcversion = other.mcversion; - this->homeurl = other.homeurl; - this->description = other.description; - this->authors = other.authors; - this->issue_tracker = other.issue_tracker; - this->licenses = other.licenses; - this->icon_file = other.icon_file; - this->status = other.status; - - return *this; - } + ModDetails& operator=(ModDetails&& other) = default; }; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index eed35615c..2f0e9b3e4 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -52,15 +52,16 @@ #include "Application.h" #include "Json.h" +#include "Resource.h" #include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModUpdateTask.h" -#include "minecraft/mod/tasks/ModFolderLoadTask.h" +#include "minecraft/mod/tasks/ResourceFolderLoadTask.h" #include "modplatform/ModIndex.h" #include "modplatform/flame/FlameAPI.h" #include "modplatform/flame/FlameModIndex.h" -ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir) - : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) +ModFolderModel::ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) + : ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent) { m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider") }); @@ -96,15 +97,8 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const } case DateColumn: return m_resources[row]->dateTimeChanged(); - case ProviderColumn: { - auto provider = at(row)->provider(); - if (!provider.has_value()) { - //: Unknown mod provider (i.e. not Modrinth, CurseForge, etc...) - return tr("Unknown"); - } - - return provider.value(); - } + case ProviderColumn: + return at(row)->provider(); default: return QVariant(); } @@ -185,14 +179,6 @@ int ModFolderModel::columnCount(const QModelIndex& parent) const return parent.isValid() ? 0 : NUM_COLUMNS; } -Task* ModFolderModel::createUpdateTask() -{ - auto index_dir = indexDir(); - auto task = new ModFolderLoadTask(dir(), index_dir, m_is_indexed, m_first_folder_load); - m_first_folder_load = false; - return task; -} - Task* ModFolderModel::createParseTask(Resource& resource) { return new LocalModParseTask(m_next_resolution_ticket, resource.type(), resource.fileinfo()); @@ -273,26 +259,6 @@ auto ModFolderModel::allMods() -> QList return mods; } -void ModFolderModel::onUpdateSucceeded() -{ - auto update_results = static_cast(m_current_update_task.get())->result(); - - auto& new_mods = update_results->mods; - -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - auto current_list = m_resources_index.keys(); - QSet current_set(current_list.begin(), current_list.end()); - - auto new_list = new_mods.keys(); - QSet new_set(new_list.begin(), new_list.end()); -#else - QSet current_set(m_resources_index.keys().toSet()); - QSet new_set(new_mods.keys().toSet()); -#endif - - applyUpdates(current_set, new_set, new_mods); -} - void ModFolderModel::onParseSucceeded(int ticket, QString mod_id) { auto iter = m_active_parse_tasks.constFind(ticket); diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index f1890e87e..9326158d4 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -47,10 +47,9 @@ #include "ResourceFolderModel.h" #include "minecraft/mod/tasks/LocalModParseTask.h" -#include "minecraft/mod/tasks/ModFolderLoadTask.h" +#include "minecraft/mod/tasks/ResourceFolderLoadTask.h" #include "modplatform/ModIndex.h" -class LegacyInstance; class BaseInstance; class QFileSystemWatcher; @@ -63,7 +62,7 @@ class ModFolderModel : public ResourceFolderModel { public: enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, VersionColumn, DateColumn, ProviderColumn, NUM_COLUMNS }; enum ModStatusAction { Disable, Enable, Toggle }; - ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed = false, bool create_dir = true); + ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr); virtual QString id() const override { return "mods"; } @@ -72,7 +71,7 @@ class ModFolderModel : public ResourceFolderModel { QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; int columnCount(const QModelIndex& parent) const override; - [[nodiscard]] Task* createUpdateTask() override; + [[nodiscard]] Resource* createResource(const QFileInfo& file) override { return new Mod(file); } [[nodiscard]] Task* createParseTask(Resource&) override; bool installMod(QString file_path) { return ResourceFolderModel::installResource(file_path); } @@ -87,18 +86,11 @@ class ModFolderModel : public ResourceFolderModel { bool startWatching() override; bool stopWatching() override; - QDir indexDir() { return { QString("%1/.index").arg(dir().absolutePath()) }; } - auto selectedMods(QModelIndexList& indexes) -> QList; auto allMods() -> QList; RESOURCE_HELPERS(Mod) private slots: - void onUpdateSucceeded() override; void onParseSucceeded(int ticket, QString resource_id) override; - - protected: - bool m_is_indexed; - bool m_first_folder_load = true; }; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index da806f0f4..0dd7f8992 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -5,6 +5,8 @@ #include "FileSystem.h" +static ModPlatform::ProviderCapabilities ProviderCaps; + Resource::Resource(QObject* parent) : QObject(parent) {} Resource::Resource(QFileInfo file_info) : QObject() @@ -54,6 +56,14 @@ void Resource::parseFile() m_changed_date_time = m_file_info.lastModified(); } +auto Resource::name() const -> QString +{ + if (metadata()) + return metadata()->name; + + return m_name; +} + static void removeThePrefix(QString& string) { QRegularExpression regex(QStringLiteral("^(?:the|teh) +"), QRegularExpression::CaseInsensitiveOption); @@ -61,6 +71,22 @@ static void removeThePrefix(QString& string) string = string.trimmed(); } +auto Resource::provider() const -> QString +{ + if (metadata()) + return ProviderCaps.readableName(metadata()->provider); + + return tr("Unknown"); +} + +void Resource::setMetadata(std::shared_ptr&& metadata) +{ + if (status() == ResourceStatus::NO_METADATA) + setStatus(ResourceStatus::INSTALLED); + + m_metadata = metadata; +} + std::pair Resource::compare(const Resource& other, SortType type) const { switch (type) { @@ -152,6 +178,23 @@ bool Resource::destroy(bool attemptTrash) return (attemptTrash && FS::trash(m_file_info.filePath())) || FS::deletePath(m_file_info.filePath()); } + +auto Resource::destroy(QDir& index_dir, bool preserve_metadata, bool attempt_trash) -> bool +{ + if (!preserve_metadata) { + qDebug() << QString("Destroying metadata for '%1' on purpose").arg(name()); + + if (metadata()) { + Metadata::remove(index_dir, metadata()->slug); + } else { + auto n = name(); + Metadata::remove(index_dir, n); + } + } + + return destroy(attempt_trash); +} + bool Resource::isSymLinkUnder(const QString& instPath) const { if (isSymLink()) @@ -168,4 +211,4 @@ bool Resource::isSymLinkUnder(const QString& instPath) const bool Resource::isMoreThanOneHardLink() const { return FS::hardLinkCount(m_file_info.absoluteFilePath()) > 1; -} +} \ No newline at end of file diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index c1ed49461..5012c23a4 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -5,6 +5,8 @@ #include #include +#include "MetadataHandler.h" +#include "ModDetails.h" #include "QObjectPtr.h" enum class ResourceType { @@ -15,6 +17,13 @@ enum class ResourceType { LITEMOD, //!< The resource is a litemod }; +enum class ResourceStatus { + INSTALLED, // Both JAR and Metadata are present + NOT_INSTALLED, // Only the Metadata is present + NO_METADATA, // Only the JAR is present + UNKNOWN, // Default status +}; + enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER }; enum class EnableAction { ENABLE, DISABLE, TOGGLE }; @@ -46,9 +55,18 @@ class Resource : public QObject { [[nodiscard]] auto type() const -> ResourceType { return m_type; } [[nodiscard]] bool enabled() const { return m_enabled; } - [[nodiscard]] virtual auto name() const -> QString { return m_name; } + [[nodiscard]] virtual auto name() const -> QString; [[nodiscard]] virtual bool valid() const { return m_type != ResourceType::UNKNOWN; } + [[nodiscard]] auto status() const -> ResourceStatus { return m_status; }; + [[nodiscard]] auto metadata() -> std::shared_ptr { return m_metadata; } + [[nodiscard]] auto metadata() const -> std::shared_ptr { return m_metadata; } + [[nodiscard]] auto provider() const -> QString; + + void setStatus(ResourceStatus status) { m_status = status; } + void setMetadata(std::shared_ptr&& metadata); + void setMetadata(const Metadata::ModStruct& metadata) { setMetadata(std::make_shared(metadata)); } + /** Compares two Resources, for sorting purposes, considering a ascending order, returning: * > 0: 'this' comes after 'other' * = 0: 'this' is equal to 'other' @@ -81,7 +99,8 @@ class Resource : public QObject { } // Delete all files of this resource. - bool destroy(bool attemptTrash = true); + auto destroy(bool attemptTrash = true) -> bool; + auto destroy(QDir& index_dir, bool preserve_metadata = false, bool attempt_trash = true) -> bool; [[nodiscard]] auto isSymLink() const -> bool { return m_file_info.isSymLink(); } @@ -110,6 +129,11 @@ class Resource : public QObject { /* The type of file we're dealing with. */ ResourceType m_type = ResourceType::UNKNOWN; + /* Installation status of the resource. */ + ResourceStatus m_status = ResourceStatus::UNKNOWN; + + std::shared_ptr m_metadata = nullptr; + /* Whether the resource is enabled (e.g. shows up in the game) or not. */ bool m_enabled = true; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index d3237b34b..a39e9adee 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -15,14 +15,14 @@ #include "FileSystem.h" #include "QVariantUtils.h" -#include "minecraft/mod/tasks/BasicFolderLoadTask.h" +#include "minecraft/mod/tasks/ResourceFolderLoadTask.h" #include "settings/Setting.h" #include "tasks/Task.h" #include "ui/dialogs/CustomMessageBox.h" -ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObject* parent, bool create_dir) - : QAbstractListModel(parent), m_dir(dir), m_instance(instance), m_watcher(this) +ResourceFolderModel::ResourceFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) + : QAbstractListModel(parent), m_dir(dir), m_instance(instance), m_watcher(this), m_is_indexed(is_indexed) { if (create_dir) { FS::ensureFolderPathExists(m_dir.absolutePath()); @@ -290,7 +290,7 @@ void ResourceFolderModel::resolveResource(Resource* res) void ResourceFolderModel::onUpdateSucceeded() { - auto update_results = static_cast(m_current_update_task.get())->result(); + auto update_results = static_cast(m_current_update_task.get())->result(); auto& new_resources = update_results->resources; @@ -320,7 +320,11 @@ void ResourceFolderModel::onParseSucceeded(int ticket, QString resource_id) Task* ResourceFolderModel::createUpdateTask() { - return new BasicFolderLoadTask(m_dir); + auto index_dir = indexDir(); + auto task = new ResourceFolderLoadTask(dir(), index_dir, m_is_indexed, m_first_folder_load, + [this](const QFileInfo& file) { return createResource(file); }); + m_first_folder_load = false; + return task; } bool ResourceFolderModel::hasPendingParseTasks() const diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 80c31e456..3a4287b30 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -29,7 +29,7 @@ class QSortFilterProxyModel; class ResourceFolderModel : public QAbstractListModel { Q_OBJECT public: - ResourceFolderModel(QDir, BaseInstance* instance, QObject* parent = nullptr, bool create_dir = true); + ResourceFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr); ~ResourceFolderModel() override; virtual QString id() const { return "resource"; } @@ -52,6 +52,8 @@ class ResourceFolderModel : public QAbstractListModel { virtual bool startWatching() { return startWatching({ m_dir.absolutePath() }); } virtual bool stopWatching() { return stopWatching({ m_dir.absolutePath() }); } + QDir indexDir() { return { QString("%1/.index").arg(dir().absolutePath()) }; } + /** Given a path in the system, install that resource, moving it to its place in the * instance file hierarchy. * @@ -152,7 +154,9 @@ class ResourceFolderModel : public QAbstractListModel { * This Task is normally executed when opening a page, so it shouldn't contain much heavy work. * If such work is needed, try using it in the Task create by createParseTask() instead! */ - [[nodiscard]] virtual Task* createUpdateTask(); + [[nodiscard]] Task* createUpdateTask(); + + [[nodiscard]] virtual Resource* createResource(const QFileInfo& info) { return new Resource(info); } /** This creates a new parse task to be executed by onUpdateSucceeded(). * @@ -210,6 +214,9 @@ class ResourceFolderModel : public QAbstractListModel { QFileSystemWatcher m_watcher; bool m_is_watching = false; + bool m_is_indexed; + bool m_first_folder_load = true; + Task::Ptr m_current_update_task = nullptr; bool m_scheduled_update = false; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index f27431576..2e72e02f2 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -44,10 +44,11 @@ #include "Application.h" #include "Version.h" -#include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalResourcePackParseTask.h" +#include "minecraft/mod/tasks/ResourceFolderLoadTask.h" -ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) +ResourcePackFolderModel::ResourcePackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) + : ResourceFolderModel(dir, instance, is_indexed, create_dir, parent) { m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") }); @@ -173,11 +174,6 @@ int ResourcePackFolderModel::columnCount(const QModelIndex& parent) const return parent.isValid() ? 0 : NUM_COLUMNS; } -Task* ResourcePackFolderModel::createUpdateTask() -{ - return new BasicFolderLoadTask(m_dir, [](QFileInfo const& entry) { return makeShared(entry); }); -} - Task* ResourcePackFolderModel::createParseTask(Resource& resource) { return new LocalResourcePackParseTask(m_next_resolution_ticket, static_cast(resource)); diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h index 29c2c5995..fd56c8c73 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.h +++ b/launcher/minecraft/mod/ResourcePackFolderModel.h @@ -9,16 +9,16 @@ class ResourcePackFolderModel : public ResourceFolderModel { public: enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, PackFormatColumn, DateColumn, NUM_COLUMNS }; - explicit ResourcePackFolderModel(const QString& dir, BaseInstance* instance); + explicit ResourcePackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr); - virtual QString id() const override { return "resourcepacks"; } + QString id() const override { return "resourcepacks"; } [[nodiscard]] QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; [[nodiscard]] int columnCount(const QModelIndex& parent) const override; - [[nodiscard]] Task* createUpdateTask() override; + [[nodiscard]] Resource* createResource(const QFileInfo& file) override { return new ResourcePack(file); } [[nodiscard]] Task* createParseTask(Resource&) override; RESOURCE_HELPERS(ResourcePack) diff --git a/launcher/minecraft/mod/ShaderPackFolderModel.h b/launcher/minecraft/mod/ShaderPackFolderModel.h index 44ed37a47..02faee49c 100644 --- a/launcher/minecraft/mod/ShaderPackFolderModel.h +++ b/launcher/minecraft/mod/ShaderPackFolderModel.h @@ -6,7 +6,9 @@ class ShaderPackFolderModel : public ResourceFolderModel { Q_OBJECT public: - explicit ShaderPackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) {} + explicit ShaderPackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr) + : ResourceFolderModel(dir, instance, is_indexed, create_dir, parent) + {} virtual QString id() const override { return "shaderpacks"; } }; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 5c5f2b7c1..23a392421 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -39,10 +39,11 @@ #include "TexturePackFolderModel.h" -#include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalTexturePackParseTask.h" +#include "minecraft/mod/tasks/ResourceFolderLoadTask.h" -TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) +TexturePackFolderModel::TexturePackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) + : ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent) { m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified") }); @@ -52,11 +53,6 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* m_columnsHideable = { false, true, false, true }; } -Task* TexturePackFolderModel::createUpdateTask() -{ - return new BasicFolderLoadTask(m_dir, [](QFileInfo const& entry) { return makeShared(entry); }); -} - Task* TexturePackFolderModel::createParseTask(Resource& resource) { return new LocalTexturePackParseTask(m_next_resolution_ticket, static_cast(resource)); diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index b975d8641..44b19b57a 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -46,7 +46,7 @@ class TexturePackFolderModel : public ResourceFolderModel { public: enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, DateColumn, NUM_COLUMNS }; - explicit TexturePackFolderModel(const QString& dir, std::shared_ptr instance); + explicit TexturePackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr); virtual QString id() const override { return "texturepacks"; } @@ -55,8 +55,7 @@ class TexturePackFolderModel : public ResourceFolderModel { [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; [[nodiscard]] int columnCount(const QModelIndex& parent) const override; - explicit TexturePackFolderModel(const QString& dir, BaseInstance* instance); - [[nodiscard]] Task* createUpdateTask() override; + [[nodiscard]] Resource* createResource(const QFileInfo& file) override { return new TexturePack(file); } [[nodiscard]] Task* createParseTask(Resource&) override; RESOURCE_HELPERS(TexturePack) diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h deleted file mode 100644 index 23a2b649a..000000000 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -#include "minecraft/mod/Resource.h" - -#include "tasks/Task.h" - -/** Very simple task that just loads a folder's contents directly. - */ -class BasicFolderLoadTask : public Task { - Q_OBJECT - public: - struct Result { - QMap resources; - }; - using ResultPtr = std::shared_ptr; - - [[nodiscard]] ResultPtr result() const { return m_result; } - - public: - BasicFolderLoadTask(QDir dir) : Task(nullptr, false), m_dir(dir), m_result(new Result), m_thread_to_spawn_into(thread()) - { - m_create_func = [](QFileInfo const& entry) -> Resource::Ptr { return makeShared(entry); }; - } - BasicFolderLoadTask(QDir dir, std::function create_function) - : Task(nullptr, false) - , m_dir(dir) - , m_result(new Result) - , m_create_func(std::move(create_function)) - , m_thread_to_spawn_into(thread()) - {} - - [[nodiscard]] bool canAbort() const override { return true; } - bool abort() override - { - m_aborted.store(true); - return true; - } - - void executeTask() override - { - if (thread() != m_thread_to_spawn_into) - connect(this, &Task::finished, this->thread(), &QThread::quit); - - m_dir.refresh(); - for (auto entry : m_dir.entryInfoList()) { - auto resource = m_create_func(entry); - resource->moveToThread(m_thread_to_spawn_into); - m_result->resources.insert(resource->internal_id(), resource); - } - - if (m_aborted) - emit finished(); - else - emitSucceeded(); - } - - private: - QDir m_dir; - ResultPtr m_result; - - std::atomic m_aborted = false; - - std::function m_create_func; - - /** This is the thread in which we should put new mod objects */ - QThread* m_thread_to_spawn_into; -}; diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.h b/launcher/minecraft/mod/tasks/LocalModParseTask.h index a03217093..ff1ff822e 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.h @@ -47,11 +47,6 @@ class LocalModParseTask : public Task { [[nodiscard]] int token() const { return m_token; } - private: - void processAsZip(); - void processAsFolder(); - void processAsLitemod(); - private: int m_token; ResourceType m_type; diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ResourceFolderLoadTask.cpp similarity index 55% rename from launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp rename to launcher/minecraft/mod/tasks/ResourceFolderLoadTask.cpp index 9f79ba098..1004bcff0 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ResourceFolderLoadTask.cpp @@ -34,23 +34,20 @@ * limitations under the License. */ -#include "ModFolderLoadTask.h" +#include "ResourceFolderLoadTask.h" #include "minecraft/mod/MetadataHandler.h" #include -ModFolderLoadTask::ModFolderLoadTask(QDir mods_dir, QDir index_dir, bool is_indexed, bool clean_orphan) - : Task(nullptr, false) - , m_mods_dir(mods_dir) - , m_index_dir(index_dir) - , m_is_indexed(is_indexed) - , m_clean_orphan(clean_orphan) - , m_result(new Result()) - , m_thread_to_spawn_into(thread()) +ResourceFolderLoadTask::ResourceFolderLoadTask(const QDir& resource_dir, + const QDir& index_dir, + bool is_indexed, + bool clean_orphan, + std::function create_function) {} -void ModFolderLoadTask::executeTask() +void ResourceFolderLoadTask::executeTask() { if (thread() != m_thread_to_spawn_into) connect(this, &Task::finished, this->thread(), &QThread::quit); @@ -63,32 +60,32 @@ void ModFolderLoadTask::executeTask() // Read JAR files that don't have metadata m_mods_dir.refresh(); for (auto entry : m_mods_dir.entryInfoList()) { - Mod* mod(new Mod(entry)); + Resource* resource = m_create_func(entry); - if (mod->enabled()) { - if (m_result->mods.contains(mod->internal_id())) { - m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); + if (resource->enabled()) { + if (m_result->resources.contains(resource->internal_id())) { + m_result->resources[resource->internal_id()]->setStatus(ResourceStatus::INSTALLED); // Delete the object we just created, since a valid one is already in the mods list. - delete mod; + delete resource; } else { - m_result->mods[mod->internal_id()].reset(std::move(mod)); - m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata); + m_result->resources[resource->internal_id()].reset(resource); + m_result->resources[resource->internal_id()]->setStatus(ResourceStatus::NO_METADATA); } } else { - QString chopped_id = mod->internal_id().chopped(9); - if (m_result->mods.contains(chopped_id)) { - m_result->mods[mod->internal_id()].reset(std::move(mod)); + QString chopped_id = resource->internal_id().chopped(9); + if (m_result->resources.contains(chopped_id)) { + m_result->resources[resource->internal_id()].reset(resource); - auto metadata = m_result->mods[chopped_id]->metadata(); + auto metadata = m_result->resources[chopped_id]->metadata(); if (metadata) { - mod->setMetadata(*metadata); + resource->setMetadata(*metadata); - m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); - m_result->mods.remove(chopped_id); + m_result->resources[resource->internal_id()]->setStatus(ResourceStatus::INSTALLED); + m_result->resources.remove(chopped_id); } } else { - m_result->mods[mod->internal_id()].reset(std::move(mod)); - m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata); + m_result->resources[resource->internal_id()].reset(resource); + m_result->resources[resource->internal_id()]->setStatus(ResourceStatus::NO_METADATA); } } } @@ -96,17 +93,17 @@ void ModFolderLoadTask::executeTask() // Remove orphan metadata to prevent issues // See https://github.com/PolyMC/PolyMC/issues/996 if (m_clean_orphan) { - QMutableMapIterator iter(m_result->mods); + QMutableMapIterator iter(m_result->resources); while (iter.hasNext()) { - auto mod = iter.next().value(); - if (mod->status() == ModStatus::NotInstalled) { - mod->destroy(m_index_dir, false, false); + auto resource = iter.next().value(); + if (resource->status() == ResourceStatus::NOT_INSTALLED) { + resource->destroy(m_index_dir, false, false); iter.remove(); } } } - for (auto mod : m_result->mods) + for (auto mod : m_result->resources) mod->moveToThread(m_thread_to_spawn_into); if (m_aborted) @@ -115,18 +112,18 @@ void ModFolderLoadTask::executeTask() emitSucceeded(); } -void ModFolderLoadTask::getFromMetadata() +void ResourceFolderLoadTask::getFromMetadata() { m_index_dir.refresh(); for (auto entry : m_index_dir.entryList(QDir::Files)) { auto metadata = Metadata::get(m_index_dir, entry); - if (!metadata.isValid()) { + if (!metadata.isValid()) return; - } - auto* mod = new Mod(m_mods_dir, metadata); - mod->setStatus(ModStatus::NotInstalled); - m_result->mods[mod->internal_id()].reset(std::move(mod)); + auto* resource = m_create_func(QFileInfo(m_mods_dir.filePath(metadata.filename))); + resource->setMetadata(metadata); + resource->setStatus(ResourceStatus::NOT_INSTALLED); + m_result->resources[resource->internal_id()].reset(resource); } } diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h b/launcher/minecraft/mod/tasks/ResourceFolderLoadTask.h similarity index 84% rename from launcher/minecraft/mod/tasks/ModFolderLoadTask.h rename to launcher/minecraft/mod/tasks/ResourceFolderLoadTask.h index 4200ef6d9..616597ca4 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/ResourceFolderLoadTask.h @@ -44,17 +44,21 @@ #include "minecraft/mod/Mod.h" #include "tasks/Task.h" -class ModFolderLoadTask : public Task { +class ResourceFolderLoadTask : public Task { Q_OBJECT public: struct Result { - QMap mods; + QMap resources; }; using ResultPtr = std::shared_ptr; ResultPtr result() const { return m_result; } public: - ModFolderLoadTask(QDir mods_dir, QDir index_dir, bool is_indexed, bool clean_orphan = false); + ResourceFolderLoadTask(const QDir& resource_dir, + const QDir& index_dir, + bool is_indexed, + bool clean_orphan, + std::function create_function); [[nodiscard]] bool canAbort() const override { return true; } bool abort() override @@ -76,6 +80,8 @@ class ModFolderLoadTask : public Task { std::atomic m_aborted = false; + std::function m_create_func; + /** This is the thread in which we should put new mod objects */ QThread* m_thread_to_spawn_into; }; diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index c3eadd06d..05caa33c9 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -94,7 +94,7 @@ void EnsureMetadataTask::executeTask() } // They already have the right metadata :o - if (mod->status() != ModStatus::NoMetadata && mod->metadata() && mod->metadata()->provider == m_provider) { + if (mod->status() != ResourceStatus::NO_METADATA && mod->metadata() && mod->metadata()->provider == m_provider) { qDebug() << "Mod" << mod->name() << "already has metadata!"; emitReady(mod); continue; diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp index 476a4667a..6653e477e 100644 --- a/launcher/modplatform/flame/FlameCheckUpdate.cpp +++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp @@ -154,7 +154,7 @@ void FlameCheckUpdate::executeTask() continue; } - if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) { + if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ResourceStatus::NOT_INSTALLED)) { // Fake pack with the necessary info to pass to the download task :) auto pack = std::make_shared(); pack->name = mod->name(); @@ -167,7 +167,7 @@ void FlameCheckUpdate::executeTask() pack->provider = ModPlatform::ResourceProvider::FLAME; auto old_version = mod->version(); - if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) { + if (old_version.isEmpty() && mod->status() != ResourceStatus::NOT_INSTALLED) { auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt()); old_version = current_ver.version; } diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index c65f4fa80..574e99ac7 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -144,7 +144,7 @@ void ModrinthCheckUpdate::executeTask() auto mod = *mod_iter; auto key = project_ver.hash; - if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) { + if ((key != hash && project_ver.is_preferred) || (mod->status() == ResourceStatus::NOT_INSTALLED)) { if (mod->version() == project_ver.version_number) continue; diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index a9ddb0c91..72b52836f 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -121,7 +121,7 @@ void ModrinthPackExportTask::collectHashes() modIter != allMods.end()) { const Mod* mod = *modIter; if (mod->metadata() != nullptr) { - QUrl& url = mod->metadata()->url; + const QUrl& url = mod->metadata()->url; // ensure the url is permitted on modrinth.com if (!url.isEmpty() && BuildConfig.MODRINTH_MRPACK_HOSTS.contains(url.host())) { qDebug() << "Resolving" << relative << "from index"; diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 7edc18cde..c49165557 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -35,6 +35,7 @@ auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool shoul class V1 { public: + // can also represent other resources beside loader mods - but this is what packwiz calls it struct Mod { QString slug{}; QString name{}; diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 1f0fa7cd2..f1216572f 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -228,7 +228,7 @@ auto ModUpdateDialog::ensureMetadata() -> bool }; for (auto candidate : m_candidates) { - if (candidate->status() != ModStatus::NoMetadata) { + if (candidate->status() != ResourceStatus::NO_METADATA) { onMetadataEnsured(candidate); continue; }