From ab725eeb1816aea428107dcc9ed9184136c7f766 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 15 Oct 2023 11:52:28 +0300 Subject: [PATCH 01/64] corected side and added loaders Signed-off-by: Trial97 --- launcher/modplatform/ModIndex.cpp | 19 ++++++++++++++++++- launcher/modplatform/ModIndex.h | 4 +++- launcher/modplatform/flame/FlameModIndex.cpp | 6 ++++++ launcher/modplatform/modrinth/ModrinthAPI.h | 2 +- launcher/modplatform/packwiz/Packwiz.cpp | 19 ++++++++++++++++++- launcher/modplatform/packwiz/Packwiz.h | 1 + 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index fc79dff15..5b7624563 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -117,7 +117,7 @@ QString getMetaURL(ResourceProvider provider, QVariant projectID) projectID.toString(); } -auto getModLoaderString(ModLoaderType type) -> const QString +auto getModLoaderAsString(ModLoaderType type) -> const QString { switch (type) { case NeoForge: @@ -138,4 +138,21 @@ auto getModLoaderString(ModLoaderType type) -> const QString return ""; } +auto getModLoaderFromString(QString type) -> const ModLoaderType +{ + if (type == "neoforge") + return NeoForge; + if (type == "forge") + return Forge; + if (type == "cauldron") + return Cauldron; + if (type == "liteloader") + return LiteLoader; + if (type == "fabric") + return Fabric; + if (type == "quilt") + return Quilt; + return {}; +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 72294c399..940dddea0 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -109,6 +109,7 @@ struct IndexedVersion { bool is_preferred = true; QString changelog; QList dependencies; + QString side; // this is for flame API // For internal use, not provided by APIs bool is_currently_selected = false; @@ -181,7 +182,8 @@ inline auto getOverrideDeps() -> QList QString getMetaURL(ResourceProvider provider, QVariant projectID); -auto getModLoaderString(ModLoaderType type) -> const QString; +auto getModLoaderAsString(ModLoaderType type) -> const QString; +auto getModLoaderFromString(QString type) -> const ModLoaderType; constexpr bool hasSingleModLoaderSelected(ModLoaderTypes l) noexcept { diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 345883c17..75c10d6f5 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -130,6 +130,12 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> file.loaders |= ModPlatform::Fabric; if (loader == "quilt") file.loaders |= ModPlatform::Quilt; + if (loader == "server" || loader == "client") { + if (file.side.isEmpty()) + file.side = loader; + else if (file.side != loader) + file.side = "both"; + } } file.addonId = Json::requireInteger(obj, "modId"); diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index d0f0811b2..857719902 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -41,7 +41,7 @@ class ModrinthAPI : public NetworkResourceAPI { for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt, ModPlatform::LiteLoader }) { if (types & loader) { - l << getModLoaderString(loader); + l << getModLoaderAsString(loader); } } return l; diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index e35567f24..90d7d0ed7 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -113,7 +113,8 @@ auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedP mod.provider = mod_pack.provider; mod.file_id = mod_version.fileId; mod.project_id = mod_pack.addonId; - mod.side = stringToSide(mod_pack.side); + mod.side = stringToSide(mod_version.side.isEmpty() ? mod_pack.side : mod_version.side); + mod.loaders = mod_version.loaders; return mod; } @@ -181,6 +182,14 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) break; } + toml::array loaders; + for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Cauldron, ModPlatform::LiteLoader, ModPlatform::Fabric, + ModPlatform::Quilt }) { + if (mod.loaders & loader) { + loaders.push_back(getModLoaderAsString(loader)); + } + } + if (!index_file.open(QIODevice::ReadWrite)) { qCritical() << QString("Could not open file %1!").arg(normalized_fname); return; @@ -192,6 +201,7 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) auto tbl = toml::table{ { "name", mod.name.toStdString() }, { "filename", mod.filename.toStdString() }, { "side", sideToString(mod.side).toStdString() }, + { "loader", loaders }, { "download", toml::table{ { "mode", mod.mode.toStdString() }, @@ -276,6 +286,13 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod mod.name = stringEntry(table, "name"); mod.filename = stringEntry(table, "filename"); mod.side = stringToSide(stringEntry(table, "side")); + if (auto loaders = table["loaders"]; loaders && loaders.is_array()) { + for (auto&& loader : *loaders.as_array()) { + if (loader.is_string()) { + mod.loaders |= ModPlatform::getModLoaderFromString(QString::fromStdString(loader.as_string()->value_or(""))); + } + } + } } { // [download] info diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index dce198b0e..a61bb0503 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -41,6 +41,7 @@ class V1 { QString name{}; QString filename{}; Side side{ Side::UniversalSide }; + ModPlatform::ModLoaderTypes loaders; // [download] QString mode{}; From 749975e8ef96ba780aa910217911ff0af6ecbe5b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 15 Oct 2023 12:46:23 +0300 Subject: [PATCH 02/64] made side and loaders visible to user Signed-off-by: Trial97 --- launcher/minecraft/mod/MetadataHandler.h | 2 ++ launcher/minecraft/mod/Mod.cpp | 29 +++++++++++++++ launcher/minecraft/mod/Mod.h | 3 ++ launcher/minecraft/mod/ModFolderModel.cpp | 35 ++++++++++++++++--- launcher/minecraft/mod/ModFolderModel.h | 12 ++++++- launcher/minecraft/mod/Resource.h | 2 +- .../modrinth/ModrinthCheckUpdate.cpp | 2 +- launcher/modplatform/packwiz/Packwiz.cpp | 4 +-- 8 files changed, 79 insertions(+), 10 deletions(-) diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 3496da2a0..ccdd7d559 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -52,4 +52,6 @@ class Metadata { static auto get(QDir& index_dir, QString mod_slug) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_slug); } static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_id); } + + static auto modSideToString(ModSide side) -> QString { return Packwiz::V1::sideToString(side); } }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 310946379..132f99f7d 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -45,6 +45,7 @@ #include "MetadataHandler.h" #include "Version.h" #include "minecraft/mod/ModDetails.h" +#include "minecraft/mod/Resource.h" #include "minecraft/mod/tasks/LocalModParseTask.h" static ModPlatform::ProviderCapabilities ProviderCaps; @@ -109,6 +110,20 @@ std::pair Mod::compare(const Resource& other, SortType type) const return { compare_result, type == SortType::PROVIDER }; break; } + case SortType::SIDE: { + if (side() > cast_other->side()) + return { 1, type == SortType::SIDE }; + else if (side() < cast_other->side()) + return { -1, type == SortType::SIDE }; + break; + } + case SortType::LOADERS: { + if (loaders() > cast_other->loaders()) + return { 1, type == SortType::LOADERS }; + else if (loaders() < cast_other->loaders()) + return { -1, type == SortType::LOADERS }; + break; + } } return { 0, false }; } @@ -232,6 +247,20 @@ auto Mod::provider() const -> std::optional return {}; } +auto Mod::side() const -> Metadata::ModSide +{ + if (metadata()) + return metadata()->side; + return Metadata::ModSide::UniversalSide; +} + +auto Mod::loaders() const -> ModPlatform::ModLoaderTypes +{ + if (metadata()) + return metadata()->loaders; + 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 e97ee9d3b..970f85a00 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -47,6 +47,7 @@ #include "ModDetails.h" #include "Resource.h" +#include "modplatform/ModIndex.h" class Mod : public Resource { Q_OBJECT @@ -70,6 +71,8 @@ class Mod : public Resource { auto licenses() const -> const QList&; auto issueTracker() const -> QString; auto metaurl() const -> QString; + auto side() const -> Metadata::ModSide; + auto loaders() const -> ModPlatform::ModLoaderTypes; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index a5f1489dd..631425a72 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -52,6 +52,8 @@ #include "Application.h" #include "Json.h" +#include "minecraft/mod/MetadataHandler.h" +#include "minecraft/mod/Resource.h" #include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModUpdateTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h" @@ -62,12 +64,15 @@ 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) { - 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") }); - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; + m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Side", "Loaders" }); + m_column_names_translated = QStringList( + { tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"), tr("Side"), tr("Loaders") }); + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, + SortType::DATE, SortType::PROVIDER, SortType::SIDE, SortType::LOADERS }; m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, - QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; - m_columnsHideable = { false, true, false, true, true, true }; + QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, + QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; + m_columnsHideable = { false, true, false, true, true, true, true, true }; } QVariant ModFolderModel::data(const QModelIndex& index, int role) const @@ -105,6 +110,20 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const return provider.value(); } + case SideColumn: { + return Metadata::modSideToString(at(row)->side()); + } + case LoadersColumn: { + QStringList loaders; + auto modLoaders = at(row)->loaders(); + for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Cauldron, ModPlatform::LiteLoader, + ModPlatform::Fabric, ModPlatform::Quilt }) { + if (modLoaders & loader) { + loaders << getModLoaderAsString(loader); + } + } + return loaders.join(","); + } default: return QVariant(); } @@ -154,6 +173,8 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio case DateColumn: case ProviderColumn: case ImageColumn: + case SideColumn: + case LoadersColumn: return columnNames().at(section); default: return QVariant(); @@ -171,6 +192,10 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio return tr("The date and time this mod was last changed (or added)."); case ProviderColumn: return tr("Where the mod was downloaded from."); + case SideColumn: + return tr("On what environment the mod is running."); + case LoadersColumn: + return tr("The mod loader."); default: return QVariant(); } diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 61d840f9b..1623fadfe 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -61,7 +61,17 @@ class QFileSystemWatcher; class ModFolderModel : public ResourceFolderModel { Q_OBJECT public: - enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, VersionColumn, DateColumn, ProviderColumn, NUM_COLUMNS }; + enum Columns { + ActiveColumn = 0, + ImageColumn, + NameColumn, + VersionColumn, + DateColumn, + ProviderColumn, + SideColumn, + LoadersColumn, + NUM_COLUMNS + }; enum ModStatusAction { Disable, Enable, Toggle }; ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed = false, bool create_dir = true); diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index c1ed49461..eefb5f8a5 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -15,7 +15,7 @@ enum class ResourceType { LITEMOD, //!< The resource is a litemod }; -enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER }; +enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER, SIDE, LOADERS }; enum class EnableAction { ENABLE, DISABLE, TOGGLE }; diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 9b7c53854..7d491f4fe 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -114,7 +114,7 @@ void ModrinthCheckUpdate::executeTask() ModPlatform::ModLoaderType::Fabric, ModPlatform::ModLoaderType::Quilt }; for (auto flag : flags) { if (m_loaders.value().testFlag(flag)) { - loader_filter = ModPlatform::getModLoaderString(flag); + loader_filter = ModPlatform::getModLoaderAsString(flag); break; } } diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 90d7d0ed7..f15ab9e7a 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -186,7 +186,7 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Cauldron, ModPlatform::LiteLoader, ModPlatform::Fabric, ModPlatform::Quilt }) { if (mod.loaders & loader) { - loaders.push_back(getModLoaderAsString(loader)); + loaders.push_back(getModLoaderAsString(loader).toStdString()); } } @@ -201,7 +201,7 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) auto tbl = toml::table{ { "name", mod.name.toStdString() }, { "filename", mod.filename.toStdString() }, { "side", sideToString(mod.side).toStdString() }, - { "loader", loaders }, + { "loaders", loaders }, { "download", toml::table{ { "mode", mod.mode.toStdString() }, From b54376062e87b9f278b3953da5f7f1bb04695b49 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 17 Oct 2023 19:25:01 +0300 Subject: [PATCH 03/64] Added mcVersion column Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 15 ++++++++++++ launcher/minecraft/mod/Mod.h | 1 + launcher/minecraft/mod/ModFolderModel.cpp | 23 ++++++++++++------- launcher/minecraft/mod/ModFolderModel.h | 1 + launcher/minecraft/mod/Resource.h | 2 +- launcher/modplatform/ModIndex.cpp | 2 +- launcher/modplatform/ModIndex.h | 2 +- launcher/modplatform/flame/FlameModIndex.cpp | 16 ++++++------- .../modrinth/ModrinthPackIndex.cpp | 10 ++++---- launcher/modplatform/packwiz/Packwiz.cpp | 18 +++++++++++++++ launcher/modplatform/packwiz/Packwiz.h | 1 + 11 files changed, 67 insertions(+), 24 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 132f99f7d..22e652319 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -124,6 +124,14 @@ std::pair Mod::compare(const Resource& other, SortType type) const return { -1, type == SortType::LOADERS }; break; } + case SortType::MC_VERSIONS: { + auto thisVersion = mcVersions().join(","); + auto otherVersion = cast_other->mcVersions().join(","); + auto compare_result = QString::compare(thisVersion, otherVersion, Qt::CaseInsensitive); + if (compare_result != 0) + return { compare_result, type == SortType::MC_VERSIONS }; + break; + } } return { 0, false }; } @@ -261,6 +269,13 @@ auto Mod::loaders() const -> ModPlatform::ModLoaderTypes return {}; } +auto Mod::mcVersions() const -> QStringList +{ + if (metadata()) + return metadata()->mcVersions; + 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 970f85a00..92de65889 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -73,6 +73,7 @@ class Mod : public Resource { auto metaurl() const -> QString; auto side() const -> Metadata::ModSide; auto loaders() const -> ModPlatform::ModLoaderTypes; + auto mcVersions() const -> QStringList; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 631425a72..ef4ab957c 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -64,15 +64,16 @@ 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) { - m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Side", "Loaders" }); - m_column_names_translated = QStringList( - { tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"), tr("Side"), tr("Loaders") }); - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, - SortType::DATE, SortType::PROVIDER, SortType::SIDE, SortType::LOADERS }; + m_column_names = + QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Side", "Loaders", "Miecraft Versions" }); + m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"), + tr("Side"), tr("Loaders"), tr("Miecraft Versions") }); + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, + SortType::PROVIDER, SortType::SIDE, SortType::LOADERS, SortType::MC_VERSIONS }; m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, - QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; - m_columnsHideable = { false, true, false, true, true, true, true, true }; + QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; + m_columnsHideable = { false, true, false, true, true, true, true, true, true }; } QVariant ModFolderModel::data(const QModelIndex& index, int role) const @@ -122,7 +123,10 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const loaders << getModLoaderAsString(loader); } } - return loaders.join(","); + return loaders.join(", "); + } + case McVersionsColumn: { + return at(row)->mcVersions().join(", "); } default: return QVariant(); @@ -175,6 +179,7 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio case ImageColumn: case SideColumn: case LoadersColumn: + case McVersionsColumn: return columnNames().at(section); default: return QVariant(); @@ -196,6 +201,8 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio return tr("On what environment the mod is running."); case LoadersColumn: return tr("The mod loader."); + case McVersionsColumn: + return tr("The supported minecraft versions."); default: return QVariant(); } diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 1623fadfe..f9a87a741 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -70,6 +70,7 @@ class ModFolderModel : public ResourceFolderModel { ProviderColumn, SideColumn, LoadersColumn, + McVersionsColumn, NUM_COLUMNS }; enum ModStatusAction { Disable, Enable, Toggle }; diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index eefb5f8a5..c46980837 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -15,7 +15,7 @@ enum class ResourceType { LITEMOD, //!< The resource is a litemod }; -enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER, SIDE, LOADERS }; +enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER, SIDE, LOADERS, MC_VERSIONS }; enum class EnableAction { ENABLE, DISABLE, TOGGLE }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 5b7624563..2cd7710e3 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -138,7 +138,7 @@ auto getModLoaderAsString(ModLoaderType type) -> const QString return ""; } -auto getModLoaderFromString(QString type) -> const ModLoaderType +auto getModLoaderFromString(QString type) -> ModLoaderType { if (type == "neoforge") return NeoForge; diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 940dddea0..7c472ec9b 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -183,7 +183,7 @@ inline auto getOverrideDeps() -> QList QString getMetaURL(ResourceProvider provider, QVariant projectID); auto getModLoaderAsString(ModLoaderType type) -> const QString; -auto getModLoaderFromString(QString type) -> const ModLoaderType; +auto getModLoaderFromString(QString type) -> ModLoaderType; constexpr bool hasSingleModLoaderSelected(ModLoaderTypes l) noexcept { diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 75c10d6f5..d56e46b23 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -117,20 +117,20 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> if (str.contains('.')) file.mcVersion.append(str); - auto loader = str.toLower(); - if (loader == "neoforge") + + if (auto loader = str.toLower(); loader == "neoforge") file.loaders |= ModPlatform::NeoForge; - if (loader == "forge") + else if (loader == "forge") file.loaders |= ModPlatform::Forge; - if (loader == "cauldron") + else if (loader == "cauldron") file.loaders |= ModPlatform::Cauldron; - if (loader == "liteloader") + else if (loader == "liteloader") file.loaders |= ModPlatform::LiteLoader; - if (loader == "fabric") + else if (loader == "fabric") file.loaders |= ModPlatform::Fabric; - if (loader == "quilt") + else if (loader == "quilt") file.loaders |= ModPlatform::Quilt; - if (loader == "server" || loader == "client") { + else if (loader == "server" || loader == "client") { if (file.side.isEmpty()) file.side = loader; else if (file.side != loader) diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 7d0893261..23770b7fb 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -152,15 +152,15 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t for (auto loader : loaders) { if (loader == "neoforge") file.loaders |= ModPlatform::NeoForge; - if (loader == "forge") + else if (loader == "forge") file.loaders |= ModPlatform::Forge; - if (loader == "cauldron") + else if (loader == "cauldron") file.loaders |= ModPlatform::Cauldron; - if (loader == "liteloader") + else if (loader == "liteloader") file.loaders |= ModPlatform::LiteLoader; - if (loader == "fabric") + else if (loader == "fabric") file.loaders |= ModPlatform::Fabric; - if (loader == "quilt") + else if (loader == "quilt") file.loaders |= ModPlatform::Quilt; } file.version = Json::requireString(obj, "name"); diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index f15ab9e7a..0692a627d 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -115,6 +115,8 @@ auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedP mod.project_id = mod_pack.addonId; mod.side = stringToSide(mod_version.side.isEmpty() ? mod_pack.side : mod_version.side); mod.loaders = mod_version.loaders; + mod.mcVersions = mod_version.mcVersion; + mod.mcVersions.sort(); return mod; } @@ -189,6 +191,10 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) loaders.push_back(getModLoaderAsString(loader).toStdString()); } } + toml::array mcVersions; + for (auto version : mod.mcVersions) { + mcVersions.push_back(version.toStdString()); + } if (!index_file.open(QIODevice::ReadWrite)) { qCritical() << QString("Could not open file %1!").arg(normalized_fname); @@ -202,6 +208,7 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) { "filename", mod.filename.toStdString() }, { "side", sideToString(mod.side).toStdString() }, { "loaders", loaders }, + { "mcVersions", mcVersions }, { "download", toml::table{ { "mode", mod.mode.toStdString() }, @@ -293,6 +300,17 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod } } } + if (auto versions = table["mcVersions"]; versions && versions.is_array()) { + for (auto&& version : *versions.as_array()) { + if (version.is_string()) { + auto ver = QString::fromStdString(version.as_string()->value_or("")); + if (!ver.isEmpty()) { + mod.mcVersions << ver; + } + } + } + mod.mcVersions.sort(); + } } { // [download] info diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index a61bb0503..5cf99e74a 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -42,6 +42,7 @@ class V1 { QString filename{}; Side side{ Side::UniversalSide }; ModPlatform::ModLoaderTypes loaders; + QStringList mcVersions; // [download] QString mode{}; From fea4c4eba8bd6d919e1fd2cb96a25b2bc0968894 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 18 Oct 2023 09:00:45 +0300 Subject: [PATCH 04/64] Updated filters Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 1 + launcher/modplatform/ModIndex.cpp | 3 +- .../ui/dialogs/ResourceDownloadDialog.cpp | 1 + launcher/ui/pages/modplatform/ModModel.cpp | 10 +- launcher/ui/pages/modplatform/ModPage.cpp | 9 +- launcher/ui/pages/modplatform/ModPage.h | 3 +- .../modplatform/flame/FlameResourceModels.cpp | 1 + launcher/ui/widgets/ModFilterWidget.cpp | 250 ++++++++++-------- launcher/ui/widgets/ModFilterWidget.h | 55 ++-- launcher/ui/widgets/ModFilterWidget.ui | 156 +++++++++-- 10 files changed, 311 insertions(+), 178 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index df8c690af..deec0db7c 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -23,6 +23,7 @@ #include #include "Json.h" #include "QObjectPtr.h" +#include "minecraft/PackProfile.h" #include "minecraft/mod/MetadataHandler.h" #include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 2cd7710e3..d2113320a 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -94,10 +94,9 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t { QCryptographicHash::Algorithm algo = QCryptographicHash::Sha1; switch (p) { - case ResourceProvider::MODRINTH: { + case ResourceProvider::MODRINTH: algo = (type == "sha1") ? QCryptographicHash::Sha1 : QCryptographicHash::Sha512; break; - } case ResourceProvider::FLAME: algo = (type == "sha1") ? QCryptographicHash::Sha1 : QCryptographicHash::Md5; break; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index dc7cfff06..f21502365 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -27,6 +27,7 @@ #include "Application.h" #include "ResourceDownloadTask.h" +#include "minecraft/PackProfile.h" #include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ResourcePackFolderModel.h" #include "minecraft/mod/ShaderPackFolderModel.h" diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index c628f74ac..3b53d1348 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -25,15 +25,18 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() Q_ASSERT(m_filter); std::optional> versions{}; + auto loaders = profile->getSupportedModLoaders(); { // Version filter if (!m_filter->versions.empty()) versions = m_filter->versions; + if (m_filter->loaders) + loaders = m_filter->loaders; } auto sort = getCurrentSortingMethodByIndex(); - return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, profile->getSupportedModLoaders(), versions }; + return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions }; } ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry) @@ -45,10 +48,13 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en Q_ASSERT(m_filter); std::optional> versions{}; + auto loaders = profile->getSupportedModLoaders(); if (!m_filter->versions.empty()) versions = m_filter->versions; + if (m_filter->loaders) + loaders = m_filter->loaders; - return { pack, versions, profile->getSupportedModLoaders() }; + return { pack, versions, loaders }; } ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(QModelIndex& entry) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index d6cc1fdcc..838cf21c8 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -71,7 +71,6 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) m_ui->gridLayout_3->addWidget(m_filter_widget.get(), 0, 0, 1, m_ui->gridLayout_3->columnCount()); - m_filter_widget->setInstance(&static_cast(m_base_instance)); m_filter = m_filter_widget->getFilter(); connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, @@ -89,13 +88,14 @@ void ModPage::filterMods() void ModPage::triggerSearch() { + auto changed = m_filter_widget->changed(); m_filter = m_filter_widget->getFilter(); m_ui->packView->clearSelection(); m_ui->packDescription->clear(); m_ui->versionSelectionBox->clear(); updateSelectionButton(); - static_cast(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt(), m_filter_widget->changed()); + static_cast(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt(), changed); m_fetch_progress.watch(m_model->activeSearchJob().get()); } @@ -116,6 +116,9 @@ void ModPage::updateVersionList() auto packProfile = (dynamic_cast(m_base_instance)).getPackProfile(); QString mcVersion = packProfile->getComponentVersion("net.minecraft"); + auto loaders = packProfile->getSupportedModLoaders(); + if (m_filter->loaders) + loaders = m_filter->loaders; auto current_pack = getCurrentPack(); if (!current_pack) @@ -124,7 +127,7 @@ void ModPage::updateVersionList() auto version = current_pack->versions[i]; bool valid = false; for (auto& mcVer : m_filter->versions) { - if (validateVersion(version, mcVer.toString(), packProfile->getSupportedModLoaders())) { + if (validateVersion(version, mcVer.toString(), loaders)) { valid = true; break; } diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index 5a43e49a6..6efb318ea 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -31,8 +31,7 @@ class ModPage : public ResourcePage { auto page = new T(dialog, instance); auto model = static_cast(page->getModel()); - auto filter_widget = - ModFilterWidget::create(static_cast(instance).getPackProfile()->getComponentVersion("net.minecraft"), page); + auto filter_widget = ModFilterWidget::create(&static_cast(instance), page); page->setFilterWidget(filter_widget); model->setFilter(page->getFilter()); diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp index 7d18e72a6..39a2a0d6a 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp @@ -6,6 +6,7 @@ #include "Json.h" +#include "minecraft/PackProfile.h" #include "modplatform/flame/FlameAPI.h" #include "modplatform/flame/FlameModIndex.h" diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index c2c099eeb..62a8eb154 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -1,13 +1,70 @@ #include "ModFilterWidget.h" +#include +#include +#include "BaseVersionList.h" +#include "meta/Index.h" +#include "modplatform/ModIndex.h" #include "ui_ModFilterWidget.h" #include "Application.h" +#include "minecraft/PackProfile.h" -unique_qobject_ptr ModFilterWidget::create(Version default_version, QWidget* parent) +unique_qobject_ptr ModFilterWidget::create(MinecraftInstance* instance, QWidget* parent) { - auto filter_widget = new ModFilterWidget(default_version, parent); + return unique_qobject_ptr(new ModFilterWidget(instance, parent)); +} - if (!filter_widget->versionList()->isLoaded()) { +ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, QWidget* parent) + : QTabWidget(parent), ui(new Ui::ModFilterWidget), m_instance(instance), m_filter(new Filter()) +{ + ui->setupUi(this); + + m_versions_proxy = new VersionProxyModel(this); + + ui->versionsCb->setModel(m_versions_proxy); + + m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter("(release)", false)); + + ui->versionsCb->setStyleSheet("combobox-popup: 0;"); + connect(ui->snapshotsCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onIncludeSnapshotsChanged); + connect(ui->versionsCb, &QComboBox::currentIndexChanged, this, &ModFilterWidget::onVersionFilterChanged); + + connect(ui->neoForgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->forgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->fabricCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->quiltCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->liteLoaderCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->cauldronCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + + ui->liteLoaderCb->hide(); + ui->cauldronCb->hide(); + + connect(ui->serverEnv, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged); + connect(ui->clientEnv, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged); + + connect(ui->hide_installed, &QCheckBox::stateChanged, this, &ModFilterWidget::onHideInstalledFilterChanged); + + setHidden(true); + loadVersionList(); + prepareBasicFilter(); +} + +auto ModFilterWidget::getFilter() -> std::shared_ptr +{ + m_filter_changed = false; + emit filterUnchanged(); + return m_filter; +} + +ModFilterWidget::~ModFilterWidget() +{ + delete ui; +} + +void ModFilterWidget::loadVersionList() +{ + m_version_list = APPLICATION->metadataIndex()->get("net.minecraft"); + if (!m_version_list->isLoaded()) { QEventLoop load_version_list_loop; QTimer time_limit_for_list_load; @@ -16,10 +73,12 @@ unique_qobject_ptr ModFilterWidget::create(Version default_vers time_limit_for_list_load.callOnTimeout(&load_version_list_loop, &QEventLoop::quit); time_limit_for_list_load.start(4000); - auto task = filter_widget->versionList()->getLoadTask(); + auto task = m_version_list->getLoadTask(); - connect(task.get(), &Task::failed, - [filter_widget] { filter_widget->disableVersionButton(VersionButtonID::Major, tr("failed to get version index")); }); + connect(task.get(), &Task::failed, [this] { + ui->versionsCb->setEnabled(false); + ui->snapshotsCb->setEnabled(false); + }); connect(task.get(), &Task::finished, &load_version_list_loop, &QEventLoop::quit); if (!task->isRunning()) @@ -29,128 +88,93 @@ unique_qobject_ptr ModFilterWidget::create(Version default_vers if (time_limit_for_list_load.isActive()) time_limit_for_list_load.stop(); } - - return unique_qobject_ptr(filter_widget); + m_versions_proxy->setSourceModel(m_version_list.get()); } -ModFilterWidget::ModFilterWidget(Version def, QWidget* parent) : QTabWidget(parent), m_filter(new Filter()), ui(new Ui::ModFilterWidget) +void ModFilterWidget::prepareBasicFilter() { - ui->setupUi(this); - - m_mcVersion_buttons.addButton(ui->strictVersionButton, VersionButtonID::Strict); - ui->strictVersionButton->click(); - m_mcVersion_buttons.addButton(ui->majorVersionButton, VersionButtonID::Major); - m_mcVersion_buttons.addButton(ui->allVersionsButton, VersionButtonID::All); - // m_mcVersion_buttons.addButton(ui->betweenVersionsButton, VersionButtonID::Between); - - connect(&m_mcVersion_buttons, SIGNAL(idClicked(int)), this, SLOT(onVersionFilterChanged(int))); - - m_filter->versions.push_front(def); - - m_version_list = APPLICATION->metadataIndex()->get("net.minecraft"); - setHidden(true); + m_filter->hideInstalled = false; + m_filter->side = ""; // or "both"t + auto loaders = m_instance->getPackProfile()->getSupportedModLoaders().value(); + ui->neoForgeCb->setChecked(loaders & ModPlatform::NeoForge); + ui->forgeCb->setChecked(loaders & ModPlatform::Forge); + ui->fabricCb->setChecked(loaders & ModPlatform::Fabric); + ui->quiltCb->setChecked(loaders & ModPlatform::Quilt); + ui->liteLoaderCb->setChecked(loaders & ModPlatform::LiteLoader); + ui->cauldronCb->setChecked(loaders & ModPlatform::Cauldron); + m_filter->loaders = loaders; + auto def = m_instance->getPackProfile()->getComponentVersion("net.minecraft"); + m_filter->versions.push_front(Version{ def }); + m_versions_proxy->setCurrentVersion(def); + ui->versionsCb->setCurrentIndex(m_versions_proxy->getVersion(def).row()); } -void ModFilterWidget::setInstance(MinecraftInstance* instance) +void ModFilterWidget::onIncludeSnapshotsChanged() { - m_instance = instance; - - ui->strictVersionButton->setText(tr("Strict match (= %1)").arg(mcVersionStr())); - - // we can't do this for snapshots sadly - if (mcVersionStr().contains('.')) { - auto mcVersionSplit = mcVersionStr().split("."); - ui->majorVersionButton->setText(tr("Major version match (= %1.%2.x)").arg(mcVersionSplit[0], mcVersionSplit[1])); - } else { - ui->majorVersionButton->setText(tr("Major version match (unsupported)")); - disableVersionButton(Major); - } - ui->allVersionsButton->setText(tr("Any version")); - // ui->betweenVersionsButton->setText( - // tr("Between two versions")); + QString filter = "(release)"; + if (ui->snapshotsCb->isChecked()) + filter += "|(snapshot)"; + m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter(filter, false)); } -auto ModFilterWidget::getFilter() -> std::shared_ptr +void ModFilterWidget::onVersionFilterChanged() { - m_last_version_id = m_version_id; - emit filterUnchanged(); - return m_filter; -} - -void ModFilterWidget::disableVersionButton(VersionButtonID id, QString reason) -{ - QAbstractButton* btn = nullptr; - - switch (id) { - case (VersionButtonID::Strict): - btn = ui->strictVersionButton; - break; - case (VersionButtonID::Major): - btn = ui->majorVersionButton; - break; - case (VersionButtonID::All): - btn = ui->allVersionsButton; - break; - case (VersionButtonID::Between): - default: - break; - } - - if (btn) { - btn->setEnabled(false); - if (!reason.isEmpty()) - btn->setText(btn->text() + QString(" (%1)").arg(reason)); - } -} - -void ModFilterWidget::onVersionFilterChanged(int id) -{ - // ui->lowerVersionComboBox->setEnabled(id == VersionButtonID::Between); - // ui->upperVersionComboBox->setEnabled(id == VersionButtonID::Between); - - int index = 1; - - auto cast_id = (VersionButtonID)id; - if (cast_id != m_version_id) { - m_version_id = cast_id; - } else { - return; - } - + auto version = ui->versionsCb->currentData(BaseVersionList::VersionIdRole).toString(); m_filter->versions.clear(); + m_filter->versions.push_front(version); + m_filter_changed = true; + emit filterChanged(); +} - switch (cast_id) { - case (VersionButtonID::Strict): - m_filter->versions.push_front(mcVersion()); - break; - case (VersionButtonID::Major): { - auto versionSplit = mcVersionStr().split("."); - - auto major_version = QString("%1.%2").arg(versionSplit[0], versionSplit[1]); - QString version_str = major_version; - - while (m_version_list->hasVersion(version_str)) { - m_filter->versions.emplace_back(version_str); - version_str = QString("%1.%2").arg(major_version, QString::number(index++)); - } - - break; - } - case (VersionButtonID::All): - // Empty list to avoid enumerating all versions :P - break; - case (VersionButtonID::Between): - // TODO - break; - } - - if (changed()) +void ModFilterWidget::onLoadersFilterChanged() +{ + ModPlatform::ModLoaderTypes loaders; + if (ui->neoForgeCb->isChecked()) + loaders |= ModPlatform::NeoForge; + if (ui->forgeCb->isChecked()) + loaders |= ModPlatform::Forge; + if (ui->fabricCb->isChecked()) + loaders |= ModPlatform::Fabric; + if (ui->quiltCb->isChecked()) + loaders |= ModPlatform::Quilt; + if (ui->cauldronCb->isChecked()) + loaders |= ModPlatform::Cauldron; + if (ui->liteLoaderCb->isChecked()) + loaders |= ModPlatform::LiteLoader; + m_filter_changed = loaders != m_filter->loaders; + m_filter->loaders = loaders; + if (m_filter_changed) emit filterChanged(); else emit filterUnchanged(); } -ModFilterWidget::~ModFilterWidget() +void ModFilterWidget::onSideFilterChanged() { - delete ui; + QString side; + if (ui->serverEnv->isChecked()) + side = "server"; + if (ui->clientEnv->isChecked()) { + if (side.isEmpty()) + side = "client"; + else + side = ""; // or both + } + m_filter_changed = side != m_filter->side; + m_filter->side = side; + if (m_filter_changed) + emit filterChanged(); + else + emit filterUnchanged(); } + +void ModFilterWidget::onHideInstalledFilterChanged() +{ + auto hide = ui->hide_installed->isChecked(); + m_filter_changed = hide != m_filter->hideInstalled; + m_filter->hideInstalled = hide; + if (m_filter_changed) + emit filterChanged(); + else + emit filterUnchanged(); +} \ No newline at end of file diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index ed6cd0ea7..b92437a4f 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -5,11 +5,11 @@ #include "Version.h" -#include "meta/Index.h" +#include "VersionProxyModel.h" #include "meta/VersionList.h" #include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" +#include "modplatform/ModIndex.h" class MinecraftInstance; @@ -20,42 +20,37 @@ class ModFilterWidget; class ModFilterWidget : public QTabWidget { Q_OBJECT public: - enum VersionButtonID { Strict = 0, Major = 1, All = 2, Between = 3 }; - struct Filter { std::list versions; + ModPlatform::ModLoaderTypes loaders; + QString side; + bool hideInstalled; - bool operator==(const Filter& other) const { return versions == other.versions; } + bool operator==(const Filter& other) const + { + return hideInstalled == other.hideInstalled && side == other.side && loaders == other.loaders && versions == other.versions; + } bool operator!=(const Filter& other) const { return !(*this == other); } }; - std::shared_ptr m_filter; - - public: - static unique_qobject_ptr create(Version default_version, QWidget* parent = nullptr); - ~ModFilterWidget(); - - void setInstance(MinecraftInstance* instance); - - /// By default all buttons are enabled - void disableVersionButton(VersionButtonID, QString reason = {}); + static unique_qobject_ptr create(MinecraftInstance* instance, QWidget* parent = nullptr); + virtual ~ModFilterWidget(); auto getFilter() -> std::shared_ptr; - auto changed() const -> bool { return m_last_version_id != m_version_id; } - - Meta::VersionList::Ptr versionList() { return m_version_list; } + auto changed() const -> bool { return m_filter_changed; } private: - ModFilterWidget(Version def, QWidget* parent = nullptr); + ModFilterWidget(MinecraftInstance* instance, QWidget* parent = nullptr); - inline auto mcVersionStr() const -> QString - { - return m_instance ? m_instance->getPackProfile()->getComponentVersion("net.minecraft") : ""; - } - inline auto mcVersion() const -> Version { return { mcVersionStr() }; } + void loadVersionList(); + void prepareBasicFilter(); private slots: - void onVersionFilterChanged(int id); + void onVersionFilterChanged(); + void onLoadersFilterChanged(); + void onSideFilterChanged(); + void onHideInstalledFilterChanged(); + void onIncludeSnapshotsChanged(); public: signals: @@ -66,13 +61,9 @@ class ModFilterWidget : public QTabWidget { Ui::ModFilterWidget* ui; MinecraftInstance* m_instance = nullptr; - - /* Version stuff */ - QButtonGroup m_mcVersion_buttons; + std::shared_ptr m_filter; + bool m_filter_changed = false; Meta::VersionList::Ptr m_version_list; - - /* Used to tell if the filter was changed since the last getFilter() call */ - VersionButtonID m_last_version_id = VersionButtonID::Strict; - VersionButtonID m_version_id = VersionButtonID::Strict; + VersionProxyModel* m_versions_proxy = nullptr; }; diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index ebe5d2be1..74e27e5f7 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -7,7 +7,7 @@ 0 0 400 - 300 + 127 @@ -16,35 +16,143 @@ 0 + + 0 + Minecraft versions + + + + + 0 + 0 + + + + 5 + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + Include Snapshots + + + + + + + + Loaders + + + + QLayout::SetMinimumSize + + + + + false + + + LiteLoader + + + + + + + false + + + Cauldron + + + - - - - - allVersions - - - - - - - strictVersion - - - - - - - majorVersion - - - - + + + NeoForge + + + + + + + Forge + + + + + + + Quilt + + + + + + + Fabric + + + + + + + + Others + + + + + + Environments + + + + QLayout::SetDefaultConstraint + + + + + Client + + + + + + + Server + + + + + + + + + + Instaled status + + + + + + Hide already installed + + + + + From 55946c8923bf0e1b804944934aec2a42478f84a4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 19 Oct 2023 23:53:26 +0300 Subject: [PATCH 05/64] first attempt at a combobox Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 2 + launcher/ui/widgets/CheckComboBox.cpp | 205 ++++++++++++++++++++++++ launcher/ui/widgets/CheckComboBox.h | 61 +++++++ launcher/ui/widgets/ModFilterWidget.cpp | 8 +- launcher/ui/widgets/ModFilterWidget.ui | 9 +- 5 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 launcher/ui/widgets/CheckComboBox.cpp create mode 100644 launcher/ui/widgets/CheckComboBox.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index d15dc85de..a6c3a3e08 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1035,6 +1035,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/InstallLoaderDialog.h # GUI - widgets + ui/widgets/CheckComboBox.cpp + ui/widgets/CheckComboBox.h ui/widgets/Common.cpp ui/widgets/Common.h ui/widgets/CustomCommands.cpp diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp new file mode 100644 index 000000000..9c9006c74 --- /dev/null +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CheckComboBox.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "BaseVersionList.h" + +class CheckComboModel : public QIdentityProxyModel { + Q_OBJECT + + public: + explicit CheckComboModel(QObject* parent = nullptr) : QIdentityProxyModel(parent) {} + + virtual Qt::ItemFlags flags(const QModelIndex& index) const { return QIdentityProxyModel::flags(index) | Qt::ItemIsUserCheckable; } + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const + { + if (role == Qt::CheckStateRole) { + auto txt = QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole).toString(); + return checked.contains(txt) ? Qt::Checked : Qt::Unchecked; + } + if (role == Qt::DisplayRole) + return QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole); + return {}; + } + virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) + { + if (role == Qt::CheckStateRole) { + auto txt = QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole).toString(); + if (checked.contains(txt)) { + checked.removeOne(txt); + } else { + checked.push_back(txt); + } + emit dataChanged(index, index); + emit checkStateChanged(); + return true; + } + return QIdentityProxyModel::setData(index, value, role); + } + QStringList getChecked() { return checked; } + + signals: + void checkStateChanged(); + + private: + QStringList checked; +}; + +CheckComboBox::CheckComboBox(QWidget* parent) : QComboBox(parent), m_separator(",") +{ + // read-only contents + // QLineEdit* lineEdit = new QLineEdit(this); + // lineEdit->setReadOnly(false); + // setLineEdit(lineEdit); + // lineEdit->disconnect(this); + setInsertPolicy(QComboBox::NoInsert); + + view()->installEventFilter(this); + view()->window()->installEventFilter(this); + view()->viewport()->installEventFilter(this); + this->installEventFilter(this); +} + +void CheckComboBox::setModel(QAbstractItemModel* new_model) +{ + auto proxy = new CheckComboModel(this); + proxy->setSourceModel(new_model); + model()->disconnect(this); + QComboBox::setModel(proxy); + connect(this, QOverload::of(&QComboBox::activated), this, &CheckComboBox::toggleCheckState); + connect(proxy, &CheckComboModel::checkStateChanged, this, &CheckComboBox::updateCheckedItems); + connect(model(), &CheckComboModel::rowsInserted, this, &CheckComboBox::updateCheckedItems); + connect(model(), &CheckComboModel::rowsRemoved, this, &CheckComboBox::updateCheckedItems); +} + +void CheckComboBox::hidePopup() +{ + if (containerMousePress) + QComboBox::hidePopup(); +} + +void CheckComboBox::updateCheckedItems() +{ + QStringList items = checkedItems(); + if (items.isEmpty()) + setEditText(defaultText()); + else + setEditText(items.join(separator())); + + emit checkedItemsChanged(items); +} + +QString CheckComboBox::defaultText() const +{ + return m_default_text; +} + +void CheckComboBox::setDefaultText(const QString& text) +{ + if (m_default_text != text) { + m_default_text = text; + updateCheckedItems(); + } +} + +QString CheckComboBox::separator() const +{ + return m_separator; +} + +void CheckComboBox::setSeparator(const QString& separator) +{ + if (m_separator != separator) { + m_separator = separator; + updateCheckedItems(); + } +} + +bool CheckComboBox::eventFilter(QObject* receiver, QEvent* event) +{ + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { + QKeyEvent* keyEvent = static_cast(event); + if (receiver == this && (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)) { + showPopup(); + return true; + } else if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Escape) { + // it is important to call QComboBox implementation + QComboBox::hidePopup(); + return (keyEvent->key() != Qt::Key_Escape); + } + } + case QEvent::MouseButtonPress: + containerMousePress = (receiver == view()->window()); + break; + case QEvent::MouseButtonRelease: + containerMousePress = false; + break; + default: + break; + } + return false; +} + +void CheckComboBox::toggleCheckState(int index) +{ + QVariant value = itemData(index, Qt::CheckStateRole); + if (value.isValid()) { + Qt::CheckState state = static_cast(value.toInt()); + setItemData(index, (state == Qt::Unchecked ? Qt::Checked : Qt::Unchecked), Qt::CheckStateRole); + } + updateCheckedItems(); +} + +Qt::CheckState CheckComboBox::itemCheckState(int index) const +{ + return static_cast(itemData(index, Qt::CheckStateRole).toInt()); +} + +void CheckComboBox::setItemCheckState(int index, Qt::CheckState state) +{ + setItemData(index, state, Qt::CheckStateRole); +} + +QStringList CheckComboBox::checkedItems() const +{ + if (model()) + return dynamic_cast(model())->getChecked(); + return {}; +} + +void CheckComboBox::setCheckedItems(const QStringList& items) +{ + foreach (auto text, items) { + auto index = findText(text); + setItemCheckState(index, index != -1 ? Qt::Checked : Qt::Unchecked); + } +} + +#include "CheckComboBox.moc" \ No newline at end of file diff --git a/launcher/ui/widgets/CheckComboBox.h b/launcher/ui/widgets/CheckComboBox.h new file mode 100644 index 000000000..277dd5fb8 --- /dev/null +++ b/launcher/ui/widgets/CheckComboBox.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +class CheckComboBox : public QComboBox { + Q_OBJECT + + public: + explicit CheckComboBox(QWidget* parent = nullptr); + virtual ~CheckComboBox() = default; + + virtual void hidePopup() override; + + QString defaultText() const; + void setDefaultText(const QString& text); + + Qt::CheckState itemCheckState(int index) const; + void setItemCheckState(int index, Qt::CheckState state); + + QString separator() const; + void setSeparator(const QString& separator); + + QStringList checkedItems() const; + + virtual void setModel(QAbstractItemModel* model) override; + + public slots: + void setCheckedItems(const QStringList& items); + + signals: + void checkedItemsChanged(const QStringList& items); + + private: + void updateCheckedItems(); + bool eventFilter(QObject* receiver, QEvent* event) override; + void toggleCheckState(int index); + + private: + QString m_default_text; + QString m_separator; + bool containerMousePress; +}; \ No newline at end of file diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 62a8eb154..5ed2e34f6 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -105,8 +105,7 @@ void ModFilterWidget::prepareBasicFilter() m_filter->loaders = loaders; auto def = m_instance->getPackProfile()->getComponentVersion("net.minecraft"); m_filter->versions.push_front(Version{ def }); - m_versions_proxy->setCurrentVersion(def); - ui->versionsCb->setCurrentIndex(m_versions_proxy->getVersion(def).row()); + ui->versionsCb->setCheckedItems({ def }); } void ModFilterWidget::onIncludeSnapshotsChanged() @@ -119,9 +118,10 @@ void ModFilterWidget::onIncludeSnapshotsChanged() void ModFilterWidget::onVersionFilterChanged() { - auto version = ui->versionsCb->currentData(BaseVersionList::VersionIdRole).toString(); + auto versions = ui->versionsCb->checkedItems(); m_filter->versions.clear(); - m_filter->versions.push_front(version); + for (auto version : versions) + m_filter->versions.push_back(version); m_filter_changed = true; emit filterChanged(); } diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index 74e27e5f7..e27de6f1a 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -25,7 +25,7 @@ - + 0 @@ -157,6 +157,13 @@ + + + CheckComboBox + QComboBox +
ui/widgets/CheckComboBox.h
+
+
From 6883c195795a8bb61a7ab50869d60265ddebc3d8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 20 Oct 2023 00:44:36 +0300 Subject: [PATCH 06/64] Fixed the version combobox Signed-off-by: Trial97 --- launcher/ui/widgets/CheckComboBox.cpp | 16 +++++++--------- launcher/ui/widgets/ModFilterWidget.cpp | 23 +++++++++++++++++++++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index 9c9006c74..f826c1afe 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -39,17 +39,17 @@ class CheckComboModel : public QIdentityProxyModel { virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const { if (role == Qt::CheckStateRole) { - auto txt = QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole).toString(); + auto txt = QIdentityProxyModel::data(index, Qt::DisplayRole).toString(); return checked.contains(txt) ? Qt::Checked : Qt::Unchecked; } if (role == Qt::DisplayRole) - return QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole); + return QIdentityProxyModel::data(index, Qt::DisplayRole); return {}; } virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) { if (role == Qt::CheckStateRole) { - auto txt = QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole).toString(); + auto txt = QIdentityProxyModel::data(index, Qt::DisplayRole).toString(); if (checked.contains(txt)) { checked.removeOne(txt); } else { @@ -72,11 +72,10 @@ class CheckComboModel : public QIdentityProxyModel { CheckComboBox::CheckComboBox(QWidget* parent) : QComboBox(parent), m_separator(",") { - // read-only contents - // QLineEdit* lineEdit = new QLineEdit(this); - // lineEdit->setReadOnly(false); - // setLineEdit(lineEdit); - // lineEdit->disconnect(this); + QLineEdit* lineEdit = new QLineEdit(this); + lineEdit->setReadOnly(false); + setLineEdit(lineEdit); + lineEdit->disconnect(this); setInsertPolicy(QComboBox::NoInsert); view()->installEventFilter(this); @@ -150,7 +149,6 @@ bool CheckComboBox::eventFilter(QObject* receiver, QEvent* event) showPopup(); return true; } else if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Escape) { - // it is important to call QComboBox implementation QComboBox::hidePopup(); return (keyEvent->key() != Qt::Key_Escape); } diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 5ed2e34f6..5a67757b5 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -14,6 +14,20 @@ unique_qobject_ptr ModFilterWidget::create(MinecraftInstance* i return unique_qobject_ptr(new ModFilterWidget(instance, parent)); } +class VersionBasicModel : public QIdentityProxyModel { + Q_OBJECT + + public: + explicit VersionBasicModel(QObject* parent = nullptr) : QIdentityProxyModel(parent) {} + + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override + { + if (role == Qt::DisplayRole) + return QIdentityProxyModel::data(index, BaseVersionList::VersionIdRole); + return {}; + } +}; + ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, QWidget* parent) : QTabWidget(parent), ui(new Ui::ModFilterWidget), m_instance(instance), m_filter(new Filter()) { @@ -21,7 +35,10 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, QWidget* parent) m_versions_proxy = new VersionProxyModel(this); - ui->versionsCb->setModel(m_versions_proxy); + auto proxy = new VersionBasicModel(this); + proxy->setSourceModel(m_versions_proxy); + ui->versionsCb->setModel(proxy); + ui->versionsCb->setSeparator("| "); m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter("(release)", false)); @@ -177,4 +194,6 @@ void ModFilterWidget::onHideInstalledFilterChanged() emit filterChanged(); else emit filterUnchanged(); -} \ No newline at end of file +} + +#include "ModFilterWidget.moc" From 4850434c67017622cf7b082728cf56a3b42d7920 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Oct 2023 12:16:02 +0300 Subject: [PATCH 07/64] added releaseType? Signed-off-by: Trial97 --- launcher/ui/widgets/ModFilterWidget.ui | 75 +++++++++++++++++++------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index e27de6f1a..3113f2df2 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -17,7 +17,7 @@ - 0 + 2 @@ -57,23 +57,10 @@ QLayout::SetMinimumSize - - - - false - + + - LiteLoader - - - - - - - false - - - Cauldron + Fabric @@ -91,6 +78,16 @@ + + + + false + + + Cauldron + + + @@ -98,10 +95,48 @@ - - + + + + false + - Fabric + LiteLoader + + + + + + + + Release type + + + + + + Release + + + + + + + Beta + + + + + + + Alpha + + + + + + + Unknown From 9e85297f7af495ecf8c34ea62a3559b712ff8e14 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Oct 2023 18:28:33 +0300 Subject: [PATCH 08/64] Connected filters Signed-off-by: Trial97 --- launcher/modplatform/ResourceAPI.h | 1 + launcher/modplatform/flame/FlameModIndex.cpp | 7 +-- launcher/modplatform/modrinth/ModrinthAPI.h | 18 +++++++ .../modrinth/ModrinthPackIndex.cpp | 7 +-- launcher/ui/pages/modplatform/ModModel.cpp | 53 +++++++++++++++--- launcher/ui/pages/modplatform/ModModel.h | 3 ++ launcher/ui/pages/modplatform/ModPage.cpp | 38 +------------ launcher/ui/pages/modplatform/ModPage.h | 9 +--- .../ui/pages/modplatform/ResourceModel.cpp | 15 ++++-- launcher/ui/pages/modplatform/ResourceModel.h | 11 ++++ .../ui/pages/modplatform/ResourcePage.cpp | 2 +- launcher/ui/pages/modplatform/ResourcePage.h | 7 --- .../modplatform/flame/FlameResourceModels.cpp | 25 +++++++++ .../modplatform/flame/FlameResourceModels.h | 8 +++ .../modplatform/flame/FlameResourcePages.cpp | 38 ++----------- .../modplatform/flame/FlameResourcePages.h | 12 +---- .../modrinth/ModrinthResourcePages.cpp | 11 ++-- .../modrinth/ModrinthResourcePages.h | 3 +- launcher/ui/widgets/CheckComboBox.cpp | 2 +- launcher/ui/widgets/CheckComboBox.h | 4 +- launcher/ui/widgets/ModFilterWidget.cpp | 54 ++++++++++++++++--- launcher/ui/widgets/ModFilterWidget.h | 19 ++++--- launcher/ui/widgets/ModFilterWidget.ui | 19 ++++--- 23 files changed, 214 insertions(+), 152 deletions(-) diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index 3b1959384..732c66621 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -73,6 +73,7 @@ class ResourceAPI { std::optional sorting; std::optional loaders; std::optional > versions; + std::optional side; }; struct SearchCallbacks { std::function on_succeed; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index d56e46b23..f95b17683 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -79,10 +79,6 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, const BaseInstance* inst) { QVector unsortedVersions; - auto profile = (dynamic_cast(inst))->getPackProfile(); - QString mcVersion = profile->getComponentVersion("net.minecraft"); - auto loaders = profile->getSupportedModLoaders(); - for (auto versionIter : arr) { auto obj = versionIter.toObject(); @@ -90,8 +86,7 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, if (!file.addonId.isValid()) file.addonId = pack.addonId; - if (file.fileId.isValid() && - (!loaders.has_value() || !file.loaders || loaders.value() & file.loaders)) // Heuristic to check if the returned value is valid + if (file.fileId.isValid()) // Heuristic to check if the returned value is valid unsortedVersions.append(file); } diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 857719902..8e0f9fe22 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -56,6 +56,18 @@ class ModrinthAPI : public NetworkResourceAPI { return l.join(','); } + static auto getSideFilters(QString side) -> const QString + { + if (side.isEmpty() || side == "both") { + return {}; + } + if (side == "client") + return QString("\"client_side:required\",\"client_side:optional\""); + if (side == "server") + return QString("\"server_side:required\",\"server_side:optional\""); + return {}; + } + private: [[nodiscard]] static QString resourceTypeParameter(ModPlatform::ResourceType type) { @@ -73,6 +85,7 @@ class ModrinthAPI : public NetworkResourceAPI { return ""; } + [[nodiscard]] QString createFacets(SearchArgs const& args) const { QStringList facets_list; @@ -81,6 +94,11 @@ class ModrinthAPI : public NetworkResourceAPI { facets_list.append(QString("[%1]").arg(getModLoaderFilters(args.loaders.value()))); if (args.versions.has_value()) facets_list.append(QString("[%1]").arg(getGameVersionsArray(args.versions.value()))); + if (args.side.has_value()) { + auto side = getSideFilters(args.side.value()); + if (!side.isEmpty()) + facets_list.append(QString("[%1]").arg(side)); + } facets_list.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type))); return QString("[%1]").arg(facets_list.join(',')); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 23770b7fb..5de645220 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -112,16 +112,11 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr, const BaseInstance* inst) { QVector unsortedVersions; - auto profile = (dynamic_cast(inst))->getPackProfile(); - QString mcVersion = profile->getComponentVersion("net.minecraft"); - auto loaders = profile->getSupportedModLoaders(); - for (auto versionIter : arr) { auto obj = versionIter.toObject(); auto file = loadIndexedPackVersion(obj); - if (file.fileId.isValid() && - (!loaders.has_value() || !file.loaders || loaders.value() & file.loaders)) // Heuristic to check if the returned value is valid + if (file.fileId.isValid()) // Heuristic to check if the returned value is valid unsortedVersions.append(file); } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 3b53d1348..64ae7de36 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -27,16 +27,16 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() std::optional> versions{}; auto loaders = profile->getSupportedModLoaders(); - { // Version filter - if (!m_filter->versions.empty()) - versions = m_filter->versions; - if (m_filter->loaders) - loaders = m_filter->loaders; - } + // Version filter + if (!m_filter->versions.empty()) + versions = m_filter->versions; + if (m_filter->loaders) + loaders = m_filter->loaders; + auto side = m_filter->side; auto sort = getCurrentSortingMethodByIndex(); - return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions }; + return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions, side }; } ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry) @@ -85,4 +85,43 @@ bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const }); } +bool checkSide(QString filter, QString value) +{ + return filter.isEmpty() || value.isEmpty() || filter == "both" || value == "both" || filter == value; +} + +bool checkMcVersions(std::list filter, QStringList value) +{ + bool valid = false; + for (auto mcVersion : filter) { + if (value.contains(mcVersion.toString())) { + valid = true; + break; + } + } + return filter.empty() || valid; +} + +bool ModModel::checkFilters(ModPlatform::IndexedPack::Ptr pack) +{ + if (!m_filter) + return true; + return !(m_filter->hideInstalled && isPackInstalled(pack)) && checkSide(m_filter->side, pack->side); +} + +bool ModModel::checkVersionFilters(const ModPlatform::IndexedVersion& v) +{ + if (!m_filter) + return true; + auto loaders = static_cast(m_base_instance).getPackProfile()->getSupportedModLoaders(); + if (m_filter->loaders) + loaders = m_filter->loaders; + return (!optedOut(v) && // is opted out(aka curseforge download link) + (!loaders.has_value() || !v.loaders || loaders.value() & v.loaders) && // loaders + checkSide(m_filter->side, v.side) && // side + (m_filter->releases.empty() || // releases + std::find(m_filter->releases.cbegin(), m_filter->releases.cend(), v.version_type) != m_filter->releases.cend()) && + checkMcVersions(m_filter->versions, v.mcVersion)); // mcVersions +} + } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index dd187aa8d..9101e07ba 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -45,6 +45,9 @@ class ModModel : public ResourceModel { auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0; virtual bool isPackInstalled(ModPlatform::IndexedPack::Ptr) const override; + virtual bool checkFilters(ModPlatform::IndexedPack::Ptr) override; + virtual bool checkVersionFilters(const ModPlatform::IndexedVersion&) override; + protected: BaseInstance& m_base_instance; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 838cf21c8..e6106a0de 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -73,6 +73,7 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) m_filter = m_filter_widget->getFilter(); + connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, &ResourcePage::updateVersionList); connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, [&] { m_ui->searchButton->setStyleSheet("text-decoration: underline"); }); connect(m_filter_widget.get(), &ModFilterWidget::filterUnchanged, this, @@ -110,43 +111,6 @@ QMap ModPage::urlHandlers() const /******** Make changes to the UI ********/ -void ModPage::updateVersionList() -{ - m_ui->versionSelectionBox->clear(); - auto packProfile = (dynamic_cast(m_base_instance)).getPackProfile(); - - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - auto loaders = packProfile->getSupportedModLoaders(); - if (m_filter->loaders) - loaders = m_filter->loaders; - - auto current_pack = getCurrentPack(); - if (!current_pack) - return; - for (int i = 0; i < current_pack->versions.size(); i++) { - auto version = current_pack->versions[i]; - bool valid = false; - for (auto& mcVer : m_filter->versions) { - if (validateVersion(version, mcVer.toString(), loaders)) { - valid = true; - break; - } - } - - // Only add the version if it's valid or using the 'Any' filter, but never if the version is opted out - if ((valid || m_filter->versions.empty()) && !optedOut(version)) { - auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : ""; - m_ui->versionSelectionBox->addItem(QString("%1%2").arg(version.version, release_type), QVariant(i)); - } - } - if (m_ui->versionSelectionBox->count() == 0) { - m_ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); - m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :(")); - } - - updateSelectionButton(); -} - void ModPage::addResourceToPage(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion& version, const std::shared_ptr base_model) diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index 6efb318ea..c878bc004 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -31,7 +31,7 @@ class ModPage : public ResourcePage { auto page = new T(dialog, instance); auto model = static_cast(page->getModel()); - auto filter_widget = ModFilterWidget::create(&static_cast(instance), page); + auto filter_widget = page->createFilterWidget(); page->setFilterWidget(filter_widget); model->setFilter(page->getFilter()); @@ -52,17 +52,12 @@ class ModPage : public ResourcePage { ModPlatform::IndexedVersion&, const std::shared_ptr) override; - virtual auto validateVersion(ModPlatform::IndexedVersion& ver, - QString mineVer, - std::optional loaders = {}) const -> bool = 0; + virtual unique_qobject_ptr createFilterWidget() = 0; [[nodiscard]] bool supportsFiltering() const override { return true; }; auto getFilter() const -> const std::shared_ptr { return m_filter; } void setFilterWidget(unique_qobject_ptr&); - public slots: - void updateVersionList() override; - protected: ModPage(ModDownloadDialog* dialog, BaseInstance& instance); diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 48e66efca..776765d64 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -399,12 +399,17 @@ void ResourceModel::searchRequestSucceeded(QJsonDocument& doc) m_search_state = SearchState::CanFetchMore; } + QList filteredNewList; + for (auto p : newList) + if (checkFilters(p)) + filteredNewList << p; + // When you have a Qt build with assertions turned on, proceeding here will abort the application - if (newList.size() == 0) + if (filteredNewList.size() == 0) return; - beginInsertRows(QModelIndex(), m_packs.size(), m_packs.size() + newList.size() - 1); - m_packs.append(newList); + beginInsertRows(QModelIndex(), m_packs.size(), m_packs.size() + filteredNewList.size() - 1); + m_packs.append(filteredNewList); endInsertRows(); } @@ -547,4 +552,8 @@ void ResourceModel::removePack(const QString& rem) ver.is_currently_selected = false; } +bool ResourceModel::checkVersionFilters(const ModPlatform::IndexedVersion& v) +{ + return (!optedOut(v)); +} } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index ecf4f8f79..1956e54ac 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -11,6 +11,7 @@ #include "QObjectPtr.h" #include "ResourceDownloadTask.h" +#include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" #include "tasks/ConcurrentTask.h" @@ -55,6 +56,16 @@ class ResourceModel : public QAbstractListModel { [[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); } + /** Whether the version is opted out or not. Currently only makes sense in CF. */ + virtual bool optedOut(const ModPlatform::IndexedVersion& ver) const + { + Q_UNUSED(ver); + return false; + }; + + virtual bool checkFilters(ModPlatform::IndexedPack::Ptr) { return true; } + virtual bool checkVersionFilters(const ModPlatform::IndexedVersion&); + public slots: void fetchMore(const QModelIndex& parent) override; // NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12 diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 44a91003d..158b13c96 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -263,7 +263,7 @@ void ResourcePage::updateVersionList() if (current_pack) for (int i = 0; i < current_pack->versions.size(); i++) { auto& version = current_pack->versions[i]; - if (optedOut(version)) + if (!m_model->checkVersionFilters(version)) continue; auto release_type = current_pack->versions[i].version_type.isValid() diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 7bec0a375..84b37f50b 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -96,13 +96,6 @@ class ResourcePage : public QWidget, public BasePage { virtual QMap urlHandlers() const = 0; virtual void openUrl(const QUrl&); - /** Whether the version is opted out or not. Currently only makes sense in CF. */ - virtual bool optedOut(ModPlatform::IndexedVersion& ver) const - { - Q_UNUSED(ver); - return false; - }; - public: BaseInstance& m_base_instance; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp index 39a2a0d6a..ae4562be4 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp @@ -12,6 +12,11 @@ namespace ResourceDownload { +static bool isOptedOut(const ModPlatform::IndexedVersion& ver) +{ + return ver.downloadUrl.isEmpty(); +} + FlameModModel::FlameModModel(BaseInstance& base) : ModModel(base, new FlameAPI) {} void FlameModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) @@ -35,6 +40,11 @@ auto FlameModModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJs return FlameMod::loadDependencyVersions(m, arr, &m_base_instance); } +bool FlameModModel::optedOut(const ModPlatform::IndexedVersion& ver) const +{ + return isOptedOut(ver); +} + auto FlameModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); @@ -58,6 +68,11 @@ void FlameResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +bool FlameResourcePackModel::optedOut(const ModPlatform::IndexedVersion& ver) const +{ + return isOptedOut(ver); +} + auto FlameResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); @@ -117,6 +132,11 @@ ResourceAPI::VersionSearchArgs FlameTexturePackModel::createVersionsArguments(QM return args; } +bool FlameTexturePackModel::optedOut(const ModPlatform::IndexedVersion& ver) const +{ + return isOptedOut(ver); +} + auto FlameTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); @@ -140,6 +160,11 @@ void FlameShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +bool FlameShaderPackModel::optedOut(const ModPlatform::IndexedVersion& ver) const +{ + return isOptedOut(ver); +} + auto FlameShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h index 76dbd7b3d..458fd85d0 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h @@ -17,6 +17,8 @@ class FlameModModel : public ModModel { FlameModModel(BaseInstance&); ~FlameModModel() override = default; + bool optedOut(const ModPlatform::IndexedVersion& ver) const override; + private: [[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; } [[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); } @@ -36,6 +38,8 @@ class FlameResourcePackModel : public ResourcePackResourceModel { FlameResourcePackModel(const BaseInstance&); ~FlameResourcePackModel() override = default; + bool optedOut(const ModPlatform::IndexedVersion& ver) const override; + private: [[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; } [[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); } @@ -54,6 +58,8 @@ class FlameTexturePackModel : public TexturePackResourceModel { FlameTexturePackModel(const BaseInstance&); ~FlameTexturePackModel() override = default; + bool optedOut(const ModPlatform::IndexedVersion& ver) const override; + private: [[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; } [[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); } @@ -75,6 +81,8 @@ class FlameShaderPackModel : public ShaderPackResourceModel { FlameShaderPackModel(const BaseInstance&); ~FlameShaderPackModel() override = default; + bool optedOut(const ModPlatform::IndexedVersion& ver) const override; + private: [[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; } [[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); } diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp index 23373ec9d..66a51decd 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp @@ -44,11 +44,6 @@ namespace ResourceDownload { -static bool isOptedOut(ModPlatform::IndexedVersion const& ver) -{ - return ver.downloadUrl.isEmpty(); -} - FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ModPage(dialog, instance) { m_model = new FlameModModel(instance); @@ -66,19 +61,6 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance) : m_ui->packDescription->setMetaEntry(metaEntryBase()); } -auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, - QString mineVer, - std::optional loaders) const -> bool -{ - return ver.mcVersion.contains(mineVer) && !ver.downloadUrl.isEmpty() && - (!loaders.has_value() || !ver.loaders || loaders.value() & ver.loaders); -} - -bool FlameModPage::optedOut(ModPlatform::IndexedVersion& ver) const -{ - return isOptedOut(ver); -} - void FlameModPage::openUrl(const QUrl& url) { if (url.scheme().isEmpty()) { @@ -113,11 +95,6 @@ FlameResourcePackPage::FlameResourcePackPage(ResourcePackDownloadDialog* dialog, m_ui->packDescription->setMetaEntry(metaEntryBase()); } -bool FlameResourcePackPage::optedOut(ModPlatform::IndexedVersion& ver) const -{ - return isOptedOut(ver); -} - void FlameResourcePackPage::openUrl(const QUrl& url) { if (url.scheme().isEmpty()) { @@ -152,11 +129,6 @@ FlameTexturePackPage::FlameTexturePackPage(TexturePackDownloadDialog* dialog, Ba m_ui->packDescription->setMetaEntry(metaEntryBase()); } -bool FlameTexturePackPage::optedOut(ModPlatform::IndexedVersion& ver) const -{ - return isOptedOut(ver); -} - void FlameTexturePackPage::openUrl(const QUrl& url) { if (url.scheme().isEmpty()) { @@ -191,11 +163,6 @@ FlameShaderPackPage::FlameShaderPackPage(ShaderPackDownloadDialog* dialog, BaseI m_ui->packDescription->setMetaEntry(metaEntryBase()); } -bool FlameShaderPackPage::optedOut(ModPlatform::IndexedVersion& ver) const -{ - return isOptedOut(ver); -} - void FlameShaderPackPage::openUrl(const QUrl& url) { if (url.scheme().isEmpty()) { @@ -232,4 +199,9 @@ auto FlameShaderPackPage::shouldDisplay() const -> bool return true; } +unique_qobject_ptr FlameModPage::createFilterWidget() +{ + return ModFilterWidget::create(&static_cast(m_base_instance), false, this); +} + } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h index f2f5cecad..88ef404fb 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h @@ -94,12 +94,8 @@ class FlameModPage : public ModPage { [[nodiscard]] inline auto helpPage() const -> QString override { return "Mod-platform"; } - bool validateVersion(ModPlatform::IndexedVersion& ver, - QString mineVer, - std::optional loaders = {}) const override; - bool optedOut(ModPlatform::IndexedVersion& ver) const override; - void openUrl(const QUrl& url) override; + unique_qobject_ptr createFilterWidget() override; }; class FlameResourcePackPage : public ResourcePackResourcePage { @@ -124,8 +120,6 @@ class FlameResourcePackPage : public ResourcePackResourcePage { [[nodiscard]] inline auto helpPage() const -> QString override { return ""; } - bool optedOut(ModPlatform::IndexedVersion& ver) const override; - void openUrl(const QUrl& url) override; }; @@ -151,8 +145,6 @@ class FlameTexturePackPage : public TexturePackResourcePage { [[nodiscard]] inline auto helpPage() const -> QString override { return ""; } - bool optedOut(ModPlatform::IndexedVersion& ver) const override; - void openUrl(const QUrl& url) override; }; @@ -178,8 +170,6 @@ class FlameShaderPackPage : public ShaderPackResourcePage { [[nodiscard]] inline auto helpPage() const -> QString override { return ""; } - bool optedOut(ModPlatform::IndexedVersion& ver) const override; - void openUrl(const QUrl& url) override; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp index a4197b225..ab015ff0e 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp @@ -63,13 +63,6 @@ ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instan m_ui->packDescription->setMetaEntry(metaEntryBase()); } -auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, - QString mineVer, - std::optional loaders) const -> bool -{ - return ver.mcVersion.contains(mineVer) && (!loaders.has_value() || !ver.loaders || loaders.value() & ver.loaders); -} - ModrinthResourcePackPage::ModrinthResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance) : ResourcePackResourcePage(dialog, instance) { @@ -144,4 +137,8 @@ auto ModrinthShaderPackPage::shouldDisplay() const -> bool return true; } +unique_qobject_ptr ModrinthModPage::createFilterWidget() +{ + return ModFilterWidget::create(&static_cast(m_base_instance), true, this); +} } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h index 311bcfe32..0a715d747 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h @@ -93,8 +93,7 @@ class ModrinthModPage : public ModPage { [[nodiscard]] inline auto helpPage() const -> QString override { return "Mod-platform"; } - auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional loaders = {}) const - -> bool override; + unique_qobject_ptr createFilterWidget() override; }; class ModrinthResourcePackPage : public ResourcePackResourcePage { diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index f826c1afe..af4594335 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -84,7 +84,7 @@ CheckComboBox::CheckComboBox(QWidget* parent) : QComboBox(parent), m_separator(" this->installEventFilter(this); } -void CheckComboBox::setModel(QAbstractItemModel* new_model) +void CheckComboBox::setSourceModel(QAbstractItemModel* new_model) { auto proxy = new CheckComboModel(this); proxy->setSourceModel(new_model); diff --git a/launcher/ui/widgets/CheckComboBox.h b/launcher/ui/widgets/CheckComboBox.h index 277dd5fb8..f1d9771cc 100644 --- a/launcher/ui/widgets/CheckComboBox.h +++ b/launcher/ui/widgets/CheckComboBox.h @@ -28,7 +28,7 @@ class CheckComboBox : public QComboBox { explicit CheckComboBox(QWidget* parent = nullptr); virtual ~CheckComboBox() = default; - virtual void hidePopup() override; + void hidePopup() override; QString defaultText() const; void setDefaultText(const QString& text); @@ -41,7 +41,7 @@ class CheckComboBox : public QComboBox { QStringList checkedItems() const; - virtual void setModel(QAbstractItemModel* model) override; + void setSourceModel(QAbstractItemModel* model); public slots: void setCheckedItems(const QStringList& items); diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 5a67757b5..dde5d7502 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -9,9 +9,9 @@ #include "Application.h" #include "minecraft/PackProfile.h" -unique_qobject_ptr ModFilterWidget::create(MinecraftInstance* instance, QWidget* parent) +unique_qobject_ptr ModFilterWidget::create(MinecraftInstance* instance, bool extendedSupport, QWidget* parent) { - return unique_qobject_ptr(new ModFilterWidget(instance, parent)); + return unique_qobject_ptr(new ModFilterWidget(instance, extendedSupport, parent)); } class VersionBasicModel : public QIdentityProxyModel { @@ -28,23 +28,33 @@ class VersionBasicModel : public QIdentityProxyModel { } }; -ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, QWidget* parent) +ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent) : QTabWidget(parent), ui(new Ui::ModFilterWidget), m_instance(instance), m_filter(new Filter()) { ui->setupUi(this); m_versions_proxy = new VersionProxyModel(this); + m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter("(release)", false)); auto proxy = new VersionBasicModel(this); proxy->setSourceModel(m_versions_proxy); - ui->versionsCb->setModel(proxy); - ui->versionsCb->setSeparator("| "); - m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter("(release)", false)); + if (!extendedSupport) { + ui->versionsSimpleCb->setModel(proxy); + ui->versionsCb->hide(); + ui->snapshotsCb->hide(); + ui->envBox->hide(); + } else { + ui->versionsCb->setSourceModel(proxy); + ui->versionsCb->setSeparator("| "); + ui->versionsSimpleCb->hide(); + } ui->versionsCb->setStyleSheet("combobox-popup: 0;"); + ui->versionsSimpleCb->setStyleSheet("combobox-popup: 0;"); connect(ui->snapshotsCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onIncludeSnapshotsChanged); connect(ui->versionsCb, &QComboBox::currentIndexChanged, this, &ModFilterWidget::onVersionFilterChanged); + connect(ui->versionsSimpleCb, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); connect(ui->neoForgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); connect(ui->forgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); @@ -61,6 +71,11 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, QWidget* parent) connect(ui->hide_installed, &QCheckBox::stateChanged, this, &ModFilterWidget::onHideInstalledFilterChanged); + connect(ui->releaseCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); + connect(ui->betaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); + connect(ui->alphaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); + connect(ui->unknownCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); + setHidden(true); loadVersionList(); prepareBasicFilter(); @@ -196,4 +211,31 @@ void ModFilterWidget::onHideInstalledFilterChanged() emit filterUnchanged(); } +void ModFilterWidget::onReleaseFilterChanged() +{ + std::list releases; + if (ui->releaseCb->isChecked()) + releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Release)); + if (ui->betaCb->isChecked()) + releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Beta)); + if (ui->alphaCb->isChecked()) + releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Alpha)); + if (ui->unknownCb->isChecked()) + releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Unknown)); + m_filter_changed = releases != m_filter->releases; + m_filter->releases = releases; + if (m_filter_changed) + emit filterChanged(); + else + emit filterUnchanged(); +} + +void ModFilterWidget::onVersionFilterTextChanged(QString version) +{ + m_filter->versions.clear(); + m_filter->versions.push_front(version); + m_filter_changed = true; + emit filterChanged(); +} + #include "ModFilterWidget.moc" diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index b92437a4f..50e6b3762 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -22,41 +22,44 @@ class ModFilterWidget : public QTabWidget { public: struct Filter { std::list versions; + std::list releases; ModPlatform::ModLoaderTypes loaders; QString side; bool hideInstalled; bool operator==(const Filter& other) const { - return hideInstalled == other.hideInstalled && side == other.side && loaders == other.loaders && versions == other.versions; + return hideInstalled == other.hideInstalled && side == other.side && loaders == other.loaders && versions == other.versions && + releases == other.releases; } bool operator!=(const Filter& other) const { return !(*this == other); } }; - static unique_qobject_ptr create(MinecraftInstance* instance, QWidget* parent = nullptr); + static unique_qobject_ptr create(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); virtual ~ModFilterWidget(); auto getFilter() -> std::shared_ptr; auto changed() const -> bool { return m_filter_changed; } + signals: + void filterChanged(); + void filterUnchanged(); + private: - ModFilterWidget(MinecraftInstance* instance, QWidget* parent = nullptr); + ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); void loadVersionList(); void prepareBasicFilter(); private slots: void onVersionFilterChanged(); + void onVersionFilterTextChanged(QString version); + void onReleaseFilterChanged(); void onLoadersFilterChanged(); void onSideFilterChanged(); void onHideInstalledFilterChanged(); void onIncludeSnapshotsChanged(); - public: - signals: - void filterChanged(); - void filterUnchanged(); - private: Ui::ModFilterWidget* ui; diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index 3113f2df2..d962ea44a 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -6,7 +6,7 @@ 0 0 - 400 + 460 127 @@ -17,13 +17,20 @@ - 2 + 0 Minecraft versions + + + + Include Snapshots + + + @@ -40,12 +47,8 @@ - - - - Include Snapshots - - + + From 9aac8e389f4e5daaf05826691b6bdb21bfb06e09 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Oct 2023 18:48:55 +0300 Subject: [PATCH 09/64] made release type visible Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 15 +++++++++++++++ launcher/minecraft/mod/Mod.h | 1 + launcher/minecraft/mod/ModFolderModel.cpp | 21 ++++++++++++++------- launcher/minecraft/mod/ModFolderModel.h | 1 + launcher/minecraft/mod/Resource.h | 2 +- launcher/modplatform/packwiz/Packwiz.cpp | 3 +++ launcher/modplatform/packwiz/Packwiz.h | 1 + launcher/ui/widgets/ModFilterWidget.cpp | 2 +- launcher/ui/widgets/ModFilterWidget.h | 2 +- 9 files changed, 38 insertions(+), 10 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 22e652319..f301cc949 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -47,6 +47,7 @@ #include "minecraft/mod/ModDetails.h" #include "minecraft/mod/Resource.h" #include "minecraft/mod/tasks/LocalModParseTask.h" +#include "modplatform/ModIndex.h" static ModPlatform::ProviderCapabilities ProviderCaps; @@ -132,6 +133,13 @@ std::pair Mod::compare(const Resource& other, SortType type) const return { compare_result, type == SortType::MC_VERSIONS }; break; } + case SortType::RELEASE_TYPE: { + if (releaseType() > cast_other->releaseType()) + return { 1, type == SortType::RELEASE_TYPE }; + else if (releaseType() < cast_other->releaseType()) + return { -1, type == SortType::RELEASE_TYPE }; + break; + } } return { 0, false }; } @@ -262,6 +270,13 @@ auto Mod::side() const -> Metadata::ModSide return Metadata::ModSide::UniversalSide; } +auto Mod::releaseType() const -> ModPlatform::IndexedVersionType +{ + if (metadata()) + return metadata()->releaseType; + return ModPlatform::IndexedVersionType::VersionType::Unknown; +} + auto Mod::loaders() const -> ModPlatform::ModLoaderTypes { if (metadata()) diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 92de65889..bf503bc80 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -74,6 +74,7 @@ class Mod : public Resource { auto side() const -> Metadata::ModSide; auto loaders() const -> ModPlatform::ModLoaderTypes; auto mcVersions() const -> QStringList; + auto releaseType() const -> ModPlatform::IndexedVersionType; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index ef4ab957c..fb3688d5d 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -64,16 +64,17 @@ 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) { - m_column_names = - QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Side", "Loaders", "Miecraft Versions" }); + m_column_names = QStringList( + { "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Side", "Loaders", "Miecraft Versions", "Release Type" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"), - tr("Side"), tr("Loaders"), tr("Miecraft Versions") }); - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, - SortType::PROVIDER, SortType::SIDE, SortType::LOADERS, SortType::MC_VERSIONS }; + tr("Side"), tr("Loaders"), tr("Miecraft Versions"), tr("Release Type") }); + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, + SortType::PROVIDER, SortType::SIDE, SortType::LOADERS, SortType::MC_VERSIONS, SortType::RELEASE_TYPE }; m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, - QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; - m_columnsHideable = { false, true, false, true, true, true, true, true, true }; + QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, + QHeaderView::ResizeToContents }; + m_columnsHideable = { false, true, false, true, true, true, true, true, true, true }; } QVariant ModFolderModel::data(const QModelIndex& index, int role) const @@ -128,6 +129,9 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const case McVersionsColumn: { return at(row)->mcVersions().join(", "); } + case ReleaseTypeColumn: { + return at(row)->releaseType().toString(); + } default: return QVariant(); } @@ -180,6 +184,7 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio case SideColumn: case LoadersColumn: case McVersionsColumn: + case ReleaseTypeColumn: return columnNames().at(section); default: return QVariant(); @@ -203,6 +208,8 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio return tr("The mod loader."); case McVersionsColumn: return tr("The supported minecraft versions."); + case ReleaseTypeColumn: + return tr("The release type."); default: return QVariant(); } diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index f9a87a741..a243a3c92 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -71,6 +71,7 @@ class ModFolderModel : public ResourceFolderModel { SideColumn, LoadersColumn, McVersionsColumn, + ReleaseTypeColumn, NUM_COLUMNS }; enum ModStatusAction { Disable, Enable, Toggle }; diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index c46980837..101f65271 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -15,7 +15,7 @@ enum class ResourceType { LITEMOD, //!< The resource is a litemod }; -enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER, SIDE, LOADERS, MC_VERSIONS }; +enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER, SIDE, LOADERS, MC_VERSIONS, RELEASE_TYPE }; enum class EnableAction { ENABLE, DISABLE, TOGGLE }; diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 0692a627d..1672cdf3d 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -117,6 +117,7 @@ auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedP mod.loaders = mod_version.loaders; mod.mcVersions = mod_version.mcVersion; mod.mcVersions.sort(); + mod.releaseType = mod_version.version_type; return mod; } @@ -209,6 +210,7 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) { "side", sideToString(mod.side).toStdString() }, { "loaders", loaders }, { "mcVersions", mcVersions }, + { "releaseType", mod.releaseType.toString().toStdString() }, { "download", toml::table{ { "mode", mod.mode.toStdString() }, @@ -293,6 +295,7 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod mod.name = stringEntry(table, "name"); mod.filename = stringEntry(table, "filename"); mod.side = stringToSide(stringEntry(table, "side")); + mod.releaseType = ModPlatform::IndexedVersionType(stringEntry(table, "releaseType")); if (auto loaders = table["loaders"]; loaders && loaders.is_array()) { for (auto&& loader : *loaders.as_array()) { if (loader.is_string()) { diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 5cf99e74a..50cce9c66 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -43,6 +43,7 @@ class V1 { Side side{ Side::UniversalSide }; ModPlatform::ModLoaderTypes loaders; QStringList mcVersions; + ModPlatform::IndexedVersionType releaseType; // [download] QString mode{}; diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index dde5d7502..d702173f1 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -148,7 +148,7 @@ void ModFilterWidget::onIncludeSnapshotsChanged() m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter(filter, false)); } -void ModFilterWidget::onVersionFilterChanged() +void ModFilterWidget::onVersionFilterChanged(int) { auto versions = ui->versionsCb->checkedItems(); m_filter->versions.clear(); diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 50e6b3762..b6edcb21e 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -52,7 +52,7 @@ class ModFilterWidget : public QTabWidget { void prepareBasicFilter(); private slots: - void onVersionFilterChanged(); + void onVersionFilterChanged(int); void onVersionFilterTextChanged(QString version); void onReleaseFilterChanged(); void onLoadersFilterChanged(); From 35d62cc5f2d79e499791a20a3997bf91137aadc0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Oct 2023 19:05:31 +0300 Subject: [PATCH 10/64] Updated dependencies Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 15 ++++++++++++--- launcher/ui/widgets/ModFilterWidget.cpp | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index deec0db7c..625ab23bb 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -45,6 +45,14 @@ static ModPlatform::ModLoaderTypes mcLoaders(BaseInstance* inst) return static_cast(inst)->getPackProfile()->getSupportedModLoaders().value(); } +static bool checkDependencies(std::shared_ptr sel, + Version mcVersion, + ModPlatform::ModLoaderTypes loaders) +{ + return (sel->pack->versions.isEmpty() || sel->version.mcVersion.contains(mcVersion.toString())) && + (!loaders || !sel->version.loaders || sel->version.loaders & loaders); +} + GetModDependenciesTask::GetModDependenciesTask(QObject* parent, BaseInstance* instance, ModFolderModel* folder, @@ -67,9 +75,10 @@ GetModDependenciesTask::GetModDependenciesTask(QObject* parent, void GetModDependenciesTask::prepare() { for (auto sel : m_selected) { - for (auto dep : getDependenciesForVersion(sel->version, sel->pack->provider)) { - addTask(prepareDependencyTask(dep, sel->pack->provider, 20)); - } + if (checkDependencies(sel, m_version, m_loaderType)) + for (auto dep : getDependenciesForVersion(sel->version, sel->pack->provider)) { + addTask(prepareDependencyTask(dep, sel->pack->provider, 20)); + } } } diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index d702173f1..0dff97510 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -53,7 +53,7 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extendedSuppo ui->versionsCb->setStyleSheet("combobox-popup: 0;"); ui->versionsSimpleCb->setStyleSheet("combobox-popup: 0;"); connect(ui->snapshotsCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onIncludeSnapshotsChanged); - connect(ui->versionsCb, &QComboBox::currentIndexChanged, this, &ModFilterWidget::onVersionFilterChanged); + connect(ui->versionsCb, QOverload::of(&QComboBox::currentIndexChanged), this, &ModFilterWidget::onVersionFilterChanged); connect(ui->versionsSimpleCb, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); connect(ui->neoForgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); From 41c9ca4f8ae0d18c53a5523b81e31d5d4e42072f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Oct 2023 22:15:07 +0300 Subject: [PATCH 11/64] Added categories filter Signed-off-by: Trial97 --- launcher/modplatform/ModIndex.h | 5 +++ launcher/modplatform/ResourceAPI.h | 1 + launcher/modplatform/flame/FlameAPI.cpp | 41 +++++++++++++++++++ launcher/modplatform/flame/FlameAPI.h | 7 ++++ launcher/modplatform/modrinth/ModrinthAPI.cpp | 38 +++++++++++++++++ launcher/modplatform/modrinth/ModrinthAPI.h | 15 +++++++ launcher/ui/pages/modplatform/ModModel.cpp | 5 ++- launcher/ui/pages/modplatform/ModPage.cpp | 1 + launcher/ui/pages/modplatform/ModPage.h | 2 + .../modplatform/flame/FlameResourcePages.cpp | 14 +++++++ .../modplatform/flame/FlameResourcePages.h | 3 ++ .../modrinth/ModrinthResourcePages.cpp | 11 +++++ .../modrinth/ModrinthResourcePages.h | 3 ++ launcher/ui/widgets/ModFilterWidget.cpp | 39 ++++++++++++++++-- launcher/ui/widgets/ModFilterWidget.h | 11 ++++- launcher/ui/widgets/ModFilterWidget.ui | 40 +++++++++++++++++- 16 files changed, 230 insertions(+), 6 deletions(-) diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 7c472ec9b..a8ec6e7b3 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -191,6 +191,11 @@ constexpr bool hasSingleModLoaderSelected(ModLoaderTypes l) noexcept return x && !(x & (x - 1)); } +struct Category { + QString name; + QString id; +}; + } // namespace ModPlatform Q_DECLARE_METATYPE(ModPlatform::IndexedPack) diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index 732c66621..97a38ca69 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -74,6 +74,7 @@ class ResourceAPI { std::optional loaders; std::optional > versions; std::optional side; + std::optional categoryIds; }; struct SearchCallbacks { std::function on_succeed; diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index e99ce3a56..cc3f31e32 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -3,10 +3,12 @@ // SPDX-License-Identifier: GPL-3.0-only #include "FlameAPI.h" +#include #include "FlameModIndex.h" #include "Application.h" #include "Json.h" +#include "modplatform/ModIndex.h" #include "net/ApiDownload.h" #include "net/ApiUpload.h" #include "net/NetJob.h" @@ -222,3 +224,42 @@ QList FlameAPI::getSortingMethods() const { return s_sorts; } + +Task::Ptr FlameAPI::getModCategories(std::shared_ptr response) +{ + auto netJob = makeShared(QString("Flame::GetCategories"), APPLICATION->network()); + netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl("https://api.curseforge.com/v1/categories?gameId=432&classId=6"), response)); + QObject::connect(netJob.get(), &Task::failed, [](QString msg) { qDebug() << "Flame failed to get categories:" << msg; }); + return netJob; +} + +QList FlameAPI::loadModCategories(std::shared_ptr response) +{ + QList categories; + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from categories at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return categories; + } + + try { + auto obj = Json::requireObject(doc); + auto arr = Json::requireArray(obj, "data"); + + for (auto val : arr) { + auto cat = Json::requireObject(val); + auto id = Json::requireInteger(cat, "id"); + auto name = Json::requireString(cat, "name"); + categories.push_back({ name, QString::number(id) }); + } + + } catch (Json::JsonException& e) { + qCritical() << "Failed to parse response from a version request."; + qCritical() << e.what(); + qDebug() << doc; + } + return categories; +}; \ No newline at end of file diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index e22d8f0d8..dfe76f9d5 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "modplatform/ModIndex.h" @@ -22,6 +23,9 @@ class FlameAPI : public NetworkResourceAPI { Task::Ptr getFiles(const QStringList& fileIds, std::shared_ptr response) const; Task::Ptr getFile(const QString& addonId, const QString& fileId, std::shared_ptr response) const; + static Task::Ptr getModCategories(std::shared_ptr response); + static QList loadModCategories(std::shared_ptr response); + [[nodiscard]] auto getSortingMethods() const -> QList override; static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool @@ -96,6 +100,9 @@ class FlameAPI : public NetworkResourceAPI { get_arguments.append("sortOrder=desc"); if (args.loaders.has_value()) get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(args.loaders.value()))); + if (args.categoryIds.has_value() && !args.categoryIds->empty()) + get_arguments.append(QString("categoryIds=[%1]").arg(args.categoryIds->join(","))); + get_arguments.append(gameVersionStr); return "https://api.curseforge.com/v1/mods/search?gameId=432&" + get_arguments.join('&'); diff --git a/launcher/modplatform/modrinth/ModrinthAPI.cpp b/launcher/modplatform/modrinth/ModrinthAPI.cpp index f453f5cb9..d3f006e6f 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.cpp +++ b/launcher/modplatform/modrinth/ModrinthAPI.cpp @@ -122,3 +122,41 @@ QList ModrinthAPI::getSortingMethods() const { return s_sorts; } + +Task::Ptr ModrinthAPI::getModCategories(std::shared_ptr response) +{ + auto netJob = makeShared(QString("Modrinth::GetCategories"), APPLICATION->network()); + netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(BuildConfig.MODRINTH_PROD_URL + "/tag/category"), response)); + QObject::connect(netJob.get(), &Task::failed, [](QString msg) { qDebug() << "Modrinth failed to get categories:" << msg; }); + return netJob; +} + +QList ModrinthAPI::loadModCategories(std::shared_ptr response) +{ + QList categories; + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from categories at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return categories; + } + + try { + auto arr = Json::requireArray(doc); + + for (auto val : arr) { + auto cat = Json::requireObject(val); + auto name = Json::requireString(cat, "name"); + if (Json::ensureString(cat, "project_type", "") == "mod") + categories.push_back({ name, name }); + } + + } catch (Json::JsonException& e) { + qCritical() << "Failed to parse response from a version request."; + qCritical() << e.what(); + qDebug() << doc; + } + return categories; +}; \ No newline at end of file diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 8e0f9fe22..d1f8f712a 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -30,6 +30,9 @@ class ModrinthAPI : public NetworkResourceAPI { Task::Ptr getProjects(QStringList addonIds, std::shared_ptr response) const override; + static Task::Ptr getModCategories(std::shared_ptr response); + static QList loadModCategories(std::shared_ptr response); + public: [[nodiscard]] auto getSortingMethods() const -> QList override; @@ -56,6 +59,15 @@ class ModrinthAPI : public NetworkResourceAPI { return l.join(','); } + static auto getCategoriesFilters(QStringList categories) -> const QString + { + QStringList l; + for (auto cat : categories) { + l << QString("\"categories:%1\"").arg(cat); + } + return l.join(','); + } + static auto getSideFilters(QString side) -> const QString { if (side.isEmpty() || side == "both") { @@ -99,6 +111,9 @@ class ModrinthAPI : public NetworkResourceAPI { if (!side.isEmpty()) facets_list.append(QString("[%1]").arg(side)); } + if (args.categoryIds.has_value() && !args.categoryIds->empty()) + facets_list.append(QString("[%1]").arg(getCategoriesFilters(args.categoryIds.value()))); + facets_list.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type))); return QString("[%1]").arg(facets_list.join(',')); diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 64ae7de36..61a01ddd2 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -25,6 +25,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() Q_ASSERT(m_filter); std::optional> versions{}; + std::optional categories{}; auto loaders = profile->getSupportedModLoaders(); // Version filter @@ -32,11 +33,13 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() versions = m_filter->versions; if (m_filter->loaders) loaders = m_filter->loaders; + if (!m_filter->categoryIds.empty()) + categories = m_filter->categoryIds; auto side = m_filter->side; auto sort = getCurrentSortingMethodByIndex(); - return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions, side }; + return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions, side, categories }; } ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index e6106a0de..e4da1a962 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -78,6 +78,7 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) [&] { m_ui->searchButton->setStyleSheet("text-decoration: underline"); }); connect(m_filter_widget.get(), &ModFilterWidget::filterUnchanged, this, [&] { m_ui->searchButton->setStyleSheet("text-decoration: none"); }); + prepareProviderCategories(); } /******** Callbacks to events in the UI (set up in the derived classes) ********/ diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index c878bc004..d6a7d64e4 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -61,6 +61,8 @@ class ModPage : public ResourcePage { protected: ModPage(ModDownloadDialog* dialog, BaseInstance& instance); + virtual void prepareProviderCategories(){}; + protected slots: virtual void filterMods(); void triggerSearch() override; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp index 66a51decd..7a6046824 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp @@ -37,6 +37,10 @@ */ #include "FlameResourcePages.h" +#include +#include +#include "modplatform/ModIndex.h" +#include "modplatform/flame/FlameAPI.h" #include "ui_ResourcePage.h" #include "FlameResourceModels.h" @@ -204,4 +208,14 @@ unique_qobject_ptr FlameModPage::createFilterWidget() return ModFilterWidget::create(&static_cast(m_base_instance), false, this); } +void FlameModPage::prepareProviderCategories() +{ + auto response = std::make_shared(); + auto task = FlameAPI::getModCategories(response); + QObject::connect(task.get(), &Task::succeeded, [this, response]() { + auto categories = FlameAPI::loadModCategories(response); + m_filter_widget->setCategories(categories); + }); + task->start(); +}; } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h index 88ef404fb..0288023ca 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h @@ -96,6 +96,9 @@ class FlameModPage : public ModPage { void openUrl(const QUrl& url) override; unique_qobject_ptr createFilterWidget() override; + + protected: + virtual void prepareProviderCategories() override; }; class FlameResourcePackPage : public ResourcePackResourcePage { diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp index ab015ff0e..5b5099863 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp @@ -141,4 +141,15 @@ unique_qobject_ptr ModrinthModPage::createFilterWidget() { return ModFilterWidget::create(&static_cast(m_base_instance), true, this); } + +void ModrinthModPage::prepareProviderCategories() +{ + auto response = std::make_shared(); + auto task = ModrinthAPI::getModCategories(response); + QObject::connect(task.get(), &Task::succeeded, [this, response]() { + auto categories = ModrinthAPI::loadModCategories(response); + m_filter_widget->setCategories(categories); + }); + task->start(); +}; } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h index 0a715d747..a8dcd1de5 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h @@ -94,6 +94,9 @@ class ModrinthModPage : public ModPage { [[nodiscard]] inline auto helpPage() const -> QString override { return "Mod-platform"; } unique_qobject_ptr createFilterWidget() override; + + protected: + virtual void prepareProviderCategories() override; }; class ModrinthResourcePackPage : public ResourcePackResourcePage { diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 0dff97510..a3b0a0cc0 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -1,6 +1,8 @@ #include "ModFilterWidget.h" -#include -#include +#include +#include +#include +#include #include "BaseVersionList.h" #include "meta/Index.h" #include "modplatform/ModIndex.h" @@ -76,6 +78,8 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extendedSuppo connect(ui->alphaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); connect(ui->unknownCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); + connect(ui->categoriesList, &QListWidget::itemClicked, this, &ModFilterWidget::onCategoryClicked); + setHidden(true); loadVersionList(); prepareBasicFilter(); @@ -238,4 +242,33 @@ void ModFilterWidget::onVersionFilterTextChanged(QString version) emit filterChanged(); } -#include "ModFilterWidget.moc" +void ModFilterWidget::setCategories(QList categories) +{ + ui->categoriesList->clear(); + m_categories = categories; + for (auto cat : categories) { + auto item = new QListWidgetItem(cat.name, ui->categoriesList); + item->setFlags(item->flags() & (~Qt::ItemIsUserCheckable)); + item->setCheckState(Qt::Unchecked); + ui->categoriesList->addItem(item); + } +} + +void ModFilterWidget::onCategoryClicked(QListWidgetItem* item) +{ + if (item) + item->setCheckState(item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked); + m_filter->categoryIds.clear(); + for (auto i = 0; i < ui->categoriesList->count(); i++) { + auto item = ui->categoriesList->item(i); + if (item->checkState() == Qt::Checked) { + auto c = std::find_if(m_categories.cbegin(), m_categories.cend(), [item](auto v) { return v.name == item->text(); }); + if (c != m_categories.cend()) + m_filter->categoryIds << c->id; + } + } + m_filter_changed = true; + emit filterChanged(); +}; + +#include "ModFilterWidget.moc" \ No newline at end of file diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index b6edcb21e..402e11ae4 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include #include "Version.h" @@ -26,11 +28,12 @@ class ModFilterWidget : public QTabWidget { ModPlatform::ModLoaderTypes loaders; QString side; bool hideInstalled; + QStringList categoryIds; bool operator==(const Filter& other) const { return hideInstalled == other.hideInstalled && side == other.side && loaders == other.loaders && versions == other.versions && - releases == other.releases; + releases == other.releases && categoryIds == other.categoryIds; } bool operator!=(const Filter& other) const { return !(*this == other); } }; @@ -45,6 +48,9 @@ class ModFilterWidget : public QTabWidget { void filterChanged(); void filterUnchanged(); + public slots: + void setCategories(QList); + private: ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); @@ -59,6 +65,7 @@ class ModFilterWidget : public QTabWidget { void onSideFilterChanged(); void onHideInstalledFilterChanged(); void onIncludeSnapshotsChanged(); + void onCategoryClicked(QListWidgetItem* item); private: Ui::ModFilterWidget* ui; @@ -69,4 +76,6 @@ class ModFilterWidget : public QTabWidget { Meta::VersionList::Ptr m_version_list; VersionProxyModel* m_versions_proxy = nullptr; + + QList m_categories; }; diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index d962ea44a..56cd33fa6 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -7,7 +7,7 @@ 0 0 460 - 127 + 132 @@ -145,6 +145,44 @@ + + + Categories + + + + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + false + + + QAbstractItemView::NoSelection + + + QAbstractItemView::ScrollPerItem + + + QListView::LeftToRight + + + true + + + QListView::ListMode + + + 0 + + + + + Others From d151e97e3a24667063ad4fe9cd6f5aca6cdf7b21 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Oct 2023 22:40:37 +0300 Subject: [PATCH 12/64] Fixed some headers Signed-off-by: Trial97 --- launcher/minecraft/mod/MetadataHandler.h | 1 + launcher/minecraft/mod/Mod.cpp | 1 + launcher/minecraft/mod/Mod.h | 1 + launcher/minecraft/mod/ModFolderModel.cpp | 1 + launcher/minecraft/mod/ModFolderModel.h | 1 + launcher/minecraft/mod/Resource.h | 35 +++++++++++++++++++ launcher/modplatform/ModIndex.cpp | 1 + launcher/modplatform/ResourceAPI.h | 1 + .../modrinth/ModrinthPackIndex.cpp | 1 + launcher/modplatform/packwiz/Packwiz.cpp | 1 + launcher/modplatform/packwiz/Packwiz.h | 1 + launcher/ui/pages/modplatform/ModPage.cpp | 1 + .../ui/pages/modplatform/ResourcePage.cpp | 1 + .../modplatform/flame/FlameResourcePages.cpp | 1 + .../modplatform/flame/FlameResourcePages.h | 1 + .../modrinth/ModrinthResourcePages.cpp | 1 + .../modrinth/ModrinthResourcePages.h | 1 + launcher/ui/widgets/CheckComboBox.cpp | 6 ++-- launcher/ui/widgets/CheckComboBox.h | 2 +- launcher/ui/widgets/ModFilterWidget.cpp | 35 +++++++++++++++++++ launcher/ui/widgets/ModFilterWidget.h | 35 +++++++++++++++++++ 21 files changed, 124 insertions(+), 5 deletions(-) diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index ccdd7d559..fb3a10133 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index f301cc949..e89131034 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -3,6 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index bf503bc80..e9baeed58 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index fb3688d5d..8e31fa34b 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -3,6 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index a243a3c92..31c739e5b 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -3,6 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index 101f65271..0710a400b 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -1,3 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #pragma once #include diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index d2113320a..20bd3f827 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index 97a38ca69..a306dcc52 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -4,6 +4,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 5de645220..a2bda2ec5 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 1672cdf3d..c8899345e 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 50cce9c66..95362bbfe 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index e4da1a962..8fd42b427 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -5,6 +5,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 158b13c96..35c4afc0d 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -5,6 +5,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2023 TheKodeToad + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp index 7a6046824..d82c76c3a 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp @@ -5,6 +5,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h index 0288023ca..6eef3e435 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h @@ -5,6 +5,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp index 5b5099863..26fe46a54 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp @@ -4,6 +4,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h index a8dcd1de5..eaf6129a5 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h @@ -4,6 +4,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index af4594335..8117baa58 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -17,17 +17,15 @@ */ #include "CheckComboBox.h" -#include -#include -#include #include +#include #include #include #include #include +#include #include -#include "BaseVersionList.h" class CheckComboModel : public QIdentityProxyModel { Q_OBJECT diff --git a/launcher/ui/widgets/CheckComboBox.h b/launcher/ui/widgets/CheckComboBox.h index f1d9771cc..4d6daf5a4 100644 --- a/launcher/ui/widgets/CheckComboBox.h +++ b/launcher/ui/widgets/CheckComboBox.h @@ -18,8 +18,8 @@ #pragma once -#include #include +#include class CheckComboBox : public QComboBox { Q_OBJECT diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index a3b0a0cc0..b7da6878a 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -1,3 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "ModFilterWidget.h" #include #include diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 402e11ae4..dd98d9afa 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -1,3 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #pragma once #include From 10ae808da90c819df03c9ea78a3248ddb66179d1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 22 Oct 2023 00:06:08 +0300 Subject: [PATCH 13/64] fixed codeql Signed-off-by: Trial97 --- launcher/ui/widgets/ModFilterWidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index b7da6878a..341823244 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -289,10 +289,10 @@ void ModFilterWidget::setCategories(QList categories) } } -void ModFilterWidget::onCategoryClicked(QListWidgetItem* item) +void ModFilterWidget::onCategoryClicked(QListWidgetItem* itm) { - if (item) - item->setCheckState(item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked); + if (itm) + itm->setCheckState(itm->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked); m_filter->categoryIds.clear(); for (auto i = 0; i < ui->categoriesList->count(); i++) { auto item = ui->categoriesList->item(i); From 85b4e1f24f444627f48fe2e13b6cb34c45aa7361 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 22 Nov 2023 19:23:24 +0200 Subject: [PATCH 14/64] Made column hidden by default Signed-off-by: Trial97 --- launcher/minecraft/mod/ModFolderModel.cpp | 1 + launcher/minecraft/mod/ResourceFolderModel.cpp | 4 ++++ launcher/minecraft/mod/ResourceFolderModel.h | 1 + launcher/minecraft/mod/ResourcePackFolderModel.cpp | 1 + launcher/minecraft/mod/TexturePackFolderModel.cpp | 1 + 5 files changed, 8 insertions(+) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 98e21b9f0..6a948e2ec 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -75,6 +75,7 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true, true, true, true, true, true, true }; + m_columnsHiddenByDefault = { false, false, false, false, false, false, true, true, true, true }; } QVariant ModFolderModel::data(const QModelIndex& index, int role) const diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 4a3ee9922..8a0797c58 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -528,6 +528,10 @@ void ResourceFolderModel::saveColumns(QTreeView* tree) void ResourceFolderModel::loadColumns(QTreeView* tree) { + for (auto i = 0; i < m_columnsHiddenByDefault.size(); ++i) { + tree->setColumnHidden(i, m_columnsHiddenByDefault[i]); + } + auto const setting_name = QString("UI/%1_Page/Columns").arg(id()); auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index b3f6d9a58..77bece636 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -203,6 +203,7 @@ class ResourceFolderModel : public QAbstractListModel { QStringList m_column_names_translated = { tr("Enable"), tr("Name"), tr("Last Modified") }; QList m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive }; QList m_columnsHideable = { false, false, true }; + QList m_columnsHiddenByDefault = { false, false, false }; QDir m_dir; BaseInstance* m_instance; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 693b8af05..3fcbca4ce 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -55,6 +55,7 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive, QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true, true }; + m_columnsHiddenByDefault = { false, false, false, false, false }; } QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index f210501c7..1a35a3795 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -49,6 +49,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true }; + m_columnsHiddenByDefault = { false, false, false, false }; } Task* TexturePackFolderModel::createUpdateTask() From e3af4f9a7892d90f3da9432c686b2e4f211fd499 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 22 Nov 2023 20:34:12 +0200 Subject: [PATCH 15/64] Fixed playtime recording Signed-off-by: Trial97 --- launcher/BaseInstance.cpp | 11 +++++++---- launcher/BaseInstance.h | 1 + launcher/minecraft/launch/LauncherPartLaunch.cpp | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 33dc3f741..bb9e5223a 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -267,13 +267,18 @@ void BaseInstance::setRunning(bool running) m_isRunning = running; - if (!m_settings->get("RecordGameTime").toBool()) { - emit runningStatusChanged(running); + emit runningStatusChanged(running); +} + +void BaseInstance::setMinecraftRunning(bool running) +{ + if (!settings()->get("RecordGameTime").toBool()) { return; } if (running) { m_timeStarted = QDateTime::currentDateTime(); + setLastLaunch(m_timeStarted.toMSecsSinceEpoch()); } else { QDateTime timeEnded = QDateTime::currentDateTime(); @@ -283,8 +288,6 @@ void BaseInstance::setRunning(bool running) emit propertiesChanged(this); } - - emit runningStatusChanged(running); } int64_t BaseInstance::totalTimePlayed() const diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index f4ed9113c..499ec7866 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -104,6 +104,7 @@ class BaseInstance : public QObject, public std::enable_shared_from_thisshowMainWindow(); m_parent->setPid(-1); + m_parent->instance()->setMinecraftRunning(false); // if the exit code wasn't 0, report this as a crash auto exitCode = m_process.exitCode(); if (exitCode != 0) { @@ -228,7 +229,6 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) case LoggedProcess::Running: emit logLine(QString("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::Launcher); m_parent->setPid(m_process.processId()); - m_parent->instance()->setLastLaunch(); // send the launch script to the launcher part m_process.write(m_launchScript.toUtf8()); @@ -248,6 +248,7 @@ void LauncherPartLaunch::setWorkingDirectory(const QString& wd) void LauncherPartLaunch::proceed() { if (mayProceed) { + m_parent->instance()->setMinecraftRunning(true); QString launchString("launch\n"); m_process.write(launchString.toUtf8()); mayProceed = false; From 1a0fd5f9932574c95d0591d4d6d1d64093613f83 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 25 Nov 2023 00:18:10 +0200 Subject: [PATCH 16/64] Added mod reinstall dialog Signed-off-by: Trial97 --- .../ui/dialogs/ResourceDownloadDialog.cpp | 15 +++++ launcher/ui/dialogs/ResourceDownloadDialog.h | 2 + launcher/ui/pages/instance/ModFolderPage.cpp | 63 ++++++++++++++++++- launcher/ui/pages/instance/ModFolderPage.h | 1 + launcher/ui/pages/modplatform/ModModel.cpp | 10 +++ launcher/ui/pages/modplatform/ModModel.h | 1 + launcher/ui/pages/modplatform/ModPage.cpp | 12 +++- launcher/ui/pages/modplatform/ResourceModel.h | 2 + .../ui/pages/modplatform/ResourcePage.cpp | 60 ++++++++++++++++-- launcher/ui/pages/modplatform/ResourcePage.h | 4 ++ launcher/ui/widgets/PageContainer.h | 3 + 11 files changed, 165 insertions(+), 8 deletions(-) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 1431ea92c..5d49c0dfa 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -356,4 +356,19 @@ QList ShaderPackDownloadDialog::getPages() return pages; } +void ModDownloadDialog::setModMetadata(std::shared_ptr meta) +{ + switch (meta->provider) { + case ModPlatform::ResourceProvider::MODRINTH: + selectPage(Modrinth::id()); + break; + case ModPlatform::ResourceProvider::FLAME: + selectPage(Flame::id()); + break; + } + m_container->hidePageList(); + m_buttons.hide(); + auto page = selectedPage(); + page->openProject(meta->project_id); +} } // namespace ResourceDownload diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h index a6efca138..7a0d6e895 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.h +++ b/launcher/ui/dialogs/ResourceDownloadDialog.h @@ -107,6 +107,8 @@ class ModDownloadDialog final : public ResourceDownloadDialog { QList getPages() override; GetModDependenciesTask::Ptr getModDependenciesTask() override; + void setModMetadata(std::shared_ptr); + private: BaseInstance* m_instance; }; diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index ce1cc3a90..e33bcfc36 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -40,6 +40,7 @@ #include "ui_ExternalResourcesPage.h" #include +#include #include #include #include @@ -121,10 +122,16 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->addAction(ui->actionVisitItemPage); connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); + auto changeVersion = new QAction(tr("Reinstall")); + changeVersion->setToolTip(tr("Reinstall mod")); + changeVersion->setEnabled(false); + ui->actionsToolbar->insertActionAfter(ui->actionVisitItemPage, changeVersion); + connect(changeVersion, &QAction::triggered, this, &ModFolderPage::changeModVersion); + auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); }; connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, - [this, check_allow_update, actionRemoveItemMetadata] { + [this, check_allow_update, actionRemoveItemMetadata, changeVersion] { ui->actionUpdateItem->setEnabled(check_allow_update()); auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); @@ -134,11 +141,12 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr if (selected <= 1) { ui->actionVisitItemPage->setText(tr("Visit mod's page")); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); - } else { ui->actionVisitItemPage->setText(tr("Visit mods' pages")); ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); } + + changeVersion->setEnabled(mods_list.length() == 1 && mods_list[0]->metadata() != nullptr); ui->actionVisitItemPage->setEnabled(selected != 0); actionRemoveItemMetadata->setEnabled(selected != 0); }); @@ -372,3 +380,54 @@ void ModFolderPage::deleteModMetadata() m_model->deleteModsMetadata(selection); } + +void ModFolderPage::changeModVersion() +{ + if (m_instance->typeName() != "Minecraft") + return; // this is a null instance or a legacy instance + + auto profile = static_cast(m_instance)->getPackProfile(); + if (!profile->getModLoaders().has_value()) { + QMessageBox::critical(this, tr("Error"), tr("Please install a mod loader first!")); + return; + } + if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) { + QMessageBox::critical(this, tr("Error"), tr("Mod updates are unavailable when metadata is disabled!")); + return; + } + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + auto mods_list = m_model->selectedMods(selection); + if (mods_list.length() != 1 || mods_list[0]->metadata() == nullptr) + return; + + ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance); + mdownload.setModMetadata((*mods_list.begin())->metadata()); + if (mdownload.exec()) { + auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); + connect(tasks, &Task::failed, [this, tasks](QString reason) { + CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); + tasks->deleteLater(); + }); + connect(tasks, &Task::aborted, [this, tasks]() { + CustomMessageBox::selectable(this, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show(); + tasks->deleteLater(); + }); + connect(tasks, &Task::succeeded, [this, tasks]() { + QStringList warnings = tasks->warnings(); + if (warnings.count()) + CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show(); + + tasks->deleteLater(); + }); + + for (auto& task : mdownload.getTasks()) { + tasks->addTask(task); + } + + ProgressDialog loadDialog(this); + loadDialog.setSkipButton(true, tr("Abort")); + loadDialog.execWithTask(tasks); + + m_model->update(); + } +} diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 4672350c6..9aa2fdbb1 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -66,6 +66,7 @@ class ModFolderPage : public ExternalResourcesPage { void installMods(); void updateMods(bool includeDeps = false); void visitModPages(); + void changeModVersion(); protected: std::shared_ptr m_model; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index c628f74ac..e7012c095 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -79,4 +79,14 @@ bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const }); } +QVariant ModModel:: getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const +{ + auto allMods = static_cast(m_base_instance).loaderModList()->allMods(); + for (auto mod : allMods) { + if (auto meta = mod->metadata(); meta && meta->provider == pack->provider && meta->project_id == pack->addonId) { + return meta->version(); + } + } + return {}; +} } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index dd187aa8d..36540bb03 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -35,6 +35,7 @@ class ModModel : public ResourceModel { virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) = 0; void setFilter(std::shared_ptr filter) { m_filter = filter; } + virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const override; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index d6cc1fdcc..0ac08d4dd 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -120,6 +120,8 @@ void ModPage::updateVersionList() auto current_pack = getCurrentPack(); if (!current_pack) return; + auto installedVersion = m_model->getInstalledPackVersion(current_pack); + auto installedIndex = -1; for (int i = 0; i < current_pack->versions.size(); i++) { auto version = current_pack->versions[i]; bool valid = false; @@ -129,13 +131,19 @@ void ModPage::updateVersionList() break; } } - + QString flag; + if (installedIndex == -1 && installedVersion.isValid() && installedVersion == version.fileId) { + flag = tr("[installed]"); + installedIndex = i; + } // Only add the version if it's valid or using the 'Any' filter, but never if the version is opted out if ((valid || m_filter->versions.empty()) && !optedOut(version)) { auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : ""; - m_ui->versionSelectionBox->addItem(QString("%1%2").arg(version.version, release_type), QVariant(i)); + m_ui->versionSelectionBox->addItem(QString("%1%2%3").arg(version.version, release_type, flag), QVariant(i)); } } + if (installedIndex != -1) + m_ui->versionSelectionBox->setCurrentIndex(installedIndex); if (m_ui->versionSelectionBox->count() == 0) { m_ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :(")); diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 12db49080..97f9e36b4 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -55,6 +55,8 @@ class ResourceModel : public QAbstractListModel { [[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); } + virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const { return {}; } + public slots: void fetchMore(const QModelIndex& parent) override; // NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12 diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 44a91003d..00bd7548a 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -260,7 +260,9 @@ void ResourcePage::updateVersionList() m_ui->versionSelectionBox->clear(); m_ui->versionSelectionBox->blockSignals(false); - if (current_pack) + if (current_pack) { + auto installedVersion = m_model->getInstalledPackVersion(current_pack); + for (int i = 0; i < current_pack->versions.size(); i++) { auto& version = current_pack->versions[i]; if (optedOut(version)) @@ -269,9 +271,10 @@ void ResourcePage::updateVersionList() auto release_type = current_pack->versions[i].version_type.isValid() ? QString(" [%1]").arg(current_pack->versions[i].version_type.toString()) : ""; - m_ui->versionSelectionBox->addItem(current_pack->versions[i].version, QVariant(i)); - } + m_ui->versionSelectionBox->addItem(QString("%1%2").arg(version.version, release_type), QVariant(i)); + } + } if (m_ui->versionSelectionBox->count() == 0) { m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1)); m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :(")); @@ -388,7 +391,7 @@ void ResourcePage::openUrl(const QUrl& url) } } - if (!page.isNull()) { + if (!page.isNull() && !m_do_not_jump_to_mod) { const QString slug = match.captured(1); // ensure the user isn't opening the same mod @@ -432,4 +435,53 @@ void ResourcePage::openUrl(const QUrl& url) QDesktopServices::openUrl(url); } +void ResourcePage::openProject(QVariant projectID) +{ + m_ui->sortByBox->hide(); + m_ui->searchButton->hide(); + m_ui->searchEdit->hide(); + m_ui->resourceFilterButton->hide(); + m_ui->packView->hide(); + m_ui->resourceSelectionButton->hide(); + m_do_not_jump_to_mod = true; + + auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + + auto okBtn = buttonBox->button(QDialogButtonBox::Ok); + okBtn->setDefault(true); + okBtn->setAutoDefault(true); + okBtn->setText(tr("Reinstall")); + okBtn->setShortcut(tr("Ctrl+Return")); + okBtn->setEnabled(false); + + auto cancelBtn = buttonBox->button(QDialogButtonBox::Cancel); + cancelBtn->setDefault(false); + cancelBtn->setAutoDefault(false); + + connect(okBtn, &QPushButton::clicked, this, [this] { + onResourceSelected(); + m_parent_dialog->accept(); + }); + + connect(cancelBtn, &QPushButton::clicked, m_parent_dialog, &ResourceDownloadDialog::reject); + m_ui->gridLayout_4->addWidget(buttonBox, 1, 2); + + auto jump = [this, okBtn] { + for (int row = 0; row < m_model->rowCount({}); row++) { + const QModelIndex index = m_model->index(row); + m_ui->packView->setCurrentIndex(index); + okBtn->setEnabled(true); + return; + } + m_ui->packDescription->setText(tr("The resource was not found")); + }; + + m_ui->searchEdit->setText("#" + projectID.toString()); + triggerSearch(); + + if (m_model->hasActiveSearchJob()) + connect(m_model->activeSearchJob().get(), &Task::finished, jump); + else + jump(); +} } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 235b44412..212c83ea5 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -83,6 +83,8 @@ class ResourcePage : public QWidget, public BasePage { QList selectedPacks() { return m_model->selectedPacks(); } bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); } + virtual void openProject(QVariant projectID); + protected slots: virtual void triggerSearch() {} @@ -118,6 +120,8 @@ class ResourcePage : public QWidget, public BasePage { // Used to do instant searching with a delay to cache quick changes QTimer m_search_timer; + + bool m_do_not_jump_to_mod = false; }; } // namespace ResourceDownload diff --git a/launcher/ui/widgets/PageContainer.h b/launcher/ui/widgets/PageContainer.h index 05be1c3a5..ab4444c99 100644 --- a/launcher/ui/widgets/PageContainer.h +++ b/launcher/ui/widgets/PageContainer.h @@ -36,6 +36,7 @@ #pragma once +#include #include #include @@ -86,6 +87,8 @@ class PageContainer : public QWidget, public BasePageContainer { void changeEvent(QEvent*) override; + void hidePageList() { m_pageList->hide(); } + private: void createUI(); void retranslate(); From f4e098f7f542186c907aae2f9e634e36a1aae333 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 25 Nov 2023 09:36:55 +0200 Subject: [PATCH 17/64] Formated file Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ModModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index e7012c095..02fc8a3dd 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -79,7 +79,7 @@ bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const }); } -QVariant ModModel:: getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const +QVariant ModModel::getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const { auto allMods = static_cast(m_base_instance).loaderModList()->allMods(); for (auto mod : allMods) { From 6f6b6312a55d970c6d7d809305151e874a910f79 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 27 Nov 2023 09:39:31 +0200 Subject: [PATCH 18/64] Moved the button up Signed-off-by: Trial97 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 1 + launcher/ui/pages/instance/ModFolderPage.cpp | 6 +++--- launcher/ui/pages/modplatform/ModPage.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 5d49c0dfa..47b58a6ed 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -366,6 +366,7 @@ void ModDownloadDialog::setModMetadata(std::shared_ptr meta selectPage(Flame::id()); break; } + setWindowTitle(tr("Change %1 version").arg(meta->name)); m_container->hidePageList(); m_buttons.hide(); auto page = selectedPage(); diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index e33bcfc36..d46bc5652 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -122,10 +122,10 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->addAction(ui->actionVisitItemPage); connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); - auto changeVersion = new QAction(tr("Reinstall")); - changeVersion->setToolTip(tr("Reinstall mod")); + auto changeVersion = new QAction(tr("Change Version")); + changeVersion->setToolTip(tr("Change mod version")); changeVersion->setEnabled(false); - ui->actionsToolbar->insertActionAfter(ui->actionVisitItemPage, changeVersion); + ui->actionsToolbar->insertActionAfter(ui->actionUpdateItem, changeVersion); connect(changeVersion, &QAction::triggered, this, &ModFolderPage::changeModVersion); auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); }; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 0ac08d4dd..ccbe5b377 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -133,7 +133,7 @@ void ModPage::updateVersionList() } QString flag; if (installedIndex == -1 && installedVersion.isValid() && installedVersion == version.fileId) { - flag = tr("[installed]"); + flag = QString(" [%1]").arg(tr("installed", "Mod version select box")); installedIndex = i; } // Only add the version if it's valid or using the 'Any' filter, but never if the version is opted out From 6a619003288a06c0f664c5454dc4b69a65b4235b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 13 Dec 2023 17:48:11 +0200 Subject: [PATCH 19/64] Fixed curseforge version filter Signed-off-by: Trial97 --- launcher/ui/widgets/ModFilterWidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 341823244..f419537c7 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -177,6 +177,7 @@ void ModFilterWidget::prepareBasicFilter() auto def = m_instance->getPackProfile()->getComponentVersion("net.minecraft"); m_filter->versions.push_front(Version{ def }); ui->versionsCb->setCheckedItems({ def }); + ui->versionsSimpleCb->setCurrentIndex(ui->versionsSimpleCb->findText(def)); } void ModFilterWidget::onIncludeSnapshotsChanged() From 71998cb7d99504d5a6dc16f0c2af606f10c33a94 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 1 Apr 2024 15:22:09 +0100 Subject: [PATCH 20/64] Rework filter widget Signed-off-by: TheKodeToad --- launcher/ui/widgets/ModFilterWidget.cpp | 198 ++++++------- launcher/ui/widgets/ModFilterWidget.h | 10 +- launcher/ui/widgets/ModFilterWidget.ui | 374 ++++++++++-------------- 3 files changed, 250 insertions(+), 332 deletions(-) diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index f419537c7..b44a573d8 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -46,9 +46,9 @@ #include "Application.h" #include "minecraft/PackProfile.h" -unique_qobject_ptr ModFilterWidget::create(MinecraftInstance* instance, bool extendedSupport, QWidget* parent) +unique_qobject_ptr ModFilterWidget::create(MinecraftInstance* instance, bool extended, QWidget* parent) { - return unique_qobject_ptr(new ModFilterWidget(instance, extendedSupport, parent)); + return unique_qobject_ptr(new ModFilterWidget(instance, extended, parent)); } class VersionBasicModel : public QIdentityProxyModel { @@ -65,55 +65,50 @@ class VersionBasicModel : public QIdentityProxyModel { } }; -ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent) +ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWidget* parent) : QTabWidget(parent), ui(new Ui::ModFilterWidget), m_instance(instance), m_filter(new Filter()) { ui->setupUi(this); m_versions_proxy = new VersionProxyModel(this); - m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter("(release)", false)); + m_versions_proxy->setFilter(BaseVersionList::TypeRole, new ExactFilter("release")); auto proxy = new VersionBasicModel(this); proxy->setSourceModel(m_versions_proxy); - if (!extendedSupport) { - ui->versionsSimpleCb->setModel(proxy); - ui->versionsCb->hide(); - ui->snapshotsCb->hide(); - ui->envBox->hide(); + if (extended) { + ui->versions->setSourceModel(proxy); + ui->versions->setSeparator(", "); + ui->version->hide(); } else { - ui->versionsCb->setSourceModel(proxy); - ui->versionsCb->setSeparator("| "); - ui->versionsSimpleCb->hide(); + ui->version->setModel(proxy); + ui->versions->hide(); + ui->showAllVersions->hide(); + ui->environmentGroup->hide(); } - ui->versionsCb->setStyleSheet("combobox-popup: 0;"); - ui->versionsSimpleCb->setStyleSheet("combobox-popup: 0;"); - connect(ui->snapshotsCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onIncludeSnapshotsChanged); - connect(ui->versionsCb, QOverload::of(&QComboBox::currentIndexChanged), this, &ModFilterWidget::onVersionFilterChanged); - connect(ui->versionsSimpleCb, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); + ui->versions->setStyleSheet("combobox-popup: 0;"); + ui->version->setStyleSheet("combobox-popup: 0;"); + connect(ui->showAllVersions, &QCheckBox::stateChanged, this, &ModFilterWidget::onShowAllVersionsChanged); + connect(ui->versions, QOverload::of(&QComboBox::currentIndexChanged), this, &ModFilterWidget::onVersionFilterChanged); + connect(ui->version, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); - connect(ui->neoForgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - connect(ui->forgeCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - connect(ui->fabricCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - connect(ui->quiltCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - connect(ui->liteLoaderCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - connect(ui->cauldronCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->neoForge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->forge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->fabric, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->quilt, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - ui->liteLoaderCb->hide(); - ui->cauldronCb->hide(); + connect(ui->neoForge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->forge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->fabric, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); + connect(ui->quilt, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); - connect(ui->serverEnv, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged); - connect(ui->clientEnv, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged); + if (extended) { + connect(ui->clientSide, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged); + connect(ui->serverSide, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged); + } - connect(ui->hide_installed, &QCheckBox::stateChanged, this, &ModFilterWidget::onHideInstalledFilterChanged); - - connect(ui->releaseCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); - connect(ui->betaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); - connect(ui->alphaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); - connect(ui->unknownCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged); - - connect(ui->categoriesList, &QListWidget::itemClicked, this, &ModFilterWidget::onCategoryClicked); + connect(ui->hideInstalled, &QCheckBox::stateChanged, this, &ModFilterWidget::onHideInstalledFilterChanged); setHidden(true); loadVersionList(); @@ -147,8 +142,8 @@ void ModFilterWidget::loadVersionList() auto task = m_version_list->getLoadTask(); connect(task.get(), &Task::failed, [this] { - ui->versionsCb->setEnabled(false); - ui->snapshotsCb->setEnabled(false); + ui->versions->setEnabled(false); + ui->showAllVersions->setEnabled(false); }); connect(task.get(), &Task::finished, &load_version_list_loop, &QEventLoop::quit); @@ -165,35 +160,35 @@ void ModFilterWidget::loadVersionList() void ModFilterWidget::prepareBasicFilter() { m_filter->hideInstalled = false; - m_filter->side = ""; // or "both"t + m_filter->side = ""; // or "both" auto loaders = m_instance->getPackProfile()->getSupportedModLoaders().value(); - ui->neoForgeCb->setChecked(loaders & ModPlatform::NeoForge); - ui->forgeCb->setChecked(loaders & ModPlatform::Forge); - ui->fabricCb->setChecked(loaders & ModPlatform::Fabric); - ui->quiltCb->setChecked(loaders & ModPlatform::Quilt); - ui->liteLoaderCb->setChecked(loaders & ModPlatform::LiteLoader); - ui->cauldronCb->setChecked(loaders & ModPlatform::Cauldron); + ui->neoForge->setChecked(loaders & ModPlatform::NeoForge); + ui->forge->setChecked(loaders & ModPlatform::Forge); + ui->fabric->setChecked(loaders & ModPlatform::Fabric); + ui->quilt->setChecked(loaders & ModPlatform::Quilt); m_filter->loaders = loaders; auto def = m_instance->getPackProfile()->getComponentVersion("net.minecraft"); - m_filter->versions.push_front(Version{ def }); - ui->versionsCb->setCheckedItems({ def }); - ui->versionsSimpleCb->setCurrentIndex(ui->versionsSimpleCb->findText(def)); + m_filter->versions.emplace_front(def); + ui->versions->setCheckedItems({ def }); + ui->version->setCurrentIndex(ui->version->findText(def)); } -void ModFilterWidget::onIncludeSnapshotsChanged() +void ModFilterWidget::onShowAllVersionsChanged() { - QString filter = "(release)"; - if (ui->snapshotsCb->isChecked()) - filter += "|(snapshot)"; - m_versions_proxy->setFilter(BaseVersionList::TypeRole, new RegexpFilter(filter, false)); + if (ui->showAllVersions->isChecked()) + m_versions_proxy->clearFilters(); + else + m_versions_proxy->setFilter(BaseVersionList::TypeRole, new ExactFilter("release")); } void ModFilterWidget::onVersionFilterChanged(int) { - auto versions = ui->versionsCb->checkedItems(); + auto versions = ui->versions->checkedItems(); m_filter->versions.clear(); - for (auto version : versions) - m_filter->versions.push_back(version); + + for (const QString& version : versions) + m_filter->versions.emplace_back(version); + m_filter_changed = true; emit filterChanged(); } @@ -201,18 +196,14 @@ void ModFilterWidget::onVersionFilterChanged(int) void ModFilterWidget::onLoadersFilterChanged() { ModPlatform::ModLoaderTypes loaders; - if (ui->neoForgeCb->isChecked()) + if (ui->neoForge->isChecked()) loaders |= ModPlatform::NeoForge; - if (ui->forgeCb->isChecked()) + if (ui->forge->isChecked()) loaders |= ModPlatform::Forge; - if (ui->fabricCb->isChecked()) + if (ui->fabric->isChecked()) loaders |= ModPlatform::Fabric; - if (ui->quiltCb->isChecked()) + if (ui->quilt->isChecked()) loaders |= ModPlatform::Quilt; - if (ui->cauldronCb->isChecked()) - loaders |= ModPlatform::Cauldron; - if (ui->liteLoaderCb->isChecked()) - loaders |= ModPlatform::LiteLoader; m_filter_changed = loaders != m_filter->loaders; m_filter->loaders = loaders; if (m_filter_changed) @@ -224,14 +215,17 @@ void ModFilterWidget::onLoadersFilterChanged() void ModFilterWidget::onSideFilterChanged() { QString side; - if (ui->serverEnv->isChecked()) - side = "server"; - if (ui->clientEnv->isChecked()) { - if (side.isEmpty()) + + if (ui->clientSide->isChecked() != ui->serverSide->isChecked()) { + if (ui->clientSide->isChecked()) side = "client"; else - side = ""; // or both + side = "server"; + } else { + // both are checked or none are checked; in either case no filtering will happen + side = ""; } + m_filter_changed = side != m_filter->side; m_filter->side = side; if (m_filter_changed) @@ -242,7 +236,7 @@ void ModFilterWidget::onSideFilterChanged() void ModFilterWidget::onHideInstalledFilterChanged() { - auto hide = ui->hide_installed->isChecked(); + auto hide = ui->hideInstalled->isChecked(); m_filter_changed = hide != m_filter->hideInstalled; m_filter->hideInstalled = hide; if (m_filter_changed) @@ -251,60 +245,36 @@ void ModFilterWidget::onHideInstalledFilterChanged() emit filterUnchanged(); } -void ModFilterWidget::onReleaseFilterChanged() -{ - std::list releases; - if (ui->releaseCb->isChecked()) - releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Release)); - if (ui->betaCb->isChecked()) - releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Beta)); - if (ui->alphaCb->isChecked()) - releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Alpha)); - if (ui->unknownCb->isChecked()) - releases.push_back(ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::VersionType::Unknown)); - m_filter_changed = releases != m_filter->releases; - m_filter->releases = releases; - if (m_filter_changed) - emit filterChanged(); - else - emit filterUnchanged(); -} - -void ModFilterWidget::onVersionFilterTextChanged(QString version) +void ModFilterWidget::onVersionFilterTextChanged(const QString& version) { m_filter->versions.clear(); - m_filter->versions.push_front(version); + m_filter->versions.emplace_back(version); m_filter_changed = true; emit filterChanged(); } -void ModFilterWidget::setCategories(QList categories) +void ModFilterWidget::setCategories(const QList& categories) { - ui->categoriesList->clear(); m_categories = categories; - for (auto cat : categories) { - auto item = new QListWidgetItem(cat.name, ui->categoriesList); - item->setFlags(item->flags() & (~Qt::ItemIsUserCheckable)); - item->setCheckState(Qt::Unchecked); - ui->categoriesList->addItem(item); + + delete ui->categoryGroup->layout(); + auto layout = new QVBoxLayout(ui->categoryGroup); + + for (const auto& category : categories) { + auto checkbox = new QCheckBox(category.name); + layout->addWidget(checkbox); + + const QString id = category.id; + connect(checkbox, &QCheckBox::toggled, this, [this, id](bool checked) { + if (checked) + m_filter->categoryIds.append(id); + else + m_filter->categoryIds.removeOne(id); + + m_filter_changed = true; + emit filterChanged(); + }); } } -void ModFilterWidget::onCategoryClicked(QListWidgetItem* itm) -{ - if (itm) - itm->setCheckState(itm->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked); - m_filter->categoryIds.clear(); - for (auto i = 0; i < ui->categoriesList->count(); i++) { - auto item = ui->categoriesList->item(i); - if (item->checkState() == Qt::Checked) { - auto c = std::find_if(m_categories.cbegin(), m_categories.cend(), [item](auto v) { return v.name == item->text(); }); - if (c != m_categories.cend()) - m_filter->categoryIds << c->id; - } - } - m_filter_changed = true; - emit filterChanged(); -}; - #include "ModFilterWidget.moc" \ No newline at end of file diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index dd98d9afa..4358dd91d 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -73,7 +73,7 @@ class ModFilterWidget : public QTabWidget { bool operator!=(const Filter& other) const { return !(*this == other); } }; - static unique_qobject_ptr create(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); + static unique_qobject_ptr create(MinecraftInstance* instance, bool extended, QWidget* parent = nullptr); virtual ~ModFilterWidget(); auto getFilter() -> std::shared_ptr; @@ -84,7 +84,7 @@ class ModFilterWidget : public QTabWidget { void filterUnchanged(); public slots: - void setCategories(QList); + void setCategories(const QList&); private: ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); @@ -94,13 +94,11 @@ class ModFilterWidget : public QTabWidget { private slots: void onVersionFilterChanged(int); - void onVersionFilterTextChanged(QString version); - void onReleaseFilterChanged(); + void onVersionFilterTextChanged(const QString& version); void onLoadersFilterChanged(); void onSideFilterChanged(); void onHideInstalledFilterChanged(); - void onIncludeSnapshotsChanged(); - void onCategoryClicked(QListWidgetItem* item); + void onShowAllVersionsChanged(); private: Ui::ModFilterWidget* ui; diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index 56cd33fa6..27f3b8610 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -1,237 +1,187 @@ ModFilterWidget - + 0 0 - 460 - 132 + 553 + 604 - - - 0 - 0 - + + Form - - 0 - - - - Minecraft versions - - - - - - Include Snapshots + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 553 + 604 + - - - - - - - 0 - 0 - - - - 5 - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - - - - Loaders - - - - QLayout::SetMinimumSize - - - - - Fabric - - - - - - - NeoForge - - - - - - - Forge - - - - - - - false - - - Cauldron - - - - - - - Quilt - - - - - - - false - - - LiteLoader - - - - - - - - Release type - - - - - - Release - - - - - - - Beta - - - - - - - Alpha - - - - - - - Unknown - - - - - - - - Categories - - - - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoEditTriggers - - - false - - - QAbstractItemView::NoSelection - - - QAbstractItemView::ScrollPerItem - - - QListView::LeftToRight - - - true - - - QListView::ListMode - - - 0 - - - - - - - - Others - - - - - - Environments - - - - QLayout::SetDefaultConstraint - + - - - Client + + + Category + + + false + + + false - + + + Loader + + + false + + + false + + + + + + NeoForge + + + + + + + Forge + + + + + + + Fabric + + + + + + + Quilt + + + + + + + + + + Version + + + false + + + false + + + + + + + + + + + + Show all versions + + + + + + + + + + Environment + + + false + + + false + + + + + + Client + + + + + + + Server + + + + + + + + - Server + Hide installed items + + + + Qt::Vertical + + + + 20 + 40 + + + + - - - - - Instaled status - - - - - - Hide already installed - - - - - - - - + + + From 71904b52c1cd6addd467a44b9dffd9a2f96f30e4 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 1 Apr 2024 15:31:10 +0100 Subject: [PATCH 21/64] Make option groups plural Signed-off-by: TheKodeToad --- launcher/ui/widgets/ModFilterWidget.ui | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index 27f3b8610..5f1e661e4 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -47,7 +47,7 @@ - Category + Categories false @@ -60,7 +60,7 @@ - Loader + Loaders false @@ -103,7 +103,7 @@ - Version + Versions false @@ -112,12 +112,6 @@ false - - - - - - @@ -125,13 +119,19 @@ + + + + + + - Environment + Environments false From 186a6d0c523cf63461fb4d883f0e1ead026bcb6d Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 1 Apr 2024 17:00:10 +0100 Subject: [PATCH 22/64] Make filters vertical Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 3 +- .../ui/pages/modplatform/ResourcePage.cpp | 6 +- launcher/ui/pages/modplatform/ResourcePage.ui | 72 +++++++++++-------- launcher/ui/widgets/ModFilterWidget.ui | 17 +++-- 4 files changed, 57 insertions(+), 41 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 8fd42b427..3561afd38 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -68,10 +68,9 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) if (m_filter_widget) disconnect(m_filter_widget.get(), nullptr, nullptr, nullptr); + m_ui->horizontalLayout->replaceWidget(m_filter_widget == nullptr ? m_ui->filterWidget : m_filter_widget.get(), widget.get()); m_filter_widget.swap(widget); - m_ui->gridLayout_3->addWidget(m_filter_widget.get(), 0, 0, 1, m_ui->gridLayout_3->columnCount()); - m_filter = m_filter_widget->getFilter(); connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, &ResourcePage::updateVersionList); diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 35c4afc0d..112b01b20 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -71,7 +71,7 @@ ResourcePage::ResourcePage(ResourceDownloadDialog* parent, BaseInstance& base_in m_fetch_progress.setFixedHeight(24); m_fetch_progress.progressFormat(""); - m_ui->gridLayout_3->addWidget(&m_fetch_progress, 0, 0, 1, m_ui->gridLayout_3->columnCount()); + layout()->replaceWidget(m_ui->fetchProgress, &m_fetch_progress); m_ui->packView->setItemDelegate(new ProjectItemDelegate(this)); m_ui->packView->installEventFilter(this); @@ -93,8 +93,10 @@ void ResourcePage::retranslate() void ResourcePage::openedImpl() { - if (!supportsFiltering()) + if (!supportsFiltering()) { m_ui->resourceFilterButton->setVisible(false); + m_ui->filterWidget->hide(); + } //: String in the search bar of the mod downloading dialog m_ui->searchEdit->setPlaceholderText(tr("Search for %1...").arg(resourcesString())); diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index 73a9d3b1a..b4f48f074 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -11,19 +11,12 @@ - - - - - - false - - - false - - + + + + - + Qt::ScrollBarAlwaysOff @@ -39,19 +32,19 @@ + + + + false + + + false + + + - - - - Search - - - - - - - + @@ -74,13 +67,6 @@ - - - - Filter options - - - @@ -88,6 +74,26 @@ + + + + + + + Search + + + + + + + + + + Filter options + + + @@ -96,6 +102,12 @@ QTextBrowser
ui/widgets/ProjectDescriptionPage.h
+ + ProgressWidget + QWidget +
ui/widgets/ProgressWidget.h
+ 1 +
searchEdit diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index 5f1e661e4..13727167f 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -6,10 +6,16 @@ 0 0 - 553 - 604 + 310 + 600 + + + 310 + 16777215 + + Form @@ -28,9 +34,6 @@ - - QFrame::NoFrame - true @@ -39,8 +42,8 @@ 0 0 - 553 - 604 + 308 + 598 From 1961e2081fc8f0787622820a33543751b8aef0a7 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 25 Apr 2024 00:48:40 +0300 Subject: [PATCH 23/64] Removed scroll from version checkbox Signed-off-by: Trial97 --- launcher/ui/widgets/CheckComboBox.cpp | 4 ++-- launcher/ui/widgets/ModFilterWidget.cpp | 9 +++++++++ launcher/ui/widgets/ModFilterWidget.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index 8117baa58..189f7ebb4 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -68,10 +68,10 @@ class CheckComboModel : public QIdentityProxyModel { QStringList checked; }; -CheckComboBox::CheckComboBox(QWidget* parent) : QComboBox(parent), m_separator(",") +CheckComboBox::CheckComboBox(QWidget* parent) : QComboBox(parent), m_separator(", ") { QLineEdit* lineEdit = new QLineEdit(this); - lineEdit->setReadOnly(false); + lineEdit->setReadOnly(true); setLineEdit(lineEdit); lineEdit->disconnect(this); setInsertPolicy(QComboBox::NoInsert); diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index b44a573d8..ead573aee 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -89,6 +89,8 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi ui->versions->setStyleSheet("combobox-popup: 0;"); ui->version->setStyleSheet("combobox-popup: 0;"); + ui->versions->installEventFilter(this); + ui->version->installEventFilter(this); connect(ui->showAllVersions, &QCheckBox::stateChanged, this, &ModFilterWidget::onShowAllVersionsChanged); connect(ui->versions, QOverload::of(&QComboBox::currentIndexChanged), this, &ModFilterWidget::onVersionFilterChanged); connect(ui->version, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); @@ -115,6 +117,13 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi prepareBasicFilter(); } +bool ModFilterWidget::eventFilter(QObject* obj, QEvent* evt) +{ + if ((obj != ui->versions && obj != ui->version) || evt->type() != QEvent::Wheel) + return QTabWidget::eventFilter(obj, evt); + return true; +} + auto ModFilterWidget::getFilter() -> std::shared_ptr { m_filter_changed = false; diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 4358dd91d..35125c910 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -85,6 +85,7 @@ class ModFilterWidget : public QTabWidget { public slots: void setCategories(const QList&); + bool eventFilter(QObject* obj, QEvent* evt); private: ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); From e1ed317c137c2ea3f4f54cb5a1c65e9f309d3ad1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 26 Apr 2024 00:16:48 +0300 Subject: [PATCH 24/64] Updated CheckComboBox to look more like QComboBox Signed-off-by: Trial97 --- launcher/ui/widgets/CheckComboBox.cpp | 56 +++++++++++++------------ launcher/ui/widgets/CheckComboBox.h | 5 ++- launcher/ui/widgets/ModFilterWidget.cpp | 9 ---- launcher/ui/widgets/ModFilterWidget.h | 1 - 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index 189f7ebb4..f8411dd79 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -26,6 +26,7 @@ #include #include #include +#include class CheckComboModel : public QIdentityProxyModel { Q_OBJECT @@ -70,12 +71,6 @@ class CheckComboModel : public QIdentityProxyModel { CheckComboBox::CheckComboBox(QWidget* parent) : QComboBox(parent), m_separator(", ") { - QLineEdit* lineEdit = new QLineEdit(this); - lineEdit->setReadOnly(true); - setLineEdit(lineEdit); - lineEdit->disconnect(this); - setInsertPolicy(QComboBox::NoInsert); - view()->installEventFilter(this); view()->window()->installEventFilter(this); view()->viewport()->installEventFilter(this); @@ -89,9 +84,9 @@ void CheckComboBox::setSourceModel(QAbstractItemModel* new_model) model()->disconnect(this); QComboBox::setModel(proxy); connect(this, QOverload::of(&QComboBox::activated), this, &CheckComboBox::toggleCheckState); - connect(proxy, &CheckComboModel::checkStateChanged, this, &CheckComboBox::updateCheckedItems); - connect(model(), &CheckComboModel::rowsInserted, this, &CheckComboBox::updateCheckedItems); - connect(model(), &CheckComboModel::rowsRemoved, this, &CheckComboBox::updateCheckedItems); + connect(proxy, &CheckComboModel::checkStateChanged, this, &CheckComboBox::emitCheckedItemsChanged); + connect(model(), &CheckComboModel::rowsInserted, this, &CheckComboBox::emitCheckedItemsChanged); + connect(model(), &CheckComboModel::rowsRemoved, this, &CheckComboBox::emitCheckedItemsChanged); } void CheckComboBox::hidePopup() @@ -100,15 +95,9 @@ void CheckComboBox::hidePopup() QComboBox::hidePopup(); } -void CheckComboBox::updateCheckedItems() +void CheckComboBox::emitCheckedItemsChanged() { - QStringList items = checkedItems(); - if (items.isEmpty()) - setEditText(defaultText()); - else - setEditText(items.join(separator())); - - emit checkedItemsChanged(items); + emit checkedItemsChanged(checkedItems()); } QString CheckComboBox::defaultText() const @@ -118,10 +107,7 @@ QString CheckComboBox::defaultText() const void CheckComboBox::setDefaultText(const QString& text) { - if (m_default_text != text) { - m_default_text = text; - updateCheckedItems(); - } + m_default_text = text; } QString CheckComboBox::separator() const @@ -131,10 +117,7 @@ QString CheckComboBox::separator() const void CheckComboBox::setSeparator(const QString& separator) { - if (m_separator != separator) { - m_separator = separator; - updateCheckedItems(); - } + m_separator = separator; } bool CheckComboBox::eventFilter(QObject* receiver, QEvent* event) @@ -157,6 +140,8 @@ bool CheckComboBox::eventFilter(QObject* receiver, QEvent* event) case QEvent::MouseButtonRelease: containerMousePress = false; break; + case QEvent::Wheel: + return receiver == this; default: break; } @@ -170,7 +155,7 @@ void CheckComboBox::toggleCheckState(int index) Qt::CheckState state = static_cast(value.toInt()); setItemData(index, (state == Qt::Unchecked ? Qt::Checked : Qt::Unchecked), Qt::CheckStateRole); } - updateCheckedItems(); + emitCheckedItemsChanged(); } Qt::CheckState CheckComboBox::itemCheckState(int index) const @@ -198,4 +183,23 @@ void CheckComboBox::setCheckedItems(const QStringList& items) } } +void CheckComboBox::paintEvent(QPaintEvent*) +{ + QStylePainter painter(this); + painter.setPen(palette().color(QPalette::Text)); + + // draw the combobox frame, focusrect and selected etc. + QStyleOptionComboBox opt; + initStyleOption(&opt); + QStringList items = checkedItems(); + if (items.isEmpty()) + opt.currentText = defaultText(); + else + opt.currentText = items.join(separator()); + painter.drawComplexControl(QStyle::CC_ComboBox, opt); + + // draw the icon and text + painter.drawControl(QStyle::CE_ComboBoxLabel, opt); +} + #include "CheckComboBox.moc" \ No newline at end of file diff --git a/launcher/ui/widgets/CheckComboBox.h b/launcher/ui/widgets/CheckComboBox.h index 4d6daf5a4..876c6e3e1 100644 --- a/launcher/ui/widgets/CheckComboBox.h +++ b/launcher/ui/widgets/CheckComboBox.h @@ -49,8 +49,11 @@ class CheckComboBox : public QComboBox { signals: void checkedItemsChanged(const QStringList& items); + protected: + void paintEvent(QPaintEvent*) override; + private: - void updateCheckedItems(); + void emitCheckedItemsChanged(); bool eventFilter(QObject* receiver, QEvent* event) override; void toggleCheckState(int index); diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index ead573aee..b44a573d8 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -89,8 +89,6 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi ui->versions->setStyleSheet("combobox-popup: 0;"); ui->version->setStyleSheet("combobox-popup: 0;"); - ui->versions->installEventFilter(this); - ui->version->installEventFilter(this); connect(ui->showAllVersions, &QCheckBox::stateChanged, this, &ModFilterWidget::onShowAllVersionsChanged); connect(ui->versions, QOverload::of(&QComboBox::currentIndexChanged), this, &ModFilterWidget::onVersionFilterChanged); connect(ui->version, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); @@ -117,13 +115,6 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi prepareBasicFilter(); } -bool ModFilterWidget::eventFilter(QObject* obj, QEvent* evt) -{ - if ((obj != ui->versions && obj != ui->version) || evt->type() != QEvent::Wheel) - return QTabWidget::eventFilter(obj, evt); - return true; -} - auto ModFilterWidget::getFilter() -> std::shared_ptr { m_filter_changed = false; diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 35125c910..4358dd91d 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -85,7 +85,6 @@ class ModFilterWidget : public QTabWidget { public slots: void setCategories(const QList&); - bool eventFilter(QObject* obj, QEvent* evt); private: ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr); From 399071c717a31a29329c38ae997569ee46c3a634 Mon Sep 17 00:00:00 2001 From: Richard-Rogalski Date: Tue, 21 May 2024 11:41:47 -0500 Subject: [PATCH 25/64] Fix Java auto-detect so it finds Gentoo installed JDKs Signed-off-by: Richard-Rogalski --- launcher/java/JavaUtils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index e767eff89..5e7137c85 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -405,6 +405,10 @@ QList JavaUtils::FindJavaPaths() scanJavaDirs("/usr/lib/jvm"); scanJavaDirs("/usr/lib64/jvm"); scanJavaDirs("/usr/lib32/jvm"); + // Gentoo's locations for openjdk and openjdk-bin respectively + scanJavaDir("/usr/lib64"); + scanJavaDir("/usr/lib"); + scanJavaDir("/opt"); // javas stored in Prism Launcher's folder scanJavaDirs("java"); // manually installed JDKs in /opt From 3f7847ad34abd71aaab2a730b39e7f27b7bef706 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 28 May 2024 14:47:44 +0300 Subject: [PATCH 26/64] made ResourcePage elements resizable Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ModPage.cpp | 2 +- launcher/ui/pages/modplatform/ResourcePage.ui | 110 +++++++++--------- launcher/ui/widgets/ModFilterWidget.ui | 21 ++++ 3 files changed, 77 insertions(+), 56 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index fc70e9f60..8eb605f9e 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -68,7 +68,7 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) if (m_filter_widget) disconnect(m_filter_widget.get(), nullptr, nullptr, nullptr); - m_ui->horizontalLayout->replaceWidget(m_filter_widget == nullptr ? m_ui->filterWidget : m_filter_widget.get(), widget.get()); + m_ui->spliter->replaceWidget(0, widget.get()); m_filter_widget.swap(widget); m_filter = m_filter_widget->getFilter(); diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index b4f48f074..7ef94a5ce 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -11,38 +11,62 @@ + + + + Qt::Vertical + + + + + + + + + + Filter options + + + - - - - - - - - Qt::ScrollBarAlwaysOff - - - true - - - - 48 - 48 - - - - - - - - false - - - false - - - - + + + Qt::Horizontal + + + false + + + + + Qt::ScrollBarAlwaysOff + + + true + + + + 48 + 48 + + + + + + false + + + false + + + + + + + + Search + + @@ -67,33 +91,9 @@ - - - - Qt::Vertical - - - - - - - - - - Search - - - - - - - Filter options - - -
diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui index 13727167f..236847094 100644 --- a/launcher/ui/widgets/ModFilterWidget.ui +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -10,6 +10,18 @@ 600 + + + 0 + 0 + + + + + 275 + 0 + + 310 @@ -34,6 +46,15 @@ + + + 275 + 0 + + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + true From 5012178a98b702255b28fe356ab7b2cd88498aba Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 28 May 2024 14:48:03 +0300 Subject: [PATCH 27/64] trigger search on filter change Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ModPage.cpp | 2 +- launcher/ui/widgets/ModFilterWidget.cpp | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 8eb605f9e..17b8a93ba 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -73,7 +73,7 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) m_filter = m_filter_widget->getFilter(); - connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, &ResourcePage::updateVersionList); + connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, &ModPage::triggerSearch); connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, [&] { m_ui->searchButton->setStyleSheet("text-decoration: underline"); }); connect(m_filter_widget.get(), &ModFilterWidget::filterUnchanged, this, diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index b44a573d8..d59b4ebe5 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -38,9 +38,12 @@ #include #include #include +#include #include "BaseVersionList.h" +#include "Version.h" #include "meta/Index.h" #include "modplatform/ModIndex.h" +#include "ui/widgets/CheckComboBox.h" #include "ui_ModFilterWidget.h" #include "Application.h" @@ -91,6 +94,7 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi ui->version->setStyleSheet("combobox-popup: 0;"); connect(ui->showAllVersions, &QCheckBox::stateChanged, this, &ModFilterWidget::onShowAllVersionsChanged); connect(ui->versions, QOverload::of(&QComboBox::currentIndexChanged), this, &ModFilterWidget::onVersionFilterChanged); + connect(ui->versions, &CheckComboBox::checkedItemsChanged, this, [this] { onVersionFilterChanged(0); }); connect(ui->version, &QComboBox::currentTextChanged, this, &ModFilterWidget::onVersionFilterTextChanged); connect(ui->neoForge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged); @@ -184,13 +188,19 @@ void ModFilterWidget::onShowAllVersionsChanged() void ModFilterWidget::onVersionFilterChanged(int) { auto versions = ui->versions->checkedItems(); - m_filter->versions.clear(); + versions.sort(); + std::list current_list; for (const QString& version : versions) - m_filter->versions.emplace_back(version); + current_list.emplace_back(version); - m_filter_changed = true; - emit filterChanged(); + m_filter_changed = m_filter->versions.size() != current_list.size() || + !std::equal(m_filter->versions.begin(), m_filter->versions.end(), current_list.begin(), current_list.end()); + m_filter->versions = current_list; + if (m_filter_changed) + emit filterChanged(); + else + emit filterUnchanged(); } void ModFilterWidget::onLoadersFilterChanged() From f3325030880750eb6b8f3940bb5f3fa1aee791ed Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Wed, 29 May 2024 00:32:17 +0300 Subject: [PATCH 28/64] Apply suggestions from code review Co-authored-by: Tayou Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/pages/modplatform/ModPage.cpp | 2 +- launcher/ui/pages/modplatform/ResourcePage.ui | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 17b8a93ba..3f87e8207 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -68,7 +68,7 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) if (m_filter_widget) disconnect(m_filter_widget.get(), nullptr, nullptr, nullptr); - m_ui->spliter->replaceWidget(0, widget.get()); + m_ui->splitter->replaceWidget(0, widget.get()); m_filter_widget.swap(widget); m_filter = m_filter_widget->getFilter(); diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index 7ef94a5ce..3e666c8c1 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -29,7 +29,7 @@ - + Qt::Horizontal From b256d325f7c38cf038d7fba3478b9c4d0b671b1a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 29 May 2024 01:03:17 +0300 Subject: [PATCH 29/64] fix win combobox Signed-off-by: Trial97 --- launcher/ui/widgets/CheckComboBox.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index f8411dd79..644f94795 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -133,12 +133,12 @@ bool CheckComboBox::eventFilter(QObject* receiver, QEvent* event) QComboBox::hidePopup(); return (keyEvent->key() != Qt::Key_Escape); } + break; } case QEvent::MouseButtonPress: - containerMousePress = (receiver == view()->window()); - break; + /* fallthrough */ case QEvent::MouseButtonRelease: - containerMousePress = false; + containerMousePress = (receiver == view()->window()); break; case QEvent::Wheel: return receiver == this; From 660772d4d7dda6db8cb0d744c3bd96a758570573 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 29 May 2024 01:06:11 +0300 Subject: [PATCH 30/64] swap buttons Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourcePage.ui | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index 3e666c8c1..c42325f65 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -11,23 +11,19 @@ - - - - Qt::Vertical - - - - - + + - Filter options + Search + + + @@ -61,13 +57,6 @@ - - - - Search - - - @@ -91,8 +80,12 @@ - - + + + + Filter options + + @@ -110,7 +103,6 @@ - searchEdit searchButton packView packDescription From 29444cfe0fb9e19397646701d059e02e06874862 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 29 May 2024 17:19:15 +0300 Subject: [PATCH 31/64] fix win combobox take#2 Signed-off-by: Trial97 --- launcher/ui/widgets/CheckComboBox.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/launcher/ui/widgets/CheckComboBox.cpp b/launcher/ui/widgets/CheckComboBox.cpp index 644f94795..41def3ba1 100644 --- a/launcher/ui/widgets/CheckComboBox.cpp +++ b/launcher/ui/widgets/CheckComboBox.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -91,7 +92,7 @@ void CheckComboBox::setSourceModel(QAbstractItemModel* new_model) void CheckComboBox::hidePopup() { - if (containerMousePress) + if (!containerMousePress) QComboBox::hidePopup(); } @@ -135,11 +136,11 @@ bool CheckComboBox::eventFilter(QObject* receiver, QEvent* event) } break; } - case QEvent::MouseButtonPress: - /* fallthrough */ - case QEvent::MouseButtonRelease: - containerMousePress = (receiver == view()->window()); + case QEvent::MouseButtonPress: { + auto ev = static_cast(event); + containerMousePress = ev && view()->indexAt(ev->pos()).isValid(); break; + } case QEvent::Wheel: return receiver == this; default: From b8fe93efa35ffcecf41554f38eda1bf486272407 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 29 May 2024 19:52:58 +0200 Subject: [PATCH 32/64] fix & clean ResourcePage.ui Qt is cursed. Signed-off-by: Tayou --- launcher/ui/pages/modplatform/ResourcePage.ui | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index c42325f65..964437cc7 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -11,23 +11,38 @@ - - - - - - - Search + + + + false - - + + + + + + Filter options + + + + + + + + + + Search + + + + - + - Qt::Horizontal + Qt::Orientation::Horizontal false @@ -35,7 +50,7 @@ - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff true @@ -57,7 +72,7 @@ - + @@ -68,7 +83,7 @@ Version selected: - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -80,13 +95,6 @@ - - - - Filter options - - -
From 469f051e30994e92902986aebd1d58bcf52d596f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 30 May 2024 00:14:37 +0300 Subject: [PATCH 33/64] remove search button Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ModPage.cpp | 12 +++---- .../ui/pages/modplatform/ResourcePackPage.cpp | 1 - .../ui/pages/modplatform/ResourcePage.cpp | 9 ++++- launcher/ui/pages/modplatform/ResourcePage.h | 2 +- launcher/ui/pages/modplatform/ResourcePage.ui | 36 ++++++++----------- .../ui/pages/modplatform/ShaderPackPage.cpp | 1 - .../ui/pages/modplatform/TexturePackPage.h | 1 - launcher/ui/widgets/ModFilterWidget.cpp | 9 ----- launcher/ui/widgets/ModFilterWidget.h | 1 - 9 files changed, 29 insertions(+), 43 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 3f87e8207..c9817cdf7 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -58,7 +58,6 @@ namespace ResourceDownload { ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) { - connect(m_ui->searchButton, &QPushButton::clicked, this, &ModPage::triggerSearch); connect(m_ui->resourceFilterButton, &QPushButton::clicked, this, &ModPage::filterMods); connect(m_ui->packView, &QListView::doubleClicked, this, &ModPage::onResourceSelected); } @@ -68,16 +67,17 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) if (m_filter_widget) disconnect(m_filter_widget.get(), nullptr, nullptr, nullptr); - m_ui->splitter->replaceWidget(0, widget.get()); + auto old = m_ui->splitter->replaceWidget(0, widget.get()); + // because we replaced the widget we also need to delete it + if (old) { + delete old; + } + m_filter_widget.swap(widget); m_filter = m_filter_widget->getFilter(); connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, &ModPage::triggerSearch); - connect(m_filter_widget.get(), &ModFilterWidget::filterChanged, this, - [&] { m_ui->searchButton->setStyleSheet("text-decoration: underline"); }); - connect(m_filter_widget.get(), &ModFilterWidget::filterUnchanged, this, - [&] { m_ui->searchButton->setStyleSheet("text-decoration: none"); }); prepareProviderCategories(); } diff --git a/launcher/ui/pages/modplatform/ResourcePackPage.cpp b/launcher/ui/pages/modplatform/ResourcePackPage.cpp index fc2dc15f3..849ea1111 100644 --- a/launcher/ui/pages/modplatform/ResourcePackPage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePackPage.cpp @@ -15,7 +15,6 @@ namespace ResourceDownload { ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) { - connect(m_ui->searchButton, &QPushButton::clicked, this, &ResourcePackResourcePage::triggerSearch); connect(m_ui->packView, &QListView::doubleClicked, this, &ResourcePackResourcePage::onResourceSelected); } diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 9c2c8990a..713feb254 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -67,11 +67,18 @@ ResourcePage::ResourcePage(ResourceDownloadDialog* parent, BaseInstance& base_in connect(&m_search_timer, &QTimer::timeout, this, &ResourcePage::triggerSearch); + // hide both progress bars to prevent weird artifact + m_ui->fetchProgress->hide(); + m_fetch_progress.hide(); m_fetch_progress.hideIfInactive(true); m_fetch_progress.setFixedHeight(24); m_fetch_progress.progressFormat(""); - layout()->replaceWidget(m_ui->fetchProgress, &m_fetch_progress); + auto old = layout()->replaceWidget(m_ui->fetchProgress, &m_fetch_progress); + // because we replaced the widget we also need to delete it + if (old) { + delete old; + } m_ui->packView->setItemDelegate(new ProjectItemDelegate(this)); m_ui->packView->installEventFilter(this); diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 6cc117320..938e549f6 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -84,7 +84,7 @@ class ResourcePage : public QWidget, public BasePage { bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); } protected slots: - virtual void triggerSearch() {} + virtual void triggerSearch() = 0; void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index 964437cc7..202ba1ceb 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -10,15 +10,8 @@ 685 - - - - - false - - - - + + @@ -30,19 +23,19 @@ - - - - Search - - - - + + + + false + + + + - Qt::Orientation::Horizontal + Qt::Horizontal false @@ -50,7 +43,7 @@ - Qt::ScrollBarPolicy::ScrollBarAlwaysOff + Qt::ScrollBarAlwaysOff true @@ -72,7 +65,7 @@ - + @@ -83,7 +76,7 @@ Version selected: - Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -111,7 +104,6 @@ - searchButton packView packDescription sortByBox diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp index 8be068312..ebd8d4ea2 100644 --- a/launcher/ui/pages/modplatform/ShaderPackPage.cpp +++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp @@ -16,7 +16,6 @@ namespace ResourceDownload { ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) { - connect(m_ui->searchButton, &QPushButton::clicked, this, &ShaderPackResourcePage::triggerSearch); connect(m_ui->packView, &QListView::doubleClicked, this, &ShaderPackResourcePage::onResourceSelected); } diff --git a/launcher/ui/pages/modplatform/TexturePackPage.h b/launcher/ui/pages/modplatform/TexturePackPage.h index 948e5286b..42aa921c5 100644 --- a/launcher/ui/pages/modplatform/TexturePackPage.h +++ b/launcher/ui/pages/modplatform/TexturePackPage.h @@ -41,7 +41,6 @@ class TexturePackResourcePage : public ResourcePackResourcePage { protected: TexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance) : ResourcePackResourcePage(dialog, instance) { - connect(m_ui->searchButton, &QPushButton::clicked, this, &TexturePackResourcePage::triggerSearch); connect(m_ui->packView, &QListView::doubleClicked, this, &TexturePackResourcePage::onResourceSelected); } }; diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index d59b4ebe5..6503c684f 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -122,7 +122,6 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi auto ModFilterWidget::getFilter() -> std::shared_ptr { m_filter_changed = false; - emit filterUnchanged(); return m_filter; } @@ -199,8 +198,6 @@ void ModFilterWidget::onVersionFilterChanged(int) m_filter->versions = current_list; if (m_filter_changed) emit filterChanged(); - else - emit filterUnchanged(); } void ModFilterWidget::onLoadersFilterChanged() @@ -218,8 +215,6 @@ void ModFilterWidget::onLoadersFilterChanged() m_filter->loaders = loaders; if (m_filter_changed) emit filterChanged(); - else - emit filterUnchanged(); } void ModFilterWidget::onSideFilterChanged() @@ -240,8 +235,6 @@ void ModFilterWidget::onSideFilterChanged() m_filter->side = side; if (m_filter_changed) emit filterChanged(); - else - emit filterUnchanged(); } void ModFilterWidget::onHideInstalledFilterChanged() @@ -251,8 +244,6 @@ void ModFilterWidget::onHideInstalledFilterChanged() m_filter->hideInstalled = hide; if (m_filter_changed) emit filterChanged(); - else - emit filterUnchanged(); } void ModFilterWidget::onVersionFilterTextChanged(const QString& version) diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 4358dd91d..fdfd2c8bb 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -81,7 +81,6 @@ class ModFilterWidget : public QTabWidget { signals: void filterChanged(); - void filterUnchanged(); public slots: void setCategories(const QList&); From 7fed5e9173efa297aa20f308fcedb57a13c1870d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 30 May 2024 08:51:36 +0300 Subject: [PATCH 34/64] Capitalize the mod categories Signed-off-by: Trial97 --- launcher/ui/widgets/ModFilterWidget.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 6503c684f..bbb91eac2 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -262,7 +262,14 @@ void ModFilterWidget::setCategories(const QList& categori auto layout = new QVBoxLayout(ui->categoryGroup); for (const auto& category : categories) { - auto checkbox = new QCheckBox(category.name); + auto name = category.name; + name.replace("-", " "); + name.replace("&", "&&"); + auto checkbox = new QCheckBox(name); + auto font = checkbox->font(); + font.setCapitalization(QFont::Capitalize); + checkbox->setFont(font); + layout->addWidget(checkbox); const QString id = category.id; From 8704cd84021049f5999cbc2d875be51a528719ee Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 30 May 2024 11:49:09 +0300 Subject: [PATCH 35/64] remove duplicate proggress bar Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourcePage.cpp | 9 ++------- launcher/ui/pages/modplatform/ResourcePage.ui | 13 ------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 713feb254..4f49cc4f4 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -67,18 +67,13 @@ ResourcePage::ResourcePage(ResourceDownloadDialog* parent, BaseInstance& base_in connect(&m_search_timer, &QTimer::timeout, this, &ResourcePage::triggerSearch); - // hide both progress bars to prevent weird artifact - m_ui->fetchProgress->hide(); + // hide progress bar to prevent weird artifact m_fetch_progress.hide(); m_fetch_progress.hideIfInactive(true); m_fetch_progress.setFixedHeight(24); m_fetch_progress.progressFormat(""); - auto old = layout()->replaceWidget(m_ui->fetchProgress, &m_fetch_progress); - // because we replaced the widget we also need to delete it - if (old) { - delete old; - } + m_ui->verticalLayout->insertWidget(1, &m_fetch_progress); m_ui->packView->setItemDelegate(new ProjectItemDelegate(this)); m_ui->packView->installEventFilter(this); diff --git a/launcher/ui/pages/modplatform/ResourcePage.ui b/launcher/ui/pages/modplatform/ResourcePage.ui index 202ba1ceb..491e7d9f0 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.ui +++ b/launcher/ui/pages/modplatform/ResourcePage.ui @@ -25,13 +25,6 @@ - - - - false - - - @@ -96,12 +89,6 @@ QTextBrowser
ui/widgets/ProjectDescriptionPage.h
- - ProgressWidget - QWidget -
ui/widgets/ProgressWidget.h
- 1 -
packView From 3263a706b462ff6ab449d11776b9791a0e46d41a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:39:15 +0000 Subject: [PATCH 36/64] chore(deps): update determinatesystems/update-flake-lock action to v22 --- .github/workflows/update-flake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml index a923edd1d..2226d0710 100644 --- a/.github/workflows/update-flake.yml +++ b/.github/workflows/update-flake.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v4 - uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27 - - uses: DeterminateSystems/update-flake-lock@v21 + - uses: DeterminateSystems/update-flake-lock@v22 with: commit-msg: "chore(nix): update lockfile" pr-title: "chore(nix): update lockfile" From 052ee0d71c4735163b9f4a9200fc2f1372483740 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:48:19 +0200 Subject: [PATCH 37/64] chore: update Qt to 6.7.1 Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b530dad9..8212af233 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -79,7 +79,7 @@ jobs: qt_ver: 6 qt_host: windows qt_arch: "" - qt_version: "6.7.0" + qt_version: "6.7.1" qt_modules: "qt5compat qtimageformats qtnetworkauth" - os: windows-2022 @@ -90,7 +90,7 @@ jobs: qt_ver: 6 qt_host: windows qt_arch: "win64_msvc2019_arm64" - qt_version: "6.7.0" + qt_version: "6.7.1" qt_modules: "qt5compat qtimageformats qtnetworkauth" - os: macos-12 @@ -99,7 +99,7 @@ jobs: qt_ver: 6 qt_host: mac qt_arch: "" - qt_version: "6.7.0" + qt_version: "6.7.1" qt_modules: "qt5compat qtimageformats qtnetworkauth" - os: macos-12 From d5fb9f0935f10d372d6707bdb80677e8189206da Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jun 2024 10:21:21 +0300 Subject: [PATCH 38/64] force aspect ratio for skin preview Signed-off-by: Trial97 --- launcher/ui/dialogs/skins/SkinManageDialog.cpp | 16 ++++++++++++++-- launcher/ui/dialogs/skins/SkinManageDialog.h | 1 + launcher/ui/dialogs/skins/SkinManageDialog.ui | 10 ++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/launcher/ui/dialogs/skins/SkinManageDialog.cpp b/launcher/ui/dialogs/skins/SkinManageDialog.cpp index d676ac38c..d1eeb759d 100644 --- a/launcher/ui/dialogs/skins/SkinManageDialog.cpp +++ b/launcher/ui/dialogs/skins/SkinManageDialog.cpp @@ -118,7 +118,7 @@ void SkinManageDialog::selectionChanged(QItemSelection selected, QItemSelection auto skin = m_list.skin(key); if (!skin) return; - ui->selectedModel->setPixmap(skin->getTexture().scaled(128, 128, Qt::KeepAspectRatio, Qt::FastTransformation)); + ui->selectedModel->setPixmap(skin->getTexture().scaled(size() * (1. / 3), Qt::KeepAspectRatio, Qt::FastTransformation)); ui->capeCombo->setCurrentIndex(m_capes_idx.value(skin->getCapeId())); ui->steveBtn->setChecked(skin->getModel() == SkinModel::CLASSIC); ui->alexBtn->setChecked(skin->getModel() == SkinModel::SLIM); @@ -212,7 +212,7 @@ void SkinManageDialog::setupCapes() void SkinManageDialog::on_capeCombo_currentIndexChanged(int index) { auto id = ui->capeCombo->currentData(); - ui->capeImage->setPixmap(m_capes.value(id.toString(), {})); + ui->capeImage->setPixmap(m_capes.value(id.toString(), {}).scaled(size() * (1. / 3), Qt::KeepAspectRatio, Qt::FastTransformation)); if (auto skin = m_list.skin(m_selected_skin); skin) { skin->setCapeId(id.toString()); } @@ -498,3 +498,15 @@ void SkinManageDialog::on_userBtn_clicked() } m_list.updateSkin(&s); } + +void SkinManageDialog::resizeEvent(QResizeEvent* event) +{ + QWidget::resizeEvent(event); + QSize s = size() * (1. / 3); + + if (auto skin = m_list.skin(m_selected_skin); skin) { + ui->selectedModel->setPixmap(skin->getTexture().scaled(s, Qt::KeepAspectRatio, Qt::FastTransformation)); + } + auto id = ui->capeCombo->currentData(); + ui->capeImage->setPixmap(m_capes.value(id.toString(), {}).scaled(s, Qt::KeepAspectRatio, Qt::FastTransformation)); +} diff --git a/launcher/ui/dialogs/skins/SkinManageDialog.h b/launcher/ui/dialogs/skins/SkinManageDialog.h index ce8fc9348..cdb37a513 100644 --- a/launcher/ui/dialogs/skins/SkinManageDialog.h +++ b/launcher/ui/dialogs/skins/SkinManageDialog.h @@ -34,6 +34,7 @@ class SkinManageDialog : public QDialog { public: explicit SkinManageDialog(QWidget* parent, MinecraftAccountPtr acct); virtual ~SkinManageDialog(); + void resizeEvent(QResizeEvent* event) override; public slots: void selectionChanged(QItemSelection, QItemSelection); diff --git a/launcher/ui/dialogs/skins/SkinManageDialog.ui b/launcher/ui/dialogs/skins/SkinManageDialog.ui index ed8b7e530..c77eeaaa3 100644 --- a/launcher/ui/dialogs/skins/SkinManageDialog.ui +++ b/launcher/ui/dialogs/skins/SkinManageDialog.ui @@ -24,7 +24,10 @@
- true + false + + + Qt::AlignCenter
@@ -75,7 +78,10 @@ - true + false + + + Qt::AlignCenter From a121bfbb15cad179dc922921e8a2cccc2a788fce Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jun 2024 10:43:21 +0300 Subject: [PATCH 39/64] add size back to texture view Signed-off-by: Trial97 --- launcher/minecraft/mod/TexturePackFolderModel.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 16b7328cf..577b33878 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -45,11 +45,12 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) { - m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified" }); - m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified") }); + m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified", "Size" }); + m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified"), tr("Size") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; - m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive }; - m_columnsHideable = { false, true, false, true }; + m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive, + QHeaderView::Interactive }; + m_columnsHideable = { false, true, false, true, true }; } Task* TexturePackFolderModel::createUpdateTask() From f1d1c9e22c393eafa961b4a3e4f9eb80034c17fb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jun 2024 11:06:20 +0300 Subject: [PATCH 40/64] forget sort keys Signed-off-by: Trial97 --- launcher/minecraft/mod/TexturePackFolderModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 577b33878..a042c9113 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -47,7 +47,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* { m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified", "Size" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified"), tr("Size") }); - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE, SortType::SIZE }; m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive, QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true, true }; From 5fbbdb9707ba243e9ef96762160041566f879e88 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jun 2024 00:31:31 +0300 Subject: [PATCH 41/64] fix merge issues Signed-off-by: Trial97 --- .../minecraft/mod/TexturePackFolderModel.cpp | 1 - launcher/ui/pages/modplatform/ModPage.cpp | 42 ------------------- .../ui/pages/modplatform/ResourcePage.cpp | 1 - 3 files changed, 44 deletions(-) diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index a042c9113..48e940e9b 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -37,7 +37,6 @@ #include "Application.h" -#include "StringUtils.h" #include "TexturePackFolderModel.h" #include "minecraft/mod/tasks/BasicFolderLoadTask.h" diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 055d5465b..c9817cdf7 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -113,48 +113,6 @@ QMap ModPage::urlHandlers() const /******** Make changes to the UI ********/ -void ModPage::updateVersionList() -{ - m_ui->versionSelectionBox->clear(); - auto packProfile = (dynamic_cast(m_base_instance)).getPackProfile(); - - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - - auto current_pack = getCurrentPack(); - if (!current_pack) - return; - auto installedVersion = m_model->getInstalledPackVersion(current_pack); - auto installedIndex = -1; - for (int i = 0; i < current_pack->versions.size(); i++) { - auto version = current_pack->versions[i]; - bool valid = false; - for (auto& mcVer : m_filter->versions) { - if (validateVersion(version, mcVer.toString(), packProfile->getSupportedModLoaders())) { - valid = true; - break; - } - } - QString flag; - if (installedIndex == -1 && installedVersion.isValid() && installedVersion == version.fileId) { - flag = QString(" [%1]").arg(tr("installed", "Mod version select box")); - installedIndex = i; - } - // Only add the version if it's valid or using the 'Any' filter, but never if the version is opted out - if ((valid || m_filter->versions.empty()) && !optedOut(version)) { - auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : ""; - m_ui->versionSelectionBox->addItem(QString("%1%2%3").arg(version.version, release_type, flag), QVariant(i)); - } - } - if (installedIndex != -1) - m_ui->versionSelectionBox->setCurrentIndex(installedIndex); - if (m_ui->versionSelectionBox->count() == 0) { - m_ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); - m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :(")); - } - - updateSelectionButton(); -} - void ModPage::addResourceToPage(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion& version, const std::shared_ptr base_model) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index b697f35cd..4d01fb1f0 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -449,7 +449,6 @@ void ResourcePage::openUrl(const QUrl& url) void ResourcePage::openProject(QVariant projectID) { m_ui->sortByBox->hide(); - m_ui->searchButton->hide(); m_ui->searchEdit->hide(); m_ui->resourceFilterButton->hide(); m_ui->packView->hide(); From 2108ddcc1d9225c5edbd71a6438a23bfa6a4ab3c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jun 2024 01:16:09 +0300 Subject: [PATCH 42/64] completly remove metadata on refresh Signed-off-by: Trial97 --- launcher/Application.cpp | 7 ------- launcher/net/HttpMetaCache.cpp | 2 ++ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 9519ef553..019327763 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -847,24 +847,17 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) { m_metacache.reset(new HttpMetaCache("metacache")); m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath()); - m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath()); - m_metacache->addBase("versions", QDir("versions").absolutePath()); m_metacache->addBase("libraries", QDir("libraries").absolutePath()); - m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath()); m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath()); - m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath()); m_metacache->addBase("general", QDir("cache").absolutePath()); m_metacache->addBase("ATLauncherPacks", QDir("cache/ATLauncherPacks").absolutePath()); m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath()); - m_metacache->addBase("ModpacksCHPacks", QDir("cache/ModpacksCHPacks").absolutePath()); m_metacache->addBase("TechnicPacks", QDir("cache/TechnicPacks").absolutePath()); m_metacache->addBase("FlamePacks", QDir("cache/FlamePacks").absolutePath()); m_metacache->addBase("FlameMods", QDir("cache/FlameMods").absolutePath()); m_metacache->addBase("ModrinthPacks", QDir("cache/ModrinthPacks").absolutePath()); m_metacache->addBase("ModrinthModpacks", QDir("cache/ModrinthModpacks").absolutePath()); - m_metacache->addBase("root", QDir::currentPath()); m_metacache->addBase("translations", QDir("translations").absolutePath()); - m_metacache->addBase("icons", QDir("cache/icons").absolutePath()); m_metacache->addBase("meta", QDir("meta").absolutePath()); m_metacache->Load(); qDebug() << "<> Cache initialized."; diff --git a/launcher/net/HttpMetaCache.cpp b/launcher/net/HttpMetaCache.cpp index d8b1c7636..4985ad080 100644 --- a/launcher/net/HttpMetaCache.cpp +++ b/launcher/net/HttpMetaCache.cpp @@ -175,6 +175,8 @@ void HttpMetaCache::evictAll() if (!evictEntry(entry)) qCWarning(taskHttpMetaCacheLogC) << "Unexpected missing cache entry" << entry->m_basePath; } + map.entry_list.clear(); + FS::deletePath(map.base_path); } } From 8dde773486884bfcf3c6c6be27e26192fb563be7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 16 Jun 2024 00:21:16 +0000 Subject: [PATCH 43/64] chore(nix): update lockfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:nixos/nixpkgs/d226935fd75012939397c83f6c385e4d6d832288?narHash=sha256-HV97wqUQv9wvptiHCb3Y0/YH0lJ60uZ8FYfEOIzYEqI%3D' (2024-06-07) → 'github:nixos/nixpkgs/3f84a279f1a6290ce154c5531378acc827836fbb?narHash=sha256-u1fA0DYQYdeG%2B5kDm1bOoGcHtX0rtC7qs2YA2N1X%2B%2BI%3D' (2024-06-13) --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 810bedea9..e6b9ced5d 100644 --- a/flake.lock +++ b/flake.lock @@ -75,11 +75,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1717774105, - "narHash": "sha256-HV97wqUQv9wvptiHCb3Y0/YH0lJ60uZ8FYfEOIzYEqI=", + "lastModified": 1718276985, + "narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d226935fd75012939397c83f6c385e4d6d832288", + "rev": "3f84a279f1a6290ce154c5531378acc827836fbb", "type": "github" }, "original": { From a587de8553527b771bec22cb9ef8b8044a6e673b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jun 2024 13:35:23 +0300 Subject: [PATCH 44/64] relax fat FS filename restrictions Signed-off-by: Trial97 --- launcher/FileSystem.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index cafc4f25a..9e399bbfb 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -815,20 +815,11 @@ QString NormalizePath(QString path) } } -QString removeDuplicates(QString a) -{ - auto b = a.split(""); - b.removeDuplicates(); - return b.join(""); -} - -static const QString BAD_WIN_CHARS = "\"?<>:*|\r\n"; - -static const QString BAD_FAT_CHARS = "<>:\"|?*+.,;=[]!"; +static const QString BAD_WIN_CHARS = "<>:\"|?*\r\n"; static const QString BAD_NTFS_CHARS = "<>:\"|?*"; static const QString BAD_HFS_CHARS = ":"; -static const QString BAD_FILENAME_CHARS = removeDuplicates(BAD_WIN_CHARS + BAD_FAT_CHARS + BAD_NTFS_CHARS + BAD_HFS_CHARS) + "\\/"; +static const QString BAD_FILENAME_CHARS = BAD_WIN_CHARS + "\\/"; QString RemoveInvalidFilenameChars(QString string, QChar replaceWith) { @@ -847,9 +838,8 @@ QString RemoveInvalidPathChars(QString path, QChar replaceWith) // the null character is ignored in this check as it was not a problem until now switch (statFS(path).fsType) { - case FilesystemType::FAT: - invalidChars += BAD_FAT_CHARS; - break; + case FilesystemType::FAT: // similar to NTFS + /* fallthrough */ case FilesystemType::NTFS: /* fallthrough */ case FilesystemType::REFS: // similar to NTFS(should be available only on windows) From c9827f8085b4a871e616210501fddf40c4e51b3c Mon Sep 17 00:00:00 2001 From: Cart <81428538+Cartrigger@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:12:07 -0400 Subject: [PATCH 45/64] Spelling mistake in m_column_names and translated it is Miecraft and not Minecraft Signed-off-by: Cart <81428538+Cartrigger@users.noreply.github.com> --- launcher/minecraft/mod/ModFolderModel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index caa225b24..bd68f14ef 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -65,9 +65,9 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) { m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Size", "Side", "Loaders", - "Miecraft Versions", "Release Type" }); + "Minecraft Versions", "Release Type" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"), - tr("Size"), tr("Side"), tr("Loaders"), tr("Miecraft Versions"), tr("Release Type") }); + tr("Size"), tr("Side"), tr("Loaders"), tr("Minecraft Versions"), tr("Release Type") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER, SortType::SIZE, SortType::SIDE, SortType::LOADERS, SortType::MC_VERSIONS, SortType::RELEASE_TYPE }; From 6af52c97c26aba0bd2c2375cb7e40640bd97c238 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:40:40 +0200 Subject: [PATCH 46/64] fix: update datapack and resourcepack versions Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- launcher/minecraft/mod/DataPack.cpp | 4 +++- launcher/minecraft/mod/ResourcePack.cpp | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp index ee4d4f1a6..cd1be439c 100644 --- a/launcher/minecraft/mod/DataPack.cpp +++ b/launcher/minecraft/mod/DataPack.cpp @@ -35,7 +35,9 @@ static const QMap> s_pack_format_versions = { { 8, { Version("1.18"), Version("1.18.1") } }, { 9, { Version("1.18.2"), Version("1.18.2") } }, { 10, { Version("1.19"), Version("1.19.3") } }, { 11, { Version("23w03a"), Version("23w05a") } }, { 12, { Version("1.19.4"), Version("1.19.4") } }, { 13, { Version("23w12a"), Version("23w14a") } }, - { 14, { Version("23w16a"), Version("23w17a") } }, { 15, { Version("1.20"), Version("1.20") } }, + { 14, { Version("23w16a"), Version("23w17a") } }, { 15, { Version("1.20"), Version("1.20.1") } }, + { 18, { Version("1.20.2"), Version("1.20.2") } }, { 26, { Version("1.20.3"), Version("1.20.4") } }, + { 41, { Version("1.20.5"), Version("1.20.6") } }, { 48, { Version("1.21"), Version("1.21") } } }; void DataPack::setPackFormat(int new_format_id) diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 5b26503f5..b8fee8432 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -19,7 +19,16 @@ static const QMap> s_pack_format_versions = { { 7, { Version("1.17"), Version("1.17.1") } }, { 8, { Version("1.18"), Version("1.18.2") } }, { 9, { Version("1.19"), Version("1.19.2") } }, { 11, { Version("22w42a"), Version("22w44a") } }, { 12, { Version("1.19.3"), Version("1.19.3") } }, { 13, { Version("1.19.4"), Version("1.19.4") } }, - { 14, { Version("1.20"), Version("1.20") } } + { 14, { Version("23w14a"), Version("23w16a") } }, { 15, { Version("1.20"), Version("1.20.1") } }, + { 16, { Version("23w31a"), Version("23w31a") } }, { 17, { Version("23w32a"), Version("23w35a") } }, + { 18, { Version("1.20.2"), Version("23w16a") } }, { 19, { Version("23w42a"), Version("23w42a") } }, + { 20, { Version("23w43a"), Version("23w44a") } }, { 21, { Version("23w45a"), Version("23w46a") } }, + { 22, { Version("1.20.3-pre1"), Version("23w51b") } }, { 24, { Version("24w03a"), Version("24w04a") } }, + { 25, { Version("24w05a"), Version("24w05b") } }, { 26, { Version("24w06a"), Version("24w07a") } }, + { 28, { Version("24w09a"), Version("24w10a") } }, { 29, { Version("24w11a"), Version("24w11a") } }, + { 30, { Version("24w12a"), Version("23w12a") } }, { 31, { Version("24w13a"), Version("1.20.5-pre3") } }, + { 32, { Version("1.20.5-pre4"), Version("1.20.6") } }, { 33, { Version("24w18a"), Version("24w20a") } }, + { 34, { Version("24w21a"), Version("1.21") } } }; void ResourcePack::setPackFormat(int new_format_id) From c07e791d7fdc5899b01945df68e4e347256e975f Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:17:48 +0200 Subject: [PATCH 47/64] chore: clang-format ResourcePack.cpp Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- launcher/minecraft/mod/ResourcePack.cpp | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index b8fee8432..420407c7f 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -13,20 +13,20 @@ // Values taken from: // https://minecraft.wiki/w/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta static const QMap> s_pack_format_versions = { - { 1, { Version("1.6.1"), Version("1.8.9") } }, { 2, { Version("1.9"), Version("1.10.2") } }, - { 3, { Version("1.11"), Version("1.12.2") } }, { 4, { Version("1.13"), Version("1.14.4") } }, - { 5, { Version("1.15"), Version("1.16.1") } }, { 6, { Version("1.16.2"), Version("1.16.5") } }, - { 7, { Version("1.17"), Version("1.17.1") } }, { 8, { Version("1.18"), Version("1.18.2") } }, - { 9, { Version("1.19"), Version("1.19.2") } }, { 11, { Version("22w42a"), Version("22w44a") } }, - { 12, { Version("1.19.3"), Version("1.19.3") } }, { 13, { Version("1.19.4"), Version("1.19.4") } }, - { 14, { Version("23w14a"), Version("23w16a") } }, { 15, { Version("1.20"), Version("1.20.1") } }, - { 16, { Version("23w31a"), Version("23w31a") } }, { 17, { Version("23w32a"), Version("23w35a") } }, - { 18, { Version("1.20.2"), Version("23w16a") } }, { 19, { Version("23w42a"), Version("23w42a") } }, - { 20, { Version("23w43a"), Version("23w44a") } }, { 21, { Version("23w45a"), Version("23w46a") } }, + { 1, { Version("1.6.1"), Version("1.8.9") } }, { 2, { Version("1.9"), Version("1.10.2") } }, + { 3, { Version("1.11"), Version("1.12.2") } }, { 4, { Version("1.13"), Version("1.14.4") } }, + { 5, { Version("1.15"), Version("1.16.1") } }, { 6, { Version("1.16.2"), Version("1.16.5") } }, + { 7, { Version("1.17"), Version("1.17.1") } }, { 8, { Version("1.18"), Version("1.18.2") } }, + { 9, { Version("1.19"), Version("1.19.2") } }, { 11, { Version("22w42a"), Version("22w44a") } }, + { 12, { Version("1.19.3"), Version("1.19.3") } }, { 13, { Version("1.19.4"), Version("1.19.4") } }, + { 14, { Version("23w14a"), Version("23w16a") } }, { 15, { Version("1.20"), Version("1.20.1") } }, + { 16, { Version("23w31a"), Version("23w31a") } }, { 17, { Version("23w32a"), Version("23w35a") } }, + { 18, { Version("1.20.2"), Version("23w16a") } }, { 19, { Version("23w42a"), Version("23w42a") } }, + { 20, { Version("23w43a"), Version("23w44a") } }, { 21, { Version("23w45a"), Version("23w46a") } }, { 22, { Version("1.20.3-pre1"), Version("23w51b") } }, { 24, { Version("24w03a"), Version("24w04a") } }, - { 25, { Version("24w05a"), Version("24w05b") } }, { 26, { Version("24w06a"), Version("24w07a") } }, - { 28, { Version("24w09a"), Version("24w10a") } }, { 29, { Version("24w11a"), Version("24w11a") } }, - { 30, { Version("24w12a"), Version("23w12a") } }, { 31, { Version("24w13a"), Version("1.20.5-pre3") } }, + { 25, { Version("24w05a"), Version("24w05b") } }, { 26, { Version("24w06a"), Version("24w07a") } }, + { 28, { Version("24w09a"), Version("24w10a") } }, { 29, { Version("24w11a"), Version("24w11a") } }, + { 30, { Version("24w12a"), Version("23w12a") } }, { 31, { Version("24w13a"), Version("1.20.5-pre3") } }, { 32, { Version("1.20.5-pre4"), Version("1.20.6") } }, { 33, { Version("24w18a"), Version("24w20a") } }, { 34, { Version("24w21a"), Version("1.21") } } }; From 766ddc80e38f52d91d24b09099e7de62251b9a6c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jun 2024 16:51:26 +0300 Subject: [PATCH 48/64] refactored hassing task Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 4 +- launcher/modplatform/EnsureMetadataTask.cpp | 8 +- launcher/modplatform/ModIndex.cpp | 28 +-- launcher/modplatform/ModIndex.h | 12 +- launcher/modplatform/flame/FlameModIndex.cpp | 3 +- .../modplatform/flame/FlamePackExportTask.cpp | 4 +- launcher/modplatform/helpers/HashUtils.cpp | 210 +++++++++--------- launcher/modplatform/helpers/HashUtils.h | 52 ++--- .../modrinth/ModrinthCheckUpdate.cpp | 5 +- .../modrinth/ModrinthPackExportTask.cpp | 13 +- .../modrinth/ModrinthPackIndex.cpp | 3 +- launcher/modplatform/packwiz/Packwiz.cpp | 8 +- launcher/ui/dialogs/BlockedModsDialog.cpp | 2 +- launcher/ui/dialogs/ChooseProviderDialog.cpp | 4 +- launcher/ui/dialogs/ModUpdateDialog.cpp | 4 +- .../ui/dialogs/ResourceDownloadDialog.cpp | 4 +- libraries/murmur2/src/MurmurHash2.cpp | 20 +- libraries/murmur2/src/MurmurHash2.h | 19 +- 18 files changed, 178 insertions(+), 225 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 87ff62917..5442df7fe 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -50,8 +50,6 @@ #include "minecraft/mod/tasks/LocalModParseTask.h" #include "modplatform/ModIndex.h" -static ModPlatform::ProviderCapabilities ProviderCaps; - Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details() { m_enabled = (file.suffix() != "disabled"); @@ -250,7 +248,7 @@ void Mod::finishResolvingWithDetails(ModDetails&& details) auto Mod::provider() const -> std::optional { if (metadata()) - return ProviderCaps.readableName(metadata()->provider); + return ModPlatform::ProviderCapabilities::readableName(metadata()->provider); return {}; } diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index ce53ee62d..43acea1a2 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -15,8 +15,6 @@ #include "modplatform/modrinth/ModrinthAPI.h" #include "modplatform/modrinth/ModrinthPackIndex.h" -static ModPlatform::ProviderCapabilities ProviderCaps; - static ModrinthAPI modrinth_api; static FlameAPI flame_api; @@ -162,10 +160,10 @@ void EnsureMetadataTask::executeTask() }); if (m_mods.size() > 1) - setStatus(tr("Requesting metadata information from %1...").arg(ProviderCaps.readableName(m_provider))); + setStatus(tr("Requesting metadata information from %1...").arg(ModPlatform::ProviderCapabilities::readableName(m_provider))); else if (!m_mods.empty()) setStatus(tr("Requesting metadata information from %1 for '%2'...") - .arg(ProviderCaps.readableName(m_provider), m_mods.begin().value()->name())); + .arg(ModPlatform::ProviderCapabilities::readableName(m_provider), m_mods.begin().value()->name())); m_current_task = version_task; version_task->start(); @@ -215,7 +213,7 @@ void EnsureMetadataTask::emitFail(Mod* m, QString key, RemoveFromList remove) Task::Ptr EnsureMetadataTask::modrinthVersionsTask() { - auto hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first(); + auto hash_type = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first(); auto response = std::make_shared(); auto ver_task = modrinth_api.currentVersions(m_mods.keys(), hash_type, response); diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 20bd3f827..8c85ae122 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -59,7 +59,7 @@ IndexedVersionType::VersionType IndexedVersionType::enumFromString(const QString return s_indexed_version_type_names.value(type, IndexedVersionType::VersionType::Unknown); } -auto ProviderCapabilities::name(ResourceProvider p) -> const char* +const char* ProviderCapabilities::name(ResourceProvider p) { switch (p) { case ResourceProvider::MODRINTH: @@ -69,7 +69,8 @@ auto ProviderCapabilities::name(ResourceProvider p) -> const char* } return {}; } -auto ProviderCapabilities::readableName(ResourceProvider p) -> QString + +QString ProviderCapabilities::readableName(ResourceProvider p) { switch (p) { case ResourceProvider::MODRINTH: @@ -79,7 +80,8 @@ auto ProviderCapabilities::readableName(ResourceProvider p) -> QString } return {}; } -auto ProviderCapabilities::hashType(ResourceProvider p) -> QStringList + +QStringList ProviderCapabilities::hashType(ResourceProvider p) { switch (p) { case ResourceProvider::MODRINTH: @@ -91,26 +93,6 @@ auto ProviderCapabilities::hashType(ResourceProvider p) -> QStringList return {}; } -auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString type) -> QString -{ - QCryptographicHash::Algorithm algo = QCryptographicHash::Sha1; - switch (p) { - case ResourceProvider::MODRINTH: - algo = (type == "sha1") ? QCryptographicHash::Sha1 : QCryptographicHash::Sha512; - break; - case ResourceProvider::FLAME: - algo = (type == "sha1") ? QCryptographicHash::Sha1 : QCryptographicHash::Md5; - break; - } - - QCryptographicHash hash(algo); - if (!hash.addData(device)) - qCritical() << "Failed to read JAR to create hash!"; - - Q_ASSERT(hash.result().length() == hash.hashLength(algo)); - return { hash.result().toHex() }; -} - QString getMetaURL(ResourceProvider provider, QVariant projectID) { return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/projects/" : "https://modrinth.com/mod/") + diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 9b1f8a6f6..91c9898a9 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -40,13 +40,11 @@ enum class ResourceType { MOD, RESOURCE_PACK, SHADER_PACK }; enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN }; -class ProviderCapabilities { - public: - auto name(ResourceProvider) -> const char*; - auto readableName(ResourceProvider) -> QString; - auto hashType(ResourceProvider) -> QStringList; - auto hash(ResourceProvider, QIODevice*, QString type = "") -> QString; -}; +namespace ProviderCapabilities { +const char* name(ResourceProvider); +QString readableName(ResourceProvider); +QStringList hashType(ResourceProvider); +}; // namespace ProviderCapabilities struct ModpackAuthor { QString name; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 335af094d..cde31dded 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -7,7 +7,6 @@ #include "modplatform/flame/FlameAPI.h" static FlameAPI api; -static ModPlatform::ProviderCapabilities ProviderCaps; void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) { @@ -161,7 +160,7 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> auto hash_list = Json::ensureArray(obj, "hashes"); for (auto h : hash_list) { auto hash_entry = Json::ensureObject(h); - auto hash_types = ProviderCaps.hashType(ModPlatform::ResourceProvider::FLAME); + auto hash_types = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::FLAME); auto hash_algo = enumToString(Json::ensureInteger(hash_entry, "algo", 1, "algorithm")); if (hash_types.contains(hash_algo)) { file.hash = Json::requireString(hash_entry, "value"); diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 569181732..11bc3553b 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -116,7 +116,7 @@ void FlamePackExportTask::collectHashes() if (relative.startsWith("resourcepacks/") && (relative.endsWith(".zip") || relative.endsWith(".zip.disabled"))) { // is resourcepack - auto hashTask = Hashing::createFlameHasher(file.absoluteFilePath()); + auto hashTask = Hashing::createHasher(file.absoluteFilePath(), ModPlatform::ResourceProvider::FLAME); connect(hashTask.get(), &Hashing::Hasher::resultsReady, [this, relative, file](QString hash) { if (m_state == Task::State::Running) { pendingHashes.insert(hash, { relative, file.absoluteFilePath(), relative.endsWith(".zip") }); @@ -140,7 +140,7 @@ void FlamePackExportTask::collectHashes() continue; } - auto hashTask = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); + auto hashTask = Hashing::createHasher(mod->fileinfo().absoluteFilePath(), ModPlatform::ResourceProvider::FLAME); connect(hashTask.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { if (m_state == Task::State::Running) { pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled(), true }); diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index 6ff1d1710..b111ab1c1 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -7,18 +7,21 @@ #include "StringUtils.h" #include +#include +#include +#include +#include namespace Hashing { -static ModPlatform::ProviderCapabilities ProviderCaps; - Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provider) { switch (provider) { case ModPlatform::ResourceProvider::MODRINTH: - return createModrinthHasher(file_path); + return makeShared(file_path, + ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first()); case ModPlatform::ResourceProvider::FLAME: - return createFlameHasher(file_path); + return makeShared(file_path, Algorithm::Murmur2); default: qCritical() << "[Hashing]" << "Unrecognized mod platform!"; @@ -26,119 +29,126 @@ Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provid } } -Hasher::Ptr createModrinthHasher(QString file_path) +Hasher::Ptr createHasher(QString file_path, QString type) { - return makeShared(file_path); + return makeShared(file_path, type); } -Hasher::Ptr createFlameHasher(QString file_path) +class QIODeviceReader : public Murmur2::Reader { + public: + QIODeviceReader(QIODevice* device) : m_device(device) {} + virtual ~QIODeviceReader() = default; + virtual int read(char* s, int n) { return m_device->read(s, n); } + virtual bool eof() { return m_device->atEnd(); } + virtual void goToBegining() { m_device->seek(0); } + virtual void close() { m_device->close(); } + + private: + QIODevice* m_device; +}; + +QString algorithmToString(Algorithm type) { - return makeShared(file_path); + switch (type) { + case Algorithm::Md4: + return "md4"; + case Algorithm::Md5: + return "md5"; + case Algorithm::Sha1: + return "sha1"; + case Algorithm::Sha256: + return "sha256"; + case Algorithm::Sha512: + return "sha512"; + case Algorithm::Murmur2: + return "murmur2"; + // case Algorithm::Unknown: + default: + break; + } + return "unknown"; } -Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider) +Algorithm algorithmFromString(QString type) { - return makeShared(file_path, provider); + if (type == "md4") + return Algorithm::Md4; + if (type == "md5") + return Algorithm::Md5; + if (type == "sha1") + return Algorithm::Sha1; + if (type == "sha256") + return Algorithm::Sha256; + if (type == "sha512") + return Algorithm::Sha512; + if (type == "murmur2") + return Algorithm::Murmur2; + return Algorithm::Unknown; } -Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider, QString type) +QString hash(QIODevice* device, Algorithm type) { - auto hasher = makeShared(file_path, provider); - hasher->useHashType(type); - return hasher; -} - -void ModrinthHasher::executeTask() -{ - QFile file(m_path); - - try { - file.open(QFile::ReadOnly); - } catch (FS::FileSystemException& e) { - qCritical() << QString("Failed to open JAR file in %1").arg(m_path); - qCritical() << QString("Reason: ") << e.cause(); - - emitFailed("Failed to open file for hashing."); - return; + if (!device->isOpen() && !device->open(QFile::ReadOnly)) + return ""; + QCryptographicHash::Algorithm alg = QCryptographicHash::Sha1; + switch (type) { + case Algorithm::Md4: + alg = QCryptographicHash::Algorithm::Md4; + break; + case Algorithm::Md5: + alg = QCryptographicHash::Algorithm::Md5; + break; + case Algorithm::Sha1: + alg = QCryptographicHash::Algorithm::Sha1; + break; + case Algorithm::Sha256: + alg = QCryptographicHash::Algorithm::Sha256; + break; + case Algorithm::Sha512: + alg = QCryptographicHash::Algorithm::Sha512; + break; + case Algorithm::Murmur2: { // CF-specific + auto should_filter_out = [](char c) { return (c == 9 || c == 10 || c == 13 || c == 32); }; + auto reader = std::make_unique(device); + auto result = QString::number(Murmur2::hash(reader.get(), 4 * MiB, should_filter_out)); + device->close(); + return result; + } + case Algorithm::Unknown: + device->close(); + return ""; } - auto hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first(); - m_hash = ProviderCaps.hash(ModPlatform::ResourceProvider::MODRINTH, &file, hash_type); + QCryptographicHash hash(alg); + if (!hash.addData(device)) + qCritical() << "Failed to read JAR to create hash!"; - file.close(); + Q_ASSERT(hash.result().length() == hash.hashLength(alg)); + auto result = hash.result().toHex(); + device->close(); + return result; +} - if (m_hash.isEmpty()) { +QString hash(QString fileName, Algorithm type) +{ + QFile file(fileName); + return hash(&file, type); +} + +QString hash(QByteArray data, Algorithm type) +{ + QBuffer buff(&data); + return hash(&buff, type); +} + +void Hasher::executeTask() +{ + m_result = hash(m_path, m_alg); + if (m_result.isEmpty()) { emitFailed("Empty hash!"); } else { emitSucceeded(); - emit resultsReady(m_hash); + emit resultsReady(m_result); } } - -void FlameHasher::executeTask() -{ - // CF-specific - auto should_filter_out = [](char c) { return (c == 9 || c == 10 || c == 13 || c == 32); }; - - std::ifstream file_stream(StringUtils::toStdString(m_path).c_str(), std::ifstream::binary); - // TODO: This is very heavy work, but apparently QtConcurrent can't use move semantics, so we can't boop this to another thread. - // How do we make this non-blocking then? - m_hash = QString::number(MurmurHash2(std::move(file_stream), 4 * MiB, should_filter_out)); - - if (m_hash.isEmpty()) { - emitFailed("Empty hash!"); - } else { - emitSucceeded(); - emit resultsReady(m_hash); - } -} - -BlockedModHasher::BlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider) : Hasher(file_path), provider(provider) -{ - setObjectName(QString("BlockedModHasher: %1").arg(file_path)); - hash_type = ProviderCaps.hashType(provider).first(); -} - -void BlockedModHasher::executeTask() -{ - QFile file(m_path); - - try { - file.open(QFile::ReadOnly); - } catch (FS::FileSystemException& e) { - qCritical() << QString("Failed to open JAR file in %1").arg(m_path); - qCritical() << QString("Reason: ") << e.cause(); - - emitFailed("Failed to open file for hashing."); - return; - } - - m_hash = ProviderCaps.hash(provider, &file, hash_type); - - file.close(); - - if (m_hash.isEmpty()) { - emitFailed("Empty hash!"); - } else { - emitSucceeded(); - emit resultsReady(m_hash); - } -} - -QStringList BlockedModHasher::getHashTypes() -{ - return ProviderCaps.hashType(provider); -} - -bool BlockedModHasher::useHashType(QString type) -{ - auto types = ProviderCaps.hashType(provider); - if (types.contains(type)) { - hash_type = type; - return true; - } - qDebug() << "Bad hash type " << type << " for provider"; - return false; -} - } // namespace Hashing diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index 73a2435a2..2390312d2 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "modplatform/ModIndex.h" @@ -7,61 +8,40 @@ namespace Hashing { +enum class Algorithm { Md4, Md5, Sha1, Sha256, Sha512, Murmur2, Unknown }; + +QString algorithmToString(Algorithm type); +Algorithm algorithmFromString(QString type); +QString hash(QIODevice* device, Algorithm type); +QString hash(QString fileName, Algorithm type); +QString hash(QByteArray data, Algorithm type); + class Hasher : public Task { Q_OBJECT public: using Ptr = shared_qobject_ptr; - Hasher(QString file_path) : m_path(std::move(file_path)) {} + Hasher(QString file_path, Algorithm alg) : m_path(file_path), m_alg(alg) {} + Hasher(QString file_path, QString alg) : Hasher(file_path, algorithmFromString(alg)) {} /* We can't really abort this task, but we can say we aborted and finish our thing quickly :) */ bool abort() override { return true; } - void executeTask() override = 0; + void executeTask() override; - QString getResult() const { return m_hash; }; + QString getResult() const { return m_result; }; QString getPath() const { return m_path; }; signals: void resultsReady(QString hash); protected: - QString m_hash; + QString m_result; QString m_path; -}; - -class FlameHasher : public Hasher { - public: - FlameHasher(QString file_path) : Hasher(file_path) { setObjectName(QString("FlameHasher: %1").arg(file_path)); } - - void executeTask() override; -}; - -class ModrinthHasher : public Hasher { - public: - ModrinthHasher(QString file_path) : Hasher(file_path) { setObjectName(QString("ModrinthHasher: %1").arg(file_path)); } - - void executeTask() override; -}; - -class BlockedModHasher : public Hasher { - public: - BlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider); - - void executeTask() override; - - QStringList getHashTypes(); - bool useHashType(QString type); - - private: - ModPlatform::ResourceProvider provider; - QString hash_type; + Algorithm m_alg; }; Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provider); -Hasher::Ptr createFlameHasher(QString file_path); -Hasher::Ptr createModrinthHasher(QString file_path); -Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider); -Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider, QString type); +Hasher::Ptr createHasher(QString file_path, QString type); } // namespace Hashing diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 335b81b89..700bcd2e6 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -13,7 +13,6 @@ #include "minecraft/mod/ModFolderModel.h" static ModrinthAPI api; -static ModPlatform::ProviderCapabilities ProviderCaps; bool ModrinthCheckUpdate::abort() { @@ -36,7 +35,7 @@ void ModrinthCheckUpdate::executeTask() // Create all hashes QStringList hashes; - auto best_hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first(); + auto best_hash_type = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first(); ConcurrentTask hashing_task(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); for (auto* mod : m_mods) { @@ -51,7 +50,7 @@ void ModrinthCheckUpdate::executeTask() // need to generate a new hash if the current one is innadequate // (though it will rarely happen, if at all) if (mod->metadata()->hash_format != best_hash_type) { - auto hash_task = Hashing::createModrinthHasher(mod->fileinfo().absoluteFilePath()); + auto hash_task = Hashing::createHasher(mod->fileinfo().absoluteFilePath(), ModPlatform::ResourceProvider::MODRINTH); connect(hash_task.get(), &Hashing::Hasher::resultsReady, [&hashes, &mappings, mod](QString hash) { hashes.append(hash); mappings.insert(hash, mod); diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 7e52153b9..ef0a3df16 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -27,6 +27,7 @@ #include "minecraft/PackProfile.h" #include "minecraft/mod/MetadataHandler.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/HashUtils.h" const QStringList ModrinthPackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); const QStringList ModrinthPackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "zip" }); @@ -102,8 +103,6 @@ void ModrinthPackExportTask::collectHashes() })) continue; - QCryptographicHash sha512(QCryptographicHash::Algorithm::Sha512); - QFile openFile(file.absoluteFilePath()); if (!openFile.open(QFile::ReadOnly)) { qWarning() << "Could not open" << file << "for hashing"; @@ -115,7 +114,7 @@ void ModrinthPackExportTask::collectHashes() qWarning() << "Could not read" << file; continue; } - sha512.addData(data); + auto sha512 = Hashing::hash(data, Hashing::Algorithm::Sha512); auto allMods = mcInstance->loaderModList()->allMods(); if (auto modIter = std::find_if(allMods.begin(), allMods.end(), [&file](Mod* mod) { return mod->fileinfo() == file; }); @@ -127,11 +126,9 @@ void ModrinthPackExportTask::collectHashes() if (!url.isEmpty() && BuildConfig.MODRINTH_MRPACK_HOSTS.contains(url.host())) { qDebug() << "Resolving" << relative << "from index"; - QCryptographicHash sha1(QCryptographicHash::Algorithm::Sha1); - sha1.addData(data); + auto sha1 = Hashing::hash(data, Hashing::Algorithm::Sha1); - ResolvedFile resolvedFile{ sha1.result().toHex(), sha512.result().toHex(), url.toEncoded(), openFile.size(), - mod->metadata()->side }; + ResolvedFile resolvedFile{ sha1, sha512, url.toEncoded(), openFile.size(), mod->metadata()->side }; resolvedFiles[relative] = resolvedFile; // nice! we've managed to resolve based on local metadata! @@ -142,7 +139,7 @@ void ModrinthPackExportTask::collectHashes() } qDebug() << "Enqueueing" << relative << "for Modrinth query"; - pendingHashes[relative] = sha512.result().toHex(); + pendingHashes[relative] = sha512; } setAbortable(true); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index f3d4fd187..7925a33b4 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -27,7 +27,6 @@ #include "modplatform/ModIndex.h" static ModrinthAPI api; -static ModPlatform::ProviderCapabilities ProviderCaps; bool shouldDownloadOnSide(QString side) { @@ -231,7 +230,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t file.hash = Json::requireString(hash_list, preferred_hash_type); file.hash_type = preferred_hash_type; } else { - auto hash_types = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH); + auto hash_types = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH); for (auto& hash_type : hash_types) { if (hash_list.contains(hash_type)) { file.hash = Json::requireString(hash_list, hash_type); diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index c8899345e..626f1c9df 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -67,8 +67,6 @@ static inline auto indexFileName(QString const& mod_slug) -> QString return QString("%1.pw.toml").arg(mod_slug); } -static ModPlatform::ProviderCapabilities ProviderCaps; - // Helper functions for extracting data from the TOML file auto stringEntry(toml::table table, QString entry_name) -> QString { @@ -219,7 +217,7 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) { "hash-format", mod.hash_format.toStdString() }, { "hash", mod.hash.toStdString() }, } }, - { "update", toml::table{ { ProviderCaps.name(mod.provider), update } } } }; + { "update", toml::table{ { ModPlatform::ProviderCapabilities::name(mod.provider), update } } } }; std::stringstream ss; ss << tbl; in_stream << QString::fromStdString(ss.str()); @@ -340,11 +338,11 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod } toml::table* mod_provider_table = nullptr; - if ((mod_provider_table = update_table[ProviderCaps.name(Provider::FLAME)].as_table())) { + if ((mod_provider_table = update_table[ModPlatform::ProviderCapabilities::name(Provider::FLAME)].as_table())) { mod.provider = Provider::FLAME; mod.file_id = intEntry(*mod_provider_table, "file-id"); mod.project_id = intEntry(*mod_provider_table, "project-id"); - } else if ((mod_provider_table = update_table[ProviderCaps.name(Provider::MODRINTH)].as_table())) { + } else if ((mod_provider_table = update_table[ModPlatform::ProviderCapabilities::name(Provider::MODRINTH)].as_table())) { mod.provider = Provider::MODRINTH; mod.mod_id() = stringEntry(*mod_provider_table, "mod-id"); mod.version() = stringEntry(*mod_provider_table, "version"); diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index 2b415c2d9..5c93053d1 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -266,7 +266,7 @@ void BlockedModsDialog::addHashTask(QString path) /// @param path the path to the local file being hashed void BlockedModsDialog::buildHashTask(QString path) { - auto hash_task = Hashing::createBlockedModHasher(path, ModPlatform::ResourceProvider::FLAME, m_hash_type); + auto hash_task = Hashing::createHasher(path, m_hash_type); qDebug() << "[Blocked Mods Dialog] Creating Hash task for path: " << path; diff --git a/launcher/ui/dialogs/ChooseProviderDialog.cpp b/launcher/ui/dialogs/ChooseProviderDialog.cpp index 83748e1e2..68457802d 100644 --- a/launcher/ui/dialogs/ChooseProviderDialog.cpp +++ b/launcher/ui/dialogs/ChooseProviderDialog.cpp @@ -6,8 +6,6 @@ #include "modplatform/ModIndex.h" -static ModPlatform::ProviderCapabilities ProviderCaps; - ChooseProviderDialog::ChooseProviderDialog(QWidget* parent, bool single_choice, bool allow_skipping) : QDialog(parent), ui(new Ui::ChooseProviderDialog) { @@ -78,7 +76,7 @@ void ChooseProviderDialog::addProviders() QRadioButton* btn; for (auto& provider : { ModPlatform::ResourceProvider::MODRINTH, ModPlatform::ResourceProvider::FLAME }) { - btn = new QRadioButton(ProviderCaps.readableName(provider), this); + btn = new QRadioButton(ModPlatform::ProviderCapabilities::readableName(provider), this); m_providers.addButton(btn, btn_index++); ui->providersLayout->addWidget(btn); } diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 6649bee4e..1583b4f46 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -25,8 +25,6 @@ #include -static ModPlatform::ProviderCapabilities ProviderCaps; - static std::list mcVersions(BaseInstance* inst) { return { static_cast(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion() }; @@ -427,7 +425,7 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info, QStri item_top->setExpanded(true); auto provider_item = new QTreeWidgetItem(item_top); - provider_item->setText(0, tr("Provider: %1").arg(ProviderCaps.readableName(info.provider))); + provider_item->setText(0, tr("Provider: %1").arg(ModPlatform::ProviderCapabilities::readableName(info.provider))); auto old_version_item = new QTreeWidgetItem(item_top); old_version_item->setText(0, tr("Old version: %1").arg(info.old_version.isEmpty() ? tr("Not installed") : info.old_version)); diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index c5dfe4915..ef36edb32 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -126,8 +126,6 @@ void ResourceDownloadDialog::connectButtons() connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help); } -static ModPlatform::ProviderCapabilities ProviderCaps; - void ResourceDownloadDialog::confirm() { auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString())); @@ -169,7 +167,7 @@ void ResourceDownloadDialog::confirm() for (auto& task : selected) { auto extraInfo = dependencyExtraInfo.value(task->getPack()->addonId.toString()); confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(), - ProviderCaps.name(task->getProvider()), extraInfo.required_by, + ModPlatform::ProviderCapabilities::name(task->getProvider()), extraInfo.required_by, task->getVersion().version_type.toString(), !extraInfo.maybe_installed }); } diff --git a/libraries/murmur2/src/MurmurHash2.cpp b/libraries/murmur2/src/MurmurHash2.cpp index e73127953..680a211ba 100644 --- a/libraries/murmur2/src/MurmurHash2.cpp +++ b/libraries/murmur2/src/MurmurHash2.cpp @@ -8,14 +8,14 @@ #include "MurmurHash2.h" -//----------------------------------------------------------------------------- +namespace Murmur2 { // 'm' and 'r' are mixing constants generated offline. // They're not really 'magic', they just happen to work well. const uint32_t m = 0x5bd1e995; const int r = 24; -uint32_t MurmurHash2(std::ifstream&& file_stream, std::size_t buffer_size, std::function filter_out) +uint32_t hash(Reader* file_stream, std::size_t buffer_size, std::function filter_out) { auto* buffer = new char[buffer_size]; char data[4]; @@ -26,24 +26,21 @@ uint32_t MurmurHash2(std::ifstream&& file_stream, std::size_t buffer_size, std:: // We need the size without the filtered out characters before actually calculating the hash, // to setup the initial value for the hash. do { - file_stream.read(buffer, buffer_size); - read = file_stream.gcount(); + read = file_stream->read(buffer, buffer_size); for (int i = 0; i < read; i++) { if (!filter_out(buffer[i])) size += 1; } - } while (!file_stream.eof()); + } while (!file_stream->eof()); - file_stream.clear(); - file_stream.seekg(0, file_stream.beg); + file_stream->goToBegining(); int index = 0; // This forces a seed of 1. IncrementalHashInfo info{ (uint32_t)1 ^ size, (uint32_t)size }; do { - file_stream.read(buffer, buffer_size); - read = file_stream.gcount(); + read = file_stream->read(buffer, buffer_size); for (int i = 0; i < read; i++) { char c = buffer[i]; @@ -57,14 +54,13 @@ uint32_t MurmurHash2(std::ifstream&& file_stream, std::size_t buffer_size, std:: if (index == 0) FourBytes_MurmurHash2(reinterpret_cast(&data), info); } - } while (!file_stream.eof()); + } while (!file_stream->eof()); // Do one last bit shuffle in the hash FourBytes_MurmurHash2(reinterpret_cast(&data), info); delete[] buffer; - file_stream.close(); return info.h; } @@ -109,4 +105,4 @@ void FourBytes_MurmurHash2(const unsigned char* data, IncrementalHashInfo& prev) } } -//----------------------------------------------------------------------------- +} // namespace Murmur2 \ No newline at end of file diff --git a/libraries/murmur2/src/MurmurHash2.h b/libraries/murmur2/src/MurmurHash2.h index 5d4f48713..e1b949b45 100644 --- a/libraries/murmur2/src/MurmurHash2.h +++ b/libraries/murmur2/src/MurmurHash2.h @@ -9,17 +9,23 @@ #pragma once #include -#include - #include -//----------------------------------------------------------------------------- +namespace Murmur2 { #define KiB 1024 #define MiB 1024 * KiB -uint32_t MurmurHash2( - std::ifstream&& file_stream, +class Reader { + public: + virtual ~Reader() = default; + virtual int read(char* s, int n) = 0; + virtual bool eof() = 0; + virtual void goToBegining() = 0; +}; + +uint32_t hash( + Reader* file_stream, std::size_t buffer_size = 4 * MiB, std::function filter_out = [](char) { return false; }); @@ -29,5 +35,4 @@ struct IncrementalHashInfo { }; void FourBytes_MurmurHash2(const unsigned char* data, IncrementalHashInfo& prev); - -//----------------------------------------------------------------------------- +} // namespace Murmur2 From 9cbdbddb08da2b5c78e068f543f1bf417860107b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jun 2024 17:27:17 +0300 Subject: [PATCH 49/64] made hasing task async Signed-off-by: Trial97 --- launcher/MMCZip.h | 2 +- launcher/modplatform/helpers/HashUtils.cpp | 37 ++++++++++++++-------- launcher/modplatform/helpers/HashUtils.h | 10 ++++-- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index a872411fa..eb0ea8f6a 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -213,7 +213,7 @@ class ExtractZipTask : public Task { {} virtual ~ExtractZipTask() = default; - typedef std::optional ZipResult; + using ZipResult = std::optional; protected: virtual void executeTask() override; diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index b111ab1c1..13bac582e 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -1,16 +1,11 @@ #include "HashUtils.h" +#include #include #include - -#include "FileSystem.h" -#include "StringUtils.h" +#include #include -#include -#include -#include -#include namespace Hashing { @@ -143,12 +138,28 @@ QString hash(QByteArray data, Algorithm type) void Hasher::executeTask() { - m_result = hash(m_path, m_alg); - if (m_result.isEmpty()) { - emitFailed("Empty hash!"); - } else { - emitSucceeded(); - emit resultsReady(m_result); + m_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return hash(m_path, m_alg); }); + connect(&m_zip_watcher, &QFutureWatcher::finished, this, [this] { + if (m_zip_future.isCanceled()) { + emitAborted(); + } else if (m_result = m_zip_future.result(); m_result.isEmpty()) { + emitFailed("Empty hash!"); + } else { + emitSucceeded(); + emit resultsReady(m_result); + } + }); + m_zip_watcher.setFuture(m_zip_future); +} + +bool Hasher::abort() +{ + if (m_zip_future.isRunning()) { + m_zip_future.cancel(); + // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not + // occur immediately. + return true; } + return false; } } // namespace Hashing diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index 2390312d2..3402c5c1f 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include #include "modplatform/ModIndex.h" @@ -24,8 +26,7 @@ class Hasher : public Task { Hasher(QString file_path, Algorithm alg) : m_path(file_path), m_alg(alg) {} Hasher(QString file_path, QString alg) : Hasher(file_path, algorithmFromString(alg)) {} - /* We can't really abort this task, but we can say we aborted and finish our thing quickly :) */ - bool abort() override { return true; } + bool abort() override; void executeTask() override; @@ -35,10 +36,13 @@ class Hasher : public Task { signals: void resultsReady(QString hash); - protected: + private: QString m_result; QString m_path; Algorithm m_alg; + + QFuture m_zip_future; + QFutureWatcher m_zip_watcher; }; Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provider); From ac8c7baff211ff6622430578af0fc90edd8c1fcc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jun 2024 17:49:07 +0300 Subject: [PATCH 50/64] fix tipo Signed-off-by: Trial97 --- launcher/modplatform/helpers/HashUtils.cpp | 2 +- libraries/murmur2/src/MurmurHash2.cpp | 2 +- libraries/murmur2/src/MurmurHash2.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index 13bac582e..b40361bcc 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -35,7 +35,7 @@ class QIODeviceReader : public Murmur2::Reader { virtual ~QIODeviceReader() = default; virtual int read(char* s, int n) { return m_device->read(s, n); } virtual bool eof() { return m_device->atEnd(); } - virtual void goToBegining() { m_device->seek(0); } + virtual void goToBeginning() { m_device->seek(0); } virtual void close() { m_device->close(); } private: diff --git a/libraries/murmur2/src/MurmurHash2.cpp b/libraries/murmur2/src/MurmurHash2.cpp index 680a211ba..99befd107 100644 --- a/libraries/murmur2/src/MurmurHash2.cpp +++ b/libraries/murmur2/src/MurmurHash2.cpp @@ -33,7 +33,7 @@ uint32_t hash(Reader* file_stream, std::size_t buffer_size, std::functioneof()); - file_stream->goToBegining(); + file_stream->goToBeginning(); int index = 0; diff --git a/libraries/murmur2/src/MurmurHash2.h b/libraries/murmur2/src/MurmurHash2.h index e1b949b45..233538556 100644 --- a/libraries/murmur2/src/MurmurHash2.h +++ b/libraries/murmur2/src/MurmurHash2.h @@ -21,7 +21,7 @@ class Reader { virtual ~Reader() = default; virtual int read(char* s, int n) = 0; virtual bool eof() = 0; - virtual void goToBegining() = 0; + virtual void goToBeginning() = 0; }; uint32_t hash( From a63842c727eb3f4c2b02b6392f5f66cfa6832206 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:58:39 +0200 Subject: [PATCH 51/64] fix: add more datapack formats and clang-format it Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- launcher/minecraft/mod/DataPack.cpp | 57 ++++++++++++++++++++----- launcher/minecraft/mod/ResourcePack.cpp | 2 +- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp index cd1be439c..4a9e77a70 100644 --- a/launcher/minecraft/mod/DataPack.cpp +++ b/launcher/minecraft/mod/DataPack.cpp @@ -28,17 +28,52 @@ #include "Version.h" // Values taken from: -// https://minecraft.wiki/w/Tutorials/Creating_a_data_pack#%22pack_format%22 -static const QMap> s_pack_format_versions = { - { 4, { Version("1.13"), Version("1.14.4") } }, { 5, { Version("1.15"), Version("1.16.1") } }, - { 6, { Version("1.16.2"), Version("1.16.5") } }, { 7, { Version("1.17"), Version("1.17.1") } }, - { 8, { Version("1.18"), Version("1.18.1") } }, { 9, { Version("1.18.2"), Version("1.18.2") } }, - { 10, { Version("1.19"), Version("1.19.3") } }, { 11, { Version("23w03a"), Version("23w05a") } }, - { 12, { Version("1.19.4"), Version("1.19.4") } }, { 13, { Version("23w12a"), Version("23w14a") } }, - { 14, { Version("23w16a"), Version("23w17a") } }, { 15, { Version("1.20"), Version("1.20.1") } }, - { 18, { Version("1.20.2"), Version("1.20.2") } }, { 26, { Version("1.20.3"), Version("1.20.4") } }, - { 41, { Version("1.20.5"), Version("1.20.6") } }, { 48, { Version("1.21"), Version("1.21") } } -}; +// https://minecraft.wiki/w/Pack_format#List_of_data_pack_formats +static const QMap> s_pack_format_versions = { { 4, { Version("1.13"), Version("1.14.4") } }, + { 5, { Version("1.15"), Version("1.16.1") } }, + { 6, { Version("1.16.2"), Version("1.16.5") } }, + { 7, { Version("1.17"), Version("1.17.1") } }, + { 8, { Version("1.18"), Version("1.18.1") } }, + { 9, { Version("1.18.2"), Version("1.18.2") } }, + { 10, { Version("1.19"), Version("1.19.3") } }, + { 11, { Version("23w03a"), Version("23w05a") } }, + { 12, { Version("1.19.4"), Version("1.19.4") } }, + { 13, { Version("23w12a"), Version("23w14a") } }, + { 14, { Version("23w16a"), Version("23w17a") } }, + { 15, { Version("1.20"), Version("1.20.1") } }, + { 16, { Version("23w31a"), Version("23w31a") } }, + { 17, { Version("23w32a"), Version("23w35a") } }, + { 18, { Version("1.20.2"), Version("1.20.2") } }, + { 19, { Version("23w40a"), Version("23w40a") } }, + { 20, { Version("23w41a"), Version("23w41a") } }, + { 21, { Version("23w42a"), Version("23w42a") } }, + { 22, { Version("23w43a"), Version("23w43b") } }, + { 23, { Version("23w44a"), Version("23w44a") } }, + { 24, { Version("23w45a"), Version("23w45a") } }, + { 25, { Version("23w46a"), Version("23w46a") } }, + { 26, { Version("1.20.3"), Version("1.20.4") } }, + { 27, { Version("23w51a"), Version("23w51b") } }, + { 28, { Version("24w05a"), Version("24w05b") } }, + { 29, { Version("24w04a"), Version("24w04a") } }, + { 30, { Version("24w05a"), Version("24w05b") } }, + { 31, { Version("24w06a"), Version("24w06a") } }, + { 32, { Version("24w07a"), Version("24w07a") } }, + { 33, { Version("24w09a"), Version("24w09a") } }, + { 34, { Version("24w10a"), Version("24w10a") } }, + { 35, { Version("24w11a"), Version("24w11a") } }, + { 36, { Version("24w12a"), Version("24w12a") } }, + { 37, { Version("24w13a"), Version("24w13a") } }, + { 38, { Version("24w14a"), Version("24w14a") } }, + { 39, { Version("1.20.5-pre1"), Version("1.20.5-pre1") } }, + { 40, { Version("1.20.5-pre2"), Version("1.20.5-pre2") } }, + { 41, { Version("1.20.5"), Version("1.20.6") } }, + { 42, { Version("24w18a"), Version("24w18a") } }, + { 43, { Version("24w19a"), Version("24w19b") } }, + { 44, { Version("24w20a"), Version("24w20a") } }, + { 45, { Version("21w21a"), Version("21w21b") } }, + { 46, { Version("1.21-pre1"), Version("1.21-pre1") } }, + { 47, { Version("1.21-pre2"), Version("1.21-pre2") } }, + { 48, { Version("1.21"), Version("1.21") } } }; void DataPack::setPackFormat(int new_format_id) { diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 420407c7f..81fb91485 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -11,7 +11,7 @@ #include "minecraft/mod/tasks/LocalResourcePackParseTask.h" // Values taken from: -// https://minecraft.wiki/w/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta +// https://minecraft.wiki/w/Pack_format#List_of_resource_pack_formats static const QMap> s_pack_format_versions = { { 1, { Version("1.6.1"), Version("1.8.9") } }, { 2, { Version("1.9"), Version("1.10.2") } }, { 3, { Version("1.11"), Version("1.12.2") } }, { 4, { Version("1.13"), Version("1.14.4") } }, From 97147f2d24cc4316d581a2b4bab334d8ad2161f3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jun 2024 22:31:41 +0300 Subject: [PATCH 52/64] fix(nix): drop unsupported Qt 5 package Signed-off-by: Sefa Eyeoglu Signed-off-by: Trial97 --- flake.lock | 6 +++--- flake.nix | 2 +- nix/distribution.nix | 15 ++------------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/flake.lock b/flake.lock index e6b9ced5d..caed1a708 100644 --- a/flake.lock +++ b/flake.lock @@ -77,14 +77,14 @@ "locked": { "lastModified": 1718276985, "narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=", - "owner": "nixos", + "owner": "NixOS", "repo": "nixpkgs", "rev": "3f84a279f1a6290ce154c5531378acc827836fbb", "type": "github" }, "original": { - "owner": "nixos", - "ref": "nixpkgs-unstable", + "owner": "NixOS", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } diff --git a/flake.nix b/flake.nix index e16c76699..7cef5217a 100644 --- a/flake.nix +++ b/flake.nix @@ -7,7 +7,7 @@ }; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-parts = { url = "github:hercules-ci/flake-parts"; inputs.nixpkgs-lib.follows = "nixpkgs"; diff --git a/nix/distribution.nix b/nix/distribution.nix index 01c90f783..d9c6784a1 100644 --- a/nix/distribution.nix +++ b/nix/distribution.nix @@ -13,8 +13,6 @@ in { inherit (ourPackages) - prismlauncher-qt5-unwrapped - prismlauncher-qt5 prismlauncher-unwrapped prismlauncher ; @@ -25,21 +23,12 @@ flake = { overlays.default = final: prev: let version = builtins.substring 0 8 self.lastModifiedDate or "dirty"; - - # common args for prismlauncher evaluations - unwrappedArgs = { + in { + prismlauncher-unwrapped = prev.qt6Packages.callPackage ./pkg { inherit (inputs) libnbtplusplus; inherit ((final.darwin or prev.darwin).apple_sdk.frameworks) Cocoa; inherit version; }; - in { - prismlauncher-qt5-unwrapped = prev.libsForQt5.callPackage ./pkg unwrappedArgs; - - prismlauncher-qt5 = prev.libsForQt5.callPackage ./pkg/wrapper.nix { - prismlauncher-unwrapped = final.prismlauncher-qt5-unwrapped; - }; - - prismlauncher-unwrapped = prev.qt6Packages.callPackage ./pkg unwrappedArgs; prismlauncher = prev.qt6Packages.callPackage ./pkg/wrapper.nix { inherit (final) prismlauncher-unwrapped; From 888b22b4c7ec9febdcf1a3963cc975abf0bc8270 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jun 2024 22:36:39 +0300 Subject: [PATCH 53/64] rename variable Signed-off-by: Trial97 --- launcher/modplatform/helpers/HashUtils.cpp | 14 +++++++------- launcher/modplatform/helpers/HashUtils.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index b40361bcc..f20af1f09 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -138,24 +138,24 @@ QString hash(QByteArray data, Algorithm type) void Hasher::executeTask() { - m_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return hash(m_path, m_alg); }); - connect(&m_zip_watcher, &QFutureWatcher::finished, this, [this] { - if (m_zip_future.isCanceled()) { + m_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return hash(m_path, m_alg); }); + connect(&m_watcher, &QFutureWatcher::finished, this, [this] { + if (m_future.isCanceled()) { emitAborted(); - } else if (m_result = m_zip_future.result(); m_result.isEmpty()) { + } else if (m_result = m_future.result(); m_result.isEmpty()) { emitFailed("Empty hash!"); } else { emitSucceeded(); emit resultsReady(m_result); } }); - m_zip_watcher.setFuture(m_zip_future); + m_watcher.setFuture(m_future); } bool Hasher::abort() { - if (m_zip_future.isRunning()) { - m_zip_future.cancel(); + if (m_future.isRunning()) { + m_future.cancel(); // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not // occur immediately. return true; diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index 3402c5c1f..5d8b7d132 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -41,8 +41,8 @@ class Hasher : public Task { QString m_path; Algorithm m_alg; - QFuture m_zip_future; - QFutureWatcher m_zip_watcher; + QFuture m_future; + QFutureWatcher m_watcher; }; Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provider); From c1d05605243f3c60bb0c013b3eb9040e962fca18 Mon Sep 17 00:00:00 2001 From: leia uwu Date: Thu, 20 Jun 2024 13:20:21 -0300 Subject: [PATCH 54/64] perf: print api servers asynchronously on instance launch Doing this on the main thread can cause the launcher to freeze for up to 5 seconds when launching an instance on my system so i moved it to a launch step where it gets all the servers info asynchronously to print Signed-off-by: leia uwu --- launcher/CMakeLists.txt | 2 + launcher/LaunchController.cpp | 20 +------- launcher/launch/steps/PrintServers.cpp | 65 ++++++++++++++++++++++++++ launcher/launch/steps/PrintServers.h | 37 +++++++++++++++ 4 files changed, 106 insertions(+), 18 deletions(-) create mode 100644 launcher/launch/steps/PrintServers.cpp create mode 100644 launcher/launch/steps/PrintServers.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index dc0965f66..366719dec 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -163,6 +163,8 @@ set(LAUNCH_SOURCES launch/steps/Update.h launch/steps/QuitAfterGameStop.cpp launch/steps/QuitAfterGameStop.h + launch/steps/PrintServers.cpp + launch/steps/PrintServers.h launch/LaunchStep.cpp launch/LaunchStep.h launch/LaunchTask.cpp diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index cb37e4594..bccc426a9 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -36,6 +36,7 @@ #include "LaunchController.h" #include "Application.h" +#include "launch/steps/PrintServers.h" #include "minecraft/auth/AccountData.h" #include "minecraft/auth/AccountList.h" @@ -345,25 +346,8 @@ void LaunchController::launchInstance() // Prepend Server Status QStringList servers = { "login.microsoftonline.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" }; - QString resolved_servers = ""; - QHostInfo host_info; - for (QString server : servers) { - host_info = QHostInfo::fromName(server); - resolved_servers = resolved_servers + server + " resolves to:\n ["; - if (!host_info.addresses().isEmpty()) { - for (QHostAddress address : host_info.addresses()) { - resolved_servers = resolved_servers + address.toString(); - if (!host_info.addresses().endsWith(address)) { - resolved_servers = resolved_servers + ", "; - } - } - } else { - resolved_servers = resolved_servers + "N/A"; - } - resolved_servers = resolved_servers + "]\n\n"; - } - m_launcher->prependStep(makeShared(m_launcher.get(), resolved_servers, MessageLevel::Launcher)); + m_launcher->prependStep(makeShared(m_launcher.get(), servers)); } else { online_mode = m_demo ? "demo" : "offline"; } diff --git a/launcher/launch/steps/PrintServers.cpp b/launcher/launch/steps/PrintServers.cpp new file mode 100644 index 000000000..ba96d37b9 --- /dev/null +++ b/launcher/launch/steps/PrintServers.cpp @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Leia uwu + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "PrintServers.h" +#include "QHostInfo" + +PrintServers::PrintServers(LaunchTask* parent, const QStringList& servers) : LaunchStep(parent) +{ + m_servers = servers; +} + +void PrintServers::executeTask() +{ + for (QString server : m_servers) { + QHostInfo::lookupHost(server, this, &PrintServers::resolveServer); + } +} + +void PrintServers::resolveServer(const QHostInfo& host_info) +{ + QString server = host_info.hostName(); + QString addresses = server + " resolves to:\n ["; + + if (!host_info.addresses().isEmpty()) { + for (QHostAddress address : host_info.addresses()) { + addresses += address.toString(); + if (!host_info.addresses().endsWith(address)) { + addresses += ", "; + } + } + } else { + addresses += "N/A"; + } + addresses += "]\n\n"; + + m_server_to_address.insert(server, addresses); + + // print server info in order once all servers are resolved + if (m_server_to_address.size() >= m_servers.size()) { + for (QString serv : m_servers) { + emit logLine(m_server_to_address.value(serv), MessageLevel::Launcher); + } + emitSucceeded(); + } +} + +bool PrintServers::canAbort() const +{ + return true; +} diff --git a/launcher/launch/steps/PrintServers.h b/launcher/launch/steps/PrintServers.h new file mode 100644 index 000000000..7d2f1b194 --- /dev/null +++ b/launcher/launch/steps/PrintServers.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2024 Leia uwu + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include +#include +#include +#include + +class PrintServers : public LaunchStep { + Q_OBJECT + public: + PrintServers(LaunchTask* parent, const QStringList& servers); + + virtual void executeTask(); + virtual bool canAbort() const; + + private: + void resolveServer(const QHostInfo& host_info); + QMap m_server_to_address; + QStringList m_servers; +}; From 178bd4a9c336fadd18bbfc2b8f4f38ac50e26350 Mon Sep 17 00:00:00 2001 From: Tayou Date: Sat, 22 Jun 2024 17:28:59 +0200 Subject: [PATCH 55/64] don't tr() file types on file save/open, etc. dialogs Signed-off-by: Tayou --- launcher/ui/MainWindow.cpp | 2 +- launcher/ui/dialogs/ExportPackDialog.cpp | 4 ++-- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- launcher/ui/pages/instance/ManagedPackPage.cpp | 4 ++-- launcher/ui/pages/instance/VersionPage.cpp | 8 ++++---- launcher/ui/pages/instance/WorldListPage.cpp | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 13b6240fe..83a352410 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1560,7 +1560,7 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() QFileDialog fileDialog; // workaround to make sure the portal file dialog opens in the desktop directory fileDialog.setDirectoryUrl(desktopPath); - desktopFilePath = fileDialog.getSaveFileName(this, tr("Create Shortcut"), desktopFilePath, tr("Desktop Entries (*.desktop)")); + desktopFilePath = fileDialog.getSaveFileName(this, tr("Create Shortcut"), desktopFilePath, tr("Desktop Entries") + " (*.desktop)"); if (desktopFilePath.isEmpty()) return; // file dialog canceled by user appPath = "flatpak"; diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index 73e44efb1..0278c6cb0 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -129,14 +129,14 @@ void ExportPackDialog::done(int result) QString output; if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + ".mrpack"), - "Modrinth pack (*.mrpack *.zip)", nullptr); + tr("Modrinth pack") + " (*.mrpack *.zip)", nullptr); if (output.isEmpty()) return; if (!(output.endsWith(".zip") || output.endsWith(".mrpack"))) output.append(".mrpack"); } else { output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + ".zip"), - "CurseForge pack (*.zip)", nullptr); + tr("CurseForge pack") + " (*.zip)", nullptr); if (output.isEmpty()) return; if (!output.endsWith(".zip")) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 4202dbe30..1e0ae87a3 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -160,7 +160,7 @@ void ExportToModListDialog::done(int result) const QString filename = FS::RemoveInvalidFilenameChars(m_name); const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(m_name), FS::PathCombine(QDir::homePath(), filename + extension()), - "File (*.txt *.html *.md *.json *.csv)", nullptr); + tr("File") + " (*.txt *.html *.md *.json *.csv)", nullptr); if (output.isEmpty()) return; diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index a47403926..a909d10d1 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -371,7 +371,7 @@ void ModrinthManagedPackPage::update() void ModrinthManagedPackPage::updateFromFile() { - auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), "Modrinth pack (*.mrpack *.zip)"); + auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), tr("Modrinth pack") + " (*.mrpack *.zip)"); if (output.isEmpty()) return; QMap extra_info; @@ -538,7 +538,7 @@ void FlameManagedPackPage::update() void FlameManagedPackPage::updateFromFile() { - auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), "CurseForge pack (*.zip)"); + auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), tr("CurseForge pack") + " (*.zip)"); if (output.isEmpty()) return; diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 487433230..807bc5d58 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -297,7 +297,7 @@ void VersionPage::on_actionRemove_triggered() void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() { - auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), + auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods") + " (*.zip *.jar)", APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!list.empty()) { m_profile->installJarMods(list); @@ -307,7 +307,7 @@ void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() void VersionPage::on_actionReplace_Minecraft_jar_triggered() { - auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), + auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement") + " (*.jar)", APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!jarPath.isEmpty()) { m_profile->installCustomJar(jarPath); @@ -317,7 +317,7 @@ void VersionPage::on_actionReplace_Minecraft_jar_triggered() void VersionPage::on_actionImport_Components_triggered() { - QStringList list = GuiUtil::BrowseForFiles("component", tr("Select components"), tr("Components (*.json)"), + QStringList list = GuiUtil::BrowseForFiles("component", tr("Select components"), tr("Components") + " (*.json)", APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!list.isEmpty()) { @@ -332,7 +332,7 @@ void VersionPage::on_actionImport_Components_triggered() void VersionPage::on_actionAdd_Agents_triggered() { - QStringList list = GuiUtil::BrowseForFiles("agent", tr("Select agents"), tr("Java agents (*.jar)"), + QStringList list = GuiUtil::BrowseForFiles("agent", tr("Select agents"), tr("Java agents") + " (*.jar)", APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!list.isEmpty()) diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index 692db7ad7..4f30e4bb7 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -343,7 +343,7 @@ void WorldListPage::worldChanged([[maybe_unused]] const QModelIndex& current, [[ void WorldListPage::on_actionAdd_triggered() { - auto list = GuiUtil::BrowseForFiles(displayName(), tr("Select a Minecraft world zip"), tr("Minecraft World Zip File (*.zip)"), + auto list = GuiUtil::BrowseForFiles(displayName(), tr("Select a Minecraft world zip"), tr("Minecraft World Zip File") + " (*.zip)", QString(), this->parentWidget()); if (!list.empty()) { m_worlds->stopWatching(); From 73db320bff887701fbb3c2429547c09ee81097ad Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 24 Jun 2024 21:13:21 +0300 Subject: [PATCH 56/64] fix missing curseforge logo Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameModIndex.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index cde31dded..7de05f177 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -20,6 +20,9 @@ void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) QJsonObject logo = Json::ensureObject(obj, "logo"); pack.logoName = Json::ensureString(logo, "title"); pack.logoUrl = Json::ensureString(logo, "thumbnailUrl"); + if (pack.logoUrl.isEmpty()) { + pack.logoUrl = Json::ensureString(logo, "url"); + } auto authors = Json::ensureArray(obj, "authors"); for (auto authorIter : authors) { From 096266c1411a090c002d8912b992b52426956d80 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 24 Jun 2024 21:31:26 +0300 Subject: [PATCH 57/64] fix update message Signed-off-by: Trial97 --- launcher/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 9519ef553..cd17f346c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -991,7 +991,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) "\n" "You are now running %1 .\n" "Check the Prism Launcher updater log at: \n" - "%1\n" + "%2\n" "for details.") .arg(BuildConfig.printableVersionString()) .arg(update_log_path); From 2f88da9de20af705a5f8889e2186f485193b5a8b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 25 Jun 2024 09:50:33 +0300 Subject: [PATCH 58/64] add warnning when user closes the resource download dialog with selection Signed-off-by: Trial97 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index ef36edb32..9574d0bc4 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -92,6 +92,19 @@ void ResourceDownloadDialog::accept() void ResourceDownloadDialog::reject() { + auto selected = getTasks(); + if (selected.count() > 0) { + auto reply = CustomMessageBox::selectable(this, tr("Confirmation Needed"), + tr("You have %1 selected resources.\n" + "Are you sure you want to close this dialog?") + .arg(selected.count()), + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + if (reply != QMessageBox::Yes) { + return; + } + } + if (!geometrySaveKey().isEmpty()) APPLICATION->settings()->set(geometrySaveKey(), saveGeometry().toBase64()); From 295869185707dd49290e050b3982aedd51b93f98 Mon Sep 17 00:00:00 2001 From: porter milton <57007161+porterporter@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:16:26 +0000 Subject: [PATCH 59/64] add ~/Library/Java/JavaVirtualMachines/* to java installation detection Signed-off-by: porter milton <57007161+porterporter@users.noreply.github.com> --- launcher/java/JavaUtils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index b6c51be78..29db8c026 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -378,6 +378,14 @@ QList JavaUtils::FindJavaPaths() // javas downloaded by sdkman javas.append(FS::PathCombine(home, ".sdkman/candidates/java")); + // java in user library folder (like from intellij downloads) + QDir userLibraryJVMDir(FS::PathCombine(home, "Library/Java/JavaVirtualMachines/")); + QStringList userLibraryJVMJavas = userLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (const QString& java, userLibraryJVMJavas) { + javas.append(userLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); + javas.append(userLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); + } + javas.append(getMinecraftJavaBundle()); javas = addJavasFromEnv(javas); javas.removeDuplicates(); From b1a86bec34cefd8af931ac4c6d495e56ff1280c1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 26 Jun 2024 09:50:55 +0300 Subject: [PATCH 60/64] refresh account if it should refresh on instance launch Signed-off-by: Trial97 --- launcher/LaunchController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index bccc426a9..3866a7672 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -194,7 +194,8 @@ void LaunchController::login() bool tryagain = true; unsigned int tries = 0; - if (m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) { + if ((m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) || + m_accountToUse->shouldRefresh()) { // Force account refresh on the account used to launch the instance updating the AccountState // only on first try and if it is not meant to be offline auto accounts = APPLICATION->accounts(); From 3b473b24d88341774765e8561ccefe435d815bf2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 26 Jun 2024 10:07:15 +0300 Subject: [PATCH 61/64] fix sdkman on macos Signed-off-by: Trial97 --- launcher/java/JavaUtils.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 29db8c026..ba6eef42d 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -376,7 +376,11 @@ QList JavaUtils::FindJavaPaths() auto home = qEnvironmentVariable("HOME"); // javas downloaded by sdkman - javas.append(FS::PathCombine(home, ".sdkman/candidates/java")); + QDir sdkmanDir(FS::PathCombine(home, ".sdkman/candidates/java")); + QStringList sdkmanJavas = sdkmanDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (const QString& java, sdkmanJavas) { + javas.append(sdkmanDir.absolutePath() + "/" + java + "/bin/java"); + } // java in user library folder (like from intellij downloads) QDir userLibraryJVMDir(FS::PathCombine(home, "Library/Java/JavaVirtualMachines/")); From 37388e1d48c6ead6b930724a34da06008f6f1014 Mon Sep 17 00:00:00 2001 From: Aiden J Erickson Date: Wed, 26 Jun 2024 20:47:10 -0400 Subject: [PATCH 62/64] fix non-persistent user icon selection in NewInstanceDialog.cpp Signed-off-by: Aiden J Erickson --- launcher/ui/dialogs/NewInstanceDialog.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index 1601708f9..2e799d2a8 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -200,7 +200,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task importVersion.clear(); if (!task) { - ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default")); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); importIcon = false; } @@ -216,7 +216,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, I importVersion = std::move(version); if (!task) { - ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default")); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); importIcon = false; } @@ -236,6 +236,9 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QStr void NewInstanceDialog::setSuggestedIcon(const QString& key) { + if (key == "default") + return; + auto icon = APPLICATION->icons()->getIcon(key); importIcon = false; From 147741e6161cb6db3ced5ee3b8337e48d6bf4c95 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 28 Jun 2024 12:48:52 +0300 Subject: [PATCH 63/64] increment clang-tools version Signed-off-by: Trial97 --- launcher/Application.cpp | 9 +++------ launcher/BaseInstaller.h | 2 +- launcher/InstancePageProvider.h | 2 +- launcher/JavaCommon.h | 2 +- launcher/LaunchController.h | 2 +- launcher/MMCZip.h | 2 +- launcher/NullInstance.h | 2 +- launcher/VersionProxyModel.h | 2 +- launcher/icons/IconList.h | 2 +- launcher/java/JavaCheckerJob.h | 4 ++-- launcher/java/JavaUtils.cpp | 6 ++---- launcher/launch/LaunchStep.h | 6 +++--- launcher/launch/LaunchTask.h | 2 +- launcher/launch/steps/CheckJava.h | 4 ++-- launcher/launch/steps/LookupServerAddress.h | 2 +- launcher/launch/steps/PostLaunchCommand.h | 2 +- launcher/launch/steps/PreLaunchCommand.h | 2 +- launcher/launch/steps/QuitAfterGameStop.h | 4 ++-- launcher/launch/steps/TextPrint.h | 2 +- launcher/launch/steps/Update.h | 4 ++-- launcher/meta/BaseEntity.cpp | 4 ++-- launcher/minecraft/MinecraftInstance.h | 2 +- launcher/minecraft/MinecraftLoadAndCheck.h | 2 +- launcher/minecraft/MinecraftUpdate.h | 2 +- launcher/minecraft/auth/AuthStep.h | 2 +- launcher/minecraft/launch/ClaimAccount.h | 2 +- launcher/minecraft/launch/CreateGameFolders.h | 2 +- launcher/minecraft/launch/ExtractNatives.h | 4 ++-- launcher/minecraft/launch/LauncherPartLaunch.h | 2 +- launcher/minecraft/launch/ModMinecraftJar.h | 4 ++-- launcher/minecraft/launch/PrintInstanceInfo.h | 4 ++-- launcher/minecraft/launch/ReconstructAssets.h | 4 ++-- launcher/minecraft/launch/ScanModFolders.h | 4 ++-- launcher/minecraft/launch/VerifyJavaInstall.h | 2 +- launcher/minecraft/mod/ResourceFolderModel.cpp | 3 +-- launcher/minecraft/update/FMLLibrariesTask.h | 2 +- launcher/minecraft/update/FoldersTask.h | 2 +- launcher/minecraft/update/LibrariesTask.h | 2 +- launcher/modplatform/CheckUpdateTask.h | 2 +- launcher/modplatform/flame/FileResolvingTask.h | 2 +- launcher/modplatform/legacy_ftb/PackFetchTask.h | 2 +- launcher/modplatform/modrinth/ModrinthPackIndex.cpp | 10 ++++++---- launcher/modplatform/packwiz/Packwiz.cpp | 5 +++-- launcher/net/ByteArraySink.h | 2 +- launcher/net/ChecksumValidator.h | 2 +- launcher/net/FileSink.h | 2 +- launcher/net/StaticHeaderProxy.h | 2 +- launcher/pathmatcher/FSTreeMatcher.h | 2 +- launcher/pathmatcher/MultiMatcher.h | 2 +- launcher/pathmatcher/SimplePrefixMatcher.h | 2 +- launcher/screenshots/ImgurAlbumCreation.h | 2 +- launcher/screenshots/ImgurUpload.h | 2 +- launcher/tools/GenericProfiler.h | 2 +- launcher/ui/dialogs/ModUpdateDialog.cpp | 10 ++++------ launcher/ui/dialogs/VersionSelectDialog.h | 2 +- launcher/ui/dialogs/skins/SkinManageDialog.cpp | 2 +- launcher/ui/pages/BasePageContainer.h | 2 +- launcher/ui/pages/instance/ManagedPackPage.h | 6 +++--- launcher/ui/pages/instance/ServersPage.cpp | 2 +- launcher/ui/pages/modplatform/ModPage.h | 2 +- launcher/ui/setupwizard/BaseWizardPage.h | 2 +- launcher/ui/setupwizard/JavaWizardPage.h | 2 +- launcher/ui/widgets/JavaSettingsWidget.h | 2 +- launcher/ui/widgets/LanguageSelectionWidget.h | 2 +- launcher/updater/prismupdater/PrismUpdater.cpp | 3 +-- nix/dev.nix | 2 +- 66 files changed, 93 insertions(+), 99 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index cd17f346c..7cd791fe4 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -945,8 +945,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) [[fallthrough]]; default: { qDebug() << "Exiting because update lockfile is present"; - QMetaObject::invokeMethod( - this, []() { exit(1); }, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection); return; } } @@ -978,8 +977,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) [[fallthrough]]; default: { qDebug() << "Exiting because update lockfile is present"; - QMetaObject::invokeMethod( - this, []() { exit(1); }, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection); return; } } @@ -1673,8 +1671,7 @@ QString Application::getJarPath(QString jarFile) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME), #endif - FS::PathCombine(m_rootPath, "jars"), - FS::PathCombine(applicationDirPath(), "jars"), + FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"), FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging }; for (QString p : potentialPaths) { diff --git a/launcher/BaseInstaller.h b/launcher/BaseInstaller.h index 6244ced7d..1cf7d65f5 100644 --- a/launcher/BaseInstaller.h +++ b/launcher/BaseInstaller.h @@ -29,7 +29,7 @@ class BaseVersion; class BaseInstaller { public: BaseInstaller(); - virtual ~BaseInstaller(){}; + virtual ~BaseInstaller() {}; bool isApplied(MinecraftInstance* on); virtual bool add(MinecraftInstance* to); diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index 66d2b6750..52399e912 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -22,7 +22,7 @@ class InstancePageProvider : protected QObject, public BasePageProvider { public: explicit InstancePageProvider(InstancePtr parent) { inst = parent; } - virtual ~InstancePageProvider(){}; + virtual ~InstancePageProvider() {}; virtual QList getPages() override { QList values; diff --git a/launcher/JavaCommon.h b/launcher/JavaCommon.h index c96f7a985..cf3b75c9c 100644 --- a/launcher/JavaCommon.h +++ b/launcher/JavaCommon.h @@ -24,7 +24,7 @@ class TestCheck : public QObject { TestCheck(QWidget* parent, QString path, QString args, int minMem, int maxMem, int permGen) : m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen) {} - virtual ~TestCheck(){}; + virtual ~TestCheck() {}; void run(); diff --git a/launcher/LaunchController.h b/launcher/LaunchController.h index 02b1e0d33..bc688f2ba 100644 --- a/launcher/LaunchController.h +++ b/launcher/LaunchController.h @@ -48,7 +48,7 @@ class LaunchController : public Task { void executeTask() override; LaunchController(QObject* parent = nullptr); - virtual ~LaunchController(){}; + virtual ~LaunchController() {}; void setInstance(InstancePtr instance) { m_instance = instance; } diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index eb0ea8f6a..35baa6ee3 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -176,7 +176,7 @@ class ExportToZipTask : public Task { QString destinationPrefix = "", bool followSymlinks = false, bool utf8Enabled = false) - : ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks, utf8Enabled){}; + : ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks, utf8Enabled) {}; virtual ~ExportToZipTask() = default; diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h index c79600e7d..b6a9478a8 100644 --- a/launcher/NullInstance.h +++ b/launcher/NullInstance.h @@ -46,7 +46,7 @@ class NullInstance : public BaseInstance { { setVersionBroken(true); } - virtual ~NullInstance(){}; + virtual ~NullInstance() {}; void saveNow() override {} void loadSpecificSettings() override { setSpecificSettingsLoaded(true); } QString getStatusbarDescription() override { return tr("Unknown instance type"); }; diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index 0863a7c80..efea1a0bb 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -14,7 +14,7 @@ class VersionProxyModel : public QAbstractProxyModel { public: VersionProxyModel(QObject* parent = 0); - virtual ~VersionProxyModel(){}; + virtual ~VersionProxyModel() {}; virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; diff --git a/launcher/icons/IconList.h b/launcher/icons/IconList.h index c51826057..553946c42 100644 --- a/launcher/icons/IconList.h +++ b/launcher/icons/IconList.h @@ -52,7 +52,7 @@ class IconList : public QAbstractListModel { Q_OBJECT public: explicit IconList(const QStringList& builtinPaths, QString path, QObject* parent = 0); - virtual ~IconList(){}; + virtual ~IconList() {}; QIcon getIcon(const QString& key) const; int getIconIndex(const QString& key) const; diff --git a/launcher/java/JavaCheckerJob.h b/launcher/java/JavaCheckerJob.h index ddf827968..16b572632 100644 --- a/launcher/java/JavaCheckerJob.h +++ b/launcher/java/JavaCheckerJob.h @@ -26,8 +26,8 @@ using JavaCheckerJobPtr = shared_qobject_ptr; class JavaCheckerJob : public Task { Q_OBJECT public: - explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name){}; - virtual ~JavaCheckerJob(){}; + explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name) {}; + virtual ~JavaCheckerJob() {}; bool addJavaCheckerAction(JavaCheckerPtr base) { diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index ba6eef42d..809d81087 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -79,11 +79,9 @@ QProcessEnvironment CleanEnviroment() QStringList stripped = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - "LD_LIBRARY_PATH", - "LD_PRELOAD", + "LD_LIBRARY_PATH", "LD_PRELOAD", #endif - "QT_PLUGIN_PATH", - "QT_FONTPATH" + "QT_PLUGIN_PATH", "QT_FONTPATH" }; for (auto key : rawenv.keys()) { auto value = rawenv.value(key); diff --git a/launcher/launch/LaunchStep.h b/launcher/launch/LaunchStep.h index b1bec2b4a..6a28afb1f 100644 --- a/launcher/launch/LaunchStep.h +++ b/launcher/launch/LaunchStep.h @@ -25,7 +25,7 @@ class LaunchStep : public Task { Q_OBJECT public: /* methods */ explicit LaunchStep(LaunchTask* parent) : Task(nullptr), m_parent(parent) { bind(parent); }; - virtual ~LaunchStep(){}; + virtual ~LaunchStep() {}; private: /* methods */ void bind(LaunchTask* parent); @@ -37,9 +37,9 @@ class LaunchStep : public Task { void progressReportingRequest(); public slots: - virtual void proceed(){}; + virtual void proceed() {}; // called in the opposite order than the Task launch(), used to clean up or otherwise undo things after the launch ends - virtual void finalize(){}; + virtual void finalize() {}; protected: /* data */ LaunchTask* m_parent; diff --git a/launcher/launch/LaunchTask.h b/launcher/launch/LaunchTask.h index e79c43557..ae24b9a26 100644 --- a/launcher/launch/LaunchTask.h +++ b/launcher/launch/LaunchTask.h @@ -55,7 +55,7 @@ class LaunchTask : public Task { public: /* methods */ static shared_qobject_ptr create(InstancePtr inst); - virtual ~LaunchTask(){}; + virtual ~LaunchTask() {}; void appendStep(shared_qobject_ptr step); void prependStep(shared_qobject_ptr step); diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h index 4436e2a55..ac9c36244 100644 --- a/launcher/launch/steps/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h @@ -22,8 +22,8 @@ class CheckJava : public LaunchStep { Q_OBJECT public: - explicit CheckJava(LaunchTask* parent) : LaunchStep(parent){}; - virtual ~CheckJava(){}; + explicit CheckJava(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~CheckJava() {}; virtual void executeTask(); virtual bool canAbort() const { return false; } diff --git a/launcher/launch/steps/LookupServerAddress.h b/launcher/launch/steps/LookupServerAddress.h index abd92a5e8..acbd74309 100644 --- a/launcher/launch/steps/LookupServerAddress.h +++ b/launcher/launch/steps/LookupServerAddress.h @@ -25,7 +25,7 @@ class LookupServerAddress : public LaunchStep { Q_OBJECT public: explicit LookupServerAddress(LaunchTask* parent); - virtual ~LookupServerAddress(){}; + virtual ~LookupServerAddress() {}; virtual void executeTask(); virtual bool abort(); diff --git a/launcher/launch/steps/PostLaunchCommand.h b/launcher/launch/steps/PostLaunchCommand.h index 578433b86..fd1443b29 100644 --- a/launcher/launch/steps/PostLaunchCommand.h +++ b/launcher/launch/steps/PostLaunchCommand.h @@ -22,7 +22,7 @@ class PostLaunchCommand : public LaunchStep { Q_OBJECT public: explicit PostLaunchCommand(LaunchTask* parent); - virtual ~PostLaunchCommand(){}; + virtual ~PostLaunchCommand() {}; virtual void executeTask(); virtual bool abort(); diff --git a/launcher/launch/steps/PreLaunchCommand.h b/launcher/launch/steps/PreLaunchCommand.h index 10568ea34..b6dc6cd8b 100644 --- a/launcher/launch/steps/PreLaunchCommand.h +++ b/launcher/launch/steps/PreLaunchCommand.h @@ -22,7 +22,7 @@ class PreLaunchCommand : public LaunchStep { Q_OBJECT public: explicit PreLaunchCommand(LaunchTask* parent); - virtual ~PreLaunchCommand(){}; + virtual ~PreLaunchCommand() {}; virtual void executeTask(); virtual bool abort(); diff --git a/launcher/launch/steps/QuitAfterGameStop.h b/launcher/launch/steps/QuitAfterGameStop.h index 9326b2a8c..d4324cce6 100644 --- a/launcher/launch/steps/QuitAfterGameStop.h +++ b/launcher/launch/steps/QuitAfterGameStop.h @@ -23,8 +23,8 @@ class QuitAfterGameStop : public LaunchStep { Q_OBJECT public: - explicit QuitAfterGameStop(LaunchTask* parent) : LaunchStep(parent){}; - virtual ~QuitAfterGameStop(){}; + explicit QuitAfterGameStop(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~QuitAfterGameStop() {}; virtual void executeTask(); virtual bool canAbort() const { return false; } diff --git a/launcher/launch/steps/TextPrint.h b/launcher/launch/steps/TextPrint.h index bd6c28567..a96c2f887 100644 --- a/launcher/launch/steps/TextPrint.h +++ b/launcher/launch/steps/TextPrint.h @@ -28,7 +28,7 @@ class TextPrint : public LaunchStep { public: explicit TextPrint(LaunchTask* parent, const QStringList& lines, MessageLevel::Enum level); explicit TextPrint(LaunchTask* parent, const QString& line, MessageLevel::Enum level); - virtual ~TextPrint(){}; + virtual ~TextPrint() {}; virtual void executeTask(); virtual bool canAbort() const; diff --git a/launcher/launch/steps/Update.h b/launcher/launch/steps/Update.h index 9262cdbe4..878a43e7e 100644 --- a/launcher/launch/steps/Update.h +++ b/launcher/launch/steps/Update.h @@ -25,8 +25,8 @@ class Update : public LaunchStep { Q_OBJECT public: - explicit Update(LaunchTask* parent, Net::Mode mode) : LaunchStep(parent), m_mode(mode){}; - virtual ~Update(){}; + explicit Update(LaunchTask* parent, Net::Mode mode) : LaunchStep(parent), m_mode(mode) {}; + virtual ~Update() {}; void executeTask() override; bool canAbort() const override; diff --git a/launcher/meta/BaseEntity.cpp b/launcher/meta/BaseEntity.cpp index 8a99e3303..e74406752 100644 --- a/launcher/meta/BaseEntity.cpp +++ b/launcher/meta/BaseEntity.cpp @@ -26,8 +26,8 @@ class ParsingValidator : public Net::Validator { public: /* con/des */ - ParsingValidator(Meta::BaseEntity* entity) : m_entity(entity){}; - virtual ~ParsingValidator(){}; + ParsingValidator(Meta::BaseEntity* entity) : m_entity(entity) {}; + virtual ~ParsingValidator() {}; public: /* methods */ bool init(QNetworkRequest&) override { return true; } diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index b1f305201..7af0df389 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -56,7 +56,7 @@ class MinecraftInstance : public BaseInstance { Q_OBJECT public: MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir); - virtual ~MinecraftInstance(){}; + virtual ~MinecraftInstance() {}; virtual void saveNow() override; void loadSpecificSettings() override; diff --git a/launcher/minecraft/MinecraftLoadAndCheck.h b/launcher/minecraft/MinecraftLoadAndCheck.h index 9556c1d6a..09edaf909 100644 --- a/launcher/minecraft/MinecraftLoadAndCheck.h +++ b/launcher/minecraft/MinecraftLoadAndCheck.h @@ -31,7 +31,7 @@ class MinecraftLoadAndCheck : public Task { Q_OBJECT public: explicit MinecraftLoadAndCheck(MinecraftInstance* inst, QObject* parent = 0); - virtual ~MinecraftLoadAndCheck(){}; + virtual ~MinecraftLoadAndCheck() {}; void executeTask() override; private slots: diff --git a/launcher/minecraft/MinecraftUpdate.h b/launcher/minecraft/MinecraftUpdate.h index 9c41d7f56..591c6afcb 100644 --- a/launcher/minecraft/MinecraftUpdate.h +++ b/launcher/minecraft/MinecraftUpdate.h @@ -33,7 +33,7 @@ class MinecraftUpdate : public Task { Q_OBJECT public: explicit MinecraftUpdate(MinecraftInstance* inst, QObject* parent = 0); - virtual ~MinecraftUpdate(){}; + virtual ~MinecraftUpdate() {}; void executeTask() override; bool canAbort() const override; diff --git a/launcher/minecraft/auth/AuthStep.h b/launcher/minecraft/auth/AuthStep.h index 4d2cf69c1..cbe157790 100644 --- a/launcher/minecraft/auth/AuthStep.h +++ b/launcher/minecraft/auth/AuthStep.h @@ -27,7 +27,7 @@ class AuthStep : public QObject { public: using Ptr = shared_qobject_ptr; - explicit AuthStep(AccountData* data) : QObject(nullptr), m_data(data){}; + explicit AuthStep(AccountData* data) : QObject(nullptr), m_data(data) {}; virtual ~AuthStep() noexcept = default; virtual QString describe() = 0; diff --git a/launcher/minecraft/launch/ClaimAccount.h b/launcher/minecraft/launch/ClaimAccount.h index 3d47539ac..357a4d4c5 100644 --- a/launcher/minecraft/launch/ClaimAccount.h +++ b/launcher/minecraft/launch/ClaimAccount.h @@ -22,7 +22,7 @@ class ClaimAccount : public LaunchStep { Q_OBJECT public: explicit ClaimAccount(LaunchTask* parent, AuthSessionPtr session); - virtual ~ClaimAccount(){}; + virtual ~ClaimAccount() {}; void executeTask() override; void finalize() override; diff --git a/launcher/minecraft/launch/CreateGameFolders.h b/launcher/minecraft/launch/CreateGameFolders.h index 44524ded5..b44762d62 100644 --- a/launcher/minecraft/launch/CreateGameFolders.h +++ b/launcher/minecraft/launch/CreateGameFolders.h @@ -24,7 +24,7 @@ class CreateGameFolders : public LaunchStep { Q_OBJECT public: explicit CreateGameFolders(LaunchTask* parent); - virtual ~CreateGameFolders(){}; + virtual ~CreateGameFolders() {}; virtual void executeTask(); virtual bool canAbort() const { return false; } diff --git a/launcher/minecraft/launch/ExtractNatives.h b/launcher/minecraft/launch/ExtractNatives.h index 4837a9dbb..1ad9a416e 100644 --- a/launcher/minecraft/launch/ExtractNatives.h +++ b/launcher/minecraft/launch/ExtractNatives.h @@ -21,8 +21,8 @@ class ExtractNatives : public LaunchStep { Q_OBJECT public: - explicit ExtractNatives(LaunchTask* parent) : LaunchStep(parent){}; - virtual ~ExtractNatives(){}; + explicit ExtractNatives(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~ExtractNatives() {}; void executeTask() override; bool canAbort() const override { return false; } diff --git a/launcher/minecraft/launch/LauncherPartLaunch.h b/launcher/minecraft/launch/LauncherPartLaunch.h index 9f6ca1e7b..fcd4daec6 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.h +++ b/launcher/minecraft/launch/LauncherPartLaunch.h @@ -25,7 +25,7 @@ class LauncherPartLaunch : public LaunchStep { Q_OBJECT public: explicit LauncherPartLaunch(LaunchTask* parent); - virtual ~LauncherPartLaunch(){}; + virtual ~LauncherPartLaunch() {}; virtual void executeTask(); virtual bool abort(); diff --git a/launcher/minecraft/launch/ModMinecraftJar.h b/launcher/minecraft/launch/ModMinecraftJar.h index 12e73b5f8..6fc2a8a26 100644 --- a/launcher/minecraft/launch/ModMinecraftJar.h +++ b/launcher/minecraft/launch/ModMinecraftJar.h @@ -21,8 +21,8 @@ class ModMinecraftJar : public LaunchStep { Q_OBJECT public: - explicit ModMinecraftJar(LaunchTask* parent) : LaunchStep(parent){}; - virtual ~ModMinecraftJar(){}; + explicit ModMinecraftJar(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~ModMinecraftJar() {}; virtual void executeTask() override; virtual bool canAbort() const override { return false; } diff --git a/launcher/minecraft/launch/PrintInstanceInfo.h b/launcher/minecraft/launch/PrintInstanceInfo.h index 8e1c41b62..93c5f0fd6 100644 --- a/launcher/minecraft/launch/PrintInstanceInfo.h +++ b/launcher/minecraft/launch/PrintInstanceInfo.h @@ -25,8 +25,8 @@ class PrintInstanceInfo : public LaunchStep { Q_OBJECT public: explicit PrintInstanceInfo(LaunchTask* parent, AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) - : LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin){}; - virtual ~PrintInstanceInfo(){}; + : LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin) {}; + virtual ~PrintInstanceInfo() {}; virtual void executeTask(); virtual bool canAbort() const { return false; } diff --git a/launcher/minecraft/launch/ReconstructAssets.h b/launcher/minecraft/launch/ReconstructAssets.h index bd867c8d4..2c910c595 100644 --- a/launcher/minecraft/launch/ReconstructAssets.h +++ b/launcher/minecraft/launch/ReconstructAssets.h @@ -21,8 +21,8 @@ class ReconstructAssets : public LaunchStep { Q_OBJECT public: - explicit ReconstructAssets(LaunchTask* parent) : LaunchStep(parent){}; - virtual ~ReconstructAssets(){}; + explicit ReconstructAssets(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~ReconstructAssets() {}; void executeTask() override; bool canAbort() const override { return false; } diff --git a/launcher/minecraft/launch/ScanModFolders.h b/launcher/minecraft/launch/ScanModFolders.h index a5b75825b..5d9350952 100644 --- a/launcher/minecraft/launch/ScanModFolders.h +++ b/launcher/minecraft/launch/ScanModFolders.h @@ -21,8 +21,8 @@ class ScanModFolders : public LaunchStep { Q_OBJECT public: - explicit ScanModFolders(LaunchTask* parent) : LaunchStep(parent){}; - virtual ~ScanModFolders(){}; + explicit ScanModFolders(LaunchTask* parent) : LaunchStep(parent) {}; + virtual ~ScanModFolders() {}; virtual void executeTask() override; virtual bool canAbort() const override { return false; } diff --git a/launcher/minecraft/launch/VerifyJavaInstall.h b/launcher/minecraft/launch/VerifyJavaInstall.h index dabbf3b25..3591ce665 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.h +++ b/launcher/minecraft/launch/VerifyJavaInstall.h @@ -42,7 +42,7 @@ class VerifyJavaInstall : public LaunchStep { Q_OBJECT public: - explicit VerifyJavaInstall(LaunchTask* parent) : LaunchStep(parent){}; + explicit VerifyJavaInstall(LaunchTask* parent) : LaunchStep(parent) {}; ~VerifyJavaInstall() override = default; void executeTask() override; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index e70ada274..aba0886e8 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -282,8 +282,7 @@ void ResourceFolderModel::resolveResource(Resource* res) connect( task.get(), &Task::succeeded, this, [=] { onParseSucceeded(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); - connect( - task.get(), &Task::failed, this, [=] { onParseFailed(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); + connect(task.get(), &Task::failed, this, [=] { onParseFailed(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); connect( task.get(), &Task::finished, this, [=] { diff --git a/launcher/minecraft/update/FMLLibrariesTask.h b/launcher/minecraft/update/FMLLibrariesTask.h index 9d0102be7..32712d239 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.h +++ b/launcher/minecraft/update/FMLLibrariesTask.h @@ -9,7 +9,7 @@ class FMLLibrariesTask : public Task { Q_OBJECT public: FMLLibrariesTask(MinecraftInstance* inst); - virtual ~FMLLibrariesTask(){}; + virtual ~FMLLibrariesTask() {}; void executeTask() override; diff --git a/launcher/minecraft/update/FoldersTask.h b/launcher/minecraft/update/FoldersTask.h index 2d2954b2a..be4e33eb7 100644 --- a/launcher/minecraft/update/FoldersTask.h +++ b/launcher/minecraft/update/FoldersTask.h @@ -7,7 +7,7 @@ class FoldersTask : public Task { Q_OBJECT public: FoldersTask(MinecraftInstance* inst); - virtual ~FoldersTask(){}; + virtual ~FoldersTask() {}; void executeTask() override; diff --git a/launcher/minecraft/update/LibrariesTask.h b/launcher/minecraft/update/LibrariesTask.h index c969e74df..441191154 100644 --- a/launcher/minecraft/update/LibrariesTask.h +++ b/launcher/minecraft/update/LibrariesTask.h @@ -7,7 +7,7 @@ class LibrariesTask : public Task { Q_OBJECT public: LibrariesTask(MinecraftInstance* inst); - virtual ~LibrariesTask(){}; + virtual ~LibrariesTask() {}; void executeTask() override; diff --git a/launcher/modplatform/CheckUpdateTask.h b/launcher/modplatform/CheckUpdateTask.h index b19b25484..e17b1520a 100644 --- a/launcher/modplatform/CheckUpdateTask.h +++ b/launcher/modplatform/CheckUpdateTask.h @@ -17,7 +17,7 @@ class CheckUpdateTask : public Task { std::list& mcVersions, std::optional loaders, std::shared_ptr mods_folder) - : Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder){}; + : Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder) {}; struct UpdatableMod { QString name; diff --git a/launcher/modplatform/flame/FileResolvingTask.h b/launcher/modplatform/flame/FileResolvingTask.h index c280827af..cfa53cb22 100644 --- a/launcher/modplatform/flame/FileResolvingTask.h +++ b/launcher/modplatform/flame/FileResolvingTask.h @@ -9,7 +9,7 @@ class FileResolvingTask : public Task { Q_OBJECT public: explicit FileResolvingTask(const shared_qobject_ptr& network, Flame::Manifest& toProcess); - virtual ~FileResolvingTask(){}; + virtual ~FileResolvingTask() {}; bool canAbort() const override { return true; } bool abort() override; diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.h b/launcher/modplatform/legacy_ftb/PackFetchTask.h index f2116ce99..e37d949d5 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.h +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.h @@ -13,7 +13,7 @@ class PackFetchTask : public QObject { Q_OBJECT public: - PackFetchTask(shared_qobject_ptr network) : QObject(nullptr), m_network(network){}; + PackFetchTask(shared_qobject_ptr network) : QObject(nullptr), m_network(network) {}; virtual ~PackFetchTask() = default; void fetch(); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 7925a33b4..48b27a597 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -131,8 +131,9 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArra pack.versionsLoaded = true; } -auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name) - -> ModPlatform::IndexedVersion +auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, + QString preferred_hash_type, + QString preferred_file_name) -> ModPlatform::IndexedVersion { ModPlatform::IndexedVersion file; @@ -246,8 +247,9 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t return {}; } -auto Modrinth::loadDependencyVersions([[maybe_unused]] const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst) - -> ModPlatform::IndexedVersion +auto Modrinth::loadDependencyVersions([[maybe_unused]] const ModPlatform::Dependency& m, + QJsonArray& arr, + const BaseInstance* inst) -> ModPlatform::IndexedVersion { auto profile = (dynamic_cast(inst))->getPackProfile(); QString mcVersion = profile->getComponentVersion("net.minecraft"); diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 626f1c9df..77a0935f3 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -90,8 +90,9 @@ auto intEntry(toml::table table, QString entry_name) -> int return node.value_or(0); } -auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) - -> Mod +auto V1::createModFormat([[maybe_unused]] QDir& index_dir, + ModPlatform::IndexedPack& mod_pack, + ModPlatform::IndexedVersion& mod_version) -> Mod { Mod mod; diff --git a/launcher/net/ByteArraySink.h b/launcher/net/ByteArraySink.h index d636f6634..ac64052b9 100644 --- a/launcher/net/ByteArraySink.h +++ b/launcher/net/ByteArraySink.h @@ -45,7 +45,7 @@ namespace Net { */ class ByteArraySink : public Sink { public: - ByteArraySink(std::shared_ptr output) : m_output(output){}; + ByteArraySink(std::shared_ptr output) : m_output(output) {}; virtual ~ByteArraySink() = default; diff --git a/launcher/net/ChecksumValidator.h b/launcher/net/ChecksumValidator.h index dfee0aee5..34ee5f856 100644 --- a/launcher/net/ChecksumValidator.h +++ b/launcher/net/ChecksumValidator.h @@ -44,7 +44,7 @@ namespace Net { class ChecksumValidator : public Validator { public: ChecksumValidator(QCryptographicHash::Algorithm algorithm, QByteArray expected = QByteArray()) - : m_checksum(algorithm), m_expected(expected){}; + : m_checksum(algorithm), m_expected(expected) {}; virtual ~ChecksumValidator() = default; public: diff --git a/launcher/net/FileSink.h b/launcher/net/FileSink.h index 40134b5f4..816254ff9 100644 --- a/launcher/net/FileSink.h +++ b/launcher/net/FileSink.h @@ -42,7 +42,7 @@ namespace Net { class FileSink : public Sink { public: - FileSink(QString filename) : m_filename(filename){}; + FileSink(QString filename) : m_filename(filename) {}; virtual ~FileSink() = default; public: diff --git a/launcher/net/StaticHeaderProxy.h b/launcher/net/StaticHeaderProxy.h index 2c0d5ecc8..73678c026 100644 --- a/launcher/net/StaticHeaderProxy.h +++ b/launcher/net/StaticHeaderProxy.h @@ -25,7 +25,7 @@ namespace Net { class StaticHeaderProxy : public HeaderProxy { public: - StaticHeaderProxy(QList hdrs = {}) : HeaderProxy(), m_hdrs(hdrs){}; + StaticHeaderProxy(QList hdrs = {}) : HeaderProxy(), m_hdrs(hdrs) {}; virtual ~StaticHeaderProxy() = default; public: diff --git a/launcher/pathmatcher/FSTreeMatcher.h b/launcher/pathmatcher/FSTreeMatcher.h index 52f1404df..689f11979 100644 --- a/launcher/pathmatcher/FSTreeMatcher.h +++ b/launcher/pathmatcher/FSTreeMatcher.h @@ -6,7 +6,7 @@ class FSTreeMatcher : public IPathMatcher { public: - virtual ~FSTreeMatcher(){}; + virtual ~FSTreeMatcher() {}; FSTreeMatcher(SeparatorPrefixTree<'/'>& tree) : m_fsTree(tree) {} bool matches(const QString& string) const override { return m_fsTree.covers(string); } diff --git a/launcher/pathmatcher/MultiMatcher.h b/launcher/pathmatcher/MultiMatcher.h index 101595809..3e2bdb95d 100644 --- a/launcher/pathmatcher/MultiMatcher.h +++ b/launcher/pathmatcher/MultiMatcher.h @@ -4,7 +4,7 @@ class MultiMatcher : public IPathMatcher { public: - virtual ~MultiMatcher(){}; + virtual ~MultiMatcher() {}; MultiMatcher() {} MultiMatcher& add(Ptr add) { diff --git a/launcher/pathmatcher/SimplePrefixMatcher.h b/launcher/pathmatcher/SimplePrefixMatcher.h index fc1f5cede..ff3805179 100644 --- a/launcher/pathmatcher/SimplePrefixMatcher.h +++ b/launcher/pathmatcher/SimplePrefixMatcher.h @@ -7,7 +7,7 @@ class SimplePrefixMatcher : public IPathMatcher { public: - virtual ~SimplePrefixMatcher(){}; + virtual ~SimplePrefixMatcher() {}; SimplePrefixMatcher(const QString& prefix) { m_prefix = prefix; diff --git a/launcher/screenshots/ImgurAlbumCreation.h b/launcher/screenshots/ImgurAlbumCreation.h index 7c292db73..ecb225394 100644 --- a/launcher/screenshots/ImgurAlbumCreation.h +++ b/launcher/screenshots/ImgurAlbumCreation.h @@ -49,7 +49,7 @@ class ImgurAlbumCreation : public Net::NetRequest { class Sink : public Net::Sink { public: - Sink(std::shared_ptr res) : m_result(res){}; + Sink(std::shared_ptr res) : m_result(res) {}; virtual ~Sink() = default; public: diff --git a/launcher/screenshots/ImgurUpload.h b/launcher/screenshots/ImgurUpload.h index 5867ad306..5a58ad2b5 100644 --- a/launcher/screenshots/ImgurUpload.h +++ b/launcher/screenshots/ImgurUpload.h @@ -43,7 +43,7 @@ class ImgurUpload : public Net::NetRequest { public: class Sink : public Net::Sink { public: - Sink(ScreenShot::Ptr shot) : m_shot(shot){}; + Sink(ScreenShot::Ptr shot) : m_shot(shot) {}; virtual ~Sink() = default; public: diff --git a/launcher/tools/GenericProfiler.h b/launcher/tools/GenericProfiler.h index e99fc059f..7868990ea 100644 --- a/launcher/tools/GenericProfiler.h +++ b/launcher/tools/GenericProfiler.h @@ -22,7 +22,7 @@ class GenericProfilerFactory : public BaseProfilerFactory { public: QString name() const override { return "Generic"; } - void registerSettings([[maybe_unused]] SettingsObjectPtr settings) override{}; + void registerSettings([[maybe_unused]] SettingsObjectPtr settings) override {}; BaseExternalTool* createTool(InstancePtr instance, QObject* parent = 0) override; bool check([[maybe_unused]] QString* error) override { return true; }; bool check([[maybe_unused]] const QString& path, [[maybe_unused]] QString* error) override { return true; }; diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 1583b4f46..3d04aca6b 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -92,17 +92,15 @@ void ModUpdateDialog::checkCandidates() if (!m_modrinth_to_update.empty()) { m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model)); - connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) { - m_failed_check_update.append({ mod, reason, recover_url }); - }); + connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, + [this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({ mod, reason, recover_url }); }); check_task.addTask(m_modrinth_check_task); } if (!m_flame_to_update.empty()) { m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model)); - connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) { - m_failed_check_update.append({ mod, reason, recover_url }); - }); + connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, + [this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({ mod, reason, recover_url }); }); check_task.addTask(m_flame_check_task); } diff --git a/launcher/ui/dialogs/VersionSelectDialog.h b/launcher/ui/dialogs/VersionSelectDialog.h index 0ccd45e74..34c5e66f8 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.h +++ b/launcher/ui/dialogs/VersionSelectDialog.h @@ -37,7 +37,7 @@ class VersionSelectDialog : public QDialog { public: explicit VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent = 0, bool cancelable = true); - virtual ~VersionSelectDialog(){}; + virtual ~VersionSelectDialog() {}; int exec() override; diff --git a/launcher/ui/dialogs/skins/SkinManageDialog.cpp b/launcher/ui/dialogs/skins/SkinManageDialog.cpp index d1eeb759d..a947af632 100644 --- a/launcher/ui/dialogs/skins/SkinManageDialog.cpp +++ b/launcher/ui/dialogs/skins/SkinManageDialog.cpp @@ -371,7 +371,7 @@ void SkinManageDialog::on_urlBtn_clicked() class WaitTask : public Task { public: - WaitTask() : m_loop(), m_done(false){}; + WaitTask() : m_loop(), m_done(false) {}; virtual ~WaitTask() = default; public slots: diff --git a/launcher/ui/pages/BasePageContainer.h b/launcher/ui/pages/BasePageContainer.h index a497ef7b3..671c2735d 100644 --- a/launcher/ui/pages/BasePageContainer.h +++ b/launcher/ui/pages/BasePageContainer.h @@ -4,7 +4,7 @@ class BasePage; class BasePageContainer { public: - virtual ~BasePageContainer(){}; + virtual ~BasePageContainer() {}; virtual bool selectPage(QString pageId) = 0; virtual BasePage* selectedPage() const = 0; virtual BasePage* getPage(QString pageId) { return nullptr; }; diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h index d77cb97b8..fe5a200de 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.h +++ b/launcher/ui/pages/instance/ManagedPackPage.h @@ -50,7 +50,7 @@ class ManagedPackPage : public QWidget, public BasePage { /** Gets the necessary information about the managed pack, such as * available versions*/ - virtual void parseManagedPack(){}; + virtual void parseManagedPack() {}; /** URL of the managed pack. * Not the version-specific one. @@ -64,8 +64,8 @@ class ManagedPackPage : public QWidget, public BasePage { */ virtual void suggestVersion(); - virtual void update(){}; - virtual void updateFromFile(){}; + virtual void update() {}; + virtual void updateFromFile() {}; protected slots: /** Does the necessary UI changes for when something failed. diff --git a/launcher/ui/pages/instance/ServersPage.cpp b/launcher/ui/pages/instance/ServersPage.cpp index 2142e6c9f..f842b4b93 100644 --- a/launcher/ui/pages/instance/ServersPage.cpp +++ b/launcher/ui/pages/instance/ServersPage.cpp @@ -168,7 +168,7 @@ class ServersModel : public QAbstractListModel { m_saveTimer.setInterval(5000); connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal); } - virtual ~ServersModel(){}; + virtual ~ServersModel() {}; void observe() { diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index 99e674eab..5c9a82303 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -59,7 +59,7 @@ class ModPage : public ResourcePage { protected: ModPage(ModDownloadDialog* dialog, BaseInstance& instance); - virtual void prepareProviderCategories(){}; + virtual void prepareProviderCategories() {}; protected slots: virtual void filterMods(); diff --git a/launcher/ui/setupwizard/BaseWizardPage.h b/launcher/ui/setupwizard/BaseWizardPage.h index 80cc64969..b5ea06214 100644 --- a/launcher/ui/setupwizard/BaseWizardPage.h +++ b/launcher/ui/setupwizard/BaseWizardPage.h @@ -6,7 +6,7 @@ class BaseWizardPage : public QWizardPage { public: explicit BaseWizardPage(QWidget* parent = Q_NULLPTR) : QWizardPage(parent) {} - virtual ~BaseWizardPage(){}; + virtual ~BaseWizardPage() {}; virtual bool wantsRefreshButton() { return false; } virtual void refresh() {} diff --git a/launcher/ui/setupwizard/JavaWizardPage.h b/launcher/ui/setupwizard/JavaWizardPage.h index 6c083dc96..dde765f27 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.h +++ b/launcher/ui/setupwizard/JavaWizardPage.h @@ -9,7 +9,7 @@ class JavaWizardPage : public BaseWizardPage { public: explicit JavaWizardPage(QWidget* parent = Q_NULLPTR); - virtual ~JavaWizardPage(){}; + virtual ~JavaWizardPage() {}; bool wantsRefreshButton() override; void refresh() override; diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 6ea73da60..18a480532 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -25,7 +25,7 @@ class JavaSettingsWidget : public QWidget { public: explicit JavaSettingsWidget(QWidget* parent); - virtual ~JavaSettingsWidget(){}; + virtual ~JavaSettingsWidget() {}; enum class JavaStatus { NotSet, Pending, Good, DoesNotExist, DoesNotStart, ReturnedInvalidData } javaStatus = JavaStatus::NotSet; diff --git a/launcher/ui/widgets/LanguageSelectionWidget.h b/launcher/ui/widgets/LanguageSelectionWidget.h index f034853dd..cf1f5bf3c 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.h +++ b/launcher/ui/widgets/LanguageSelectionWidget.h @@ -27,7 +27,7 @@ class LanguageSelectionWidget : public QWidget { Q_OBJECT public: explicit LanguageSelectionWidget(QWidget* parent = 0); - virtual ~LanguageSelectionWidget(){}; + virtual ~LanguageSelectionWidget() {}; QString getSelectedLanguageKey() const; void retranslate(); diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp index c77640654..83d8efa22 100644 --- a/launcher/updater/prismupdater/PrismUpdater.cpp +++ b/launcher/updater/prismupdater/PrismUpdater.cpp @@ -469,8 +469,7 @@ PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, ar target_dir = QDir(m_rootPath).absoluteFilePath(".."); } - QMetaObject::invokeMethod( - this, [this, target_dir]() { moveAndFinishUpdate(target_dir); }, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, [this, target_dir]() { moveAndFinishUpdate(target_dir); }, Qt::QueuedConnection); } else { QMetaObject::invokeMethod(this, &PrismUpdaterApp::loadReleaseList, Qt::QueuedConnection); diff --git a/nix/dev.nix b/nix/dev.nix index c476ed10f..cf61449a7 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -19,7 +19,7 @@ }; }; - tools.clang-tools = lib.mkForce pkgs.clang-tools_16; + tools.clang-tools = lib.mkForce pkgs.clang-tools_18; }; devShells.default = pkgs.mkShell { From bac678a7fc74b077990479adabb5f52017e0ed9d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 28 Jun 2024 12:54:37 +0300 Subject: [PATCH 64/64] format files outside launcher Signed-off-by: Trial97 --- libraries/murmur2/src/MurmurHash2.h | 5 +---- tests/ResourceFolderModel_test.cpp | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/murmur2/src/MurmurHash2.h b/libraries/murmur2/src/MurmurHash2.h index 233538556..e6c196fd1 100644 --- a/libraries/murmur2/src/MurmurHash2.h +++ b/libraries/murmur2/src/MurmurHash2.h @@ -24,10 +24,7 @@ class Reader { virtual void goToBeginning() = 0; }; -uint32_t hash( - Reader* file_stream, - std::size_t buffer_size = 4 * MiB, - std::function filter_out = [](char) { return false; }); +uint32_t hash(Reader* file_stream, std::size_t buffer_size = 4 * MiB, std::function filter_out = [](char) { return false; }); struct IncrementalHashInfo { uint32_t h; diff --git a/tests/ResourceFolderModel_test.cpp b/tests/ResourceFolderModel_test.cpp index 57c2cbdff..350ab615e 100644 --- a/tests/ResourceFolderModel_test.cpp +++ b/tests/ResourceFolderModel_test.cpp @@ -203,7 +203,10 @@ class ResourceFolderModelTest : public QObject { QCOMPARE(model.size(), 0); - { EXEC_UPDATE_TASK(model.installResource(folder_resource), QVERIFY) } { + { + EXEC_UPDATE_TASK(model.installResource(folder_resource), QVERIFY) + } + { EXEC_UPDATE_TASK(model.installResource(file_mod), QVERIFY) }