From e8ee4497f77a571b305a48b70f84c8729b800859 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 25 Dec 2022 23:39:38 +0100 Subject: [PATCH 001/429] store logs in sperate directory Signed-off-by: chmodsayshello --- launcher/Application.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index ff34a168d..f68e8792b 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -394,7 +394,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // init the logger { - static const QString logBase = BuildConfig.LAUNCHER_NAME + "-%0.log"; + static const QString logBase = "logs/"+BuildConfig.LAUNCHER_NAME + "-%0.log"; + QDir logDir = QDir(dataPath); + if(!logDir.exists("logs")) { + logDir.mkpath("logs"); //this can fail, but there is no need to throw an error *yet*, since it also triggers the error message below! + } auto moveFile = [](const QString &oldName, const QString &newName) { QFile::remove(newName); @@ -415,11 +419,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QString( "The launcher couldn't create a log file - the data folder is not writable.\n" "\n" - "Make sure you have write permissions to the data folder.\n" + "Make sure you have write permissions to the logs folder.\n" "(%1)\n" "\n" "The launcher cannot continue until you fix this problem." - ).arg(dataPath) + ).arg(dataPath+"/logs") ); return; } @@ -1666,6 +1670,7 @@ bool Application::handleDataMigration(const QString& currentData, matcher->add(std::make_shared(configFile)); matcher->add(std::make_shared( BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before + matcher->add(std::make_shared("logs/")); matcher->add(std::make_shared("accounts.json")); matcher->add(std::make_shared("accounts/")); matcher->add(std::make_shared("assets/")); From 6d5c629b4316fb37b1ca0705c17867d6d9c771bd Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 10 Apr 2023 00:04:35 +0300 Subject: [PATCH 002/429] Added dependencies to the APIs Signed-off-by: Trial97 --- launcher/modplatform/ModIndex.h | 9 ++++++ launcher/modplatform/flame/FlameModIndex.cpp | 30 ++++++++++++++++++- .../modrinth/ModrinthPackIndex.cpp | 21 ++++++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 40f1efc4e..ffa3a3ab8 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -32,6 +32,8 @@ enum class ResourceProvider { MODRINTH, FLAME }; enum class ResourceType { MOD, RESOURCE_PACK, SHADER_PACK }; +enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE }; + class ProviderCapabilities { public: auto name(ResourceProvider) -> const char*; @@ -51,6 +53,12 @@ struct DonationData { QString url; }; +struct Dependency { + QVariant addonId; + DependencyType type; + QString version; +}; + struct IndexedVersion { QVariant addonId; QVariant fileId; @@ -65,6 +73,7 @@ struct IndexedVersion { QString hash; bool is_preferred = true; QString changelog; + QList dependencies; // For internal use, not provided by APIs bool is_currently_selected = false; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 7498e8302..a820e3a1e 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -136,7 +136,35 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> } } - if(load_changelog) + auto dependencies = Json::ensureArray(obj, "dependencies"); + for (auto d : dependencies) { + auto dep = Json::ensureObject(d); + ModPlatform::Dependency dependency; + dependency.addonId = Json::requireInteger(dep, "modId"); + switch (Json::requireInteger(dep, "relationType")) { + case 1: // EmbeddedLibrary + dependency.type = ModPlatform::DependencyType::EMBEDDED; + break; + case 2: // OptionalDependency + dependency.type = ModPlatform::DependencyType::OPTIONAL; + break; + case 3: // RequiredDependency + dependency.type = ModPlatform::DependencyType::REQUIRED; + break; + case 4: // Tool + dependency.type = ModPlatform::DependencyType::TOOL; + break; + case 5: // Incompatible + dependency.type = ModPlatform::DependencyType::INCOMPATIBLE; + break; + case 6: // Include + dependency.type = ModPlatform::DependencyType::INCLUDE; + break; + } + file.dependencies.append(dependency); + } + + if (load_changelog) file.changelog = api.getModFileChangelog(file.addonId.toInt(), file.fileId.toInt()); return file; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 7ade131e4..8e97ee7cf 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -22,7 +22,6 @@ #include "Json.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "net/NetJob.h" static ModrinthAPI api; static ModPlatform::ProviderCapabilities ProviderCaps; @@ -140,6 +139,26 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t file.version_number = Json::requireString(obj, "version_number"); file.changelog = Json::requireString(obj, "changelog"); + auto dependencies = Json::ensureArray(obj, "dependencies"); + for (auto d : dependencies) { + auto dep = Json::ensureObject(d); + ModPlatform::Dependency dependency; + dependency.addonId = Json::requireString(dep, "project_id"); + dependency.version = Json::requireString(dep, "version_id"); + auto depType = Json::requireString(dep, "dependency_type"); + + if (depType == "required") + dependency.type = ModPlatform::DependencyType::REQUIRED; + else if (depType == "optional") + dependency.type = ModPlatform::DependencyType::OPTIONAL; + else if (depType == "incompatible") + dependency.type = ModPlatform::DependencyType::INCOMPATIBLE; + else if (depType == "embedded") + dependency.type = ModPlatform::DependencyType::EMBEDDED; + + file.dependencies.append(dependency); + } + auto files = Json::requireArray(obj, "files"); int i = 0; From d524935b6726c1a8d589d01abad4d262a55af149 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 11 Apr 2023 20:55:10 +0300 Subject: [PATCH 003/429] Added task to load local mod information Signed-off-by: Trial97 --- .../minecraft/mod/tasks/LocalModGetTask.cpp | 51 +++++++++++++++++++ .../minecraft/mod/tasks/LocalModGetTask.h | 46 +++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 launcher/minecraft/mod/tasks/LocalModGetTask.cpp create mode 100644 launcher/minecraft/mod/tasks/LocalModGetTask.h diff --git a/launcher/minecraft/mod/tasks/LocalModGetTask.cpp b/launcher/minecraft/mod/tasks/LocalModGetTask.cpp new file mode 100644 index 000000000..9c056d02a --- /dev/null +++ b/launcher/minecraft/mod/tasks/LocalModGetTask.cpp @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "LocalModGetTask.h" + +#include "FileSystem.h" +#include "minecraft/mod/MetadataHandler.h" + +#ifdef Q_OS_WIN32 +#include +#endif + +LocalModGetTask::LocalModGetTask(QDir index_dir, QVariant addonId) : m_index_dir(index_dir), m_addonId(addonId) +{ + // Ensure a '.index' folder exists in the mods folder, and create it if it does not + if (!FS::ensureFolderPathExists(index_dir.path())) { + emitFailed(QString("Unable to create index for modId %1!").arg(m_addonId.toString())); + } + +#ifdef Q_OS_WIN32 + SetFileAttributesW(index_dir.path().toStdWString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); +#endif +} + +void LocalModGetTask::executeTask() +{ + setStatus(tr("Updating index for modId:\n%1").arg(m_addonId.toString())); + emit getMod(Metadata::get(m_index_dir, m_addonId)); +} + +auto LocalModGetTask::abort() -> bool +{ + emitAborted(); + return true; +} diff --git a/launcher/minecraft/mod/tasks/LocalModGetTask.h b/launcher/minecraft/mod/tasks/LocalModGetTask.h new file mode 100644 index 000000000..5b7411226 --- /dev/null +++ b/launcher/minecraft/mod/tasks/LocalModGetTask.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 "minecraft/mod/MetadataHandler.h" +#include "tasks/Task.h" + +class LocalModGetTask : public Task { + Q_OBJECT + public: + using Ptr = shared_qobject_ptr; + + explicit LocalModGetTask(QDir index_dir, QVariant addonId); + + auto canAbort() const -> bool override { return true; } + auto abort() -> bool override; + + protected slots: + //! Entry point for tasks. + void executeTask() override; + + signals: + void getMod(Metadata::ModStruct); + + private: + QDir m_index_dir; + QVariant m_addonId; +}; From 4fbd5abe41ac10ecd28974ff857e9bce35c7d264 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Apr 2023 00:45:44 +0300 Subject: [PATCH 004/429] Added task to load dependencies Signed-off-by: Trial97 --- launcher/minecraft/mod/MetadataHandler.h | 57 ++++----- .../mod/tasks/GetModDependenciesTask.cpp | 116 ++++++++++++++++++ .../mod/tasks/GetModDependenciesTask.h | 63 ++++++++++ ...lModGetTask.cpp => LocalModGetAllTask.cpp} | 15 +-- ...LocalModGetTask.h => LocalModGetAllTask.h} | 9 +- launcher/modplatform/packwiz/Packwiz.cpp | 11 ++ launcher/modplatform/packwiz/Packwiz.h | 57 +++++---- 7 files changed, 254 insertions(+), 74 deletions(-) create mode 100644 launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp create mode 100644 launcher/minecraft/mod/tasks/GetModDependenciesTask.h rename launcher/minecraft/mod/tasks/{LocalModGetTask.cpp => LocalModGetAllTask.cpp} (73%) rename launcher/minecraft/mod/tasks/{LocalModGetTask.h => LocalModGetAllTask.h} (83%) diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 39723b49c..f7f08a79c 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -42,28 +42,15 @@ class Metadata { return Packwiz::V1::createModFormat(index_dir, internal_mod, mod_slug); } - static void update(QDir& index_dir, ModStruct& mod) - { - Packwiz::V1::updateModIndex(index_dir, mod); - } + static void update(QDir& index_dir, ModStruct& mod) { Packwiz::V1::updateModIndex(index_dir, mod); } - static void remove(QDir& index_dir, QString mod_slug) - { - Packwiz::V1::deleteModIndex(index_dir, mod_slug); - } + static void remove(QDir& index_dir, QString mod_slug) { Packwiz::V1::deleteModIndex(index_dir, mod_slug); } - static void remove(QDir& index_dir, QVariant& mod_id) - { - Packwiz::V1::deleteModIndex(index_dir, mod_id); - } + static void remove(QDir& index_dir, QVariant& mod_id) { Packwiz::V1::deleteModIndex(index_dir, mod_id); } - static auto get(QDir& index_dir, QString mod_slug) -> ModStruct - { - return Packwiz::V1::getIndexForMod(index_dir, mod_slug); - } + 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 get(QDir& index_dir, QVariant& mod_id) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_id); } + + static auto getAll(QDir& index_dir) -> QList { return Packwiz::V1::getAllMods(index_dir); } }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp new file mode 100644 index 000000000..dcff10289 --- /dev/null +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "GetModDependenciesTask.h" + +#include "QObjectPtr.h" +#include "minecraft/mod/MetadataHandler.h" +#include "minecraft/mod/tasks/LocalModGetAllTask.h" +#include "modplatform/ModIndex.h" +#include "tasks/ConcurrentTask.h" +#include "tasks/SequentialTask.h" + +#ifdef Q_OS_WIN32 +#include +#endif + +GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask& api) + : m_selected(selected), m_getDependenciesVersionAPI(api) +{ + m_getAllMods = makeShared(index_dir); + m_getNetworkDep = makeShared(this, "GetDepInfo"); + QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMod, [this](QList mods) { + m_mods = mods; + prepareDependecies(); + }); + +#ifdef Q_OS_WIN32 + SetFileAttributesW(index_dir.path().toStdWString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); +#endif +} + +void GetModDependenciesTask::executeTask() +{ + setStatus(tr("Geting all mods")); + m_getAllMods->start(); +} + +auto GetModDependenciesTask::abort() -> bool +{ + emitAborted(); + return true; +} + +void GetModDependenciesTask::prepareDependecies() +{ + auto c_dependencies = getDependenciesForVersions(m_selected); + if (c_dependencies.length() == 0) { + emitSucceeded(); + return; + } + for (auto dep : c_dependencies) { + auto task = m_getDependenciesVersionAPI( + dep, 20, [this](QList new_versions, int level) { addDependecies(new_versions, level - 1); }); + m_getNetworkDep->addTask(task); + } + m_getNetworkDep->start(); +} + +void GetModDependenciesTask::addDependecies(QList new_versions, int level) +{ + // some mutex? + m_dependencies.append(new_versions); + auto c_dependencies = getDependenciesForVersions(m_selected); + if (c_dependencies.length() == 0) { + return; + } + if (level == 0) { + qWarning() << "Dependency cycle exeeded"; + } + for (auto dep : c_dependencies) { + auto task = m_getDependenciesVersionAPI( + dep, 20, [this](QList new_versions, int level) { addDependecies(new_versions, level - 1); }); + m_getNetworkDep->addTask(task); + } +}; + +QList GetModDependenciesTask::getDependenciesForVersions(QList selected) +{ + auto c_dependencies = QList(); + for (auto version : selected) { + for (auto ver_dep : version.dependencies) { + if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { + if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), + [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + dep == c_dependencies.end()) { // check the current dependency list + c_dependencies.append(ver_dep); + } else if (auto dep = + std::find_if(selected.begin(), selected.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + dep == selected.end()) { // check the selected versions + c_dependencies.append(ver_dep); + } else if (auto dep = + std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + dep == m_mods.end()) { // check the existing mods + c_dependencies.append(ver_dep); + } + } + } + } + return c_dependencies; +}; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h new file mode 100644 index 000000000..28112bba2 --- /dev/null +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 "minecraft/mod/MetadataHandler.h" +#include "minecraft/mod/tasks/LocalModGetAllTask.h" +#include "modplatform/ModIndex.h" +#include "tasks/SequentialTask.h" +#include "tasks/Task.h" + +class GetModDependenciesTask : public Task { + Q_OBJECT + public: + using Ptr = shared_qobject_ptr; + using LocalModGetAllTaskPtr = shared_qobject_ptr; + + using NewDependecyVersionAPITask = + std::function, int)>)>; + + explicit GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask& api); + + auto canAbort() const -> bool override { return true; } + auto abort() -> bool override; + + protected slots: + //! Entry point for tasks. + void executeTask() override; + + void prepareDependecies(); + void addDependecies(QList, int); + QList getDependenciesForVersions(QList); + + signals: + void getAllMod(QList); + + private: + QList m_selected; + QList m_dependencies; + QList m_mods; + + LocalModGetAllTaskPtr m_getAllMods = nullptr; + NewDependecyVersionAPITask m_getDependenciesVersionAPI; + SequentialTask::Ptr m_getNetworkDep; +}; diff --git a/launcher/minecraft/mod/tasks/LocalModGetTask.cpp b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp similarity index 73% rename from launcher/minecraft/mod/tasks/LocalModGetTask.cpp rename to launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp index 9c056d02a..9e4293ff6 100644 --- a/launcher/minecraft/mod/tasks/LocalModGetTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -#include "LocalModGetTask.h" +#include "LocalModGetAllTask.h" #include "FileSystem.h" #include "minecraft/mod/MetadataHandler.h" @@ -26,11 +26,11 @@ #include #endif -LocalModGetTask::LocalModGetTask(QDir index_dir, QVariant addonId) : m_index_dir(index_dir), m_addonId(addonId) +LocalModGetAllTask::LocalModGetAllTask(QDir index_dir) : m_index_dir(index_dir) { // Ensure a '.index' folder exists in the mods folder, and create it if it does not if (!FS::ensureFolderPathExists(index_dir.path())) { - emitFailed(QString("Unable to create index for modId %1!").arg(m_addonId.toString())); + emitFailed(QString("Unable to create index for all mods!")); } #ifdef Q_OS_WIN32 @@ -38,13 +38,14 @@ LocalModGetTask::LocalModGetTask(QDir index_dir, QVariant addonId) : m_index_dir #endif } -void LocalModGetTask::executeTask() +void LocalModGetAllTask::executeTask() { - setStatus(tr("Updating index for modId:\n%1").arg(m_addonId.toString())); - emit getMod(Metadata::get(m_index_dir, m_addonId)); + setStatus(tr("Geting all mods")); + emit getAllMod(Metadata::getAll(m_index_dir)); + emitSucceeded(); } -auto LocalModGetTask::abort() -> bool +auto LocalModGetAllTask::abort() -> bool { emitAborted(); return true; diff --git a/launcher/minecraft/mod/tasks/LocalModGetTask.h b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h similarity index 83% rename from launcher/minecraft/mod/tasks/LocalModGetTask.h rename to launcher/minecraft/mod/tasks/LocalModGetAllTask.h index 5b7411226..09e453e4d 100644 --- a/launcher/minecraft/mod/tasks/LocalModGetTask.h +++ b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h @@ -23,12 +23,12 @@ #include "minecraft/mod/MetadataHandler.h" #include "tasks/Task.h" -class LocalModGetTask : public Task { +class LocalModGetAllTask : public Task { Q_OBJECT public: - using Ptr = shared_qobject_ptr; + using Ptr = shared_qobject_ptr; - explicit LocalModGetTask(QDir index_dir, QVariant addonId); + explicit LocalModGetAllTask(QDir index_dir); auto canAbort() const -> bool override { return true; } auto abort() -> bool override; @@ -38,9 +38,8 @@ class LocalModGetTask : public Task { void executeTask() override; signals: - void getMod(Metadata::ModStruct); + void getAllMod(QList); private: QDir m_index_dir; - QVariant m_addonId; }; diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 510c7309d..a2598b970 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "FileSystem.h" #include "StringUtils.h" @@ -311,4 +313,13 @@ auto V1::getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod return {}; } +auto V1::getAllMods(QDir& index_dir) -> QList +{ + auto files = index_dir.entryList(QDir::Filter::Files); + auto mods = QList(); + std::transform(files.begin(), files.end(), std::back_inserter(mods), + [index_dir](auto file_name) { return getIndexForMod(index_dir, file_name); }); + return mods; +} + } // namespace Packwiz diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 4b096eec7..2801f5d0f 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -36,22 +36,22 @@ auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool shoul class V1 { public: struct Mod { - QString slug {}; - QString name {}; - QString filename {}; + QString slug{}; + QString name{}; + QString filename{}; // FIXME: make side an enum - QString side {"both"}; + QString side{ "both" }; // [download] - QString mode {}; - QUrl url {}; - QString hash_format {}; - QString hash {}; + QString mode{}; + QUrl url{}; + QString hash_format{}; + QString hash{}; // [update] - ModPlatform::ResourceProvider provider {}; - QVariant file_id {}; - QVariant project_id {}; + ModPlatform::ResourceProvider provider{}; + QVariant file_id{}; + QVariant project_id{}; public: // This is a totally heuristic, but should work for now. @@ -93,6 +93,9 @@ class V1 { * If the mod doesn't have a metadata, it simply returns an empty Mod object. * */ static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod; + + /* Gets the metadata for all the mods */ + static auto getAllMods(QDir& index_dir) -> QList; }; -} // namespace Packwiz +} // namespace Packwiz From 11f8d25d94296aab13f885fde14ff26767082600 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Apr 2023 00:49:50 +0300 Subject: [PATCH 005/429] Added missing character Signed-off-by: Trial97 --- launcher/modplatform/packwiz/Packwiz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index a2598b970..33b5f364a 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -318,7 +318,7 @@ auto V1::getAllMods(QDir& index_dir) -> QList auto files = index_dir.entryList(QDir::Filter::Files); auto mods = QList(); std::transform(files.begin(), files.end(), std::back_inserter(mods), - [index_dir](auto file_name) { return getIndexForMod(index_dir, file_name); }); + [&index_dir](auto file_name) { return getIndexForMod(index_dir, file_name); }); return mods; } From 87db723008727b32681f5a2a39b20497bc5fb34e Mon Sep 17 00:00:00 2001 From: Tayou Date: Tue, 18 Apr 2023 20:25:45 +0200 Subject: [PATCH 006/429] add global .editorconfig for doxygen comment style Signed-off-by: Tayou --- .editorconfig | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..a6521c873 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +# Visual Studio generated .editorconfig file with C++ settings. +root = true + +[*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}] + +# Visual C++ Code Style settings + +cpp_generate_documentation_comments = doxygen_triple_slash From 5655a3351551aa36aeeba79b0ac7f2474ca74352 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Apr 2023 18:59:31 +0300 Subject: [PATCH 007/429] Added Dependency API Signed-off-by: Trial97 --- launcher/modplatform/ResourceAPI.h | 24 +++++++++ launcher/modplatform/flame/FlameAPI.h | 15 ++++-- .../helpers/NetworkResourceAPI.cpp | 49 ++++++++++++++----- .../modplatform/helpers/NetworkResourceAPI.h | 2 + launcher/modplatform/modrinth/ModrinthAPI.h | 35 ++++++------- 5 files changed, 93 insertions(+), 32 deletions(-) diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index 34f337791..a8e144dc8 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -111,6 +111,24 @@ class ResourceAPI { std::function on_succeed; }; + struct DependencySearchArgs { + ModPlatform::Dependency dependency; + Version mcVersion; + ModLoaderTypes loader; + + DependencySearchArgs(DependencySearchArgs const&) = default; + void operator=(DependencySearchArgs other) + { + dependency = other.dependency; + mcVersion = other.mcVersion; + loader = other.loader; + } + }; + + struct DependencySearchCallbacks { + std::function on_succeed; + }; + public: /** Gets a list of available sorting methods for this API. */ [[nodiscard]] virtual auto getSortingMethods() const -> QList = 0; @@ -143,6 +161,12 @@ class ResourceAPI { return nullptr; } + [[nodiscard]] virtual Task::Ptr getDependencyVersion(DependencySearchArgs&&, DependencySearchCallbacks&&) const + { + qWarning() << "TODO"; + return nullptr; + } + static auto getModLoaderString(ModLoaderType type) -> const QString { switch (type) { diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 5811d7175..91993e64c 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -41,14 +41,15 @@ class FlameAPI : public NetworkResourceAPI { return 4; // TODO: remove this once Quilt drops official Fabric support if (loaders & Quilt) // NOTE: Most if not all Fabric mods should work *currently* - return 4; // Quilt would probably be 5 + return 4; // Quilt would probably be 5 return 0; } private: [[nodiscard]] std::optional getSearchURL(SearchArgs const& args) const override { - auto gameVersionStr = args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString(); + auto gameVersionStr = + args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString(); QStringList get_arguments; get_arguments.append(QString("classId=%1").arg(getClassId(args.type))); @@ -73,7 +74,7 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getVersionsURL(VersionSearchArgs const& args) const override { - QString url{QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString())}; + QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString()) }; QStringList get_parameters; if (args.mcVersions.has_value()) @@ -83,4 +84,12 @@ class FlameAPI : public NetworkResourceAPI { return url + get_parameters.join('&'); }; + + [[nodiscard]] std::optional getDependecyURL(DependencySearchArgs const& args) const override + { + return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%") + .arg(args.dependency.addonId.toString()) + .arg(args.mcVersion.toString()) + .arg(getMappedModLoader(args.loader)); + }; }; diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.cpp b/launcher/modplatform/helpers/NetworkResourceAPI.cpp index 010ac15e9..a7f763d36 100644 --- a/launcher/modplatform/helpers/NetworkResourceAPI.cpp +++ b/launcher/modplatform/helpers/NetworkResourceAPI.cpp @@ -24,7 +24,7 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks& netJob->addNetAction(Net::Download::makeByteArray(QUrl(search_url), response)); - QObject::connect(netJob.get(), &NetJob::succeeded, [=]{ + QObject::connect(netJob.get(), &NetJob::succeeded, [=] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -40,16 +40,14 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks& callbacks.on_succeed(doc); }); - QObject::connect(netJob.get(), &NetJob::failed, [=](QString reason){ + QObject::connect(netJob.get(), &NetJob::failed, [=](QString reason) { int network_error_code = -1; if (auto* failed_action = netJob->getFailedActions().at(0); failed_action && failed_action->m_reply) network_error_code = failed_action->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - callbacks.on_fail(reason, network_error_code); - }); - QObject::connect(netJob.get(), &NetJob::aborted, [=]{ - callbacks.on_abort(); + callbacks.on_fail(reason, network_error_code); }); + QObject::connect(netJob.get(), &NetJob::aborted, [=] { callbacks.on_abort(); }); return netJob; } @@ -101,9 +99,7 @@ Task::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Versi callbacks.on_succeed(doc, args.pack); }); - QObject::connect(netJob.get(), &NetJob::finished, [response] { - delete response; - }); + QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); return netJob; } @@ -120,9 +116,38 @@ Task::Ptr NetworkResourceAPI::getProject(QString addonId, QByteArray* response) netJob->addNetAction(Net::Download::makeByteArray(QUrl(project_url), response)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { - delete response; - }); + QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); return netJob; } + +Task::Ptr NetworkResourceAPI::getDependencyVersion(DependencySearchArgs&& args, DependencySearchCallbacks&& callbacks) const +{ + auto versions_url_optional = getDependecyURL(args); + if (!versions_url_optional.has_value()) + return nullptr; + + auto versions_url = versions_url_optional.value(); + + auto netJob = makeShared(QString("%1::Dependecy").arg(args.dependency.addonId.toString()), APPLICATION->network()); + auto response = new QByteArray(); + + netJob->addNetAction(Net::Download::makeByteArray(versions_url, response)); + + QObject::connect(netJob.get(), &NetJob::succeeded, [=] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response for getting versions at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + callbacks.on_succeed(doc, args.dependency); + }); + + QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); + + return netJob; +}; diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.h b/launcher/modplatform/helpers/NetworkResourceAPI.h index 94813bec8..bbe0a2c76 100644 --- a/launcher/modplatform/helpers/NetworkResourceAPI.h +++ b/launcher/modplatform/helpers/NetworkResourceAPI.h @@ -14,9 +14,11 @@ class NetworkResourceAPI : public ResourceAPI { Task::Ptr getProjectInfo(ProjectInfoArgs&&, ProjectInfoCallbacks&&) const override; Task::Ptr getProjectVersions(VersionSearchArgs&&, VersionSearchCallbacks&&) const override; + Task::Ptr getDependencyVersion(DependencySearchArgs&&, DependencySearchCallbacks&&) const override; protected: [[nodiscard]] virtual auto getSearchURL(SearchArgs const& args) const -> std::optional = 0; [[nodiscard]] virtual auto getInfoURL(QString const& id) const -> std::optional = 0; [[nodiscard]] virtual auto getVersionsURL(VersionSearchArgs const& args) const -> std::optional = 0; + [[nodiscard]] virtual auto getDependecyURL(DependencySearchArgs const& args) const -> std::optional = 0; }; diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index b91ac5c14..2d6049bae 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -12,13 +12,9 @@ class ModrinthAPI : public NetworkResourceAPI { public: - auto currentVersion(QString hash, - QString hash_format, - QByteArray* response) -> Task::Ptr; + auto currentVersion(QString hash, QString hash_format, QByteArray* response) -> Task::Ptr; - auto currentVersions(const QStringList& hashes, - QString hash_format, - QByteArray* response) -> Task::Ptr; + auto currentVersions(const QStringList& hashes, QString hash_format, QByteArray* response) -> Task::Ptr; auto latestVersion(QString hash, QString hash_format, @@ -28,8 +24,8 @@ class ModrinthAPI : public NetworkResourceAPI { auto latestVersions(const QStringList& hashes, QString hash_format, - std::optional> mcVersions, - std::optional loaders, + std::optional> mcVersions, + std::optional loaders, QByteArray* response) -> Task::Ptr; Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const override; @@ -42,7 +38,7 @@ class ModrinthAPI : public NetworkResourceAPI { static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList { QStringList l; - for (auto loader : {Forge, Fabric, Quilt}) { + for (auto loader : { Forge, Fabric, Quilt }) { if (types & loader) { l << getModLoaderString(loader); } @@ -55,8 +51,7 @@ class ModrinthAPI : public NetworkResourceAPI { static auto getModLoaderFilters(ModLoaderTypes types) -> const QString { QStringList l; - for (auto loader : getModLoaderStrings(types)) - { + for (auto loader : getModLoaderStrings(types)) { l << QString("\"categories:%1\"").arg(loader); } return l.join(','); @@ -139,16 +134,22 @@ class ModrinthAPI : public NetworkResourceAPI { auto getGameVersionsArray(std::list mcVersions) const -> QString { QString s; - for(auto& ver : mcVersions){ + for (auto& ver : mcVersions) { s += QString("\"versions:%1\",").arg(ver.toString()); } - s.remove(s.length() - 1, 1); //remove last comma + s.remove(s.length() - 1, 1); // remove last comma return s.isEmpty() ? QString() : s; } - inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool - { - return loaders & (Forge | Fabric | Quilt); - } + inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool { return loaders & (Forge | Fabric | Quilt); } + [[nodiscard]] std::optional getDependecyURL(DependencySearchArgs const& args) const override + { + return args.dependency.version.length() != 0 ? QString("%1/version/%2").arg(BuildConfig.MODRINTH_PROD_URL, args.dependency.version) + : QString("%1/project/%2/version?game_versions=[\"%1\"]&loaders=[\"%1\"]") + .arg(BuildConfig.MODRINTH_PROD_URL) + .arg(args.dependency.addonId.toString()) + .arg(args.mcVersion.toString()) + .arg(getModLoaderStrings(args.loader).join("\",\"")); + }; }; From 4fe497cd682258ca80501be2ad616de7a40043d9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Apr 2023 23:02:33 +0300 Subject: [PATCH 008/429] First working version with curseforge mods Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 4 ++ launcher/ResourceDownloadTask.h | 51 +++++++++--------- .../mod/tasks/GetModDependenciesTask.cpp | 54 +++++++++++++------ .../mod/tasks/GetModDependenciesTask.h | 16 +++--- launcher/modplatform/flame/FlameModIndex.cpp | 48 ++++++++++++----- launcher/modplatform/flame/FlameModIndex.h | 6 +-- launcher/modplatform/flame/FlamePackIndex.h | 10 ++-- .../modrinth/ModrinthPackIndex.cpp | 19 +++++++ .../modplatform/modrinth/ModrinthPackIndex.h | 3 +- .../ui/dialogs/ResourceDownloadDialog.cpp | 40 +++++++++++--- launcher/ui/pages/modplatform/ModModel.cpp | 16 +++++- launcher/ui/pages/modplatform/ModModel.h | 2 + .../ui/pages/modplatform/ResourceModel.cpp | 39 ++++++++++++++ launcher/ui/pages/modplatform/ResourceModel.h | 8 +++ .../ui/pages/modplatform/ResourcePackModel.h | 1 + .../ui/pages/modplatform/ResourcePage.cpp | 5 ++ launcher/ui/pages/modplatform/ResourcePage.h | 5 +- .../ui/pages/modplatform/ShaderPackModel.h | 1 + .../modplatform/flame/FlameResourceModels.cpp | 17 +++++- .../modplatform/flame/FlameResourceModels.h | 3 ++ .../modrinth/ModrinthResourceModels.cpp | 26 +++++++-- .../modrinth/ModrinthResourceModels.h | 4 ++ 22 files changed, 293 insertions(+), 85 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 074570e31..fca8c9144 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -359,6 +359,10 @@ set(MINECRAFT_SOURCES minecraft/mod/tasks/LocalWorldSaveParseTask.cpp minecraft/mod/tasks/LocalResourceParse.h minecraft/mod/tasks/LocalResourceParse.cpp + minecraft/mod/tasks/GetModDependenciesTask.h + minecraft/mod/tasks/GetModDependenciesTask.cpp + minecraft/mod/tasks/LocalModGetAllTask.h + minecraft/mod/tasks/LocalModGetAllTask.cpp # Assets minecraft/AssetsUtils.h diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index 73ad2d070..f2118524a 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -1,41 +1,45 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* Prism Launcher - Minecraft Launcher -* Copyright (c) 2022-2023 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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 . -*/ + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022-2023 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "net/NetJob.h" #include "tasks/SequentialTask.h" -#include "modplatform/ModIndex.h" #include "minecraft/mod/tasks/LocalModUpdateTask.h" +#include "modplatform/ModIndex.h" class ResourceFolderModel; class ResourceDownloadTask : public SequentialTask { Q_OBJECT -public: - explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr packs, bool is_indexed = true); + public: + explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, + ModPlatform::IndexedVersion version, + const std::shared_ptr packs, + bool is_indexed = true); const QString& getFilename() const { return m_pack_version.fileName; } const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } + const ModPlatform::IndexedVersion& getVersion() const { return m_pack_version; } -private: + private: ModPlatform::IndexedPack m_pack; ModPlatform::IndexedVersion m_pack_version; const std::shared_ptr m_pack_model; @@ -47,11 +51,8 @@ private: void downloadFailed(QString reason); void downloadSucceeded(); - std::tuple to_delete {"", ""}; + std::tuple to_delete{ "", "" }; -private slots: + private slots: void hasOldResource(QString name, QString filename); }; - - - diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index dcff10289..9cc227f2e 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -30,11 +30,12 @@ #include #endif -GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask& api) +GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask api) : m_selected(selected), m_getDependenciesVersionAPI(api) { m_getAllMods = makeShared(index_dir); m_getNetworkDep = makeShared(this, "GetDepInfo"); + connect(m_getNetworkDep.get(), &Task::finished, &loop, &QEventLoop::quit); QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMod, [this](QList mods) { m_mods = mods; prepareDependecies(); @@ -49,6 +50,8 @@ void GetModDependenciesTask::executeTask() { setStatus(tr("Geting all mods")); m_getAllMods->start(); + loop.exec(); + emitSucceeded(); } auto GetModDependenciesTask::abort() -> bool @@ -61,22 +64,21 @@ void GetModDependenciesTask::prepareDependecies() { auto c_dependencies = getDependenciesForVersions(m_selected); if (c_dependencies.length() == 0) { - emitSucceeded(); + m_getNetworkDep->start(); return; } for (auto dep : c_dependencies) { - auto task = m_getDependenciesVersionAPI( - dep, 20, [this](QList new_versions, int level) { addDependecies(new_versions, level - 1); }); + auto task = m_getDependenciesVersionAPI(dep, [this](ModPlatform::IndexedVersion new_version) { addDependecies(new_version, 20); }); m_getNetworkDep->addTask(task); } m_getNetworkDep->start(); } -void GetModDependenciesTask::addDependecies(QList new_versions, int level) +void GetModDependenciesTask::addDependecies(ModPlatform::IndexedVersion new_version, int level) { // some mutex? - m_dependencies.append(new_versions); - auto c_dependencies = getDependenciesForVersions(m_selected); + m_dependencies.append(new_version); + auto c_dependencies = getDependenciesForVersion(new_version); if (c_dependencies.length() == 0) { return; } @@ -85,7 +87,7 @@ void GetModDependenciesTask::addDependecies(QList n } for (auto dep : c_dependencies) { auto task = m_getDependenciesVersionAPI( - dep, 20, [this](QList new_versions, int level) { addDependecies(new_versions, level - 1); }); + dep, [this, level](ModPlatform::IndexedVersion new_versions) { addDependecies(new_versions, level - 1); }); m_getNetworkDep->addTask(task); } }; @@ -99,18 +101,36 @@ QList GetModDependenciesTask::getDependenciesForVersion if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); dep == c_dependencies.end()) { // check the current dependency list - c_dependencies.append(ver_dep); - } else if (auto dep = - std::find_if(selected.begin(), selected.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); - dep == selected.end()) { // check the selected versions - c_dependencies.append(ver_dep); - } else if (auto dep = - std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); - dep == m_mods.end()) { // check the existing mods - c_dependencies.append(ver_dep); + if (auto dep = + std::find_if(selected.begin(), selected.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + dep == selected.end()) { // check the selected versions + if (auto dep = + std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + dep == m_mods.end()) { // check the existing mods + c_dependencies.append(ver_dep); + } + } } } } } return c_dependencies; }; + +QList GetModDependenciesTask::getDependenciesForVersion(ModPlatform::IndexedVersion version) +{ + auto c_dependencies = QList(); + for (auto ver_dep : version.dependencies) { + if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { + if (auto dep = + std::find_if(c_dependencies.begin(), c_dependencies.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + dep == c_dependencies.end()) { // check the current dependency list + if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + dep == m_mods.end()) { // check the existing mods + c_dependencies.append(ver_dep); + } + } + } + } + return c_dependencies; +}; \ No newline at end of file diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 28112bba2..4353c1e1f 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -18,6 +18,8 @@ #pragma once +#include +#include #include #include @@ -33,24 +35,23 @@ class GetModDependenciesTask : public Task { using Ptr = shared_qobject_ptr; using LocalModGetAllTaskPtr = shared_qobject_ptr; - using NewDependecyVersionAPITask = - std::function, int)>)>; + using NewDependecyVersionAPITask = std::function)>; - explicit GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask& api); + explicit GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask api); auto canAbort() const -> bool override { return true; } auto abort() -> bool override; + auto getDependecies() const -> QList { return m_dependencies; } + protected slots: //! Entry point for tasks. void executeTask() override; void prepareDependecies(); - void addDependecies(QList, int); + void addDependecies(ModPlatform::IndexedVersion, int); QList getDependenciesForVersions(QList); - - signals: - void getAllMod(QList); + QList getDependenciesForVersion(ModPlatform::IndexedVersion); private: QList m_selected; @@ -60,4 +61,5 @@ class GetModDependenciesTask : public Task { LocalModGetAllTaskPtr m_getAllMods = nullptr; NewDependecyVersionAPITask m_getDependenciesVersionAPI; SequentialTask::Ptr m_getNetworkDep; + QEventLoop loop; }; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index a820e3a1e..38ecb9ab9 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -39,15 +39,15 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj) auto links_obj = Json::ensureObject(obj, "links"); pack.extraData.issuesUrl = Json::ensureString(links_obj, "issuesUrl"); - if(pack.extraData.issuesUrl.endsWith('/')) + if (pack.extraData.issuesUrl.endsWith('/')) pack.extraData.issuesUrl.chop(1); pack.extraData.sourceUrl = Json::ensureString(links_obj, "sourceUrl"); - if(pack.extraData.sourceUrl.endsWith('/')) + if (pack.extraData.sourceUrl.endsWith('/')) pack.extraData.sourceUrl.chop(1); pack.extraData.wikiUrl = Json::ensureString(links_obj, "wikiUrl"); - if(pack.extraData.wikiUrl.endsWith('/')) + if (pack.extraData.wikiUrl.endsWith('/')) pack.extraData.wikiUrl.chop(1); if (!pack.extraData.body.isEmpty()) @@ -56,7 +56,7 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj) void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj) { - pack.extraData.body = api.getModDescription(pack.addonId.toInt()); + pack.extraData.body = api.getModDescription(pack.addonId.toInt()); if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty()) pack.extraDataLoaded = true; @@ -64,12 +64,12 @@ void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj) static QString enumToString(int hash_algorithm) { - switch(hash_algorithm){ - default: - case 1: - return "sha1"; - case 2: - return "md5"; + switch (hash_algorithm) { + default: + case 1: + return "sha1"; + case 2: + return "md5"; } } @@ -84,12 +84,12 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, for (auto versionIter : arr) { auto obj = versionIter.toObject(); - + auto file = loadIndexedPackVersion(obj); - if(!file.addonId.isValid()) + if (!file.addonId.isValid()) file.addonId = pack.addonId; - if(file.fileId.isValid()) // 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); } @@ -169,3 +169,25 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> return file; } + +ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) +{ + QVector unsortedVersions; + for (auto versionIter : arr) { + auto obj = versionIter.toObject(); + + auto file = loadIndexedPackVersion(obj); + if (!file.addonId.isValid()) + file.addonId = m.addonId; + + 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 { + // dates are in RFC 3339 format + return a.date > b.date; + }; + std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + return unsortedVersions.front(); +}; diff --git a/launcher/modplatform/flame/FlameModIndex.h b/launcher/modplatform/flame/FlameModIndex.h index 33c4a5298..306959e00 100644 --- a/launcher/modplatform/flame/FlameModIndex.h +++ b/launcher/modplatform/flame/FlameModIndex.h @@ -6,8 +6,8 @@ #include "modplatform/ModIndex.h" -#include "BaseInstance.h" #include +#include "BaseInstance.h" namespace FlameMod { @@ -19,5 +19,5 @@ void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, const shared_qobject_ptr& network, const BaseInstance* inst); auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion; - -} // namespace FlameMod +auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion; +} // namespace FlameMod \ No newline at end of file diff --git a/launcher/modplatform/flame/FlamePackIndex.h b/launcher/modplatform/flame/FlamePackIndex.h index 1ca0fc0e5..b089b722c 100644 --- a/launcher/modplatform/flame/FlamePackIndex.h +++ b/launcher/modplatform/flame/FlamePackIndex.h @@ -4,6 +4,7 @@ #include #include #include +#include "modplatform/ModIndex.h" namespace Flame { @@ -27,8 +28,7 @@ struct ModpackExtra { QString sourceUrl; }; -struct IndexedPack -{ +struct IndexedPack { int addonId; QString name; QString description; @@ -43,9 +43,9 @@ struct IndexedPack ModpackExtra extra; }; -void loadIndexedPack(IndexedPack & m, QJsonObject & obj); +void loadIndexedPack(IndexedPack& m, QJsonObject& obj); void loadIndexedInfo(IndexedPack&, QJsonObject&); -void loadIndexedPackVersions(IndexedPack & m, QJsonArray & arr); -} +void loadIndexedPackVersions(IndexedPack& m, QJsonArray& arr); +} // namespace Flame Q_DECLARE_METATYPE(Flame::IndexedPack) diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 8e97ee7cf..9f898c393 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -214,3 +214,22 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t return {}; } + +auto Modrinth::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + QVector unsortedVersions; + + for (auto versionIter : arr) { + auto obj = versionIter.toObject(); + auto file = loadIndexedPackVersion(obj); + + 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 { + // dates are in RFC 3339 format + return a.date > b.date; + }; + std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + return unsortedVersions.front(); +} \ No newline at end of file diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index e73e4b186..8aa53a116 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -19,8 +19,8 @@ #include "modplatform/ModIndex.h" -#include "BaseInstance.h" #include +#include "BaseInstance.h" namespace Modrinth { @@ -31,5 +31,6 @@ void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, const shared_qobject_ptr& network, const BaseInstance* inst); auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion; +auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion; } // namespace Modrinth diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index edb7d063c..e1041d952 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -18,17 +18,22 @@ */ #include "ResourceDownloadDialog.h" +#include +#include #include +#include +#include #include "Application.h" #include "ResourceDownloadTask.h" #include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ResourcePackFolderModel.h" -#include "minecraft/mod/TexturePackFolderModel.h" #include "minecraft/mod/ShaderPackFolderModel.h" +#include "minecraft/mod/TexturePackFolderModel.h" +#include "modplatform/ModIndex.h" #include "ui/dialogs/ReviewMessageBox.h" #include "ui/pages/modplatform/ResourcePage.h" @@ -41,7 +46,10 @@ namespace ResourceDownload { ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent, const std::shared_ptr base_model) - : QDialog(parent), m_base_model(base_model), m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel), m_vertical_layout(this) + : QDialog(parent) + , m_base_model(base_model) + , m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel) + , m_vertical_layout(this) { setObjectName(QStringLiteral("ResourceDownloadDialog")); @@ -102,7 +110,8 @@ void ResourceDownloadDialog::initializeContainer() void ResourceDownloadDialog::connectButtons() { auto OkButton = m_buttons.button(QDialogButtonBox::Ok); - OkButton->setToolTip(tr("Opens a new popup to review your selected %1 and confirm your selection. Shortcut: Ctrl+Return").arg(resourcesString())); + OkButton->setToolTip( + tr("Opens a new popup to review your selected %1 and confirm your selection. Shortcut: Ctrl+Return").arg(resourcesString())); connect(OkButton, &QPushButton::clicked, this, &ResourceDownloadDialog::confirm); auto CancelButton = m_buttons.button(QDialogButtonBox::Cancel); @@ -120,6 +129,26 @@ void ResourceDownloadDialog::confirm() auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString())); confirm_dialog->retranslateUi(resourcesString()); + if (auto model = dynamic_cast(getBaseModel().get()); model) { + QList selectedVers; + for (auto& task : keys) { + auto selected = m_selected.constFind(task).value(); + selectedVers.append(selected->getVersion()); + } + + auto dir = model->indexDir(); + auto dependencies = m_selectedPage->getDependecies(dir, selectedVers); + + for (auto dep : dependencies) { + dep.is_currently_selected = true; + auto pack = ModPlatform::IndexedPack{ + .addonId = dep.addonId, .provider = ModPlatform::ResourceProvider::FLAME, .name = dep.fileName, .slug = dep.fileName + }; + m_selected.insert(dep.fileName, makeShared(pack, dep, getBaseModel(), true)); + } + + keys = m_selected.keys(); + } for (auto& task : keys) { auto selected = m_selected.constFind(task).value(); confirm_dialog->appendResource({ task, selected->getFilename(), selected->getCustomPath() }); @@ -205,8 +234,6 @@ void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* s m_selectedPage->setSearchTerm(prev_page->getSearchTerm()); } - - ModDownloadDialog::ModDownloadDialog(QWidget* parent, const std::shared_ptr& mods, BaseInstance* instance) : ResourceDownloadDialog(parent, mods), m_instance(instance) { @@ -232,7 +259,6 @@ QList ModDownloadDialog::getPages() return pages; } - ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent, const std::shared_ptr& resource_packs, BaseInstance* instance) @@ -258,7 +284,6 @@ QList ResourcePackDownloadDialog::getPages() return pages; } - TexturePackDownloadDialog::TexturePackDownloadDialog(QWidget* parent, const std::shared_ptr& resource_packs, BaseInstance* instance) @@ -284,7 +309,6 @@ QList TexturePackDownloadDialog::getPages() return pages; } - ShaderPackDownloadDialog::ShaderPackDownloadDialog(QWidget* parent, const std::shared_ptr& shaders, BaseInstance* instance) diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 3ffe6cb06..bdbfe4609 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -24,7 +24,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() std::optional> versions{}; - { // Version filter + { // Version filter if (!m_filter->versions.empty()) versions = m_filter->versions; } @@ -49,6 +49,20 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en return { pack, versions, profile->getModLoaders() }; } +ResourceAPI::DependencySearchArgs ModModel::createDependecyArguments(ModPlatform::Dependency& dep) +{ + auto profile = static_cast(m_base_instance).getPackProfile(); + + Q_ASSERT(profile); + Q_ASSERT(m_filter); + + std::optional> versions{}; + if (!m_filter->versions.empty()) + versions = m_filter->versions; + + return { dep, versions->front(), profile->getModLoaders().value() }; +}; + ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(QModelIndex& entry) { auto& pack = m_packs[entry.row()]; diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 5d4a77859..ca536f8f8 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -32,6 +32,7 @@ class ModModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override = 0; + ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) override = 0; void setFilter(std::shared_ptr filter) { m_filter = filter; } @@ -39,6 +40,7 @@ class ModModel : public ResourceModel { ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override; + ResourceAPI::DependencySearchArgs createDependecyArguments(ModPlatform::Dependency&) override; protected: auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index db7d26f86..42dd8daed 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -3,6 +3,8 @@ // SPDX-License-Identifier: GPL-3.0-only #include "ResourceModel.h" +#include +#include #include #include @@ -14,6 +16,7 @@ #include "BuildConfig.h" #include "Json.h" +#include "minecraft/mod/tasks/GetModDependenciesTask.h" #include "net/Download.h" #include "net/NetJob.h" @@ -321,6 +324,11 @@ void ResourceModel::loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArra { NEED_FOR_CALLBACK_ASSERT("loadIndexedPackVersions"); } +ModPlatform::IndexedVersion ResourceModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) +{ + NEED_FOR_CALLBACK_ASSERT("loadDependencyVersions"); + return {}; +} /* Default callbacks */ @@ -441,4 +449,35 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe emit projectInfoUpdated(); } +QList ResourceModel::getDependecies(QDir& dir, QList selected) +{ + auto task = new GetModDependenciesTask( + dir, selected, [this](ModPlatform::Dependency dependency, std::function succeeded) -> Task::Ptr { + auto args{ createDependecyArguments(dependency) }; + auto callbacks{ createDependecyCallbacks() }; + + // Use default if no callbacks are set + if (!callbacks.on_succeed) + callbacks.on_succeed = [this, dependency, succeeded](auto& doc, auto pack) { + ModPlatform::IndexedVersion ver; + try { + auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); + ver = loadDependencyVersions(dependency, arr); + } catch (const JSONValidationError& e) { + qDebug() << doc; + qWarning() << "Error while reading " << debugName() << " resource version: " << e.cause(); + return; + } + + succeeded(ver); + }; + + return m_api->getDependencyVersion(std::move(args), std::move(callbacks)); + }); + + task->start(); + + return task->getDependecies(); +}; + } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 46a02d6ef..0292b84b8 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -4,12 +4,14 @@ #pragma once +#include #include #include #include "QObjectPtr.h" +#include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" #include "tasks/ConcurrentTask.h" @@ -68,6 +70,9 @@ class ResourceModel : public QAbstractListModel { virtual ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) = 0; virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) { return {}; } + virtual ResourceAPI::DependencySearchArgs createDependecyArguments(ModPlatform::Dependency&) { return {}; }; + virtual ResourceAPI::DependencySearchCallbacks createDependecyCallbacks() { return {}; } + /** Requests the API for more entries. */ virtual void search(); @@ -80,6 +85,8 @@ class ResourceModel : public QAbstractListModel { /** Gets the icon at the URL for the given index. If it's not fetched yet, fetch it and update when fisinhed. */ std::optional getIcon(QModelIndex&, const QUrl&); + QList getDependecies(QDir& dir, QList m_selected); + protected: /** Resets the model's data. */ void clearData(); @@ -104,6 +111,7 @@ class ResourceModel : public QAbstractListModel { virtual void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&); + virtual ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr); protected: /* Basic search parameters */ diff --git a/launcher/ui/pages/modplatform/ResourcePackModel.h b/launcher/ui/pages/modplatform/ResourcePackModel.h index e2b4a1957..40b271d63 100644 --- a/launcher/ui/pages/modplatform/ResourcePackModel.h +++ b/launcher/ui/pages/modplatform/ResourcePackModel.h @@ -28,6 +28,7 @@ class ResourcePackResourceModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0; + ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) override = 0; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index bbd465bc1..ec43521fb 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -408,4 +408,9 @@ void ResourcePage::openUrl(const QUrl& url) QDesktopServices::openUrl(url); } +QList ResourcePage::getDependecies(QDir& dir, QList selected) +{ + return m_model->getDependecies(dir, selected); +}; + } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 1896d53ea..07f87929a 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include @@ -75,9 +76,11 @@ class ResourcePage : public QWidget, public BasePage { virtual void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); virtual void removeResourceFromDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); + QList getDependecies(QDir& dir, QList m_selected); + protected slots: virtual void triggerSearch() {} - + void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); void onResourceSelected(); diff --git a/launcher/ui/pages/modplatform/ShaderPackModel.h b/launcher/ui/pages/modplatform/ShaderPackModel.h index f3c695e9f..60d74777c 100644 --- a/launcher/ui/pages/modplatform/ShaderPackModel.h +++ b/launcher/ui/pages/modplatform/ShaderPackModel.h @@ -28,6 +28,7 @@ class ShaderPackResourceModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0; + ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) override = 0; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp index e3d0bc144..563ff9638 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp @@ -29,6 +29,11 @@ void FlameModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonAr FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +auto FlameModModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return FlameMod::loadDependencyVersions(m, arr); +}; + auto FlameModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); @@ -52,6 +57,11 @@ void FlameResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +auto FlameResourcePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return FlameMod::loadDependencyVersions(m, arr); +}; + auto FlameResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); @@ -81,13 +91,18 @@ void FlameTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, auto const& mc_versions = version.mcVersion; if (std::any_of(mc_versions.constBegin(), mc_versions.constEnd(), - [this](auto const& mc_version){ return Version(mc_version) <= maximumTexturePackVersion(); })) + [this](auto const& mc_version) { return Version(mc_version) <= maximumTexturePackVersion(); })) filtered_versions.push_back(version); } m.versions = filtered_versions; } +auto FlameTexturePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return FlameMod::loadDependencyVersions(m, arr); +}; + ResourceAPI::SearchArgs FlameTexturePackModel::createSearchArguments() { auto args = TexturePackResourceModel::createSearchArguments(); diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h index 0252ac403..2f4413acf 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h @@ -24,6 +24,7 @@ class FlameModModel : public ModModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -42,6 +43,7 @@ class FlameResourcePackModel : public ResourcePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -60,6 +62,7 @@ class FlameTexturePackModel : public TexturePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp index f5d1cc282..047e3aaaa 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp @@ -42,12 +42,17 @@ void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJso ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +auto ModrinthModModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return ::Modrinth::loadDependencyVersions(m, arr); +}; + auto ModrinthModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); } -ModrinthResourcePackModel::ModrinthResourcePackModel(const BaseInstance& base) : ResourcePackResourceModel(base, new ModrinthAPI){} +ModrinthResourcePackModel::ModrinthResourcePackModel(const BaseInstance& base) : ResourcePackResourceModel(base, new ModrinthAPI) {} void ModrinthResourcePackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) { @@ -64,12 +69,17 @@ void ModrinthResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +auto ModrinthResourcePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return ::Modrinth::loadDependencyVersions(m, arr); +}; + auto ModrinthResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); } -ModrinthTexturePackModel::ModrinthTexturePackModel(const BaseInstance& base) : TexturePackResourceModel(base, new ModrinthAPI){} +ModrinthTexturePackModel::ModrinthTexturePackModel(const BaseInstance& base) : TexturePackResourceModel(base, new ModrinthAPI) {} void ModrinthTexturePackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) { @@ -86,12 +96,17 @@ void ModrinthTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +auto ModrinthTexturePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return ::Modrinth::loadDependencyVersions(m, arr); +}; + auto ModrinthTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); } -ModrinthShaderPackModel::ModrinthShaderPackModel(const BaseInstance& base) : ShaderPackResourceModel(base, new ModrinthAPI){} +ModrinthShaderPackModel::ModrinthShaderPackModel(const BaseInstance& base) : ShaderPackResourceModel(base, new ModrinthAPI) {} void ModrinthShaderPackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) { @@ -108,6 +123,11 @@ void ModrinthShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } +auto ModrinthShaderPackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +{ + return ::Modrinth::loadDependencyVersions(m, arr); +}; + auto ModrinthShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h index b351b19b9..77157a41e 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h @@ -40,6 +40,7 @@ class ModrinthModModel : public ModModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -58,6 +59,7 @@ class ModrinthResourcePackModel : public ResourcePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -76,6 +78,7 @@ class ModrinthTexturePackModel : public TexturePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -94,6 +97,7 @@ class ModrinthShaderPackModel : public ShaderPackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; From 5079ce8d64d68d3fd2925baf18976385e44ebdc2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Apr 2023 23:18:37 +0300 Subject: [PATCH 009/429] Fixed headers Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 1 + launcher/minecraft/mod/tasks/GetModDependenciesTask.h | 3 +-- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 4 ++-- launcher/ui/pages/modplatform/ResourceModel.cpp | 4 ++-- launcher/ui/pages/modplatform/ResourceModel.h | 2 +- launcher/ui/pages/modplatform/ResourcePage.h | 3 +-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 9cc227f2e..1247e7630 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -19,6 +19,7 @@ #include "GetModDependenciesTask.h" +#include #include "QObjectPtr.h" #include "minecraft/mod/MetadataHandler.h" #include "minecraft/mod/tasks/LocalModGetAllTask.h" diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 4353c1e1f..1670cb6f7 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -18,9 +18,8 @@ #pragma once -#include -#include #include +#include #include #include "minecraft/mod/MetadataHandler.h" diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index e1041d952..143a6e507 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -18,8 +18,8 @@ */ #include "ResourceDownloadDialog.h" -#include -#include +#include +#include #include #include diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 42dd8daed..eb8c18203 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -3,8 +3,8 @@ // SPDX-License-Identifier: GPL-3.0-only #include "ResourceModel.h" -#include -#include +#include +#include #include #include diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 0292b84b8..5dbef7941 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 07f87929a..4fffd506d 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -4,12 +4,11 @@ #pragma once -#include +#include #include #include #include "modplatform/ModIndex.h" -#include "modplatform/ResourceAPI.h" #include "ui/pages/BasePage.h" #include "ui/widgets/ProgressWidget.h" From bcea19b957bb0db4270b7573540af40143cca7de Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Apr 2023 00:10:45 +0300 Subject: [PATCH 010/429] Tried to fix codeQL Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 17 +++++++++-------- .../mod/tasks/GetModDependenciesTask.h | 9 +++++---- launcher/ui/pages/modplatform/ModModel.cpp | 2 +- launcher/ui/pages/modplatform/ModModel.h | 2 +- launcher/ui/pages/modplatform/ResourceModel.cpp | 3 ++- launcher/ui/pages/modplatform/ResourceModel.h | 2 +- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 1247e7630..aeaa4b5b4 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -75,7 +75,7 @@ void GetModDependenciesTask::prepareDependecies() m_getNetworkDep->start(); } -void GetModDependenciesTask::addDependecies(ModPlatform::IndexedVersion new_version, int level) +void GetModDependenciesTask::addDependecies(const ModPlatform::IndexedVersion& new_version, int level) { // some mutex? m_dependencies.append(new_version); @@ -85,6 +85,7 @@ void GetModDependenciesTask::addDependecies(ModPlatform::IndexedVersion new_vers } if (level == 0) { qWarning() << "Dependency cycle exeeded"; + return; } for (auto dep : c_dependencies) { auto task = m_getDependenciesVersionAPI( @@ -93,20 +94,20 @@ void GetModDependenciesTask::addDependecies(ModPlatform::IndexedVersion new_vers } }; -QList GetModDependenciesTask::getDependenciesForVersions(QList selected) +QList GetModDependenciesTask::getDependenciesForVersions(const QList& selected) { auto c_dependencies = QList(); for (auto version : selected) { for (auto ver_dep : version.dependencies) { if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), - [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + [&ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); dep == c_dependencies.end()) { // check the current dependency list if (auto dep = - std::find_if(selected.begin(), selected.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + std::find_if(selected.begin(), selected.end(), [&ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); dep == selected.end()) { // check the selected versions if (auto dep = - std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); dep == m_mods.end()) { // check the existing mods c_dependencies.append(ver_dep); } @@ -118,15 +119,15 @@ QList GetModDependenciesTask::getDependenciesForVersion return c_dependencies; }; -QList GetModDependenciesTask::getDependenciesForVersion(ModPlatform::IndexedVersion version) +QList GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version) { auto c_dependencies = QList(); for (auto ver_dep : version.dependencies) { if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { if (auto dep = - std::find_if(c_dependencies.begin(), c_dependencies.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + std::find_if(c_dependencies.begin(), c_dependencies.end(), [&ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); dep == c_dependencies.end()) { // check the current dependency list - if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); dep == m_mods.end()) { // check the existing mods c_dependencies.append(ver_dep); } diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 1670cb6f7..7f7e1fb1b 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -34,7 +34,8 @@ class GetModDependenciesTask : public Task { using Ptr = shared_qobject_ptr; using LocalModGetAllTaskPtr = shared_qobject_ptr; - using NewDependecyVersionAPITask = std::function)>; + using NewDependecyVersionAPITask = + std::function)>; explicit GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask api); @@ -48,9 +49,9 @@ class GetModDependenciesTask : public Task { void executeTask() override; void prepareDependecies(); - void addDependecies(ModPlatform::IndexedVersion, int); - QList getDependenciesForVersions(QList); - QList getDependenciesForVersion(ModPlatform::IndexedVersion); + void addDependecies(const ModPlatform::IndexedVersion&, int); + QList getDependenciesForVersions(const QList&); + QList getDependenciesForVersion(const ModPlatform::IndexedVersion&); private: QList m_selected; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index bdbfe4609..19c20e65e 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -49,7 +49,7 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en return { pack, versions, profile->getModLoaders() }; } -ResourceAPI::DependencySearchArgs ModModel::createDependecyArguments(ModPlatform::Dependency& dep) +ResourceAPI::DependencySearchArgs ModModel::createDependecyArguments(const ModPlatform::Dependency& dep) { auto profile = static_cast(m_base_instance).getPackProfile(); diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index ca536f8f8..976389021 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -40,7 +40,7 @@ class ModModel : public ResourceModel { ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override; - ResourceAPI::DependencySearchArgs createDependecyArguments(ModPlatform::Dependency&) override; + ResourceAPI::DependencySearchArgs createDependecyArguments(const ModPlatform::Dependency&) override; protected: auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index eb8c18203..75585d6f7 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -452,7 +452,8 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe QList ResourceModel::getDependecies(QDir& dir, QList selected) { auto task = new GetModDependenciesTask( - dir, selected, [this](ModPlatform::Dependency dependency, std::function succeeded) -> Task::Ptr { + dir, selected, + [this](const ModPlatform::Dependency& dependency, std::function succeeded) -> Task::Ptr { auto args{ createDependecyArguments(dependency) }; auto callbacks{ createDependecyCallbacks() }; diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 5dbef7941..ce327c3bd 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -70,7 +70,7 @@ class ResourceModel : public QAbstractListModel { virtual ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) = 0; virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) { return {}; } - virtual ResourceAPI::DependencySearchArgs createDependecyArguments(ModPlatform::Dependency&) { return {}; }; + virtual ResourceAPI::DependencySearchArgs createDependecyArguments(const ModPlatform::Dependency&) { return {}; }; virtual ResourceAPI::DependencySearchCallbacks createDependecyCallbacks() { return {}; } /** Requests the API for more entries. */ From 7bd26ce4687b498fb91d42594da07fea1eca5552 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Apr 2023 00:49:35 +0300 Subject: [PATCH 011/429] Semi fixed the Modrinth dependency implementation Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 22 ++++++++++--------- launcher/modplatform/ResourceAPI.h | 2 +- .../modrinth/ModrinthPackIndex.cpp | 5 +++-- .../ui/pages/modplatform/ResourceModel.cpp | 11 ++++++++-- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index aeaa4b5b4..92e652c0c 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -69,7 +69,8 @@ void GetModDependenciesTask::prepareDependecies() return; } for (auto dep : c_dependencies) { - auto task = m_getDependenciesVersionAPI(dep, [this](ModPlatform::IndexedVersion new_version) { addDependecies(new_version, 20); }); + auto task = + m_getDependenciesVersionAPI(dep, [this](const ModPlatform::IndexedVersion& new_version) { addDependecies(new_version, 20); }); m_getNetworkDep->addTask(task); } m_getNetworkDep->start(); @@ -89,7 +90,7 @@ void GetModDependenciesTask::addDependecies(const ModPlatform::IndexedVersion& n } for (auto dep : c_dependencies) { auto task = m_getDependenciesVersionAPI( - dep, [this, level](ModPlatform::IndexedVersion new_versions) { addDependecies(new_versions, level - 1); }); + dep, [this, level](const ModPlatform::IndexedVersion& new_versions) { addDependecies(new_versions, level - 1); }); m_getNetworkDep->addTask(task); } }; @@ -101,13 +102,13 @@ QList GetModDependenciesTask::getDependenciesForVersion for (auto ver_dep : version.dependencies) { if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), - [&ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; }); dep == c_dependencies.end()) { // check the current dependency list - if (auto dep = - std::find_if(selected.begin(), selected.end(), [&ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + if (auto dep = std::find_if(selected.begin(), selected.end(), + [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; }); dep == selected.end()) { // check the selected versions - if (auto dep = - std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), + [&ver_dep](const auto& i) { return i.project_id == ver_dep.addonId; }); dep == m_mods.end()) { // check the existing mods c_dependencies.append(ver_dep); } @@ -124,10 +125,11 @@ QList GetModDependenciesTask::getDependenciesForVersion auto c_dependencies = QList(); for (auto ver_dep : version.dependencies) { if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { - if (auto dep = - std::find_if(c_dependencies.begin(), c_dependencies.end(), [&ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), + [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; }); dep == c_dependencies.end()) { // check the current dependency list - if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + if (auto dep = + std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](const auto& i) { return i.project_id == ver_dep.addonId; }); dep == m_mods.end()) { // check the existing mods c_dependencies.append(ver_dep); } diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index a8e144dc8..c23444b3a 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -126,7 +126,7 @@ class ResourceAPI { }; struct DependencySearchCallbacks { - std::function on_succeed; + std::function on_succeed; }; public: diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 9f898c393..ee9576802 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -22,6 +22,7 @@ #include "Json.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "modplatform/ModIndex.h" static ModrinthAPI api; static ModPlatform::ProviderCapabilities ProviderCaps; @@ -144,7 +145,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t auto dep = Json::ensureObject(d); ModPlatform::Dependency dependency; dependency.addonId = Json::requireString(dep, "project_id"); - dependency.version = Json::requireString(dep, "version_id"); + dependency.version = Json::ensureString(dep, "version_id"); auto depType = Json::requireString(dep, "dependency_type"); if (depType == "required") @@ -231,5 +232,5 @@ auto Modrinth::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr return a.date > b.date; }; std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); - return unsortedVersions.front(); + return unsortedVersions.length() != 0 ? unsortedVersions.front() : ModPlatform::IndexedVersion(); } \ No newline at end of file diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 75585d6f7..c1ffd0daf 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -459,11 +459,18 @@ QList ResourceModel::getDependecies(QDir& dir, QLis // Use default if no callbacks are set if (!callbacks.on_succeed) - callbacks.on_succeed = [this, dependency, succeeded](auto& doc, auto pack) { + callbacks.on_succeed = [this, dependency, succeeded](auto& doc, auto& pack) { ModPlatform::IndexedVersion ver; try { - auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); + auto arr = dependency.version.length() != 0 && doc.isObject() + ? Json::toJsonArray(QList() << doc.object()) + : doc.isObject() ? Json::ensureArray(doc.object(), "data") + : doc.array(); ver = loadDependencyVersions(dependency, arr); + if (!ver.addonId.isValid()) { + qWarning() << "Error while reading " << debugName() << " resource version empty "; + qDebug() << doc; + } } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading " << debugName() << " resource version: " << e.cause(); From f3f8f3574af20e279e41d3a02f337d5d59fc4a7e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Apr 2023 01:10:02 +0300 Subject: [PATCH 012/429] Small headers removal Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 8 ----- .../mod/tasks/LocalModUpdateTask.cpp | 33 +++++++++---------- .../ui/dialogs/ResourceDownloadDialog.cpp | 1 - 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 92e652c0c..f1f8581fb 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -27,10 +27,6 @@ #include "tasks/ConcurrentTask.h" #include "tasks/SequentialTask.h" -#ifdef Q_OS_WIN32 -#include -#endif - GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask api) : m_selected(selected), m_getDependenciesVersionAPI(api) { @@ -41,10 +37,6 @@ GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "LocalModUpdateTask.h" -#include "Application.h" #include "FileSystem.h" #include "minecraft/mod/MetadataHandler.h" diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 143a6e507..fe4692d6a 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -23,7 +23,6 @@ #include #include -#include #include "Application.h" #include "ResourceDownloadTask.h" From 31e84780a882622385dda0c574c128046d625eba Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Apr 2023 20:03:49 +0300 Subject: [PATCH 013/429] Hope to fix windows build errors Signed-off-by: Trial97 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 4 +--- launcher/ui/pages/modplatform/ResourcePage.cpp | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index fe4692d6a..610f24494 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -140,9 +140,7 @@ void ResourceDownloadDialog::confirm() for (auto dep : dependencies) { dep.is_currently_selected = true; - auto pack = ModPlatform::IndexedPack{ - .addonId = dep.addonId, .provider = ModPlatform::ResourceProvider::FLAME, .name = dep.fileName, .slug = dep.fileName - }; + auto pack = ModPlatform::IndexedPack{ dep.addonId, ModPlatform::ResourceProvider::FLAME, dep.fileName, dep.fileName }; m_selected.insert(dep.fileName, makeShared(pack, dep, getBaseModel(), true)); } diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index ec43521fb..02412fd9c 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -43,9 +43,6 @@ #include #include "Markdown.h" -#include "ResourceDownloadTask.h" - -#include "minecraft/MinecraftInstance.h" #include "ui/dialogs/ResourceDownloadDialog.h" #include "ui/pages/modplatform/ResourceModel.h" From fac33498dbd50fd9af60164e786534615586d6ac Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Apr 2023 20:41:00 +0300 Subject: [PATCH 014/429] Made some copy by reference Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 2 +- .../minecraft/mod/tasks/LocalModGetAllTask.cpp | 2 +- launcher/minecraft/mod/tasks/LocalModGetAllTask.h | 2 +- launcher/modplatform/flame/FlameModIndex.cpp | 2 +- launcher/modplatform/flame/FlameModIndex.h | 2 +- .../modplatform/modrinth/ModrinthPackIndex.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackIndex.h | 2 +- launcher/ui/pages/modplatform/ModModel.h | 2 +- launcher/ui/pages/modplatform/ResourceModel.cpp | 15 +++++++++------ launcher/ui/pages/modplatform/ResourceModel.h | 2 +- launcher/ui/pages/modplatform/ResourcePackModel.h | 2 +- launcher/ui/pages/modplatform/ShaderPackModel.h | 2 +- .../modplatform/flame/FlameResourceModels.cpp | 6 +++--- .../pages/modplatform/flame/FlameResourceModels.h | 6 +++--- .../modrinth/ModrinthResourceModels.cpp | 8 ++++---- .../modplatform/modrinth/ModrinthResourceModels.h | 8 ++++---- 16 files changed, 34 insertions(+), 31 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index f1f8581fb..7f1847654 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -33,7 +33,7 @@ GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList(index_dir); m_getNetworkDep = makeShared(this, "GetDepInfo"); connect(m_getNetworkDep.get(), &Task::finished, &loop, &QEventLoop::quit); - QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMod, [this](QList mods) { + QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMods, [this](QList mods) { m_mods = mods; prepareDependecies(); }); diff --git a/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp index 9e4293ff6..670588079 100644 --- a/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp @@ -41,7 +41,7 @@ LocalModGetAllTask::LocalModGetAllTask(QDir index_dir) : m_index_dir(index_dir) void LocalModGetAllTask::executeTask() { setStatus(tr("Geting all mods")); - emit getAllMod(Metadata::getAll(m_index_dir)); + emit getAllMods(Metadata::getAll(m_index_dir)); emitSucceeded(); } diff --git a/launcher/minecraft/mod/tasks/LocalModGetAllTask.h b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h index 09e453e4d..bf4b78b7f 100644 --- a/launcher/minecraft/mod/tasks/LocalModGetAllTask.h +++ b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h @@ -38,7 +38,7 @@ class LocalModGetAllTask : public Task { void executeTask() override; signals: - void getAllMod(QList); + void getAllMods(QList); private: QDir m_index_dir; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 38ecb9ab9..120bfc91d 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -170,7 +170,7 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> return file; } -ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) +ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) { QVector unsortedVersions; for (auto versionIter : arr) { diff --git a/launcher/modplatform/flame/FlameModIndex.h b/launcher/modplatform/flame/FlameModIndex.h index 306959e00..aa0d6f812 100644 --- a/launcher/modplatform/flame/FlameModIndex.h +++ b/launcher/modplatform/flame/FlameModIndex.h @@ -19,5 +19,5 @@ void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, const shared_qobject_ptr& network, const BaseInstance* inst); auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion; -auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion; +auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion; } // namespace FlameMod \ No newline at end of file diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index ee9576802..879260a3f 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -216,7 +216,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t return {}; } -auto Modrinth::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto Modrinth::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { QVector unsortedVersions; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index 8aa53a116..a8d986c57 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -31,6 +31,6 @@ void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, const shared_qobject_ptr& network, const BaseInstance* inst); auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion; -auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion; +auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion; } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 976389021..59b27dda4 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -32,7 +32,7 @@ class ModModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override = 0; - ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) override = 0; + ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) override = 0; void setFilter(std::shared_ptr filter) { m_filter = filter; } diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index c1ffd0daf..c1746d419 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -324,7 +324,7 @@ void ResourceModel::loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArra { NEED_FOR_CALLBACK_ASSERT("loadIndexedPackVersions"); } -ModPlatform::IndexedVersion ResourceModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) +ModPlatform::IndexedVersion ResourceModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) { NEED_FOR_CALLBACK_ASSERT("loadDependencyVersions"); return {}; @@ -451,7 +451,7 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe QList ResourceModel::getDependecies(QDir& dir, QList selected) { - auto task = new GetModDependenciesTask( + auto task = std::make_unique( dir, selected, [this](const ModPlatform::Dependency& dependency, std::function succeeded) -> Task::Ptr { auto args{ createDependecyArguments(dependency) }; @@ -462,14 +462,17 @@ QList ResourceModel::getDependecies(QDir& dir, QLis callbacks.on_succeed = [this, dependency, succeeded](auto& doc, auto& pack) { ModPlatform::IndexedVersion ver; try { - auto arr = dependency.version.length() != 0 && doc.isObject() - ? Json::toJsonArray(QList() << doc.object()) - : doc.isObject() ? Json::ensureArray(doc.object(), "data") - : doc.array(); + QJsonArray arr; + if (dependency.version.length() != 0 && doc.isObject()) { + arr.append(doc.object()); + } else { + arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); + } ver = loadDependencyVersions(dependency, arr); if (!ver.addonId.isValid()) { qWarning() << "Error while reading " << debugName() << " resource version empty "; qDebug() << doc; + return; } } catch (const JSONValidationError& e) { qDebug() << doc; diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index ce327c3bd..3b1f4748f 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -111,7 +111,7 @@ class ResourceModel : public QAbstractListModel { virtual void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&); - virtual ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr); + virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr); protected: /* Basic search parameters */ diff --git a/launcher/ui/pages/modplatform/ResourcePackModel.h b/launcher/ui/pages/modplatform/ResourcePackModel.h index 40b271d63..8ff4d8a29 100644 --- a/launcher/ui/pages/modplatform/ResourcePackModel.h +++ b/launcher/ui/pages/modplatform/ResourcePackModel.h @@ -28,7 +28,7 @@ class ResourcePackResourceModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0; - ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) override = 0; + ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) override = 0; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/ShaderPackModel.h b/launcher/ui/pages/modplatform/ShaderPackModel.h index 60d74777c..17a07aa49 100644 --- a/launcher/ui/pages/modplatform/ShaderPackModel.h +++ b/launcher/ui/pages/modplatform/ShaderPackModel.h @@ -28,7 +28,7 @@ class ShaderPackResourceModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0; - ModPlatform::IndexedVersion loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) override = 0; + ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) override = 0; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp index 563ff9638..08bf22fef 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp @@ -29,7 +29,7 @@ void FlameModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonAr FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto FlameModModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto FlameModModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return FlameMod::loadDependencyVersions(m, arr); }; @@ -57,7 +57,7 @@ void FlameResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto FlameResourcePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto FlameResourcePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return FlameMod::loadDependencyVersions(m, arr); }; @@ -98,7 +98,7 @@ void FlameTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, m.versions = filtered_versions; } -auto FlameTexturePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto FlameTexturePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return FlameMod::loadDependencyVersions(m, arr); }; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h index 2f4413acf..7871d9aa5 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h @@ -24,7 +24,7 @@ class FlameModModel : public ModModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -43,7 +43,7 @@ class FlameResourcePackModel : public ResourcePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -62,7 +62,7 @@ class FlameTexturePackModel : public TexturePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp index 047e3aaaa..53be2d2ca 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp @@ -42,7 +42,7 @@ void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJso ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthModModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto ModrinthModModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return ::Modrinth::loadDependencyVersions(m, arr); }; @@ -69,7 +69,7 @@ void ModrinthResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthResourcePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto ModrinthResourcePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return ::Modrinth::loadDependencyVersions(m, arr); }; @@ -96,7 +96,7 @@ void ModrinthTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthTexturePackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto ModrinthTexturePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return ::Modrinth::loadDependencyVersions(m, arr); }; @@ -123,7 +123,7 @@ void ModrinthShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthShaderPackModel::loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion +auto ModrinthShaderPackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { return ::Modrinth::loadDependencyVersions(m, arr); }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h index 77157a41e..0045fe86c 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h @@ -40,7 +40,7 @@ class ModrinthModModel : public ModModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -59,7 +59,7 @@ class ModrinthResourcePackModel : public ResourcePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -78,7 +78,7 @@ class ModrinthTexturePackModel : public TexturePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -97,7 +97,7 @@ class ModrinthShaderPackModel : public ShaderPackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(ModPlatform::Dependency m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; + auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; From c1490cd62703975c5478aea1156d0bbefcc37bc8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 20 Apr 2023 00:57:09 +0300 Subject: [PATCH 015/429] Refator task to work with multiple providers Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 2 - launcher/ResourceDownloadTask.h | 1 + .../mod/tasks/GetModDependenciesTask.cpp | 209 +++++++++++------- .../mod/tasks/GetModDependenciesTask.h | 62 ++++-- .../mod/tasks/LocalModGetAllTask.cpp | 52 ----- .../minecraft/mod/tasks/LocalModGetAllTask.h | 45 ---- .../ui/dialogs/ResourceDownloadDialog.cpp | 63 ++++-- launcher/ui/dialogs/ResourceDownloadDialog.h | 15 +- .../ui/pages/modplatform/ResourceModel.cpp | 42 ---- launcher/ui/pages/modplatform/ResourceModel.h | 2 - .../ui/pages/modplatform/ResourcePage.cpp | 5 - launcher/ui/pages/modplatform/ResourcePage.h | 2 - 12 files changed, 220 insertions(+), 280 deletions(-) delete mode 100644 launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp delete mode 100644 launcher/minecraft/mod/tasks/LocalModGetAllTask.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index fca8c9144..19356b946 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -361,8 +361,6 @@ set(MINECRAFT_SOURCES minecraft/mod/tasks/LocalResourceParse.cpp minecraft/mod/tasks/GetModDependenciesTask.h minecraft/mod/tasks/GetModDependenciesTask.cpp - minecraft/mod/tasks/LocalModGetAllTask.h - minecraft/mod/tasks/LocalModGetAllTask.cpp # Assets minecraft/AssetsUtils.h diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index f2118524a..29d3ae0af 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -38,6 +38,7 @@ class ResourceDownloadTask : public SequentialTask { const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } const ModPlatform::IndexedVersion& getVersion() const { return m_pack_version; } + const ModPlatform::IndexedPack& getPack() const { return m_pack; } private: ModPlatform::IndexedPack m_pack; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 7f1847654..966eea19b 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -20,90 +20,74 @@ #include "GetModDependenciesTask.h" #include +#include +#include +#include "Json.h" #include "QObjectPtr.h" #include "minecraft/mod/MetadataHandler.h" -#include "minecraft/mod/tasks/LocalModGetAllTask.h" #include "modplatform/ModIndex.h" +#include "modplatform/flame/FlameAPI.h" +#include "modplatform/modrinth/ModrinthAPI.h" #include "tasks/ConcurrentTask.h" #include "tasks/SequentialTask.h" +#include "ui/pages/modplatform/ModModel.h" +#include "ui/pages/modplatform/flame/FlameResourceModels.h" +#include "ui/pages/modplatform/modrinth/ModrinthResourceModels.h" -GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask api) - : m_selected(selected), m_getDependenciesVersionAPI(api) +static Version mcVersions(BaseInstance* inst) { - m_getAllMods = makeShared(index_dir); - m_getNetworkDep = makeShared(this, "GetDepInfo"); - connect(m_getNetworkDep.get(), &Task::finished, &loop, &QEventLoop::quit); - QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMods, [this](QList mods) { - m_mods = mods; - prepareDependecies(); - }); + return static_cast(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion(); } -void GetModDependenciesTask::executeTask() +static ResourceAPI::ModLoaderTypes mcLoaders(BaseInstance* inst) { - setStatus(tr("Geting all mods")); - m_getAllMods->start(); - loop.exec(); - emitSucceeded(); + return static_cast(inst)->getPackProfile()->getModLoaders().value(); } -auto GetModDependenciesTask::abort() -> bool +GetModDependenciesTask::GetModDependenciesTask(QObject* parent, + BaseInstance* instance, + ModFolderModel* folder, + QList> selected) + : SequentialTask(parent, "Get dependencies"), m_selected(selected), m_version(mcVersions(instance)), m_loaderType(mcLoaders(instance)) { - emitAborted(); - return true; -} - -void GetModDependenciesTask::prepareDependecies() -{ - auto c_dependencies = getDependenciesForVersions(m_selected); - if (c_dependencies.length() == 0) { - m_getNetworkDep->start(); - return; - } - for (auto dep : c_dependencies) { - auto task = - m_getDependenciesVersionAPI(dep, [this](const ModPlatform::IndexedVersion& new_version) { addDependecies(new_version, 20); }); - m_getNetworkDep->addTask(task); - } - m_getNetworkDep->start(); -} - -void GetModDependenciesTask::addDependecies(const ModPlatform::IndexedVersion& new_version, int level) -{ - // some mutex? - m_dependencies.append(new_version); - auto c_dependencies = getDependenciesForVersion(new_version); - if (c_dependencies.length() == 0) { - return; - } - if (level == 0) { - qWarning() << "Dependency cycle exeeded"; - return; - } - for (auto dep : c_dependencies) { - auto task = m_getDependenciesVersionAPI( - dep, [this, level](const ModPlatform::IndexedVersion& new_versions) { addDependecies(new_versions, level - 1); }); - m_getNetworkDep->addTask(task); - } + m_providers.append(Provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared(*instance), + std::make_shared() }); + m_providers.append(Provider{ ModPlatform::ResourceProvider::MODRINTH, std::make_shared(*instance), + std::make_shared() }); + for (auto mod : folder->allMods()) + m_mods.append(mod->metadata()); + prepare(); }; -QList GetModDependenciesTask::getDependenciesForVersions(const QList& selected) +void GetModDependenciesTask::prepare() +{ + for (auto sel : m_selected) { + for (auto dep : getDependenciesForVersion(sel->version, sel->pack.provider)) { + addTask(prepareDependencyTask(dep, sel->pack.provider, 20)); + } + } +} + +QList GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version, + const ModPlatform::ResourceProvider providerName) { auto c_dependencies = QList(); - for (auto version : selected) { - for (auto ver_dep : version.dependencies) { - if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { - if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), - [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; }); - dep == c_dependencies.end()) { // check the current dependency list - if (auto dep = std::find_if(selected.begin(), selected.end(), - [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; }); - dep == selected.end()) { // check the selected versions - if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), - [&ver_dep](const auto& i) { return i.project_id == ver_dep.addonId; }); - dep == m_mods.end()) { // check the existing mods - c_dependencies.append(ver_dep); - } + for (auto ver_dep : version.dependencies) { + if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { + if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), + [&ver_dep](const ModPlatform::Dependency& i) { return i.addonId == ver_dep.addonId; }); + dep == c_dependencies.end()) { // check the current dependency list + if (auto dep = std::find_if(m_selected.begin(), m_selected.end(), + [&ver_dep, providerName](std::shared_ptr i) { + return i->pack.addonId == ver_dep.addonId && i->pack.provider == providerName; + }); + dep == m_selected.end()) { // check the selected versions + if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), + [&ver_dep, providerName](std::shared_ptr i) { + return i->project_id == ver_dep.addonId && i->provider == providerName; + }); + dep == m_mods.end()) { // check the existing mods + c_dependencies.append(ver_dep); } } } @@ -112,21 +96,80 @@ QList GetModDependenciesTask::getDependenciesForVersion return c_dependencies; }; -QList GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version) +Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Dependency& dep, + const ModPlatform::ResourceProvider providerName, + int level) { - auto c_dependencies = QList(); - for (auto ver_dep : version.dependencies) { - if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { - if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), - [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; }); - dep == c_dependencies.end()) { // check the current dependency list - if (auto dep = - std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](const auto& i) { return i.project_id == ver_dep.addonId; }); - dep == m_mods.end()) { // check the existing mods - c_dependencies.append(ver_dep); - } - } + auto pDep = std::make_shared(); + pDep->dependency = dep; + pDep->pack = { dep.addonId, providerName }; + m_pack_dependencies.append(pDep); + auto provider = + std::find_if(m_providers.begin(), m_providers.end(), [providerName](const Provider& p) { return p.name == providerName; }); + // if (provider == m_providers.end()) { + // qWarning() << "Unsuported provider for dependency check"; + // return nullptr; + // } + + auto tasks = makeShared(this, QString("DependencyInfo: %1").arg(dep.addonId.toString())); + + auto responseInfo = new QByteArray(); + auto info = provider->api->getProject(dep.addonId.toString(), responseInfo); + QObject::connect(info.get(), &NetJob::succeeded, [responseInfo, provider, pDep] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*responseInfo, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *responseInfo; + return; } - } - return c_dependencies; -}; \ No newline at end of file + try { + auto obj = provider->name == ModPlatform::ResourceProvider::FLAME ? Json::requireObject(Json::requireObject(doc), "data") + : Json::requireObject(doc); + provider->mod->loadIndexedPack(pDep->pack, obj); + } catch (const JSONValidationError& e) { + qDebug() << doc; + qWarning() << "Error while reading mod info: " << e.cause(); + } + }); + tasks->addTask(info); + + ResourceAPI::DependencySearchArgs args = { dep, m_version, m_loaderType }; + ResourceAPI::DependencySearchCallbacks callbacks; + + callbacks.on_succeed = [dep, provider, pDep, level, this](auto& doc, auto& pack) { + try { + QJsonArray arr; + if (dep.version.length() != 0 && doc.isObject()) { + arr.append(doc.object()); + } else { + arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); + } + pDep->version = provider->mod->loadDependencyVersions(dep, arr); + if (!pDep->version.addonId.isValid()) { + qWarning() << "Error while reading mod version empty "; + qDebug() << doc; + return; + } + pDep->version.is_currently_selected = true; + pDep->pack.versions = { pDep->version }; + pDep->pack.versionsLoaded = true; + } catch (const JSONValidationError& e) { + qDebug() << doc; + qWarning() << "Error while reading mod version: " << e.cause(); + return; + } + if (level == 0) { + qWarning() << "Dependency cycle exeeded"; + return; + } + for (auto dep : getDependenciesForVersion(pDep->version, provider->name)) { + addTask(prepareDependencyTask(dep, provider->name, level - 1)); + } + }; + + auto version = provider->api->getDependencyVersion(std::move(args), std::move(callbacks)); + tasks->addTask(version); + return tasks; +}; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 7f7e1fb1b..d83d6e271 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -18,48 +18,64 @@ #pragma once +#include +#include #include #include +#include #include +#include #include "minecraft/mod/MetadataHandler.h" -#include "minecraft/mod/tasks/LocalModGetAllTask.h" +#include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" +#include "modplatform/ResourceAPI.h" #include "tasks/SequentialTask.h" #include "tasks/Task.h" +#include "ui/pages/modplatform/ModModel.h" -class GetModDependenciesTask : public Task { +class GetModDependenciesTask : public SequentialTask { Q_OBJECT public: using Ptr = shared_qobject_ptr; - using LocalModGetAllTaskPtr = shared_qobject_ptr; - using NewDependecyVersionAPITask = - std::function)>; + struct PackDependecny { + ModPlatform::Dependency dependency; + ModPlatform::IndexedPack pack; + ModPlatform::IndexedVersion version; + PackDependecny(){}; + PackDependecny(const ModPlatform::IndexedPack& p, const ModPlatform::IndexedVersion& v) + { + pack = p; + version = v; + } + }; - explicit GetModDependenciesTask(QDir index_dir, QList selected, NewDependecyVersionAPITask api); + struct Provider { + ModPlatform::ResourceProvider name; + std::shared_ptr mod; + std::shared_ptr api; + }; - auto canAbort() const -> bool override { return true; } - auto abort() -> bool override; + explicit GetModDependenciesTask(QObject* parent, + BaseInstance* instance, + ModFolderModel* folder, + QList> selected); - auto getDependecies() const -> QList { return m_dependencies; } + auto getDependecies() const -> QList> { return m_pack_dependencies; } protected slots: - //! Entry point for tasks. - void executeTask() override; - - void prepareDependecies(); - void addDependecies(const ModPlatform::IndexedVersion&, int); - QList getDependenciesForVersions(const QList&); - QList getDependenciesForVersion(const ModPlatform::IndexedVersion&); + Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int); + QList getDependenciesForVersion(const ModPlatform::IndexedVersion&, + const ModPlatform::ResourceProvider providerName); + void prepare(); private: - QList m_selected; - QList m_dependencies; - QList m_mods; + QList> m_pack_dependencies; + QList> m_mods; + QList> m_selected; + QList m_providers; - LocalModGetAllTaskPtr m_getAllMods = nullptr; - NewDependecyVersionAPITask m_getDependenciesVersionAPI; - SequentialTask::Ptr m_getNetworkDep; - QEventLoop loop; + Version m_version; + ResourceAPI::ModLoaderTypes m_loaderType; }; diff --git a/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp deleted file mode 100644 index 670588079..000000000 --- a/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln - * Copyright (C) 2022 Sefa Eyeoglu - * - * 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 "LocalModGetAllTask.h" - -#include "FileSystem.h" -#include "minecraft/mod/MetadataHandler.h" - -#ifdef Q_OS_WIN32 -#include -#endif - -LocalModGetAllTask::LocalModGetAllTask(QDir index_dir) : m_index_dir(index_dir) -{ - // Ensure a '.index' folder exists in the mods folder, and create it if it does not - if (!FS::ensureFolderPathExists(index_dir.path())) { - emitFailed(QString("Unable to create index for all mods!")); - } - -#ifdef Q_OS_WIN32 - SetFileAttributesW(index_dir.path().toStdWString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); -#endif -} - -void LocalModGetAllTask::executeTask() -{ - setStatus(tr("Geting all mods")); - emit getAllMods(Metadata::getAll(m_index_dir)); - emitSucceeded(); -} - -auto LocalModGetAllTask::abort() -> bool -{ - emitAborted(); - return true; -} diff --git a/launcher/minecraft/mod/tasks/LocalModGetAllTask.h b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h deleted file mode 100644 index bf4b78b7f..000000000 --- a/launcher/minecraft/mod/tasks/LocalModGetAllTask.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln - * - * 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 "minecraft/mod/MetadataHandler.h" -#include "tasks/Task.h" - -class LocalModGetAllTask : public Task { - Q_OBJECT - public: - using Ptr = shared_qobject_ptr; - - explicit LocalModGetAllTask(QDir index_dir); - - auto canAbort() const -> bool override { return true; } - auto abort() -> bool override; - - protected slots: - //! Entry point for tasks. - void executeTask() override; - - signals: - void getAllMods(QList); - - private: - QDir m_index_dir; -}; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 610f24494..03466bbad 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -23,8 +23,10 @@ #include #include +#include #include "Application.h" +#include "QObjectPtr.h" #include "ResourceDownloadTask.h" #include "minecraft/mod/ModFolderModel.h" @@ -32,7 +34,10 @@ #include "minecraft/mod/ShaderPackFolderModel.h" #include "minecraft/mod/TexturePackFolderModel.h" +#include "minecraft/mod/tasks/GetModDependenciesTask.h" #include "modplatform/ModIndex.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/ReviewMessageBox.h" #include "ui/pages/modplatform/ResourcePage.h" @@ -122,30 +127,38 @@ void ResourceDownloadDialog::connectButtons() void ResourceDownloadDialog::confirm() { - auto keys = m_selected.keys(); - keys.sort(Qt::CaseInsensitive); - auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString())); confirm_dialog->retranslateUi(resourcesString()); - if (auto model = dynamic_cast(getBaseModel().get()); model) { - QList selectedVers; - for (auto& task : keys) { - auto selected = m_selected.constFind(task).value(); - selectedVers.append(selected->getVersion()); - } + if (auto task = getModDependenciesTask(); task) { + connect(task.get(), &Task::failed, this, + [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }); - auto dir = model->indexDir(); - auto dependencies = m_selectedPage->getDependecies(dir, selectedVers); + connect(task.get(), &Task::succeeded, this, [&]() { + QStringList warnings = task->warnings(); + if (warnings.count()) { + CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec(); + } + }); - for (auto dep : dependencies) { - dep.is_currently_selected = true; - auto pack = ModPlatform::IndexedPack{ dep.addonId, ModPlatform::ResourceProvider::FLAME, dep.fileName, dep.fileName }; - m_selected.insert(dep.fileName, makeShared(pack, dep, getBaseModel(), true)); - } + // Check for updates + ProgressDialog progress_dialog(this); + progress_dialog.setSkipButton(true, tr("Abort")); + progress_dialog.setWindowTitle(tr("Checking for dependencies...")); + auto ret = progress_dialog.execWithTask(task.get()); - keys = m_selected.keys(); + // If the dialog was skipped / some download error happened + if (ret == QDialog::DialogCode::Rejected) { + QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection); + return; + } else + for (auto dep : task->getDependecies()) { + addResource(dep->pack, dep->version, true); + } } + + auto keys = m_selected.keys(); + keys.sort(Qt::CaseInsensitive); for (auto& task : keys) { auto selected = m_selected.constFind(task).value(); confirm_dialog->appendResource({ task, selected->getFilename(), selected->getCustomPath() }); @@ -173,6 +186,7 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage() void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed) { + qWarning() << "DebugName: " << pack.name; removeResource(pack, ver); ver.is_currently_selected = true; @@ -256,6 +270,21 @@ QList ModDownloadDialog::getPages() return pages; } +GetModDependenciesTask::Ptr ModDownloadDialog::getModDependenciesTask() +{ + if (auto model = dynamic_cast(getBaseModel().get()); model) { + auto keys = m_selected.keys(); + QList> selectedVers; + for (auto& task : keys) { + auto selected = m_selected.constFind(task).value(); + selectedVers.append(std::make_shared(selected->getPack(), selected->getVersion())); + } + + return makeShared(this, m_instance, model, selectedVers); + } + return nullptr; +}; + ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent, const std::shared_ptr& resource_packs, BaseInstance* instance) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h index 5678dc8bb..f498df014 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.h +++ b/launcher/ui/dialogs/ResourceDownloadDialog.h @@ -25,7 +25,9 @@ #include #include "QObjectPtr.h" +#include "minecraft/mod/tasks/GetModDependenciesTask.h" #include "modplatform/ModIndex.h" +#include "tasks/Task.h" #include "ui/pages/BasePageProvider.h" class BaseInstance; @@ -80,6 +82,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { protected: [[nodiscard]] virtual QString geometrySaveKey() const { return ""; } + [[nodiscard]] virtual GetModDependenciesTask::Ptr getModDependenciesTask() { return nullptr; } + protected: const std::shared_ptr m_base_model; @@ -92,8 +96,6 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { QHash m_selected; }; - - class ModDownloadDialog final : public ResourceDownloadDialog { Q_OBJECT @@ -106,6 +108,7 @@ class ModDownloadDialog final : public ResourceDownloadDialog { [[nodiscard]] QString geometrySaveKey() const override { return "ModDownloadGeometry"; } QList getPages() override; + GetModDependenciesTask::Ptr getModDependenciesTask() override; private: BaseInstance* m_instance; @@ -135,8 +138,8 @@ class TexturePackDownloadDialog final : public ResourceDownloadDialog { public: explicit TexturePackDownloadDialog(QWidget* parent, - const std::shared_ptr& resource_packs, - BaseInstance* instance); + const std::shared_ptr& resource_packs, + BaseInstance* instance); ~TexturePackDownloadDialog() override = default; //: String that gets appended to the texture pack download dialog title ("Download " + resourcesString()) @@ -153,9 +156,7 @@ class ShaderPackDownloadDialog final : public ResourceDownloadDialog { Q_OBJECT public: - explicit ShaderPackDownloadDialog(QWidget* parent, - const std::shared_ptr& shader_packs, - BaseInstance* instance); + explicit ShaderPackDownloadDialog(QWidget* parent, const std::shared_ptr& shader_packs, BaseInstance* instance); ~ShaderPackDownloadDialog() override = default; //: String that gets appended to the shader pack download dialog title ("Download " + resourcesString()) diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index c1746d419..97b9efa96 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -449,46 +449,4 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe emit projectInfoUpdated(); } -QList ResourceModel::getDependecies(QDir& dir, QList selected) -{ - auto task = std::make_unique( - dir, selected, - [this](const ModPlatform::Dependency& dependency, std::function succeeded) -> Task::Ptr { - auto args{ createDependecyArguments(dependency) }; - auto callbacks{ createDependecyCallbacks() }; - - // Use default if no callbacks are set - if (!callbacks.on_succeed) - callbacks.on_succeed = [this, dependency, succeeded](auto& doc, auto& pack) { - ModPlatform::IndexedVersion ver; - try { - QJsonArray arr; - if (dependency.version.length() != 0 && doc.isObject()) { - arr.append(doc.object()); - } else { - arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); - } - ver = loadDependencyVersions(dependency, arr); - if (!ver.addonId.isValid()) { - qWarning() << "Error while reading " << debugName() << " resource version empty "; - qDebug() << doc; - return; - } - } catch (const JSONValidationError& e) { - qDebug() << doc; - qWarning() << "Error while reading " << debugName() << " resource version: " << e.cause(); - return; - } - - succeeded(ver); - }; - - return m_api->getDependencyVersion(std::move(args), std::move(callbacks)); - }); - - task->start(); - - return task->getDependecies(); -}; - } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 3b1f4748f..3ea567afd 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -85,8 +85,6 @@ class ResourceModel : public QAbstractListModel { /** Gets the icon at the URL for the given index. If it's not fetched yet, fetch it and update when fisinhed. */ std::optional getIcon(QModelIndex&, const QUrl&); - QList getDependecies(QDir& dir, QList m_selected); - protected: /** Resets the model's data. */ void clearData(); diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 02412fd9c..1baa24eec 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -405,9 +405,4 @@ void ResourcePage::openUrl(const QUrl& url) QDesktopServices::openUrl(url); } -QList ResourcePage::getDependecies(QDir& dir, QList selected) -{ - return m_model->getDependecies(dir, selected); -}; - } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 4fffd506d..a8299728b 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -75,8 +75,6 @@ class ResourcePage : public QWidget, public BasePage { virtual void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); virtual void removeResourceFromDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); - QList getDependecies(QDir& dir, QList m_selected); - protected slots: virtual void triggerSearch() {} From ffaa47bf54bc5b320049064a897c8ad0737574ee Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 20 Apr 2023 22:35:10 +0300 Subject: [PATCH 016/429] Small cleanup Signed-off-by: Trial97 --- launcher/minecraft/mod/MetadataHandler.h | 2 - .../mod/tasks/GetModDependenciesTask.cpp | 36 ++++++------ .../mod/tasks/GetModDependenciesTask.h | 6 +- launcher/modplatform/packwiz/Packwiz.cpp | 11 ---- launcher/modplatform/packwiz/Packwiz.h | 57 +++++++++---------- .../ui/dialogs/ResourceDownloadDialog.cpp | 1 - launcher/ui/dialogs/ResourceDownloadDialog.h | 1 - launcher/ui/pages/modplatform/ModModel.cpp | 16 +----- launcher/ui/pages/modplatform/ModModel.h | 3 +- .../ui/pages/modplatform/ResourceModel.cpp | 5 -- launcher/ui/pages/modplatform/ResourceModel.h | 4 -- .../ui/pages/modplatform/ResourcePackModel.h | 1 - .../ui/pages/modplatform/ResourcePage.cpp | 3 + launcher/ui/pages/modplatform/ResourcePage.h | 4 +- .../ui/pages/modplatform/ShaderPackModel.h | 1 - .../modplatform/flame/FlameResourceModels.cpp | 10 ---- .../modplatform/flame/FlameResourceModels.h | 2 - .../modrinth/ModrinthResourceModels.cpp | 15 ----- .../modrinth/ModrinthResourceModels.h | 3 - 19 files changed, 54 insertions(+), 127 deletions(-) diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index f7f08a79c..ea9078e04 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -51,6 +51,4 @@ 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 getAll(QDir& index_dir) -> QList { return Packwiz::V1::getAllMods(index_dir); } }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 966eea19b..e1760f163 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -48,12 +48,15 @@ GetModDependenciesTask::GetModDependenciesTask(QObject* parent, BaseInstance* instance, ModFolderModel* folder, QList> selected) - : SequentialTask(parent, "Get dependencies"), m_selected(selected), m_version(mcVersions(instance)), m_loaderType(mcLoaders(instance)) + : SequentialTask(parent, "Get dependencies") + , m_selected(selected) + , m_flame_provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared(*instance), + std::make_shared() } + , m_modrinth_provider{ ModPlatform::ResourceProvider::MODRINTH, std::make_shared(*instance), + std::make_shared() } + , m_version(mcVersions(instance)) + , m_loaderType(mcLoaders(instance)) { - m_providers.append(Provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared(*instance), - std::make_shared() }); - m_providers.append(Provider{ ModPlatform::ResourceProvider::MODRINTH, std::make_shared(*instance), - std::make_shared() }); for (auto mod : folder->allMods()) m_mods.append(mod->metadata()); prepare(); @@ -104,17 +107,12 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen pDep->dependency = dep; pDep->pack = { dep.addonId, providerName }; m_pack_dependencies.append(pDep); - auto provider = - std::find_if(m_providers.begin(), m_providers.end(), [providerName](const Provider& p) { return p.name == providerName; }); - // if (provider == m_providers.end()) { - // qWarning() << "Unsuported provider for dependency check"; - // return nullptr; - // } + auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; auto tasks = makeShared(this, QString("DependencyInfo: %1").arg(dep.addonId.toString())); auto responseInfo = new QByteArray(); - auto info = provider->api->getProject(dep.addonId.toString(), responseInfo); + auto info = provider.api->getProject(dep.addonId.toString(), responseInfo); QObject::connect(info.get(), &NetJob::succeeded, [responseInfo, provider, pDep] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*responseInfo, &parse_error); @@ -125,9 +123,9 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen return; } try { - auto obj = provider->name == ModPlatform::ResourceProvider::FLAME ? Json::requireObject(Json::requireObject(doc), "data") - : Json::requireObject(doc); - provider->mod->loadIndexedPack(pDep->pack, obj); + auto obj = provider.name == ModPlatform::ResourceProvider::FLAME ? Json::requireObject(Json::requireObject(doc), "data") + : Json::requireObject(doc); + provider.mod->loadIndexedPack(pDep->pack, obj); } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading mod info: " << e.cause(); @@ -146,7 +144,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen } else { arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); } - pDep->version = provider->mod->loadDependencyVersions(dep, arr); + pDep->version = provider.mod->loadDependencyVersions(dep, arr); if (!pDep->version.addonId.isValid()) { qWarning() << "Error while reading mod version empty "; qDebug() << doc; @@ -164,12 +162,12 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen qWarning() << "Dependency cycle exeeded"; return; } - for (auto dep : getDependenciesForVersion(pDep->version, provider->name)) { - addTask(prepareDependencyTask(dep, provider->name, level - 1)); + for (auto dep : getDependenciesForVersion(pDep->version, provider.name)) { + addTask(prepareDependencyTask(dep, provider.name, level - 1)); } }; - auto version = provider->api->getDependencyVersion(std::move(args), std::move(callbacks)); + auto version = provider.api->getDependencyVersion(std::move(args), std::move(callbacks)); tasks->addTask(version); return tasks; }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index d83d6e271..40f80ebf6 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -18,11 +18,10 @@ #pragma once -#include -#include #include #include #include +#include #include #include @@ -74,7 +73,8 @@ class GetModDependenciesTask : public SequentialTask { QList> m_pack_dependencies; QList> m_mods; QList> m_selected; - QList m_providers; + Provider m_flame_provider; + Provider m_modrinth_provider; Version m_version; ResourceAPI::ModLoaderTypes m_loaderType; diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 33b5f364a..510c7309d 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include "FileSystem.h" #include "StringUtils.h" @@ -313,13 +311,4 @@ auto V1::getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod return {}; } -auto V1::getAllMods(QDir& index_dir) -> QList -{ - auto files = index_dir.entryList(QDir::Filter::Files); - auto mods = QList(); - std::transform(files.begin(), files.end(), std::back_inserter(mods), - [&index_dir](auto file_name) { return getIndexForMod(index_dir, file_name); }); - return mods; -} - } // namespace Packwiz diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 2801f5d0f..4b096eec7 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln - * - * 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 . - */ +* PolyMC - Minecraft Launcher +* Copyright (c) 2022 flowln +* +* 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 @@ -36,22 +36,22 @@ auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool shoul class V1 { public: struct Mod { - QString slug{}; - QString name{}; - QString filename{}; + QString slug {}; + QString name {}; + QString filename {}; // FIXME: make side an enum - QString side{ "both" }; + QString side {"both"}; // [download] - QString mode{}; - QUrl url{}; - QString hash_format{}; - QString hash{}; + QString mode {}; + QUrl url {}; + QString hash_format {}; + QString hash {}; // [update] - ModPlatform::ResourceProvider provider{}; - QVariant file_id{}; - QVariant project_id{}; + ModPlatform::ResourceProvider provider {}; + QVariant file_id {}; + QVariant project_id {}; public: // This is a totally heuristic, but should work for now. @@ -93,9 +93,6 @@ class V1 { * If the mod doesn't have a metadata, it simply returns an empty Mod object. * */ static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod; - - /* Gets the metadata for all the mods */ - static auto getAllMods(QDir& index_dir) -> QList; }; -} // namespace Packwiz +} // namespace Packwiz diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 03466bbad..dc1d927e8 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -26,7 +26,6 @@ #include #include "Application.h" -#include "QObjectPtr.h" #include "ResourceDownloadTask.h" #include "minecraft/mod/ModFolderModel.h" diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h index f498df014..9610c8b36 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.h +++ b/launcher/ui/dialogs/ResourceDownloadDialog.h @@ -27,7 +27,6 @@ #include "QObjectPtr.h" #include "minecraft/mod/tasks/GetModDependenciesTask.h" #include "modplatform/ModIndex.h" -#include "tasks/Task.h" #include "ui/pages/BasePageProvider.h" class BaseInstance; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 19c20e65e..3ffe6cb06 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -24,7 +24,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() std::optional> versions{}; - { // Version filter + { // Version filter if (!m_filter->versions.empty()) versions = m_filter->versions; } @@ -49,20 +49,6 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en return { pack, versions, profile->getModLoaders() }; } -ResourceAPI::DependencySearchArgs ModModel::createDependecyArguments(const ModPlatform::Dependency& dep) -{ - auto profile = static_cast(m_base_instance).getPackProfile(); - - Q_ASSERT(profile); - Q_ASSERT(m_filter); - - std::optional> versions{}; - if (!m_filter->versions.empty()) - versions = m_filter->versions; - - return { dep, versions->front(), profile->getModLoaders().value() }; -}; - ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(QModelIndex& entry) { auto& pack = m_packs[entry.row()]; diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 59b27dda4..f7563171f 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -32,7 +32,7 @@ class ModModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override = 0; - ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) override = 0; + virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) = 0; void setFilter(std::shared_ptr filter) { m_filter = filter; } @@ -40,7 +40,6 @@ class ModModel : public ResourceModel { ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override; - ResourceAPI::DependencySearchArgs createDependecyArguments(const ModPlatform::Dependency&) override; protected: auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 97b9efa96..b1e936f8c 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -324,11 +324,6 @@ void ResourceModel::loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArra { NEED_FOR_CALLBACK_ASSERT("loadIndexedPackVersions"); } -ModPlatform::IndexedVersion ResourceModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -{ - NEED_FOR_CALLBACK_ASSERT("loadDependencyVersions"); - return {}; -} /* Default callbacks */ diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 3ea567afd..c08445897 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -70,9 +70,6 @@ class ResourceModel : public QAbstractListModel { virtual ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) = 0; virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) { return {}; } - virtual ResourceAPI::DependencySearchArgs createDependecyArguments(const ModPlatform::Dependency&) { return {}; }; - virtual ResourceAPI::DependencySearchCallbacks createDependecyCallbacks() { return {}; } - /** Requests the API for more entries. */ virtual void search(); @@ -109,7 +106,6 @@ class ResourceModel : public QAbstractListModel { virtual void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&); - virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr); protected: /* Basic search parameters */ diff --git a/launcher/ui/pages/modplatform/ResourcePackModel.h b/launcher/ui/pages/modplatform/ResourcePackModel.h index 8ff4d8a29..e2b4a1957 100644 --- a/launcher/ui/pages/modplatform/ResourcePackModel.h +++ b/launcher/ui/pages/modplatform/ResourcePackModel.h @@ -28,7 +28,6 @@ class ResourcePackResourceModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0; - ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) override = 0; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 1baa24eec..bbd465bc1 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -43,6 +43,9 @@ #include #include "Markdown.h" +#include "ResourceDownloadTask.h" + +#include "minecraft/MinecraftInstance.h" #include "ui/dialogs/ResourceDownloadDialog.h" #include "ui/pages/modplatform/ResourceModel.h" diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index a8299728b..1896d53ea 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -4,11 +4,11 @@ #pragma once -#include #include #include #include "modplatform/ModIndex.h" +#include "modplatform/ResourceAPI.h" #include "ui/pages/BasePage.h" #include "ui/widgets/ProgressWidget.h" @@ -77,7 +77,7 @@ class ResourcePage : public QWidget, public BasePage { protected slots: virtual void triggerSearch() {} - + void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); void onResourceSelected(); diff --git a/launcher/ui/pages/modplatform/ShaderPackModel.h b/launcher/ui/pages/modplatform/ShaderPackModel.h index 17a07aa49..f3c695e9f 100644 --- a/launcher/ui/pages/modplatform/ShaderPackModel.h +++ b/launcher/ui/pages/modplatform/ShaderPackModel.h @@ -28,7 +28,6 @@ class ShaderPackResourceModel : public ResourceModel { void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0; void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0; - ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) override = 0; public slots: ResourceAPI::SearchArgs createSearchArguments() override; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp index 08bf22fef..b233a8459 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp @@ -57,11 +57,6 @@ void FlameResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto FlameResourcePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion -{ - return FlameMod::loadDependencyVersions(m, arr); -}; - auto FlameResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return Json::ensureArray(obj.object(), "data"); @@ -98,11 +93,6 @@ void FlameTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, m.versions = filtered_versions; } -auto FlameTexturePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion -{ - return FlameMod::loadDependencyVersions(m, arr); -}; - ResourceAPI::SearchArgs FlameTexturePackModel::createSearchArguments() { auto args = TexturePackResourceModel::createSearchArguments(); diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h index 7871d9aa5..f3ef918ad 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h @@ -43,7 +43,6 @@ class FlameResourcePackModel : public ResourcePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -62,7 +61,6 @@ class FlameTexturePackModel : public TexturePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp index 53be2d2ca..e9f09387e 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp @@ -69,11 +69,6 @@ void ModrinthResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthResourcePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion -{ - return ::Modrinth::loadDependencyVersions(m, arr); -}; - auto ModrinthResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); @@ -96,11 +91,6 @@ void ModrinthTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthTexturePackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion -{ - return ::Modrinth::loadDependencyVersions(m, arr); -}; - auto ModrinthTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); @@ -123,11 +113,6 @@ void ModrinthShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance); } -auto ModrinthShaderPackModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion -{ - return ::Modrinth::loadDependencyVersions(m, arr); -}; - auto ModrinthShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h index 0045fe86c..6cd19c415 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h @@ -59,7 +59,6 @@ class ModrinthResourcePackModel : public ResourcePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -78,7 +77,6 @@ class ModrinthTexturePackModel : public TexturePackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; @@ -97,7 +95,6 @@ class ModrinthShaderPackModel : public ShaderPackResourceModel { void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; }; From 2c744da9f7352073e744015a4c1da42794bcd004 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 20 Apr 2023 22:51:20 +0300 Subject: [PATCH 017/429] More cleanup Signed-off-by: Trial97 --- launcher/minecraft/mod/MetadataHandler.h | 55 ++++++++++++------- .../ui/dialogs/ResourceDownloadDialog.cpp | 1 - .../ui/pages/modplatform/ResourceModel.cpp | 3 - launcher/ui/pages/modplatform/ResourceModel.h | 2 - 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index ea9078e04..39723b49c 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln - * - * 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 . - */ +* PolyMC - Minecraft Launcher +* Copyright (c) 2022 flowln +* +* 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 @@ -42,13 +42,28 @@ class Metadata { return Packwiz::V1::createModFormat(index_dir, internal_mod, mod_slug); } - static void update(QDir& index_dir, ModStruct& mod) { Packwiz::V1::updateModIndex(index_dir, mod); } + static void update(QDir& index_dir, ModStruct& mod) + { + Packwiz::V1::updateModIndex(index_dir, mod); + } - static void remove(QDir& index_dir, QString mod_slug) { Packwiz::V1::deleteModIndex(index_dir, mod_slug); } + static void remove(QDir& index_dir, QString mod_slug) + { + Packwiz::V1::deleteModIndex(index_dir, mod_slug); + } - static void remove(QDir& index_dir, QVariant& mod_id) { Packwiz::V1::deleteModIndex(index_dir, mod_id); } + static void remove(QDir& index_dir, QVariant& mod_id) + { + Packwiz::V1::deleteModIndex(index_dir, mod_id); + } - static auto get(QDir& index_dir, QString mod_slug) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_slug); } + 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 get(QDir& index_dir, QVariant& mod_id) -> ModStruct + { + return Packwiz::V1::getIndexForMod(index_dir, mod_id); + } }; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index dc1d927e8..38c573611 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -185,7 +185,6 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage() void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed) { - qWarning() << "DebugName: " << pack.name; removeResource(pack, ver); ver.is_currently_selected = true; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index b1e936f8c..db7d26f86 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -3,8 +3,6 @@ // SPDX-License-Identifier: GPL-3.0-only #include "ResourceModel.h" -#include -#include #include #include @@ -16,7 +14,6 @@ #include "BuildConfig.h" #include "Json.h" -#include "minecraft/mod/tasks/GetModDependenciesTask.h" #include "net/Download.h" #include "net/NetJob.h" diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index c08445897..46a02d6ef 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -4,14 +4,12 @@ #pragma once -#include #include #include #include "QObjectPtr.h" -#include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" #include "tasks/ConcurrentTask.h" From b4fa6e120a98fde89443b262f351412f36de7566 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 21 Apr 2023 18:41:40 +0300 Subject: [PATCH 018/429] Fixed tipo Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameAPI.h | 2 +- launcher/modplatform/helpers/NetworkResourceAPI.cpp | 4 ++-- launcher/modplatform/helpers/NetworkResourceAPI.h | 2 +- launcher/modplatform/modrinth/ModrinthAPI.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 91993e64c..3b4af9527 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -85,7 +85,7 @@ class FlameAPI : public NetworkResourceAPI { return url + get_parameters.join('&'); }; - [[nodiscard]] std::optional getDependecyURL(DependencySearchArgs const& args) const override + [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%") .arg(args.dependency.addonId.toString()) diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.cpp b/launcher/modplatform/helpers/NetworkResourceAPI.cpp index a7f763d36..9f95cde4f 100644 --- a/launcher/modplatform/helpers/NetworkResourceAPI.cpp +++ b/launcher/modplatform/helpers/NetworkResourceAPI.cpp @@ -123,13 +123,13 @@ Task::Ptr NetworkResourceAPI::getProject(QString addonId, QByteArray* response) Task::Ptr NetworkResourceAPI::getDependencyVersion(DependencySearchArgs&& args, DependencySearchCallbacks&& callbacks) const { - auto versions_url_optional = getDependecyURL(args); + auto versions_url_optional = getDependencyURL(args); if (!versions_url_optional.has_value()) return nullptr; auto versions_url = versions_url_optional.value(); - auto netJob = makeShared(QString("%1::Dependecy").arg(args.dependency.addonId.toString()), APPLICATION->network()); + auto netJob = makeShared(QString("%1::Dependency").arg(args.dependency.addonId.toString()), APPLICATION->network()); auto response = new QByteArray(); netJob->addNetAction(Net::Download::makeByteArray(versions_url, response)); diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.h b/launcher/modplatform/helpers/NetworkResourceAPI.h index bbe0a2c76..938657137 100644 --- a/launcher/modplatform/helpers/NetworkResourceAPI.h +++ b/launcher/modplatform/helpers/NetworkResourceAPI.h @@ -20,5 +20,5 @@ class NetworkResourceAPI : public ResourceAPI { [[nodiscard]] virtual auto getSearchURL(SearchArgs const& args) const -> std::optional = 0; [[nodiscard]] virtual auto getInfoURL(QString const& id) const -> std::optional = 0; [[nodiscard]] virtual auto getVersionsURL(VersionSearchArgs const& args) const -> std::optional = 0; - [[nodiscard]] virtual auto getDependecyURL(DependencySearchArgs const& args) const -> std::optional = 0; + [[nodiscard]] virtual auto getDependencyURL(DependencySearchArgs const& args) const -> std::optional = 0; }; diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 2d6049bae..07c8cf2a3 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -143,7 +143,7 @@ class ModrinthAPI : public NetworkResourceAPI { inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool { return loaders & (Forge | Fabric | Quilt); } - [[nodiscard]] std::optional getDependecyURL(DependencySearchArgs const& args) const override + [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { return args.dependency.version.length() != 0 ? QString("%1/version/%2").arg(BuildConfig.MODRINTH_PROD_URL, args.dependency.version) : QString("%1/project/%2/version?game_versions=[\"%1\"]&loaders=[\"%1\"]") From 42bc91463e8dc7c078476c8606937552ce623c62 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 21 Apr 2023 20:37:17 +0300 Subject: [PATCH 019/429] Updated links Signed-off-by: Trial97 --- launcher/ResourceDownloadTask.h | 3 ++- launcher/modplatform/flame/FlameAPI.h | 2 +- launcher/modplatform/modrinth/ModrinthAPI.h | 2 +- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 12 ++++++++---- launcher/ui/dialogs/ReviewMessageBox.cpp | 12 ++++++++++-- launcher/ui/dialogs/ReviewMessageBox.h | 7 ++++--- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index 29d3ae0af..a12c05b8d 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -38,7 +38,8 @@ class ResourceDownloadTask : public SequentialTask { const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } const ModPlatform::IndexedVersion& getVersion() const { return m_pack_version; } - const ModPlatform::IndexedPack& getPack() const { return m_pack; } + ModPlatform::IndexedPack& getPack() { return m_pack; } + const ModPlatform::ResourceProvider& getProvider() const { return m_pack.provider; } private: ModPlatform::IndexedPack m_pack; diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 3b4af9527..4ffc36d29 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -87,7 +87,7 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { - return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%") + return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%3") .arg(args.dependency.addonId.toString()) .arg(args.mcVersion.toString()) .arg(getMappedModLoader(args.loader)); diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 07c8cf2a3..95722ccb3 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -146,7 +146,7 @@ class ModrinthAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { return args.dependency.version.length() != 0 ? QString("%1/version/%2").arg(BuildConfig.MODRINTH_PROD_URL, args.dependency.version) - : QString("%1/project/%2/version?game_versions=[\"%1\"]&loaders=[\"%1\"]") + : QString("%1/project/%2/version?game_versions=[\"%3\"]&loaders=[\"%4\"]") .arg(BuildConfig.MODRINTH_PROD_URL) .arg(args.dependency.addonId.toString()) .arg(args.mcVersion.toString()) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 38c573611..c16dcca7b 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -124,6 +124,8 @@ 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())); @@ -160,7 +162,8 @@ void ResourceDownloadDialog::confirm() keys.sort(Qt::CaseInsensitive); for (auto& task : keys) { auto selected = m_selected.constFind(task).value(); - confirm_dialog->appendResource({ task, selected->getFilename(), selected->getCustomPath() }); + confirm_dialog->appendResource( + { task, selected->getFilename(), selected->getCustomPath(), ProviderCaps.name(selected->getProvider()) }); } if (confirm_dialog->exec()) { @@ -206,9 +209,10 @@ void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModP if (auto selected_task_it = m_selected.find(pack.name); selected_task_it != m_selected.end()) { auto selected_task = *selected_task_it; auto old_version_id = selected_task->getVersionID(); - - // If the new and old version IDs don't match, search for the old one and deselect it. - if (ver.fileId != old_version_id) + if (selected_task->getProvider() != pack.provider) // If the pack name matches but they are different providers search for the + // old one(in the actual pack) and deselect it. + getVersionWithID(selected_task->getPack(), old_version_id).is_currently_selected = false; + else if (ver.fileId != old_version_id) // If the new and old version IDs don't match, search for the old one and deselect it. getVersionWithID(pack, old_version_id).is_currently_selected = false; } diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp index 7b2df2780..86e68aae8 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.cpp +++ b/launcher/ui/dialogs/ReviewMessageBox.cpp @@ -40,7 +40,8 @@ void ReviewMessageBox::appendResource(ResourceInformation&& info) auto filenameItem = new QTreeWidgetItem(itemTop); filenameItem->setText(0, tr("Filename: %1").arg(info.filename)); - itemTop->insertChildren(0, { filenameItem }); + auto childIndx = 0; + itemTop->insertChildren(childIndx++, { filenameItem }); if (!info.custom_file_path.isEmpty()) { auto customPathItem = new QTreeWidgetItem(itemTop); @@ -49,9 +50,16 @@ void ReviewMessageBox::appendResource(ResourceInformation&& info) itemTop->insertChildren(1, { customPathItem }); itemTop->setIcon(1, QIcon(APPLICATION->getThemedIcon("status-yellow"))); - itemTop->setToolTip(1, tr("This file will be downloaded to a folder location different from the default, possibly due to its loader requiring it.")); + itemTop->setToolTip( + childIndx++, + tr("This file will be downloaded to a folder location different from the default, possibly due to its loader requiring it.")); } + auto providerItem = new QTreeWidgetItem(itemTop); + providerItem->setText(0, tr("Provider: %1").arg(info.provider)); + + itemTop->insertChildren(childIndx++, { providerItem }); + ui->modTreeWidget->addTopLevelItem(itemTop); } diff --git a/launcher/ui/dialogs/ReviewMessageBox.h b/launcher/ui/dialogs/ReviewMessageBox.h index 5ec2bc231..9579da335 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.h +++ b/launcher/ui/dialogs/ReviewMessageBox.h @@ -13,9 +13,10 @@ class ReviewMessageBox : public QDialog { static auto create(QWidget* parent, QString&& title, QString&& icon = "") -> ReviewMessageBox*; using ResourceInformation = struct res_info { - QString name; - QString filename; - QString custom_file_path {}; + QString name; + QString filename; + QString custom_file_path{}; + QString provider; }; void appendResource(ResourceInformation&& info); From 10aac4fe1721c3e1cf83bacefddc086918ca03da Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 21 Apr 2023 21:03:01 +0300 Subject: [PATCH 020/429] Fixed assert Signed-off-by: Trial97 --- launcher/ResourceDownloadTask.h | 52 ++++++++++--------- .../ui/dialogs/ResourceDownloadDialog.cpp | 21 ++++---- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index 73ad2d070..27c3c2ec2 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -1,41 +1,46 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* Prism Launcher - Minecraft Launcher -* Copyright (c) 2022-2023 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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 . -*/ + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022-2023 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "net/NetJob.h" #include "tasks/SequentialTask.h" -#include "modplatform/ModIndex.h" #include "minecraft/mod/tasks/LocalModUpdateTask.h" +#include "modplatform/ModIndex.h" class ResourceFolderModel; class ResourceDownloadTask : public SequentialTask { Q_OBJECT -public: - explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr packs, bool is_indexed = true); + public: + explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, + ModPlatform::IndexedVersion version, + const std::shared_ptr packs, + bool is_indexed = true); const QString& getFilename() const { return m_pack_version.fileName; } const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } + ModPlatform::IndexedPack& getPack() { return m_pack; } + const ModPlatform::ResourceProvider& getProvider() const { return m_pack.provider; } -private: + private: ModPlatform::IndexedPack m_pack; ModPlatform::IndexedVersion m_pack_version; const std::shared_ptr m_pack_model; @@ -47,11 +52,8 @@ private: void downloadFailed(QString reason); void downloadSucceeded(); - std::tuple to_delete {"", ""}; + std::tuple to_delete{ "", "" }; -private slots: + private slots: void hasOldResource(QString name, QString filename); }; - - - diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index edb7d063c..7fb4a6578 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -26,8 +26,8 @@ #include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ResourcePackFolderModel.h" -#include "minecraft/mod/TexturePackFolderModel.h" #include "minecraft/mod/ShaderPackFolderModel.h" +#include "minecraft/mod/TexturePackFolderModel.h" #include "ui/dialogs/ReviewMessageBox.h" @@ -41,7 +41,10 @@ namespace ResourceDownload { ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent, const std::shared_ptr base_model) - : QDialog(parent), m_base_model(base_model), m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel), m_vertical_layout(this) + : QDialog(parent) + , m_base_model(base_model) + , m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel) + , m_vertical_layout(this) { setObjectName(QStringLiteral("ResourceDownloadDialog")); @@ -102,7 +105,8 @@ void ResourceDownloadDialog::initializeContainer() void ResourceDownloadDialog::connectButtons() { auto OkButton = m_buttons.button(QDialogButtonBox::Ok); - OkButton->setToolTip(tr("Opens a new popup to review your selected %1 and confirm your selection. Shortcut: Ctrl+Return").arg(resourcesString())); + OkButton->setToolTip( + tr("Opens a new popup to review your selected %1 and confirm your selection. Shortcut: Ctrl+Return").arg(resourcesString())); connect(OkButton, &QPushButton::clicked, this, &ResourceDownloadDialog::confirm); auto CancelButton = m_buttons.button(QDialogButtonBox::Cancel); @@ -169,8 +173,10 @@ void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModP auto selected_task = *selected_task_it; auto old_version_id = selected_task->getVersionID(); - // If the new and old version IDs don't match, search for the old one and deselect it. - if (ver.fileId != old_version_id) + if (selected_task->getProvider() != pack.provider) // If the pack name matches but they are different providers search for the + // old one(in the actual pack) and deselect it. + getVersionWithID(selected_task->getPack(), old_version_id).is_currently_selected = false; + else if (ver.fileId != old_version_id) // If the new and old version IDs don't match, search for the old one and deselect it. getVersionWithID(pack, old_version_id).is_currently_selected = false; } @@ -205,8 +211,6 @@ void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* s m_selectedPage->setSearchTerm(prev_page->getSearchTerm()); } - - ModDownloadDialog::ModDownloadDialog(QWidget* parent, const std::shared_ptr& mods, BaseInstance* instance) : ResourceDownloadDialog(parent, mods), m_instance(instance) { @@ -232,7 +236,6 @@ QList ModDownloadDialog::getPages() return pages; } - ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent, const std::shared_ptr& resource_packs, BaseInstance* instance) @@ -258,7 +261,6 @@ QList ResourcePackDownloadDialog::getPages() return pages; } - TexturePackDownloadDialog::TexturePackDownloadDialog(QWidget* parent, const std::shared_ptr& resource_packs, BaseInstance* instance) @@ -284,7 +286,6 @@ QList TexturePackDownloadDialog::getPages() return pages; } - ShaderPackDownloadDialog::ShaderPackDownloadDialog(QWidget* parent, const std::shared_ptr& shaders, BaseInstance* instance) From f7931c2ee202025740caf424fa00ffb76743a1d2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 22 Apr 2023 00:47:51 +0300 Subject: [PATCH 021/429] Better version handling Signed-off-by: Trial97 --- launcher/ResourceDownloadTask.h | 1 - launcher/modplatform/ModIndex.h | 37 ++++++++++--------- .../ui/dialogs/ResourceDownloadDialog.cpp | 20 +--------- launcher/ui/pages/modplatform/ModModel.cpp | 16 +++++++- launcher/ui/pages/modplatform/ModPage.cpp | 18 ++++----- .../ui/pages/modplatform/ResourceModel.cpp | 30 +++++++++++++++ launcher/ui/pages/modplatform/ResourceModel.h | 4 ++ .../ui/pages/modplatform/ResourcePage.cpp | 6 +++ launcher/ui/pages/modplatform/ResourcePage.h | 3 +- .../ui/pages/modplatform/ShaderPackPage.cpp | 8 ++-- 10 files changed, 90 insertions(+), 53 deletions(-) diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index 27c3c2ec2..0d90bd360 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -37,7 +37,6 @@ class ResourceDownloadTask : public SequentialTask { const QString& getFilename() const { return m_pack_version.fileName; } const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } - ModPlatform::IndexedPack& getPack() { return m_pack; } const ModPlatform::ResourceProvider& getProvider() const { return m_pack.provider; } private: diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 40f1efc4e..de0af78c5 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -1,23 +1,24 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -95,6 +96,7 @@ struct IndexedPack { bool versionsLoaded = false; QVector versions; + QVariant loadedFileId; // to check for already downloaded mods // Don't load by default, since some modplatform don't have that info bool extraDataLoaded = true; @@ -110,11 +112,12 @@ struct IndexedPack { } [[nodiscard]] bool isAnyVersionSelected() const { + if (loadedFileId.isValid()) + return true; if (!versionsLoaded) return false; - return std::any_of(versions.constBegin(), versions.constEnd(), - [](auto const& v) { return v.is_currently_selected; }); + return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); } }; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 7fb4a6578..562dda33e 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -159,26 +159,10 @@ void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlat m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty()); } -static ModPlatform::IndexedVersion& getVersionWithID(ModPlatform::IndexedPack& pack, QVariant id) -{ - Q_ASSERT(pack.versionsLoaded); - auto it = std::find_if(pack.versions.begin(), pack.versions.end(), [id](auto const& v) { return v.fileId == id; }); - Q_ASSERT(it != pack.versions.end()); - return *it; -} - void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver) { - if (auto selected_task_it = m_selected.find(pack.name); selected_task_it != m_selected.end()) { - auto selected_task = *selected_task_it; - auto old_version_id = selected_task->getVersionID(); - - if (selected_task->getProvider() != pack.provider) // If the pack name matches but they are different providers search for the - // old one(in the actual pack) and deselect it. - getVersionWithID(selected_task->getPack(), old_version_id).is_currently_selected = false; - else if (ver.fileId != old_version_id) // If the new and old version IDs don't match, search for the old one and deselect it. - getVersionWithID(pack, old_version_id).is_currently_selected = false; - } + dynamic_cast(m_container->getPage(Modrinth::id()))->removeResourceFromPage(pack.name); + dynamic_cast(m_container->getPage(Flame::id()))->removeResourceFromPage(pack.name); // Deselect the new version too, since all versions of that pack got removed. ver.is_currently_selected = false; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 3ffe6cb06..b69d2cf9e 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -6,12 +6,24 @@ #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" #include namespace ResourceDownload { -ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(api), m_base_instance(base_inst) {} +ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(api), m_base_instance(base_inst) +{ + auto folder = static_cast(m_base_instance).loaderModList(); + for (auto mod : folder->allMods()) { + auto meta = mod->metadata(); + ModPlatform::IndexedPack pack{ meta->project_id, meta->provider, meta->name, meta->slug }; + pack.loadedFileId = meta->file_id; + qWarning() << pack.loadedFileId; + addPack(pack); + } +} /******** Make data requests ********/ @@ -24,7 +36,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() std::optional> versions{}; - { // Version filter + { // Version filter if (!m_filter->versions.empty()) versions = m_filter->versions; } diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 04be43ada..efff1ff40 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -55,8 +55,7 @@ namespace ResourceDownload { -ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance) - : ResourcePage(dialog, instance) +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); @@ -75,12 +74,10 @@ void ModPage::setFilterWidget(unique_qobject_ptr& widget) m_filter_widget->setInstance(&static_cast(m_base_instance)); m_filter = m_filter_widget->getFilter(); - 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"); - }); + 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"); }); } /******** Callbacks to events in the UI (set up in the derived classes) ********/ @@ -128,8 +125,8 @@ void ModPage::updateVersionList() 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){ - //NOTE: Flame doesn't care about loader, so passing it changes nothing. + for (auto& mcVer : m_filter->versions) { + // NOTE: Flame doesn't care about loader, so passing it changes nothing. if (validateVersion(version, mcVer.toString(), packProfile->getModLoaders())) { valid = true; break; @@ -151,6 +148,7 @@ void ModPage::updateVersionList() void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); + m_model->addPack(pack); m_parent_dialog->addResource(pack, version, is_indexed); } diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index db7d26f86..c7c34a7cb 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -3,12 +3,14 @@ // SPDX-License-Identifier: GPL-3.0-only #include "ResourceModel.h" +#include #include #include #include #include #include +#include #include "Application.h" #include "BuildConfig.h" @@ -335,6 +337,14 @@ void ResourceModel::searchRequestSucceeded(QJsonDocument& doc) ModPlatform::IndexedPack pack; try { loadIndexedPack(pack, packObj); + if (auto sel = + std::find_if(m_selected.begin(), m_selected.end(), + [&pack](ModPlatform::IndexedPack& i) { return i.provider == pack.provider && i.addonId == pack.addonId; }); + sel != m_selected.end()) { + pack.versionsLoaded = sel->versionsLoaded; + pack.versions = sel->versions; + pack.loadedFileId = sel->loadedFileId; + } newList.append(pack); } catch (const JSONValidationError& e) { qWarning() << "Error while loading resource from " << debugName() << ": " << e.cause(); @@ -398,6 +408,11 @@ void ResourceModel::versionRequestSucceeded(QJsonDocument& doc, ModPlatform::Ind try { auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); loadIndexedPackVersions(current_pack, arr); + if (current_pack.loadedFileId.isValid()) + if (auto ver = std::find_if(current_pack.versions.begin(), current_pack.versions.end(), + [¤t_pack](ModPlatform::IndexedVersion v) { return v.fileId == current_pack.loadedFileId; }); + ver != current_pack.versions.end()) + ver->is_currently_selected = true; } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading " << debugName() << " resource version: " << e.cause(); @@ -441,4 +456,19 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe emit projectInfoUpdated(); } +void ResourceModel::removePack(QString& rem) +{ + m_selected.removeIf([&rem](ModPlatform::IndexedPack i) { return rem == i.name; }); + auto pack = std::find_if(m_packs.begin(), m_packs.end(), [&rem](ModPlatform::IndexedPack i) { return rem == i.name; }); + if (pack == m_packs.end()) { // ignore it if is not in the current search + return; + } + if (!pack->versionsLoaded) { + pack->loadedFileId = {}; + return; + } + for (auto& ver : pack->versions) + ver.is_currently_selected = false; +} + } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 46a02d6ef..5eb639011 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -80,6 +80,9 @@ class ResourceModel : public QAbstractListModel { /** Gets the icon at the URL for the given index. If it's not fetched yet, fetch it and update when fisinhed. */ std::optional getIcon(QModelIndex&, const QUrl&); + void addPack(ModPlatform::IndexedPack& add) { m_selected.append(add); } + void removePack(QString& rem); + protected: /** Resets the model's data. */ void clearData(); @@ -124,6 +127,7 @@ class ResourceModel : public QAbstractListModel { QSet m_failed_icon_actions; QList m_packs; + QList m_selected; // HACK: We need this to prevent callbacks from calling the model after it has already been deleted. // This leaks a tiny bit of memory per time the user has opened a resource dialog. How to make this better? diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index bbd465bc1..24347dbd4 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -308,6 +308,7 @@ void ResourcePage::onVersionSelectionChanged(QString data) void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) { + m_model->addPack(pack); m_parent_dialog->addResource(pack, version); } @@ -316,6 +317,11 @@ void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModP m_parent_dialog->removeResource(pack, version); } +void ResourcePage::removeResourceFromPage(QString& name) +{ + m_model->removePack(name); +} + void ResourcePage::onResourceSelected() { if (m_selected_version_index < 0) diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index 1896d53ea..a9db52e30 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -74,10 +74,11 @@ class ResourcePage : public QWidget, public BasePage { virtual void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); virtual void removeResourceFromDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); + virtual void removeResourceFromPage(QString& name); protected slots: virtual void triggerSearch() {} - + void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); void onResourceSelected(); diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp index 251c07e71..1b9b2b83e 100644 --- a/launcher/ui/pages/modplatform/ShaderPackPage.cpp +++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp @@ -13,8 +13,7 @@ namespace ResourceDownload { -ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance) - : ResourcePage(dialog, instance) +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); @@ -38,7 +37,8 @@ QMap ShaderPackResourcePage::urlHandlers() const { QMap map; map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/shaders\\/([^\\/]+)\\/?"), "modrinth"); - map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/customization\\/([^\\/]+)\\/?"), "curseforge"); + map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/customization\\/([^\\/]+)\\/?"), + "curseforge"); map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge"); return map; } @@ -47,7 +47,7 @@ void ShaderPackResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, { if (version.loaders.contains(QStringLiteral("canvas"))) version.custom_target_folder = QStringLiteral("resourcepacks"); - + m_model->addPack(pack); m_parent_dialog->addResource(pack, version); } From 75116364c6daea5affb029038d2a7d20bc601beb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 22 Apr 2023 00:55:11 +0300 Subject: [PATCH 022/429] Small Cleanup Signed-off-by: Trial97 --- launcher/modplatform/ModIndex.h | 1 - launcher/ui/pages/modplatform/ModModel.cpp | 1 - launcher/ui/pages/modplatform/ResourceModel.cpp | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index de0af78c5..b736aaf41 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -18,7 +18,6 @@ #pragma once -#include #include #include #include diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index b69d2cf9e..251200f77 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -20,7 +20,6 @@ ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceMo auto meta = mod->metadata(); ModPlatform::IndexedPack pack{ meta->project_id, meta->provider, meta->name, meta->slug }; pack.loadedFileId = meta->file_id; - qWarning() << pack.loadedFileId; addPack(pack); } } diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index c7c34a7cb..0e74395fb 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -3,10 +3,10 @@ // SPDX-License-Identifier: GPL-3.0-only #include "ResourceModel.h" -#include #include #include +#include #include #include #include From 460e83207f9ae087846fc9ca210799e41f51a326 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 22 Apr 2023 01:18:27 +0300 Subject: [PATCH 023/429] Fixed removeIf for Qt version Signed-off-by: Trial97 --- .../ui/pages/modplatform/ResourceModel.cpp | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 0e74395fb..459c8c726 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -458,7 +458,39 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe void ResourceModel::removePack(QString& rem) { - m_selected.removeIf([&rem](ModPlatform::IndexedPack i) { return rem == i.name; }); + auto pred = [&rem](ModPlatform::IndexedPack i) { return rem == i.name; }; +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) + m_selected.removeIf(pred); +#else + { // well partial implementation of remove_if in case the QT Version is not high enough + const auto cbegin = m_selected.cbegin(); + const auto cend = m_selected.cend(); + const auto t_it = std::find_if(cbegin, cend, pred); + auto result = std::distance(cbegin, t_it); + if (result != m_selected.size()) { + // now detach: + const auto e = m_selected.end(); + + auto it = std::next(m_selected.begin(), result); + auto dest = it; + + // Loop Invariants: + // - it != e + // - [next(it), e[ still to be checked + // - [c.begin(), dest[ are result + while (++it != e) { + if (!pred(*it)) { + *dest = std::move(*it); + ++dest; + } + } + + result = std::distance(dest, e); + m_selected.erase(dest, e); + } + } +#endif + // m_selected.removeAt(qsizetype i) auto pack = std::find_if(m_packs.begin(), m_packs.end(), [&rem](ModPlatform::IndexedPack i) { return rem == i.name; }); if (pack == m_packs.end()) { // ignore it if is not in the current search return; From f738d7566e45f618634c4d40ec45f78f96fac588 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 22 Apr 2023 22:27:33 +0300 Subject: [PATCH 024/429] Fixed code qulity Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourceModel.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 459c8c726..a58ce549d 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -337,9 +337,9 @@ void ResourceModel::searchRequestSucceeded(QJsonDocument& doc) ModPlatform::IndexedPack pack; try { loadIndexedPack(pack, packObj); - if (auto sel = - std::find_if(m_selected.begin(), m_selected.end(), - [&pack](ModPlatform::IndexedPack& i) { return i.provider == pack.provider && i.addonId == pack.addonId; }); + if (auto sel = std::find_if( + m_selected.begin(), m_selected.end(), + [&pack](const ModPlatform::IndexedPack& i) { return i.provider == pack.provider && i.addonId == pack.addonId; }); sel != m_selected.end()) { pack.versionsLoaded = sel->versionsLoaded; pack.versions = sel->versions; @@ -409,8 +409,9 @@ void ResourceModel::versionRequestSucceeded(QJsonDocument& doc, ModPlatform::Ind auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); loadIndexedPackVersions(current_pack, arr); if (current_pack.loadedFileId.isValid()) - if (auto ver = std::find_if(current_pack.versions.begin(), current_pack.versions.end(), - [¤t_pack](ModPlatform::IndexedVersion v) { return v.fileId == current_pack.loadedFileId; }); + if (auto ver = + std::find_if(current_pack.versions.begin(), current_pack.versions.end(), + [¤t_pack](const ModPlatform::IndexedVersion& v) { return v.fileId == current_pack.loadedFileId; }); ver != current_pack.versions.end()) ver->is_currently_selected = true; } catch (const JSONValidationError& e) { @@ -458,7 +459,7 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe void ResourceModel::removePack(QString& rem) { - auto pred = [&rem](ModPlatform::IndexedPack i) { return rem == i.name; }; + auto pred = [&rem](const ModPlatform::IndexedPack& i) { return rem == i.name; }; #if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) m_selected.removeIf(pred); #else @@ -491,7 +492,7 @@ void ResourceModel::removePack(QString& rem) } #endif // m_selected.removeAt(qsizetype i) - auto pack = std::find_if(m_packs.begin(), m_packs.end(), [&rem](ModPlatform::IndexedPack i) { return rem == i.name; }); + auto pack = std::find_if(m_packs.begin(), m_packs.end(), [&rem](const ModPlatform::IndexedPack& i) { return rem == i.name; }); if (pack == m_packs.end()) { // ignore it if is not in the current search return; } From 248920a2211db0c55d01273cc36c735a629b0325 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 27 Apr 2023 01:33:46 +0300 Subject: [PATCH 025/429] Removed extra code Signed-off-by: Trial97 --- launcher/modplatform/ModIndex.h | 3 -- .../ui/dialogs/ResourceDownloadDialog.cpp | 4 +- launcher/ui/pages/modplatform/ModModel.cpp | 11 +---- launcher/ui/pages/modplatform/ModPage.cpp | 2 +- .../ui/pages/modplatform/ResourceModel.cpp | 41 +++---------------- .../ui/pages/modplatform/ResourcePage.cpp | 2 +- .../ui/pages/modplatform/ShaderPackPage.cpp | 2 +- launcher/ui/widgets/PageContainer.cpp | 5 +++ launcher/ui/widgets/PageContainer.h | 1 + 9 files changed, 18 insertions(+), 53 deletions(-) diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index b736aaf41..4497088c7 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -95,7 +95,6 @@ struct IndexedPack { bool versionsLoaded = false; QVector versions; - QVariant loadedFileId; // to check for already downloaded mods // Don't load by default, since some modplatform don't have that info bool extraDataLoaded = true; @@ -111,8 +110,6 @@ struct IndexedPack { } [[nodiscard]] bool isAnyVersionSelected() const { - if (loadedFileId.isValid()) - return true; if (!versionsLoaded) return false; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 562dda33e..4ba383749 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -161,8 +161,8 @@ void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlat void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver) { - dynamic_cast(m_container->getPage(Modrinth::id()))->removeResourceFromPage(pack.name); - dynamic_cast(m_container->getPage(Flame::id()))->removeResourceFromPage(pack.name); + for (auto page : m_container->getPages()) + static_cast(page)->removeResourceFromPage(pack.name); // Deselect the new version too, since all versions of that pack got removed. ver.is_currently_selected = false; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 251200f77..6a206a7c4 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -13,16 +13,7 @@ namespace ResourceDownload { -ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(api), m_base_instance(base_inst) -{ - auto folder = static_cast(m_base_instance).loaderModList(); - for (auto mod : folder->allMods()) { - auto meta = mod->metadata(); - ModPlatform::IndexedPack pack{ meta->project_id, meta->provider, meta->name, meta->slug }; - pack.loadedFileId = meta->file_id; - addPack(pack); - } -} +ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(api), m_base_instance(base_inst) {} /******** Make data requests ********/ diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index efff1ff40..8a4f55cb7 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -148,8 +148,8 @@ void ModPage::updateVersionList() void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); - m_model->addPack(pack); m_parent_dialog->addResource(pack, version, is_indexed); + m_model->addPack(pack); } } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index a58ce549d..b83cad0dc 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -343,7 +343,6 @@ void ResourceModel::searchRequestSucceeded(QJsonDocument& doc) sel != m_selected.end()) { pack.versionsLoaded = sel->versionsLoaded; pack.versions = sel->versions; - pack.loadedFileId = sel->loadedFileId; } newList.append(pack); } catch (const JSONValidationError& e) { @@ -408,12 +407,6 @@ void ResourceModel::versionRequestSucceeded(QJsonDocument& doc, ModPlatform::Ind try { auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); loadIndexedPackVersions(current_pack, arr); - if (current_pack.loadedFileId.isValid()) - if (auto ver = - std::find_if(current_pack.versions.begin(), current_pack.versions.end(), - [¤t_pack](const ModPlatform::IndexedVersion& v) { return v.fileId == current_pack.loadedFileId; }); - ver != current_pack.versions.end()) - ver->is_currently_selected = true; } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading " << debugName() << " resource version: " << e.cause(); @@ -463,41 +456,19 @@ void ResourceModel::removePack(QString& rem) #if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) m_selected.removeIf(pred); #else - { // well partial implementation of remove_if in case the QT Version is not high enough - const auto cbegin = m_selected.cbegin(); - const auto cend = m_selected.cend(); - const auto t_it = std::find_if(cbegin, cend, pred); - auto result = std::distance(cbegin, t_it); - if (result != m_selected.size()) { - // now detach: - const auto e = m_selected.end(); - - auto it = std::next(m_selected.begin(), result); - auto dest = it; - - // Loop Invariants: - // - it != e - // - [next(it), e[ still to be checked - // - [c.begin(), dest[ are result - while (++it != e) { - if (!pred(*it)) { - *dest = std::move(*it); - ++dest; - } - } - - result = std::distance(dest, e); - m_selected.erase(dest, e); - } + { + for (auto it = m_selected.begin(); it != m_selected.end();) + if (pred(*it)) + it = m_selected.erase(it); + else + ++it; } #endif - // m_selected.removeAt(qsizetype i) auto pack = std::find_if(m_packs.begin(), m_packs.end(), [&rem](const ModPlatform::IndexedPack& i) { return rem == i.name; }); if (pack == m_packs.end()) { // ignore it if is not in the current search return; } if (!pack->versionsLoaded) { - pack->loadedFileId = {}; return; } for (auto& ver : pack->versions) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 24347dbd4..d41503e8e 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -308,8 +308,8 @@ void ResourcePage::onVersionSelectionChanged(QString data) void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) { - m_model->addPack(pack); m_parent_dialog->addResource(pack, version); + m_model->addPack(pack); } void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp index 1b9b2b83e..729e714c0 100644 --- a/launcher/ui/pages/modplatform/ShaderPackPage.cpp +++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp @@ -47,8 +47,8 @@ void ShaderPackResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, { if (version.loaders.contains(QStringLiteral("canvas"))) version.custom_target_folder = QStringLiteral("resourcepacks"); - m_model->addPack(pack); m_parent_dialog->addResource(pack, version); + m_model->addPack(pack); } } // namespace ResourceDownload diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 0a06a3518..84a4e0de6 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -135,6 +135,11 @@ BasePage* PageContainer::getPage(QString pageId) return m_model->findPageEntryById(pageId); } +const QList PageContainer::getPages() const +{ + return m_model->pages(); +} + void PageContainer::refreshContainer() { m_proxyModel->invalidate(); diff --git a/launcher/ui/widgets/PageContainer.h b/launcher/ui/widgets/PageContainer.h index 97e294dcf..ad74d43a2 100644 --- a/launcher/ui/widgets/PageContainer.h +++ b/launcher/ui/widgets/PageContainer.h @@ -80,6 +80,7 @@ public: virtual bool selectPage(QString pageId) override; BasePage* getPage(QString pageId) override; + const QList getPages() const; void refreshContainer() override; virtual void setParentContainer(BasePageContainer * container) From 61a235561896fc82a19da00126e361bb56d61c69 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 27 Apr 2023 01:41:26 +0300 Subject: [PATCH 026/429] Removed formated but not used files Signed-off-by: Trial97 --- launcher/ResourceDownloadTask.h | 51 +++++++++++----------- launcher/modplatform/ModIndex.h | 33 +++++++------- launcher/ui/pages/modplatform/ModModel.cpp | 4 +- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index 0d90bd360..73ad2d070 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -1,45 +1,41 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2022-2023 flowln - * Copyright (C) 2022 Sefa Eyeoglu - * - * 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 . - */ +* Prism Launcher - Minecraft Launcher +* Copyright (c) 2022-2023 flowln +* Copyright (C) 2022 Sefa Eyeoglu +* +* 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 "net/NetJob.h" #include "tasks/SequentialTask.h" -#include "minecraft/mod/tasks/LocalModUpdateTask.h" #include "modplatform/ModIndex.h" +#include "minecraft/mod/tasks/LocalModUpdateTask.h" class ResourceFolderModel; class ResourceDownloadTask : public SequentialTask { Q_OBJECT - public: - explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, - ModPlatform::IndexedVersion version, - const std::shared_ptr packs, - bool is_indexed = true); +public: + explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr packs, bool is_indexed = true); const QString& getFilename() const { return m_pack_version.fileName; } const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } - const ModPlatform::ResourceProvider& getProvider() const { return m_pack.provider; } - private: +private: ModPlatform::IndexedPack m_pack; ModPlatform::IndexedVersion m_pack_version; const std::shared_ptr m_pack_model; @@ -51,8 +47,11 @@ class ResourceDownloadTask : public SequentialTask { void downloadFailed(QString reason); void downloadSucceeded(); - std::tuple to_delete{ "", "" }; + std::tuple to_delete {"", ""}; - private slots: +private slots: void hasOldResource(QString name, QString filename); }; + + + diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 4497088c7..40f1efc4e 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln - * - * 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 . - */ +* PolyMC - Minecraft Launcher +* Copyright (c) 2022 flowln +* +* 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 @@ -113,7 +113,8 @@ struct IndexedPack { if (!versionsLoaded) return false; - return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); + return std::any_of(versions.constBegin(), versions.constEnd(), + [](auto const& v) { return v.is_currently_selected; }); } }; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 6a206a7c4..3ffe6cb06 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -6,8 +6,6 @@ #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "minecraft/mod/ModFolderModel.h" -#include "modplatform/ModIndex.h" #include @@ -26,7 +24,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() std::optional> versions{}; - { // Version filter + { // Version filter if (!m_filter->versions.empty()) versions = m_filter->versions; } From f8bf71e152aba15d23b5b92382bb112de125d4d1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 3 May 2023 00:49:54 +0300 Subject: [PATCH 027/429] Moved the selected resources to one list Signed-off-by: Trial97 --- launcher/ResourceDownloadTask.cpp | 11 ++-- launcher/ResourceDownloadTask.h | 25 ++++---- launcher/modplatform/ModIndex.h | 1 - .../ui/dialogs/ResourceDownloadDialog.cpp | 59 +++++++++++-------- launcher/ui/dialogs/ResourceDownloadDialog.h | 9 +-- launcher/ui/pages/modplatform/ModPage.cpp | 7 ++- launcher/ui/pages/modplatform/ModPage.h | 2 +- .../ui/pages/modplatform/ResourceModel.cpp | 29 ++++++--- launcher/ui/pages/modplatform/ResourceModel.h | 14 ++++- .../ui/pages/modplatform/ResourcePage.cpp | 17 ++++-- launcher/ui/pages/modplatform/ResourcePage.h | 13 +++- .../ui/pages/modplatform/ShaderPackPage.cpp | 10 ++-- .../ui/pages/modplatform/ShaderPackPage.h | 2 +- 13 files changed, 124 insertions(+), 75 deletions(-) diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp index 98bcf2592..f7d3487ad 100644 --- a/launcher/ResourceDownloadTask.cpp +++ b/launcher/ResourceDownloadTask.cpp @@ -27,8 +27,9 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr packs, - bool is_indexed) - : m_pack(std::move(pack)), m_pack_version(std::move(version)), m_pack_model(packs) + bool is_indexed, + QString custom_target_folder) + : m_pack(std::move(pack)), m_pack_version(std::move(version)), m_pack_model(packs), m_custom_target_folder(custom_target_folder) { if (auto model = dynamic_cast(m_pack_model.get()); model && is_indexed) { m_update_task.reset(new LocalModUpdateTask(model->indexDir(), m_pack, m_pack_version)); @@ -40,13 +41,13 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack pack, m_filesNetJob.reset(new NetJob(tr("Resource download"), APPLICATION->network())); m_filesNetJob->setStatus(tr("Downloading resource:\n%1").arg(m_pack_version.downloadUrl)); - QDir dir { m_pack_model->dir() }; + QDir dir{ m_pack_model->dir() }; { // FIXME: Make this more generic. May require adding additional info to IndexedVersion, // or adquiring a reference to the base instance. - if (!m_pack_version.custom_target_folder.isEmpty()) { + if (!m_custom_target_folder.isEmpty()) { dir.cdUp(); - dir.cd(m_pack_version.custom_target_folder); + dir.cd(m_custom_target_folder); } } diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index 73ad2d070..fe41170a8 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -22,23 +22,31 @@ #include "net/NetJob.h" #include "tasks/SequentialTask.h" -#include "modplatform/ModIndex.h" #include "minecraft/mod/tasks/LocalModUpdateTask.h" +#include "modplatform/ModIndex.h" class ResourceFolderModel; class ResourceDownloadTask : public SequentialTask { Q_OBJECT -public: - explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr packs, bool is_indexed = true); + public: + explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, + ModPlatform::IndexedVersion version, + const std::shared_ptr packs, + bool is_indexed = true, + QString custom_target_folder = {}); const QString& getFilename() const { return m_pack_version.fileName; } - const QString& getCustomPath() const { return m_pack_version.custom_target_folder; } + const QString& getCustomPath() const { return m_custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } + const QString& getName() const { return m_pack.name; } + ModPlatform::IndexedPack& getPack() { return m_pack; } + // void setSelectedVersion(ModPlatform::IndexedVersion version) { m_pack_version = std::move(version); } -private: + private: ModPlatform::IndexedPack m_pack; ModPlatform::IndexedVersion m_pack_version; const std::shared_ptr m_pack_model; + QString m_custom_target_folder; NetJob::Ptr m_filesNetJob; LocalModUpdateTask::Ptr m_update_task; @@ -47,11 +55,8 @@ private: void downloadFailed(QString reason); void downloadSucceeded(); - std::tuple to_delete {"", ""}; + std::tuple to_delete{ "", "" }; -private slots: + private slots: void hasOldResource(QString name, QString filename); }; - - - diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 40f1efc4e..1b99a88e1 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -68,7 +68,6 @@ struct IndexedVersion { // For internal use, not provided by APIs bool is_currently_selected = false; - QString custom_target_folder; }; struct ExtraPackData { diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 4ba383749..ef3200a25 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -20,6 +20,7 @@ #include "ResourceDownloadDialog.h" #include +#include #include "Application.h" #include "ResourceDownloadTask.h" @@ -118,21 +119,24 @@ void ResourceDownloadDialog::connectButtons() void ResourceDownloadDialog::confirm() { - auto keys = m_selected.keys(); - keys.sort(Qt::CaseInsensitive); + auto selected = getTasks(); + std::sort(selected.begin(), selected.end(), [](const DownloadTaskPtr& a, const DownloadTaskPtr& b) { + return QString::compare(a->getName(), b->getName(), Qt::CaseInsensitive) < 0; + }); auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString())); confirm_dialog->retranslateUi(resourcesString()); - for (auto& task : keys) { - auto selected = m_selected.constFind(task).value(); - confirm_dialog->appendResource({ task, selected->getFilename(), selected->getCustomPath() }); + for (auto& task : selected) { + confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath() }); } if (confirm_dialog->exec()) { auto deselected = confirm_dialog->deselectedResources(); - for (auto name : deselected) { - m_selected.remove(name); + for (auto page : m_container->getPages()) { + auto res = static_cast(page); + for (auto name : deselected) + res->removeResourceFromPage(name); } this->accept(); @@ -149,32 +153,39 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage() return m_selectedPage; } -void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed) +void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver) { - removeResource(pack, ver); - - ver.is_currently_selected = true; - m_selected.insert(pack.name, makeShared(pack, ver, getBaseModel(), is_indexed)); - - m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty()); + removeResource(pack.name); + m_selectedPage->addResourceToPage(pack, ver, getBaseModel()); + setButtonStatus(); } -void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver) +void ResourceDownloadDialog::removeResource(const QString& pack_name) { - for (auto page : m_container->getPages()) - static_cast(page)->removeResourceFromPage(pack.name); + for (auto page : m_container->getPages()) { + static_cast(page)->removeResourceFromPage(pack_name); + } + setButtonStatus(); +} - // Deselect the new version too, since all versions of that pack got removed. - ver.is_currently_selected = false; - - m_selected.remove(pack.name); - - m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty()); +void ResourceDownloadDialog::setButtonStatus() +{ + bool selected; + for (auto page : m_container->getPages()) { + auto res = static_cast(page); + selected = selected || res->hasSelectedPacks(); + } + m_buttons.button(QDialogButtonBox::Ok)->setEnabled(selected); } const QList ResourceDownloadDialog::getTasks() { - return m_selected.values(); + QList selected; + for (auto page : m_container->getPages()) { + auto res = static_cast(page); + selected.append(res->selectedPacks()); + } + return selected; } void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* selected) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h index 5678dc8bb..204e870fd 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.h +++ b/launcher/ui/dialogs/ResourceDownloadDialog.h @@ -62,8 +62,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { bool selectPage(QString pageId); ResourcePage* getSelectedPage(); - void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, bool is_indexed = false); - void removeResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); + void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); + void removeResource(const QString&); const QList getTasks(); [[nodiscard]] const std::shared_ptr getBaseModel() const { return m_base_model; } @@ -79,6 +79,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { protected: [[nodiscard]] virtual QString geometrySaveKey() const { return ""; } + void setButtonStatus(); protected: const std::shared_ptr m_base_model; @@ -88,12 +89,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { QDialogButtonBox m_buttons; QVBoxLayout m_vertical_layout; - - QHash m_selected; }; - - class ModDownloadDialog final : public ResourceDownloadDialog { Q_OBJECT diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 8a4f55cb7..a6186d89c 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -145,11 +145,12 @@ void ModPage::updateVersionList() updateSelectionButton(); } -void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) +void ModPage::addResourceToPage(ModPlatform::IndexedPack& pack, + ModPlatform::IndexedVersion& version, + const std::shared_ptr base_model) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); - m_parent_dialog->addResource(pack, version, is_indexed); - m_model->addPack(pack); + m_model->addPack(pack, version, base_model, is_indexed); } } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index c3b58cd63..6ecf8a947 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -50,7 +50,7 @@ class ModPage : public ResourcePage { [[nodiscard]] QMap urlHandlers() const override; - void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&) override; + void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr) override; virtual auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional loaders = {}) const -> bool = 0; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index b83cad0dc..056b28cce 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -337,14 +337,15 @@ void ResourceModel::searchRequestSucceeded(QJsonDocument& doc) ModPlatform::IndexedPack pack; try { loadIndexedPack(pack, packObj); - if (auto sel = std::find_if( - m_selected.begin(), m_selected.end(), - [&pack](const ModPlatform::IndexedPack& i) { return i.provider == pack.provider && i.addonId == pack.addonId; }); + if (auto sel = std::find_if(m_selected.begin(), m_selected.end(), + [&pack](const DownloadTaskPtr i) { + const auto ipack = i->getPack(); + return ipack.provider == pack.provider && ipack.addonId == pack.addonId; + }); sel != m_selected.end()) { - pack.versionsLoaded = sel->versionsLoaded; - pack.versions = sel->versions; - } - newList.append(pack); + newList.append(sel->get()->getPack()); + } else + newList.append(pack); } catch (const JSONValidationError& e) { qWarning() << "Error while loading resource from " << debugName() << ": " << e.cause(); continue; @@ -450,9 +451,19 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe emit projectInfoUpdated(); } -void ResourceModel::removePack(QString& rem) +void ResourceModel::addPack(ModPlatform::IndexedPack& pack, + ModPlatform::IndexedVersion& version, + const std::shared_ptr packs, + bool is_indexed, + QString custom_target_folder) { - auto pred = [&rem](const ModPlatform::IndexedPack& i) { return rem == i.name; }; + version.is_currently_selected = true; + m_selected.append(makeShared(pack, version, packs, is_indexed, custom_target_folder)); +} + +void ResourceModel::removePack(const QString& rem) +{ + auto pred = [&rem](const DownloadTaskPtr i) { return rem == i->getName(); }; #if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) m_selected.removeIf(pred); #else diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 5eb639011..735d1687b 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -10,6 +10,7 @@ #include "QObjectPtr.h" +#include "ResourceDownloadTask.h" #include "modplatform/ResourceAPI.h" #include "tasks/ConcurrentTask.h" @@ -29,6 +30,8 @@ class ResourceModel : public QAbstractListModel { Q_PROPERTY(QString search_term MEMBER m_search_term WRITE setSearchTerm) public: + using DownloadTaskPtr = shared_qobject_ptr; + ResourceModel(ResourceAPI* api); ~ResourceModel() override; @@ -80,8 +83,13 @@ class ResourceModel : public QAbstractListModel { /** Gets the icon at the URL for the given index. If it's not fetched yet, fetch it and update when fisinhed. */ std::optional getIcon(QModelIndex&, const QUrl&); - void addPack(ModPlatform::IndexedPack& add) { m_selected.append(add); } - void removePack(QString& rem); + void addPack(ModPlatform::IndexedPack& pack, + ModPlatform::IndexedVersion& version, + const std::shared_ptr packs, + bool is_indexed = false, + QString custom_target_folder = {}); + void removePack(const QString& rem); + QList selectedPacks() { return m_selected; } protected: /** Resets the model's data. */ @@ -127,7 +135,7 @@ class ResourceModel : public QAbstractListModel { QSet m_failed_icon_actions; QList m_packs; - QList m_selected; + QList m_selected; // HACK: We need this to prevent callbacks from calling the model after it has already been deleted. // This leaks a tiny bit of memory per time the user has opened a resource dialog. How to make this better? diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index d41503e8e..4ebdea56d 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -37,6 +37,7 @@ */ #include "ResourcePage.h" +#include "modplatform/ModIndex.h" #include "ui_ResourcePage.h" #include @@ -309,15 +310,21 @@ void ResourcePage::onVersionSelectionChanged(QString data) void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) { m_parent_dialog->addResource(pack, version); - m_model->addPack(pack); } -void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) +void ResourcePage::removeResourceFromDialog(const QString& pack_name) { - m_parent_dialog->removeResource(pack, version); + m_parent_dialog->removeResource(pack_name); } -void ResourcePage::removeResourceFromPage(QString& name) +void ResourcePage::addResourceToPage(ModPlatform::IndexedPack& pack, + ModPlatform::IndexedVersion& ver, + const std::shared_ptr base_model) +{ + m_model->addPack(pack, ver, base_model); +} + +void ResourcePage::removeResourceFromPage(const QString& name) { m_model->removePack(name); } @@ -333,7 +340,7 @@ void ResourcePage::onResourceSelected() auto& version = current_pack.versions[m_selected_version_index]; if (version.is_currently_selected) - removeResourceFromDialog(current_pack, version); + removeResourceFromDialog(current_pack.name); else addResourceToDialog(current_pack, version); diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index a9db52e30..df68e6fd3 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -7,10 +7,12 @@ #include #include +#include "ResourceDownloadTask.h" #include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" #include "ui/pages/BasePage.h" +#include "ui/pages/modplatform/ResourceModel.h" #include "ui/widgets/ProgressWidget.h" namespace Ui { @@ -27,6 +29,7 @@ class ResourceModel; class ResourcePage : public QWidget, public BasePage { Q_OBJECT public: + using DownloadTaskPtr = shared_qobject_ptr; ~ResourcePage() override; /* Affects what the user sees */ @@ -72,9 +75,13 @@ class ResourcePage : public QWidget, public BasePage { virtual void updateSelectionButton(); virtual void updateVersionList(); - virtual void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); - virtual void removeResourceFromDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); - virtual void removeResourceFromPage(QString& name); + void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); + void removeResourceFromDialog(const QString& pack_name); + virtual void removeResourceFromPage(const QString& name); + virtual void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr); + + QList selectedPacks() { return m_model->selectedPacks(); } + bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); } protected slots: virtual void triggerSearch() {} diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp index 729e714c0..c7a69418f 100644 --- a/launcher/ui/pages/modplatform/ShaderPackPage.cpp +++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp @@ -43,12 +43,14 @@ QMap ShaderPackResourcePage::urlHandlers() const return map; } -void ShaderPackResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version) +void ShaderPackResourcePage::addResourceToPage(ModPlatform::IndexedPack& pack, + ModPlatform::IndexedVersion& version, + const std::shared_ptr base_model) { + QString custom_target_folder; if (version.loaders.contains(QStringLiteral("canvas"))) - version.custom_target_folder = QStringLiteral("resourcepacks"); - m_parent_dialog->addResource(pack, version); - m_model->addPack(pack); + custom_target_folder = QStringLiteral("resourcepacks"); + m_model->addPack(pack, version, base_model, false, custom_target_folder); } } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.h b/launcher/ui/pages/modplatform/ShaderPackPage.h index 972419a81..8a293f74b 100644 --- a/launcher/ui/pages/modplatform/ShaderPackPage.h +++ b/launcher/ui/pages/modplatform/ShaderPackPage.h @@ -40,7 +40,7 @@ class ShaderPackResourcePage : public ResourcePage { [[nodiscard]] bool supportsFiltering() const override { return false; }; - void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&) override; + void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr) override; [[nodiscard]] QMap urlHandlers() const override; From f6ed2036b34177d7f932007dc5b3cc3d59f99aea Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 3 May 2023 00:55:18 +0300 Subject: [PATCH 028/429] Removed comment Signed-off-by: Trial97 --- launcher/ResourceDownloadTask.h | 1 - 1 file changed, 1 deletion(-) diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index fe41170a8..32b1120c5 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -40,7 +40,6 @@ class ResourceDownloadTask : public SequentialTask { const QVariant& getVersionID() const { return m_pack_version.fileId; } const QString& getName() const { return m_pack.name; } ModPlatform::IndexedPack& getPack() { return m_pack; } - // void setSelectedVersion(ModPlatform::IndexedVersion version) { m_pack_version = std::move(version); } private: ModPlatform::IndexedPack m_pack; From e4449a0ba32593b4fd76e3f2ced176e5b3bbd952 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 3 May 2023 09:09:07 +0300 Subject: [PATCH 029/429] Initialized variable Signed-off-by: Trial97 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index ef3200a25..90922c8e5 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -170,7 +170,7 @@ void ResourceDownloadDialog::removeResource(const QString& pack_name) void ResourceDownloadDialog::setButtonStatus() { - bool selected; + auto selected = false; for (auto page : m_container->getPages()) { auto res = static_cast(page); selected = selected || res->hasSelectedPacks(); From f7b912fc9d804902a725fa903be8574e1e202f69 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 4 May 2023 21:52:48 +0300 Subject: [PATCH 030/429] Fixed comments Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 32 +++++++++++++------ .../mod/tasks/GetModDependenciesTask.h | 20 ++++++------ .../mod/tasks/LocalModUpdateTask.cpp | 2 +- launcher/modplatform/ModIndex.h | 4 ++- .../ui/dialogs/ResourceDownloadDialog.cpp | 23 +++++++++++-- launcher/ui/dialogs/ResourceDownloadDialog.h | 2 ++ launcher/ui/dialogs/ReviewMessageBox.cpp | 12 +++++++ launcher/ui/dialogs/ReviewMessageBox.h | 1 + 8 files changed, 71 insertions(+), 25 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index e1760f163..2f08ae6d6 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln - * Copyright (C) 2022 Sefa Eyeoglu + * 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 @@ -47,7 +46,7 @@ static ResourceAPI::ModLoaderTypes mcLoaders(BaseInstance* inst) GetModDependenciesTask::GetModDependenciesTask(QObject* parent, BaseInstance* instance, ModFolderModel* folder, - QList> selected) + QList> selected) : SequentialTask(parent, "Get dependencies") , m_selected(selected) , m_flame_provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared(*instance), @@ -66,7 +65,7 @@ void GetModDependenciesTask::prepare() { for (auto sel : m_selected) { for (auto dep : getDependenciesForVersion(sel->version, sel->pack.provider)) { - addTask(prepareDependencyTask(dep, sel->pack.provider, 20)); + addTask(prepareDependencyTask(dep, sel->pack.provider, sel->pack.addonId, 20)); } } } @@ -81,7 +80,7 @@ QList GetModDependenciesTask::getDependenciesForVersion [&ver_dep](const ModPlatform::Dependency& i) { return i.addonId == ver_dep.addonId; }); dep == c_dependencies.end()) { // check the current dependency list if (auto dep = std::find_if(m_selected.begin(), m_selected.end(), - [&ver_dep, providerName](std::shared_ptr i) { + [&ver_dep, providerName](std::shared_ptr i) { return i->pack.addonId == ver_dep.addonId && i->pack.provider == providerName; }); dep == m_selected.end()) { // check the selected versions @@ -90,7 +89,15 @@ QList GetModDependenciesTask::getDependenciesForVersion return i->project_id == ver_dep.addonId && i->provider == providerName; }); dep == m_mods.end()) { // check the existing mods - c_dependencies.append(ver_dep); + if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(), + [&ver_dep, providerName](std::shared_ptr i) { + return i->pack.addonId == ver_dep.addonId && i->pack.provider == providerName; + }); + dep == m_pack_dependencies.end()) { // check loaded dependencies + c_dependencies.append(ver_dep); + } else { // already there just append the required_by + dep->get()->version.required_by.append(version.addonId); + } } } } @@ -101,11 +108,13 @@ QList GetModDependenciesTask::getDependenciesForVersion Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Dependency& dep, const ModPlatform::ResourceProvider providerName, + QVariant required_by, int level) { - auto pDep = std::make_shared(); + auto pDep = std::make_shared(); pDep->dependency = dep; pDep->pack = { dep.addonId, providerName }; + pDep->version.required_by.append(required_by); m_pack_dependencies.append(pDep); auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; @@ -136,7 +145,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen ResourceAPI::DependencySearchArgs args = { dep, m_version, m_loaderType }; ResourceAPI::DependencySearchCallbacks callbacks; - callbacks.on_succeed = [dep, provider, pDep, level, this](auto& doc, auto& pack) { + callbacks.on_succeed = [dep, provider, pDep, level, required_by, this](auto& doc, auto& pack) { try { QJsonArray arr; if (dep.version.length() != 0 && doc.isObject()) { @@ -144,6 +153,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen } else { arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); } + auto required_by = pDep->version.required_by; pDep->version = provider.mod->loadDependencyVersions(dep, arr); if (!pDep->version.addonId.isValid()) { qWarning() << "Error while reading mod version empty "; @@ -151,8 +161,10 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen return; } pDep->version.is_currently_selected = true; + pDep->version.required_by = required_by; pDep->pack.versions = { pDep->version }; pDep->pack.versionsLoaded = true; + } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading mod version: " << e.cause(); @@ -163,7 +175,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen return; } for (auto dep : getDependenciesForVersion(pDep->version, provider.name)) { - addTask(prepareDependencyTask(dep, provider.name, level - 1)); + addTask(prepareDependencyTask(dep, provider.name, pDep->pack.addonId, level - 1)); } }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 40f80ebf6..c8d378ef6 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 flowln + * 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 @@ -38,12 +38,12 @@ class GetModDependenciesTask : public SequentialTask { public: using Ptr = shared_qobject_ptr; - struct PackDependecny { + struct PackDependency { ModPlatform::Dependency dependency; ModPlatform::IndexedPack pack; ModPlatform::IndexedVersion version; - PackDependecny(){}; - PackDependecny(const ModPlatform::IndexedPack& p, const ModPlatform::IndexedVersion& v) + PackDependency(){}; + PackDependency(const ModPlatform::IndexedPack& p, const ModPlatform::IndexedVersion& v) { pack = p; version = v; @@ -59,20 +59,20 @@ class GetModDependenciesTask : public SequentialTask { explicit GetModDependenciesTask(QObject* parent, BaseInstance* instance, ModFolderModel* folder, - QList> selected); + QList> selected); - auto getDependecies() const -> QList> { return m_pack_dependencies; } + auto getDependecies() const -> QList> { return m_pack_dependencies; } protected slots: - Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int); + Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, QVariant, int); QList getDependenciesForVersion(const ModPlatform::IndexedVersion&, const ModPlatform::ResourceProvider providerName); void prepare(); private: - QList> m_pack_dependencies; + QList> m_pack_dependencies; QList> m_mods; - QList> m_selected; + QList> m_selected; Provider m_flame_provider; Provider m_modrinth_provider; diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index 6b139ca1d..4352fad91 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 5ff7bbc9f..5b4399351 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * 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 @@ -78,6 +79,7 @@ struct IndexedVersion { // For internal use, not provided by APIs bool is_currently_selected = false; QString custom_target_folder; + QList required_by; }; struct ExtraPackData { diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 9c28acd9c..ca2d409ce 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -126,6 +126,22 @@ void ResourceDownloadDialog::connectButtons() static ModPlatform::ProviderCapabilities ProviderCaps; +QStringList ResourceDownloadDialog::getReqiredBy(QList req_by) +{ + auto req = QStringList(); + auto keys = m_selected.keys(); + for (auto r : req_by) { + for (auto& task : keys) { + auto selected = m_selected.constFind(task).value()->getPack(); + if (selected.addonId == r) { + req.append(selected.name); + break; + } + } + } + return req; +} + void ResourceDownloadDialog::confirm() { auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString())); @@ -162,8 +178,9 @@ void ResourceDownloadDialog::confirm() keys.sort(Qt::CaseInsensitive); for (auto& task : keys) { auto selected = m_selected.constFind(task).value(); + auto required_by = getReqiredBy(selected->getVersion().required_by); confirm_dialog->appendResource( - { task, selected->getFilename(), selected->getCustomPath(), ProviderCaps.name(selected->getProvider()) }); + { task, selected->getFilename(), selected->getCustomPath(), ProviderCaps.name(selected->getProvider()), required_by }); } if (confirm_dialog->exec()) { @@ -261,10 +278,10 @@ GetModDependenciesTask::Ptr ModDownloadDialog::getModDependenciesTask() { if (auto model = dynamic_cast(getBaseModel().get()); model) { auto keys = m_selected.keys(); - QList> selectedVers; + QList> selectedVers; for (auto& task : keys) { auto selected = m_selected.constFind(task).value(); - selectedVers.append(std::make_shared(selected->getPack(), selected->getVersion())); + selectedVers.append(std::make_shared(selected->getPack(), selected->getVersion())); } return makeShared(this, m_instance, model, selectedVers); diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h index 9610c8b36..1145f63a4 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.h +++ b/launcher/ui/dialogs/ResourceDownloadDialog.h @@ -83,6 +83,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { [[nodiscard]] virtual GetModDependenciesTask::Ptr getModDependenciesTask() { return nullptr; } + QStringList getReqiredBy(QList req_by); + protected: const std::shared_ptr m_base_model; diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp index 86e68aae8..e18519c38 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.cpp +++ b/launcher/ui/dialogs/ReviewMessageBox.cpp @@ -60,6 +60,18 @@ void ReviewMessageBox::appendResource(ResourceInformation&& info) itemTop->insertChildren(childIndx++, { providerItem }); + if (!info.required_by.isEmpty()) { + auto requiredByItem = new QTreeWidgetItem(itemTop); + QString req; + if (info.required_by.length() == 1) + req = info.required_by.back(); + else + req = QString("[%1]").arg(info.required_by.join(", ")); + requiredByItem->setText(0, tr("Required by: %1").arg(req)); + + itemTop->insertChildren(childIndx++, { requiredByItem }); + } + ui->modTreeWidget->addTopLevelItem(itemTop); } diff --git a/launcher/ui/dialogs/ReviewMessageBox.h b/launcher/ui/dialogs/ReviewMessageBox.h index 9579da335..a520cc2a6 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.h +++ b/launcher/ui/dialogs/ReviewMessageBox.h @@ -17,6 +17,7 @@ class ReviewMessageBox : public QDialog { QString filename; QString custom_file_path{}; QString provider; + QStringList required_by; }; void appendResource(ResourceInformation&& info); From 107b4702895afdbaf9912006d91c910bb6634361 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 4 May 2023 23:54:46 +0300 Subject: [PATCH 031/429] Updated required_by as dependency Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 12 +++--------- .../mod/tasks/GetModDependenciesTask.h | 2 +- launcher/modplatform/ModIndex.h | 1 - .../ui/dialogs/ResourceDownloadDialog.cpp | 19 ++++++++++--------- launcher/ui/dialogs/ReviewMessageBox.cpp | 17 +++++++++++------ 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 2f08ae6d6..96d343a19 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -65,7 +65,7 @@ void GetModDependenciesTask::prepare() { for (auto sel : m_selected) { for (auto dep : getDependenciesForVersion(sel->version, sel->pack.provider)) { - addTask(prepareDependencyTask(dep, sel->pack.provider, sel->pack.addonId, 20)); + addTask(prepareDependencyTask(dep, sel->pack.provider, 20)); } } } @@ -95,8 +95,6 @@ QList GetModDependenciesTask::getDependenciesForVersion }); dep == m_pack_dependencies.end()) { // check loaded dependencies c_dependencies.append(ver_dep); - } else { // already there just append the required_by - dep->get()->version.required_by.append(version.addonId); } } } @@ -108,13 +106,11 @@ QList GetModDependenciesTask::getDependenciesForVersion Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Dependency& dep, const ModPlatform::ResourceProvider providerName, - QVariant required_by, int level) { auto pDep = std::make_shared(); pDep->dependency = dep; pDep->pack = { dep.addonId, providerName }; - pDep->version.required_by.append(required_by); m_pack_dependencies.append(pDep); auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; @@ -145,7 +141,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen ResourceAPI::DependencySearchArgs args = { dep, m_version, m_loaderType }; ResourceAPI::DependencySearchCallbacks callbacks; - callbacks.on_succeed = [dep, provider, pDep, level, required_by, this](auto& doc, auto& pack) { + callbacks.on_succeed = [dep, provider, pDep, level, this](auto& doc, auto& pack) { try { QJsonArray arr; if (dep.version.length() != 0 && doc.isObject()) { @@ -153,7 +149,6 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen } else { arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array(); } - auto required_by = pDep->version.required_by; pDep->version = provider.mod->loadDependencyVersions(dep, arr); if (!pDep->version.addonId.isValid()) { qWarning() << "Error while reading mod version empty "; @@ -161,7 +156,6 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen return; } pDep->version.is_currently_selected = true; - pDep->version.required_by = required_by; pDep->pack.versions = { pDep->version }; pDep->pack.versionsLoaded = true; @@ -175,7 +169,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen return; } for (auto dep : getDependenciesForVersion(pDep->version, provider.name)) { - addTask(prepareDependencyTask(dep, provider.name, pDep->pack.addonId, level - 1)); + addTask(prepareDependencyTask(dep, provider.name, level - 1)); } }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index c8d378ef6..aca3c0040 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -64,7 +64,7 @@ class GetModDependenciesTask : public SequentialTask { auto getDependecies() const -> QList> { return m_pack_dependencies; } protected slots: - Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, QVariant, int); + Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int); QList getDependenciesForVersion(const ModPlatform::IndexedVersion&, const ModPlatform::ResourceProvider providerName); void prepare(); diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index edf924169..a19fc0eb9 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -78,7 +78,6 @@ struct IndexedVersion { // For internal use, not provided by APIs bool is_currently_selected = false; - QList required_by; }; struct ExtraPackData { diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index c74aaace0..b65f2ffd1 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -125,16 +125,17 @@ void ResourceDownloadDialog::connectButtons() static ModPlatform::ProviderCapabilities ProviderCaps; -QStringList getReqiredBy(QList tasks, QList req_by) +QStringList getReqiredBy(QList tasks, QVariant addonId) { auto req = QStringList(); - for (auto r : req_by) { - for (auto& task : tasks) { - auto selected = task->getPack(); - if (selected.addonId == r) { - req.append(selected.name); - break; - } + for (auto& task : tasks) { + auto deps = task->getVersion().dependencies; + if (auto dep = std::find_if(deps.begin(), deps.end(), + [addonId](const ModPlatform::Dependency& d) { + return d.addonId == addonId && d.type == ModPlatform::DependencyType::REQUIRED; + }); + dep) { + req.append(task->getName()); } } return req; @@ -178,7 +179,7 @@ void ResourceDownloadDialog::confirm() }); for (auto& task : selected) { confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(), - ProviderCaps.name(task->getProvider()), getReqiredBy(selected, task->getVersion().required_by) }); + ProviderCaps.name(task->getProvider()), getReqiredBy(selected, task->getPack().addonId) }); } if (confirm_dialog->exec()) { diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp index e18519c38..7b33765fd 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.cpp +++ b/launcher/ui/dialogs/ReviewMessageBox.cpp @@ -62,12 +62,17 @@ void ReviewMessageBox::appendResource(ResourceInformation&& info) if (!info.required_by.isEmpty()) { auto requiredByItem = new QTreeWidgetItem(itemTop); - QString req; - if (info.required_by.length() == 1) - req = info.required_by.back(); - else - req = QString("[%1]").arg(info.required_by.join(", ")); - requiredByItem->setText(0, tr("Required by: %1").arg(req)); + if (info.required_by.length() == 1) { + requiredByItem->setText(0, tr("Required by: %1").arg(info.required_by.back())); + } else { + requiredByItem->setText(0, tr("Required by:")); + auto i = 0; + for (auto req : info.required_by) { + auto reqItem = new QTreeWidgetItem(requiredByItem); + reqItem->setText(0, req); + reqItem->insertChildren(i++, { reqItem }); + } + } itemTop->insertChildren(childIndx++, { requiredByItem }); } From 469ef3e06d93f9b00d7c23ac03f4eff07385e446 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 5 May 2023 00:04:24 +0300 Subject: [PATCH 032/429] Fixed code error Signed-off-by: Trial97 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index b65f2ffd1..181067010 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -134,7 +134,7 @@ QStringList getReqiredBy(QList tasks, Q [addonId](const ModPlatform::Dependency& d) { return d.addonId == addonId && d.type == ModPlatform::DependencyType::REQUIRED; }); - dep) { + dep != deps.end()) { req.append(task->getName()); } } From ec157b766efd9eb781a8ca85fb9c28674e073da0 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 4 May 2023 23:42:42 -0700 Subject: [PATCH 033/429] feat(mod parsing): load extra mod details - (image, license, issuetracker) Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/Mod.cpp | 46 ++++ launcher/minecraft/mod/Mod.h | 20 ++ launcher/minecraft/mod/ModDetails.h | 90 ++++++++ .../minecraft/mod/tasks/LocalModParseTask.cpp | 210 ++++++++++++++++++ .../minecraft/mod/tasks/LocalModParseTask.h | 3 + 5 files changed, 369 insertions(+) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index c495cd47e..392f7f2eb 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -41,9 +41,11 @@ #include #include +#include "MTPixmapCache.h" #include "MetadataHandler.h" #include "Version.h" #include "minecraft/mod/ModDetails.h" +#include "minecraft/mod/tasks/LocalModParseTask.h" static ModPlatform::ProviderCapabilities ProviderCaps; @@ -201,6 +203,9 @@ void Mod::finishResolvingWithDetails(ModDetails&& details) m_local_details = std::move(details); if (metadata) setMetadata(std::move(metadata)); + if (!iconPath().isEmpty()) { + m_pack_image_cache_key.was_read_attempt = false; + } }; auto Mod::provider() const -> std::optional @@ -210,6 +215,47 @@ auto Mod::provider() const -> std::optional return {}; } + +void Mod::setIcon(QImage new_image) const +{ + QMutexLocker locker(&m_data_lock); + + Q_ASSERT(!new_image.isNull()); + + if (m_pack_image_cache_key.key.isValid()) + PixmapCache::remove(m_pack_image_cache_key.key); + + // scale the image to avoid flooding the pixmapcache + auto pixmap = QPixmap::fromImage(new_image.scaled({128, 128}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + + m_pack_image_cache_key.key = PixmapCache::insert(pixmap); + m_pack_image_cache_key.was_ever_used = true; + m_pack_image_cache_key.was_read_attempt = true; +} + +QPixmap Mod::icon(QSize size, Qt::AspectRatioMode mode) const +{ + QPixmap cached_image; + if (PixmapCache::find(m_pack_image_cache_key.key, &cached_image)) { + if (size.isNull()) + return cached_image; + return cached_image.scaled(size, mode); + } + + // No valid image we can get + if ((!m_pack_image_cache_key.was_ever_used && m_pack_image_cache_key.was_read_attempt) || iconPath().isEmpty()) + return {}; + + if (m_pack_image_cache_key.was_ever_used) { + qDebug() << "Mod" << name() << "Had it's icon evicted form the cache. reloading..."; + PixmapCache::markCacheMissByEviciton(); + } + // Imaged got evicted from the cache or an attmept to load it has not been made. load it and retry. + m_pack_image_cache_key.was_read_attempt = true; + ModUtils::loadIconFile(*this); + return icon(size); +} + bool Mod::valid() const { return !m_local_details.mod_id.isEmpty(); diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index c40325387..4be0842f7 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -38,6 +38,10 @@ #include #include #include +#include +#include +#include +#include #include @@ -65,6 +69,13 @@ public: auto status() const -> ModStatus; auto provider() const -> std::optional; + /** Get the intneral path to the mod's icon file*/ + QString iconPath() const { return m_local_details.icon_file; }; + /** Gets the icon of the mod, converted to a QPixmap for drawing, and scaled to size. */ + [[nodiscard]] QPixmap icon(QSize size, Qt::AspectRatioMode mode = Qt::AspectRatioMode::IgnoreAspectRatio) const; + /** Thread-safe. */ + void setIcon(QImage new_image) const; + auto metadata() -> std::shared_ptr; auto metadata() const -> const std::shared_ptr; @@ -85,4 +96,13 @@ public: protected: ModDetails m_local_details; + + mutable QMutex m_data_lock; + + struct { + QPixmapCache::Key key; + bool was_ever_used = false; + bool was_read_attempt = false; + } mutable m_pack_image_cache_key; + }; diff --git a/launcher/minecraft/mod/ModDetails.h b/launcher/minecraft/mod/ModDetails.h index 176e4fc14..eb3770d69 100644 --- a/launcher/minecraft/mod/ModDetails.h +++ b/launcher/minecraft/mod/ModDetails.h @@ -39,6 +39,7 @@ #include #include +#include #include "minecraft/mod/MetadataHandler.h" @@ -49,6 +50,77 @@ enum class ModStatus { Unknown, // Default status }; +struct ModLicense { + QString name = {}; + QString id = {}; + QString url = {}; + QString description = {}; + + ModLicense() {} + + ModLicense(const QString license) { + // FIXME: come up with a better license parseing. + // handle SPDX identifiers? https://spdx.org/licenses/ + auto parts = license.split(' '); + QStringList notNameParts = {}; + for (auto part : parts) { + auto url = QUrl::fromUserInput(part); + if (url.isValid()) { + this->url = url.toString(); + notNameParts.append(part); + continue; + } + } + + for (auto part : notNameParts) { + parts.removeOne(part); + } + + auto licensePart = parts.join(' '); + this->name = licensePart; + this->description = licensePart; + + if (parts.size() == 1) { + this->id = parts.first(); + } + + } + + ModLicense(const QString name, const QString id, const QString url, const QString description) { + this->name = name; + this->id = id; + this->url = url; + this->description = description; + } + + ModLicense(const ModLicense& other) + : name(other.name) + , id(other.id) + , url(other.url) + , description(other.description) + {} + + ModLicense& operator=(const ModLicense& other) + { + this->name = other.name; + this->id = other.id; + this->url = other.url; + this->description = other.description; + + return *this; + } + + ModLicense& operator=(const ModLicense&& other) + { + this->name = other.name; + this->id = other.id; + this->url = other.url; + this->description = other.description; + + return *this; + } +}; + struct ModDetails { /* Mod ID as defined in the ModLoader-specific metadata */ @@ -72,6 +144,15 @@ struct ModDetails /* List of the author's names */ QStringList authors = {}; + /* Issue Tracker URL */ + QString issue_tracker = {}; + + /* License */ + QList licenses = {}; + + /* Path of mod logo */ + QString icon_file = {}; + /* Installation status of the mod */ ModStatus status = ModStatus::Unknown; @@ -89,6 +170,9 @@ struct ModDetails , homeurl(other.homeurl) , description(other.description) , authors(other.authors) + , issue_tracker(other.issue_tracker) + , licenses(other.licenses) + , icon_file(other.icon_file) , status(other.status) {} @@ -101,6 +185,9 @@ struct ModDetails this->homeurl = other.homeurl; this->description = other.description; this->authors = other.authors; + this->issue_tracker = other.issue_tracker; + this->licenses = other.licenses; + this->icon_file = other.icon_file; this->status = other.status; return *this; @@ -115,6 +202,9 @@ struct ModDetails this->homeurl = other.homeurl; this->description = other.description; this->authors = other.authors; + this->issue_tracker = other.issue_tracker; + this->licenses = other.licenses; + this->icon_file = other.icon_file; this->status = other.status; return *this; diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 5342d693b..084b0afbc 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -52,6 +52,10 @@ ModDetails ReadMCModInfo(QByteArray contents) authors = firstObj.value("authors").toArray(); } + if (firstObj.contains("logoFile")) { + details.icon_file = firstObj.value("logoFile").toString(); + } + for (auto author : authors) { details.authors.append(author.toString()); } @@ -166,6 +170,30 @@ ModDetails ReadMCModTOML(QByteArray contents) } details.homeurl = homeurl; + QString issueTrackerURL = ""; + if (auto issueTrackerURLDatum = tomlData["issueTrackerURL"].as_string()) { + issueTrackerURL = QString::fromStdString(issueTrackerURLDatum->get()); + } else if (auto issueTrackerURLDatum = (*modsTable)["issueTrackerURL"].as_string()) { + issueTrackerURL = QString::fromStdString(issueTrackerURLDatum->get()); + } + details.issue_tracker = issueTrackerURL; + + QString license = ""; + if (auto licenseDatum = tomlData["license"].as_string()) { + license = QString::fromStdString(licenseDatum->get()); + } else if (auto licenseDatum =(*modsTable)["license"].as_string()) { + license = QString::fromStdString(licenseDatum->get()); + } + details.licenses.push_back(ModLicense(license)); + + QString logoFile = ""; + if (auto logoFileDatum = tomlData["logoFile"].as_string()) { + logoFile = QString::fromStdString(logoFileDatum->get()); + } else if (auto logoFileDatum =(*modsTable)["logoFile"].as_string()) { + logoFile = QString::fromStdString(logoFileDatum->get()); + } + details.icon_file = logoFile; + return details; } @@ -201,6 +229,57 @@ ModDetails ReadFabricModInfo(QByteArray contents) if (contact.contains("homepage")) { details.homeurl = contact.value("homepage").toString(); } + if (contact.contains("issues")) { + details.issue_tracker = contact.value("issues").toString(); + } + } + + if (object.contains("license")) { + auto license = object.value("license"); + if (license.isArray()) { + for (auto l : license.toArray()) { + if (l.isString()) { + details.licenses.append(ModLicense(l.toString())); + } else if (l.isObject()) { + auto obj = l.toObject(); + details.licenses.append(ModLicense(obj.value("name").toString(), obj.value("id").toString(), + obj.value("url").toString(), obj.value("description").toString())); + } + } + } else if (license.isString()) { + details.licenses.append(ModLicense(license.toString())); + } else if (license.isObject()) { + auto obj = license.toObject(); + details.licenses.append(ModLicense(obj.value("name").toString(), obj.value("id").toString(), obj.value("url").toString(), + obj.value("description").toString())); + } + } + + if (object.contains("icon")) { + auto icon = object.value("icon"); + if (icon.isObject()) { + auto obj = icon.toObject(); + // take the largest icon + int largest = 0; + for (auto key : obj.keys()) { + auto size = key.split('x').first().toInt(); + if (size > largest) { + largest = size; + } + } + if (largest > 0) { + auto key = QString::number(largest) + "x" + largest; + details.icon_file = obj.value(key).toString(); + } else { // parsing the sizes failed + // take the first + for (auto icon : obj) { + details.icon_file = icon.toString(); + break; + } + } + } else if (icon.isString()) { + details.icon_file = icon.toString(); + } } } return details; @@ -238,6 +317,58 @@ ModDetails ReadQuiltModInfo(QByteArray contents) if (modContact.contains("homepage")) { details.homeurl = Json::requireString(modContact.value("homepage")); } + if (modContact.contains("issues")) { + details.issue_tracker = Json::requireString(modContact.value("issues")); + } + + if (modMetadata.contains("license")) { + auto license = modMetadata.value("license"); + if (license.isArray()) { + for (auto l : license.toArray()) { + if (l.isString()) { + details.licenses.append(ModLicense(l.toString())); + } else if (l.isObject()) { + auto obj = l.toObject(); + details.licenses.append(ModLicense(obj.value("name").toString(), obj.value("id").toString(), + obj.value("url").toString(), obj.value("description").toString())); + } + } + } else if (license.isString()) { + details.licenses.append(ModLicense(license.toString())); + } else if (license.isObject()) { + auto obj = license.toObject(); + details.licenses.append(ModLicense(obj.value("name").toString(), obj.value("id").toString(), obj.value("url").toString(), + obj.value("description").toString())); + } + } + + if (modMetadata.contains("icon")) { + auto icon = modMetadata.value("icon"); + if (icon.isObject()) { + auto obj = icon.toObject(); + // take the largest icon + int largest = 0; + for (auto key : obj.keys()) { + auto size = key.split('x').first().toInt(); + if (size > largest) { + largest = size; + } + } + if (largest > 0) { + auto key = QString::number(largest) + "x" + largest; + details.icon_file = obj.value(key).toString(); + } else { // parsing the sizes failed + // take the first + for (auto icon : obj) { + details.icon_file = icon.toString(); + break; + } + } + } else if (icon.isString()) { + details.icon_file = icon.toString(); + } + } + } return details; } @@ -515,6 +646,85 @@ bool validate(QFileInfo file) return ModUtils::process(mod, ProcessingLevel::BasicInfoOnly) && mod.valid(); } +bool processIconPNG(const Mod& mod, QByteArray&& raw_data) +{ + auto img = QImage::fromData(raw_data); + if (!img.isNull()) { + mod.setIcon(img); + } else { + qWarning() << "Failed to parse mod logo:" << mod.iconPath() << "from" << mod.name(); + return false; + } + return true; +} + +bool loadIconFile(const Mod& mod) { + if (mod.iconPath().isEmpty()) { + qWarning() << "No Iconfile set, be sure to parse the mod first"; + return false; + } + + auto png_invalid = [&mod]() { + qWarning() << "Mod at" << mod.fileinfo().filePath() << "does not have a valid icon"; + return false; + }; + + switch (mod.type()) { + case ResourceType::FOLDER: + { + QFileInfo icon_info(FS::PathCombine(mod.fileinfo().filePath(), mod.iconPath())); + if (icon_info.exists() && icon_info.isFile()) { + QFile icon(icon_info.filePath()); + if (!icon.open(QIODevice::ReadOnly)) + return false; + auto data = icon.readAll(); + + bool icon_result = ModUtils::processIconPNG(mod, std::move(data)); + + icon.close(); + + if (!icon_result) { + return png_invalid(); // icon invalid + } + } + } + case ResourceType::ZIPFILE: + { + QuaZip zip(mod.fileinfo().filePath()); + if (!zip.open(QuaZip::mdUnzip)) + return false; + + QuaZipFile file(&zip); + + if (zip.setCurrentFile(mod.iconPath())) { + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "Failed to open file in zip."; + zip.close(); + return png_invalid(); + } + + auto data = file.readAll(); + + bool icon_result = ModUtils::processIconPNG(mod, std::move(data)); + + file.close(); + if (!icon_result) { + return png_invalid(); // icon png invalid + } + } else { + return png_invalid(); // could not set icon as current file. + } + } + case ResourceType::LITEMOD: + { + return false; // can lightmods even have icons? + } + default: + qWarning() << "Invalid type for mod, can not load icon."; + return false; + } +} + } // namespace ModUtils LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile) diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.h b/launcher/minecraft/mod/tasks/LocalModParseTask.h index 38dae1357..a03217093 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.h @@ -25,6 +25,9 @@ bool processLitemod(Mod& mod, ProcessingLevel level = ProcessingLevel::Full); /** Checks whether a file is valid as a mod or not. */ bool validate(QFileInfo file); + +bool processIconPNG(const Mod& mod, QByteArray&& raw_data); +bool loadIconFile(const Mod& mod); } // namespace ModUtils class LocalModParseTask : public Task { From 9913080a829acb4ca921c3a68e0caefad0ebcaa1 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 4 May 2023 23:44:28 -0700 Subject: [PATCH 034/429] feat(modpage): mod icon in description and column Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/ModFolderModel.cpp | 8 ++++++-- launcher/minecraft/mod/ModFolderModel.h | 1 + launcher/ui/widgets/InfoFrame.cpp | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 6ae25d338..8a58b9d78 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -57,7 +57,7 @@ ModFolderModel::ModFolderModel(const QString& dir, std::shared_ptr instance, bool is_indexed, bool create_dir) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) { - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER, SortType::NAME }; } QVariant ModFolderModel::data(const QModelIndex &index, int role) const @@ -118,7 +118,9 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const case Qt::DecorationRole: { if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); - + if (column == ImageColumn) { + return at(row)->icon(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding); + } return {}; } case Qt::CheckStateRole: @@ -151,6 +153,8 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in return tr("Last changed"); case ProviderColumn: return tr("Provider"); + case ImageColumn: + return tr("Image"); default: return QVariant(); } diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 46f5087f0..20018e9c4 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -68,6 +68,7 @@ public: VersionColumn, DateColumn, ProviderColumn, + ImageColumn, NUM_COLUMNS }; enum ModStatusAction { diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index fdc581b41..6f4036a25 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -88,7 +88,7 @@ void InfoFrame::updateWithMod(Mod const& m) setDescription(m.description()); } - setImage(); + setImage(m.icon({64,64})); } void InfoFrame::updateWithResource(const Resource& resource) From d384d991fad80cdadf6486d61e5c06a692a0031d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 4 May 2023 23:45:24 -0700 Subject: [PATCH 035/429] feat(texturepackPage): icon column Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/TexturePack.cpp | 25 +++-- launcher/minecraft/mod/TexturePack.h | 6 +- .../minecraft/mod/TexturePackFolderModel.cpp | 102 +++++++++++++++++- .../minecraft/mod/TexturePackFolderModel.h | 20 ++++ .../mod/tasks/LocalTexturePackParseTask.cpp | 67 +++++++++++- .../mod/tasks/LocalTexturePackParseTask.h | 5 +- 6 files changed, 211 insertions(+), 14 deletions(-) diff --git a/launcher/minecraft/mod/TexturePack.cpp b/launcher/minecraft/mod/TexturePack.cpp index 99d555843..8ff1e8526 100644 --- a/launcher/minecraft/mod/TexturePack.cpp +++ b/launcher/minecraft/mod/TexturePack.cpp @@ -23,6 +23,8 @@ #include #include +#include "MTPixmapCache.h" + #include "minecraft/mod/tasks/LocalTexturePackParseTask.h" void TexturePack::setDescription(QString new_description) @@ -32,34 +34,41 @@ void TexturePack::setDescription(QString new_description) m_description = new_description; } -void TexturePack::setImage(QImage new_image) +void TexturePack::setImage(QImage new_image) const { QMutexLocker locker(&m_data_lock); Q_ASSERT(!new_image.isNull()); if (m_pack_image_cache_key.key.isValid()) - QPixmapCache::remove(m_pack_image_cache_key.key); + PixmapCache::remove(m_pack_image_cache_key.key); - m_pack_image_cache_key.key = QPixmapCache::insert(QPixmap::fromImage(new_image)); + // scale the image to avoid flooding the pixmapcache + auto pixmap = QPixmap::fromImage(new_image.scaled(QSize(128, 128), Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + + m_pack_image_cache_key.key = PixmapCache::insert(pixmap); m_pack_image_cache_key.was_ever_used = true; } -QPixmap TexturePack::image(QSize size) +QPixmap TexturePack::image(QSize size, Qt::AspectRatioMode mode) const { QPixmap cached_image; - if (QPixmapCache::find(m_pack_image_cache_key.key, &cached_image)) { + if (PixmapCache::find(m_pack_image_cache_key.key, &cached_image)) { if (size.isNull()) return cached_image; - return cached_image.scaled(size); + return cached_image.scaled(size, mode); } // No valid image we can get - if (!m_pack_image_cache_key.was_ever_used) + if (!m_pack_image_cache_key.was_ever_used) { return {}; + } else { + qDebug() << "Texture Pack" << name() << "Had it's image evicted from the cache. reloading..."; + PixmapCache::markCacheMissByEviciton(); + } // Imaged got evicted from the cache. Re-process it and retry. - TexturePackUtils::process(*this); + TexturePackUtils::processPackPNG(*this); return image(size); } diff --git a/launcher/minecraft/mod/TexturePack.h b/launcher/minecraft/mod/TexturePack.h index 81bd5c699..577005655 100644 --- a/launcher/minecraft/mod/TexturePack.h +++ b/launcher/minecraft/mod/TexturePack.h @@ -40,13 +40,13 @@ class TexturePack : public Resource { [[nodiscard]] QString description() const { return m_description; } /** Gets the image of the texture pack, converted to a QPixmap for drawing, and scaled to size. */ - [[nodiscard]] QPixmap image(QSize size); + [[nodiscard]] QPixmap image(QSize size, Qt::AspectRatioMode mode = Qt::AspectRatioMode::IgnoreAspectRatio) const; /** Thread-safe. */ void setDescription(QString new_description); /** Thread-safe. */ - void setImage(QImage new_image); + void setImage(QImage new_image) const; bool valid() const override; @@ -65,5 +65,5 @@ class TexturePack : public Resource { struct { QPixmapCache::Key key; bool was_ever_used = false; - } m_pack_image_cache_key; + } mutable m_pack_image_cache_key; }; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 1e218537e..dd93a4698 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -33,6 +33,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include + +#include "Application.h" #include "TexturePackFolderModel.h" @@ -41,7 +44,9 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, std::shared_ptr instance) : ResourceFolderModel(QDir(dir), instance) -{} +{ + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE, SortType::NAME }; +} Task* TexturePackFolderModel::createUpdateTask() { @@ -52,3 +57,98 @@ Task* TexturePackFolderModel::createParseTask(Resource& resource) { return new LocalTexturePackParseTask(m_next_resolution_ticket, static_cast(resource)); } + + +QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const +{ + if (!validateIndex(index)) + return {}; + + int row = index.row(); + int column = index.column(); + + switch (role) { + case Qt::DisplayRole: + switch (column) { + case NameColumn: + return m_resources[row]->name(); + case DateColumn: + return m_resources[row]->dateTimeChanged(); + default: + return {}; + } + case Qt::ToolTipRole: + if (column == NameColumn) { + if (at(row)->isSymLinkUnder(instDirPath())) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(at(row)->fileinfo().canonicalFilePath());; + } + if (at(row)->isMoreThanOneHardLink()) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); + } + } + + return m_resources[row]->internal_id(); + case Qt::DecorationRole: { + if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) + return APPLICATION->getThemedIcon("status-yellow"); + if (column == ImageColumn) { + return at(row)->image(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding); + } + return {}; + } + case Qt::CheckStateRole: + switch (column) { + case ActiveColumn: + return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked; + default: + return {}; + } + default: + return {}; + } +} + +QVariant TexturePackFolderModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch (role) { + case Qt::DisplayRole: + switch (section) { + case NameColumn: + return tr("Name"); + case DateColumn: + return tr("Last modified"); + case ImageColumn: + return tr("Image"); + default: + return {}; + } + case Qt::ToolTipRole: { + switch (section) { + case ActiveColumn: + //: Here, resource is a generic term for external resources, like Mods, Resource Packs, Shader Packs, etc. + return tr("Is the resource enabled?"); + case NameColumn: + //: Here, resource is a generic term for external resources, like Mods, Resource Packs, Shader Packs, etc. + return tr("The name of the resource."); + case DateColumn: + //: Here, resource is a generic term for external resources, like Mods, Resource Packs, Shader Packs, etc. + return tr("The date and time this resource was last changed (or added)."); + default: + return {}; + } + } + default: + break; + } + + return {}; +} + +int TexturePackFolderModel::columnCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : NUM_COLUMNS; +} \ No newline at end of file diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index 246997bdb..4467691a8 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -38,12 +38,32 @@ #include "ResourceFolderModel.h" +#include "TexturePack.h" + class TexturePackFolderModel : public ResourceFolderModel { Q_OBJECT public: + + enum Columns + { + ActiveColumn = 0, + NameColumn, + DateColumn, + ImageColumn, + NUM_COLUMNS + }; + explicit TexturePackFolderModel(const QString &dir, std::shared_ptr instance); + + [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + [[nodiscard]] int columnCount(const QModelIndex &parent) const override; + [[nodiscard]] Task* createUpdateTask() override; [[nodiscard]] Task* createParseTask(Resource&) override; + + RESOURCE_HELPERS(TexturePack) }; diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp index 38f1d7c1f..a72e81150 100644 --- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp @@ -131,6 +131,7 @@ bool processZIP(TexturePack& pack, ProcessingLevel level) bool packPNG_result = TexturePackUtils::processPackPNG(pack, std::move(data)); file.close(); + zip.close(); if (!packPNG_result) { return false; } @@ -147,7 +148,7 @@ bool processPackTXT(TexturePack& pack, QByteArray&& raw_data) return true; } -bool processPackPNG(TexturePack& pack, QByteArray&& raw_data) +bool processPackPNG(const TexturePack& pack, QByteArray&& raw_data) { auto img = QImage::fromData(raw_data); if (!img.isNull()) { @@ -159,6 +160,70 @@ bool processPackPNG(TexturePack& pack, QByteArray&& raw_data) return true; } +bool processPackPNG(const TexturePack& pack) +{ + auto png_invalid = [&pack]() { + qWarning() << "Texture pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png"; + return false; + }; + + switch (pack.type()) { + case ResourceType::FOLDER: + { + QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png")); + if (image_file_info.exists() && image_file_info.isFile()) { + QFile pack_png_file(image_file_info.filePath()); + if (!pack_png_file.open(QIODevice::ReadOnly)) + return png_invalid(); // can't open pack.png file + + auto data = pack_png_file.readAll(); + + bool pack_png_result = TexturePackUtils::processPackPNG(pack, std::move(data)); + + pack_png_file.close(); + if (!pack_png_result) { + return png_invalid(); // pack.png invalid + } + } else { + return png_invalid(); // pack.png does not exists or is not a valid file. + } + } + case ResourceType::ZIPFILE: + { + Q_ASSERT(pack.type() == ResourceType::ZIPFILE); + + QuaZip zip(pack.fileinfo().filePath()); + if (!zip.open(QuaZip::mdUnzip)) + return false; // can't open zip file + + QuaZipFile file(&zip); + if (zip.setCurrentFile("pack.png")) { + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "Failed to open file in zip."; + zip.close(); + return png_invalid(); + } + + auto data = file.readAll(); + + bool pack_png_result = TexturePackUtils::processPackPNG(pack, std::move(data)); + + file.close(); + if (!pack_png_result) { + zip.close(); + return png_invalid(); // pack.png invalid + } + } else { + zip.close(); + return png_invalid(); // could not set pack.mcmeta as current file. + } + } + default: + qWarning() << "Invalid type for resource pack parse task!"; + return false; + } +} + bool validate(QFileInfo file) { TexturePack rp{ file }; diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h index 1589f8cbd..6b91565ad 100644 --- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h @@ -36,7 +36,10 @@ bool processZIP(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full bool processFolder(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full); bool processPackTXT(TexturePack& pack, QByteArray&& raw_data); -bool processPackPNG(TexturePack& pack, QByteArray&& raw_data); +bool processPackPNG(const TexturePack& pack, QByteArray&& raw_data); + +/// processes ONLY the pack.png (rest of the pack may be invalid) +bool processPackPNG(const TexturePack& pack); /** Checks whether a file is valid as a texture pack or not. */ bool validate(QFileInfo file); From ed185f047fa2efc80cc622165583e57f21ffa560 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 4 May 2023 23:46:00 -0700 Subject: [PATCH 036/429] feat(resourcePackPage): icon column Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/ResourcePack.cpp | 19 ++++-- launcher/minecraft/mod/ResourcePack.h | 6 +- .../minecraft/mod/ResourcePackFolderModel.cpp | 21 ++++-- .../minecraft/mod/ResourcePackFolderModel.h | 1 + .../mod/tasks/LocalResourcePackParseTask.cpp | 67 ++++++++++++++++++- .../mod/tasks/LocalResourcePackParseTask.h | 5 +- 6 files changed, 103 insertions(+), 16 deletions(-) diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 876d5c3ee..5fc9d7a6e 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -39,7 +39,7 @@ void ResourcePack::setDescription(QString new_description) m_description = new_description; } -void ResourcePack::setImage(QImage new_image) +void ResourcePack::setImage(QImage new_image) const { QMutexLocker locker(&m_data_lock); @@ -48,7 +48,10 @@ void ResourcePack::setImage(QImage new_image) if (m_pack_image_cache_key.key.isValid()) PixmapCache::instance().remove(m_pack_image_cache_key.key); - m_pack_image_cache_key.key = PixmapCache::instance().insert(QPixmap::fromImage(new_image)); + // scale the image to avoid flooding the pixmapcache + auto pixmap = QPixmap::fromImage(new_image.scaled(QSize(128, 128), Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + + m_pack_image_cache_key.key = PixmapCache::instance().insert(pixmap); m_pack_image_cache_key.was_ever_used = true; // This can happen if the pixmap is too big to fit in the cache :c @@ -58,21 +61,25 @@ void ResourcePack::setImage(QImage new_image) } } -QPixmap ResourcePack::image(QSize size) +QPixmap ResourcePack::image(QSize size, Qt::AspectRatioMode mode) const { QPixmap cached_image; if (PixmapCache::instance().find(m_pack_image_cache_key.key, &cached_image)) { if (size.isNull()) return cached_image; - return cached_image.scaled(size); + return cached_image.scaled(size, mode); } // No valid image we can get - if (!m_pack_image_cache_key.was_ever_used) + if (!m_pack_image_cache_key.was_ever_used) { return {}; + } else { + qDebug() << "Resource Pack" << name() << "Had it's image evicted from the cache. reloading..."; + PixmapCache::markCacheMissByEviciton(); + } // Imaged got evicted from the cache. Re-process it and retry. - ResourcePackUtils::process(*this); + ResourcePackUtils::processPackPNG(*this); return image(size); } diff --git a/launcher/minecraft/mod/ResourcePack.h b/launcher/minecraft/mod/ResourcePack.h index 7cb414d83..da354bc1c 100644 --- a/launcher/minecraft/mod/ResourcePack.h +++ b/launcher/minecraft/mod/ResourcePack.h @@ -31,7 +31,7 @@ class ResourcePack : public Resource { [[nodiscard]] QString description() const { return m_description; } /** Gets the image of the resource pack, converted to a QPixmap for drawing, and scaled to size. */ - [[nodiscard]] QPixmap image(QSize size); + [[nodiscard]] QPixmap image(QSize size, Qt::AspectRatioMode mode = Qt::AspectRatioMode::IgnoreAspectRatio) const; /** Thread-safe. */ void setPackFormat(int new_format_id); @@ -40,7 +40,7 @@ class ResourcePack : public Resource { void setDescription(QString new_description); /** Thread-safe. */ - void setImage(QImage new_image); + void setImage(QImage new_image) const; bool valid() const override; @@ -67,5 +67,5 @@ class ResourcePack : public Resource { struct { QPixmapCache::Key key; bool was_ever_used = false; - } m_pack_image_cache_key; + } mutable m_pack_image_cache_key; }; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 6eba4e2ec..c8c0c7732 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -35,6 +35,8 @@ */ #include "ResourcePackFolderModel.h" +#include +#include #include #include @@ -48,7 +50,7 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, std::shared_ptr instance) : ResourceFolderModel(QDir(dir), instance) { - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE }; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE, SortType::NAME }; } QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const @@ -84,9 +86,11 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const return {}; } case Qt::DecorationRole: { - if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) + if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); - + if (column == ImageColumn) { + return at(row)->image(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding); + } return {}; } case Qt::ToolTipRole: { @@ -94,7 +98,7 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const //: The string being explained by this is in the format: ID (Lower version - Upper version) return tr("The resource pack format ID, as well as the Minecraft versions it was designed for."); } - if (column == NAME_COLUMN) { + if (column == NameColumn) { if (at(row)->isSymLinkUnder(instDirPath())) { return m_resources[row]->internal_id() + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." @@ -133,6 +137,8 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient return tr("Pack Format"); case DateColumn: return tr("Last changed"); + case ImageColumn: + return tr("Image"); default: return {}; } @@ -151,6 +157,13 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient default: return {}; } + case Qt::SizeHintRole: + switch (section) { + case ImageColumn: + return QSize(64,0); + default: + return {}; + } default: return {}; } diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h index 66d5a074b..71532f30d 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.h +++ b/launcher/minecraft/mod/ResourcePackFolderModel.h @@ -14,6 +14,7 @@ public: NameColumn, PackFormatColumn, DateColumn, + ImageColumn, NUM_COLUMNS }; diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp index 4bf0b80d8..a67c56a8f 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp @@ -165,15 +165,16 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level) bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data)); file.close(); + zip.close(); if (!pack_png_result) { return png_invalid(); // pack.png invalid } } else { + zip.close(); return png_invalid(); // could not set pack.mcmeta as current file. } zip.close(); - return true; } @@ -193,7 +194,7 @@ bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data) return true; } -bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data) +bool processPackPNG(const ResourcePack& pack, QByteArray&& raw_data) { auto img = QImage::fromData(raw_data); if (!img.isNull()) { @@ -205,6 +206,68 @@ bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data) return true; } +bool processPackPNG(const ResourcePack& pack) +{ + auto png_invalid = [&pack]() { + qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png"; + return false; + }; + + switch (pack.type()) { + case ResourceType::FOLDER: + { + QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png")); + if (image_file_info.exists() && image_file_info.isFile()) { + QFile pack_png_file(image_file_info.filePath()); + if (!pack_png_file.open(QIODevice::ReadOnly)) + return png_invalid(); // can't open pack.png file + + auto data = pack_png_file.readAll(); + + bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data)); + + pack_png_file.close(); + if (!pack_png_result) { + return png_invalid(); // pack.png invalid + } + } else { + return png_invalid(); // pack.png does not exists or is not a valid file. + } + } + case ResourceType::ZIPFILE: + { + Q_ASSERT(pack.type() == ResourceType::ZIPFILE); + + QuaZip zip(pack.fileinfo().filePath()); + if (!zip.open(QuaZip::mdUnzip)) + return false; // can't open zip file + + QuaZipFile file(&zip); + if (zip.setCurrentFile("pack.png")) { + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "Failed to open file in zip."; + zip.close(); + return png_invalid(); + } + + auto data = file.readAll(); + + bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data)); + + file.close(); + if (!pack_png_result) { + return png_invalid(); // pack.png invalid + } + } else { + return png_invalid(); // could not set pack.mcmeta as current file. + } + } + default: + qWarning() << "Invalid type for resource pack parse task!"; + return false; + } +} + bool validate(QFileInfo file) { ResourcePack rp{ file }; diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h index d0c24c2b1..58d90b3b9 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h @@ -35,7 +35,10 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Ful bool processFolder(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full); bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data); -bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data); +bool processPackPNG(const ResourcePack& pack, QByteArray&& raw_data); + +/// processes ONLY the pack.png (rest of the pack may be invalid) +bool processPackPNG(const ResourcePack& pack); /** Checks whether a file is valid as a resource pack or not. */ bool validate(QFileInfo file); From fd7338d3f3f72ca9532f11c9759ad02bbc759c7c Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 4 May 2023 23:47:27 -0700 Subject: [PATCH 037/429] fix: grow pixmapcache if it is evicting too fast Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/MTPixmapCache.h | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/launcher/MTPixmapCache.h b/launcher/MTPixmapCache.h index 57847a0e1..271788c01 100644 --- a/launcher/MTPixmapCache.h +++ b/launcher/MTPixmapCache.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include #define GET_TYPE() \ Qt::ConnectionType type; \ @@ -60,6 +62,8 @@ class PixmapCache final : public QObject { DEFINE_FUNC_ONE_PARAM(remove, bool, const QPixmapCache::Key&) DEFINE_FUNC_TWO_PARAM(replace, bool, const QPixmapCache::Key&, const QPixmap&) DEFINE_FUNC_ONE_PARAM(setCacheLimit, bool, int) + DEFINE_FUNC_NO_PARAM(markCacheMissByEviciton, bool) + DEFINE_FUNC_ONE_PARAM(setFastEvictionThreshold, bool, int) // NOTE: Every function returns something non-void to simplify the macros. private slots: @@ -90,6 +94,43 @@ class PixmapCache final : public QObject { return true; } + /** + * Mark that a cach miss occured because of a eviciton if too man of these occure to fast the cache size is increased + * @return if the cache size was increased + */ + bool _markCacheMissByEviciton() + { + auto now = QTime::currentTime(); + if (!m_last_cache_miss_by_eviciton.isNull()) { + auto diff = m_last_cache_miss_by_eviciton.msecsTo(now); + if (diff < 1000) { // less than a second ago + ++m_consecutive_fast_evicitons; + } else { + m_consecutive_fast_evicitons = 0; + } + } + m_last_cache_miss_by_eviciton = now; + if (m_consecutive_fast_evicitons >= m_consecutive_fast_evicitons_threshold) { + // double the cache size + auto newSize = _cacheLimit() * 2; + qDebug() << m_consecutive_fast_evicitons << "pixmap cache misses by eviction happened too fast, doubling cache size to" + << newSize; + _setCacheLimit(newSize); + m_consecutive_fast_evicitons = 0; + return true; + } + return false; + } + + bool _setFastEvictionThreshold(int threshold) + { + m_consecutive_fast_evicitons_threshold = threshold; + return true; + } + private: static PixmapCache* s_instance; + QTime m_last_cache_miss_by_eviciton; + int m_consecutive_fast_evicitons = 0; + int m_consecutive_fast_evicitons_threshold = 15; }; From 2fe3dc5960a6cc231891a91dd68fcc8b159e9365 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 5 May 2023 11:13:36 -0700 Subject: [PATCH 038/429] fix: fix qchar conversion and codeql Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/MTPixmapCache.h | 2 +- launcher/minecraft/mod/Mod.cpp | 4 ++-- launcher/minecraft/mod/ResourcePackFolderModel.cpp | 8 +++----- launcher/minecraft/mod/TexturePackFolderModel.cpp | 8 +++----- launcher/minecraft/mod/tasks/LocalModParseTask.cpp | 12 ++++++------ 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/launcher/MTPixmapCache.h b/launcher/MTPixmapCache.h index 271788c01..65cbe032a 100644 --- a/launcher/MTPixmapCache.h +++ b/launcher/MTPixmapCache.h @@ -95,7 +95,7 @@ class PixmapCache final : public QObject { } /** - * Mark that a cach miss occured because of a eviciton if too man of these occure to fast the cache size is increased + * Mark that a cache miss occurred because of a eviction if too many of these occur too fast the cache size is increased * @return if the cache size was increased */ bool _markCacheMissByEviciton() diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 392f7f2eb..aabc2db45 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -206,7 +206,7 @@ void Mod::finishResolvingWithDetails(ModDetails&& details) if (!iconPath().isEmpty()) { m_pack_image_cache_key.was_read_attempt = false; } -}; +} auto Mod::provider() const -> std::optional { @@ -250,7 +250,7 @@ QPixmap Mod::icon(QSize size, Qt::AspectRatioMode mode) const qDebug() << "Mod" << name() << "Had it's icon evicted form the cache. reloading..."; PixmapCache::markCacheMissByEviciton(); } - // Imaged got evicted from the cache or an attmept to load it has not been made. load it and retry. + // Image got evicted from the cache or an attempt to load it has not been made. load it and retry. m_pack_image_cache_key.was_read_attempt = true; ModUtils::loadIconFile(*this); return icon(size); diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index c8c0c7732..349353a5e 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -158,12 +158,10 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient return {}; } case Qt::SizeHintRole: - switch (section) { - case ImageColumn: - return QSize(64,0); - default: - return {}; + if (section == ImageColumn) { + return QSize(64,0); } + return {}; default: return {}; } diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index dd93a4698..f053eab1c 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -101,12 +101,10 @@ QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const return {}; } case Qt::CheckStateRole: - switch (column) { - case ActiveColumn: - return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked; - default: - return {}; + if (column == ActiveColumn) { + return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked; } + return {}; default: return {}; } diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 084b0afbc..f045bde37 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -268,12 +268,12 @@ ModDetails ReadFabricModInfo(QByteArray contents) } } if (largest > 0) { - auto key = QString::number(largest) + "x" + largest; + auto key = QString::number(largest) + "x" + QString::number(largest); details.icon_file = obj.value(key).toString(); } else { // parsing the sizes failed // take the first - for (auto icon : obj) { - details.icon_file = icon.toString(); + for (auto i : obj) { + details.icon_file = i.toString(); break; } } @@ -355,12 +355,12 @@ ModDetails ReadQuiltModInfo(QByteArray contents) } } if (largest > 0) { - auto key = QString::number(largest) + "x" + largest; + auto key = QString::number(largest) + "x" + QString::number(largest); details.icon_file = obj.value(key).toString(); } else { // parsing the sizes failed // take the first - for (auto icon : obj) { - details.icon_file = icon.toString(); + for (auto i : obj) { + details.icon_file = i.toString(); break; } } From ee94be624eb11a12d4eb3e07c32ea4734b3ba6dc Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 5 May 2023 11:28:19 -0700 Subject: [PATCH 039/429] use 32x32 images for image column Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/Mod.cpp | 2 +- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- launcher/minecraft/mod/ResourcePack.cpp | 2 +- launcher/minecraft/mod/ResourcePackFolderModel.cpp | 2 +- launcher/minecraft/mod/TexturePack.cpp | 2 +- launcher/minecraft/mod/TexturePackFolderModel.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index aabc2db45..f236d2acc 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -226,7 +226,7 @@ void Mod::setIcon(QImage new_image) const PixmapCache::remove(m_pack_image_cache_key.key); // scale the image to avoid flooding the pixmapcache - auto pixmap = QPixmap::fromImage(new_image.scaled({128, 128}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + auto pixmap = QPixmap::fromImage(new_image.scaled({64, 64}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); m_pack_image_cache_key.key = PixmapCache::insert(pixmap); m_pack_image_cache_key.was_ever_used = true; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 8a58b9d78..f1c26e682 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -119,7 +119,7 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); if (column == ImageColumn) { - return at(row)->icon(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding); + return at(row)->icon({32, 32}, Qt::AspectRatioMode::KeepAspectRatioByExpanding); } return {}; } diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 5fc9d7a6e..9aea22ef7 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -49,7 +49,7 @@ void ResourcePack::setImage(QImage new_image) const PixmapCache::instance().remove(m_pack_image_cache_key.key); // scale the image to avoid flooding the pixmapcache - auto pixmap = QPixmap::fromImage(new_image.scaled(QSize(128, 128), Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + auto pixmap = QPixmap::fromImage(new_image.scaled({64, 64}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); m_pack_image_cache_key.key = PixmapCache::instance().insert(pixmap); m_pack_image_cache_key.was_ever_used = true; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 349353a5e..b11e2262d 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -89,7 +89,7 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); if (column == ImageColumn) { - return at(row)->image(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding); + return at(row)->image({32, 32}, Qt::AspectRatioMode::KeepAspectRatioByExpanding); } return {}; } diff --git a/launcher/minecraft/mod/TexturePack.cpp b/launcher/minecraft/mod/TexturePack.cpp index 8ff1e8526..c7a50a97a 100644 --- a/launcher/minecraft/mod/TexturePack.cpp +++ b/launcher/minecraft/mod/TexturePack.cpp @@ -44,7 +44,7 @@ void TexturePack::setImage(QImage new_image) const PixmapCache::remove(m_pack_image_cache_key.key); // scale the image to avoid flooding the pixmapcache - auto pixmap = QPixmap::fromImage(new_image.scaled(QSize(128, 128), Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + auto pixmap = QPixmap::fromImage(new_image.scaled({64, 64}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); m_pack_image_cache_key.key = PixmapCache::insert(pixmap); m_pack_image_cache_key.was_ever_used = true; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index f053eab1c..e115cce68 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -96,7 +96,7 @@ QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); if (column == ImageColumn) { - return at(row)->image(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding); + return at(row)->image({32, 32}, Qt::AspectRatioMode::KeepAspectRatioByExpanding); } return {}; } From 3cfcc83ea99e8f42dba8848b5ef885c296b4566a Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 5 May 2023 13:46:01 -0700 Subject: [PATCH 040/429] change: don't toggle a resource's enabeling just by selecting it. only if they are on the checkbox. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/pages/instance/ExternalResourcesPage.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 1115ddc3b..6c11b85b7 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -96,7 +96,6 @@ void ExternalResourcesPage::itemActivated(const QModelIndex&) return; auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); - m_model->setResourceEnabled(selection.indexes(), EnableAction::TOGGLE); } void ExternalResourcesPage::filterTextChanged(const QString& newContents) From 74e7c13a177afdb503a642cb9c97d71e72249291 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 5 May 2023 13:46:38 -0700 Subject: [PATCH 041/429] feat: display license and issue tracker Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/Mod.cpp | 9 ++ launcher/minecraft/mod/Mod.h | 2 + launcher/minecraft/mod/ModDetails.h | 11 +- launcher/minecraft/mod/ModFolderModel.cpp | 1 - .../minecraft/mod/tasks/LocalModParseTask.cpp | 3 +- launcher/ui/widgets/InfoFrame.cpp | 120 +++++++++++++++++- launcher/ui/widgets/InfoFrame.h | 4 + launcher/ui/widgets/InfoFrame.ui | 110 +++++++++++----- 8 files changed, 218 insertions(+), 42 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index f236d2acc..e613ddeb7 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -215,6 +215,15 @@ auto Mod::provider() const -> std::optional return {}; } +auto Mod::licenses() const -> const QList& +{ + return details().licenses; +} + + auto Mod::issueTracker() const -> QString +{ + return details().issue_tracker; +} void Mod::setIcon(QImage new_image) const { diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 4be0842f7..d4e419f4f 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -68,6 +68,8 @@ public: auto authors() const -> QStringList; auto status() const -> ModStatus; auto provider() const -> std::optional; + auto licenses() const -> const QList&; + auto issueTracker() const -> QString; /** 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/ModDetails.h b/launcher/minecraft/mod/ModDetails.h index eb3770d69..b4e59d52d 100644 --- a/launcher/minecraft/mod/ModDetails.h +++ b/launcher/minecraft/mod/ModDetails.h @@ -64,8 +64,11 @@ struct ModLicense { auto parts = license.split(' '); QStringList notNameParts = {}; for (auto part : parts) { - auto url = QUrl::fromUserInput(part); - if (url.isValid()) { + auto url = QUrl(part); + if (part.startsWith("(") && part.endsWith(")")) + url = QUrl(part.mid(1, part.size() - 2)); + + if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) { this->url = url.toString(); notNameParts.append(part); continue; @@ -119,6 +122,10 @@ struct ModLicense { return *this; } + + bool isEmpty() { + return this->name.isEmpty() && this->id.isEmpty() && this->url.isEmpty() && this->description.isEmpty(); + } }; struct ModDetails diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index f1c26e682..8843f79f6 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -52,7 +52,6 @@ #include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h" -#include "modplatform/ModIndex.h" ModFolderModel::ModFolderModel(const QString& dir, std::shared_ptr instance, bool is_indexed, bool create_dir) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index f045bde37..264019f84 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -184,7 +184,8 @@ ModDetails ReadMCModTOML(QByteArray contents) } else if (auto licenseDatum =(*modsTable)["license"].as_string()) { license = QString::fromStdString(licenseDatum->get()); } - details.licenses.push_back(ModLicense(license)); + if (!license.isEmpty()) + details.licenses.append(ModLicense(license)); QString logoFile = ""; if (auto logoFileDatum = tomlData["logoFile"].as_string()) { diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 6f4036a25..9c041bfe9 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -47,6 +47,8 @@ InfoFrame::InfoFrame(QWidget *parent) : ui->setupUi(this); ui->descriptionLabel->setHidden(true); ui->nameLabel->setHidden(true); + ui->licenseLabel->setHidden(true); + ui->issueTrackerLabel->setHidden(true); updateHiddenState(); } @@ -89,6 +91,40 @@ void InfoFrame::updateWithMod(Mod const& m) } setImage(m.icon({64,64})); + + auto licenses = m.licenses(); + QString licenseText = ""; + if (!licenses.empty()) { + for (auto l : licenses) { + if (!licenseText.isEmpty()) { + licenseText += "\n"; // add newline between licenses + } + if (!l.name.isEmpty()) { + if (l.url.isEmpty()) { + licenseText += l.name; + } else { + licenseText += "" + l.name + ""; + } + } else if (!l.url.isEmpty()) { + licenseText += "" + l.url + ""; + } + if (!l.description.isEmpty() && l.description != l.name) { + licenseText += " " + l.description; + } + } + } + if (!licenseText.isEmpty()) { + setLicense(tr("License: %1").arg(licenseText)); + } else { + setLicense(); + } + + QString issueTracker = ""; + if (!m.issueTracker().isEmpty()) { + issueTracker += tr("Report issues to: "); + issueTracker += "" + m.issueTracker() + ""; + } + setIssueTracker(issueTracker); } void InfoFrame::updateWithResource(const Resource& resource) @@ -177,16 +213,16 @@ void InfoFrame::clear() setName(); setDescription(); setImage(); + setLicense(); + setIssueTracker(); } void InfoFrame::updateHiddenState() { - if(ui->descriptionLabel->isHidden() && ui->nameLabel->isHidden()) - { + if (ui->descriptionLabel->isHidden() && ui->nameLabel->isHidden() && ui->licenseLabel->isHidden() && + ui->issueTrackerLabel->isHidden()) { setHidden(true); - } - else - { + } else { setHidden(false); } } @@ -251,6 +287,66 @@ void InfoFrame::setDescription(QString text) ui->descriptionLabel->setText(labeltext); } +void InfoFrame::setLicense(QString text) +{ + if(text.isEmpty()) + { + ui->licenseLabel->setHidden(true); + updateHiddenState(); + return; + } + else + { + ui->licenseLabel->setHidden(false); + updateHiddenState(); + } + ui->licenseLabel->setToolTip(""); + QString intermediatetext = text.trimmed(); + bool prev(false); + QChar rem('\n'); + QString finaltext; + finaltext.reserve(intermediatetext.size()); + foreach(const QChar& c, intermediatetext) + { + if(c == rem && prev){ + continue; + } + prev = c == rem; + finaltext += c; + } + QString labeltext; + labeltext.reserve(300); + if(finaltext.length() > 290) + { + ui->licenseLabel->setOpenExternalLinks(false); + ui->licenseLabel->setTextFormat(Qt::TextFormat::RichText); + m_description = text; + // This allows injecting HTML here. + labeltext.append("" + finaltext.left(287) + "..."); + QObject::connect(ui->licenseLabel, &QLabel::linkActivated, this, &InfoFrame::licenseEllipsisHandler); + } + else + { + ui->licenseLabel->setTextFormat(Qt::TextFormat::AutoText); + labeltext.append(finaltext); + } + ui->licenseLabel->setText(labeltext); +} + +void InfoFrame::setIssueTracker(QString text) +{ + if(text.isEmpty()) + { + ui->issueTrackerLabel->setHidden(true); + } + else + { + ui->issueTrackerLabel->setText(text); + ui->issueTrackerLabel->setHidden(false); + } + updateHiddenState(); +} + void InfoFrame::setImage(QPixmap img) { if (img.isNull()) { @@ -275,6 +371,20 @@ void InfoFrame::descriptionEllipsisHandler(QString link) } } +void InfoFrame::licenseEllipsisHandler(QString link) +{ + if(!m_current_box) + { + m_current_box = CustomMessageBox::selectable(this, "", m_license); + connect(m_current_box, &QMessageBox::finished, this, &InfoFrame::boxClosed); + m_current_box->show(); + } + else + { + m_current_box->setText(m_license); + } +} + void InfoFrame::boxClosed(int result) { m_current_box = nullptr; diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h index 84523e281..7eb679a9d 100644 --- a/launcher/ui/widgets/InfoFrame.h +++ b/launcher/ui/widgets/InfoFrame.h @@ -36,6 +36,8 @@ class InfoFrame : public QFrame { void setName(QString text = {}); void setDescription(QString text = {}); void setImage(QPixmap img = {}); + void setLicense(QString text = {}); + void setIssueTracker(QString text = {}); void clear(); @@ -48,6 +50,7 @@ class InfoFrame : public QFrame { public slots: void descriptionEllipsisHandler(QString link); + void licenseEllipsisHandler(QString link); void boxClosed(int result); private: @@ -56,5 +59,6 @@ class InfoFrame : public QFrame { private: Ui::InfoFrame* ui; QString m_description; + QString m_license; class QMessageBox* m_current_box = nullptr; }; diff --git a/launcher/ui/widgets/InfoFrame.ui b/launcher/ui/widgets/InfoFrame.ui index 9e407ce90..c4d8c83d3 100644 --- a/launcher/ui/widgets/InfoFrame.ui +++ b/launcher/ui/widgets/InfoFrame.ui @@ -35,25 +35,28 @@ 0 - - + + + + + 0 + 0 + + + + + 64 + 64 + + - - Qt::RichText + + false - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + 0 @@ -82,28 +85,69 @@ - - - - - 0 - 0 - - - - - 64 - 64 - - + + - - false + + Qt::RichText - - 0 + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse From 0b251fa7545dbe7e61a2a57f5f3e0ff2198b2314 Mon Sep 17 00:00:00 2001 From: Redson Date: Mon, 8 May 2023 19:57:30 -0300 Subject: [PATCH 042/429] feat: Add the launcher root folder to the Folders menu Signed-off-by: Redson --- launcher/ui/MainWindow.cpp | 8 ++++++++ launcher/ui/MainWindow.h | 2 ++ launcher/ui/MainWindow.ui | 13 +++++++++++++ 3 files changed, 23 insertions(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 72b7db641..8d62dcd60 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1201,6 +1201,14 @@ void MainWindow::on_actionViewInstanceFolder_triggered() DesktopServices::openDirectory(str); } +void MainWindow::on_actionViewLauncherRootFolder_triggered() +{ + QDir rootDir(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); + QString DataPath = rootDir.absolutePath(); + + DesktopServices::openDirectory(DataPath); +} + void MainWindow::refreshInstances() { APPLICATION->instances()->loadList(); diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3a42c34e1..08efb8a1c 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -112,6 +112,8 @@ private slots: void on_actionViewInstanceFolder_triggered(); + void on_actionViewLauncherRootFolder_triggered(); + void on_actionViewSelectedInstFolder_triggered(); void refreshInstances(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 2b6a10b10..7c53e294d 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -187,6 +187,7 @@ true + @@ -528,6 +529,18 @@ Open the instance folder in a file browser. + + + + .. + + + &View Launcher Root Folder + + + Open the launcher's root folder in a file browser. + + From 475761b295b3c77aa852af254f783340055090f6 Mon Sep 17 00:00:00 2001 From: Redson Date: Tue, 9 May 2023 06:36:21 -0300 Subject: [PATCH 043/429] fix: Prism sets the data dir to the working directory. Signed-off-by: Redson --- launcher/ui/MainWindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 8d62dcd60..629ace830 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1203,10 +1203,10 @@ void MainWindow::on_actionViewInstanceFolder_triggered() void MainWindow::on_actionViewLauncherRootFolder_triggered() { - QDir rootDir(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); - QString DataPath = rootDir.absolutePath(); + QDir dataDir = QDir::current(); + QString dataPath = dataDir.absolutePath(); - DesktopServices::openDirectory(DataPath); + DesktopServices::openDirectory(dataPath); } void MainWindow::refreshInstances() From 37a6ef95f05b474da1ce449bef696258d22a9d9b Mon Sep 17 00:00:00 2001 From: Redson Date: Wed, 10 May 2023 08:25:13 -0300 Subject: [PATCH 044/429] feat: Don't hide the settings tab when an instance is running Signed-off-by: Redson --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 11 ++++++++++- launcher/ui/pages/instance/InstanceSettingsPage.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 4b4c73dc6..97939461f 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -60,11 +60,15 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) m_settings = inst->settings(); ui->setupUi(this); + // As the signal will (probably) not be triggered once we click edit, let's update it manually instead. + updateRunningStatus(m_instance->isRunning()); + accountMenu = new QMenu(this); // Use undocumented property... https://stackoverflow.com/questions/7121718/create-a-scrollbar-in-a-submenu-qt accountMenu->setStyleSheet("QMenu { menu-scrollable: 1; }"); ui->instanceAccountSelector->setMenu(accountMenu); + connect(m_instance, &BaseInstance::runningStatusChanged, this, &InstanceSettingsPage::updateRunningStatus); connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); @@ -74,7 +78,7 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) bool InstanceSettingsPage::shouldDisplay() const { - return !m_instance->isRunning(); + return true; } InstanceSettingsPage::~InstanceSettingsPage() @@ -552,3 +556,8 @@ void InstanceSettingsPage::updateThresholds() ui->labelMaxMemIcon->setPixmap(pix); } } + +void InstanceSettingsPage::updateRunningStatus(bool running) +{ + setEnabled(!running); +} diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index cb6fbae0c..89e663bf7 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -81,6 +81,7 @@ public: void updateThresholds(); private slots: + void updateRunningStatus(bool running); void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); From 79ce7eb1fc9351e689e7106e3dc3a641d9614c9a Mon Sep 17 00:00:00 2001 From: Redson Date: Sat, 13 May 2023 09:00:10 -0300 Subject: [PATCH 045/429] fix: `shouldDisplay()` is now redundant. Signed-off-by: Redson --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 5 ----- launcher/ui/pages/instance/InstanceSettingsPage.h | 1 - 2 files changed, 6 deletions(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 97939461f..46830720d 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -76,11 +76,6 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) updateThresholds(); } -bool InstanceSettingsPage::shouldDisplay() const -{ - return true; -} - InstanceSettingsPage::~InstanceSettingsPage() { delete ui; diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index 89e663bf7..8bd854ad5 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -75,7 +75,6 @@ public: { return "Instance-settings"; } - virtual bool shouldDisplay() const override; void retranslate() override; void updateThresholds(); From 94cd831e8d15349e6e3428574cdada1b734f2e61 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 14 May 2023 22:13:53 +0300 Subject: [PATCH 046/429] Made sure the metadata is valid when checking mod deps Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 96d343a19..948837d42 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -57,7 +57,8 @@ GetModDependenciesTask::GetModDependenciesTask(QObject* parent, , m_loaderType(mcLoaders(instance)) { for (auto mod : folder->allMods()) - m_mods.append(mod->metadata()); + if (auto meta = mod->metadata(); meta) + m_mods.append(meta); prepare(); }; From 7537ea1ef532f5d8d50ad7aa7e49c4961ddf7b1c Mon Sep 17 00:00:00 2001 From: leo78913 Date: Sun, 14 May 2023 14:57:51 -0300 Subject: [PATCH 047/429] make instance settings account selector a comboBox Signed-off-by: leo78913 --- .../pages/instance/InstanceSettingsPage.cpp | 54 +++++-------------- .../ui/pages/instance/InstanceSettingsPage.h | 3 +- .../ui/pages/instance/InstanceSettingsPage.ui | 9 +--- 3 files changed, 15 insertions(+), 51 deletions(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 4b4c73dc6..a583ab1d0 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -60,15 +60,13 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) m_settings = inst->settings(); ui->setupUi(this); - accountMenu = new QMenu(this); - // Use undocumented property... https://stackoverflow.com/questions/7121718/create-a-scrollbar-in-a-submenu-qt - accountMenu->setStyleSheet("QMenu { menu-scrollable: 1; }"); - ui->instanceAccountSelector->setMenu(accountMenu); - connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); + connect(ui->instanceAccountSelector, QOverload::of(&QComboBox::currentIndexChanged), this, &InstanceSettingsPage::changeInstanceAccount); loadSettings(); + + updateThresholds(); } @@ -454,36 +452,17 @@ void InstanceSettingsPage::on_javaTestBtn_clicked() void InstanceSettingsPage::updateAccountsMenu() { - accountMenu->clear(); - + ui->instanceAccountSelector->clear(); auto accounts = APPLICATION->accounts(); int accountIndex = accounts->findAccountByProfileId(m_settings->get("InstanceAccountId").toString()); - MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); - - if (accountIndex != -1 && accounts->at(accountIndex)) { - defaultAccount = accounts->at(accountIndex); - } - - if (defaultAccount) { - ui->instanceAccountSelector->setText(defaultAccount->profileName()); - ui->instanceAccountSelector->setIcon(getFaceForAccount(defaultAccount)); - } else { - ui->instanceAccountSelector->setText(tr("No default account")); - ui->instanceAccountSelector->setIcon(APPLICATION->getThemedIcon("noaccount")); - } for (int i = 0; i < accounts->count(); i++) { MinecraftAccountPtr account = accounts->at(i); - QAction* action = new QAction(account->profileName(), this); - action->setData(i); - action->setCheckable(true); - if (accountIndex == i) { - action->setChecked(true); - } - action->setIcon(getFaceForAccount(account)); - accountMenu->addAction(action); - connect(action, SIGNAL(triggered(bool)), this, SLOT(changeInstanceAccount())); + ui->instanceAccountSelector->addItem(getFaceForAccount(account), account->profileName(), i); + if (i == accountIndex) + ui->instanceAccountSelector->setCurrentIndex(i); } + } QIcon InstanceSettingsPage::getFaceForAccount(MinecraftAccountPtr account) @@ -495,20 +474,13 @@ QIcon InstanceSettingsPage::getFaceForAccount(MinecraftAccountPtr account) return APPLICATION->getThemedIcon("noaccount"); } -void InstanceSettingsPage::changeInstanceAccount() +void InstanceSettingsPage::changeInstanceAccount(int index) { - QAction* sAction = (QAction*)sender(); - - Q_ASSERT(sAction->data().type() == QVariant::Type::Int); - - QVariant data = sAction->data(); - int index = data.toInt(); auto accounts = APPLICATION->accounts(); - auto account = accounts->at(index); - m_settings->set("InstanceAccountId", account->profileId()); - - ui->instanceAccountSelector->setText(account->profileName()); - ui->instanceAccountSelector->setIcon(getFaceForAccount(account)); + if (index != -1 && accounts->at(index) && ui->instanceAccountGroupBox->isChecked()) { + auto account = accounts->at(index); + m_settings->set("InstanceAccountId", account->profileId()); + } } void InstanceSettingsPage::on_maxMemSpinBox_valueChanged(int i) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index cb6fbae0c..043c3e25b 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -95,12 +95,11 @@ private slots: void updateAccountsMenu(); QIcon getFaceForAccount(MinecraftAccountPtr account); - void changeInstanceAccount(); + void changeInstanceAccount(int index); private: Ui::InstanceSettingsPage *ui; BaseInstance *m_instance; SettingsObjectPtr m_settings; unique_qobject_ptr checker; - QMenu *accountMenu = nullptr; }; diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 1b9861842..19d6dc02d 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -636,14 +636,7 @@ - - - QToolButton::InstantPopup - - - Qt::ToolButtonTextBesideIcon - - + From 4f0ec908ecc0c14c1ffe8e9631d031c754e3540a Mon Sep 17 00:00:00 2001 From: leo78913 Date: Tue, 9 May 2023 23:29:16 -0300 Subject: [PATCH 048/429] feat: add a close button to the main toolbar when running on gamescope Signed-off-by: leo78913 --- launcher/ui/MainWindow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 72b7db641..9b8db1ae5 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -219,6 +219,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // disabled until we have an instance selected ui->instanceToolBar->setEnabled(false); setInstanceActionsEnabled(false); + + // add a close button at the end of the main toolbar when running on gamescope / steam deck + if (qgetenv("XDG_CURRENT_DESKTOP") == "gamescope") { + ui->mainToolBar->addAction(ui->actionCloseWindow); + } + } // add the toolbar toggles to the view menu From 086a7e19f099c6c9b9529afb2360300e534876bf Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 24 May 2023 20:15:34 -0700 Subject: [PATCH 049/429] feat: Column on left, hideable - columns are hideable (saves to settings) - image column moved to left - datamodals can provide resize modes Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/ModFolderModel.cpp | 6 +- launcher/minecraft/mod/ModFolderModel.h | 4 +- .../minecraft/mod/ResourceFolderModel.cpp | 66 +++++++++++++++++++ launcher/minecraft/mod/ResourceFolderModel.h | 12 ++++ .../minecraft/mod/ResourcePackFolderModel.cpp | 6 +- .../minecraft/mod/ResourcePackFolderModel.h | 4 +- .../minecraft/mod/ShaderPackFolderModel.h | 2 + .../minecraft/mod/TexturePackFolderModel.cpp | 9 ++- .../minecraft/mod/TexturePackFolderModel.h | 4 +- .../pages/instance/ExternalResourcesPage.cpp | 15 +++++ .../ui/pages/instance/ExternalResourcesPage.h | 1 + launcher/ui/widgets/ModListView.cpp | 9 +++ launcher/ui/widgets/ModListView.h | 2 + 13 files changed, 131 insertions(+), 9 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 8843f79f6..59e078f13 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -37,6 +37,7 @@ #include "ModFolderModel.h" #include +#include #include #include #include @@ -56,7 +57,8 @@ ModFolderModel::ModFolderModel(const QString& dir, std::shared_ptr instance, bool is_indexed, bool create_dir) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) { - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER, SortType::NAME }; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME , SortType::VERSION, SortType::DATE, SortType::PROVIDER}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; } QVariant ModFolderModel::data(const QModelIndex &index, int role) const @@ -143,7 +145,7 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in switch (section) { case ActiveColumn: - return QString(); + return tr("Enable"); case NameColumn: return tr("Name"); case VersionColumn: diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 20018e9c4..c1f9a2b61 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -64,11 +64,11 @@ public: enum Columns { ActiveColumn = 0, + ImageColumn, NameColumn, VersionColumn, DateColumn, ProviderColumn, - ImageColumn, NUM_COLUMNS }; enum ModStatusAction { @@ -78,6 +78,8 @@ public: }; ModFolderModel(const QString &dir, std::shared_ptr instance, bool is_indexed = false, bool create_dir = true); + virtual QString id() const override { return "mods"; } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index e19734689..ba64497b5 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -8,12 +8,15 @@ #include #include #include +#include #include "Application.h" #include "FileSystem.h" +#include "QVariantUtils.h" #include "minecraft/mod/tasks/BasicFolderLoadTask.h" +#include "settings/Setting.h" #include "tasks/Task.h" ResourceFolderModel::ResourceFolderModel(QDir dir, std::shared_ptr instance, QObject* parent, bool create_dir) @@ -471,6 +474,8 @@ QVariant ResourceFolderModel::headerData(int section, Qt::Orientation orientatio switch (role) { case Qt::DisplayRole: switch (section) { + case ACTIVE_COLUMN: + return tr("Enable"); case NAME_COLUMN: return tr("Name"); case DATE_COLUMN: @@ -500,6 +505,67 @@ QVariant ResourceFolderModel::headerData(int section, Qt::Orientation orientatio return {}; } +void ResourceFolderModel::setupHeaderAction(QAction* act, int column) +{ + Q_ASSERT(act); + + act->setText(headerData(column, Qt::Orientation::Horizontal).toString()); +} + +void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) +{ + auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); + auto setting = (APPLICATION->settings()->contains(setting_name)) ? + APPLICATION->settings()->getSetting(setting_name) : APPLICATION->settings()->registerSetting(setting_name); + + auto hiddenColumns = QVariantUtils::toList(setting->get()); + auto index = hiddenColumns.indexOf(column); + if (index >= 0 && !hidden) { + hiddenColumns.removeAt(index); + } else if ( index < 0 && hidden) { + hiddenColumns.append(column); + } + setting->set(QVariantUtils::fromList(hiddenColumns)); +} + +void ResourceFolderModel::loadHiddenColumns(QTreeView *tree) +{ + auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); + auto setting = (APPLICATION->settings()->contains(setting_name)) ? + APPLICATION->settings()->getSetting(setting_name) : APPLICATION->settings()->registerSetting(setting_name); + + auto hiddenColumns = QVariantUtils::toList(setting->get().toList()); + for (auto col : hiddenColumns) { + tree->setColumnHidden(col, true); + } + +} + +std::unique_ptr ResourceFolderModel::createHeaderContextMenu(QWidget* parent, QTreeView* tree) +{ + auto menu = std::make_unique(parent); + + menu->addSeparator()->setText(tr("Show / Hide Columns")); + + for (int col = 0; col < columnCount(); ++col) { + auto act = new QAction(); + setupHeaderAction(act, col); + + act->setCheckable(true); + act->setChecked(!tree->isColumnHidden(col)); + + connect(act, &QAction::toggled, tree, [this, col, tree](bool toggled){ + tree->setColumnHidden(col, !toggled); + saveHiddenColumn(col, !toggled); + }); + + menu->addAction(act); + + } + + return menu; +} + QSortFilterProxyModel* ResourceFolderModel::createFilterProxyModel(QObject* parent) { return new ProxyModel(parent); diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index fdf5f3315..54627c801 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -1,5 +1,8 @@ #pragma once +#include +#include +#include #include #include #include @@ -29,6 +32,8 @@ class ResourceFolderModel : public QAbstractListModel { ResourceFolderModel(QDir, std::shared_ptr, QObject* parent = nullptr, bool create_dir = true); ~ResourceFolderModel() override; + virtual QString id() const { return "resource"; } + /** Starts watching the paths for changes. * * Returns whether starting to watch all the paths was successful. @@ -110,6 +115,11 @@ class ResourceFolderModel : public QAbstractListModel { [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + void setupHeaderAction(QAction* act, int column); + void saveHiddenColumn(int column, bool hidden); + void loadHiddenColumns(QTreeView* tree); + std::unique_ptr createHeaderContextMenu(QWidget* parent, QTreeView* tree); + /** This creates a proxy model to filter / sort the model for a UI. * * The actual comparisons and filtering are done directly by the Resource, so to modify behavior go there instead! @@ -117,6 +127,7 @@ class ResourceFolderModel : public QAbstractListModel { QSortFilterProxyModel* createFilterProxyModel(QObject* parent = nullptr); [[nodiscard]] SortType columnToSortKey(size_t column) const; + [[nodiscard]] QList columnResizeModes() const { return m_column_resize_modes; } class ProxyModel : public QSortFilterProxyModel { public: @@ -187,6 +198,7 @@ class ResourceFolderModel : public QAbstractListModel { // Represents the relationship between a column's index (represented by the list index), and it's sorting key. // As such, the order in with they appear is very important! QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; + QList m_column_resize_modes = { QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; bool m_can_interact = true; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index b11e2262d..7ec5668c0 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -50,7 +50,9 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, std::shared_ptr instance) : ResourceFolderModel(QDir(dir), instance) { - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE, SortType::NAME }; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents}; + } QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const @@ -130,7 +132,7 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient case Qt::DisplayRole: switch (section) { case ActiveColumn: - return QString(); + return tr("Enable"); case NameColumn: return tr("Name"); case PackFormatColumn: diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h index 71532f30d..bbec96190 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.h +++ b/launcher/minecraft/mod/ResourcePackFolderModel.h @@ -11,15 +11,17 @@ public: enum Columns { ActiveColumn = 0, + ImageColumn, NameColumn, PackFormatColumn, DateColumn, - ImageColumn, NUM_COLUMNS }; explicit ResourcePackFolderModel(const QString &dir, std::shared_ptr instance); + virtual QString id() const override { return "resourcepacks"; } + [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/ShaderPackFolderModel.h b/launcher/minecraft/mod/ShaderPackFolderModel.h index 6f3f2811b..e010f6eda 100644 --- a/launcher/minecraft/mod/ShaderPackFolderModel.h +++ b/launcher/minecraft/mod/ShaderPackFolderModel.h @@ -9,4 +9,6 @@ class ShaderPackFolderModel : public ResourceFolderModel { explicit ShaderPackFolderModel(const QString& dir, std::shared_ptr instance) : ResourceFolderModel(QDir(dir), instance) {} + + virtual QString id() const override { return "shaderpacks"; } }; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index e115cce68..c88f8f377 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -45,7 +45,9 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, std::shared_ptr instance) : ResourceFolderModel(QDir(dir), instance) { - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE, SortType::NAME }; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents}; + } Task* TexturePackFolderModel::createUpdateTask() @@ -115,6 +117,8 @@ QVariant TexturePackFolderModel::headerData(int section, Qt::Orientation orienta switch (role) { case Qt::DisplayRole: switch (section) { + case ActiveColumn: + return tr("Enable"); case NameColumn: return tr("Name"); case DateColumn: @@ -149,4 +153,5 @@ QVariant TexturePackFolderModel::headerData(int section, Qt::Orientation orienta int TexturePackFolderModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : NUM_COLUMNS; -} \ No newline at end of file +} + diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index 4467691a8..ce9c06c4a 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -49,14 +49,16 @@ public: enum Columns { ActiveColumn = 0, + ImageColumn, NameColumn, DateColumn, - ImageColumn, NUM_COLUMNS }; explicit TexturePackFolderModel(const QString &dir, std::shared_ptr instance); + virtual QString id() const override { return "texturepacks"; } + [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 6c11b85b7..bee11d9ae 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -24,6 +24,8 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared m_filterModel->setSourceModel(m_model.get()); m_filterModel->setFilterKeyColumn(-1); ui->treeView->setModel(m_filterModel); + // must come after setModel + ui->treeView->setResizeModes(m_model->columnResizeModes()); ui->treeView->installEventFilter(this); ui->treeView->sortByColumn(1, Qt::AscendingOrder); @@ -44,6 +46,13 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared auto selection_model = ui->treeView->selectionModel(); connect(selection_model, &QItemSelectionModel::currentChanged, this, &ExternalResourcesPage::current); connect(ui->filterEdit, &QLineEdit::textChanged, this, &ExternalResourcesPage::filterTextChanged); + + auto viewHeader = ui->treeView->header(); + viewHeader->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(viewHeader, &QHeaderView::customContextMenuRequested, this, &ExternalResourcesPage::ShowHeaderContextMenu); + + m_model->loadHiddenColumns(ui->treeView); } ExternalResourcesPage::~ExternalResourcesPage() @@ -65,6 +74,12 @@ void ExternalResourcesPage::ShowContextMenu(const QPoint& pos) delete menu; } +void ExternalResourcesPage::ShowHeaderContextMenu(const QPoint& pos) +{ + auto menu = m_model->createHeaderContextMenu(this, ui->treeView); + menu->exec(ui->treeView->mapToGlobal(pos)); +} + void ExternalResourcesPage::openedImpl() { m_model->startWatching(); diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index d17fbb7f1..906e6df70 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -60,6 +60,7 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { virtual void viewConfigs(); void ShowContextMenu(const QPoint& pos); + void ShowHeaderContextMenu(const QPoint& pos); protected: BaseInstance* m_instance = nullptr; diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index 09b03a76a..893cd120a 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -79,3 +79,12 @@ void ModListView::setModel ( QAbstractItemModel* model ) }); } } + +void ModListView::setResizeModes(const QList &modes) +{ + auto head = header(); + for(int i = 0; i < modes.count(); i++) { + head->setSectionResizeMode(i, modes[i]); + } +} + diff --git a/launcher/ui/widgets/ModListView.h b/launcher/ui/widgets/ModListView.h index 881e092f7..3f0b3b0e1 100644 --- a/launcher/ui/widgets/ModListView.h +++ b/launcher/ui/widgets/ModListView.h @@ -14,6 +14,7 @@ */ #pragma once +#include #include class ModListView: public QTreeView @@ -22,4 +23,5 @@ class ModListView: public QTreeView public: explicit ModListView ( QWidget* parent = 0 ); virtual void setModel ( QAbstractItemModel* model ); + virtual void setResizeModes (const QList& modes); }; From d582bf7f1f803d0ea8422732b46e25ee05f2fcb0 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 27 May 2023 13:45:28 -0400 Subject: [PATCH 050/429] feat(nix): flake-utils -> flake-parts Signed-off-by: seth --- default.nix | 15 +++++- flake.lock | 68 ++++++++++++++++-------- flake.nix | 78 +++------------------------- nix/default.nix | 120 ++++++++++--------------------------------- nix/dev.nix | 44 ++++++++++++++++ nix/distribution.nix | 27 ++++++++++ nix/flake-compat.nix | 9 ---- nix/package.nix | 100 ++++++++++++++++++++++++++++++++++++ 8 files changed, 264 insertions(+), 197 deletions(-) create mode 100644 nix/dev.nix create mode 100644 nix/distribution.nix delete mode 100644 nix/flake-compat.nix create mode 100644 nix/package.nix diff --git a/default.nix b/default.nix index 146942d59..c7d0c267d 100644 --- a/default.nix +++ b/default.nix @@ -1 +1,14 @@ -(import nix/flake-compat.nix).defaultNix +( + import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + {src = ./.;} +) +.defaultNix diff --git a/flake.lock b/flake.lock index ad9196a9b..f4122f77d 100644 --- a/flake.lock +++ b/flake.lock @@ -16,29 +16,34 @@ "type": "github" } }, - "flake-compat_2": { - "flake": false, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "lastModified": 1683560683, + "narHash": "sha256-XAygPMN5Xnk/W2c1aW0jyEa6lfMDZWlQgiNtmHXytPc=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "006c75898cf814ef9497252b022e91c946ba8e17", "type": "github" }, "original": { - "owner": "edolstra", - "repo": "flake-compat", + "owner": "hercules-ci", + "repo": "flake-parts", "type": "github" } }, "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1676283394, - "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", "owner": "numtide", "repo": "flake-utils", - "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", "type": "github" }, "original": { @@ -100,33 +105,37 @@ "type": "github" } }, - "nixpkgs-stable": { + "nixpkgs-lib": { "locked": { - "lastModified": 1673800717, - "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=", + "dir": "lib", + "lastModified": 1682879489, + "narHash": "sha256-sASwo8gBt7JDnOOstnps90K1wxmVfyhsTPPNTGBPjjg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f", + "rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0", "type": "github" }, "original": { + "dir": "lib", "owner": "NixOS", - "ref": "nixos-22.11", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, "pre-commit-hooks": { "inputs": { - "flake-compat": "flake-compat_2", - "flake-utils": [ - "flake-utils" + "flake-compat": [ + "flake-compat" ], + "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable" + "nixpkgs-stable": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1678376203, @@ -145,11 +154,26 @@ "root": { "inputs": { "flake-compat": "flake-compat", - "flake-utils": "flake-utils", + "flake-parts": "flake-parts", "libnbtplusplus": "libnbtplusplus", "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index f656703ce..c3148fe03 100644 --- a/flake.nix +++ b/flake.nix @@ -3,11 +3,12 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; - flake-utils.url = "github:numtide/flake-utils"; + flake-parts.url = "github:hercules-ci/flake-parts"; pre-commit-hooks = { url = "github:cachix/pre-commit-hooks.nix"; inputs.nixpkgs.follows = "nixpkgs"; - inputs.flake-utils.follows = "flake-utils"; + inputs.nixpkgs-stable.follows = "nixpkgs"; + inputs.flake-compat.follows = "flake-compat"; }; flake-compat = { url = "github:edolstra/flake-compat"; @@ -19,73 +20,8 @@ }; }; - outputs = { - self, - nixpkgs, - flake-utils, - pre-commit-hooks, - libnbtplusplus, - ... - }: let - # User-friendly version number. - version = builtins.substring 0 8 self.lastModifiedDate; - - # Supported systems (qtbase is currently broken for "aarch64-darwin") - supportedSystems = with flake-utils.lib.system; [ - x86_64-linux - x86_64-darwin - aarch64-linux - ]; - - packagesFn = pkgs: { - prismlauncher-qt5 = pkgs.libsForQt5.callPackage ./nix { - inherit version self libnbtplusplus; - }; - prismlauncher = pkgs.qt6Packages.callPackage ./nix { - inherit version self libnbtplusplus; - }; - }; - in - flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}; - in { - checks = { - pre-commit-check = pre-commit-hooks.lib.${system}.run { - src = ./.; - hooks = { - markdownlint.enable = true; - - alejandra.enable = true; - deadnix.enable = true; - - clang-format = { - enable = - false; # As most of the codebase is **not** formatted, we don't want clang-format yet - types_or = ["c" "c++"]; - }; - }; - }; - }; - - packages = let - packages = packagesFn pkgs; - in - packages // {default = packages.prismlauncher;}; - - devShells.default = pkgs.mkShell { - inherit (self.checks.${system}.pre-commit-check) shellHook; - packages = with pkgs; [ - nodePackages.markdownlint-cli - alejandra - deadnix - clang-tools - ]; - - inputsFrom = [self.packages.${system}.default]; - buildInputs = with pkgs; [ccache ninja]; - }; - }) - // { - overlays.default = final: _: (packagesFn final); - }; + outputs = inputs: + inputs.flake-parts.lib.mkFlake + {inherit inputs;} + {imports = [./nix];}; } diff --git a/nix/default.nix b/nix/default.nix index e0616b6ea..7bad1440c 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -1,100 +1,32 @@ { - lib, - stdenv, - cmake, - ninja, - jdk8, - jdk17, - zlib, - file, - wrapQtAppsHook, - xorg, - libpulseaudio, - qtbase, - qtsvg, - qtwayland, - libGL, - quazip, - glfw, - openal, - extra-cmake-modules, - tomlplusplus, - ghc_filesystem, - cmark, - msaClientID ? "", - jdks ? [jdk17 jdk8], - gamemodeSupport ? true, - gamemode, - # flake + inputs, self, - version, - libnbtplusplus, -}: -stdenv.mkDerivation rec { - pname = "prismlauncher"; - inherit version; - - src = lib.cleanSource self; - - nativeBuildInputs = [extra-cmake-modules cmake file jdk17 ninja wrapQtAppsHook]; - buildInputs = - [ - qtbase - qtsvg - zlib - quazip - ghc_filesystem - tomlplusplus - cmark - ] - ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland - ++ lib.optional gamemodeSupport gamemode.dev; - - cmakeFlags = - lib.optionals (msaClientID != "") ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"] - ++ lib.optionals (lib.versionOlder qtbase.version "6") ["-DLauncher_QT_VERSION_MAJOR=5"]; - - postUnpack = '' - rm -rf source/libraries/libnbtplusplus - mkdir source/libraries/libnbtplusplus - ln -s ${libnbtplusplus}/* source/libraries/libnbtplusplus - chmod -R +r+w source/libraries/libnbtplusplus - chown -R $USER: source/libraries/libnbtplusplus - ''; - - qtWrapperArgs = let - libpath = with xorg; - lib.makeLibraryPath ([ - libX11 - libXext - libXcursor - libXrandr - libXxf86vm - libpulseaudio - libGL - glfw - openal - stdenv.cc.cc.lib - ] - ++ lib.optional gamemodeSupport gamemode.lib); - in [ - "--set LD_LIBRARY_PATH /run/opengl-driver/lib:${libpath}" - "--prefix PRISMLAUNCHER_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}" - # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128 - "--prefix PATH : ${lib.makeBinPath [xorg.xrandr]}" + ... +}: { + imports = [ + ./dev.nix + ./distribution.nix ]; - meta = with lib; { - homepage = "https://prismlauncher.org/"; - description = "A free, open source launcher for Minecraft"; - longDescription = '' - Allows you to have multiple, separate instances of Minecraft (each with - their own mods, texture packs, saves, etc) and helps you manage them and - their associated options with a simple interface. - ''; - platforms = platforms.linux; - changelog = "https://github.com/PrismLauncher/PrismLauncher/releases/tag/${version}"; - license = licenses.gpl3Only; - maintainers = with maintainers; [minion3665 Scrumplex]; + _module.args = { + # User-friendly version number. + version = builtins.substring 0 8 self.lastModifiedDate; }; + + perSystem = {system, ...}: { + # Nixpkgs instantiated for supported systems with our overlay. + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + overlays = [self.overlays.default]; + }; + }; + + # Supported systems. + systems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-linux" + # Disabled due to qtbase being currently broken for "aarch64-darwin." + # "aarch64-darwin" + ]; } diff --git a/nix/dev.nix b/nix/dev.nix new file mode 100644 index 000000000..0fe68c4ec --- /dev/null +++ b/nix/dev.nix @@ -0,0 +1,44 @@ +{ + inputs, + self, + ... +}: { + perSystem = { + system, + pkgs, + ... + }: { + checks = { + pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run { + src = self; + hooks = { + markdownlint.enable = true; + + alejandra.enable = true; + deadnix.enable = true; + + clang-format = { + enable = + false; # As most of the codebase is **not** formatted, we don't want clang-format yet + types_or = ["c" "c++"]; + }; + }; + }; + }; + + devShells.default = pkgs.mkShell { + inherit (self.checks.${system}.pre-commit-check) shellHook; + packages = with pkgs; [ + nodePackages.markdownlint-cli + alejandra + deadnix + clang-tools + ]; + + inputsFrom = [self.packages.${system}.default]; + buildInputs = with pkgs; [ccache ninja]; + }; + + formatter = pkgs.alejandra; + }; +} diff --git a/nix/distribution.nix b/nix/distribution.nix new file mode 100644 index 000000000..0b223f175 --- /dev/null +++ b/nix/distribution.nix @@ -0,0 +1,27 @@ +{ + inputs, + self, + version, + ... +}: { + perSystem = {pkgs, ...}: { + packages = { + inherit (pkgs) prismlauncher prismlauncher-qt5; + default = pkgs.prismlauncher; + }; + }; + + flake = { + overlays.default = _: prev: let + # Helper function to build prism against different versions of Qt. + mkPrism = qt: + qt.callPackage ./package.nix { + inherit (inputs) libnbtplusplus; + inherit self version; + }; + in { + prismlauncher = mkPrism prev.qt6Packages; + prismlauncher-qt5 = mkPrism prev.libsForQt5; + }; + }; +} diff --git a/nix/flake-compat.nix b/nix/flake-compat.nix deleted file mode 100644 index 7162a6cf1..000000000 --- a/nix/flake-compat.nix +++ /dev/null @@ -1,9 +0,0 @@ -let - lock = builtins.fromJSON (builtins.readFile ../flake.lock); - inherit (lock.nodes.flake-compat.locked) rev narHash; - flake-compat = fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/${rev}.tar.gz"; - sha256 = narHash; - }; -in - import flake-compat {src = ../.;} diff --git a/nix/package.nix b/nix/package.nix new file mode 100644 index 000000000..e0616b6ea --- /dev/null +++ b/nix/package.nix @@ -0,0 +1,100 @@ +{ + lib, + stdenv, + cmake, + ninja, + jdk8, + jdk17, + zlib, + file, + wrapQtAppsHook, + xorg, + libpulseaudio, + qtbase, + qtsvg, + qtwayland, + libGL, + quazip, + glfw, + openal, + extra-cmake-modules, + tomlplusplus, + ghc_filesystem, + cmark, + msaClientID ? "", + jdks ? [jdk17 jdk8], + gamemodeSupport ? true, + gamemode, + # flake + self, + version, + libnbtplusplus, +}: +stdenv.mkDerivation rec { + pname = "prismlauncher"; + inherit version; + + src = lib.cleanSource self; + + nativeBuildInputs = [extra-cmake-modules cmake file jdk17 ninja wrapQtAppsHook]; + buildInputs = + [ + qtbase + qtsvg + zlib + quazip + ghc_filesystem + tomlplusplus + cmark + ] + ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland + ++ lib.optional gamemodeSupport gamemode.dev; + + cmakeFlags = + lib.optionals (msaClientID != "") ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"] + ++ lib.optionals (lib.versionOlder qtbase.version "6") ["-DLauncher_QT_VERSION_MAJOR=5"]; + + postUnpack = '' + rm -rf source/libraries/libnbtplusplus + mkdir source/libraries/libnbtplusplus + ln -s ${libnbtplusplus}/* source/libraries/libnbtplusplus + chmod -R +r+w source/libraries/libnbtplusplus + chown -R $USER: source/libraries/libnbtplusplus + ''; + + qtWrapperArgs = let + libpath = with xorg; + lib.makeLibraryPath ([ + libX11 + libXext + libXcursor + libXrandr + libXxf86vm + libpulseaudio + libGL + glfw + openal + stdenv.cc.cc.lib + ] + ++ lib.optional gamemodeSupport gamemode.lib); + in [ + "--set LD_LIBRARY_PATH /run/opengl-driver/lib:${libpath}" + "--prefix PRISMLAUNCHER_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}" + # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128 + "--prefix PATH : ${lib.makeBinPath [xorg.xrandr]}" + ]; + + meta = with lib; { + homepage = "https://prismlauncher.org/"; + description = "A free, open source launcher for Minecraft"; + longDescription = '' + Allows you to have multiple, separate instances of Minecraft (each with + their own mods, texture packs, saves, etc) and helps you manage them and + their associated options with a simple interface. + ''; + platforms = platforms.linux; + changelog = "https://github.com/PrismLauncher/PrismLauncher/releases/tag/${version}"; + license = licenses.gpl3Only; + maintainers = with maintainers; [minion3665 Scrumplex]; + }; +} From 5d14724e66a1911b04dd5091e520751fd7f5ee90 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 27 May 2023 19:16:36 -0400 Subject: [PATCH 051/429] chore(deps): enable nix lockfile maintenance for renovate Signed-off-by: seth --- renovate.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index 39a2b6e9a..d97a8dc6c 100644 --- a/renovate.json +++ b/renovate.json @@ -2,5 +2,11 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:base" - ] + ], + "nix": { + "enabled": true + }, + "lockFileMaintenance": { + "enabled": true + } } From a52574b02670229e4731507b11230a47535c223e Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 27 May 2023 19:25:49 -0400 Subject: [PATCH 052/429] chore(nix): add nil Signed-off-by: seth --- nix/dev.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nix/dev.nix b/nix/dev.nix index 0fe68c4ec..a4ff2cc49 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -16,6 +16,7 @@ alejandra.enable = true; deadnix.enable = true; + nil.enable = true; clang-format = { enable = @@ -33,6 +34,7 @@ alejandra deadnix clang-tools + nil ]; inputsFrom = [self.packages.${system}.default]; From acf1946dacb50913305c3edc05705e8e735eafb1 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 27 May 2023 19:25:58 -0400 Subject: [PATCH 053/429] chore(nix): update sources Signed-off-by: seth --- flake.lock | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/flake.lock b/flake.lock index f4122f77d..875866438 100644 --- a/flake.lock +++ b/flake.lock @@ -35,15 +35,12 @@ } }, "flake-utils": { - "inputs": { - "systems": "systems" - }, "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "owner": "numtide", "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "type": "github" }, "original": { @@ -91,11 +88,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1678693419, - "narHash": "sha256-bbSv5yqZAW6dz+3f3f3pOUZbxpPN+3OgCljgn7P+nnQ=", + "lastModified": 1685012353, + "narHash": "sha256-U3oOge4cHnav8OLGdRVhL45xoRj4Ppd+It6nPC9nNIU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "8e3fad82be64c06fbfb9fd43993aec9ef4623936", + "rev": "aeb75dba965e790de427b73315d5addf91a54955", "type": "github" }, "original": { @@ -138,11 +135,11 @@ ] }, "locked": { - "lastModified": 1678376203, - "narHash": "sha256-3tyYGyC8h7fBwncLZy5nCUjTJPrHbmNwp47LlNLOHSM=", + "lastModified": 1684842236, + "narHash": "sha256-rYWsIXHvNhVQ15RQlBUv67W3YnM+Pd+DuXGMvCBq2IE=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "1a20b9708962096ec2481eeb2ddca29ed747770a", + "rev": "61e567d6497bc9556f391faebe5e410e6623217f", "type": "github" }, "original": { @@ -159,21 +156,6 @@ "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks" } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", From bf0a577fb9d063d90d0003227fce08f32fa09dd1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 28 May 2023 16:57:35 +0300 Subject: [PATCH 054/429] Fixed repaint issue Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourcePage.cpp | 10 ++++++---- launcher/ui/pages/modplatform/ResourcePage.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 4ebdea56d..1edd4f818 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -312,9 +312,11 @@ void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatfo m_parent_dialog->addResource(pack, version); } -void ResourcePage::removeResourceFromDialog(const QString& pack_name) +void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack) { - m_parent_dialog->removeResource(pack_name); + m_parent_dialog->removeResource(pack.name); + for (auto& ver : pack.versions) + ver.is_currently_selected = false; } void ResourcePage::addResourceToPage(ModPlatform::IndexedPack& pack, @@ -340,7 +342,7 @@ void ResourcePage::onResourceSelected() auto& version = current_pack.versions[m_selected_version_index]; if (version.is_currently_selected) - removeResourceFromDialog(current_pack.name); + removeResourceFromDialog(current_pack); else addResourceToDialog(current_pack, version); @@ -351,7 +353,7 @@ void ResourcePage::onResourceSelected() updateSelectionButton(); /* Force redraw on the resource list when the selection changes */ - m_ui->packView->adjustSize(); + m_ui->packView->repaint(); } void ResourcePage::openUrl(const QUrl& url) diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index df68e6fd3..41b0d0e46 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -76,7 +76,7 @@ class ResourcePage : public QWidget, public BasePage { virtual void updateVersionList(); void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&); - void removeResourceFromDialog(const QString& pack_name); + void removeResourceFromDialog(ModPlatform::IndexedPack& pack); virtual void removeResourceFromPage(const QString& name); virtual void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr); From bdff8591aa945bd193f0fdae613f14dea6fb4809 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 28 May 2023 17:54:46 +0300 Subject: [PATCH 055/429] Removed extra loop Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourcePage.cpp | 8 +++----- launcher/ui/pages/modplatform/ResourcePage.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index c8b3bb614..736034add 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -314,11 +314,9 @@ void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack::Ptr pack, ModPl m_parent_dialog->addResource(pack, version); } -void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack::Ptr pack) +void ResourcePage::removeResourceFromDialog(const QString& pack_name) { - m_parent_dialog->removeResource(pack->name); - for (auto& ver : pack->versions) - ver.is_currently_selected = false; + m_parent_dialog->removeResource(pack_name); } void ResourcePage::addResourceToPage(ModPlatform::IndexedPack::Ptr pack, @@ -344,7 +342,7 @@ void ResourcePage::onResourceSelected() auto& version = current_pack->versions[m_selected_version_index]; if (version.is_currently_selected) - removeResourceFromDialog(current_pack); + removeResourceFromDialog(current_pack->name); else addResourceToDialog(current_pack, version); diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h index cc7aa707e..b4a87f573 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.h +++ b/launcher/ui/pages/modplatform/ResourcePage.h @@ -76,7 +76,7 @@ class ResourcePage : public QWidget, public BasePage { virtual void updateVersionList(); void addResourceToDialog(ModPlatform::IndexedPack::Ptr, ModPlatform::IndexedVersion&); - void removeResourceFromDialog(ModPlatform::IndexedPack::Ptr pack); + void removeResourceFromDialog(const QString& pack_name); virtual void removeResourceFromPage(const QString& name); virtual void addResourceToPage(ModPlatform::IndexedPack::Ptr, ModPlatform::IndexedVersion&, const std::shared_ptr); From b4dff181f7dd222086c9405ab49347633dcb7ff8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 28 May 2023 18:22:55 +0300 Subject: [PATCH 056/429] Fixed Ptr logic Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 18 ++++++++++-------- .../mod/tasks/GetModDependenciesTask.h | 4 ++-- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 948837d42..bd80a6611 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -65,8 +65,8 @@ 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)); + for (auto dep : getDependenciesForVersion(sel->version, sel->pack->provider)) { + addTask(prepareDependencyTask(dep, sel->pack->provider, 20)); } } } @@ -82,7 +82,7 @@ QList GetModDependenciesTask::getDependenciesForVersion dep == c_dependencies.end()) { // check the current dependency list if (auto dep = std::find_if(m_selected.begin(), m_selected.end(), [&ver_dep, providerName](std::shared_ptr i) { - return i->pack.addonId == ver_dep.addonId && i->pack.provider == providerName; + return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; }); dep == m_selected.end()) { // check the selected versions if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), @@ -92,7 +92,7 @@ QList GetModDependenciesTask::getDependenciesForVersion dep == m_mods.end()) { // check the existing mods if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(), [&ver_dep, providerName](std::shared_ptr i) { - return i->pack.addonId == ver_dep.addonId && i->pack.provider == providerName; + return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; }); dep == m_pack_dependencies.end()) { // check loaded dependencies c_dependencies.append(ver_dep); @@ -111,7 +111,9 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen { auto pDep = std::make_shared(); pDep->dependency = dep; - pDep->pack = { dep.addonId, providerName }; + pDep->pack = std::make_shared(); + pDep->pack->addonId = dep.addonId; + pDep->pack->provider = providerName; m_pack_dependencies.append(pDep); auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; @@ -131,7 +133,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen try { auto obj = provider.name == ModPlatform::ResourceProvider::FLAME ? Json::requireObject(Json::requireObject(doc), "data") : Json::requireObject(doc); - provider.mod->loadIndexedPack(pDep->pack, obj); + provider.mod->loadIndexedPack(*pDep->pack, obj); } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading mod info: " << e.cause(); @@ -157,8 +159,8 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen return; } pDep->version.is_currently_selected = true; - pDep->pack.versions = { pDep->version }; - pDep->pack.versionsLoaded = true; + pDep->pack->versions = { pDep->version }; + pDep->pack->versionsLoaded = true; } catch (const JSONValidationError& e) { qDebug() << doc; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index aca3c0040..3824e7816 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -40,10 +40,10 @@ class GetModDependenciesTask : public SequentialTask { struct PackDependency { ModPlatform::Dependency dependency; - ModPlatform::IndexedPack pack; + ModPlatform::IndexedPack::Ptr pack; ModPlatform::IndexedVersion version; PackDependency(){}; - PackDependency(const ModPlatform::IndexedPack& p, const ModPlatform::IndexedVersion& v) + PackDependency(const ModPlatform::IndexedPack::Ptr p, const ModPlatform::IndexedVersion& v) { pack = p; version = v; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 6bb9b78a7..495ee8ed2 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -179,7 +179,7 @@ void ResourceDownloadDialog::confirm() }); for (auto& task : selected) { confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(), - ProviderCaps.name(task->getProvider()), getReqiredBy(selected, task->getPack().addonId) }); + ProviderCaps.name(task->getProvider()), getReqiredBy(selected, task->getPack()->addonId) }); } if (confirm_dialog->exec()) { From b9503ff15f355f0ddc2f2bdb841877766d5fe99d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 28 May 2023 18:27:02 +0300 Subject: [PATCH 057/429] Added Q_DECLARE_METATYPE(ModPlatform::IndexedPack::Ptr) Signed-off-by: Trial97 --- launcher/modplatform/ModIndex.h | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index dcc3484d4..82da2ab2f 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -115,12 +115,12 @@ struct IndexedPack { if (!versionsLoaded) return false; - return std::any_of(versions.constBegin(), versions.constEnd(), - [](auto const& v) { return v.is_currently_selected; }); + return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); } }; } // namespace ModPlatform Q_DECLARE_METATYPE(ModPlatform::IndexedPack) +Q_DECLARE_METATYPE(ModPlatform::IndexedPack::Ptr) Q_DECLARE_METATYPE(ModPlatform::ResourceProvider) From 10436ed70cc967da8d1d9ee5bca497ec8f70a66f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 28 May 2023 19:15:41 +0300 Subject: [PATCH 058/429] Fixed code quality Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameCheckUpdate.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp index ca7262c2e..e09aeb3d9 100644 --- a/launcher/modplatform/flame/FlameCheckUpdate.cpp +++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp @@ -130,8 +130,7 @@ void FlameCheckUpdate::executeTask() setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name())); setProgress(i++, m_mods.size()); - ModPlatform::IndexedPack pack{ mod->metadata()->project_id.toString() }; - auto latest_ver = api.getLatestVersion({ pack, m_game_versions, m_loaders }); + auto latest_ver = api.getLatestVersion({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders }); // Check if we were aborted while getting the latest version if (m_was_aborted) { From c0f9ccc5b5fc943c033fd52af5eca1ddadcc1be0 Mon Sep 17 00:00:00 2001 From: Tayou <31988415+TayouVR@users.noreply.github.com> Date: Sun, 28 May 2023 19:57:08 +0200 Subject: [PATCH 059/429] Use slash_star comment style in .editorconfig Signed-off-by: Tayou <31988415+TayouVR@users.noreply.github.com> --- .editorconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.editorconfig b/.editorconfig index a6521c873..56166b207 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,8 @@ -# Visual Studio generated .editorconfig file with C++ settings. +# EditorConfig specs and documentation: https://EditorConfig.org + +# top-most EditorConfig file root = true +# C++ Code Style settings [*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}] - -# Visual C++ Code Style settings - -cpp_generate_documentation_comments = doxygen_triple_slash +cpp_generate_documentation_comments = doxygen_slash_star From 4eb9083ddc3c57f45d252ceae18d3e9dbf4ee4a3 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 28 May 2023 13:00:08 -0700 Subject: [PATCH 060/429] refactor: column names as class property, use string names in setting Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/ModFolderModel.cpp | 9 +++------ launcher/minecraft/mod/ResourceFolderModel.cpp | 13 ++++++------- launcher/minecraft/mod/ResourceFolderModel.h | 3 +++ launcher/minecraft/mod/ResourcePackFolderModel.cpp | 8 +++----- launcher/minecraft/mod/TexturePackFolderModel.cpp | 7 +++---- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 02e77b306..b49aac18e 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -57,6 +57,8 @@ 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_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; } @@ -145,17 +147,12 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in switch (section) { case ActiveColumn: - return tr("Enable"); case NameColumn: - return tr("Name"); case VersionColumn: - return tr("Version"); case DateColumn: - return tr("Last changed"); case ProviderColumn: - return tr("Provider"); case ImageColumn: - return tr("Image"); + return columnNames().at(section); default: return QVariant(); } diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 838fca536..2997a43d7 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -475,11 +475,9 @@ QVariant ResourceFolderModel::headerData(int section, Qt::Orientation orientatio case Qt::DisplayRole: switch (section) { case ACTIVE_COLUMN: - return tr("Enable"); case NAME_COLUMN: - return tr("Name"); case DATE_COLUMN: - return tr("Last modified"); + return columnNames().at(section); default: return {}; } @@ -509,7 +507,7 @@ void ResourceFolderModel::setupHeaderAction(QAction* act, int column) { Q_ASSERT(act); - act->setText(headerData(column, Qt::Orientation::Horizontal).toString()); + act->setText(columnNames().at(column)); } void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) @@ -518,12 +516,13 @@ void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) auto setting = (APPLICATION->settings()->contains(setting_name)) ? APPLICATION->settings()->getSetting(setting_name) : APPLICATION->settings()->registerSetting(setting_name); - auto hiddenColumns = QVariantUtils::toList(setting->get()); - auto index = hiddenColumns.indexOf(column); + auto hiddenColumns = QVariantUtils::toList(setting->get()); + auto name = columnNames(false).at(column); + auto index = hiddenColumns.indexOf(name); if (index >= 0 && !hidden) { hiddenColumns.removeAt(index); } else if ( index < 0 && hidden) { - hiddenColumns.append(column); + hiddenColumns.append(name); } setting->set(QVariantUtils::fromList(hiddenColumns)); } diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index e1dc685b6..138815cff 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -97,6 +97,7 @@ class ResourceFolderModel : public QAbstractListModel { /* Basic columns */ enum Columns { ACTIVE_COLUMN = 0, NAME_COLUMN, DATE_COLUMN, NUM_COLUMNS }; + QStringList columnNames(bool translated = true) const { return translated ? m_column_names_translated : m_column_names; }; [[nodiscard]] int rowCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : static_cast(size()); } [[nodiscard]] int columnCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : NUM_COLUMNS; }; @@ -198,6 +199,8 @@ class ResourceFolderModel : public QAbstractListModel { // Represents the relationship between a column's index (represented by the list index), and it's sorting key. // As such, the order in with they appear is very important! QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; + QStringList m_column_names = {"Enable", "Name", "Last Modified"}; + QStringList m_column_names_translated = {tr("Enable"), tr("Name"), tr("Last Modified")}; QList m_column_resize_modes = { QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; bool m_can_interact = true; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 8a7b10497..989554de9 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -50,6 +50,8 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) { + m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" }); + m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE}; m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents}; @@ -132,15 +134,11 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient case Qt::DisplayRole: switch (section) { case ActiveColumn: - return tr("Enable"); case NameColumn: - return tr("Name"); case PackFormatColumn: - return tr("Pack Format"); case DateColumn: - return tr("Last changed"); case ImageColumn: - return tr("Image"); + return columnNames().at(section); default: return {}; } diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 76145b3bd..898d128fa 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -45,6 +45,8 @@ 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_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents}; @@ -118,13 +120,10 @@ QVariant TexturePackFolderModel::headerData(int section, Qt::Orientation orienta case Qt::DisplayRole: switch (section) { case ActiveColumn: - return tr("Enable"); case NameColumn: - return tr("Name"); case DateColumn: - return tr("Last modified"); case ImageColumn: - return tr("Image"); + return columnNames().at(section); default: return {}; } From 5fe9e30f394a8025cdb6aa11b4cc11b9a2bb6a64 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 28 May 2023 14:53:15 -0700 Subject: [PATCH 061/429] fix: use instance settings, make image column user resizeable, fix memory leak Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- .../minecraft/mod/ResourceFolderModel.cpp | 27 ++++++++++--------- launcher/minecraft/mod/ResourceFolderModel.h | 2 +- .../minecraft/mod/ResourcePackFolderModel.cpp | 2 +- .../minecraft/mod/TexturePackFolderModel.cpp | 2 +- .../pages/instance/ExternalResourcesPage.cpp | 3 ++- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index b49aac18e..e745f954a 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -60,7 +60,7 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool 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_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; } QVariant ModFolderModel::data(const QModelIndex &index, int role) const diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 2997a43d7..b60f81825 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -513,10 +513,10 @@ void ResourceFolderModel::setupHeaderAction(QAction* act, int column) void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) { auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); - auto setting = (APPLICATION->settings()->contains(setting_name)) ? - APPLICATION->settings()->getSetting(setting_name) : APPLICATION->settings()->registerSetting(setting_name); + auto setting = (m_instance->settings()->contains(setting_name)) ? + m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); - auto hiddenColumns = QVariantUtils::toList(setting->get()); + auto hiddenColumns = setting->get().toStringList(); auto name = columnNames(false).at(column); auto index = hiddenColumns.indexOf(name); if (index >= 0 && !hidden) { @@ -524,30 +524,33 @@ void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) } else if ( index < 0 && hidden) { hiddenColumns.append(name); } - setting->set(QVariantUtils::fromList(hiddenColumns)); + setting->set(hiddenColumns); } void ResourceFolderModel::loadHiddenColumns(QTreeView *tree) { auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); - auto setting = (APPLICATION->settings()->contains(setting_name)) ? - APPLICATION->settings()->getSetting(setting_name) : APPLICATION->settings()->registerSetting(setting_name); + auto setting = (m_instance->settings()->contains(setting_name)) ? + m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); - auto hiddenColumns = QVariantUtils::toList(setting->get().toList()); - for (auto col : hiddenColumns) { - tree->setColumnHidden(col, true); + auto hiddenColumns = setting->get().toStringList(); + auto col_names = columnNames(false); + for (auto col_name : hiddenColumns) { + auto index = col_names.indexOf(col_name); + if (index >= 0) + tree->setColumnHidden(index, true); } } -std::unique_ptr ResourceFolderModel::createHeaderContextMenu(QWidget* parent, QTreeView* tree) +QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) { - auto menu = std::make_unique(parent); + auto menu = new QMenu(tree); menu->addSeparator()->setText(tr("Show / Hide Columns")); for (int col = 0; col < columnCount(); ++col) { - auto act = new QAction(); + auto act = new QAction(menu); setupHeaderAction(act, col); act->setCheckable(true); diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 138815cff..3c9c4d897 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -119,7 +119,7 @@ class ResourceFolderModel : public QAbstractListModel { void setupHeaderAction(QAction* act, int column); void saveHiddenColumn(int column, bool hidden); void loadHiddenColumns(QTreeView* tree); - std::unique_ptr createHeaderContextMenu(QWidget* parent, QTreeView* tree); + QMenu* createHeaderContextMenu(QTreeView* tree); /** This creates a proxy model to filter / sort the model for a UI. * diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 989554de9..14a28b471 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -53,7 +53,7 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE}; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents}; } diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 898d128fa..531a70232 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -48,7 +48,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* 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_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents}; } diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index bee11d9ae..2f824ffb4 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -76,8 +76,9 @@ void ExternalResourcesPage::ShowContextMenu(const QPoint& pos) void ExternalResourcesPage::ShowHeaderContextMenu(const QPoint& pos) { - auto menu = m_model->createHeaderContextMenu(this, ui->treeView); + auto menu = m_model->createHeaderContextMenu(ui->treeView); menu->exec(ui->treeView->mapToGlobal(pos)); + menu->deleteLater(); } void ExternalResourcesPage::openedImpl() From 6c082403c4e910248a41fd84a1a48522484be2cf Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 31 May 2023 20:23:23 +0300 Subject: [PATCH 062/429] Fixed comments Signed-off-by: Trial97 --- launcher/Application.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 430a96aff..026d16360 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -376,13 +376,10 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // init the logger { - static const QString logBase = "logs/"+BuildConfig.LAUNCHER_NAME + "-%0.log"; - QDir logDir = QDir(dataPath); - if(!logDir.exists("logs")) { - logDir.mkpath("logs"); //this can fail, but there is no need to throw an error *yet*, since it also triggers the error message below! - } - auto moveFile = [](const QString &oldName, const QString &newName) - { + static const QString logBase = FS::PathCombine("logs", BuildConfig.LAUNCHER_NAME + "-%0.log"); + FS::ensureFolderPathExists( + "logs"); // this can fail, but there is no need to throw an error *yet*, since it also triggers the error message below! + auto moveFile = [](const QString& oldName, const QString& newName) { QFile::remove(newName); QFile::copy(oldName, newName); QFile::remove(oldName); @@ -394,19 +391,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) moveFile(logBase.arg(0), logBase.arg(1)); logFile = std::unique_ptr(new QFile(logBase.arg(0))); - if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) - { - showFatalErrorMessage( - "The launcher data folder is not writable!", - QString( - "The launcher couldn't create a log file - the data folder is not writable.\n" - "\n" - "Make sure you have write permissions to the logs folder.\n" - "(%1)\n" - "\n" - "The launcher cannot continue until you fix this problem." - ).arg(dataPath+"/logs") - ); + if (!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + showFatalErrorMessage("The launcher data folder is not writable!", + QString("The launcher couldn't create a log file - the data folder is not writable.\n" + "\n" + "Make sure you have write permissions to the data folder.\n" + "(%1)\n" + "\n" + "The launcher cannot continue until you fix this problem.") + .arg(dataPath)); return; } qInstallMessageHandler(appDebugOutput); From 03b66ba7a5a1e35f47a59a9e1cd5d73ad6685c8e Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 31 May 2023 13:25:14 -0700 Subject: [PATCH 063/429] packaging: make windows nsis installer run the uninstaller for previous install before installing Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- program_info/win_install.nsi.in | 76 +++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 1d902d5d9..27c400395 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -12,6 +12,8 @@ OutFile "../@Launcher_CommonName@-Setup.exe" !define MUI_ICON "../@Launcher_Branding_ICO@" +!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\@Launcher_CommonName@" + ;-------------------------------- ; Pages @@ -269,7 +271,74 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@ !macroend -;-------------------------------- +;------------------------------------------ +; Uninstall Previous install + +!macro RunUninstall exitcode uninstcommand + Push `${uninstcommand}` + Call RunUninstall + Pop ${exitcode} +!macroend + +; Checks that the uninstaller in the provided command exists and runs it. +Function RunUninstall + Exch $1 ; input uninstcommand + Push $2 ; Uninstaller + Push $3 ; Len + Push $4 ; uninstcommand + StrCpy $4 $1 ; make a copy of the command for later + StrCpy $3 "" + StrCpy $2 $1 1 ; take first char of string + StrCmp $2 '"' quoteloop stringloop + stringloop: ; get string length + StrCpy $2 $1 1 $3 ; get next char + IntOp $3 $3 + 1 ; index += 1 + StrCmp $2 "" +2 stringloop; if empty exit loop + IntOp $3 $3 - 1 ; index -= 1 + Goto run + quoteloop: ; get string length with quotes removed + StrCmp $3 "" 0 +2 ; if index is set skip quote removal + StrCpy $1 $1 "" 1 ; Remove initial quote + IntOp $3 $3 + 1 ; index += 1 + StrCpy $2 $1 1 $3 ; get next char + StrCmp $2 "" +2 ; if empty exit loop + StrCmp $2 '"' 0 quoteloop ; if ending quote exit loop, else loop + run: + StrCpy $2 $1 $3 ; Path to uninstaller ; (copy string up to ending quote - if it exists) + StrCpy $1 161 ; ERROR_BAD_PATHNAME ; set exit code (it get's overwritten with uninstaller exit code if ExecWait call doesn't error) + GetFullPathName $3 "$2\.." ; $InstDir + IfFileExists "$2" 0 +4 + ExecWait $4 $1 ; The file exists, call the saved command + IntCmp $1 0 "" +2 +2 ; Don't delete the installer if it was aborted ; + Delete "$2" ; Delete the uninstaller + RMDir "$3" ; Try to delete $InstDir + Pop $4 + Pop $3 + Pop $2 + Exch $1 ; exitcode +FunctionEnd + +; The "" makes the section hidden. +Section "" UninstallPrevious + + ReadRegStr $0 HKCU "${UNINST_KEY}" "QuietUninstallString" + ${If} $0 == "" + ReadRegStr $0 HKCU "${UNINST_KEY}" "UninstallString" + ${EndIf} + + ${If} $0 != "" + ${AndIf} ${Cmd} `MessageBox MB_YESNO|MB_ICONQUESTION "Uninstall previous version?" /SD IDYES IDYES` + !insertmacro RunUninstall $0 $0 + ${If} $0 <> 0 + MessageBox MB_YESNO|MB_ICONSTOP "Failed to uninstall, continue anyway?" /SD IDYES IDYES +2 + Abort + ${EndIf} + ${EndIf} + +SectionEnd + + +;------------------------------------ ; The stuff to install Section "@Launcher_DisplayName@" @@ -299,11 +368,10 @@ Section "@Launcher_DisplayName@" ${GetParameters} $R0 ${GetOptions} $R0 "/NoUninstaller" $R1 ${If} ${Errors} - !define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\@Launcher_CommonName@" WriteRegStr HKCU "${UNINST_KEY}" "DisplayName" "@Launcher_DisplayName@" WriteRegStr HKCU "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\@Launcher_APP_BINARY_NAME@.exe" - WriteRegStr HKCU "${UNINST_KEY}" "UninstallString" '"$INSTDIR\uninstall.exe"' - WriteRegStr HKCU "${UNINST_KEY}" "QuietUninstallString" '"$INSTDIR\uninstall.exe" /S' + WriteRegStr HKCU "${UNINST_KEY}" "UninstallString" '"$INSTDIR\uninstall.exe" _?=$INSTDIR' + WriteRegStr HKCU "${UNINST_KEY}" "QuietUninstallString" '"$INSTDIR\uninstall.exe" /S _?=$INSTDIR' WriteRegStr HKCU "${UNINST_KEY}" "InstallLocation" "$INSTDIR" WriteRegStr HKCU "${UNINST_KEY}" "Publisher" "@Launcher_DisplayName@ Contributors" WriteRegStr HKCU "${UNINST_KEY}" "Version" "@Launcher_VERSION_NAME4@" From 4593538fc864fe67d4c31376506f4d2b81201895 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 31 May 2023 13:54:13 -0700 Subject: [PATCH 064/429] fix: typo - space before comment Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- program_info/win_install.nsi.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 27c400395..8389e2468 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -293,7 +293,7 @@ Function RunUninstall stringloop: ; get string length StrCpy $2 $1 1 $3 ; get next char IntOp $3 $3 + 1 ; index += 1 - StrCmp $2 "" +2 stringloop; if empty exit loop + StrCmp $2 "" +2 stringloop ; if empty exit loop IntOp $3 $3 - 1 ; index -= 1 Goto run quoteloop: ; get string length with quotes removed From 6a4fb6a27149893f65d09cb69f1ee7f0ad6bcfad Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 1 Jun 2023 12:40:08 -0700 Subject: [PATCH 065/429] packaging: remove redundant "do you want to uninstall previous version" Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- program_info/win_install.nsi.in | 1 - 1 file changed, 1 deletion(-) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 8389e2468..d3b5c256f 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -327,7 +327,6 @@ Section "" UninstallPrevious ${EndIf} ${If} $0 != "" - ${AndIf} ${Cmd} `MessageBox MB_YESNO|MB_ICONQUESTION "Uninstall previous version?" /SD IDYES IDYES` !insertmacro RunUninstall $0 $0 ${If} $0 <> 0 MessageBox MB_YESNO|MB_ICONSTOP "Failed to uninstall, continue anyway?" /SD IDYES IDYES +2 From 3a6657596ba19a0310df38ed0c94f292c2de68c9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 1 Jun 2023 23:48:48 +0300 Subject: [PATCH 066/429] Added migration for old logs Signed-off-by: Trial97 --- launcher/Application.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 026d16360..e9a3cb894 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -376,9 +376,18 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // init the logger { - static const QString logBase = FS::PathCombine("logs", BuildConfig.LAUNCHER_NAME + "-%0.log"); - FS::ensureFolderPathExists( - "logs"); // this can fail, but there is no need to throw an error *yet*, since it also triggers the error message below! + static const QString baseLogFile = BuildConfig.LAUNCHER_NAME + "-%0.log"; + static const QString logBase = FS::PathCombine("logs", baseLogFile); + if (FS::ensureFolderPathExists("logs")) { // if this did not fail + for (auto i = 0; i <= 4; i++) { + auto oldName = baseLogFile.arg(i); + auto newName = logBase.arg(i); + if (QFile::exists(newName)) // in case there are already files in folder just to be safe add a suffix + newName += ".old"; + QFile::rename(oldName, newName); + } + } + auto moveFile = [](const QString& oldName, const QString& newName) { QFile::remove(newName); QFile::copy(oldName, newName); From 17691ab5154ecadf661f1035cfc87b4e4c5e236f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 2 Jun 2023 01:22:25 +0300 Subject: [PATCH 067/429] Made use of moveFile function Signed-off-by: Trial97 --- launcher/Application.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index e9a3cb894..724e6e44d 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -378,26 +378,20 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) { static const QString baseLogFile = BuildConfig.LAUNCHER_NAME + "-%0.log"; static const QString logBase = FS::PathCombine("logs", baseLogFile); - if (FS::ensureFolderPathExists("logs")) { // if this did not fail - for (auto i = 0; i <= 4; i++) { - auto oldName = baseLogFile.arg(i); - auto newName = logBase.arg(i); - if (QFile::exists(newName)) // in case there are already files in folder just to be safe add a suffix - newName += ".old"; - QFile::rename(oldName, newName); - } - } - auto moveFile = [](const QString& oldName, const QString& newName) { QFile::remove(newName); QFile::copy(oldName, newName); QFile::remove(oldName); }; + if (FS::ensureFolderPathExists("logs")) { // if this did not fail + for (auto i = 0; i <= 4; i++) + if (auto oldName = baseLogFile.arg(i); + QFile::exists(oldName)) // do not pointlessly delete new files if the old ones are not there + moveFile(oldName, logBase.arg(i)); + } - moveFile(logBase.arg(3), logBase.arg(4)); - moveFile(logBase.arg(2), logBase.arg(3)); - moveFile(logBase.arg(1), logBase.arg(2)); - moveFile(logBase.arg(0), logBase.arg(1)); + for (auto i = 4; i > 0; i--) + moveFile(logBase.arg(i - 1), logBase.arg(i)); logFile = std::unique_ptr(new QFile(logBase.arg(0))); if (!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { From 0f0cbd4c1faf7584f8f6deff7421ce8d7e79befb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 2 Jun 2023 12:41:18 +0200 Subject: [PATCH 068/429] refactor(nix): introduce unwrapped packages Signed-off-by: Sefa Eyeoglu --- nix/distribution.nix | 10 ++++---- nix/package.nix | 57 +++++++++----------------------------------- 2 files changed, 17 insertions(+), 50 deletions(-) diff --git a/nix/distribution.nix b/nix/distribution.nix index 0b223f175..7c5ef93ad 100644 --- a/nix/distribution.nix +++ b/nix/distribution.nix @@ -6,13 +6,13 @@ }: { perSystem = {pkgs, ...}: { packages = { - inherit (pkgs) prismlauncher prismlauncher-qt5; + inherit (pkgs) prismlauncher-qt5-unwrapped prismlauncher-qt5 prismlauncher-unwrapped prismlauncher; default = pkgs.prismlauncher; }; }; flake = { - overlays.default = _: prev: let + overlays.default = final: prev: let # Helper function to build prism against different versions of Qt. mkPrism = qt: qt.callPackage ./package.nix { @@ -20,8 +20,10 @@ inherit self version; }; in { - prismlauncher = mkPrism prev.qt6Packages; - prismlauncher-qt5 = mkPrism prev.libsForQt5; + prismlauncher-qt5-unwrapped = mkPrism final.libsForQt5; + prismlauncher-qt5 = prev.prismlauncher-qt5.override {inherit (final) prismlauncher-unwrapped;}; + prismlauncher-unwrapped = mkPrism final.qt6Packages; + prismlauncher = prev.prismlauncher.override {inherit (final) prismlauncher-unwrapped;}; }; }; } diff --git a/nix/package.nix b/nix/package.nix index e0616b6ea..edc266dc4 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -3,86 +3,51 @@ stdenv, cmake, ninja, - jdk8, jdk17, zlib, - file, - wrapQtAppsHook, - xorg, - libpulseaudio, qtbase, - qtsvg, - qtwayland, - libGL, quazip, - glfw, - openal, extra-cmake-modules, tomlplusplus, - ghc_filesystem, cmark, - msaClientID ? "", - jdks ? [jdk17 jdk8], - gamemodeSupport ? true, + ghc_filesystem, gamemode, - # flake + msaClientID ? null, + gamemodeSupport ? true, self, version, libnbtplusplus, }: stdenv.mkDerivation rec { - pname = "prismlauncher"; + pname = "prismlauncher-unwrapped"; inherit version; src = lib.cleanSource self; - nativeBuildInputs = [extra-cmake-modules cmake file jdk17 ninja wrapQtAppsHook]; + nativeBuildInputs = [extra-cmake-modules cmake jdk17 ninja]; buildInputs = [ qtbase - qtsvg zlib quazip ghc_filesystem tomlplusplus cmark ] - ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland - ++ lib.optional gamemodeSupport gamemode.dev; + ++ lib.optional gamemodeSupport gamemode; + + hardeningEnable = ["pie"]; cmakeFlags = - lib.optionals (msaClientID != "") ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"] + lib.optionals (msaClientID != null) ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"] ++ lib.optionals (lib.versionOlder qtbase.version "6") ["-DLauncher_QT_VERSION_MAJOR=5"]; postUnpack = '' rm -rf source/libraries/libnbtplusplus - mkdir source/libraries/libnbtplusplus - ln -s ${libnbtplusplus}/* source/libraries/libnbtplusplus - chmod -R +r+w source/libraries/libnbtplusplus - chown -R $USER: source/libraries/libnbtplusplus + ln -s ${libnbtplusplus} source/libraries/libnbtplusplus ''; - qtWrapperArgs = let - libpath = with xorg; - lib.makeLibraryPath ([ - libX11 - libXext - libXcursor - libXrandr - libXxf86vm - libpulseaudio - libGL - glfw - openal - stdenv.cc.cc.lib - ] - ++ lib.optional gamemodeSupport gamemode.lib); - in [ - "--set LD_LIBRARY_PATH /run/opengl-driver/lib:${libpath}" - "--prefix PRISMLAUNCHER_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}" - # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128 - "--prefix PATH : ${lib.makeBinPath [xorg.xrandr]}" - ]; + dontWrapQtApps = true; meta = with lib; { homepage = "https://prismlauncher.org/"; From 29e532c096e8c89ba3f0e071fbdecf646f9814ea Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 2 Jun 2023 11:53:09 -0400 Subject: [PATCH 069/429] fix(nix): fix prismlauncher-qt5 Signed-off-by: seth --- nix/distribution.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/distribution.nix b/nix/distribution.nix index 7c5ef93ad..0f2e26f3e 100644 --- a/nix/distribution.nix +++ b/nix/distribution.nix @@ -21,7 +21,7 @@ }; in { prismlauncher-qt5-unwrapped = mkPrism final.libsForQt5; - prismlauncher-qt5 = prev.prismlauncher-qt5.override {inherit (final) prismlauncher-unwrapped;}; + prismlauncher-qt5 = prev.prismlauncher-qt5.override {prismlauncher-unwrapped = final.prismlauncher-qt5-unwrapped;}; prismlauncher-unwrapped = mkPrism final.qt6Packages; prismlauncher = prev.prismlauncher.override {inherit (final) prismlauncher-unwrapped;}; }; From f6f32914de6dbad07cffe786d0f15df03525a1c2 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:48:02 -0700 Subject: [PATCH 070/429] fix: add origonal instance path to allowed_symlinks.txt when copying via symlinks Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/InstanceCopyTask.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index 4ac3b51ad..abe97b170 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -39,7 +39,16 @@ void InstanceCopyTask::executeTask() setStatus(tr("Copying instance %1").arg(m_origInstance->name())); auto copySaves = [&]() { - FS::copy savesCopy(FS::PathCombine(m_origInstance->instanceRoot(), "saves"), FS::PathCombine(m_stagingPath, "saves")); + QFileInfo mcDir(FS::PathCombine(m_stagingPath, "minecraft")); + QFileInfo dotMCDir(FS::PathCombine(m_stagingPath, ".minecraft")); + + QString staging_mc_dir; + if (mcDir.exists() && !dotMCDir.exists()) + staging_mc_dir = mcDir.filePath(); + else + staging_mc_dir = dotMCDir.filePath(); + + FS::copy savesCopy(FS::PathCombine(m_origInstance->gameRoot(), "saves"), FS::PathCombine(staging_mc_dir, "saves")); savesCopy.followSymlinks(true); return savesCopy(); @@ -123,6 +132,7 @@ void InstanceCopyTask::copyFinished() emitFailed(tr("Instance folder copy failed.")); return; } + // FIXME: shouldn't this be able to report errors? auto instanceSettings = std::make_shared(FS::PathCombine(m_stagingPath, "instance.cfg")); @@ -134,6 +144,24 @@ void InstanceCopyTask::copyFinished() } if (m_useLinks) inst->addLinkedInstanceId(m_origInstance->id()); + if (m_useLinks) { + auto allowed_symlinks_file = QFileInfo(FS::PathCombine(inst->gameRoot(), "allowed_symlinks.txt")); + + QByteArray allowed_symlinks; + if (allowed_symlinks_file.exists()) { + allowed_symlinks.append(FS::read(allowed_symlinks_file.path())); + if (allowed_symlinks.right(1) != "\n") + allowed_symlinks.append("\n"); // we want to be on a new line + } + allowed_symlinks.append(m_origInstance->gameRoot().toUtf8()); + allowed_symlinks.append("\n"); + if (allowed_symlinks_file.isSymbolicLink()) + FS::deletePath(allowed_symlinks_file + .path()); // we dont want to modify the origonal. also make sure the resulting file is not itself a link. + + FS::write(allowed_symlinks_file.path(), allowed_symlinks); + } + emitSucceeded(); } From 8eb10e991f79ef38e1c689d28e34b5f4fda8dc83 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 2 Jun 2023 16:14:38 -0700 Subject: [PATCH 071/429] fix: use isSymLink (i've made this mistake before but I've made it again) Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/InstanceCopyTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index abe97b170..a0b5635c5 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -155,7 +155,7 @@ void InstanceCopyTask::copyFinished() } allowed_symlinks.append(m_origInstance->gameRoot().toUtf8()); allowed_symlinks.append("\n"); - if (allowed_symlinks_file.isSymbolicLink()) + if (allowed_symlinks_file.isSymLink()) FS::deletePath(allowed_symlinks_file .path()); // we dont want to modify the origonal. also make sure the resulting file is not itself a link. From f613b03efd58e04451e70d4e673adff5837492a9 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 3 Jun 2023 08:28:49 -0700 Subject: [PATCH 072/429] Typo fix Co-authored-by: Sefa Eyeoglu Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/InstanceCopyTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index a0b5635c5..60dcd5a1c 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -157,7 +157,7 @@ void InstanceCopyTask::copyFinished() allowed_symlinks.append("\n"); if (allowed_symlinks_file.isSymLink()) FS::deletePath(allowed_symlinks_file - .path()); // we dont want to modify the origonal. also make sure the resulting file is not itself a link. + .path()); // we dont want to modify the original. also make sure the resulting file is not itself a link. FS::write(allowed_symlinks_file.path(), allowed_symlinks); } From 5824047ffa4e31f018ddc068c2677ce9b8e5b43d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 5 Jun 2023 01:12:16 -0700 Subject: [PATCH 073/429] fix(memory leak): cyclic refrence in translations model dl task Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/translations/TranslationsModel.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 46db48049..23e55c51d 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -190,7 +190,7 @@ struct TranslationsModel::Private std::unique_ptr m_qt_translator; std::unique_ptr m_app_translator; - Net::Download::Ptr m_index_task; + Net::Download* m_index_task; QString m_downloadingTranslation; NetJob::Ptr m_dl_job; NetJob::Ptr m_index_job; @@ -673,8 +673,9 @@ void TranslationsModel::downloadIndex() d->m_index_job.reset(new NetJob("Translations Index", APPLICATION->network())); MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("translations", "index_v2.json"); entry->setStale(true); - d->m_index_task = Net::Download::makeCached(QUrl(BuildConfig.TRANSLATIONS_BASE_URL + "index_v2.json"), entry); - d->m_index_job->addNetAction(d->m_index_task); + auto task = Net::Download::makeCached(QUrl(BuildConfig.TRANSLATIONS_BASE_URL + "index_v2.json"), entry); + d->m_index_task = task.get(); + d->m_index_job->addNetAction(task); connect(d->m_index_job.get(), &NetJob::failed, this, &TranslationsModel::indexFailed); connect(d->m_index_job.get(), &NetJob::succeeded, this, &TranslationsModel::indexReceived); d->m_index_job->start(); From 37b4f606c8e0853c831f792e7238587c66222176 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 5 Jun 2023 17:52:48 +0100 Subject: [PATCH 074/429] Validate input lengths on mrpack export Signed-off-by: TheKodeToad --- launcher/ui/dialogs/ExportMrPackDialog.cpp | 14 ++++++++++++++ launcher/ui/dialogs/ExportMrPackDialog.h | 1 + launcher/ui/dialogs/ExportMrPackDialog.ui | 6 +++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 06e4693ea..239873f6d 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "FastFileIconProvider.h" #include "FileSystem.h" #include "MMCZip.h" @@ -38,6 +39,13 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) ui->name->setText(instance->name()); ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + // ensure a valid pack is generated + // the name and version fields mustn't be empty + connect(ui->name, &QLineEdit::textEdited, this, &ExportMrPackDialog::validate); + connect(ui->version, &QLineEdit::textEdited, this, &ExportMrPackDialog::validate); + // the instance name can technically be empty + validate(); + QFileSystemModel* model = new QFileSystemModel(this); model->setIconProvider(&icons); @@ -107,3 +115,9 @@ void ExportMrPackDialog::done(int result) QDialog::done(result); } + +void ExportMrPackDialog::validate() +{ + const bool invalid = ui->name->text().isEmpty() || ui->version->text().isEmpty(); + ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(invalid); +} diff --git a/launcher/ui/dialogs/ExportMrPackDialog.h b/launcher/ui/dialogs/ExportMrPackDialog.h index 98f1d5fc5..1c70c4ae1 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.h +++ b/launcher/ui/dialogs/ExportMrPackDialog.h @@ -35,6 +35,7 @@ class ExportMrPackDialog : public QDialog { ~ExportMrPackDialog(); void done(int result) override; + void validate(); private: const InstancePtr instance; diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index f154d210b..9a7897378 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -51,7 +51,11 @@ - + + + 1.0.0 + + From 961285d6abad3e70a0ab748007349ef67632f138 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 5 Jun 2023 20:49:47 +0100 Subject: [PATCH 075/429] Add a search bar to version lists Signed-off-by: TheKodeToad --- launcher/VersionProxyModel.cpp | 21 ++++++++- launcher/VersionProxyModel.h | 3 ++ launcher/ui/dialogs/VersionSelectDialog.cpp | 47 +++++++++++++------- launcher/ui/widgets/JavaSettingsWidget.cpp | 2 +- launcher/ui/widgets/VersionSelectWidget.cpp | 34 ++++++++++++++- launcher/ui/widgets/VersionSelectWidget.h | 48 +++++++++++++++------ 6 files changed, 122 insertions(+), 33 deletions(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 6aba268d8..d5d14c246 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * 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 @@ -54,9 +55,14 @@ public: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { const auto &filters = m_parent->filters(); + const QString &search = m_parent->search(); + const QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); + + if (!search.isEmpty() && !sourceModel()->data(idx, BaseVersionList::VersionRole).toString().contains(search)) + return false; + for (auto it = filters.begin(); it != filters.end(); ++it) { - auto idx = sourceModel()->index(source_row, 0, source_parent); auto data = sourceModel()->data(idx, it.key()); auto match = data.toString(); if(!it.value()->accepts(match)) @@ -431,6 +437,7 @@ QModelIndex VersionProxyModel::getVersion(const QString& version) const void VersionProxyModel::clearFilters() { m_filters.clear(); + m_search.clear(); filterModel->filterChanged(); } @@ -440,11 +447,21 @@ void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filt filterModel->filterChanged(); } +void VersionProxyModel::setSearch(const QString &search) { + m_search = search; + filterModel->filterChanged(); +} + const VersionProxyModel::FilterMap &VersionProxyModel::filters() const { return m_filters; } +const QString &VersionProxyModel::search() const +{ + return m_search; +} + void VersionProxyModel::sourceAboutToBeReset() { beginResetModel(); diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index 8991c31b0..6434376c6 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -38,7 +38,9 @@ public: virtual void setSourceModel(QAbstractItemModel *sourceModel) override; const FilterMap &filters() const; + const QString &search() const; void setFilter(const BaseVersionList::ModelRoles column, Filter * filter); + void setSearch(const QString &search); void clearFilters(); QModelIndex getRecommended() const; QModelIndex getVersion(const QString & version) const; @@ -59,6 +61,7 @@ private slots: private: QList m_columns; FilterMap m_filters; + QString m_search; BaseVersionList::RoleList roles; VersionFilterModel * filterModel; bool hasRecommended = false; diff --git a/launcher/ui/dialogs/VersionSelectDialog.cpp b/launcher/ui/dialogs/VersionSelectDialog.cpp index d7880334f..5feb70d20 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.cpp +++ b/launcher/ui/dialogs/VersionSelectDialog.cpp @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 TheKodeToad * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * 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 "VersionSelectDialog.h" @@ -22,15 +42,10 @@ #include #include -#include "ui/dialogs/ProgressDialog.h" #include "ui/widgets/VersionSelectWidget.h" -#include "ui/dialogs/CustomMessageBox.h" #include "BaseVersion.h" #include "BaseVersionList.h" -#include "tasks/Task.h" -#include "Application.h" -#include "VersionProxyModel.h" VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable) : QDialog(parent) @@ -40,7 +55,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, m_verticalLayout = new QVBoxLayout(this); m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); - m_versionWidget = new VersionSelectWidget(parent); + m_versionWidget = new VersionSelectWidget(true, parent); m_verticalLayout->addWidget(m_versionWidget); m_horizontalLayout = new QHBoxLayout(); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 159943198..c94fdd8d5 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -46,7 +46,7 @@ void JavaSettingsWidget::setupUi() m_verticalLayout = new QVBoxLayout(this); m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); - m_versionWidget = new VersionSelectWidget(this); + m_versionWidget = new VersionSelectWidget(true, this); m_verticalLayout->addWidget(m_versionWidget); m_horizontalLayout = new QHBoxLayout(); diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp index 404860d90..252e2719e 100644 --- a/launcher/ui/widgets/VersionSelectWidget.cpp +++ b/launcher/ui/widgets/VersionSelectWidget.cpp @@ -8,8 +8,10 @@ #include "ui/dialogs/CustomMessageBox.h" -VersionSelectWidget::VersionSelectWidget(QWidget* parent) - : QWidget(parent) +VersionSelectWidget::VersionSelectWidget(QWidget* parent) : VersionSelectWidget(false, parent) {} + +VersionSelectWidget::VersionSelectWidget(bool focusSearch, QWidget* parent) + : QWidget(parent), focusSearch(focusSearch) { setObjectName(QStringLiteral("VersionSelectWidget")); verticalLayout = new QVBoxLayout(this); @@ -30,6 +32,12 @@ VersionSelectWidget::VersionSelectWidget(QWidget* parent) listView->setModel(m_proxyModel); verticalLayout->addWidget(listView); + search = new QLineEdit(this); + search->setPlaceholderText(tr("Search")); + search->setClearButtonEnabled(true); + verticalLayout->addWidget(search); + connect(search, &QLineEdit::textEdited, this, &VersionSelectWidget::updateSearch); + sneakyProgressBar = new QProgressBar(this); sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar")); sneakyProgressBar->setFormat(QStringLiteral("%p%")); @@ -89,6 +97,8 @@ void VersionSelectWidget::initialize(BaseVersionList *vlist) { listView->setEmptyMode(VersionListView::String); } + search->setFocus(); + focusSearch = false; preselect(); } } @@ -114,6 +124,7 @@ void VersionSelectWidget::loadList() loadTask->start(); } sneakyProgressBar->setHidden(false); + search->setHidden(true); } void VersionSelectWidget::onTaskSucceeded() @@ -123,6 +134,14 @@ void VersionSelectWidget::onTaskSucceeded() listView->setEmptyMode(VersionListView::String); } sneakyProgressBar->setHidden(true); + search->setHidden(false); + + if (focusSearch) + { + search->setFocus(); + focusSearch = false; + } + preselect(); loadTask = nullptr; } @@ -155,6 +174,17 @@ void VersionSelectWidget::preselect() selectRecommended(); } +void VersionSelectWidget::updateSearch(const QString &value) { + m_proxyModel->setSearch(value); + // if nothing is selected, pick the first result + if (!value.isEmpty()) { + listView->selectionModel()->setCurrentIndex( + listView->model()->index(0, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + listView->scrollToTop(); + } else + listView->scrollTo(listView->selectionModel()->currentIndex(), QAbstractItemView::PositionAtCenter); +} + void VersionSelectWidget::selectCurrent() { if(m_currentVersion.isEmpty()) diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h index e75efc6f6..df9c8a628 100644 --- a/launcher/ui/widgets/VersionSelectWidget.h +++ b/launcher/ui/widgets/VersionSelectWidget.h @@ -1,22 +1,43 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 TheKodeToad * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * 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 #include +#include #include "BaseVersionList.h" #include "VersionListView.h" @@ -30,7 +51,8 @@ class VersionSelectWidget: public QWidget { Q_OBJECT public: - explicit VersionSelectWidget(QWidget *parent = 0); + explicit VersionSelectWidget(QWidget *parent); + explicit VersionSelectWidget(bool focusSearch = false, QWidget *parent = 0); ~VersionSelectWidget(); //! loads the list if needed. @@ -67,6 +89,7 @@ private slots: private: void preselect(); + void updateSearch(const QString &value); private: QString m_currentVersion; @@ -75,9 +98,10 @@ private: int resizeOnColumn = 0; Task * loadTask; bool preselectedAlready = false; + bool focusSearch; -private: QVBoxLayout *verticalLayout = nullptr; VersionListView *listView = nullptr; + QLineEdit *search; QProgressBar *sneakyProgressBar = nullptr; }; From 7c5047b2acd25708063056cff547dc1b8fcfbb41 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 5 Jun 2023 23:10:41 +0100 Subject: [PATCH 076/429] cAsE iNsEnSiTiVe Signed-off-by: TheKodeToad --- launcher/VersionProxyModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index d5d14c246..47cfa5ba3 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -58,7 +58,7 @@ public: const QString &search = m_parent->search(); const QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); - if (!search.isEmpty() && !sourceModel()->data(idx, BaseVersionList::VersionRole).toString().contains(search)) + if (!search.isEmpty() && !sourceModel()->data(idx, BaseVersionList::VersionRole).toString().contains(search, Qt::CaseInsensitive)) return false; for (auto it = filters.begin(); it != filters.end(); ++it) From 6505a6280111e29b33d829703d1c1a87f90dba7a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 6 Jun 2023 10:34:05 +0300 Subject: [PATCH 077/429] Renamed requires fields Signed-off-by: Trial97 --- launcher/meta/JsonFormat.cpp | 7 +++---- launcher/meta/Version.cpp | 4 ++-- launcher/meta/Version.h | 4 ++-- launcher/meta/VersionList.cpp | 4 ++-- launcher/minecraft/Component.cpp | 4 ++-- launcher/minecraft/OneSixVersionFormat.cpp | 10 +++++----- launcher/minecraft/VersionFile.h | 2 +- launcher/modplatform/atlauncher/ATLPackInstallTask.cpp | 2 +- .../atlauncher/AtlUserInteractionSupportImpl.cpp | 2 +- 9 files changed, 19 insertions(+), 20 deletions(-) diff --git a/launcher/meta/JsonFormat.cpp b/launcher/meta/JsonFormat.cpp index 473f37d66..cb2d06ea0 100644 --- a/launcher/meta/JsonFormat.cpp +++ b/launcher/meta/JsonFormat.cpp @@ -56,10 +56,10 @@ static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &ob version->setType(ensureString(obj, "type", QString())); version->setRecommended(ensureBoolean(obj, QString("recommended"), false)); version->setVolatile(ensureBoolean(obj, QString("volatile"), false)); - RequireSet requires, conflicts; - parseRequires(obj, &requires, "requires"); + RequireSet reqs, conflicts; + parseRequires(obj, &reqs, "requires"); parseRequires(obj, &conflicts, "conflicts"); - version->setRequires(requires, conflicts); + version->setRequires(reqs, conflicts); return version; } @@ -176,7 +176,6 @@ void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char * keyName { if(obj.contains(keyName)) { - QSet requires; auto reqArray = requireArray(obj, keyName); auto iter = reqArray.begin(); while(iter != reqArray.end()) diff --git a/launcher/meta/Version.cpp b/launcher/meta/Version.cpp index e617abf82..0718a4204 100644 --- a/launcher/meta/Version.cpp +++ b/launcher/meta/Version.cpp @@ -116,9 +116,9 @@ void Meta::Version::setTime(const qint64 time) emit timeChanged(); } -void Meta::Version::setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts) +void Meta::Version::setRequires(const Meta::RequireSet &reqs, const Meta::RequireSet &conflicts) { - m_requires = requires; + m_requires = reqs; m_conflicts = conflicts; emit requiresChanged(); } diff --git a/launcher/meta/Version.h b/launcher/meta/Version.h index 781561931..59a96a68b 100644 --- a/launcher/meta/Version.h +++ b/launcher/meta/Version.h @@ -63,7 +63,7 @@ public: { return m_time; } - const Meta::RequireSet &requires() const + const Meta::RequireSet &requiredSet() const { return m_requires; } @@ -91,7 +91,7 @@ public: public: // for usage by format parsers only void setType(const QString &type); void setTime(const qint64 time); - void setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts); + void setRequires(const Meta::RequireSet &reqs, const Meta::RequireSet &conflicts); void setVolatile(bool volatile_); void setRecommended(bool recommended); void setProvidesRecommendations(); diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp index 7f001dfc2..9f4482784 100644 --- a/launcher/meta/VersionList.cpp +++ b/launcher/meta/VersionList.cpp @@ -77,7 +77,7 @@ QVariant VersionList::data(const QModelIndex &index, int role) const case ParentVersionRole: { // FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent uid'. - auto & reqs = version->requires(); + auto & reqs = version->requiredSet(); auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require & req) { return req.uid == "net.minecraft"; @@ -92,7 +92,7 @@ QVariant VersionList::data(const QModelIndex &index, int role) const case UidRole: return version->uid(); case TimeRole: return version->time(); - case RequiresRole: return QVariant::fromValue(version->requires()); + case RequiresRole: return QVariant::fromValue(version->requiredSet()); case SortRole: return version->rawTime(); case VersionPtrRole: return QVariant::fromValue(version); case RecommendedRole: return version->isRecommended(); diff --git a/launcher/minecraft/Component.cpp b/launcher/minecraft/Component.cpp index 7e5b60589..ff81fcbb8 100644 --- a/launcher/minecraft/Component.cpp +++ b/launcher/minecraft/Component.cpp @@ -451,9 +451,9 @@ void Component::updateCachedData() m_cachedVolatile = file->m_volatile; changed = true; } - if(!deepCompare(m_cachedRequires, file->requires)) + if(!deepCompare(m_cachedRequires, file->m_requires)) { - m_cachedRequires = file->requires; + m_cachedRequires = file->m_requires; changed = true; } if(!deepCompare(m_cachedConflicts, file->conflicts)) diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 888b68609..b586198bf 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -276,7 +276,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc if (root.contains("requires")) { - Meta::parseRequires(root, &out->requires); + Meta::parseRequires(root, &out->m_requires); } QString dependsOnMinecraftVersion = root.value("mcVersion").toString(); if(!dependsOnMinecraftVersion.isEmpty()) @@ -284,9 +284,9 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc Meta::Require mcReq; mcReq.uid = "net.minecraft"; mcReq.equalsVersion = dependsOnMinecraftVersion; - if (out->requires.count(mcReq) == 0) + if (out->m_requires.count(mcReq) == 0) { - out->requires.insert(mcReq); + out->m_requires.insert(mcReq); } } if (root.contains("conflicts")) @@ -392,9 +392,9 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch } root.insert("mods", array); } - if(!patch->requires.empty()) + if(!patch->m_requires.empty()) { - Meta::serializeRequires(root, &patch->requires, "requires"); + Meta::serializeRequires(root, &patch->m_requires, "requires"); } if(!patch->conflicts.empty()) { diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index 11c5a3af3..8e9dd1670 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -138,7 +138,7 @@ public: /* data */ * Prism Launcher: set of packages this depends on * NOTE: this is shared with the meta format!!! */ - Meta::RequireSet requires; + Meta::RequireSet m_requires; /** * Prism Launcher: set of packages this conflicts with diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 96cea7b7d..07e0bf23b 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -352,7 +352,7 @@ QString PackInstallTask::getVersionForLoader(QString uid) if(m_version.loader.recommended || m_version.loader.latest) { for (int i = 0; i < vlist->versions().size(); i++) { auto version = vlist->versions().at(i); - auto reqs = version->requires(); + auto reqs = version->requiredSet(); // filter by minecraft version, if the loader depends on a certain version. // not all mod loaders depend on a given Minecraft version, so we won't do this diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp index f5f50caee..3d2d568a1 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp @@ -68,7 +68,7 @@ QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionList::Ptr vlis // select recommended build for (int i = 0; i < vlist->versions().size(); i++) { auto version = vlist->versions().at(i); - auto reqs = version->requires(); + auto reqs = version->requiredSet(); // filter by minecraft version, if the loader depends on a certain version. if (minecraftVersion != nullptr) { From c343036d3bfd60cb24477fcd2ae1286276236a68 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 6 Jun 2023 12:24:53 +0100 Subject: [PATCH 078/429] Simplify Signed-off-by: TheKodeToad --- launcher/ui/widgets/VersionSelectWidget.cpp | 29 +++++++-------------- launcher/ui/widgets/VersionSelectWidget.h | 1 - 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp index 252e2719e..6aaffaaca 100644 --- a/launcher/ui/widgets/VersionSelectWidget.cpp +++ b/launcher/ui/widgets/VersionSelectWidget.cpp @@ -36,7 +36,15 @@ VersionSelectWidget::VersionSelectWidget(bool focusSearch, QWidget* parent) search->setPlaceholderText(tr("Search")); search->setClearButtonEnabled(true); verticalLayout->addWidget(search); - connect(search, &QLineEdit::textEdited, this, &VersionSelectWidget::updateSearch); + connect(search, &QLineEdit::textEdited, [this](const QString& value) { + m_proxyModel->setSearch(value); + if (!value.isEmpty() || !listView->selectionModel()->hasSelection()) { + const QModelIndex first = listView->model()->index(0, 0); + listView->selectionModel()->setCurrentIndex(first, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + listView->scrollToTop(); + } else + listView->scrollTo(listView->selectionModel()->currentIndex(), QAbstractItemView::PositionAtCenter); + }); sneakyProgressBar = new QProgressBar(this); sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar")); @@ -124,7 +132,6 @@ void VersionSelectWidget::loadList() loadTask->start(); } sneakyProgressBar->setHidden(false); - search->setHidden(true); } void VersionSelectWidget::onTaskSucceeded() @@ -134,13 +141,6 @@ void VersionSelectWidget::onTaskSucceeded() listView->setEmptyMode(VersionListView::String); } sneakyProgressBar->setHidden(true); - search->setHidden(false); - - if (focusSearch) - { - search->setFocus(); - focusSearch = false; - } preselect(); loadTask = nullptr; @@ -174,17 +174,6 @@ void VersionSelectWidget::preselect() selectRecommended(); } -void VersionSelectWidget::updateSearch(const QString &value) { - m_proxyModel->setSearch(value); - // if nothing is selected, pick the first result - if (!value.isEmpty()) { - listView->selectionModel()->setCurrentIndex( - listView->model()->index(0, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); - listView->scrollToTop(); - } else - listView->scrollTo(listView->selectionModel()->currentIndex(), QAbstractItemView::PositionAtCenter); -} - void VersionSelectWidget::selectCurrent() { if(m_currentVersion.isEmpty()) diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h index df9c8a628..8d2c900c8 100644 --- a/launcher/ui/widgets/VersionSelectWidget.h +++ b/launcher/ui/widgets/VersionSelectWidget.h @@ -89,7 +89,6 @@ private slots: private: void preselect(); - void updateSearch(const QString &value); private: QString m_currentVersion; From 3a068970f99c1437717651da951cee0762921308 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 6 Jun 2023 07:03:13 -0700 Subject: [PATCH 079/429] Packaging: file manifest in portable install (#1101) --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 691e257bf..a0a0943ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -375,6 +375,8 @@ jobs: shell: msys2 {0} run: | cmake --install ${{ env.BUILD_DIR }} + touch ${{ env.INSTALL_DIR }}/manifest.txt + for l in $(find ${{ env.INSTALL_DIR }} -type f); do l=$(cygpath -u $l); l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_DIR }}/}; l=${l#./}; echo $l; done >> ${{ env.INSTALL_DIR }}/manifest.txt - name: Package (Windows MSVC) if: runner.os == 'Windows' && matrix.msystem == '' @@ -387,6 +389,10 @@ jobs: Copy-Item D:/a/PrismLauncher/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll -Destination libcrypto-1_1.dll Copy-Item D:/a/PrismLauncher/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll -Destination libssl-1_1.dll } + cd ${{ github.workspace }} + + Get-ChildItem ${{ env.INSTALL_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt + - name: Fetch codesign certificate (Windows) if: runner.os == 'Windows' @@ -411,12 +417,15 @@ jobs: run: | cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }} # cmake install on Windows is slow, let's just copy instead cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable + for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=$(cygpath -u $l); l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done >> ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt - name: Package (Windows MSVC, portable) if: runner.os == 'Windows' && matrix.msystem == '' run: | cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }} # cmake install on Windows is slow, let's just copy instead cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable + + Get-ChildItem ${{ env.INSTALL_PORTABLE_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_PORTABLE_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt - name: Package (Windows, installer) if: runner.os == 'Windows' @@ -437,6 +446,7 @@ jobs: if: runner.os == 'Linux' run: | cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }} + for l in $(find ${{ env.INSTALL_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_DIR }}/manifest.txt cd ${{ env.INSTALL_DIR }} tar --owner root --group root -czf ../PrismLauncher.tar.gz * @@ -446,6 +456,8 @@ jobs: run: | cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable + for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt + cd ${{ env.INSTALL_PORTABLE_DIR }} tar -czf ../PrismLauncher-portable.tar.gz * From e8843417952ae0dc881a1ef8f352e4959f2c572b Mon Sep 17 00:00:00 2001 From: Tayou Date: Tue, 6 Jun 2023 18:15:26 +0200 Subject: [PATCH 080/429] save meta custom url as string, not QUrl Signed-off-by: Tayou --- launcher/ui/pages/global/APIPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index f662ee1c3..dca1b3a63 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -177,7 +177,7 @@ void APIPage::applySettings() metaURL.setScheme("https"); } - s->set("MetaURLOverride", metaURL); + s->set("MetaURLOverride", metaURL.toString()); QString flameKey = ui->flameKey->text(); s->set("FlameKeyOverride", flameKey); QString modrinthToken = ui->modrinthToken->text(); From d59a06344a73e028a6f026d9f32027c2b9f73b39 Mon Sep 17 00:00:00 2001 From: leo78913 Date: Sun, 14 May 2023 15:03:32 -0300 Subject: [PATCH 081/429] fix main toolbar accounts toolbutton name previously it was not using the selected account name when opening the launcher and i also added an action group to the menu items so it uses radio buttons instead of checkboxes :p Signed-off-by: leo78913 --- launcher/ui/MainWindow.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 72b7db641..fab1185dd 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -199,7 +199,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi helpMenuButton->setPopupMode(QToolButton::InstantPopup); auto accountMenuButton = dynamic_cast(ui->mainToolBar->widgetForAction(ui->actionAccountsButton)); - ui->actionAccountsButton->setMenu(ui->accountsMenu); accountMenuButton->setPopupMode(QToolButton::InstantPopup); } @@ -414,15 +413,6 @@ void MainWindow::keyReleaseEvent(QKeyEvent *event) void MainWindow::retranslateUi() { - auto accounts = APPLICATION->accounts(); - MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); - if(defaultAccount) { - auto profileLabel = profileInUseFilter(defaultAccount->profileName(), defaultAccount->isInUse()); - ui->actionAccountsButton->setText(profileLabel); - } - else { - ui->actionAccountsButton->setText(tr("Accounts")); - } if (m_selectedInstance) { m_statusLeft->setText(m_selectedInstance->getStatusbarDescription()); @@ -432,6 +422,12 @@ void MainWindow::retranslateUi() ui->retranslateUi(this); + MinecraftAccountPtr defaultAccount = APPLICATION->accounts()->defaultAccount(); + if(defaultAccount) { + auto profileLabel = profileInUseFilter(defaultAccount->profileName(), defaultAccount->isInUse()); + ui->actionAccountsButton->setText(profileLabel); + } + changeIconButton->setToolTip(ui->actionChangeInstIcon->toolTip()); renameButton->setToolTip(ui->actionRenameInstance->toolTip()); @@ -673,6 +669,15 @@ void MainWindow::repopulateAccountsMenu() { ui->accountsMenu->clear(); + // NOTE: this is done so the accounts button text is not set to the accounts menu title + QMenu *accountsButtonMenu = ui->actionAccountsButton->menu(); + if (accountsButtonMenu) { + accountsButtonMenu->clear(); + } else { + accountsButtonMenu = new QMenu(this); + ui->actionAccountsButton->setMenu(accountsButtonMenu); + } + auto accounts = APPLICATION->accounts(); MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); @@ -687,6 +692,8 @@ void MainWindow::repopulateAccountsMenu() } } + QActionGroup* accountsGroup = new QActionGroup(this); + if (accounts->count() <= 0) { ui->actionNoAccountsAdded->setEnabled(false); @@ -702,6 +709,7 @@ void MainWindow::repopulateAccountsMenu() QAction *action = new QAction(profileLabel, this); action->setData(i); action->setCheckable(true); + action->setActionGroup(accountsGroup); if (defaultAccount == account) { action->setChecked(true); @@ -730,6 +738,7 @@ void MainWindow::repopulateAccountsMenu() ui->actionNoDefaultAccount->setData(-1); ui->actionNoDefaultAccount->setChecked(!defaultAccount); + ui->actionNoDefaultAccount->setActionGroup(accountsGroup); ui->accountsMenu->addAction(ui->actionNoDefaultAccount); @@ -737,6 +746,8 @@ void MainWindow::repopulateAccountsMenu() ui->accountsMenu->addSeparator(); ui->accountsMenu->addAction(ui->actionManageAccounts); + + accountsButtonMenu->addActions(ui->accountsMenu->actions()); } void MainWindow::updatesAllowedChanged(bool allowed) From a2d0d5a71d37f39535154df1e6f740625817a9eb Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 6 Jun 2023 18:25:09 +0100 Subject: [PATCH 082/429] Allow arrow key movement, fix auto-focus Signed-off-by: TheKodeToad --- launcher/ui/widgets/VersionSelectWidget.cpp | 29 ++++++++++++++++++--- launcher/ui/widgets/VersionSelectWidget.h | 1 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp index 6aaffaaca..a956ddb3c 100644 --- a/launcher/ui/widgets/VersionSelectWidget.cpp +++ b/launcher/ui/widgets/VersionSelectWidget.cpp @@ -1,8 +1,11 @@ #include "VersionSelectWidget.h" +#include +#include +#include +#include #include #include -#include #include "VersionProxyModel.h" @@ -45,6 +48,7 @@ VersionSelectWidget::VersionSelectWidget(bool focusSearch, QWidget* parent) } else listView->scrollTo(listView->selectionModel()->currentIndex(), QAbstractItemView::PositionAtCenter); }); + search->installEventFilter(this); sneakyProgressBar = new QProgressBar(this); sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar")); @@ -88,6 +92,23 @@ void VersionSelectWidget::setResizeOn(int column) listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); } +bool VersionSelectWidget::eventFilter(QObject *watched, QEvent *event) { + if (watched == search && event->type() == QEvent::KeyPress) { + const QKeyEvent* keyEvent = (QKeyEvent*)event; + const bool up = keyEvent->key() == Qt::Key_Up; + const bool down = keyEvent->key() == Qt::Key_Down; + if (up || down) { + const QModelIndex index = listView->model()->index(listView->currentIndex().row() + (up ? -1 : 1), 0); + if (index.row() >= 0 && index.row() < listView->model()->rowCount()) { + listView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + return true; + } + } + } + + return QObject::eventFilter(watched, event); +} + void VersionSelectWidget::initialize(BaseVersionList *vlist) { m_vlist = vlist; @@ -95,6 +116,9 @@ void VersionSelectWidget::initialize(BaseVersionList *vlist) listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + if (focusSearch) + search->setFocus(); + if (!m_vlist->isLoaded()) { loadList(); @@ -105,8 +129,6 @@ void VersionSelectWidget::initialize(BaseVersionList *vlist) { listView->setEmptyMode(VersionListView::String); } - search->setFocus(); - focusSearch = false; preselect(); } } @@ -141,7 +163,6 @@ void VersionSelectWidget::onTaskSucceeded() listView->setEmptyMode(VersionListView::String); } sneakyProgressBar->setHidden(true); - preselect(); loadTask = nullptr; } diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h index 8d2c900c8..be4ba768d 100644 --- a/launcher/ui/widgets/VersionSelectWidget.h +++ b/launcher/ui/widgets/VersionSelectWidget.h @@ -74,6 +74,7 @@ public: void setEmptyErrorString(QString emptyErrorString); void setEmptyMode(VersionListView::EmptyMode mode); void setResizeOn(int column); + bool eventFilter(QObject* watched, QEvent* event) override; signals: void selectedVersionChanged(BaseVersion::Ptr version); From a807b231a75fdcb95408aa35a3143e2e5f5ca60f Mon Sep 17 00:00:00 2001 From: leo78913 Date: Tue, 6 Jun 2023 15:14:50 -0300 Subject: [PATCH 083/429] fix: fix crash when selecting resource/texture/shader packs Signed-off-by: leo78913 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 61c48e759..6d90480ff 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -253,6 +253,8 @@ QList ResourcePackDownloadDialog::getPages() if (APPLICATION->capabilities() & Application::SupportsFlame) pages.append(FlameResourcePackPage::create(this, *m_instance)); + m_selectedPage = dynamic_cast(pages[0]); + return pages; } @@ -278,6 +280,8 @@ QList TexturePackDownloadDialog::getPages() if (APPLICATION->capabilities() & Application::SupportsFlame) pages.append(FlameTexturePackPage::create(this, *m_instance)); + m_selectedPage = dynamic_cast(pages[0]); + return pages; } @@ -301,6 +305,8 @@ QList ShaderPackDownloadDialog::getPages() pages.append(ModrinthShaderPackPage::create(this, *m_instance)); + m_selectedPage = dynamic_cast(pages[0]); + return pages; } From a9302468e78c3e05ff6dd1e0bdcecea99e1a1e99 Mon Sep 17 00:00:00 2001 From: leo78913 Date: Tue, 6 Jun 2023 16:10:01 -0300 Subject: [PATCH 084/429] update resource and data pack pack_format_versions Signed-off-by: leo78913 --- launcher/minecraft/mod/DataPack.cpp | 4 +++- launcher/minecraft/mod/ResourcePack.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp index 5c58f6b27..ca75cd2aa 100644 --- a/launcher/minecraft/mod/DataPack.cpp +++ b/launcher/minecraft/mod/DataPack.cpp @@ -33,7 +33,9 @@ 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") } }, + { 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") } }, }; void DataPack::setPackFormat(int new_format_id) diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 876d5c3ee..759d2b566 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -18,7 +18,8 @@ static const QMap> s_pack_format_versions = { { 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") } }, + { 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") } } }; void ResourcePack::setPackFormat(int new_format_id) From 1e702ee40f211286f85fa5353704e358e7fe14a9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 7 Jun 2023 00:16:23 +0300 Subject: [PATCH 085/429] Added dynamic page extra info Signed-off-by: Trial97 --- launcher/ui/pages/BasePage.h | 24 +++++++++---------- .../pages/instance/ExternalResourcesPage.cpp | 19 ++++++++++++++- .../ui/pages/instance/ExternalResourcesPage.h | 1 + launcher/ui/widgets/PageContainer.cpp | 4 ++++ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/launcher/ui/pages/BasePage.h b/launcher/ui/pages/BasePage.h index ceb240401..5537c28f7 100644 --- a/launcher/ui/pages/BasePage.h +++ b/launcher/ui/pages/BasePage.h @@ -35,15 +35,16 @@ #pragma once -#include #include +#include +#include #include #include "BasePageContainer.h" -class BasePage -{ -public: +class BasePage { + public: + using updateExtraInfoFunc = std::function; virtual ~BasePage() {} virtual QString id() const = 0; virtual QString displayName() const = 0; @@ -63,17 +64,16 @@ public: } virtual void openedImpl() {} virtual void closedImpl() {} - virtual void setParentContainer(BasePageContainer * container) - { - m_container = container; - }; - virtual void retranslate() { } + virtual void setParentContainer(BasePageContainer* container) { m_container = container; }; + virtual void retranslate() {} -public: + public: int stackIndex = -1; int listIndex = -1; -protected: - BasePageContainer * m_container = nullptr; + updateExtraInfoFunc updateExtraInfo; + + protected: + BasePageContainer* m_container = nullptr; bool isOpened = false; }; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 1115ddc3b..e5567c804 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -9,6 +9,7 @@ #include #include +#include ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared_ptr model, QWidget* parent) : QMainWindow(parent), m_instance(instance), ui(new Ui::ExternalResourcesPage), m_model(model) @@ -43,6 +44,13 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared auto selection_model = ui->treeView->selectionModel(); connect(selection_model, &QItemSelectionModel::currentChanged, this, &ExternalResourcesPage::current); + auto updateExtra = [this]() { + if (updateExtraInfo) + updateExtraInfo(extraHeaderInfoString()); + }; + connect(selection_model, &QItemSelectionModel::selectionChanged, this, updateExtra); + connect(model.get(), &ResourceFolderModel::updateFinished, this, updateExtra); + connect(ui->filterEdit, &QLineEdit::textChanged, this, &ExternalResourcesPage::filterTextChanged); } @@ -248,6 +256,15 @@ bool ExternalResourcesPage::onSelectionChanged(const QModelIndex& current, const int row = sourceCurrent.row(); Resource const& resource = m_model->at(row); ui->frame->updateWithResource(resource); - return true; } + +QString ExternalResourcesPage::extraHeaderInfoString() +{ + if (ui && ui->treeView && ui->treeView->selectionModel()) { + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + if (auto count = std::count_if(selection.cbegin(), selection.cend(), [](auto v) { return v.column() == 0; }); count != 0) + return tr("[%1 installed, %2 selected]").arg(m_model->size()).arg(count); + } + return tr("[%1 installed]").arg(m_model->size()); +} diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index d17fbb7f1..fd2001938 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -29,6 +29,7 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { virtual QString helpPage() const override = 0; virtual bool shouldDisplay() const override = 0; + QString extraHeaderInfoString(); void openedImpl() override; void closedImpl() override; diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 38a228973..34df42ece 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -93,6 +93,10 @@ PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, page->listIndex = counter; page->setParentContainer(this); counter++; + page->updateExtraInfo = [this](QString info) { + if (m_currentPage) + m_header->setText(m_currentPage->displayName() + info); + }; } m_model->setPages(pages); From f724059b883d584b9f1d9ecd5fe21c7e4d214889 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 7 Jun 2023 01:23:53 +0300 Subject: [PATCH 086/429] Added visit mod's page Signed-off-by: Trial97 --- .../pages/instance/ExternalResourcesPage.ui | 11 +++++ launcher/ui/pages/instance/ModFolderPage.cpp | 48 ++++++++++++++----- launcher/ui/pages/instance/ModFolderPage.h | 1 + 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 33a033366..b110dbfd6 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -154,6 +154,17 @@ Try to check or update all selected resources (all resources if none are selected) + + + false + + + Visit on mod's page + + + Go to mods home page + + diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 4548af59a..d1787e7db 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include "Application.h" @@ -59,6 +60,7 @@ #include "minecraft/mod/Mod.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" #include "Version.h" @@ -85,22 +87,29 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); + ui->actionVisitItemPage->setToolTip(tr("Go to mods home page")); + ui->actionsToolbar->insertActionAfter(ui->actionViewFolder, ui->actionVisitItemPage); + connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); + auto check_allow_update = [this] { - return (!m_instance || !m_instance->isRunning()) && - (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); + return (!m_instance || !m_instance->isRunning()) && (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); }; connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); + + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + auto mods_list = m_model->selectedMods(selection); + auto enableView = std::any_of(mods_list.cbegin(), mods_list.cend(), + [](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; }); + ui->actionVisitItemPage->setEnabled(enableView); }); - connect(mods.get(), &ModFolderModel::rowsInserted, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - }); + connect(mods.get(), &ModFolderModel::rowsInserted, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - connect(mods.get(), &ModFolderModel::rowsRemoved, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - }); + connect(mods.get(), &ModFolderModel::rowsRemoved, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update, mods] { ui->actionUpdateItem->setEnabled(check_allow_update()); @@ -140,7 +149,7 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI return true; } -void ModFolderPage::removeItems(const QItemSelection &selection) +void ModFolderPage::removeItems(const QItemSelection& selection) { m_model->deleteMods(selection.indexes()); } @@ -214,8 +223,7 @@ void ModFolderPage::updateMods() message = tr("All selected mods are up-to-date! :)"); } } - CustomMessageBox::selectable(this, tr("Update checker"), message) - ->exec(); + CustomMessageBox::selectable(this, tr("Update checker"), message)->exec(); return; } @@ -282,3 +290,21 @@ bool NilModFolderPage::shouldDisplay() const { return m_model->dir().exists(); } + +void ModFolderPage::visitModPages() +{ + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + for (auto mod : m_model->selectedMods(selection)) + if (auto meta = mod->metadata(); meta != nullptr) { + auto slug = meta->slug.remove(".pw.toml"); + switch (meta->provider) { + case ModPlatform::ResourceProvider::MODRINTH: + DesktopServices::openUrl(QString("https://modrinth.com/mod/%1").arg(slug)); + break; + case ModPlatform::ResourceProvider::FLAME: + DesktopServices::openUrl(QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug)); + break; + } + } else if (mod->homeurl().size() != 0) + DesktopServices::openUrl(mod->homeurl()); +} \ No newline at end of file diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 2fc7b5748..d36a79951 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -64,6 +64,7 @@ class ModFolderPage : public ExternalResourcesPage { void installMods(); void updateMods(); + void visitModPages(); protected: std::shared_ptr m_model; From e936bc4c60b4262cd70ff1eb3291dc3ead4c53ac Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 7 Jun 2023 01:38:10 +0300 Subject: [PATCH 087/429] Added custom text for multiple selection Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index d1787e7db..1dbb9f473 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -87,7 +87,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); - ui->actionVisitItemPage->setToolTip(tr("Go to mods home page")); + ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); ui->actionsToolbar->insertActionAfter(ui->actionViewFolder, ui->actionVisitItemPage); connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); @@ -100,9 +100,16 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); auto mods_list = m_model->selectedMods(selection); - auto enableView = std::any_of(mods_list.cbegin(), mods_list.cend(), + auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(), [](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; }); - ui->actionVisitItemPage->setEnabled(enableView); + if (selected <= 1) { + ui->actionVisitItemPage->setText(tr("Visit on mod's page")); + ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); + } else { + ui->actionVisitItemPage->setText(tr("Visit the pages of the selected mods")); + ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); + } + ui->actionVisitItemPage->setEnabled(selected != 0); }); connect(mods.get(), &ModFolderModel::rowsInserted, this, From d12110b47bb1bb5109e41f2cf0f20908ceb8bc10 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 7 Jun 2023 06:21:01 -0700 Subject: [PATCH 088/429] fix #1118 : use `filePath` not `path` on `QFileInfo` Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/InstanceCopyTask.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index 60dcd5a1c..57a3143a1 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -149,7 +149,7 @@ void InstanceCopyTask::copyFinished() QByteArray allowed_symlinks; if (allowed_symlinks_file.exists()) { - allowed_symlinks.append(FS::read(allowed_symlinks_file.path())); + allowed_symlinks.append(FS::read(allowed_symlinks_file.filePath())); if (allowed_symlinks.right(1) != "\n") allowed_symlinks.append("\n"); // we want to be on a new line } @@ -157,9 +157,9 @@ void InstanceCopyTask::copyFinished() allowed_symlinks.append("\n"); if (allowed_symlinks_file.isSymLink()) FS::deletePath(allowed_symlinks_file - .path()); // we dont want to modify the original. also make sure the resulting file is not itself a link. + .filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link. - FS::write(allowed_symlinks_file.path(), allowed_symlinks); + FS::write(allowed_symlinks_file.filePath(), allowed_symlinks); } emitSucceeded(); From a90eaafa70e74ceaee22298b3c1ead8c1778e5ec Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 15:18:59 -0400 Subject: [PATCH 089/429] Make it clear that the statements are meant to fall through in Murmur hash Signed-off-by: PandaNinjas --- libraries/murmur2/src/MurmurHash2.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/murmur2/src/MurmurHash2.cpp b/libraries/murmur2/src/MurmurHash2.cpp index c13608f07..e73127953 100644 --- a/libraries/murmur2/src/MurmurHash2.cpp +++ b/libraries/murmur2/src/MurmurHash2.cpp @@ -89,8 +89,10 @@ void FourBytes_MurmurHash2(const unsigned char* data, IncrementalHashInfo& prev) switch (prev.len) { case 3: prev.h ^= data[2] << 16; + /* fall through */ case 2: prev.h ^= data[1] << 8; + /* fall through */ case 1: prev.h ^= data[0]; prev.h *= m; From 52054469cd351002143b30d5bb1d8160cdf4b085 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 7 Jun 2023 22:39:12 +0100 Subject: [PATCH 090/429] Fix *bug* lol Signed-off-by: TheKodeToad --- launcher/java/JavaInstallList.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index b29af8576..9277203a4 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -98,6 +98,8 @@ QVariant JavaInstallList::data(const QModelIndex &index, int role) const auto version = std::dynamic_pointer_cast(m_vlist[index.row()]); switch (role) { + case SortRole: + return -index.row(); case VersionPointerRole: return QVariant::fromValue(m_vlist[index.row()]); case VersionIdRole: @@ -117,7 +119,7 @@ QVariant JavaInstallList::data(const QModelIndex &index, int role) const BaseVersionList::RoleList JavaInstallList::providesRoles() const { - return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole}; + return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, LatestRole, PathRole, ArchitectureRole}; } From 1191c33c2b40d3fdb4ee66871f8cac4eb8aaf77d Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 7 Jun 2023 22:40:36 +0100 Subject: [PATCH 091/429] Remove flawed implementation This seems to add the latest icon (bug) as a fallback if not provided... but it mainly seems to cause problems... :shrug: I swear I did `git add .`. Signed-off-by: TheKodeToad --- launcher/VersionProxyModel.cpp | 8 -------- launcher/java/JavaInstallList.cpp | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 47cfa5ba3..e5c665662 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -212,10 +212,6 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return tr("Latest"); } } - else if(index.row() == 0) - { - return tr("Latest"); - } } } default: @@ -245,10 +241,6 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return APPLICATION->getThemedIcon("bug"); } } - else if(index.row() == 0) - { - return APPLICATION->getThemedIcon("bug"); - } QPixmap pixmap; QPixmapCache::find("placeholder", &pixmap); if(!pixmap) diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 9277203a4..04eb2e0f3 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -119,7 +119,7 @@ QVariant JavaInstallList::data(const QModelIndex &index, int role) const BaseVersionList::RoleList JavaInstallList::providesRoles() const { - return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, LatestRole, PathRole, ArchitectureRole}; + return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole}; } From d33de2e4277dfcd090a36c96e09148ea6a5d2e55 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Jun 2023 00:54:32 +0300 Subject: [PATCH 092/429] Made cat scalable Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 17 ++--------------- launcher/ui/instanceview/InstanceView.cpp | 23 ++++++++++++++++++++++- launcher/ui/instanceview/InstanceView.h | 8 ++++---- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 834f57dd9..4b77dd1c7 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -901,21 +901,8 @@ void MainWindow::onCatToggled(bool state) void MainWindow::setCatBackground(bool enabled) { - if (enabled) { - view->setStyleSheet(QString(R"( -InstanceView -{ - background-image: url(:/backgrounds/%1); - background-attachment: fixed; - background-clip: padding; - background-position: bottom right; - background-repeat: none; - background-color:palette(base); -})") - .arg(ThemeManager::getCatImage())); - } else { - view->setStyleSheet(QString()); - } + view->setCatVisible(enabled); + view->viewport()->repaint(); } void MainWindow::runModalTask(Task *task) diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index fbeffe350..4c83e94a0 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -48,6 +48,7 @@ #include #include "VisualGroup.h" +#include "ui/themes/ThemeManager.h" #include #include @@ -73,6 +74,7 @@ InstanceView::InstanceView(QWidget *parent) setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setAcceptDrops(true); setAutoScroll(true); + setCatVisible(APPLICATION->settings()->get("TheCat").toBool()); } InstanceView::~InstanceView() @@ -498,12 +500,31 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent *event) } } -void InstanceView::paintEvent(QPaintEvent *event) +void InstanceView::setCatVisible(bool visible) +{ + m_catVisible = visible; + m_catPixmap.load(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage())); +} + +void InstanceView::paintEvent(QPaintEvent* event) { executeDelayedItemsLayout(); QPainter painter(this->viewport()); + if (m_catVisible) { + int widWidth = this->viewport()->width(); + int widHeight = this->viewport()->height(); + if (m_catPixmap.width() < widWidth) + widWidth = m_catPixmap.width(); + if (m_catPixmap.height() < widHeight) + widHeight = m_catPixmap.height(); + auto pixmap = m_catPixmap.scaled(widWidth, widHeight, Qt::KeepAspectRatio); + QRect rectOfPixmap = pixmap.rect(); + rectOfPixmap.moveBottomRight(this->viewport()->rect().bottomRight()); + painter.drawPixmap(rectOfPixmap.topLeft(), pixmap); + } + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStyleOptionViewItem option; initViewItemOption(&option); diff --git a/launcher/ui/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index ac3382742..a9bd0bd7e 100644 --- a/launcher/ui/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h @@ -85,10 +85,8 @@ public: virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override; - int spacing() const - { - return m_spacing; - }; + int spacing() const { return m_spacing; }; + void setCatVisible(bool visible); public slots: virtual void updateGeometries() override; @@ -139,6 +137,8 @@ private: int m_currentItemsPerRow = -1; int m_currentCursorColumn= -1; mutable QCache geometryCache; + bool m_catVisible = false; + QPixmap m_catPixmap; // point where the currently active mouse action started in geometry coordinates QPoint m_pressedPosition; From 0b4807dc1fd723ac2f511a935649ae3a858aa388 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 7 Jun 2023 22:55:37 +0100 Subject: [PATCH 093/429] Questionable fix two Signed-off-by: TheKodeToad --- launcher/ui/widgets/VersionListView.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/launcher/ui/widgets/VersionListView.cpp b/launcher/ui/widgets/VersionListView.cpp index 0e126c65b..69f881552 100644 --- a/launcher/ui/widgets/VersionListView.cpp +++ b/launcher/ui/widgets/VersionListView.cpp @@ -125,14 +125,9 @@ void VersionListView::paintEvent(QPaintEvent *event) QString VersionListView::currentEmptyString() const { - if(m_itemCount) { - return QString(); - } switch(m_emptyMode) { default: - case VersionListView::Empty: - return QString(); case VersionListView::String: return m_emptyString; case VersionListView::ErrorString: From c225ecbb557b656184f35fdd3daa3a8aaa048f1f Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 18:00:14 -0400 Subject: [PATCH 094/429] Add sensible defaults in AccountList.cpp Signed-off-by: PandaNinjas --- launcher/minecraft/auth/AccountList.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 9e2fd1113..9069db6e0 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -328,6 +328,9 @@ QVariant AccountList::data(const QModelIndex &index, int role) const case AccountState::Gone: { return tr("Gone", "Account status"); } + case default: { + return tr("Unknown", "Account status"); + } } } From 5d425ecc025aa1fc4a5292961a5ff1b18a108885 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 18:12:46 -0400 Subject: [PATCH 095/429] Fix the AccountList code Signed-off-by: PandaNinjas --- launcher/minecraft/auth/AccountList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 9069db6e0..e454bcc49 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -328,7 +328,7 @@ QVariant AccountList::data(const QModelIndex &index, int role) const case AccountState::Gone: { return tr("Gone", "Account status"); } - case default: { + default: { return tr("Unknown", "Account status"); } } From 318d11481d719cf537ecdc00f8d676494bab22b6 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 19:37:54 -0400 Subject: [PATCH 096/429] Resolve other switch fallthrough issues --- launcher/LaunchController.cpp | 4 +- launcher/VersionProxyModel.cpp | 100 ++++++------------ launcher/meta/Index.cpp | 2 +- launcher/minecraft/auth/AccountList.cpp | 9 +- launcher/minecraft/auth/Yggdrasil.cpp | 1 + launcher/minecraft/mod/DataPack.cpp | 2 + launcher/minecraft/mod/Mod.cpp | 3 + launcher/minecraft/mod/Resource.cpp | 3 + launcher/minecraft/mod/ResourcePack.cpp | 2 + .../flame/FlameInstanceCreationTask.cpp | 3 +- launcher/translations/TranslationsModel.cpp | 1 + .../instanceview/AccessibleInstanceView.cpp | 2 +- launcher/ui/pages/instance/WorldListPage.cpp | 1 + launcher/ui/setupwizard/JavaWizardPage.cpp | 1 + 14 files changed, 60 insertions(+), 74 deletions(-) diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 070ee283c..5d84b3bf6 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -187,8 +187,8 @@ void LaunchController::login() { switch(m_accountToUse->accountState()) { case AccountState::Offline: { m_session->wants_online = false; - // NOTE: fallthrough is intentional } + /* fallthrough */ case AccountState::Online: { if(!m_session->wants_online) { // we ask the user for a player name @@ -267,8 +267,8 @@ void LaunchController::login() { // This means some sort of soft error that we can fix with a refresh ... so let's refresh. case AccountState::Unchecked: { m_accountToUse->refresh(); - // NOTE: fallthrough intentional } + /* fallthrough */ case AccountState::Working: { // refresh is in progress, we need to wait for it to finish to proceed. ProgressDialog progDialog(m_parentWidget); diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 6aba268d8..3c2948734 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -185,80 +185,50 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return QVariant(); } } - case Qt::ToolTipRole: - { - switch(column) - { - case Name: - { - if(hasRecommended) + case Qt::ToolTipRole: { + if (column == Name && hasRecommended) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if(value.toBool()) { + return tr("Recommended"); + } + else if(hasLatest) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(value.toBool()) { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { - return tr("Recommended"); - } - else if(hasLatest) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { - return tr("Latest"); - } - } - else if(index.row() == 0) - { - return tr("Latest"); - } + return tr("Latest"); } } - default: - { - return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); + else if(index.row() == 0) { + return tr("Latest"); } } + return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); } - case Qt::DecorationRole: - { - switch(column) - { - case Name: - { - if(hasRecommended) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { - return APPLICATION->getThemedIcon("star"); - } - else if(hasLatest) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { - return APPLICATION->getThemedIcon("bug"); - } - } - else if(index.row() == 0) - { - return APPLICATION->getThemedIcon("bug"); - } - QPixmap pixmap; - QPixmapCache::find("placeholder", &pixmap); - if(!pixmap) - { - QPixmap px(16,16); - px.fill(Qt::transparent); - QPixmapCache::insert("placeholder", px); - return px; - } - return pixmap; + case Qt::DecorationRole: { + if (column == Name && hasRecommended) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if(value.toBool()) { + return APPLICATION->getThemedIcon("star"); + } else if(hasLatest) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(value.toBool()) { + return APPLICATION->getThemedIcon("bug"); } } - default: - { - return QVariant(); + else if(index.row() == 0) { + return APPLICATION->getThemedIcon("bug"); } + QPixmap pixmap; + QPixmapCache::find("placeholder", &pixmap); + if(!pixmap) { + QPixmap px(16,16); + px.fill(Qt::transparent); + QPixmapCache::insert("placeholder", px); + return px; + } + return pixmap; + } else { + return QVariant(); } } default: diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp index 242aad9f9..2902f290b 100644 --- a/launcher/meta/Index.cpp +++ b/launcher/meta/Index.cpp @@ -48,8 +48,8 @@ QVariant Index::data(const QModelIndex &index, int role) const switch (index.column()) { case 0: return list->humanReadable(); - default: break; } + break; case UidRole: return list->uid(); case NameRole: return list->name(); case ListPtrRole: return QVariant::fromValue(list); diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index e454bcc49..184f8e100 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -357,11 +357,12 @@ QVariant AccountList::data(const QModelIndex &index, int role) const return QVariant::fromValue(account); case Qt::CheckStateRole: - switch (index.column()) - { - case ProfileNameColumn: - return account == m_defaultAccount ? Qt::Checked : Qt::Unchecked; + if (index.column() == ProfileNameColumn) { + return account == m_defaultAccount ? Qt::Checked : Qt::Unchecked; + } else { + return QVariant(); } + default: return QVariant(); diff --git a/launcher/minecraft/auth/Yggdrasil.cpp b/launcher/minecraft/auth/Yggdrasil.cpp index 299784119..d3e7ccddb 100644 --- a/launcher/minecraft/auth/Yggdrasil.cpp +++ b/launcher/minecraft/auth/Yggdrasil.cpp @@ -273,6 +273,7 @@ void Yggdrasil::processReply() { AccountTaskState::STATE_FAILED_GONE, tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account.") ); + return; } default: changeState( diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp index ca75cd2aa..c5754638a 100644 --- a/launcher/minecraft/mod/DataPack.cpp +++ b/launcher/minecraft/mod/DataPack.cpp @@ -74,6 +74,7 @@ std::pair DataPack::compare(const Resource& other, SortType type) con auto res = Resource::compare(other, type); if (res.first != 0) return res; + break; } case SortType::PACK_FORMAT: { auto this_ver = packFormat(); @@ -83,6 +84,7 @@ std::pair DataPack::compare(const Resource& other, SortType type) con return { 1, type == SortType::PACK_FORMAT }; if (this_ver < other_ver) return { -1, type == SortType::PACK_FORMAT }; + break; } } return { 0, false }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index c495cd47e..6cda6185c 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -89,6 +89,7 @@ std::pair Mod::compare(const Resource& other, SortType type) const auto res = Resource::compare(other, type); if (res.first != 0) return res; + break; } case SortType::VERSION: { auto this_ver = Version(version()); @@ -97,11 +98,13 @@ std::pair Mod::compare(const Resource& other, SortType type) const return { 1, type == SortType::VERSION }; if (this_ver < other_ver) return { -1, type == SortType::VERSION }; + break; } case SortType::PROVIDER: { auto compare_result = QString::compare(provider().value_or("Unknown"), cast_other->provider().value_or("Unknown"), Qt::CaseInsensitive); if (compare_result != 0) return { compare_result, type == SortType::PROVIDER }; + break; } } return { 0, false }; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index a0b8a4bbc..e50772601 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -71,6 +71,7 @@ std::pair Resource::compare(const Resource& other, SortType type) con return { 1, type == SortType::ENABLED }; if (!enabled() && other.enabled()) return { -1, type == SortType::ENABLED }; + break; case SortType::NAME: { QString this_name{ name() }; QString other_name{ other.name() }; @@ -81,12 +82,14 @@ std::pair Resource::compare(const Resource& other, SortType type) con auto compare_result = QString::compare(this_name, other_name, Qt::CaseInsensitive); if (compare_result != 0) return { compare_result, type == SortType::NAME }; + break; } case SortType::DATE: if (dateTimeChanged() > other.dateTimeChanged()) return { 1, type == SortType::DATE }; if (dateTimeChanged() < other.dateTimeChanged()) return { -1, type == SortType::DATE }; + break; } return { 0, false }; diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 759d2b566..32a789f55 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -95,6 +95,7 @@ std::pair ResourcePack::compare(const Resource& other, SortType type) auto res = Resource::compare(other, type); if (res.first != 0) return res; + break; } case SortType::PACK_FORMAT: { auto this_ver = packFormat(); @@ -104,6 +105,7 @@ std::pair ResourcePack::compare(const Resource& other, SortType type) return { 1, type == SortType::PACK_FORMAT }; if (this_ver < other_ver) return { -1, type == SortType::PACK_FORMAT }; + break; } } return { 0, false }; diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index dae93d1c6..11365a214 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -467,8 +467,9 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) switch (result.type) { case Flame::File::Type::Folder: { logWarning(tr("This 'Folder' may need extracting: %1").arg(relpath)); - // fall-through intentional, we treat these as plain old mods and dump them wherever. + // fallthrough intentional, we treat these as plain old mods and dump them wherever. } + /* fallthrough */ case Flame::File::Type::SingleFile: case Flame::File::Type::Mod: { if (!result.url.isEmpty()) { diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 23e55c51d..489dff86d 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -454,6 +454,7 @@ QVariant TranslationsModel::data(const QModelIndex& index, int role) const return QString("%1%").arg(lang.percentTranslated(), 3, 'f', 1); } } + qWarning("TranslationModel::data not implemented when role is DisplayRole"); } case Qt::ToolTipRole: { diff --git a/launcher/ui/instanceview/AccessibleInstanceView.cpp b/launcher/ui/instanceview/AccessibleInstanceView.cpp index 7de3ac726..2e7b83000 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView.cpp +++ b/launcher/ui/instanceview/AccessibleInstanceView.cpp @@ -248,8 +248,8 @@ bool AccessibleInstanceView::selectColumn(int column) if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) { return false; } - // fallthrough intentional } + /* fallthrough */ case QAbstractItemView::ContiguousSelection: { if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { view()->clearSelection(); diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index b6ad159e1..b5dc5a17c 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -338,6 +338,7 @@ void WorldListPage::mceditState(LoggedProcess::State state) case LoggedProcess::Aborted: { failed = true; + break; } case LoggedProcess::Running: case LoggedProcess::Finished: diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index 14683778a..e88335355 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -69,6 +69,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::AllOK: { settings->set("JavaPath", m_java_widget->javaPath()); + break; } case JavaSettingsWidget::ValidationStatus::JavaBad: { From 534328f16d0322c937a690f2f15eaa81489a54fe Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 19:45:23 -0400 Subject: [PATCH 097/429] Remove unnecessary switch statement Signed-off-by: PandaNinjas DCO Remediation Commit for PandaNinjas I, PandaNinjas , hereby add my Signed-off-by to this commit: 318d11481d719cf537ecdc00f8d676494bab22b6 Signed-off-by: PandaNinjas --- launcher/meta/Index.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp index 2902f290b..0c6ecccff 100644 --- a/launcher/meta/Index.cpp +++ b/launcher/meta/Index.cpp @@ -45,11 +45,11 @@ QVariant Index::data(const QModelIndex &index, int role) const switch (role) { case Qt::DisplayRole: - switch (index.column()) - { - case 0: return list->humanReadable(); + if (list.column() == 0) { + return list->humanReadable(); + } else { + break; } - break; case UidRole: return list->uid(); case NameRole: return list->name(); case ListPtrRole: return QVariant::fromValue(list); From 886b372adef86d84ca50d2e3e5b7ac39f1a5a42e Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 20:03:36 -0400 Subject: [PATCH 098/429] Fix accidentally renamed variable Signed-off-by: PandaNinjas --- launcher/meta/Index.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp index 0c6ecccff..4dccccca8 100644 --- a/launcher/meta/Index.cpp +++ b/launcher/meta/Index.cpp @@ -45,7 +45,7 @@ QVariant Index::data(const QModelIndex &index, int role) const switch (role) { case Qt::DisplayRole: - if (list.column() == 0) { + if (index.column() == 0) { return list->humanReadable(); } else { break; From 11cbeb8f96b9e6bc86290581128e28554123a427 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 22:13:57 -0400 Subject: [PATCH 099/429] Fix shadowing and add copyright header Signed-off-by: PandaNinjas --- launcher/VersionProxyModel.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 3c2948734..15ae1cc3c 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu - * * 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. @@ -187,13 +187,13 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const } case Qt::ToolTipRole: { if (column == Name && hasRecommended) { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) { + auto recommendedValue = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if(recommendedValue.toBool()) { return tr("Recommended"); } else if(hasLatest) { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) + auto latestValue = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(latestValue.toBool()) { return tr("Latest"); } @@ -206,12 +206,12 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const } case Qt::DecorationRole: { if (column == Name && hasRecommended) { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) { + auto recommendedValue = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if(recommendedValue.toBool()) { return APPLICATION->getThemedIcon("star"); } else if(hasLatest) { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) { + auto latestValue = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(latestValue.toBool()) { return APPLICATION->getThemedIcon("bug"); } } From e6872aba75231d409b19da5b876bb518b24976cc Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 22:15:44 -0400 Subject: [PATCH 100/429] Readd deleted line Signed-off-by: PandaNinjas --- launcher/VersionProxyModel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 15ae1cc3c..aca7ef002 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -3,6 +3,7 @@ * PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * * 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. From 5b3431b26884aaee695dba97ca5faaddd46a5081 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Thu, 8 Jun 2023 14:55:09 +0200 Subject: [PATCH 101/429] chore: revert macOS Qt version back to 6.5.0 Qt 6.5.1 seems to cause issues with Rectangle Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0a0943ad..3ce9fb403 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,7 +90,7 @@ jobs: qt_ver: 6 qt_host: mac qt_arch: '' - qt_version: '6.5.1' + qt_version: '6.5.0' qt_modules: 'qt5compat qtimageformats' qt_tools: '' From 95f6860005341ebf81a7bed60a4e267f3057d2a6 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Thu, 8 Jun 2023 10:12:27 -0400 Subject: [PATCH 102/429] Apply suggestions from code review Signed-off-by: PandaNinjas --- launcher/VersionProxyModel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index aca7ef002..0dbd1c951 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * From 75b1eaed0c71147398788d127df8240936ec72dc Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Thu, 8 Jun 2023 17:12:49 +0200 Subject: [PATCH 103/429] chore: bump macOS requirement to 11.0 Noticed only now that Qt 6.5 bumps the macOS requirement to macOS 11. This was basically already effective in prism since with the Qt 6.5 bump pr macOS 10.15 user's wouldn't be able to run this, but updating the requirement here makes it more clear for the end user trying to run prism on macOS 10.15 Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ce9fb403..a6a6eceaa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,7 +86,7 @@ jobs: - os: macos-12 name: macOS - macosx_deployment_target: 10.15 + macosx_deployment_target: 11.0 qt_ver: 6 qt_host: mac qt_arch: '' From f96b135ef72a762220941681cf1b314a3b2db266 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Jun 2023 20:26:09 +0300 Subject: [PATCH 104/429] Higlight installed mods Signed-off-by: Trial97 --- launcher/minecraft/MinecraftInstance.cpp | 40 ++++++++----------- launcher/minecraft/MinecraftInstance.h | 16 ++++---- launcher/minecraft/WorldList.cpp | 3 +- launcher/minecraft/WorldList.h | 4 +- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- launcher/minecraft/mod/ModFolderModel.h | 2 +- .../minecraft/mod/ResourceFolderModel.cpp | 2 +- launcher/minecraft/mod/ResourceFolderModel.h | 4 +- .../minecraft/mod/ResourcePackFolderModel.cpp | 2 +- .../minecraft/mod/ResourcePackFolderModel.h | 2 +- .../minecraft/mod/ShaderPackFolderModel.h | 4 +- .../minecraft/mod/TexturePackFolderModel.cpp | 3 +- .../minecraft/mod/TexturePackFolderModel.h | 4 +- launcher/ui/pages/modplatform/ModModel.cpp | 12 ++++++ launcher/ui/pages/modplatform/ModModel.h | 1 + .../ui/pages/modplatform/ResourceModel.cpp | 3 ++ launcher/ui/pages/modplatform/ResourceModel.h | 2 + .../ui/pages/modplatform/flame/FlameModel.cpp | 2 + .../modplatform/modrinth/ModrinthModel.cpp | 2 + launcher/ui/widgets/ProjectItem.cpp | 5 +++ launcher/ui/widgets/ProjectItem.h | 3 +- 21 files changed, 67 insertions(+), 51 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 2c624a365..76ff5723c 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1109,10 +1109,9 @@ JavaVersion MinecraftInstance::getJavaVersion() return JavaVersion(settings()->get("JavaVersion").toString()); } -std::shared_ptr MinecraftInstance::loaderModList() +std::shared_ptr MinecraftInstance::loaderModList() const { - if (!m_loader_mod_list) - { + if (!m_loader_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_loader_mod_list.reset(new ModFolderModel(modsRoot(), this, is_indexed)); m_loader_mod_list->disableInteraction(isRunning()); @@ -1121,10 +1120,9 @@ std::shared_ptr MinecraftInstance::loaderModList() return m_loader_mod_list; } -std::shared_ptr MinecraftInstance::coreModList() +std::shared_ptr MinecraftInstance::coreModList() const { - if (!m_core_mod_list) - { + if (!m_core_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_core_mod_list.reset(new ModFolderModel(coreModsDir(), this, is_indexed)); m_core_mod_list->disableInteraction(isRunning()); @@ -1133,10 +1131,9 @@ std::shared_ptr MinecraftInstance::coreModList() return m_core_mod_list; } -std::shared_ptr MinecraftInstance::nilModList() +std::shared_ptr MinecraftInstance::nilModList() const { - if (!m_nil_mod_list) - { + if (!m_nil_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_nil_mod_list.reset(new ModFolderModel(nilModsDir(), this, is_indexed, false)); m_nil_mod_list->disableInteraction(isRunning()); @@ -1145,46 +1142,41 @@ std::shared_ptr MinecraftInstance::nilModList() return m_nil_mod_list; } -std::shared_ptr MinecraftInstance::resourcePackList() +std::shared_ptr MinecraftInstance::resourcePackList() const { - if (!m_resource_pack_list) - { + if (!m_resource_pack_list) { m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir(), this)); } return m_resource_pack_list; } -std::shared_ptr MinecraftInstance::texturePackList() +std::shared_ptr MinecraftInstance::texturePackList() const { - if (!m_texture_pack_list) - { + if (!m_texture_pack_list) { m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir(), this)); } return m_texture_pack_list; } -std::shared_ptr MinecraftInstance::shaderPackList() +std::shared_ptr MinecraftInstance::shaderPackList() const { - if (!m_shader_pack_list) - { + if (!m_shader_pack_list) { m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir(), this)); } return m_shader_pack_list; } -std::shared_ptr MinecraftInstance::worldList() +std::shared_ptr MinecraftInstance::worldList() const { - if (!m_world_list) - { + if (!m_world_list) { m_world_list.reset(new WorldList(worldDir(), this)); } return m_world_list; } -std::shared_ptr MinecraftInstance::gameOptionsModel() +std::shared_ptr MinecraftInstance::gameOptionsModel() const { - if (!m_game_options) - { + if (!m_game_options) { m_game_options.reset(new GameOptions(FS::PathCombine(gameRoot(), "options.txt"))); } return m_game_options; diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 068b30082..a75fa4813 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -115,14 +115,14 @@ public: std::shared_ptr getPackProfile() const; ////// Mod Lists ////// - std::shared_ptr loaderModList(); - std::shared_ptr coreModList(); - std::shared_ptr nilModList(); - std::shared_ptr resourcePackList(); - std::shared_ptr texturePackList(); - std::shared_ptr shaderPackList(); - std::shared_ptr worldList(); - std::shared_ptr gameOptionsModel(); + std::shared_ptr loaderModList() const; + std::shared_ptr coreModList() const; + std::shared_ptr nilModList() const; + std::shared_ptr resourcePackList() const; + std::shared_ptr texturePackList() const; + std::shared_ptr shaderPackList() const; + std::shared_ptr worldList() const; + std::shared_ptr gameOptionsModel() const; ////// Launch stuff ////// Task::Ptr createUpdateTask(Net::Mode mode) override; diff --git a/launcher/minecraft/WorldList.cpp b/launcher/minecraft/WorldList.cpp index 0feee2999..42772df5a 100644 --- a/launcher/minecraft/WorldList.cpp +++ b/launcher/minecraft/WorldList.cpp @@ -45,8 +45,7 @@ #include #include -WorldList::WorldList(const QString &dir, BaseInstance* instance) - : QAbstractListModel(), m_instance(instance), m_dir(dir) +WorldList::WorldList(const QString& dir, const BaseInstance* instance) : QAbstractListModel(), m_instance(instance), m_dir(dir) { FS::ensureFolderPathExists(m_dir.absolutePath()); m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); diff --git a/launcher/minecraft/WorldList.h b/launcher/minecraft/WorldList.h index 96b64193f..92d02b9be 100644 --- a/launcher/minecraft/WorldList.h +++ b/launcher/minecraft/WorldList.h @@ -50,7 +50,7 @@ public: IconFileRole }; - WorldList(const QString &dir, BaseInstance* instance); + WorldList(const QString& dir, const BaseInstance* instance); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -128,7 +128,7 @@ signals: void changed(); protected: - BaseInstance* m_instance; + const BaseInstance* m_instance; QFileSystemWatcher *m_watcher; bool is_watching; QDir m_dir; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 5e3b31e08..eccfe4aea 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -54,7 +54,7 @@ #include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "modplatform/ModIndex.h" -ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir) +ModFolderModel::ModFolderModel(const QString& dir, const BaseInstance* instance, bool is_indexed, bool create_dir) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) { m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index d337fe296..261a007a5 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -75,7 +75,7 @@ public: Enable, Toggle }; - ModFolderModel(const QString &dir, BaseInstance* instance, bool is_indexed = false, bool create_dir = true); + ModFolderModel(const QString& dir, const BaseInstance* instance, bool is_indexed = false, bool create_dir = true); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index d2d875e48..5664ea859 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -16,7 +16,7 @@ #include "tasks/Task.h" -ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObject* parent, bool create_dir) +ResourceFolderModel::ResourceFolderModel(QDir dir, const BaseInstance* instance, QObject* parent, bool create_dir) : QAbstractListModel(parent), m_dir(dir), m_instance(instance), m_watcher(this) { if (create_dir) { diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 0a35e1bca..d853b4434 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -26,7 +26,7 @@ class QSortFilterProxyModel; class ResourceFolderModel : public QAbstractListModel { Q_OBJECT public: - ResourceFolderModel(QDir, BaseInstance* instance, QObject* parent = nullptr, bool create_dir = true); + ResourceFolderModel(QDir, const BaseInstance* instance, QObject* parent = nullptr, bool create_dir = true); ~ResourceFolderModel() override; /** Starts watching the paths for changes. @@ -191,7 +191,7 @@ class ResourceFolderModel : public QAbstractListModel { bool m_can_interact = true; QDir m_dir; - BaseInstance* m_instance; + const BaseInstance* m_instance; QFileSystemWatcher m_watcher; bool m_is_watching = false; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index c12d1f237..8036292ba 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -45,7 +45,7 @@ #include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalResourcePackParseTask.h" -ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstance* instance) +ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, const BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) { m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE }; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h index db4b14fb0..9d96253a2 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.h +++ b/launcher/minecraft/mod/ResourcePackFolderModel.h @@ -17,7 +17,7 @@ public: NUM_COLUMNS }; - explicit ResourcePackFolderModel(const QString &dir, BaseInstance* instance); + explicit ResourcePackFolderModel(const QString& dir, const BaseInstance* instance); [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/ShaderPackFolderModel.h b/launcher/minecraft/mod/ShaderPackFolderModel.h index dc5acf80f..c05bec1d3 100644 --- a/launcher/minecraft/mod/ShaderPackFolderModel.h +++ b/launcher/minecraft/mod/ShaderPackFolderModel.h @@ -6,7 +6,5 @@ class ShaderPackFolderModel : public ResourceFolderModel { Q_OBJECT public: - explicit ShaderPackFolderModel(const QString& dir, BaseInstance* instance) - : ResourceFolderModel(QDir(dir), instance) - {} + explicit ShaderPackFolderModel(const QString& dir, const BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) {} }; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index c6609ed1e..dadf8f77d 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -39,8 +39,7 @@ #include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalTexturePackParseTask.h" -TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* instance) - : ResourceFolderModel(QDir(dir), instance) +TexturePackFolderModel::TexturePackFolderModel(const QString& dir, const BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) {} Task* TexturePackFolderModel::createUpdateTask() diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index 425a71e46..a1492f8b4 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -42,8 +42,8 @@ class TexturePackFolderModel : public ResourceFolderModel { Q_OBJECT -public: - explicit TexturePackFolderModel(const QString &dir, BaseInstance* instance); + public: + explicit TexturePackFolderModel(const QString& dir, const BaseInstance* instance); [[nodiscard]] Task* createUpdateTask() override; [[nodiscard]] Task* createParseTask(Resource&) override; }; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index afd8b2921..1579bbf4c 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -6,8 +6,10 @@ #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "minecraft/mod/ModFolderModel.h" #include +#include namespace ResourceDownload { @@ -67,4 +69,14 @@ void ModModel::searchWithTerm(const QString& term, unsigned int sort, bool filte refresh(); } +bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const +{ + auto allMods = static_cast(m_base_instance).loaderModList()->allMods(); + return std::any_of(allMods.cbegin(), allMods.cend(), [pack](Mod* mod) { + if (auto meta = mod->metadata(); meta) + return meta->provider == pack->provider && meta->project_id == pack->addonId; + return false; + }); +} + } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 5d4a77859..938ce32ea 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -42,6 +42,7 @@ class ModModel : public ResourceModel { protected: auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0; + virtual bool isPackInstalled(ModPlatform::IndexedPack::Ptr) const override; protected: const BaseInstance& m_base_instance; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index a5ea1ca9f..49405a02b 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -77,6 +77,8 @@ auto ResourceModel::data(const QModelIndex& index, int role) const -> QVariant return pack->description; case UserDataTypes::SELECTED: return pack->isAnyVersionSelected(); + case UserDataTypes::INSTALLED: + return this->isPackInstalled(pack); default: break; } @@ -95,6 +97,7 @@ QHash ResourceModel::roleNames() const roles[UserDataTypes::TITLE] = "title"; roles[UserDataTypes::DESCRIPTION] = "description"; roles[UserDataTypes::SELECTED] = "selected"; + roles[UserDataTypes::INSTALLED] = "installed"; return roles; } diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 69e234730..6533d9c6a 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -116,6 +116,8 @@ class ResourceModel : public QAbstractListModel { virtual void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&); virtual void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&); + virtual bool isPackInstalled(ModPlatform::IndexedPack::Ptr) const { return false; } + protected: /* Basic search parameters */ enum class SearchState { None, CanFetchMore, ResetRequested, Finished } m_search_state = SearchState::None; diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 5961ea026..d9d5ef5b3 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -60,6 +60,8 @@ QVariant ListModel::data(const QModelIndex& index, int role) const return pack.description; case UserDataTypes::SELECTED: return false; + case UserDataTypes::INSTALLED: + return false; default: break; } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 346a00b0e..55d287b09 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -106,6 +106,8 @@ auto ModpackListModel::data(const QModelIndex& index, int role) const -> QVarian return pack.description; case UserDataTypes::SELECTED: return false; + case UserDataTypes::INSTALLED: + return false; default: break; } diff --git a/launcher/ui/widgets/ProjectItem.cpp b/launcher/ui/widgets/ProjectItem.cpp index d1ff9dbc0..e8349c106 100644 --- a/launcher/ui/widgets/ProjectItem.cpp +++ b/launcher/ui/widgets/ProjectItem.cpp @@ -64,6 +64,11 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o font.setBold(true); font.setUnderline(true); } + if (index.data(UserDataTypes::INSTALLED).toBool()) { + // Set nice font + font.setItalic(true); + font.setOverline(true); + } font.setPointSize(font.pointSize() + 2); painter->setFont(font); diff --git a/launcher/ui/widgets/ProjectItem.h b/launcher/ui/widgets/ProjectItem.h index f668edf66..196055ea4 100644 --- a/launcher/ui/widgets/ProjectItem.h +++ b/launcher/ui/widgets/ProjectItem.h @@ -6,7 +6,8 @@ enum UserDataTypes { TITLE = 257, // QString DESCRIPTION = 258, // QString - SELECTED = 259 // bool + SELECTED = 259, // bool + INSTALLED = 260 // bool }; /** This is an item delegate composed of: From 93436b09401b7f425cffaac49e03756526d04cb3 Mon Sep 17 00:00:00 2001 From: guihkx <626206+guihkx@users.noreply.github.com> Date: Fri, 9 Jun 2023 00:48:05 -0300 Subject: [PATCH 105/429] ci: exclude .git directory from the source code tarball Reduces the its final size from 17.1 MiB down to 7.9 MiB. Signed-off-by: guihkx <626206+guihkx@users.noreply.github.com> --- .github/workflows/trigger_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index 3c56a38ea..f19b83986 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -47,7 +47,7 @@ jobs: mv PrismLauncher-macOS-Legacy*/PrismLauncher.tar.gz PrismLauncher-macOS-Legacy-${{ env.VERSION }}.tar.gz mv PrismLauncher-macOS*/PrismLauncher.tar.gz PrismLauncher-macOS-${{ env.VERSION }}.tar.gz - tar -czf PrismLauncher-${{ env.VERSION }}.tar.gz PrismLauncher-${{ env.VERSION }} + tar --exclude='.git' -czf PrismLauncher-${{ env.VERSION }}.tar.gz PrismLauncher-${{ env.VERSION }} for d in PrismLauncher-Windows-MSVC*; do cd "${d}" || continue From f2932c6d0387c41bd876d4af4148a7ffb5c83154 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 9 Jun 2023 21:23:41 +0300 Subject: [PATCH 106/429] Fixed some crashes Signed-off-by: Trial97 --- launcher/net/ByteArraySink.h | 15 ++++++++++++--- launcher/tasks/ConcurrentTask.cpp | 3 +-- launcher/ui/pages/modplatform/ResourcePage.cpp | 9 ++++++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/launcher/net/ByteArraySink.h b/launcher/net/ByteArraySink.h index 501318a11..0d77727ee 100644 --- a/launcher/net/ByteArraySink.h +++ b/launcher/net/ByteArraySink.h @@ -53,7 +53,10 @@ class ByteArraySink : public Sink { public: auto init(QNetworkRequest& request) -> Task::State override { - m_output->clear(); + if (m_output) + m_output->clear(); + else + qWarning() << "ByteArraySink was not cleared because it's not adresable"; if (initAllValidators(request)) return Task::State::Running; return Task::State::Failed; @@ -61,7 +64,10 @@ class ByteArraySink : public Sink { auto write(QByteArray& data) -> Task::State override { - m_output->append(data); + if (m_output) + m_output->append(data); + else + qWarning() << "ByteArraySink no write because it's not adresable"; if (writeAllValidators(data)) return Task::State::Running; return Task::State::Failed; @@ -69,7 +75,10 @@ class ByteArraySink : public Sink { auto abort() -> Task::State override { - m_output->clear(); + if (m_output) + m_output->clear(); + else + qWarning() << "ByteArraySink no clear because it's not adresable"; failAllValidators(); return Task::State::Failed; } diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp index 5ee145055..9aada5e69 100644 --- a/launcher/tasks/ConcurrentTask.cpp +++ b/launcher/tasks/ConcurrentTask.cpp @@ -138,19 +138,18 @@ void ConcurrentTask::startNext() connect(next.get(), &Task::progress, this, [this, next](qint64 current, qint64 total) { subTaskProgress(next, current, total); }); m_doing.insert(next.get(), next); + qsizetype num_starts = qMin(m_queue.size(), m_total_max_size - m_doing.size()); auto task_progress = std::make_shared(next->getUid()); m_task_progress.insert(next->getUid(), task_progress); updateState(); updateStepProgress(*task_progress.get(), Operation::ADDED); - QCoreApplication::processEvents(); QMetaObject::invokeMethod(next.get(), &Task::start, Qt::QueuedConnection); // Allow going up the number of concurrent tasks in case of tasks being added in the middle of a running task. - int num_starts = qMin(m_queue.size(), m_total_max_size - m_doing.size()); for (int i = 0; i < num_starts; i++) QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); } diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 736034add..2bb867775 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -240,10 +240,13 @@ void ResourcePage::updateSelectionButton() } m_ui->resourceSelectionButton->setEnabled(true); - if (!getCurrentPack()->isVersionSelected(m_selected_version_index)) { - m_ui->resourceSelectionButton->setText(tr("Select %1 for download").arg(resourceString())); + if (getCurrentPack()) { + if (!getCurrentPack()->isVersionSelected(m_selected_version_index)) + m_ui->resourceSelectionButton->setText(tr("Select %1 for download").arg(resourceString())); + else + m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString())); } else { - m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString())); + qWarning() << "Try to update selection but there is not a pack selected"; } } From b3d743635c86aac583fb802c1e3c7aa25e12dc88 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 9 Jun 2023 21:29:12 +0300 Subject: [PATCH 107/429] Updated the messages Signed-off-by: Trial97 --- launcher/net/ByteArraySink.h | 6 +++--- launcher/ui/pages/modplatform/ResourcePage.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/net/ByteArraySink.h b/launcher/net/ByteArraySink.h index 0d77727ee..728193b30 100644 --- a/launcher/net/ByteArraySink.h +++ b/launcher/net/ByteArraySink.h @@ -56,7 +56,7 @@ class ByteArraySink : public Sink { if (m_output) m_output->clear(); else - qWarning() << "ByteArraySink was not cleared because it's not adresable"; + qWarning() << "ByteArraySink did not initialize the buffer because it's not addressable"; if (initAllValidators(request)) return Task::State::Running; return Task::State::Failed; @@ -67,7 +67,7 @@ class ByteArraySink : public Sink { if (m_output) m_output->append(data); else - qWarning() << "ByteArraySink no write because it's not adresable"; + qWarning() << "ByteArraySink did not write the buffer because it's not addressable"; if (writeAllValidators(data)) return Task::State::Running; return Task::State::Failed; @@ -78,7 +78,7 @@ class ByteArraySink : public Sink { if (m_output) m_output->clear(); else - qWarning() << "ByteArraySink no clear because it's not adresable"; + qWarning() << "ByteArraySink did not clear the buffer because it's not addressable"; failAllValidators(); return Task::State::Failed; } diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 2bb867775..1d2509d80 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -246,7 +246,7 @@ void ResourcePage::updateSelectionButton() else m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString())); } else { - qWarning() << "Try to update selection but there is not a pack selected"; + qWarning() << "Tried to update the selected button but there is not a pack selected"; } } From b7d82354cbf4d13c428555c5625db183dffd15d7 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 10 Jun 2023 14:42:27 +0100 Subject: [PATCH 108/429] [ci skip] License headers!! (yay) Signed-off-by: TheKodeToad --- launcher/java/JavaInstallList.cpp | 3 ++- launcher/ui/widgets/VersionListView.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 04eb2e0f3..3407fdf72 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * 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/VersionListView.cpp b/launcher/ui/widgets/VersionListView.cpp index 69f881552..06e58d221 100644 --- a/launcher/ui/widgets/VersionListView.cpp +++ b/launcher/ui/widgets/VersionListView.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * 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 From ae9e8dbafd457ef5be2b02529647c8b974488f7a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 10 Jun 2023 22:04:08 +0300 Subject: [PATCH 109/429] Removed const specification Signed-off-by: Trial97 --- launcher/minecraft/MinecraftInstance.cpp | 40 +++++++++++-------- launcher/minecraft/MinecraftInstance.h | 16 ++++---- launcher/minecraft/WorldList.cpp | 3 +- launcher/minecraft/WorldList.h | 4 +- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- launcher/minecraft/mod/ModFolderModel.h | 2 +- .../minecraft/mod/ResourceFolderModel.cpp | 2 +- launcher/minecraft/mod/ResourceFolderModel.h | 4 +- .../minecraft/mod/ResourcePackFolderModel.cpp | 2 +- .../minecraft/mod/ResourcePackFolderModel.h | 2 +- .../minecraft/mod/ShaderPackFolderModel.h | 4 +- .../minecraft/mod/TexturePackFolderModel.cpp | 3 +- .../minecraft/mod/TexturePackFolderModel.h | 4 +- launcher/ui/pages/modplatform/ModModel.cpp | 6 +-- launcher/ui/pages/modplatform/ModModel.h | 4 +- .../modplatform/flame/FlameResourceModels.cpp | 2 +- .../modplatform/flame/FlameResourceModels.h | 2 +- .../modrinth/ModrinthResourceModels.cpp | 2 +- .../modrinth/ModrinthResourceModels.h | 2 +- 19 files changed, 59 insertions(+), 47 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 76ff5723c..2c624a365 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1109,9 +1109,10 @@ JavaVersion MinecraftInstance::getJavaVersion() return JavaVersion(settings()->get("JavaVersion").toString()); } -std::shared_ptr MinecraftInstance::loaderModList() const +std::shared_ptr MinecraftInstance::loaderModList() { - if (!m_loader_mod_list) { + if (!m_loader_mod_list) + { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_loader_mod_list.reset(new ModFolderModel(modsRoot(), this, is_indexed)); m_loader_mod_list->disableInteraction(isRunning()); @@ -1120,9 +1121,10 @@ std::shared_ptr MinecraftInstance::loaderModList() const return m_loader_mod_list; } -std::shared_ptr MinecraftInstance::coreModList() const +std::shared_ptr MinecraftInstance::coreModList() { - if (!m_core_mod_list) { + if (!m_core_mod_list) + { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_core_mod_list.reset(new ModFolderModel(coreModsDir(), this, is_indexed)); m_core_mod_list->disableInteraction(isRunning()); @@ -1131,9 +1133,10 @@ std::shared_ptr MinecraftInstance::coreModList() const return m_core_mod_list; } -std::shared_ptr MinecraftInstance::nilModList() const +std::shared_ptr MinecraftInstance::nilModList() { - if (!m_nil_mod_list) { + if (!m_nil_mod_list) + { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_nil_mod_list.reset(new ModFolderModel(nilModsDir(), this, is_indexed, false)); m_nil_mod_list->disableInteraction(isRunning()); @@ -1142,41 +1145,46 @@ std::shared_ptr MinecraftInstance::nilModList() const return m_nil_mod_list; } -std::shared_ptr MinecraftInstance::resourcePackList() const +std::shared_ptr MinecraftInstance::resourcePackList() { - if (!m_resource_pack_list) { + if (!m_resource_pack_list) + { m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir(), this)); } return m_resource_pack_list; } -std::shared_ptr MinecraftInstance::texturePackList() const +std::shared_ptr MinecraftInstance::texturePackList() { - if (!m_texture_pack_list) { + if (!m_texture_pack_list) + { m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir(), this)); } return m_texture_pack_list; } -std::shared_ptr MinecraftInstance::shaderPackList() const +std::shared_ptr MinecraftInstance::shaderPackList() { - if (!m_shader_pack_list) { + if (!m_shader_pack_list) + { m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir(), this)); } return m_shader_pack_list; } -std::shared_ptr MinecraftInstance::worldList() const +std::shared_ptr MinecraftInstance::worldList() { - if (!m_world_list) { + if (!m_world_list) + { m_world_list.reset(new WorldList(worldDir(), this)); } return m_world_list; } -std::shared_ptr MinecraftInstance::gameOptionsModel() const +std::shared_ptr MinecraftInstance::gameOptionsModel() { - if (!m_game_options) { + if (!m_game_options) + { m_game_options.reset(new GameOptions(FS::PathCombine(gameRoot(), "options.txt"))); } return m_game_options; diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index a75fa4813..068b30082 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -115,14 +115,14 @@ public: std::shared_ptr getPackProfile() const; ////// Mod Lists ////// - std::shared_ptr loaderModList() const; - std::shared_ptr coreModList() const; - std::shared_ptr nilModList() const; - std::shared_ptr resourcePackList() const; - std::shared_ptr texturePackList() const; - std::shared_ptr shaderPackList() const; - std::shared_ptr worldList() const; - std::shared_ptr gameOptionsModel() const; + std::shared_ptr loaderModList(); + std::shared_ptr coreModList(); + std::shared_ptr nilModList(); + std::shared_ptr resourcePackList(); + std::shared_ptr texturePackList(); + std::shared_ptr shaderPackList(); + std::shared_ptr worldList(); + std::shared_ptr gameOptionsModel(); ////// Launch stuff ////// Task::Ptr createUpdateTask(Net::Mode mode) override; diff --git a/launcher/minecraft/WorldList.cpp b/launcher/minecraft/WorldList.cpp index 42772df5a..0feee2999 100644 --- a/launcher/minecraft/WorldList.cpp +++ b/launcher/minecraft/WorldList.cpp @@ -45,7 +45,8 @@ #include #include -WorldList::WorldList(const QString& dir, const BaseInstance* instance) : QAbstractListModel(), m_instance(instance), m_dir(dir) +WorldList::WorldList(const QString &dir, BaseInstance* instance) + : QAbstractListModel(), m_instance(instance), m_dir(dir) { FS::ensureFolderPathExists(m_dir.absolutePath()); m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); diff --git a/launcher/minecraft/WorldList.h b/launcher/minecraft/WorldList.h index 92d02b9be..96b64193f 100644 --- a/launcher/minecraft/WorldList.h +++ b/launcher/minecraft/WorldList.h @@ -50,7 +50,7 @@ public: IconFileRole }; - WorldList(const QString& dir, const BaseInstance* instance); + WorldList(const QString &dir, BaseInstance* instance); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -128,7 +128,7 @@ signals: void changed(); protected: - const BaseInstance* m_instance; + BaseInstance* m_instance; QFileSystemWatcher *m_watcher; bool is_watching; QDir m_dir; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index eccfe4aea..5e3b31e08 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -54,7 +54,7 @@ #include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "modplatform/ModIndex.h" -ModFolderModel::ModFolderModel(const QString& dir, const BaseInstance* instance, bool is_indexed, bool create_dir) +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_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 261a007a5..d337fe296 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -75,7 +75,7 @@ public: Enable, Toggle }; - ModFolderModel(const QString& dir, const BaseInstance* instance, bool is_indexed = false, bool create_dir = true); + ModFolderModel(const QString &dir, BaseInstance* instance, bool is_indexed = false, bool create_dir = true); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 5664ea859..d2d875e48 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -16,7 +16,7 @@ #include "tasks/Task.h" -ResourceFolderModel::ResourceFolderModel(QDir dir, const BaseInstance* instance, QObject* parent, bool create_dir) +ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObject* parent, bool create_dir) : QAbstractListModel(parent), m_dir(dir), m_instance(instance), m_watcher(this) { if (create_dir) { diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index d853b4434..0a35e1bca 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -26,7 +26,7 @@ class QSortFilterProxyModel; class ResourceFolderModel : public QAbstractListModel { Q_OBJECT public: - ResourceFolderModel(QDir, const BaseInstance* instance, QObject* parent = nullptr, bool create_dir = true); + ResourceFolderModel(QDir, BaseInstance* instance, QObject* parent = nullptr, bool create_dir = true); ~ResourceFolderModel() override; /** Starts watching the paths for changes. @@ -191,7 +191,7 @@ class ResourceFolderModel : public QAbstractListModel { bool m_can_interact = true; QDir m_dir; - const BaseInstance* m_instance; + BaseInstance* m_instance; QFileSystemWatcher m_watcher; bool m_is_watching = false; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 8036292ba..c12d1f237 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -45,7 +45,7 @@ #include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalResourcePackParseTask.h" -ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, const BaseInstance* instance) +ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) { m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE }; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h index 9d96253a2..db4b14fb0 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.h +++ b/launcher/minecraft/mod/ResourcePackFolderModel.h @@ -17,7 +17,7 @@ public: NUM_COLUMNS }; - explicit ResourcePackFolderModel(const QString& dir, const BaseInstance* instance); + explicit ResourcePackFolderModel(const QString &dir, BaseInstance* instance); [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/ShaderPackFolderModel.h b/launcher/minecraft/mod/ShaderPackFolderModel.h index c05bec1d3..dc5acf80f 100644 --- a/launcher/minecraft/mod/ShaderPackFolderModel.h +++ b/launcher/minecraft/mod/ShaderPackFolderModel.h @@ -6,5 +6,7 @@ class ShaderPackFolderModel : public ResourceFolderModel { Q_OBJECT public: - explicit ShaderPackFolderModel(const QString& dir, const BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) {} + explicit ShaderPackFolderModel(const QString& dir, BaseInstance* instance) + : ResourceFolderModel(QDir(dir), instance) + {} }; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index dadf8f77d..c6609ed1e 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -39,7 +39,8 @@ #include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalTexturePackParseTask.h" -TexturePackFolderModel::TexturePackFolderModel(const QString& dir, const BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) +TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* instance) + : ResourceFolderModel(QDir(dir), instance) {} Task* TexturePackFolderModel::createUpdateTask() diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index a1492f8b4..425a71e46 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -42,8 +42,8 @@ class TexturePackFolderModel : public ResourceFolderModel { Q_OBJECT - public: - explicit TexturePackFolderModel(const QString& dir, const BaseInstance* instance); +public: + explicit TexturePackFolderModel(const QString &dir, BaseInstance* instance); [[nodiscard]] Task* createUpdateTask() override; [[nodiscard]] Task* createParseTask(Resource&) override; }; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 1579bbf4c..b75378905 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -13,7 +13,7 @@ namespace ResourceDownload { -ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(api), m_base_instance(base_inst) {} +ModModel::ModModel(BaseInstance& base_inst, ResourceAPI* api) : ResourceModel(api), m_base_instance(base_inst) {} /******** Make data requests ********/ @@ -26,7 +26,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() std::optional> versions{}; - { // Version filter + { // Version filter if (!m_filter->versions.empty()) versions = m_filter->versions; } @@ -71,7 +71,7 @@ void ModModel::searchWithTerm(const QString& term, unsigned int sort, bool filte bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const { - auto allMods = static_cast(m_base_instance).loaderModList()->allMods(); + auto allMods = static_cast(m_base_instance).loaderModList()->allMods(); return std::any_of(allMods.cbegin(), allMods.cend(), [pack](Mod* mod) { if (auto meta = mod->metadata(); meta) return meta->provider == pack->provider && meta->project_id == pack->addonId; diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 938ce32ea..805d8b9ad 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -24,7 +24,7 @@ class ModModel : public ResourceModel { Q_OBJECT public: - ModModel(const BaseInstance&, ResourceAPI* api); + ModModel(BaseInstance&, ResourceAPI* api); /* Ask the API for more information */ void searchWithTerm(const QString& term, unsigned int sort, bool filter_changed); @@ -45,7 +45,7 @@ class ModModel : public ResourceModel { virtual bool isPackInstalled(ModPlatform::IndexedPack::Ptr) const override; protected: - const BaseInstance& m_base_instance; + BaseInstance& m_base_instance; std::shared_ptr m_filter = nullptr; }; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp index e3d0bc144..667a52d06 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp @@ -11,7 +11,7 @@ namespace ResourceDownload { -FlameModModel::FlameModModel(BaseInstance const& base) : ModModel(base, new FlameAPI) {} +FlameModModel::FlameModModel(BaseInstance& base) : ModModel(base, new FlameAPI) {} void FlameModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) { diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h index 0252ac403..221c8f7a8 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h @@ -14,7 +14,7 @@ class FlameModModel : public ModModel { Q_OBJECT public: - FlameModModel(const BaseInstance&); + FlameModModel(BaseInstance&); ~FlameModModel() override = default; private: diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp index f5d1cc282..7f8574852 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp @@ -25,7 +25,7 @@ namespace ResourceDownload { -ModrinthModModel::ModrinthModModel(BaseInstance const& base) : ModModel(base, new ModrinthAPI) {} +ModrinthModModel::ModrinthModModel(BaseInstance& base) : ModModel(base, new ModrinthAPI) {} void ModrinthModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) { diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h index b351b19b9..66461807a 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h @@ -30,7 +30,7 @@ class ModrinthModModel : public ModModel { Q_OBJECT public: - ModrinthModModel(const BaseInstance&); + ModrinthModModel(BaseInstance&); ~ModrinthModModel() override = default; private: From 5aa1c340dc6c353e34d0fbcac84fb89798a06481 Mon Sep 17 00:00:00 2001 From: Tayou Date: Sun, 11 Jun 2023 01:58:37 +0200 Subject: [PATCH 110/429] rainbow konami & toggle Signed-off-by: Tayou --- launcher/ui/MainWindow.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 834f57dd9..dfee3b471 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -470,7 +470,23 @@ void MainWindow::lockToolbars(bool state) void MainWindow::konamiTriggered() { - qDebug() << "Super Secret Mode ACTIVATED!"; + QString gradient = " stop:0 rgba(125, 0, 0, 255), stop:0.166 rgba(125, 125, 0, 255), stop:0.333 rgba(0, 125, 0, 255), stop:0.5 rgba(0, 125, 125, 255), stop:0.666 rgba(0, 0, 125, 255), stop:0.833 rgba(125, 0, 125, 255), stop:1 rgba(125, 0, 0, 255));"; + QString stylesheet = "background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0," + gradient; + if (ui->mainToolBar->styleSheet() == stylesheet) { + ui->mainToolBar->setStyleSheet(""); + ui->instanceToolBar->setStyleSheet(""); + ui->centralWidget->setStyleSheet(""); + ui->newsToolBar->setStyleSheet(""); + ui->statusBar->setStyleSheet(""); + qDebug() << "Super Secret Mode DEACTIVATED!"; + } else { + ui->mainToolBar->setStyleSheet(stylesheet); + ui->instanceToolBar->setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1," + gradient); + ui->centralWidget->setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1," + gradient); + ui->newsToolBar->setStyleSheet(stylesheet); + ui->statusBar->setStyleSheet(stylesheet); + qDebug() << "Super Secret Mode ACTIVATED!"; + } } void MainWindow::showInstanceContextMenu(const QPoint &pos) From ad0493390b051c27ee8d16b323a9c71b9d697097 Mon Sep 17 00:00:00 2001 From: seth Date: Sun, 11 Jun 2023 14:02:36 -0400 Subject: [PATCH 111/429] fix(nix): use prismlauncher-unwrapped in devShell Signed-off-by: seth --- nix/dev.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/dev.nix b/nix/dev.nix index a4ff2cc49..635c6bb41 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -37,7 +37,7 @@ nil ]; - inputsFrom = [self.packages.${system}.default]; + inputsFrom = [self.packages.${system}.prismlauncher-unwrapped]; buildInputs = with pkgs; [ccache ninja]; }; From d6c7b4e813a254a2fb78547a7947aa913d80dbbb Mon Sep 17 00:00:00 2001 From: leo78913 Date: Sun, 11 Jun 2023 21:49:33 -0300 Subject: [PATCH 112/429] add icons to export menu Signed-off-by: leo78913 --- launcher/ui/MainWindow.cpp | 9 ++++++--- launcher/ui/MainWindow.ui | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 834f57dd9..bb7844d38 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -187,7 +187,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi } - // set the menu for the folders help, and accounts tool buttons + // set the menu for the folders help, accounts, and export tool buttons { auto foldersMenuButton = dynamic_cast(ui->mainToolBar->widgetForAction(ui->actionFoldersButton)); ui->actionFoldersButton->setMenu(ui->foldersMenu); @@ -201,6 +201,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto accountMenuButton = dynamic_cast(ui->mainToolBar->widgetForAction(ui->actionAccountsButton)); accountMenuButton->setPopupMode(QToolButton::InstantPopup); + + auto exportInstanceMenu = new QMenu(this); + exportInstanceMenu->addAction(ui->actionExportInstanceZip); + exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); + ui->actionExportInstance->setMenu(exportInstanceMenu); } // hide, disable and show stuff @@ -397,8 +402,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // removing this looks stupid view->setFocus(); - ui->actionExportInstance->setMenu(ui->exportInstanceMenu); - retranslateUi(); } diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 4a89bc100..9e639ab05 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -150,10 +150,6 @@ - - - - @@ -467,11 +463,17 @@ + + + Prism Launcher (zip) + + + Modrinth (mrpack) From 94ddc8bbf7a65f08079c4cf42deb4eea86b1e53b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 12 Jun 2023 14:14:50 +0100 Subject: [PATCH 113/429] Could this work? Signed-off-by: TheKodeToad --- launcher/modplatform/modrinth/ModrinthPackExportTask.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 29df90ddf..eff47b37c 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -27,7 +27,7 @@ #include "minecraft/PackProfile.h" #include "minecraft/mod/ModFolderModel.h" -const QStringList ModrinthPackExportTask::PREFIXES({ "mods", "coremods", "resourcepacks", "texturepacks", "shaderpacks" }); +const QStringList ModrinthPackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); const QStringList ModrinthPackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "zip" }); ModrinthPackExportTask::ModrinthPackExportTask(const QString& name, @@ -99,14 +99,12 @@ void ModrinthPackExportTask::collectHashes() const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); // require sensible file types - if (!std::any_of(PREFIXES.begin(), PREFIXES.end(), - [&relative](const QString& prefix) { return relative.startsWith(prefix + QDir::separator()); })) + if (!std::any_of(PREFIXES.begin(), PREFIXES.end(), [&relative](const QString& prefix) { return relative.startsWith(prefix); })) continue; if (!std::any_of(FILE_EXTENSIONS.begin(), FILE_EXTENSIONS.end(), [&relative](const QString& extension) { return relative.endsWith('.' + extension) || relative.endsWith('.' + extension + ".disabled"); - })) { + })) continue; - } QCryptographicHash sha512(QCryptographicHash::Algorithm::Sha512); From f4a814b5e639641bad40bcea6abaf34f9c253046 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 12 Jun 2023 15:46:15 +0100 Subject: [PATCH 114/429] Remove unnecessary code Signed-off-by: TheKodeToad --- launcher/modplatform/modrinth/ModrinthPackExportTask.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index eff47b37c..bff9bf42e 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -301,9 +301,7 @@ QByteArray ModrinthPackExportTask::generateIndex() const ResolvedFile& value = iterator.value(); QJsonObject file; - QString path = iterator.key(); - path.replace(QDir::separator(), "/"); - file["path"] = path; + file["path"] = iterator.key(); file["downloads"] = QJsonArray({ iterator.value().url }); QJsonObject hashes; From b77fb059083ba04a3ccbc1b6e9ce4f5353b200ad Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 13 Jun 2023 21:07:05 +0300 Subject: [PATCH 115/429] Added back the INIFile read function Signed-off-by: Trial97 --- launcher/settings/INIFile.cpp | 85 +++++++++++++++++++++++++++++++---- tests/INIFile_test.cpp | 56 +++++++++++++++-------- 2 files changed, 115 insertions(+), 26 deletions(-) diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index f0347cabf..cb909ae75 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -45,12 +45,12 @@ #include -INIFile::INIFile() -{ -} +INIFile::INIFile() {} bool INIFile::saveFile(QString fileName) { + if (!contains("ConfigVersion")) + insert("ConfigVersion", "1.1"); QSettings _settings_obj{ fileName, QSettings::Format::IniFormat }; _settings_obj.setFallbacksEnabled(false); @@ -71,6 +71,67 @@ bool INIFile::saveFile(QString fileName) return true; } +QString unescape(QString orig) +{ + QString out; + QChar prev = QChar::Null; + for (auto c : orig) { + if (prev == '\\') { + if (c == 'n') + out += '\n'; + else if (c == 't') + out += '\t'; + else if (c == '#') + out += '#'; + else + out += c; + prev = QChar::Null; + } else { + if (c == '\\') { + prev = c; + continue; + } + out += c; + prev = QChar::Null; + } + } + return out; +} +bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) +{ + QTextStream in(device.readAll()); +#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) + in.setCodec("UTF-8"); +#endif + + QStringList lines = in.readAll().split('\n'); + for (int i = 0; i < lines.count(); i++) { + QString& lineRaw = lines[i]; + // Ignore comments. + int commentIndex = 0; + QString line = lineRaw; + // Search for comments until no more escaped # are available + while ((commentIndex = line.indexOf('#', commentIndex + 1)) != -1) { + if (commentIndex > 0 && line.at(commentIndex - 1) == '\\') { + continue; + } + line = line.left(lineRaw.indexOf('#')).trimmed(); + } + + int eqPos = line.indexOf('='); + if (eqPos == -1) + continue; + QString key = line.left(eqPos).trimmed(); + QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); + + valueStr = unescape(valueStr); + + QVariant value(valueStr); + map.insert(key, value); + } + + return true; +} bool INIFile::loadFile(QString fileName) { @@ -84,10 +145,19 @@ bool INIFile::loadFile(QString fileName) qCritical() << "A format error occurred (e.g. loading a malformed INI file)."; return false; } - - for (auto&& key : _settings_obj.allKeys()) - insert(key, _settings_obj.value(key)); - + if (!_settings_obj.value("ConfigVersion").isValid()) { + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return false; + QSettings::SettingsMap map; + parseOldFileFormat(file, map); + file.close(); + for (auto&& key : map.keys()) + insert(key, map.value(key)); + insert("ConfigVersion", "1.1"); + } else + for (auto&& key : _settings_obj.allKeys()) + insert(key, _settings_obj.value(key)); return true; } @@ -103,4 +173,3 @@ void INIFile::set(QString key, QVariant val) { this->operator[](key) = val; } - diff --git a/tests/INIFile_test.cpp b/tests/INIFile_test.cpp index 4be8133c0..2f49e573d 100644 --- a/tests/INIFile_test.cpp +++ b/tests/INIFile_test.cpp @@ -1,24 +1,16 @@ #include +#include #include #include -#include #include -class IniFileTest : public QObject -{ +class IniFileTest : public QObject { Q_OBJECT -private -slots: - void initTestCase() - { - - } - void cleanupTestCase() - { - - } + private slots: + void initTestCase() {} + void cleanupTestCase() {} void test_Escape_data() { @@ -47,17 +39,17 @@ slots: // load INIFile f2; f2.loadFile(filename); - QCOMPARE(f2.get("a","NOT SET").toString(), a); - QCOMPARE(f2.get("b","NOT SET").toString(), b); + QCOMPARE(f2.get("a", "NOT SET").toString(), a); + QCOMPARE(f2.get("b", "NOT SET").toString(), b); } void test_SaveLoadLists() { QString slist_strings = "(\"a\",\"b\",\"c\")"; - QStringList list_strings = {"a", "b", "c"}; + QStringList list_strings = { "a", "b", "c" }; QString slist_numbers = "(1,2,3,10)"; - QList list_numbers = {1, 2, 3, 10}; + QList list_numbers = { 1, 2, 3, 10 }; QString filename = "test_SaveLoadLists.ini"; @@ -72,13 +64,41 @@ slots: QStringList out_list_strings = f2.get("list_strings", QStringList()).toStringList(); qDebug() << "OutStringList" << out_list_strings; - + QList out_list_numbers = QVariantUtils::toList(f2.get("list_numbers", QVariantUtils::fromList(QList()))); qDebug() << "OutNumbersList" << out_list_numbers; QCOMPARE(out_list_strings, list_strings); QCOMPARE(out_list_numbers, list_numbers); } + + void test_SaveAleardyExistingFile() + { + QString fileName = "test_SaveAleardyExistingFile.ini"; + QString fileContent = R"(InstanceType=OneSix +iconKey=vanillia_icon +name=Minecraft Vanillia +OverrideCommands=true +PreLaunchCommand="$INST_JAVA" -jar packwiz-installer-bootstrap.jar link +)"; + QFile file(fileName); + + if (file.open(QFile::WriteOnly | QFile::Text)) { + QTextStream stream(&file); + stream << fileContent; + file.close(); + } + + // load + INIFile f1; + f1.loadFile(fileName); + QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); + f1.saveFile(fileName); + INIFile f2; + f2.loadFile(fileName); + QCOMPARE(f2.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); + QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.1"); + } }; QTEST_GUILESS_MAIN(IniFileTest) From d4f2059b78bd53fccb20657d11b3386e427ec795 Mon Sep 17 00:00:00 2001 From: clickdevin Date: Wed, 14 Jun 2023 10:42:37 -0400 Subject: [PATCH 116/429] Fix bugs when updating curseforge modpacks Signed-off-by: clickdevin --- launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index dae93d1c6..35443e71c 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -153,6 +153,9 @@ bool FlameCreationTask::updateInstance() old_files.remove(file.key()); files_iterator = files.erase(files_iterator); + + if (files_iterator != files.begin()) + files_iterator--; } } From e8b0a7c6f02772dbe3fc1a205595f5fa30003ec3 Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 14 Jun 2023 12:45:08 -0400 Subject: [PATCH 117/429] chore: bump to 8.0 Signed-off-by: seth --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bd12630d..70a553190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,7 @@ set(Launcher_NEWS_OPEN_URL "https://prismlauncher.org/news" CACHE STRING "URL th set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help") ######## Set version numbers ######## -set(Launcher_VERSION_MAJOR 7) +set(Launcher_VERSION_MAJOR 8) set(Launcher_VERSION_MINOR 0) set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}") From e0b901169aaa5ebc7b74c15cd3f01f08ee98c4f1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 00:27:20 +0300 Subject: [PATCH 118/429] Added new migration for special characters Signed-off-by: Trial97 --- launcher/settings/INIFile.cpp | 19 ++++++++-- tests/INIFile_test.cpp | 67 +++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index cb909ae75..1d2f9611f 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -50,7 +50,7 @@ INIFile::INIFile() {} bool INIFile::saveFile(QString fileName) { if (!contains("ConfigVersion")) - insert("ConfigVersion", "1.1"); + insert("ConfigVersion", "1.2"); QSettings _settings_obj{ fileName, QSettings::Format::IniFormat }; _settings_obj.setFallbacksEnabled(false); @@ -125,6 +125,10 @@ bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); valueStr = unescape(valueStr); + if ((valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) && valueStr.endsWith("\"") && + valueStr.startsWith("\"")) { + valueStr = valueStr.removeFirst().removeLast(); + } QVariant value(valueStr); map.insert(key, value); @@ -154,7 +158,18 @@ bool INIFile::loadFile(QString fileName) file.close(); for (auto&& key : map.keys()) insert(key, map.value(key)); - insert("ConfigVersion", "1.1"); + insert("ConfigVersion", "1.2"); + } else if (_settings_obj.value("ConfigVersion").toString() == "1.1") { + for (auto&& key : _settings_obj.allKeys()) { + if (auto valueStr = _settings_obj.value(key).toString(); + (valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) && + valueStr.endsWith("\"") && valueStr.startsWith("\"")) { + valueStr = valueStr.removeFirst().removeLast(); + insert(key, valueStr); + } else + insert(key, _settings_obj.value(key)); + } + insert("ConfigVersion", "1.2"); } else for (auto&& key : _settings_obj.allKeys()) insert(key, _settings_obj.value(key)); diff --git a/tests/INIFile_test.cpp b/tests/INIFile_test.cpp index 2f49e573d..5d9c9cd8a 100644 --- a/tests/INIFile_test.cpp +++ b/tests/INIFile_test.cpp @@ -2,7 +2,9 @@ #include #include +#include #include +#include "FileSystem.h" #include @@ -80,7 +82,10 @@ iconKey=vanillia_icon name=Minecraft Vanillia OverrideCommands=true PreLaunchCommand="$INST_JAVA" -jar packwiz-installer-bootstrap.jar link -)"; +Wrapperommand=)"; + fileContent += "\""; + fileContent += +R"(\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link =)"; + fileContent += "\"\n"; QFile file(fileName); if (file.open(QFile::WriteOnly | QFile::Text)) { @@ -93,11 +98,69 @@ PreLaunchCommand="$INST_JAVA" -jar packwiz-installer-bootstrap.jar link INIFile f1; f1.loadFile(fileName); QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); + QCOMPARE(f1.get("Wrapperommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link ="); f1.saveFile(fileName); INIFile f2; f2.loadFile(fileName); QCOMPARE(f2.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); - QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.1"); + QCOMPARE(f2.get("Wrapperommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link ="); + QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.2"); + } + + void test_SaveAleardyExistingFileWithSpecialChars() + { + QString fileName = "test_SaveAleardyExistingFileWithSpecialChars.ini"; + FS::deletePath(fileName); // just to clean the previous test run + QSettings settings{ fileName, QSettings::Format::IniFormat }; + settings.setFallbacksEnabled(false); + + settings.setValue("simple", "value1"); + settings.setValue("withQuotes", R"("value2" with quotes)"); + settings.setValue("withSpecialCharacters", "env mesa=true"); + settings.setValue("withSpecialCharacters2", "1,2,3,4"); + settings.setValue("withSpecialCharacters2", "1;2;3;4"); + settings.setValue("withAll", "val=\"$INST_JAVA\" -jar; ls "); + + settings.sync(); + + QCOMPARE(settings.status(), QSettings::Status::NoError); + + // load + INIFile f1; + f1.loadFile(fileName); + for (auto key : settings.allKeys()) + QCOMPARE(f1.get(key, "NOT SET").toString(), settings.value(key).toString()); + f1.saveFile(fileName); + INIFile f2; + f2.loadFile(fileName); + for (auto key : settings.allKeys()) + QCOMPARE(f2.get(key, "NOT SET").toString(), settings.value(key).toString()); + QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.2"); + } + + void test_SaveAleardyExistingFileWithSpecialCharsV1() + { + QString fileName = "test_SaveAleardyExistingFileWithSpecialCharsV1.ini"; + QString fileContent = R"(InstanceType=OneSix +ConfigVersion=1.1 +iconKey=vanillia_icon +name=Minecraft Vanillia +OverrideCommands=true +PreLaunchCommand=)"; + fileContent += "\"\\\"env mesa=true\\\"\"\n"; + QFile file(fileName); + + if (file.open(QFile::WriteOnly | QFile::Text)) { + QTextStream stream(&file); + stream << fileContent; + file.close(); + } + + // load + INIFile f1; + f1.loadFile(fileName); + QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "env mesa=true"); + QCOMPARE(f1.get("ConfigVersion", "NOT SET").toString(), "1.2"); } }; From cf4c1605ebe2f1db302928f847398e23236aed16 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 00:37:32 +0300 Subject: [PATCH 119/429] Fixed qt5 build Signed-off-by: Trial97 --- launcher/settings/INIFile.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index 1d2f9611f..37846d112 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -97,6 +97,20 @@ QString unescape(QString orig) } return out; } + +QString unquete(QString str) +{ + if ((str.contains(QChar(';')) || str.contains(QChar('=')) || str.contains(QChar(','))) && str.endsWith("\"") && str.startsWith("\"")) { +#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) + str = str.remove(0, 1); + str = str.remove(str.size() - 1, 1); +#else + str = str.removeFirst().removeLast(); +#endif + } + return str; +} + bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) { QTextStream in(device.readAll()); @@ -124,11 +138,7 @@ bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) QString key = line.left(eqPos).trimmed(); QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); - valueStr = unescape(valueStr); - if ((valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) && valueStr.endsWith("\"") && - valueStr.startsWith("\"")) { - valueStr = valueStr.removeFirst().removeLast(); - } + valueStr = unquete(unescape(valueStr)); QVariant value(valueStr); map.insert(key, value); @@ -164,8 +174,7 @@ bool INIFile::loadFile(QString fileName) if (auto valueStr = _settings_obj.value(key).toString(); (valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) && valueStr.endsWith("\"") && valueStr.startsWith("\"")) { - valueStr = valueStr.removeFirst().removeLast(); - insert(key, valueStr); + insert(key, unquete(valueStr)); } else insert(key, _settings_obj.value(key)); } From 811c79423fa048c5f4dd567b1121630d16aa3b0c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 00:43:05 +0300 Subject: [PATCH 120/429] Fixed version comparation Signed-off-by: Trial97 --- launcher/settings/INIFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index 37846d112..ad600ab91 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -101,7 +101,7 @@ QString unescape(QString orig) QString unquete(QString str) { if ((str.contains(QChar(';')) || str.contains(QChar('=')) || str.contains(QChar(','))) && str.endsWith("\"") && str.startsWith("\"")) { -#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) +#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) str = str.remove(0, 1); str = str.remove(str.size() - 1, 1); #else From be0df38453977c37ae8b6b241e82ace41149fdcc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 11:40:39 +0300 Subject: [PATCH 121/429] Added tooltip for name label Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 1 + launcher/ui/pages/instance/ModFolderPage.h | 3 +- launcher/ui/widgets/InfoFrame.cpp | 111 +++++++++++-------- launcher/ui/widgets/InfoFrame.h | 45 +++++--- 4 files changed, 97 insertions(+), 63 deletions(-) diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 1dbb9f473..650bf5bdb 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -4,6 +4,7 @@ * Copyright (c) 2022 Jamie Mansfield * 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/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index d36a79951..2c1a9c772 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -4,6 +4,7 @@ * Copyright (c) 2022 Jamie Mansfield * 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 @@ -60,7 +61,7 @@ class ModFolderPage : public ExternalResourcesPage { private slots: void runningStateChanged(bool running); - void removeItems(const QItemSelection &selection) override; + void removeItems(const QItemSelection& selection) override; void installMods(); void updateMods(); diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index fdc581b41..d0b55c0bb 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -1,37 +1,38 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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. -*/ + * 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 + * 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 @@ -57,34 +58,47 @@ InfoFrame::~InfoFrame() void InfoFrame::updateWithMod(Mod const& m) { - if (m.type() == ResourceType::FOLDER) - { + if (m.type() == ResourceType::FOLDER) { clear(); return; } QString text = ""; QString name = ""; + QString link = ""; + QString toolTip = ""; if (m.name().isEmpty()) name = m.internal_id(); else name = m.name(); - if (m.homeurl().isEmpty()) + if (auto meta = m.metadata(); meta != nullptr) { + auto slug = meta->slug.remove(".pw.toml"); + switch (meta->provider) { + case ModPlatform::ResourceProvider::MODRINTH: + link = QString("https://modrinth.com/mod/%1").arg(slug); + break; + case ModPlatform::ResourceProvider::FLAME: + link = QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug); + break; + } + } else if (!m.homeurl().isEmpty()) + link = m.homeurl(); + + if (link.isEmpty()) text = name; - else - text = "" + name + ""; + else { + text = "" + name + ""; + toolTip = tr("Go to mod's home page"); + } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); - setName(text); + setName(text, toolTip); - if (m.description().isEmpty()) - { + if (m.description().isEmpty()) { setDescription(QString()); - } - else - { + } else { setDescription(m.description()); } @@ -191,16 +205,15 @@ void InfoFrame::updateHiddenState() } } -void InfoFrame::setName(QString text) +void InfoFrame::setName(QString text, QString toolTip) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->nameLabel->setHidden(true); - } - else - { + ui->nameLabel->setToolTip({}); + } else { ui->nameLabel->setText(text); ui->nameLabel->setHidden(false); + ui->nameLabel->setToolTip(toolTip); } updateHiddenState(); } diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h index 84523e281..4f6adc6d6 100644 --- a/launcher/ui/widgets/InfoFrame.h +++ b/launcher/ui/widgets/InfoFrame.h @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * 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 @@ -21,8 +41,7 @@ #include "minecraft/mod/ResourcePack.h" #include "minecraft/mod/TexturePack.h" -namespace Ui -{ +namespace Ui { class InfoFrame; } @@ -33,7 +52,7 @@ class InfoFrame : public QFrame { InfoFrame(QWidget* parent = nullptr); ~InfoFrame() override; - void setName(QString text = {}); + void setName(QString text = {}, QString toolTip = {}); void setDescription(QString text = {}); void setImage(QPixmap img = {}); From 6667ff9330cc080ca3c5fc2dd90af6b8420bf3fc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 12:32:48 +0300 Subject: [PATCH 122/429] Updated text and fixed mod page text update Signed-off-by: Trial97 --- .../pages/instance/ExternalResourcesPage.cpp | 39 ++++++++++++++++++- launcher/ui/pages/instance/ModFolderPage.cpp | 27 +++++-------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index e5567c804..e50fa6353 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.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 "ExternalResourcesPage.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui_ExternalResourcesPage.h" @@ -264,7 +299,7 @@ QString ExternalResourcesPage::extraHeaderInfoString() if (ui && ui->treeView && ui->treeView->selectionModel()) { auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); if (auto count = std::count_if(selection.cbegin(), selection.cend(), [](auto v) { return v.column() == 0; }); count != 0) - return tr("[%1 installed, %2 selected]").arg(m_model->size()).arg(count); + return tr(" (%1 installed, %2 selected)").arg(m_model->size()).arg(count); } - return tr("[%1 installed]").arg(m_model->size()); + return tr(" (%1 installed)").arg(m_model->size()); } diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 4548af59a..1d090ef4d 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -4,6 +4,7 @@ * Copyright (c) 2022 Jamie Mansfield * 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 @@ -86,28 +87,20 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); auto check_allow_update = [this] { - return (!m_instance || !m_instance->isRunning()) && - (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); + return (!m_instance || !m_instance->isRunning()) && (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); }; - connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - }); + connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - connect(mods.get(), &ModFolderModel::rowsInserted, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - }); + connect(mods.get(), &ModFolderModel::rowsInserted, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - connect(mods.get(), &ModFolderModel::rowsRemoved, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - }); + connect(mods.get(), &ModFolderModel::rowsRemoved, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update, mods] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - - // Prevent a weird crash when trying to open the mods page twice in a session o.O - disconnect(mods.get(), &ModFolderModel::updateFinished, this, 0); - }); + connect(mods.get(), &ModFolderModel::updateFinished, this, + [this, check_allow_update, mods] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); connect(m_instance, &BaseInstance::runningStatusChanged, this, &ModFolderPage::runningStateChanged); ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning()); From cb52be433d2a55338df2205d2cebbf3e4d2f5eb5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 13:20:08 +0300 Subject: [PATCH 123/429] Made the installed mods more apparent Signed-off-by: Trial97 --- launcher/ui/widgets/ProjectItem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/ui/widgets/ProjectItem.cpp b/launcher/ui/widgets/ProjectItem.cpp index e8349c106..0b00a9bdf 100644 --- a/launcher/ui/widgets/ProjectItem.cpp +++ b/launcher/ui/widgets/ProjectItem.cpp @@ -65,9 +65,15 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o font.setUnderline(true); } if (index.data(UserDataTypes::INSTALLED).toBool()) { + auto rect = opt.rect; + rect.setX(rect.x() + 1); + rect.setY(rect.y() + 1); + rect.setHeight(rect.height() - 2); + rect.setWidth(rect.width() - 2); // Set nice font font.setItalic(true); font.setOverline(true); + painter->drawRect(rect); } font.setPointSize(font.pointSize() + 2); From 7ad9abf9bce2f2d7ec0e9e6848673753fefba3dd Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 15 Jun 2023 12:42:45 +0200 Subject: [PATCH 124/429] fix: add JavaVendor as an instance override This should suppress a critical error that gets printed every time an instance gets launched, as JavaCheck wants to store the vendor in the instance settings. Signed-off-by: Sefa Eyeoglu --- launcher/minecraft/MinecraftInstance.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 2c624a365..f8ed5214e 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -149,9 +149,10 @@ void MinecraftInstance::loadSpecificSettings() // special! m_settings->registerPassthrough(global_settings->getSetting("JavaTimestamp"), javaOrLocation); - m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaArchitecture"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaRealArchitecture"), javaOrLocation); + m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), javaOrLocation); + m_settings->registerPassthrough(global_settings->getSetting("JavaVendor"), javaOrLocation); // Window Size auto windowSetting = m_settings->registerSetting("OverrideWindow", false); From 6812823b55678230dd1fcd14973abc8d9a5d7245 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 15 Jun 2023 12:48:22 +0200 Subject: [PATCH 125/429] fix: simplify resolving of data path Co-authored-by: TheKodeToad Signed-off-by: Sefa Eyeoglu --- launcher/ui/MainWindow.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 629ace830..6b2191979 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1203,9 +1203,7 @@ void MainWindow::on_actionViewInstanceFolder_triggered() void MainWindow::on_actionViewLauncherRootFolder_triggered() { - QDir dataDir = QDir::current(); - QString dataPath = dataDir.absolutePath(); - + const QString dataPath = QDir::currentPath(); DesktopServices::openDirectory(dataPath); } From 98a07da39bbc41529b67cf515849d403280af07c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 14:12:29 +0300 Subject: [PATCH 126/429] Renamed variable Signed-off-by: Trial97 --- launcher/ui/widgets/ProjectItem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/ui/widgets/ProjectItem.cpp b/launcher/ui/widgets/ProjectItem.cpp index 0b00a9bdf..0085d6b2b 100644 --- a/launcher/ui/widgets/ProjectItem.cpp +++ b/launcher/ui/widgets/ProjectItem.cpp @@ -65,15 +65,15 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o font.setUnderline(true); } if (index.data(UserDataTypes::INSTALLED).toBool()) { - auto rect = opt.rect; - rect.setX(rect.x() + 1); - rect.setY(rect.y() + 1); - rect.setHeight(rect.height() - 2); - rect.setWidth(rect.width() - 2); + auto hRect = opt.rect; + hRect.setX(hRect.x() + 1); + hRect.setY(hRect.y() + 1); + hRect.setHeight(hRect.height() - 2); + hRect.setWidth(hRect.width() - 2); // Set nice font font.setItalic(true); font.setOverline(true); - painter->drawRect(rect); + painter->drawRect(hRect); } font.setPointSize(font.pointSize() + 2); From 1b42b9a08e5777fcf0d2578f3ffa05e354e47f9a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 14:25:58 +0300 Subject: [PATCH 127/429] Fixed tests Signed-off-by: Trial97 --- launcher/settings/INIFile.cpp | 6 +++--- tests/INIFile_test.cpp | 39 ++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index ad600ab91..d16256b96 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -98,7 +98,7 @@ QString unescape(QString orig) return out; } -QString unquete(QString str) +QString unquote(QString str) { if ((str.contains(QChar(';')) || str.contains(QChar('=')) || str.contains(QChar(','))) && str.endsWith("\"") && str.startsWith("\"")) { #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) @@ -138,7 +138,7 @@ bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) QString key = line.left(eqPos).trimmed(); QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); - valueStr = unquete(unescape(valueStr)); + valueStr = unquote(unescape(valueStr)); QVariant value(valueStr); map.insert(key, value); @@ -174,7 +174,7 @@ bool INIFile::loadFile(QString fileName) if (auto valueStr = _settings_obj.value(key).toString(); (valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) && valueStr.endsWith("\"") && valueStr.startsWith("\"")) { - insert(key, unquete(valueStr)); + insert(key, unquote(valueStr)); } else insert(key, _settings_obj.value(key)); } diff --git a/tests/INIFile_test.cpp b/tests/INIFile_test.cpp index 5d9c9cd8a..eaf077d43 100644 --- a/tests/INIFile_test.cpp +++ b/tests/INIFile_test.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "FileSystem.h" @@ -74,9 +75,8 @@ class IniFileTest : public QObject { QCOMPARE(out_list_numbers, list_numbers); } - void test_SaveAleardyExistingFile() + void test_SaveAlreadyExistingFile() { - QString fileName = "test_SaveAleardyExistingFile.ini"; QString fileContent = R"(InstanceType=OneSix iconKey=vanillia_icon name=Minecraft Vanillia @@ -86,9 +86,10 @@ Wrapperommand=)"; fileContent += "\""; fileContent += +R"(\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link =)"; fileContent += "\"\n"; - QFile file(fileName); + QTemporaryFile file; - if (file.open(QFile::WriteOnly | QFile::Text)) { + // QFile file(fileName); + if (file.open()) { QTextStream stream(&file); stream << fileContent; file.close(); @@ -96,22 +97,23 @@ Wrapperommand=)"; // load INIFile f1; - f1.loadFile(fileName); + f1.loadFile(file.fileName()); QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); QCOMPARE(f1.get("Wrapperommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link ="); - f1.saveFile(fileName); + f1.saveFile(file.fileName()); INIFile f2; - f2.loadFile(fileName); + f2.loadFile(file.fileName()); QCOMPARE(f2.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); QCOMPARE(f2.get("Wrapperommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link ="); QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.2"); } - void test_SaveAleardyExistingFileWithSpecialChars() + void test_SaveAlreadyExistingFileWithSpecialChars() { - QString fileName = "test_SaveAleardyExistingFileWithSpecialChars.ini"; - FS::deletePath(fileName); // just to clean the previous test run - QSettings settings{ fileName, QSettings::Format::IniFormat }; + QTemporaryFile file; + file.open(); + file.close(); + QSettings settings{ file.fileName(), QSettings::Format::IniFormat }; settings.setFallbacksEnabled(false); settings.setValue("simple", "value1"); @@ -127,20 +129,20 @@ Wrapperommand=)"; // load INIFile f1; - f1.loadFile(fileName); + f1.loadFile(file.fileName()); for (auto key : settings.allKeys()) QCOMPARE(f1.get(key, "NOT SET").toString(), settings.value(key).toString()); - f1.saveFile(fileName); + f1.saveFile(file.fileName()); INIFile f2; - f2.loadFile(fileName); + f2.loadFile(file.fileName()); for (auto key : settings.allKeys()) QCOMPARE(f2.get(key, "NOT SET").toString(), settings.value(key).toString()); QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.2"); } - void test_SaveAleardyExistingFileWithSpecialCharsV1() + void test_SaveAlreadyExistingFileWithSpecialCharsV1() { - QString fileName = "test_SaveAleardyExistingFileWithSpecialCharsV1.ini"; + QTemporaryFile file; QString fileContent = R"(InstanceType=OneSix ConfigVersion=1.1 iconKey=vanillia_icon @@ -148,9 +150,8 @@ name=Minecraft Vanillia OverrideCommands=true PreLaunchCommand=)"; fileContent += "\"\\\"env mesa=true\\\"\"\n"; - QFile file(fileName); - if (file.open(QFile::WriteOnly | QFile::Text)) { + if (file.open()) { QTextStream stream(&file); stream << fileContent; file.close(); @@ -158,7 +159,7 @@ PreLaunchCommand=)"; // load INIFile f1; - f1.loadFile(fileName); + f1.loadFile(file.fileName()); QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "env mesa=true"); QCOMPARE(f1.get("ConfigVersion", "NOT SET").toString(), "1.2"); } From 1d354df1f81e3c7f7f82d17bf3fd261eb2d98ee4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 16:51:58 +0300 Subject: [PATCH 128/429] Fix tests for window Signed-off-by: Trial97 --- tests/INIFile_test.cpp | 71 +++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/tests/INIFile_test.cpp b/tests/INIFile_test.cpp index eaf077d43..95730e244 100644 --- a/tests/INIFile_test.cpp +++ b/tests/INIFile_test.cpp @@ -86,34 +86,48 @@ Wrapperommand=)"; fileContent += "\""; fileContent += +R"(\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link =)"; fileContent += "\"\n"; +#if defined(Q_OS_WIN) + QString fileName = "test_SaveAlreadyExistingFile.ini"; + QFile file(fileName); + QCOMPARE(file.open(QFile::WriteOnly | QFile::Text), true); +#else QTemporaryFile file; - - // QFile file(fileName); - if (file.open()) { - QTextStream stream(&file); - stream << fileContent; - file.close(); - } + QCOMPARE(file.open(), true); + QCOMPARE(file.fileName().isEmpty(), false); + QString fileName = file.fileName(); +#endif + QTextStream stream(&file); + stream << fileContent; + file.close(); // load INIFile f1; - f1.loadFile(file.fileName()); + f1.loadFile(fileName); QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); QCOMPARE(f1.get("Wrapperommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link ="); - f1.saveFile(file.fileName()); + f1.saveFile(fileName); INIFile f2; - f2.loadFile(file.fileName()); + f2.loadFile(fileName); QCOMPARE(f2.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); QCOMPARE(f2.get("Wrapperommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link ="); QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.2"); +#if defined(Q_OS_WIN) + FS::deletePath(fileName); +#endif } void test_SaveAlreadyExistingFileWithSpecialChars() { +#if defined(Q_OS_WIN) + QString fileName = "test_SaveAlreadyExistingFileWithSpecialChars.ini"; +#else QTemporaryFile file; - file.open(); + QCOMPARE(file.open(), true); + QCOMPARE(file.fileName().isEmpty(), false); + QString fileName = file.fileName(); file.close(); - QSettings settings{ file.fileName(), QSettings::Format::IniFormat }; +#endif + QSettings settings{ fileName, QSettings::Format::IniFormat }; settings.setFallbacksEnabled(false); settings.setValue("simple", "value1"); @@ -129,20 +143,22 @@ Wrapperommand=)"; // load INIFile f1; - f1.loadFile(file.fileName()); + f1.loadFile(fileName); for (auto key : settings.allKeys()) QCOMPARE(f1.get(key, "NOT SET").toString(), settings.value(key).toString()); - f1.saveFile(file.fileName()); + f1.saveFile(fileName); INIFile f2; - f2.loadFile(file.fileName()); + f2.loadFile(fileName); for (auto key : settings.allKeys()) QCOMPARE(f2.get(key, "NOT SET").toString(), settings.value(key).toString()); QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.2"); +#if defined(Q_OS_WIN) + FS::deletePath(fileName); +#endif } void test_SaveAlreadyExistingFileWithSpecialCharsV1() { - QTemporaryFile file; QString fileContent = R"(InstanceType=OneSix ConfigVersion=1.1 iconKey=vanillia_icon @@ -151,17 +167,28 @@ OverrideCommands=true PreLaunchCommand=)"; fileContent += "\"\\\"env mesa=true\\\"\"\n"; - if (file.open()) { - QTextStream stream(&file); - stream << fileContent; - file.close(); - } +#if defined(Q_OS_WIN) + QString fileName = "test_SaveAlreadyExistingFileWithSpecialCharsV1.ini"; + QFile file(fileName); + QCOMPARE(file.open(QFile::WriteOnly | QFile::Text), true); +#else + QTemporaryFile file; + QCOMPARE(file.open(), true); + QCOMPARE(file.fileName().isEmpty(), false); + QString fileName = file.fileName(); +#endif + QTextStream stream(&file); + stream << fileContent; + file.close(); // load INIFile f1; - f1.loadFile(file.fileName()); + f1.loadFile(fileName); QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "env mesa=true"); QCOMPARE(f1.get("ConfigVersion", "NOT SET").toString(), "1.2"); +#if defined(Q_OS_WIN) + FS::deletePath(fileName); +#endif } }; From 13804f80de2cef845a917564adff9d9906c0eb5c Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 15 Jun 2023 16:37:03 +0100 Subject: [PATCH 129/429] Fix trailing space in instance name Signed-off-by: TheKodeToad --- launcher/InstanceTask.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/InstanceTask.cpp b/launcher/InstanceTask.cpp index 066827829..b16a40ba6 100644 --- a/launcher/InstanceTask.cpp +++ b/launcher/InstanceTask.cpp @@ -45,7 +45,10 @@ QString InstanceName::name() const { if (!m_modified_name.isEmpty()) return modifiedName(); - return QString("%1 %2").arg(m_original_name, m_original_version); + if (!m_original_version.isEmpty()) + return QString("%1 %2").arg(m_original_name, m_original_version); + + return m_original_name; } QString InstanceName::originalName() const From 147366bc0a905869f41bd8577337354bc7894e88 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 22:59:41 +0300 Subject: [PATCH 130/429] Made ByteSynkArray to use shared_ptr Signed-off-by: Trial97 --- launcher/modplatform/EnsureMetadataTask.cpp | 16 +- launcher/modplatform/ResourceAPI.h | 4 +- .../atlauncher/ATLPackInstallTask.cpp | 17 +- .../atlauncher/ATLPackInstallTask.h | 9 +- .../modplatform/flame/FileResolvingTask.cpp | 25 +- launcher/modplatform/flame/FlameAPI.cpp | 20 +- launcher/modplatform/flame/FlameAPI.h | 14 +- .../modplatform/flame/FlameCheckUpdate.cpp | 4 +- .../flame/FlameInstanceCreationTask.cpp | 2 +- .../helpers/NetworkResourceAPI.cpp | 31 +- .../modplatform/helpers/NetworkResourceAPI.h | 3 +- .../modplatform/legacy_ftb/PackFetchTask.cpp | 68 ++-- .../modplatform/legacy_ftb/PackFetchTask.h | 26 +- launcher/modplatform/modrinth/ModrinthAPI.cpp | 22 +- launcher/modplatform/modrinth/ModrinthAPI.h | 18 +- .../modrinth/ModrinthCheckUpdate.cpp | 2 +- .../modrinth/ModrinthPackExportTask.cpp | 4 +- .../modrinth/ModrinthPackExportTask.h | 2 +- .../technic/SolderPackInstallTask.cpp | 33 +- .../technic/SolderPackInstallTask.h | 73 ++-- launcher/net/ByteArraySink.h | 7 +- launcher/net/Download.cpp | 3 +- launcher/net/Download.h | 2 +- launcher/net/Upload.cpp | 376 +++++++++--------- launcher/net/Upload.h | 42 +- launcher/news/NewsChecker.cpp | 19 +- launcher/news/NewsChecker.h | 2 +- .../ui/pages/instance/ManagedPackPage.cpp | 4 +- .../modplatform/atlauncher/AtlListModel.cpp | 8 +- .../modplatform/atlauncher/AtlListModel.h | 29 +- .../atlauncher/AtlOptionalModDialog.cpp | 8 +- .../atlauncher/AtlOptionalModDialog.h | 4 +- .../ui/pages/modplatform/flame/FlameModel.cpp | 6 +- .../ui/pages/modplatform/flame/FlameModel.h | 53 ++- .../ui/pages/modplatform/flame/FlamePage.cpp | 7 +- .../modplatform/modrinth/ModrinthModel.cpp | 18 +- .../modplatform/modrinth/ModrinthModel.h | 4 +- .../modplatform/modrinth/ModrinthPage.cpp | 20 +- .../modplatform/technic/TechnicModel.cpp | 12 +- .../pages/modplatform/technic/TechnicModel.h | 27 +- .../pages/modplatform/technic/TechnicPage.cpp | 15 +- .../pages/modplatform/technic/TechnicPage.h | 2 +- 42 files changed, 497 insertions(+), 564 deletions(-) diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index 34d969f02..080dd5805 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -212,12 +212,12 @@ Task::Ptr EnsureMetadataTask::modrinthVersionsTask() { auto hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first(); - auto* response = new QByteArray(); + auto response = std::make_shared(); auto ver_task = modrinth_api.currentVersions(m_mods.keys(), hash_type, response); // Prevents unfortunate timings when aborting the task if (!ver_task) - return Task::Ptr{nullptr}; + return Task::Ptr{ nullptr }; connect(ver_task.get(), &Task::succeeded, this, [this, response] { QJsonParseError parse_error{}; @@ -264,7 +264,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() for (auto const& data : m_temp_versions) addonIds.insert(data.addonId.toString(), data.hash); - auto response = new QByteArray(); + auto response = std::make_shared(); Task::Ptr proj_task; if (addonIds.isEmpty()) { @@ -277,7 +277,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() // Prevents unfortunate timings when aborting the task if (!proj_task) - return Task::Ptr{nullptr}; + return Task::Ptr{ nullptr }; connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { QJsonParseError parse_error{}; @@ -345,7 +345,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() // Flame Task::Ptr EnsureMetadataTask::flameVersionsTask() { - auto* response = new QByteArray(); + auto response = std::make_shared(); QList fingerprints; for (auto& murmur : m_mods.keys()) { @@ -413,7 +413,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask() QHash addonIds; for (auto const& hash : m_mods.keys()) { if (m_temp_versions.contains(hash)) { - auto const& data = m_temp_versions.find(hash).value(); + auto data = m_temp_versions.find(hash).value(); auto id_str = data.addonId.toString(); if (!id_str.isEmpty()) @@ -421,7 +421,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask() } } - auto response = new QByteArray(); + auto response = std::make_shared(); Task::Ptr proj_task; if (addonIds.isEmpty()) { @@ -434,7 +434,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask() // Prevents unfortunate timings when aborting the task if (!proj_task) - return Task::Ptr{nullptr}; + return Task::Ptr{ nullptr }; connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { QJsonParseError parse_error{}; diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index 34f337791..e24971d5a 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -121,12 +121,12 @@ class ResourceAPI { qWarning() << "TODO"; return nullptr; } - [[nodiscard]] virtual Task::Ptr getProject(QString addonId, QByteArray* response) const + [[nodiscard]] virtual Task::Ptr getProject(QString addonId, std::shared_ptr response) const { qWarning() << "TODO"; return nullptr; } - [[nodiscard]] virtual Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const + [[nodiscard]] virtual Task::Ptr getProjects(QStringList addonIds, std::shared_ptr response) const { qWarning() << "TODO"; return nullptr; diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 07e0bf23b..2522020da 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -82,9 +82,9 @@ void PackInstallTask::executeTask() { qDebug() << "PackInstallTask::executeTask: " << QThread::currentThreadId(); NetJob::Ptr netJob{ new NetJob("ATLauncher::VersionFetch", APPLICATION->network()) }; - auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json") - .arg(m_pack_safe_name).arg(m_version_name); - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); + auto searchUrl = + QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json").arg(m_pack_safe_name).arg(m_version_name); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); QObject::connect(netJob.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); QObject::connect(netJob.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed); @@ -99,11 +99,12 @@ void PackInstallTask::onDownloadSucceeded() qDebug() << "PackInstallTask::onDownloadSucceeded: " << QThread::currentThreadId(); jobPtr.reset(); - QJsonParseError parse_error {}; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from ATLauncher at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response.get(), &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from ATLauncher at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response.get(); return; } auto obj = doc.object(); diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h index 90e25ae2e..bfe4d90aa 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h @@ -40,12 +40,13 @@ #include "ATLPackManifest.h" #include "InstanceTask.h" -#include "net/NetJob.h" -#include "settings/INISettingsObject.h" +#include "meta/Version.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "meta/Version.h" +#include "net/NetJob.h" +#include "settings/INISettingsObject.h" +#include #include namespace ATLauncher { @@ -123,7 +124,7 @@ private: bool abortable = false; NetJob::Ptr jobPtr; - QByteArray response; + std::shared_ptr response = std::make_shared(); InstallMode m_install_mode; QString m_pack_name; diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 83db642e7..ce7a60551 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -25,15 +25,16 @@ void Flame::FileResolvingTask::executeTask() setProgress(0, 3); m_dljob.reset(new NetJob("Mod id resolver", m_network)); result.reset(new QByteArray()); - //build json data to send + // build json data to send QJsonObject object; - object["fileIds"] = QJsonArray::fromVariantList(std::accumulate(m_toProcess.files.begin(), m_toProcess.files.end(), QVariantList(), [](QVariantList& l, const File& s) { - l.push_back(s.fileId); - return l; - })); + object["fileIds"] = QJsonArray::fromVariantList( + std::accumulate(m_toProcess.files.begin(), m_toProcess.files.end(), QVariantList(), [](QVariantList& l, const File& s) { + l.push_back(s.fileId); + return l; + })); QByteArray data = Json::toText(object); - auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result.get(), data); + auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result, data); m_dljob->addNetAction(dl); auto step_progress = std::make_shared(); @@ -87,17 +88,15 @@ void Flame::FileResolvingTask::netJobFinished() auto fileid = Json::requireInteger(Json::requireObject(file)["id"]); auto& out = m_toProcess.files[fileid]; try { - out.parseFromObject(Json::requireObject(file)); + out.parseFromObject(Json::requireObject(file)); } catch (const JSONValidationError& e) { qDebug() << "Blocked mod on curseforge" << out.fileName; auto hash = out.hash; - if(!hash.isEmpty()) { + if (!hash.isEmpty()) { auto url = QString("https://api.modrinth.com/v2/version_file/%1?algorithm=sha1").arg(hash); auto output = std::make_shared(); - auto dl = Net::Download::makeByteArray(QUrl(url), output.get()); - QObject::connect(dl.get(), &Net::Download::succeeded, [&out]() { - out.resolved = true; - }); + auto dl = Net::Download::makeByteArray(QUrl(url), output); + QObject::connect(dl.get(), &Net::Download::succeeded, [&out]() { out.resolved = true; }); m_checkJob->addNetAction(dl); blockedProjects.insert(&out, output); @@ -169,7 +168,7 @@ void Flame::FileResolvingTask::modrinthCheckFinished() { auto projectId = mod->projectId; auto output = std::make_shared(); auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(projectId); - auto dl = Net::Download::makeByteArray(url, output.get()); + auto dl = Net::Download::makeByteArray(url, output); qDebug() << "Fetching url slug for file:" << mod->fileName; QObject::connect(dl.get(), &Net::Download::succeeded, [block, index, output]() { auto mod = block->at(index); // use the shared_ptr so it is captured and only freed when we are done diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 92590a084..5b0b1d8b9 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -11,7 +11,7 @@ #include "net/NetJob.h" #include "net/Upload.h" -Task::Ptr FlameAPI::matchFingerprints(const QList& fingerprints, QByteArray* response) +Task::Ptr FlameAPI::matchFingerprints(const QList& fingerprints, std::shared_ptr response) { auto netJob = makeShared(QString("Flame::MatchFingerprints"), APPLICATION->network()); @@ -28,8 +28,6 @@ Task::Ptr FlameAPI::matchFingerprints(const QList& fingerprints, QByteArra netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/fingerprints"), response, body_raw)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); - return netJob; } @@ -43,7 +41,7 @@ auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString netJob->addNetAction(Net::Download::makeByteArray( QString("https://api.curseforge.com/v1/mods/%1/files/%2/changelog") .arg(QString::fromStdString(std::to_string(modId)), QString::fromStdString(std::to_string(fileId))), - response.get())); + response)); QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &changelog] { QJsonParseError parse_error{}; @@ -75,8 +73,8 @@ auto FlameAPI::getModDescription(int modId) -> QString auto netJob = makeShared(QString("Flame::ModDescription"), APPLICATION->network()); auto response = std::make_shared(); - netJob->addNetAction(Net::Download::makeByteArray( - QString("https://api.curseforge.com/v1/mods/%1/description").arg(QString::number(modId)), response.get())); + netJob->addNetAction( + Net::Download::makeByteArray(QString("https://api.curseforge.com/v1/mods/%1/description").arg(QString::number(modId)), response)); QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &description] { QJsonParseError parse_error{}; @@ -115,7 +113,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe auto response = std::make_shared(); ModPlatform::IndexedVersion ver; - netJob->addNetAction(Net::Download::makeByteArray(versions_url, response.get())); + netJob->addNetAction(Net::Download::makeByteArray(versions_url, response)); QObject::connect(netJob.get(), &NetJob::succeeded, [response, args, &ver] { QJsonParseError parse_error{}; @@ -137,7 +135,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe for (auto file : arr) { auto file_obj = Json::requireObject(file); auto file_tmp = FlameMod::loadIndexedPackVersion(file_obj); - if(file_tmp.date > ver_tmp.date) { + if (file_tmp.date > ver_tmp.date) { ver_tmp = file_tmp; latest_file_obj = file_obj; } @@ -160,7 +158,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe return ver; } -Task::Ptr FlameAPI::getProjects(QStringList addonIds, QByteArray* response) const +Task::Ptr FlameAPI::getProjects(QStringList addonIds, std::shared_ptr response) const { auto netJob = makeShared(QString("Flame::GetProjects"), APPLICATION->network()); @@ -177,13 +175,12 @@ Task::Ptr FlameAPI::getProjects(QStringList addonIds, QByteArray* response) cons netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods"), response, body_raw)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; }); return netJob; } -Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response) const +Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, std::shared_ptr response) const { auto netJob = makeShared(QString("Flame::GetFiles"), APPLICATION->network()); @@ -200,7 +197,6 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response) c netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods/files"), response, body_raw)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; }); return netJob; diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 5811d7175..49ba12b0a 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -4,6 +4,7 @@ #pragma once +#include #include "modplatform/ModIndex.h" #include "modplatform/helpers/NetworkResourceAPI.h" @@ -14,9 +15,9 @@ class FlameAPI : public NetworkResourceAPI { auto getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::IndexedVersion; - Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const override; - Task::Ptr matchFingerprints(const QList& fingerprints, QByteArray* response); - Task::Ptr getFiles(const QStringList& fileIds, QByteArray* response) const; + Task::Ptr getProjects(QStringList addonIds, std::shared_ptr response) const override; + Task::Ptr matchFingerprints(const QList& fingerprints, std::shared_ptr response); + Task::Ptr getFiles(const QStringList& fileIds, std::shared_ptr response) const; [[nodiscard]] auto getSortingMethods() const -> QList override; @@ -41,14 +42,15 @@ class FlameAPI : public NetworkResourceAPI { return 4; // TODO: remove this once Quilt drops official Fabric support if (loaders & Quilt) // NOTE: Most if not all Fabric mods should work *currently* - return 4; // Quilt would probably be 5 + return 4; // Quilt would probably be 5 return 0; } private: [[nodiscard]] std::optional getSearchURL(SearchArgs const& args) const override { - auto gameVersionStr = args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString(); + auto gameVersionStr = + args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString(); QStringList get_arguments; get_arguments.append(QString("classId=%1").arg(getClassId(args.type))); @@ -73,7 +75,7 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getVersionsURL(VersionSearchArgs const& args) const override { - QString url{QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString())}; + QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString()) }; QStringList get_parameters; if (args.mcVersions.has_value()) diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp index e09aeb3d9..a2628e34c 100644 --- a/launcher/modplatform/flame/FlameCheckUpdate.cpp +++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp @@ -31,7 +31,7 @@ ModPlatform::IndexedPack getProjectInfo(ModPlatform::IndexedVersion& ver_info) auto get_project_job = new NetJob("Flame::GetProjectJob", APPLICATION->network()); - auto response = new QByteArray(); + auto response = std::make_shared(); auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(ver_info.addonId.toString()); auto dl = Net::Download::makeByteArray(url, response); get_project_job->addNetAction(dl); @@ -75,7 +75,7 @@ ModPlatform::IndexedVersion getFileInfo(int addonId, int fileId) auto get_file_info_job = new NetJob("Flame::GetFileInfoJob", APPLICATION->network()); - auto response = new QByteArray(); + auto response = std::make_shared(); auto url = QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(QString::number(addonId), QString::number(fileId)); auto dl = Net::Download::makeByteArray(url, response); get_file_info_job->addNetAction(dl); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index dae93d1c6..3aa156e16 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -179,7 +179,7 @@ bool FlameCreationTask::updateInstance() fileIds.append(QString::number(file.fileId)); } - auto* raw_response = new QByteArray; + auto raw_response = std::make_shared(); auto job = api.getFiles(fileIds, raw_response); QEventLoop loop; diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.cpp b/launcher/modplatform/helpers/NetworkResourceAPI.cpp index a3c592fdc..0ed2410e9 100644 --- a/launcher/modplatform/helpers/NetworkResourceAPI.cpp +++ b/launcher/modplatform/helpers/NetworkResourceAPI.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-only #include "NetworkResourceAPI.h" +#include #include "Application.h" #include "net/NetJob.h" @@ -19,12 +20,12 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks& auto search_url = search_url_optional.value(); - auto response = new QByteArray(); + auto response = std::make_shared(); auto netJob = makeShared(QString("%1::Search").arg(debugName()), APPLICATION->network()); netJob->addNetAction(Net::Download::makeByteArray(QUrl(search_url), response)); - QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks]{ + QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -40,27 +41,21 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks& callbacks.on_succeed(doc); }); - QObject::connect(netJob.get(), &NetJob::failed, [&netJob, callbacks](QString reason){ + QObject::connect(netJob.get(), &NetJob::failed, [&netJob, callbacks](QString reason) { int network_error_code = -1; if (auto* failed_action = netJob->getFailedActions().at(0); failed_action && failed_action->m_reply) network_error_code = failed_action->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - callbacks.on_fail(reason, network_error_code); + callbacks.on_fail(reason, network_error_code); }); - QObject::connect(netJob.get(), &NetJob::aborted, [callbacks]{ - callbacks.on_abort(); - }); - QObject::connect(netJob.get(), &NetJob::finished, [response] { - delete response; - }); - + QObject::connect(netJob.get(), &NetJob::aborted, [callbacks] { callbacks.on_abort(); }); return netJob; } Task::Ptr NetworkResourceAPI::getProjectInfo(ProjectInfoArgs&& args, ProjectInfoCallbacks&& callbacks) const { - auto response = new QByteArray(); + auto response = std::make_shared(); auto job = getProject(args.pack.addonId.toString(), response); QObject::connect(job.get(), &NetJob::succeeded, [response, callbacks, args] { @@ -88,7 +83,7 @@ Task::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Versi auto versions_url = versions_url_optional.value(); auto netJob = makeShared(QString("%1::Versions").arg(args.pack.name), APPLICATION->network()); - auto response = new QByteArray(); + auto response = std::make_shared(); netJob->addNetAction(Net::Download::makeByteArray(versions_url, response)); @@ -105,14 +100,10 @@ Task::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Versi callbacks.on_succeed(doc, args.pack); }); - QObject::connect(netJob.get(), &NetJob::finished, [response] { - delete response; - }); - return netJob; } -Task::Ptr NetworkResourceAPI::getProject(QString addonId, QByteArray* response) const +Task::Ptr NetworkResourceAPI::getProject(QString addonId, std::shared_ptr response) const { auto project_url_optional = getInfoURL(addonId); if (!project_url_optional.has_value()) @@ -124,9 +115,5 @@ Task::Ptr NetworkResourceAPI::getProject(QString addonId, QByteArray* response) netJob->addNetAction(Net::Download::makeByteArray(QUrl(project_url), response)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { - delete response; - }); - return netJob; } diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.h b/launcher/modplatform/helpers/NetworkResourceAPI.h index 94813bec8..84604e410 100644 --- a/launcher/modplatform/helpers/NetworkResourceAPI.h +++ b/launcher/modplatform/helpers/NetworkResourceAPI.h @@ -4,13 +4,14 @@ #pragma once +#include #include "modplatform/ResourceAPI.h" class NetworkResourceAPI : public ResourceAPI { public: Task::Ptr searchProjects(SearchArgs&&, SearchCallbacks&&) const override; - Task::Ptr getProject(QString addonId, QByteArray* response) const override; + Task::Ptr getProject(QString addonId, std::shared_ptr response) const override; Task::Ptr getProjectInfo(ProjectInfoArgs&&, ProjectInfoCallbacks&&) const override; Task::Ptr getProjectVersions(VersionSearchArgs&&, VersionSearchCallbacks&&) const override; diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp index e8768c5cd..a8a0fc2c2 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp @@ -51,11 +51,11 @@ void PackFetchTask::fetch() QUrl publicPacksUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/modpacks.xml"); qDebug() << "Downloading public version info from" << publicPacksUrl.toString(); - jobPtr->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData)); + jobPtr->addNetAction(Net::Download::makeByteArray(publicPacksUrl, publicModpacksXmlFileData)); QUrl thirdPartyUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/thirdparty.xml"); qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString(); - jobPtr->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData)); + jobPtr->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, thirdPartyModpacksXmlFileData)); QObject::connect(jobPtr.get(), &NetJob::succeeded, this, &PackFetchTask::fileDownloadFinished); QObject::connect(jobPtr.get(), &NetJob::failed, this, &PackFetchTask::fileDownloadFailed); @@ -64,22 +64,19 @@ void PackFetchTask::fetch() jobPtr->start(); } -void PackFetchTask::fetchPrivate(const QStringList & toFetch) +void PackFetchTask::fetchPrivate(const QStringList& toFetch) { QString privatePackBaseUrl = BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1.xml"; - for (auto &packCode: toFetch) - { - QByteArray *data = new QByteArray(); - NetJob *job = new NetJob("Fetching private pack", m_network); + for (auto& packCode : toFetch) { + auto data = std::make_shared(); + NetJob* job = new NetJob("Fetching private pack", m_network); job->addNetAction(Net::Download::makeByteArray(privatePackBaseUrl.arg(packCode), data)); - QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode] - { + QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode] { ModpackList packs; parseAndAddPacks(*data, PackType::Private, packs); - foreach(Modpack currentPack, packs) - { + foreach (Modpack currentPack, packs) { currentPack.packCode = packCode; emit privateFileDownloadFinished(currentPack); } @@ -87,24 +84,20 @@ void PackFetchTask::fetchPrivate(const QStringList & toFetch) job->deleteLater(); data->clear(); - delete data; }); - QObject::connect(job, &NetJob::failed, this, [this, job, packCode, data](QString reason) - { + QObject::connect(job, &NetJob::failed, this, [this, job, packCode, data](QString reason) { emit privateFileDownloadFailed(reason, packCode); job->deleteLater(); data->clear(); - delete data; }); - QObject::connect(job, &NetJob::aborted, this, [this, job, data]{ + QObject::connect(job, &NetJob::aborted, this, [this, job, data] { emit aborted(); job->deleteLater(); data->clear(); - delete data; }); job->start(); @@ -117,27 +110,22 @@ void PackFetchTask::fileDownloadFinished() QStringList failedLists; - if(!parseAndAddPacks(publicModpacksXmlFileData, PackType::Public, publicPacks)) - { + if (!parseAndAddPacks(*publicModpacksXmlFileData, PackType::Public, publicPacks)) { failedLists.append(tr("Public Packs")); } - if(!parseAndAddPacks(thirdPartyModpacksXmlFileData, PackType::ThirdParty, thirdPartyPacks)) - { + if (!parseAndAddPacks(*thirdPartyModpacksXmlFileData, PackType::ThirdParty, thirdPartyPacks)) { failedLists.append(tr("Third Party Packs")); } - if(failedLists.size() > 0) - { + if (failedLists.size() > 0) { emit failed(tr("Failed to download some pack lists: %1").arg(failedLists.join("\n- "))); - } - else - { + } else { emit finished(publicPacks, thirdPartyPacks); } } -bool PackFetchTask::parseAndAddPacks(QByteArray &data, PackType packType, ModpackList &list) +bool PackFetchTask::parseAndAddPacks(QByteArray& data, PackType packType, ModpackList& list) { QDomDocument doc; @@ -145,8 +133,7 @@ bool PackFetchTask::parseAndAddPacks(QByteArray &data, PackType packType, Modpac int errorLine = -1; int errorCol = -1; - if(!doc.setContent(data, false, &errorMsg, &errorLine, &errorCol)) - { + if (!doc.setContent(data, false, &errorMsg, &errorLine, &errorCol)) { auto fullErrMsg = QString("Failed to fetch modpack data: %1 %2:%3!").arg(errorMsg).arg(errorLine).arg(errorCol); qWarning() << fullErrMsg; data.clear(); @@ -154,8 +141,7 @@ bool PackFetchTask::parseAndAddPacks(QByteArray &data, PackType packType, Modpac } QDomNodeList nodes = doc.elementsByTagName("modpack"); - for(int i = 0; i < nodes.length(); i++) - { + for (int i = 0; i < nodes.length(); i++) { QDomElement element = nodes.at(i).toElement(); Modpack modpack; @@ -169,26 +155,20 @@ bool PackFetchTask::parseAndAddPacks(QByteArray &data, PackType packType, Modpac modpack.broken = false; modpack.bugged = false; - //remove empty if the xml is bugged - for(QString curr : modpack.oldVersions) - { - if(curr.isNull() || curr.isEmpty()) - { + // remove empty if the xml is bugged + for (QString curr : modpack.oldVersions) { + if (curr.isNull() || curr.isEmpty()) { modpack.oldVersions.removeAll(curr); modpack.bugged = true; qWarning() << "Removed some empty versions from" << modpack.name; } } - if(modpack.oldVersions.size() < 1) - { - if(!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty()) - { + if (modpack.oldVersions.size() < 1) { + if (!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty()) { modpack.oldVersions.append(modpack.currentVersion); qWarning() << "Added current version to oldVersions because oldVersions was empty! (" + modpack.name + ")"; - } - else - { + } else { modpack.broken = true; qWarning() << "Broken pack:" << modpack.name << " => No valid version!"; } @@ -218,4 +198,4 @@ void PackFetchTask::fileDownloadAborted() emit aborted(); } -} +} // namespace LegacyFTB diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.h b/launcher/modplatform/legacy_ftb/PackFetchTask.h index 8f3c4f3ba..f2116ce99 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.h +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.h @@ -1,41 +1,41 @@ #pragma once -#include "net/NetJob.h" -#include #include #include +#include +#include #include "PackHelpers.h" +#include "net/NetJob.h" namespace LegacyFTB { class PackFetchTask : public QObject { - Q_OBJECT -public: - PackFetchTask(shared_qobject_ptr network) : QObject(nullptr), m_network(network) {}; + public: + PackFetchTask(shared_qobject_ptr network) : QObject(nullptr), m_network(network){}; virtual ~PackFetchTask() = default; void fetch(); - void fetchPrivate(const QStringList &toFetch); + void fetchPrivate(const QStringList& toFetch); -private: + private: shared_qobject_ptr m_network; NetJob::Ptr jobPtr; - QByteArray publicModpacksXmlFileData; - QByteArray thirdPartyModpacksXmlFileData; + std::shared_ptr publicModpacksXmlFileData = std::make_shared(); + std::shared_ptr thirdPartyModpacksXmlFileData = std::make_shared(); - bool parseAndAddPacks(QByteArray &data, PackType packType, ModpackList &list); + bool parseAndAddPacks(QByteArray& data, PackType packType, ModpackList& list); ModpackList publicPacks; ModpackList thirdPartyPacks; -protected slots: + protected slots: void fileDownloadFinished(); void fileDownloadFailed(QString reason); void fileDownloadAborted(); -signals: + signals: void finished(ModpackList publicPacks, ModpackList thirdPartyPacks); void failed(QString reason); void aborted(); @@ -44,4 +44,4 @@ signals: void privateFileDownloadFailed(QString reason, QString packCode); }; -} +} // namespace LegacyFTB diff --git a/launcher/modplatform/modrinth/ModrinthAPI.cpp b/launcher/modplatform/modrinth/ModrinthAPI.cpp index 29e3d129d..364cf3f30 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.cpp +++ b/launcher/modplatform/modrinth/ModrinthAPI.cpp @@ -9,19 +9,17 @@ #include "net/NetJob.h" #include "net/Upload.h" -Task::Ptr ModrinthAPI::currentVersion(QString hash, QString hash_format, QByteArray* response) +Task::Ptr ModrinthAPI::currentVersion(QString hash, QString hash_format, std::shared_ptr response) { auto netJob = makeShared(QString("Modrinth::GetCurrentVersion"), APPLICATION->network()); netJob->addNetAction(Net::Download::makeByteArray( QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1?algorithm=%2").arg(hash, hash_format), response)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); - return netJob; } -Task::Ptr ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_format, QByteArray* response) +Task::Ptr ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_format, std::shared_ptr response) { auto netJob = makeShared(QString("Modrinth::GetCurrentVersions"), APPLICATION->network()); @@ -35,8 +33,6 @@ Task::Ptr ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_f netJob->addNetAction(Net::Upload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), response, body_raw)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); - return netJob; } @@ -44,7 +40,7 @@ Task::Ptr ModrinthAPI::latestVersion(QString hash, QString hash_format, std::optional> mcVersions, std::optional loaders, - QByteArray* response) + std::shared_ptr response) { auto netJob = makeShared(QString("Modrinth::GetLatestVersion"), APPLICATION->network()); @@ -67,8 +63,6 @@ Task::Ptr ModrinthAPI::latestVersion(QString hash, netJob->addNetAction(Net::Upload::makeByteArray( QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1/update?algorithm=%2").arg(hash, hash_format), response, body_raw)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); - return netJob; } @@ -76,7 +70,7 @@ Task::Ptr ModrinthAPI::latestVersions(const QStringList& hashes, QString hash_format, std::optional> mcVersions, std::optional loaders, - QByteArray* response) + std::shared_ptr response) { auto netJob = makeShared(QString("Modrinth::GetLatestVersions"), APPLICATION->network()); @@ -101,22 +95,16 @@ Task::Ptr ModrinthAPI::latestVersions(const QStringList& hashes, netJob->addNetAction(Net::Upload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), response, body_raw)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); - return netJob; } -Task::Ptr ModrinthAPI::getProjects(QStringList addonIds, QByteArray* response) const +Task::Ptr ModrinthAPI::getProjects(QStringList addonIds, std::shared_ptr response) const { auto netJob = makeShared(QString("Modrinth::GetProjects"), APPLICATION->network()); auto searchUrl = getMultipleModInfoURL(addonIds); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); - QObject::connect(netJob.get(), &NetJob::finished, [response, netJob] { - delete response; - }); - return netJob; } diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index b91ac5c14..98f20b512 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -12,27 +12,23 @@ class ModrinthAPI : public NetworkResourceAPI { public: - auto currentVersion(QString hash, - QString hash_format, - QByteArray* response) -> Task::Ptr; + auto currentVersion(QString hash, QString hash_format, std::shared_ptr response) -> Task::Ptr; - auto currentVersions(const QStringList& hashes, - QString hash_format, - QByteArray* response) -> Task::Ptr; + auto currentVersions(const QStringList& hashes, QString hash_format, std::shared_ptr response) -> Task::Ptr; auto latestVersion(QString hash, QString hash_format, std::optional> mcVersions, std::optional loaders, - QByteArray* response) -> Task::Ptr; + std::shared_ptr response) -> Task::Ptr; auto latestVersions(const QStringList& hashes, QString hash_format, - std::optional> mcVersions, - std::optional loaders, - QByteArray* response) -> Task::Ptr; + std::optional> mcVersions, + std::optional loaders, + std::shared_ptr response) -> Task::Ptr; - Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const override; + Task::Ptr getProjects(QStringList addonIds, std::shared_ptr response) const override; public: [[nodiscard]] auto getSortingMethods() const -> QList override; diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 4fe91ce78..6a3f12f9a 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -71,7 +71,7 @@ void ModrinthCheckUpdate::executeTask() hashing_task.start(); loop.exec(); - auto* response = new QByteArray(); + auto response = std::make_shared(); auto job = api.latestVersions(hashes, best_hash_type, m_game_versions, m_loaders, response); QEventLoop lock; diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index bff9bf42e..c607bb89d 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -157,7 +157,7 @@ void ModrinthPackExportTask::makeApiRequest() if (pendingHashes.isEmpty()) buildZip(); else { - QByteArray* response = new QByteArray; + auto response = std::make_shared(); task = api.currentVersions(pendingHashes.values(), "sha512", response); connect(task.get(), &NetJob::succeeded, [this, response]() { parseApiResponse(response); }); connect(task.get(), &NetJob::failed, this, &ModrinthPackExportTask::emitFailed); @@ -165,7 +165,7 @@ void ModrinthPackExportTask::makeApiRequest() } } -void ModrinthPackExportTask::parseApiResponse(const QByteArray* response) +void ModrinthPackExportTask::parseApiResponse(const std::shared_ptr response) { task = nullptr; diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.h b/launcher/modplatform/modrinth/ModrinthPackExportTask.h index af00ffaab..96f292c1b 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.h +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.h @@ -69,7 +69,7 @@ class ModrinthPackExportTask : public Task { void collectFiles(); void collectHashes(); void makeApiRequest(); - void parseApiResponse(const QByteArray* response); + void parseApiResponse(const std::shared_ptr response); void buildZip(); void finish(); diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index c26d6a5a6..6a05d17ae 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -37,20 +37,19 @@ #include #include -#include #include +#include -#include "TechnicPackProcessor.h" #include "SolderPackManifest.h" +#include "TechnicPackProcessor.h" #include "net/ChecksumValidator.h" -Technic::SolderPackInstallTask::SolderPackInstallTask( - shared_qobject_ptr network, - const QUrl &solderUrl, - const QString &pack, - const QString &version, - const QString &minecraftVersion -) { +Technic::SolderPackInstallTask::SolderPackInstallTask(shared_qobject_ptr network, + const QUrl& solderUrl, + const QString& pack, + const QString& version, + const QString& minecraftVersion) +{ m_solderUrl = solderUrl; m_pack = pack; m_version = version; @@ -58,9 +57,9 @@ Technic::SolderPackInstallTask::SolderPackInstallTask( m_minecraftVersion = minecraftVersion; } -bool Technic::SolderPackInstallTask::abort() { - if(m_abortable) - { +bool Technic::SolderPackInstallTask::abort() +{ + if (m_abortable) { return m_filesNetJob->abort(); } return false; @@ -72,7 +71,7 @@ void Technic::SolderPackInstallTask::executeTask() m_filesNetJob.reset(new NetJob(tr("Resolving modpack files"), m_network)); auto sourceUrl = QString("%1/modpack/%2/%3").arg(m_solderUrl.toString(), m_pack, m_version); - m_filesNetJob->addNetAction(Net::Download::makeByteArray(sourceUrl, &m_response)); + m_filesNetJob->addNetAction(Net::Download::makeByteArray(sourceUrl, m_response)); auto job = m_filesNetJob.get(); connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::fileListSucceeded); @@ -85,11 +84,11 @@ void Technic::SolderPackInstallTask::fileListSucceeded() { setStatus(tr("Downloading modpack")); - QJsonParseError parse_error {}; - QJsonDocument doc = QJsonDocument::fromJson(m_response, &parse_error); + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*m_response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from Solder at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << m_response; + qWarning() << *m_response; return; } auto obj = doc.object(); @@ -110,7 +109,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded() m_filesNetJob.reset(new NetJob(tr("Downloading modpack"), m_network)); int i = 0; - for (const auto &mod : build.mods) { + for (const auto& mod : build.mods) { auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i)); auto dl = Net::Download::makeFile(mod.url, path); diff --git a/launcher/modplatform/technic/SolderPackInstallTask.h b/launcher/modplatform/technic/SolderPackInstallTask.h index aa14ce88b..f2c6a83a4 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.h +++ b/launcher/modplatform/technic/SolderPackInstallTask.h @@ -40,45 +40,48 @@ #include #include +#include -namespace Technic -{ - class SolderPackInstallTask : public InstanceTask - { - Q_OBJECT - public: - explicit SolderPackInstallTask(shared_qobject_ptr network, const QUrl &solderUrl, const QString& pack, const QString& version, const QString &minecraftVersion); +namespace Technic { +class SolderPackInstallTask : public InstanceTask { + Q_OBJECT + public: + explicit SolderPackInstallTask(shared_qobject_ptr network, + const QUrl& solderUrl, + const QString& pack, + const QString& version, + const QString& minecraftVersion); - bool canAbort() const override { return true; } - bool abort() override; + bool canAbort() const override { return true; } + bool abort() override; - protected: - //! Entry point for tasks. - virtual void executeTask() override; + protected: + //! Entry point for tasks. + virtual void executeTask() override; - private slots: - void fileListSucceeded(); - void downloadSucceeded(); - void downloadFailed(QString reason); - void downloadProgressChanged(qint64 current, qint64 total); - void downloadAborted(); - void extractFinished(); - void extractAborted(); + private slots: + void fileListSucceeded(); + void downloadSucceeded(); + void downloadFailed(QString reason); + void downloadProgressChanged(qint64 current, qint64 total); + void downloadAborted(); + void extractFinished(); + void extractAborted(); - private: - bool m_abortable = false; + private: + bool m_abortable = false; - shared_qobject_ptr m_network; + shared_qobject_ptr m_network; - NetJob::Ptr m_filesNetJob; - QUrl m_solderUrl; - QString m_pack; - QString m_version; - QString m_minecraftVersion; - QByteArray m_response; - QTemporaryDir m_outputDir; - int m_modCount; - QFuture m_extractFuture; - QFutureWatcher m_extractFutureWatcher; - }; -} + NetJob::Ptr m_filesNetJob; + QUrl m_solderUrl; + QString m_pack; + QString m_version; + QString m_minecraftVersion; + std::shared_ptr m_response = std::make_shared(); + QTemporaryDir m_outputDir; + int m_modCount; + QFuture m_extractFuture; + QFutureWatcher m_extractFutureWatcher; +}; +} // namespace Technic diff --git a/launcher/net/ByteArraySink.h b/launcher/net/ByteArraySink.h index 728193b30..d6b17d605 100644 --- a/launcher/net/ByteArraySink.h +++ b/launcher/net/ByteArraySink.h @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * 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 @@ -46,7 +47,7 @@ namespace Net { */ class ByteArraySink : public Sink { public: - ByteArraySink(QByteArray* output) : m_output(output){}; + ByteArraySink(std::shared_ptr output) : m_output(output){}; virtual ~ByteArraySink() = default; @@ -93,6 +94,6 @@ class ByteArraySink : public Sink { auto hasLocalData() -> bool override { return false; } private: - QByteArray* m_output; + std::shared_ptr m_output; }; } // namespace Net diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp index 7f8d3a067..4ea45c635 100644 --- a/launcher/net/Download.cpp +++ b/launcher/net/Download.cpp @@ -41,6 +41,7 @@ #include #include +#include #include "ByteArraySink.h" #include "ChecksumValidator.h" @@ -69,7 +70,7 @@ auto Download::makeCached(QUrl url, MetaEntryPtr entry, Options options) -> Down return dl; } -auto Download::makeByteArray(QUrl url, QByteArray* output, Options options) -> Download::Ptr +auto Download::makeByteArray(QUrl url, std::shared_ptr output, Options options) -> Download::Ptr { auto dl = makeShared(); dl->m_url = url; diff --git a/launcher/net/Download.h b/launcher/net/Download.h index 920164a30..2e861732d 100644 --- a/launcher/net/Download.h +++ b/launcher/net/Download.h @@ -60,7 +60,7 @@ class Download : public NetAction { ~Download() override = default; static auto makeCached(QUrl url, MetaEntryPtr entry, Options options = Option::NoOptions) -> Download::Ptr; - static auto makeByteArray(QUrl url, QByteArray* output, Options options = Option::NoOptions) -> Download::Ptr; + static auto makeByteArray(QUrl url, std::shared_ptr output, Options options = Option::NoOptions) -> Download::Ptr; static auto makeFile(QUrl url, QString path, Options options = Option::NoOptions) -> Download::Ptr; public: diff --git a/launcher/net/Upload.cpp b/launcher/net/Upload.cpp index 4f9553edf..3f6f58290 100644 --- a/launcher/net/Upload.cpp +++ b/launcher/net/Upload.cpp @@ -39,218 +39,226 @@ #include "Upload.h" #include -#include "ByteArraySink.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" +#include "ByteArraySink.h" #include "net/Logging.h" namespace Net { - bool Upload::abort() - { - if (m_reply) { - m_reply->abort(); - } else { - m_state = State::AbortedByUser; +bool Upload::abort() +{ + if (m_reply) { + m_reply->abort(); + } else { + m_state = State::AbortedByUser; + } + return true; +} + +void Upload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + setProgress(bytesReceived, bytesTotal); +} + +void Upload::downloadError(QNetworkReply::NetworkError error) +{ + if (error == QNetworkReply::OperationCanceledError) { + qCCritical(taskUploadLogC) << getUid().toString() << "Aborted " << m_url.toString(); + m_state = State::AbortedByUser; + } else { + // error happened during download. + qCCritical(taskUploadLogC) << getUid().toString() << "Failed " << m_url.toString() << " with reason " << error; + m_state = State::Failed; + } +} + +void Upload::sslErrors(const QList& errors) +{ + int i = 1; + for (const auto& error : errors) { + qCCritical(taskUploadLogC) << getUid().toString() << "Upload" << m_url.toString() << "SSL Error #" << i << " : " + << error.errorString(); + auto cert = error.certificate(); + qCCritical(taskUploadLogC) << getUid().toString() << "Certificate in question:\n" << cert.toText(); + i++; + } +} + +bool Upload::handleRedirect() +{ + QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl(); + if (!redirect.isValid()) { + if (!m_reply->hasRawHeader("Location")) { + // no redirect -> it's fine to continue + return false; } - return true; - } - - void Upload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { - setProgress(bytesReceived, bytesTotal); - } - - void Upload::downloadError(QNetworkReply::NetworkError error) { - if (error == QNetworkReply::OperationCanceledError) { - qCCritical(taskUploadLogC) << getUid().toString() << "Aborted " << m_url.toString(); - m_state = State::AbortedByUser; - } else { - // error happened during download. - qCCritical(taskUploadLogC) << getUid().toString() << "Failed " << m_url.toString() << " with reason " << error; - m_state = State::Failed; + // there is a Location header, but it's not correct. we need to apply some workarounds... + QByteArray redirectBA = m_reply->rawHeader("Location"); + if (redirectBA.size() == 0) { + // empty, yet present redirect header? WTF? + return false; } - } - - void Upload::sslErrors(const QList &errors) { - int i = 1; - for (const auto& error : errors) { - qCCritical(taskUploadLogC) << getUid().toString() << "Upload" << m_url.toString() << "SSL Error #" << i << " : " << error.errorString(); - auto cert = error.certificate(); - qCCritical(taskUploadLogC) << getUid().toString() << "Certificate in question:\n" << cert.toText(); - i++; - } - } - - bool Upload::handleRedirect() - { - QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl(); - if (!redirect.isValid()) { - if (!m_reply->hasRawHeader("Location")) { - // no redirect -> it's fine to continue - return false; - } - // there is a Location header, but it's not correct. we need to apply some workarounds... - QByteArray redirectBA = m_reply->rawHeader("Location"); - if (redirectBA.size() == 0) { - // empty, yet present redirect header? WTF? - return false; - } - QString redirectStr = QString::fromUtf8(redirectBA); - - if (redirectStr.startsWith("//")) { - /* - * IF the URL begins with //, we need to insert the URL scheme. - * See: https://bugreports.qt.io/browse/QTBUG-41061 - * See: http://tools.ietf.org/html/rfc3986#section-4.2 - */ - redirectStr = m_reply->url().scheme() + ":" + redirectStr; - } else if (redirectStr.startsWith("/")) { - /* - * IF the URL begins with /, we need to process it as a relative URL - */ - auto url = m_reply->url(); - url.setPath(redirectStr, QUrl::TolerantMode); - redirectStr = url.toString(); - } + QString redirectStr = QString::fromUtf8(redirectBA); + if (redirectStr.startsWith("//")) { /* - * Next, make sure the URL is parsed in tolerant mode. Qt doesn't parse the location header in tolerant mode, which causes issues. - * FIXME: report Qt bug for this + * IF the URL begins with //, we need to insert the URL scheme. + * See: https://bugreports.qt.io/browse/QTBUG-41061 + * See: http://tools.ietf.org/html/rfc3986#section-4.2 */ - redirect = QUrl(redirectStr, QUrl::TolerantMode); - if (!redirect.isValid()) { - qCWarning(taskUploadLogC) << getUid().toString() << "Failed to parse redirect URL:" << redirectStr; - downloadError(QNetworkReply::ProtocolFailure); - return false; - } - qCDebug(taskUploadLogC) << getUid().toString() << "Fixed location header:" << redirect; - } else { - qCDebug(taskUploadLogC) << getUid().toString() << "Location header:" << redirect; + redirectStr = m_reply->url().scheme() + ":" + redirectStr; + } else if (redirectStr.startsWith("/")) { + /* + * IF the URL begins with /, we need to process it as a relative URL + */ + auto url = m_reply->url(); + url.setPath(redirectStr, QUrl::TolerantMode); + redirectStr = url.toString(); } - m_url = QUrl(redirect.toString()); - qCDebug(taskUploadLogC) << getUid().toString() << "Following redirect to " << m_url.toString(); - startAction(m_network); - return true; + /* + * Next, make sure the URL is parsed in tolerant mode. Qt doesn't parse the location header in tolerant mode, which causes issues. + * FIXME: report Qt bug for this + */ + redirect = QUrl(redirectStr, QUrl::TolerantMode); + if (!redirect.isValid()) { + qCWarning(taskUploadLogC) << getUid().toString() << "Failed to parse redirect URL:" << redirectStr; + downloadError(QNetworkReply::ProtocolFailure); + return false; + } + qCDebug(taskUploadLogC) << getUid().toString() << "Fixed location header:" << redirect; + } else { + qCDebug(taskUploadLogC) << getUid().toString() << "Location header:" << redirect; } - void Upload::downloadFinished() { - // handle HTTP redirection first - // very unlikely for post requests, still can happen - if (handleRedirect()) { - qCDebug(taskUploadLogC) << getUid().toString() << "Upload redirected:" << m_url.toString(); - return; - } + m_url = QUrl(redirect.toString()); + qCDebug(taskUploadLogC) << getUid().toString() << "Following redirect to " << m_url.toString(); + startAction(m_network); + return true; +} - // if the download failed before this point ... - if (m_state == State::Succeeded) { - qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed but we are allowed to proceed:" << m_url.toString(); - m_sink->abort(); - m_reply.reset(); - emit succeeded(); - return; - } else if (m_state == State::Failed) { - qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed in previous step:" << m_url.toString(); - m_sink->abort(); - m_reply.reset(); - emit failed(""); - return; - } else if (m_state == State::AbortedByUser) { - qCDebug(taskUploadLogC) << getUid().toString() << "Upload aborted in previous step:" << m_url.toString(); - m_sink->abort(); - m_reply.reset(); - emit aborted(); - return; - } +void Upload::downloadFinished() +{ + // handle HTTP redirection first + // very unlikely for post requests, still can happen + if (handleRedirect()) { + qCDebug(taskUploadLogC) << getUid().toString() << "Upload redirected:" << m_url.toString(); + return; + } - // make sure we got all the remaining data, if any - auto data = m_reply->readAll(); - if (data.size()) { - qCDebug(taskUploadLogC) << getUid().toString() << "Writing extra" << data.size() << "bytes"; - m_state = m_sink->write(data); - } - - // otherwise, finalize the whole graph - m_state = m_sink->finalize(*m_reply.get()); - if (m_state != State::Succeeded) { - qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed to finalize:" << m_url.toString(); - m_sink->abort(); - m_reply.reset(); - emit failed(""); - return; - } + // if the download failed before this point ... + if (m_state == State::Succeeded) { + qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed but we are allowed to proceed:" << m_url.toString(); + m_sink->abort(); m_reply.reset(); - qCDebug(taskUploadLogC) << getUid().toString() << "Upload succeeded:" << m_url.toString(); emit succeeded(); + return; + } else if (m_state == State::Failed) { + qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed in previous step:" << m_url.toString(); + m_sink->abort(); + m_reply.reset(); + emit failed(""); + return; + } else if (m_state == State::AbortedByUser) { + qCDebug(taskUploadLogC) << getUid().toString() << "Upload aborted in previous step:" << m_url.toString(); + m_sink->abort(); + m_reply.reset(); + emit aborted(); + return; } - void Upload::downloadReadyRead() { - if (m_state == State::Running) { - auto data = m_reply->readAll(); - m_state = m_sink->write(data); - } + // make sure we got all the remaining data, if any + auto data = m_reply->readAll(); + if (data.size()) { + qCDebug(taskUploadLogC) << getUid().toString() << "Writing extra" << data.size() << "bytes"; + m_state = m_sink->write(data); } - void Upload::executeTask() { - setStatus(tr("Uploading %1").arg(m_url.toString())); + // otherwise, finalize the whole graph + m_state = m_sink->finalize(*m_reply.get()); + if (m_state != State::Succeeded) { + qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed to finalize:" << m_url.toString(); + m_sink->abort(); + m_reply.reset(); + emit failed(""); + return; + } + m_reply.reset(); + qCDebug(taskUploadLogC) << getUid().toString() << "Upload succeeded:" << m_url.toString(); + emit succeeded(); +} - if (m_state == State::AbortedByUser) { - qCWarning(taskUploadLogC) << getUid().toString() << "Attempt to start an aborted Upload:" << m_url.toString(); - emit aborted(); +void Upload::downloadReadyRead() +{ + if (m_state == State::Running) { + auto data = m_reply->readAll(); + m_state = m_sink->write(data); + } +} + +void Upload::executeTask() +{ + setStatus(tr("Uploading %1").arg(m_url.toString())); + + if (m_state == State::AbortedByUser) { + qCWarning(taskUploadLogC) << getUid().toString() << "Attempt to start an aborted Upload:" << m_url.toString(); + emit aborted(); + return; + } + QNetworkRequest request(m_url); + m_state = m_sink->init(request); + switch (m_state) { + case State::Succeeded: + emitSucceeded(); + qCDebug(taskUploadLogC) << getUid().toString() << "Upload cache hit " << m_url.toString(); return; - } - QNetworkRequest request(m_url); - m_state = m_sink->init(request); - switch (m_state) { - case State::Succeeded: - emitSucceeded(); - qCDebug(taskUploadLogC) << getUid().toString() << "Upload cache hit " << m_url.toString(); - return; - case State::Running: - qCDebug(taskUploadLogC) << getUid().toString() << "Uploading " << m_url.toString(); - break; - case State::Inactive: - case State::Failed: - emitFailed(""); - return; - case State::AbortedByUser: - emitAborted(); - return; - } + case State::Running: + qCDebug(taskUploadLogC) << getUid().toString() << "Uploading " << m_url.toString(); + break; + case State::Inactive: + case State::Failed: + emitFailed(""); + return; + case State::AbortedByUser: + emitAborted(); + return; + } - request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); - // TODO remove duplication - if (APPLICATION->capabilities() & Application::SupportsFlame && request.url().host() == QUrl(BuildConfig.FLAME_BASE_URL).host()) { - request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8()); - } else if (request.url().host() == QUrl(BuildConfig.MODRINTH_PROD_URL).host() || - request.url().host() == QUrl(BuildConfig.MODRINTH_STAGING_URL).host()) { - QString token = APPLICATION->getModrinthAPIToken(); - if (!token.isNull()) - request.setRawHeader("Authorization", token.toUtf8()); - } + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); + // TODO remove duplication + if (APPLICATION->capabilities() & Application::SupportsFlame && request.url().host() == QUrl(BuildConfig.FLAME_BASE_URL).host()) { + request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8()); + } else if (request.url().host() == QUrl(BuildConfig.MODRINTH_PROD_URL).host() || + request.url().host() == QUrl(BuildConfig.MODRINTH_STAGING_URL).host()) { + QString token = APPLICATION->getModrinthAPIToken(); + if (!token.isNull()) + request.setRawHeader("Authorization", token.toUtf8()); + } - //TODO other types of post requests ? - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QNetworkReply* rep = m_network->post(request, m_post_data); + // TODO other types of post requests ? + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QNetworkReply* rep = m_network->post(request, m_post_data); - m_reply.reset(rep); - connect(rep, &QNetworkReply::downloadProgress, this, &Upload::downloadProgress); - connect(rep, &QNetworkReply::finished, this, &Upload::downloadFinished); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 - connect(rep, &QNetworkReply::errorOccurred, this, &Upload::downloadError); + m_reply.reset(rep); + connect(rep, &QNetworkReply::downloadProgress, this, &Upload::downloadProgress); + connect(rep, &QNetworkReply::finished, this, &Upload::downloadFinished); +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 + connect(rep, &QNetworkReply::errorOccurred, this, &Upload::downloadError); #else - connect(rep, QOverload::of(&QNetworkReply::error), this, &Upload::downloadError); + connect(rep, QOverload::of(&QNetworkReply::error), this, &Upload::downloadError); #endif - connect(rep, &QNetworkReply::sslErrors, this, &Upload::sslErrors); - connect(rep, &QNetworkReply::readyRead, this, &Upload::downloadReadyRead); - } + connect(rep, &QNetworkReply::sslErrors, this, &Upload::sslErrors); + connect(rep, &QNetworkReply::readyRead, this, &Upload::downloadReadyRead); +} - Upload::Ptr Upload::makeByteArray(QUrl url, QByteArray *output, QByteArray m_post_data) { - auto up = makeShared(); - up->m_url = std::move(url); - up->m_sink.reset(new ByteArraySink(output)); - up->m_post_data = std::move(m_post_data); - return up; - } -} // Net +Upload::Ptr Upload::makeByteArray(QUrl url, std::shared_ptr output, QByteArray m_post_data) +{ + auto up = makeShared(); + up->m_url = std::move(url); + up->m_sink.reset(new ByteArraySink(output)); + up->m_post_data = std::move(m_post_data); + return up; +} +} // namespace Net diff --git a/launcher/net/Upload.h b/launcher/net/Upload.h index e8f0ea40d..0b0c94976 100644 --- a/launcher/net/Upload.h +++ b/launcher/net/Upload.h @@ -42,31 +42,31 @@ namespace Net { - class Upload : public NetAction { - Q_OBJECT +class Upload : public NetAction { + Q_OBJECT - public: - using Ptr = shared_qobject_ptr; + public: + using Ptr = shared_qobject_ptr; - static Upload::Ptr makeByteArray(QUrl url, QByteArray *output, QByteArray m_post_data); - auto abort() -> bool override; - auto canAbort() const -> bool override { return true; }; + static Upload::Ptr makeByteArray(QUrl url, std::shared_ptr output, QByteArray m_post_data); + auto abort() -> bool override; + auto canAbort() const -> bool override { return true; }; - protected slots: - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; - void downloadError(QNetworkReply::NetworkError error) override; - void sslErrors(const QList & errors) override; - void downloadFinished() override; - void downloadReadyRead() override; + protected slots: + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; + void downloadError(QNetworkReply::NetworkError error) override; + void sslErrors(const QList& errors) override; + void downloadFinished() override; + void downloadReadyRead() override; - public slots: - void executeTask() override; - private: - std::unique_ptr m_sink; - QByteArray m_post_data; + public slots: + void executeTask() override; - bool handleRedirect(); - }; + private: + std::unique_ptr m_sink; + QByteArray m_post_data; -} // Net + bool handleRedirect(); +}; +} // namespace Net diff --git a/launcher/news/NewsChecker.cpp b/launcher/news/NewsChecker.cpp index 1f1520d0a..4f02bf5e0 100644 --- a/launcher/news/NewsChecker.cpp +++ b/launcher/news/NewsChecker.cpp @@ -58,7 +58,7 @@ void NewsChecker::reloadNews() qDebug() << "Reloading news."; NetJob::Ptr job{ new NetJob("News RSS Feed", m_network) }; - job->addNetAction(Net::Download::makeByteArray(m_feedUrl, &newsData)); + job->addNetAction(Net::Download::makeByteArray(m_feedUrl, newsData)); QObject::connect(job.get(), &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished); QObject::connect(job.get(), &NetJob::failed, this, &NewsChecker::rssDownloadFailed); m_newsNetJob.reset(job); @@ -79,32 +79,27 @@ void NewsChecker::rssDownloadFinished() int errorCol = -1; // Parse the XML. - if (!doc.setContent(newsData, false, &errorMsg, &errorLine, &errorCol)) - { + if (!doc.setContent(*newsData, false, &errorMsg, &errorLine, &errorCol)) { QString fullErrorMsg = QString("Error parsing RSS feed XML. %1 at %2:%3.").arg(errorMsg).arg(errorLine).arg(errorCol); fail(fullErrorMsg); - newsData.clear(); + newsData->clear(); return; } - newsData.clear(); + newsData->clear(); } // If the parsing succeeded, read it. QDomNodeList items = doc.elementsByTagName("entry"); m_newsEntries.clear(); - for (int i = 0; i < items.length(); i++) - { + for (int i = 0; i < items.length(); i++) { QDomElement element = items.at(i).toElement(); NewsEntryPtr entry; entry.reset(new NewsEntry()); QString errorMsg = "An unknown error occurred."; - if (NewsEntry::fromXmlElement(element, entry.get(), &errorMsg)) - { + if (NewsEntry::fromXmlElement(element, entry.get(), &errorMsg)) { qDebug() << "Loaded news entry" << entry->title; m_newsEntries.append(entry); - } - else - { + } else { qWarning() << "Failed to load news entry at index" << i << ":" << errorMsg; } } diff --git a/launcher/news/NewsChecker.h b/launcher/news/NewsChecker.h index 8467a5412..41babfff7 100644 --- a/launcher/news/NewsChecker.h +++ b/launcher/news/NewsChecker.h @@ -85,7 +85,7 @@ protected: /* data */ //! True if news has been loaded. bool m_loadedNews; - QByteArray newsData; + std::shared_ptr newsData = std::make_shared(); /*! * Gets the error message that was given last time the news was loaded. diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index d0701a7ad..e0a7314ff 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -226,7 +226,7 @@ void ModrinthManagedPackPage::parseManagedPack() QString id = m_inst->getManagedPackID(); - m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response.get())); + m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response)); QObject::connect(m_fetch_job.get(), &NetJob::succeeded, this, [this, response, id] { QJsonParseError parse_error{}; @@ -369,7 +369,7 @@ void FlameManagedPackPage::parseManagedPack() QString id = m_inst->getManagedPackID(); - m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/mods/%2/files").arg(BuildConfig.FLAME_BASE_URL, id), response.get())); + m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/mods/%2/files").arg(BuildConfig.FLAME_BASE_URL, id), response)); QObject::connect(m_fetch_job.get(), &NetJob::succeeded, this, [this, response, id] { QJsonParseError parse_error{}; diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp index 9ad26f472..2ab865295 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp @@ -88,7 +88,7 @@ void ListModel::request() auto netJob = makeShared("Atl::Request", APPLICATION->network()); auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/json/packsnew.json"); - netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response)); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), response)); jobPtr = netJob; jobPtr->start(); @@ -101,10 +101,10 @@ void ListModel::requestFinished() jobPtr.reset(); QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if(parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from ATL at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; + qWarning() << *response; return; } @@ -120,7 +120,7 @@ void ListModel::requestFinished() ATLauncher::loadIndexedPack(pack, packObj); } catch (const JSONValidationError &e) { - qDebug() << QString::fromUtf8(response); + qDebug() << QString::fromUtf8(*response); qWarning() << "Error while reading pack manifest from ATLauncher: " << e.cause(); return; } diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h index 2574c48d6..ed1fdc9f9 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h @@ -18,42 +18,41 @@ #include -#include "net/NetJob.h" -#include #include +#include +#include "net/NetJob.h" namespace Atl { typedef QMap LogoMap; typedef std::function LogoCallback; -class ListModel : public QAbstractListModel -{ +class ListModel : public QAbstractListModel { Q_OBJECT -public: - ListModel(QObject *parent); + public: + ListModel(QObject* parent); virtual ~ListModel(); - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - QVariant data(const QModelIndex &index, int role) const override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role) const override; void request(); - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); + void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); -private slots: + private slots: void requestFinished(); void requestFailed(QString reason); void logoFailed(QString logo); void logoLoaded(QString logo, QIcon out); -private: + private: void requestLogo(QString file, QString url); -private: + private: QList modpacks; QStringList m_failedLogos; @@ -62,7 +61,7 @@ private: QMap waitingCallbacks; NetJob::Ptr jobPtr; - QByteArray response; + std::shared_ptr response = std::make_shared(); }; -} +} // namespace Atl diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index cdb4532c8..7b61daa71 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -152,7 +152,7 @@ Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const { void AtlOptionalModListModel::useShareCode(const QString& code) { m_jobPtr.reset(new NetJob("Atl::Request", APPLICATION->network())); auto url = QString(BuildConfig.ATL_API_BASE_URL + "share-codes/" + code); - m_jobPtr->addNetAction(Net::Download::makeByteArray(QUrl(url), &m_response)); + m_jobPtr->addNetAction(Net::Download::makeByteArray(QUrl(url), m_response)); connect(m_jobPtr.get(), &NetJob::succeeded, this, &AtlOptionalModListModel::shareCodeSuccess); @@ -166,10 +166,10 @@ void AtlOptionalModListModel::shareCodeSuccess() { m_jobPtr.reset(); QJsonParseError parse_error {}; - auto doc = QJsonDocument::fromJson(m_response, &parse_error); + auto doc = QJsonDocument::fromJson(*m_response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from ATL at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << m_response; + qWarning() << *m_response; return; } auto obj = doc.object(); @@ -179,7 +179,7 @@ void AtlOptionalModListModel::shareCodeSuccess() { ATLauncher::loadShareCodeResponse(response, obj); } catch (const JSONValidationError& e) { - qDebug() << QString::fromUtf8(m_response); + qDebug() << QString::fromUtf8(*m_response); qWarning() << "Error while reading response from ATLauncher: " << e.cause(); return; } diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h index 8e02444e4..639f0d489 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h @@ -82,9 +82,9 @@ private: void toggleMod(ATLauncher::VersionMod mod, int index); void setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit = true); -private: + private: NetJob::Ptr m_jobPtr; - QByteArray m_response; + std::shared_ptr m_response = std::make_shared(); ATLauncher::PackVersion m_version; QVector m_mods; diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 5961ea026..54d0b003e 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -169,7 +169,7 @@ void ListModel::performPaginatedSearch() .arg(currentSearchTerm) .arg(currentSort + 1); - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); jobPtr = netJob; jobPtr->start(); QObject::connect(netJob.get(), &NetJob::succeeded, this, &ListModel::searchRequestFinished); @@ -202,11 +202,11 @@ void Flame::ListModel::searchRequestFinished() jobPtr.reset(); QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from CurseForge at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; + qWarning() << *response; return; } diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.h b/launcher/ui/pages/modplatform/flame/FlameModel.h index cab666cc3..b3bc96b8c 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModel.h @@ -3,46 +3,44 @@ #include #include -#include -#include #include -#include #include +#include +#include #include #include -#include +#include +#include -#include #include +#include #include namespace Flame { - typedef QMap LogoMap; typedef std::function LogoCallback; -class ListModel : public QAbstractListModel -{ +class ListModel : public QAbstractListModel { Q_OBJECT -public: - ListModel(QObject *parent); + public: + ListModel(QObject* parent); virtual ~ListModel(); - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role) override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - bool canFetchMore(const QModelIndex & parent) const override; - void fetchMore(const QModelIndex & parent) override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; + Qt::ItemFlags flags(const QModelIndex& index) const override; + bool canFetchMore(const QModelIndex& parent) const override; + void fetchMore(const QModelIndex& parent) override; - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString & term, const int sort); + void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); + void searchWithTerm(const QString& term, const int sort); -private slots: + private slots: void performPaginatedSearch(); void logoFailed(QString logo); @@ -51,10 +49,10 @@ private slots: void searchRequestFinished(); void searchRequestFailed(QString reason); -private: + private: void requestLogo(QString file, QString url); -private: + private: QList modpacks; QStringList m_failedLogos; QStringList m_loadingLogos; @@ -64,14 +62,9 @@ private: QString currentSearchTerm; int currentSort = 0; int nextSearchOffset = 0; - enum SearchState { - None, - CanPossiblyFetchMore, - ResetRequested, - Finished - } searchState = None; + enum SearchState { None, CanPossiblyFetchMore, ResetRequested, Finished } searchState = None; NetJob::Ptr jobPtr; - QByteArray response; + std::shared_ptr response = std::make_shared(); }; -} +} // namespace Flame diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index f9ac4a789..cef26bb6b 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -130,7 +130,7 @@ void FlamePage::onSelectionChanged(QModelIndex curr, QModelIndex prev) if (current.versionsLoaded == false) { qDebug() << "Loading flame modpack versions"; auto netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name), APPLICATION->network()); - auto response = new QByteArray(); + auto response = std::make_shared(); int addonId = current.addonId; netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.curseforge.com/v1/mods/%1/files").arg(addonId), response)); @@ -170,10 +170,7 @@ void FlamePage::onSelectionChanged(QModelIndex curr, QModelIndex prev) } suggestCurrent(); }); - QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { - netJob->deleteLater(); - delete response; - }); + QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { netJob->deleteLater(); }); netJob->start(); } else { for (auto version : current.versions) { diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 346a00b0e..675589d08 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -129,27 +129,27 @@ void ModpackListModel::performPaginatedSearch() // TODO: Move to standalone API auto netJob = makeShared("Modrinth::SearchModpack", APPLICATION->network()); auto searchAllUrl = QString(BuildConfig.MODRINTH_PROD_URL + - "/search?" - "offset=%1&" - "limit=%2&" - "query=%3&" - "index=%4&" - "facets=[[\"project_type:modpack\"]]") + "/search?" + "offset=%1&" + "limit=%2&" + "query=%3&" + "index=%4&" + "facets=[[\"project_type:modpack\"]]") .arg(nextSearchOffset) .arg(m_modpacks_per_page) .arg(currentSearchTerm) .arg(currentSort); - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchAllUrl), &m_all_response)); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchAllUrl), m_all_response)); QObject::connect(netJob.get(), &NetJob::succeeded, this, [this] { QJsonParseError parse_error_all{}; - QJsonDocument doc_all = QJsonDocument::fromJson(m_all_response, &parse_error_all); + QJsonDocument doc_all = QJsonDocument::fromJson(*m_all_response, &parse_error_all); if (parse_error_all.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from " << debugName() << " at " << parse_error_all.offset << " reason: " << parse_error_all.errorString(); - qWarning() << m_all_response; + qWarning() << *m_all_response; return; } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 6e6be4b9e..b9e9c3da5 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -110,9 +110,9 @@ class ModpackListModel : public QAbstractListModel { NetJob::Ptr jobPtr; - QByteArray m_all_response; + std::shared_ptr m_all_response = std::make_shared(); QByteArray m_specific_response; int m_modpacks_per_page = 20; }; -} // namespace ModPlatform +} // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index 0bb11d834..c71dd9038 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -123,7 +123,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev) qDebug() << "Loading modrinth modpack information"; auto netJob = new NetJob(QString("Modrinth::PackInformation(%1)").arg(current.name), APPLICATION->network()); - auto response = new QByteArray(); + auto response = std::make_shared(); QString id = current.id; @@ -162,10 +162,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev) suggestCurrent(); }); - QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { - netJob->deleteLater(); - delete response; - }); + QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { netJob->deleteLater(); }); netJob->start(); } else updateUI(); @@ -174,7 +171,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev) qDebug() << "Loading modrinth modpack versions"; auto netJob = new NetJob(QString("Modrinth::PackVersions(%1)").arg(current.name), APPLICATION->network()); - auto response = new QByteArray(); + auto response = std::make_shared(); QString id = current.id; @@ -217,10 +214,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev) suggestCurrent(); }); - QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { - netJob->deleteLater(); - delete response; - }); + QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { netJob->deleteLater(); }); netJob->start(); } else { @@ -260,10 +254,8 @@ void ModrinthPage::updateUI() text += donates.join(", "); } - if (!current.extra.issuesUrl.isEmpty() - || !current.extra.sourceUrl.isEmpty() - || !current.extra.wikiUrl.isEmpty() - || !current.extra.discordUrl.isEmpty()) { + if (!current.extra.issuesUrl.isEmpty() || !current.extra.sourceUrl.isEmpty() || !current.extra.wikiUrl.isEmpty() || + !current.extra.discordUrl.isEmpty()) { text += "

" + tr("External links:") + "
"; } diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp index 50f0c72d1..7975fd583 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp @@ -134,7 +134,7 @@ void Technic::ListModel::performSearch() ).arg(BuildConfig.TECHNIC_API_BASE_URL, BuildConfig.TECHNIC_API_BUILD, currentSearchTerm); searchMode = List; } - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); jobPtr = netJob; jobPtr->start(); QObject::connect(netJob.get(), &NetJob::succeeded, this, &ListModel::searchRequestFinished); @@ -146,11 +146,11 @@ void Technic::ListModel::searchRequestFinished() jobPtr.reset(); QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) - { - qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; return; } diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.h b/launcher/ui/pages/modplatform/technic/TechnicModel.h index 5eea124cc..0f1a814e2 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicModel.h +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.h @@ -44,33 +44,32 @@ namespace Technic { typedef std::function LogoCallback; -class ListModel : public QAbstractListModel -{ +class ListModel : public QAbstractListModel { Q_OBJECT -public: - ListModel(QObject *parent); + public: + ListModel(QObject* parent); virtual ~ListModel(); virtual QVariant data(const QModelIndex& index, int role) const; virtual int columnCount(const QModelIndex& parent) const; virtual int rowCount(const QModelIndex& parent) const; - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString & term); + void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); + void searchWithTerm(const QString& term); -private slots: + private slots: void searchRequestFinished(); void searchRequestFailed(); void logoFailed(QString logo); void logoLoaded(QString logo, QString out); -private: + private: void performSearch(); void requestLogo(QString logo, QString url); -private: + private: QList modpacks; QStringList m_failedLogos; QStringList m_loadingLogos; @@ -78,17 +77,13 @@ private: QMap waitingCallbacks; QString currentSearchTerm; - enum SearchState { - None, - ResetRequested, - Finished - } searchState = None; + enum SearchState { None, ResetRequested, Finished } searchState = None; enum SearchMode { List, Single, } searchMode = List; NetJob::Ptr jobPtr; - QByteArray response; + std::shared_ptr response = std::make_shared(); }; -} +} // namespace Technic diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp index 859da97e9..fc678fa20 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp @@ -143,7 +143,7 @@ void TechnicPage::suggestCurrent() auto netJob = makeShared(QString("Technic::PackMeta(%1)").arg(current.name), APPLICATION->network()); QString slug = current.slug; - netJob->addNetAction(Net::Download::makeByteArray(QString("%1modpack/%2?build=%3").arg(BuildConfig.TECHNIC_API_BASE_URL, slug, BuildConfig.TECHNIC_API_BUILD), &response)); + netJob->addNetAction(Net::Download::makeByteArray(QString("%1modpack/%2?build=%3").arg(BuildConfig.TECHNIC_API_BASE_URL, slug, BuildConfig.TECHNIC_API_BUILD), response)); QObject::connect(netJob.get(), &NetJob::succeeded, this, [this, slug] { jobPtr.reset(); @@ -154,7 +154,7 @@ void TechnicPage::suggestCurrent() } QJsonParseError parse_error {}; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); QJsonObject obj = doc.object(); if(parse_error.error != QJsonParseError::NoError) { @@ -249,7 +249,7 @@ void TechnicPage::metadataLoaded() auto netJob = makeShared(QString("Technic::SolderMeta(%1)").arg(current.name), APPLICATION->network()); auto url = QString("%1/modpack/%2").arg(current.url, current.slug); - netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response)); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), response)); QObject::connect(netJob.get(), &NetJob::succeeded, this, &TechnicPage::onSolderLoaded); @@ -291,11 +291,11 @@ void TechnicPage::onSolderLoaded() { current.versions.clear(); - QJsonParseError parse_error {}; - auto doc = QJsonDocument::fromJson(response, &parse_error); + QJsonParseError parse_error{}; + auto doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from Solder at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; + qWarning() << *response; fallback(); return; } @@ -304,8 +304,7 @@ void TechnicPage::onSolderLoaded() { TechnicSolder::Pack pack; try { TechnicSolder::loadPack(pack, obj); - } - catch (const JSONValidationError& err) { + } catch (const JSONValidationError& err) { qCritical() << "Couldn't parse Solder pack metadata:" << err.cause(); fallback(); return; diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.h b/launcher/ui/pages/modplatform/technic/TechnicPage.h index f4a3b61d1..753261b30 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicPage.h +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.h @@ -104,5 +104,5 @@ private: QString selectedVersion; NetJob::Ptr jobPtr; - QByteArray response; + std::shared_ptr response = std::make_shared(); }; From 45cce1d19a7e83dcb8db35ed1f203a175ce50635 Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 16 Jun 2023 14:34:44 -0400 Subject: [PATCH 131/429] fix(appimage): bundle generic opengl lib Signed-off-by: seth --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6a6eceaa..e75c9e742 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -250,6 +250,7 @@ jobs: wget "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage" ${{ github.workspace }}/.github/scripts/prepare_JREs.sh + sudo apt install libopengl0 - name: Add QT_HOST_PATH var (Windows MSVC arm64) if: runner.os == 'Windows' && matrix.architecture == 'arm64' @@ -482,7 +483,8 @@ jobs: cp -r /home/runner/work/PrismLauncher/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ - cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}//usr/lib/ + cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ + cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64/server" From b123f4f9484d0514b5b71c091f47200e5f182984 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:58:32 +0000 Subject: [PATCH 132/429] chore(deps): update cachix/install-nix-action action to v22 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6a6eceaa..4c1c8a7f6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -599,7 +599,7 @@ jobs: submodules: 'true' - name: Install nix if: inputs.build_type == 'Debug' - uses: cachix/install-nix-action@v21 + uses: cachix/install-nix-action@v22 with: install_url: https://nixos.org/nix/install extra_nix_config: | From 2d00a727f6ea0ae8c39a1d915b6a9c4db2b84a30 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 17 Jun 2023 11:04:36 -0300 Subject: [PATCH 133/429] fix: hide git commit when the build doesn't have git stuff support This fixes the Git commit string being "GITDIR-NOTFOUND" on the About page when building a package from the bundled source archive. Signed-off-by: flow --- buildconfig/BuildConfig.cpp.in | 1 + 1 file changed, 1 insertion(+) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 353731896..8a412b7ff 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -82,6 +82,7 @@ Config::Config() { GIT_REFSPEC = "refs/heads/stable"; GIT_TAG = versionString(); + GIT_COMMIT = ""; } if (GIT_REFSPEC.startsWith("refs/heads/")) From 0161520b332f485483f57acc305ad71a00d63fbc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Jun 2023 23:27:26 +0300 Subject: [PATCH 134/429] Fixed leaks Signed-off-by: Trial97 --- launcher/modplatform/EnsureMetadataTask.cpp | 9 +- .../atlauncher/ATLPackInstallTask.h | 40 +++---- launcher/modplatform/helpers/HashUtils.cpp | 14 ++- launcher/modplatform/helpers/HashUtils.h | 6 + .../modrinth/ModrinthCheckUpdate.cpp | 5 +- launcher/ui/dialogs/NewsDialog.cpp | 2 +- .../modplatform/atlauncher/AtlListModel.cpp | 91 ++++++-------- .../AtlUserInteractionSupportImpl.h | 8 +- .../modplatform/legacy_ftb/ListModel.cpp | 112 +++++++----------- .../modplatform/technic/TechnicModel.cpp | 106 ++++++----------- 10 files changed, 164 insertions(+), 229 deletions(-) diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index 080dd5805..a04a2534c 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -10,6 +10,7 @@ #include "modplatform/flame/FlameAPI.h" #include "modplatform/flame/FlameModIndex.h" +#include "modplatform/helpers/HashUtils.h" #include "modplatform/modrinth/ModrinthAPI.h" #include "modplatform/modrinth/ModrinthPackIndex.h" @@ -24,8 +25,8 @@ EnsureMetadataTask::EnsureMetadataTask(Mod* mod, QDir dir, ModPlatform::Resource auto hash_task = createNewHash(mod); if (!hash_task) return; - connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { m_mods.insert(hash_task->getResult(), mod); }); - connect(hash_task.get(), &Task::failed, [this, hash_task, mod] { emitFail(mod, "", RemoveFromList::No); }); + connect(hash_task.get(), &Hashing::Hasher::getResults, [this, mod](QString hash) { m_mods.insert(hash, mod); }); + connect(hash_task.get(), &Task::failed, [this, mod] { emitFail(mod, "", RemoveFromList::No); }); hash_task->start(); } @@ -37,8 +38,8 @@ EnsureMetadataTask::EnsureMetadataTask(QList& mods, QDir dir, ModPlatform: auto hash_task = createNewHash(mod); if (!hash_task) continue; - connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { m_mods.insert(hash_task->getResult(), mod); }); - connect(hash_task.get(), &Task::failed, [this, hash_task, mod] { emitFail(mod, "", RemoveFromList::No); }); + connect(hash_task.get(), &Hashing::Hasher::getResults, [this, mod](QString hash) { m_mods.insert(hash, mod); }); + connect(hash_task.get(), &Task::failed, [this, mod] { emitFail(mod, "", RemoveFromList::No); }); m_hashing_task->addTask(hash_task); } } diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h index bfe4d90aa..b82f523fe 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h @@ -58,8 +58,7 @@ enum class InstallMode { }; class UserInteractionSupport { - -public: + public: /** * Requests a user interaction to select which optional mods should be installed. */ @@ -75,23 +74,27 @@ public: * Requests a user interaction to display a message. */ virtual void displayMessage(QString message) = 0; + + virtual ~UserInteractionSupport() = default; }; -class PackInstallTask : public InstanceTask -{ -Q_OBJECT +class PackInstallTask : public InstanceTask { + Q_OBJECT -public: - explicit PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode = InstallMode::Install); - virtual ~PackInstallTask(){} + public: + explicit PackInstallTask(UserInteractionSupport* support, + QString packName, + QString version, + InstallMode installMode = InstallMode::Install); + virtual ~PackInstallTask() { delete m_support; } bool canAbort() const override { return true; } bool abort() override; -protected: + protected: virtual void executeTask() override; -private slots: + private slots: void onDownloadSucceeded(); void onDownloadFailed(QString reason); void onDownloadAborted(); @@ -99,7 +102,7 @@ private slots: void onModsDownloaded(); void onModsExtracted(); -private: + private: QString getDirForModType(ModType type, QString raw); QString getVersionForLoader(QString uid); QString detectLibrary(VersionLibrary library); @@ -111,15 +114,13 @@ private: void installConfigs(); void extractConfigs(); void downloadMods(); - bool extractMods( - const QMap &toExtract, - const QMap &toDecomp, - const QMap &toCopy - ); + bool extractMods(const QMap& toExtract, + const QMap& toDecomp, + const QMap& toCopy); void install(); -private: - UserInteractionSupport *m_support; + private: + UserInteractionSupport* m_support; bool abortable = false; @@ -146,7 +147,6 @@ private: QFuture m_modExtractFuture; QFutureWatcher m_modExtractFutureWatcher; - }; -} +} // namespace ATLauncher diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index 81c94e1b5..6df1eaf98 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -71,6 +71,7 @@ void ModrinthHasher::executeTask() emitFailed("Empty hash!"); } else { emitSucceeded(); + emit getResults(m_hash); } } @@ -91,10 +92,9 @@ void FlameHasher::executeTask() } } - -BlockedModHasher::BlockedModHasher(QString file_path, ModPlatform::ResourceProvider provider) - : Hasher(file_path), provider(provider) { - setObjectName(QString("BlockedModHasher: %1").arg(file_path)); +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(); } @@ -123,11 +123,13 @@ void BlockedModHasher::executeTask() } } -QStringList BlockedModHasher::getHashTypes() { +QStringList BlockedModHasher::getHashTypes() +{ return ProviderCaps.hashType(provider); } -bool BlockedModHasher::useHashType(QString type) { +bool BlockedModHasher::useHashType(QString type) +{ auto types = ProviderCaps.hashType(provider); if (types.contains(type)) { hash_type = type; diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index 91146a525..f3b9e0302 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" @@ -8,6 +9,7 @@ namespace Hashing { class Hasher : public Task { + Q_OBJECT public: using Ptr = shared_qobject_ptr; @@ -21,6 +23,9 @@ class Hasher : public Task { QString getResult() const { return m_hash; }; QString getPath() const { return m_path; }; + signals: + void getResults(QString hash); + protected: QString m_hash; QString m_path; @@ -48,6 +53,7 @@ class BlockedModHasher : public Hasher { QStringList getHashTypes(); bool useHashType(QString type); + private: ModPlatform::ResourceProvider provider; QString hash_type; diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 6a3f12f9a..36002bad9 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -53,12 +53,11 @@ void ModrinthCheckUpdate::executeTask() // (though it will rarely happen, if at all) if (mod->metadata()->hash_format != best_hash_type) { auto hash_task = Hashing::createModrinthHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Task::succeeded, [&] { - QString hash(hash_task->getResult()); + connect(hash_task.get(), &Hashing::Hasher::getResults, [&hashes, &mappings, mod](QString hash) { hashes.append(hash); mappings.insert(hash, mod); }); - connect(hash_task.get(), &Task::failed, [this, hash_task] { failed("Failed to generate hash"); }); + connect(hash_task.get(), &Task::failed, [this] { failed("Failed to generate hash"); }); hashing_task.addTask(hash_task); } else { hashes.append(hash); diff --git a/launcher/ui/dialogs/NewsDialog.cpp b/launcher/ui/dialogs/NewsDialog.cpp index e1b5dd740..b646e3918 100644 --- a/launcher/ui/dialogs/NewsDialog.cpp +++ b/launcher/ui/dialogs/NewsDialog.cpp @@ -32,7 +32,7 @@ NewsDialog::~NewsDialog() void NewsDialog::selectedArticleChanged(const QString& new_title) { - auto const& article_entry = m_entries.constFind(new_title).value(); + auto article_entry = m_entries.constFind(new_title).value(); ui->articleTitleLabel->setText(QString("%2").arg(article_entry->link, new_title)); diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp index 2ab865295..c6b087d67 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp @@ -16,62 +16,49 @@ #include "AtlListModel.h" -#include #include +#include #include namespace Atl { -ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) -{ -} +ListModel::ListModel(QObject* parent) : QAbstractListModel(parent) {} -ListModel::~ListModel() -{ -} +ListModel::~ListModel() {} -int ListModel::rowCount(const QModelIndex &parent) const +int ListModel::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : modpacks.size(); } -int ListModel::columnCount(const QModelIndex &parent) const +int ListModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : 1; } -QVariant ListModel::data(const QModelIndex &index, int role) const +QVariant ListModel::data(const QModelIndex& index, int role) const { int pos = index.row(); - if(pos >= modpacks.size() || pos < 0 || !index.isValid()) - { + if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { return QString("INVALID INDEX %1").arg(pos); } ATLauncher::IndexedPack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { + if (role == Qt::DisplayRole) { return pack.name; - } - else if (role == Qt::ToolTipRole) - { + } else if (role == Qt::ToolTipRole) { return pack.name; - } - else if(role == Qt::DecorationRole) - { - if(m_logoMap.contains(pack.safeName)) - { + } else if (role == Qt::DecorationRole) { + if (m_logoMap.contains(pack.safeName)) { return (m_logoMap.value(pack.safeName)); } auto icon = APPLICATION->getThemedIcon("atlauncher-placeholder"); auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(pack.safeName.toLower()); - ((ListModel *)this)->requestLogo(pack.safeName, url); + ((ListModel*)this)->requestLogo(pack.safeName, url); return icon; - } - else if(role == Qt::UserRole) - { + } else if (role == Qt::UserRole) { QVariant v; v.setValue(pack); return v; @@ -102,7 +89,7 @@ void ListModel::requestFinished() QJsonParseError parse_error; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { + if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from ATL at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; return; @@ -111,26 +98,28 @@ void ListModel::requestFinished() QList newList; auto packs = doc.array(); - for(auto packRaw : packs) { + for (auto packRaw : packs) { auto packObj = packRaw.toObject(); ATLauncher::IndexedPack pack; try { ATLauncher::loadIndexedPack(pack, packObj); - } - catch (const JSONValidationError &e) { + } catch (const JSONValidationError& e) { qDebug() << QString::fromUtf8(*response); qWarning() << "Error while reading pack manifest from ATLauncher: " << e.cause(); return; } // ignore packs without a published version - if(pack.versions.length() == 0) continue; + if (pack.versions.length() == 0) + continue; // only display public packs (for now) - if(pack.type != ATLauncher::PackType::Public) continue; + if (pack.type != ATLauncher::PackType::Public) + continue; // ignore "system" packs (Vanilla, Vanilla with Forge, etc) - if(pack.system) continue; + if (pack.system) + continue; newList.append(pack); } @@ -145,14 +134,12 @@ void ListModel::requestFailed(QString reason) jobPtr.reset(); } -void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback) +void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback) { - if(m_logoMap.contains(logo)) - { - callback(APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); - } - else - { + if (m_logoMap.contains(logo)) { + callback( + APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + } else { requestLogo(logo, logoUrl); } } @@ -168,36 +155,34 @@ void ListModel::logoLoaded(QString logo, QIcon out) m_loadingLogos.removeAll(logo); m_logoMap.insert(logo, out); - for(int i = 0; i < modpacks.size(); i++) { - if(modpacks[i].safeName == logo) { - emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); + for (int i = 0; i < modpacks.size(); i++) { + if (modpacks[i].safeName == logo) { + emit dataChanged(createIndex(i, 0), createIndex(i, 0), { Qt::DecorationRole }); } } } void ListModel::requestLogo(QString file, QString url) { - if(m_loadingLogos.contains(file) || m_failedLogos.contains(file)) - { + if (m_loadingLogos.contains(file) || m_failedLogos.contains(file)) { return; } MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0))); - NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file), APPLICATION->network()); + auto job = new NetJob(QString("ATLauncher Icon Download %1").arg(file), APPLICATION->network()); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::succeeded, this, [this, file, fullPath] - { + QObject::connect(job, &NetJob::succeeded, this, [this, file, fullPath, job] { + job->deleteLater(); emit logoLoaded(file, QIcon(fullPath)); - if(waitingCallbacks.contains(file)) - { + if (waitingCallbacks.contains(file)) { waitingCallbacks.value(file)(fullPath); } }); - QObject::connect(job, &NetJob::failed, this, [this, file] - { + QObject::connect(job, &NetJob::failed, this, [this, file, job] { + job->deleteLater(); emit logoFailed(file); }); @@ -206,4 +191,4 @@ void ListModel::requestLogo(QString file, QString url) m_loadingLogos.append(file); } -} +} // namespace Atl diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h index 37010b3ff..adeb53cbc 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h @@ -42,15 +42,15 @@ class AtlUserInteractionSupportImpl : public QObject, public ATLauncher::UserInteractionSupport { Q_OBJECT -public: + public: AtlUserInteractionSupportImpl(QWidget* parent); + virtual ~AtlUserInteractionSupportImpl() = default; -private: + private: QString chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) override; std::optional> chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) override; void displayMessage(QString message) override; -private: + private: QWidget* m_parent; - }; diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index 2343b79f2..a3e292015 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -35,14 +35,15 @@ #include "ListModel.h" #include "Application.h" +#include "QObjectPtr.h" #include "net/HttpMetaCache.h" #include "net/NetJob.h" -#include "StringUtils.h" #include +#include "StringUtils.h" -#include #include +#include #include @@ -50,33 +51,33 @@ namespace LegacyFTB { -FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent) +FilterModel::FilterModel(QObject* parent) : QSortFilterProxyModel(parent) { currentSorting = Sorting::ByGameVersion; sortings.insert(tr("Sort by Name"), Sorting::ByName); sortings.insert(tr("Sort by Game Version"), Sorting::ByGameVersion); } -bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value(); Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value(); - if(currentSorting == Sorting::ByGameVersion) { + if (currentSorting == Sorting::ByGameVersion) { Version lv(leftPack.mcVersion); Version rv(rightPack.mcVersion); return lv < rv; - } else if(currentSorting == Sorting::ByName) { + } else if (currentSorting == Sorting::ByName) { return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; } - //UHM, some inavlid value set?! + // UHM, some inavlid value set?! qWarning() << "Invalid sorting set!"; return true; } -bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { return true; } @@ -102,18 +103,13 @@ FilterModel::Sorting FilterModel::getCurrentSorting() return currentSorting; } -ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) -{ -} +ListModel::ListModel(QObject* parent) : QAbstractListModel(parent) {} -ListModel::~ListModel() -{ -} +ListModel::~ListModel() {} QString ListModel::translatePackType(PackType type) const { - switch(type) - { + switch (type) { case PackType::Public: return tr("Public Modpack"); case PackType::ThirdParty: @@ -125,67 +121,51 @@ QString ListModel::translatePackType(PackType type) const return QString(); } -int ListModel::rowCount(const QModelIndex &parent) const +int ListModel::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : modpacks.size(); } -int ListModel::columnCount(const QModelIndex &parent) const +int ListModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : 1; } -QVariant ListModel::data(const QModelIndex &index, int role) const +QVariant ListModel::data(const QModelIndex& index, int role) const { int pos = index.row(); - if(pos >= modpacks.size() || pos < 0 || !index.isValid()) - { + if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { return QString("INVALID INDEX %1").arg(pos); } Modpack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { + if (role == Qt::DisplayRole) { return pack.name + "\n" + translatePackType(pack.type); - } - else if (role == Qt::ToolTipRole) - { - if(pack.description.length() > 100) - { - //some magic to prevent to long tooltips and replace html linebreaks + } else if (role == Qt::ToolTipRole) { + if (pack.description.length() > 100) { + // some magic to prevent to long tooltips and replace html linebreaks QString edit = pack.description.left(97); edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); return edit; - } return pack.description; - } - else if(role == Qt::DecorationRole) - { - if(m_logoMap.contains(pack.logo)) - { + } else if (role == Qt::DecorationRole) { + if (m_logoMap.contains(pack.logo)) { return (m_logoMap.value(pack.logo)); } QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); - ((ListModel *)this)->requestLogo(pack.logo); + ((ListModel*)this)->requestLogo(pack.logo); return icon; - } - else if(role == Qt::ForegroundRole) - { - if(pack.broken) - { - //FIXME: Hardcoded color + } else if (role == Qt::ForegroundRole) { + if (pack.broken) { + // FIXME: Hardcoded color return QColor(255, 0, 50); - } - else if(pack.bugged) - { - //FIXME: Hardcoded color - //bugged pack, currently only indicates bugged xml + } else if (pack.bugged) { + // FIXME: Hardcoded color + // bugged pack, currently only indicates bugged xml return QColor(244, 229, 66); } - } - else if(role == Qt::UserRole) - { + } else if (role == Qt::UserRole) { QVariant v; v.setValue(pack); return v; @@ -222,8 +202,7 @@ Modpack ListModel::at(int row) void ListModel::remove(int row) { - if(row < 0 || row >= modpacks.size()) - { + if (row < 0 || row >= modpacks.size()) { qWarning() << "Attempt to remove FTB modpacks with invalid row" << row; return; } @@ -247,27 +226,25 @@ void ListModel::logoFailed(QString logo) void ListModel::requestLogo(QString file) { - if(m_loadingLogos.contains(file) || m_failedLogos.contains(file)) - { + if (m_loadingLogos.contains(file) || m_failedLogos.contains(file)) { return; } MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0))); - NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file), APPLICATION->network()); + NetJob* job = new NetJob(QString("FTB Icon Download for %1").arg(file), APPLICATION->network()); job->addNetAction(Net::Download::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry)); auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::finished, this, [this, file, fullPath] - { + QObject::connect(job, &NetJob::finished, this, [this, file, fullPath, job] { + job->deleteLater(); emit logoLoaded(file, QIcon(fullPath)); - if(waitingCallbacks.contains(file)) - { + if (waitingCallbacks.contains(file)) { waitingCallbacks.value(file)(fullPath); } }); - QObject::connect(job, &NetJob::failed, this, [this, file] - { + QObject::connect(job, &NetJob::failed, this, [this, file, job] { + job->deleteLater(); emit logoFailed(file); }); @@ -276,21 +253,18 @@ void ListModel::requestLogo(QString file) m_loadingLogos.append(file); } -void ListModel::getLogo(const QString &logo, LogoCallback callback) +void ListModel::getLogo(const QString& logo, LogoCallback callback) { - if(m_logoMap.contains(logo)) - { + if (m_logoMap.contains(logo)) { callback(APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); - } - else - { + } else { requestLogo(logo); } } -Qt::ItemFlags ListModel::flags(const QModelIndex &index) const +Qt::ItemFlags ListModel::flags(const QModelIndex& index) const { return QAbstractListModel::flags(index); } -} +} // namespace LegacyFTB diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp index 7975fd583..f08eb2897 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp @@ -40,39 +40,28 @@ #include -Technic::ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) -{ -} +Technic::ListModel::ListModel(QObject* parent) : QAbstractListModel(parent) {} -Technic::ListModel::~ListModel() -{ -} +Technic::ListModel::~ListModel() {} QVariant Technic::ListModel::data(const QModelIndex& index, int role) const { int pos = index.row(); - if(pos >= modpacks.size() || pos < 0 || !index.isValid()) - { + if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { return QString("INVALID INDEX %1").arg(pos); } Modpack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { + if (role == Qt::DisplayRole) { return pack.name; - } - else if(role == Qt::DecorationRole) - { - if(m_logoMap.contains(pack.logoName)) - { + } else if (role == Qt::DecorationRole) { + if (m_logoMap.contains(pack.logoName)) { return (m_logoMap.value(pack.logoName)); } QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); - ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); + ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; - } - else if(role == Qt::UserRole) - { + } else if (role == Qt::UserRole) { QVariant v; v.setValue(pack); return v; @@ -92,16 +81,15 @@ int Technic::ListModel::rowCount(const QModelIndex& parent) const void Technic::ListModel::searchWithTerm(const QString& term) { - if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) { + if (currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) { return; } currentSearchTerm = term; - if(jobPtr) { + if (jobPtr) { jobPtr->abort(); searchState = ResetRequested; return; - } - else { + } else { beginResetModel(); modpacks.clear(); endResetModel(); @@ -115,23 +103,17 @@ void Technic::ListModel::performSearch() auto netJob = makeShared("Technic::Search", APPLICATION->network()); QString searchUrl = ""; if (currentSearchTerm.isEmpty()) { - searchUrl = QString("%1trending?build=%2") - .arg(BuildConfig.TECHNIC_API_BASE_URL, BuildConfig.TECHNIC_API_BUILD); + searchUrl = QString("%1trending?build=%2").arg(BuildConfig.TECHNIC_API_BASE_URL, BuildConfig.TECHNIC_API_BUILD); searchMode = List; - } - else if (currentSearchTerm.startsWith("http://api.technicpack.net/modpack/")) { - searchUrl = QString("https://%1?build=%2") - .arg(currentSearchTerm.mid(7), BuildConfig.TECHNIC_API_BUILD); + } else if (currentSearchTerm.startsWith("http://api.technicpack.net/modpack/")) { + searchUrl = QString("https://%1?build=%2").arg(currentSearchTerm.mid(7), BuildConfig.TECHNIC_API_BUILD); searchMode = Single; - } - else if (currentSearchTerm.startsWith("https://api.technicpack.net/modpack/")) { + } else if (currentSearchTerm.startsWith("https://api.technicpack.net/modpack/")) { searchUrl = QString("%1?build=%2").arg(currentSearchTerm, BuildConfig.TECHNIC_API_BUILD); searchMode = Single; - } - else { - searchUrl = QString( - "%1search?build=%2&q=%3" - ).arg(BuildConfig.TECHNIC_API_BASE_URL, BuildConfig.TECHNIC_API_BUILD, currentSearchTerm); + } else { + searchUrl = + QString("%1search?build=%2&q=%3").arg(BuildConfig.TECHNIC_API_BASE_URL, BuildConfig.TECHNIC_API_BUILD, currentSearchTerm); searchMode = List; } netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); @@ -161,7 +143,7 @@ void Technic::ListModel::searchRequestFinished() switch (searchMode) { case List: { auto objs = Json::requireArray(root, "modpacks"); - for (auto technicPack: objs) { + for (auto technicPack : objs) { Modpack pack; auto technicPackObject = Json::requireObject(technicPack); pack.name = Json::requireString(technicPackObject, "name"); @@ -170,11 +152,10 @@ void Technic::ListModel::searchRequestFinished() continue; auto rawURL = Json::ensureString(technicPackObject, "iconUrl", "null"); - if(rawURL == "null") { + if (rawURL == "null") { pack.logoUrl = "null"; pack.logoName = "null"; - } - else { + } else { pack.logoUrl = rawURL; pack.logoName = rawURL.section(QLatin1Char('/'), -1).section(QLatin1Char('.'), 0, 0); } @@ -199,8 +180,7 @@ void Technic::ListModel::searchRequestFinished() pack.logoUrl = iconUrl; pack.logoName = iconUrl.section(QLatin1Char('/'), -1).section(QLatin1Char('.'), 0, 0); - } - else { + } else { pack.logoUrl = "null"; pack.logoName = "null"; } @@ -210,10 +190,8 @@ void Technic::ListModel::searchRequestFinished() break; } } - } - catch (const JSONValidationError &err) - { - qCritical() << "Couldn't parse technic search results:" << err.cause() ; + } catch (const JSONValidationError& err) { + qCritical() << "Couldn't parse technic search results:" << err.cause(); return; } searchState = Finished; @@ -229,12 +207,9 @@ void Technic::ListModel::searchRequestFinished() void Technic::ListModel::getLogo(const QString& logo, const QString& logoUrl, Technic::LogoCallback callback) { - if(m_logoMap.contains(logo)) - { + if (m_logoMap.contains(logo)) { callback(APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath()); - } - else - { + } else { requestLogo(logo, logoUrl); } } @@ -243,30 +218,24 @@ void Technic::ListModel::searchRequestFailed() { jobPtr.reset(); - if(searchState == ResetRequested) - { + if (searchState == ResetRequested) { beginResetModel(); modpacks.clear(); endResetModel(); performSearch(); - } - else - { + } else { searchState = Finished; } } - void Technic::ListModel::logoLoaded(QString logo, QString out) { m_loadingLogos.removeAll(logo); m_logoMap.insert(logo, QIcon(out)); - for(int i = 0; i < modpacks.size(); i++) - { - if(modpacks[i].logoName == logo) - { - emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); + for (int i = 0; i < modpacks.size(); i++) { + if (modpacks[i].logoName == logo) { + emit dataChanged(createIndex(i, 0), createIndex(i, 0), { Qt::DecorationRole }); } } } @@ -279,24 +248,23 @@ void Technic::ListModel::logoFailed(QString logo) void Technic::ListModel::requestLogo(QString logo, QString url) { - if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo) || logo == "null") - { + if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo) || logo == "null") { return; } MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo)); - NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo), APPLICATION->network()); + auto job = new NetJob(QString("Technic Icon Download %1").arg(logo), APPLICATION->network()); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath] - { + QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] { + job->deleteLater(); logoLoaded(logo, fullPath); }); - QObject::connect(job, &NetJob::failed, this, [this, logo] - { + QObject::connect(job, &NetJob::failed, this, [this, logo, job] { + job->deleteLater(); logoFailed(logo); }); From 4e66f55d8426559942d92e61556747528be03cdf Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 18 Jun 2023 23:32:17 +0300 Subject: [PATCH 135/429] Removed extra headers Signed-off-by: Trial97 --- launcher/modplatform/helpers/HashUtils.h | 1 - launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index f3b9e0302..a541ae8fa 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include "modplatform/ModIndex.h" diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index a3e292015..330dd4fb8 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -35,7 +35,6 @@ #include "ListModel.h" #include "Application.h" -#include "QObjectPtr.h" #include "net/HttpMetaCache.h" #include "net/NetJob.h" From 1bdde1f947f57801f2fcb1a0f881f19bd8e1e29d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 00:36:37 +0300 Subject: [PATCH 136/429] Small fixes Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 61 ++++++++++--------- .../mod/tasks/GetModDependenciesTask.h | 2 +- launcher/modplatform/ModIndex.h | 2 +- launcher/modplatform/ResourceAPI.h | 8 --- launcher/modplatform/flame/FlameModIndex.cpp | 12 ++-- .../modrinth/ModrinthPackIndex.cpp | 10 +-- .../ui/dialogs/ResourceDownloadDialog.cpp | 10 +-- 7 files changed, 54 insertions(+), 51 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index bd80a6611..54116e288 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -33,7 +33,7 @@ #include "ui/pages/modplatform/flame/FlameResourceModels.h" #include "ui/pages/modplatform/modrinth/ModrinthResourceModels.h" -static Version mcVersions(BaseInstance* inst) +static Version mcVersion(BaseInstance* inst) { return static_cast(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion(); } @@ -53,7 +53,7 @@ GetModDependenciesTask::GetModDependenciesTask(QObject* parent, std::make_shared() } , m_modrinth_provider{ ModPlatform::ResourceProvider::MODRINTH, std::make_shared(*instance), std::make_shared() } - , m_version(mcVersions(instance)) + , m_version(mcVersion(instance)) , m_loaderType(mcLoaders(instance)) { for (auto mod : folder->allMods()) @@ -74,33 +74,38 @@ void GetModDependenciesTask::prepare() QList GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version, const ModPlatform::ResourceProvider providerName) { - auto c_dependencies = QList(); + QList c_dependencies; for (auto ver_dep : version.dependencies) { - if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) { - if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), - [&ver_dep](const ModPlatform::Dependency& i) { return i.addonId == ver_dep.addonId; }); - dep == c_dependencies.end()) { // check the current dependency list - if (auto dep = std::find_if(m_selected.begin(), m_selected.end(), - [&ver_dep, providerName](std::shared_ptr i) { - return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; - }); - dep == m_selected.end()) { // check the selected versions - if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), - [&ver_dep, providerName](std::shared_ptr i) { - return i->project_id == ver_dep.addonId && i->provider == providerName; - }); - dep == m_mods.end()) { // check the existing mods - if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(), - [&ver_dep, providerName](std::shared_ptr i) { - return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; - }); - dep == m_pack_dependencies.end()) { // check loaded dependencies - c_dependencies.append(ver_dep); - } - } - } - } - } + if (ver_dep.type != ModPlatform::DependencyType::REQUIRED) + continue; + + if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), + [&ver_dep](const ModPlatform::Dependency& i) { return i.addonId == ver_dep.addonId; }); + dep != c_dependencies.end()) + continue; // check the current dependency list + + if (auto dep = std::find_if(m_selected.begin(), m_selected.end(), + [&ver_dep, providerName](std::shared_ptr i) { + return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; + }); + dep != m_selected.end()) + continue; // check the selected versions + + if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), + [&ver_dep, providerName](std::shared_ptr i) { + return i->project_id == ver_dep.addonId && i->provider == providerName; + }); + dep != m_mods.end()) + continue; // check the existing mods + + if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(), + [&ver_dep, providerName](std::shared_ptr i) { + return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; + }); + dep != m_pack_dependencies.end()) // check loaded dependencies + continue; + + c_dependencies.append(ver_dep); } return c_dependencies; }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 3824e7816..99d5afb03 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -42,7 +42,7 @@ class GetModDependenciesTask : public SequentialTask { ModPlatform::Dependency dependency; ModPlatform::IndexedPack::Ptr pack; ModPlatform::IndexedVersion version; - PackDependency(){}; + PackDependency() = default; PackDependency(const ModPlatform::IndexedPack::Ptr p, const ModPlatform::IndexedVersion& v) { pack = p; diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 64b440550..7236e63eb 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -34,7 +34,7 @@ enum class ResourceProvider { MODRINTH, FLAME }; enum class ResourceType { MOD, RESOURCE_PACK, SHADER_PACK }; -enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE }; +enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN }; class ProviderCapabilities { public: diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index c23444b3a..63b917f16 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -115,14 +115,6 @@ class ResourceAPI { ModPlatform::Dependency dependency; Version mcVersion; ModLoaderTypes loader; - - DependencySearchArgs(DependencySearchArgs const&) = default; - void operator=(DependencySearchArgs other) - { - dependency = other.dependency; - mcVersion = other.mcVersion; - loader = other.loader; - } }; struct DependencySearchCallbacks { diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 120bfc91d..9c8eb832a 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -160,6 +160,10 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> case 6: // Include dependency.type = ModPlatform::DependencyType::INCLUDE; break; + default: + dependency.type = ModPlatform::DependencyType::UNKNOWN; + break; + } file.dependencies.append(dependency); } @@ -172,7 +176,7 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) { - QVector unsortedVersions; + QVector versions; for (auto versionIter : arr) { auto obj = versionIter.toObject(); @@ -181,13 +185,13 @@ ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform:: file.addonId = m.addonId; if (file.fileId.isValid()) // Heuristic to check if the returned value is valid - unsortedVersions.append(file); + versions.append(file); } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { // dates are in RFC 3339 format return a.date > b.date; }; - std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); - return unsortedVersions.front(); + std::sort(versions.begin(), versions.end(), orderSortPredicate); + return versions.front(); }; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 879260a3f..92b48e5f1 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -156,6 +156,8 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t dependency.type = ModPlatform::DependencyType::INCOMPATIBLE; else if (depType == "embedded") dependency.type = ModPlatform::DependencyType::EMBEDDED; + else + dependency.type = ModPlatform::DependencyType::UNKNOWN; file.dependencies.append(dependency); } @@ -218,19 +220,19 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t auto Modrinth::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion { - QVector unsortedVersions; + QVector versions; for (auto versionIter : arr) { auto obj = versionIter.toObject(); auto file = loadIndexedPackVersion(obj); if (file.fileId.isValid()) // Heuristic to check if the returned value is valid - unsortedVersions.append(file); + versions.append(file); } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { // dates are in RFC 3339 format return a.date > b.date; }; - std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); - return unsortedVersions.length() != 0 ? unsortedVersions.front() : ModPlatform::IndexedVersion(); + std::sort(versions.begin(), versions.end(), orderSortPredicate); + return versions.length() != 0 ? versions.front() : ModPlatform::IndexedVersion(); } \ No newline at end of file diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 819cf7de9..c7d9da4e0 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -125,7 +125,7 @@ void ResourceDownloadDialog::connectButtons() static ModPlatform::ProviderCapabilities ProviderCaps; -QStringList getReqiredBy(QList tasks, QVariant addonId) +QStringList getRequiredBy(QList tasks, QVariant addonId) { auto req = QStringList(); for (auto& task : tasks) { @@ -167,10 +167,10 @@ void ResourceDownloadDialog::confirm() if (ret == QDialog::DialogCode::Rejected) { QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection); return; - } else - for (auto dep : task->getDependecies()) { + } else { + for (auto dep : task->getDependecies()) addResource(dep->pack, dep->version); - } + } } auto selected = getTasks(); @@ -179,7 +179,7 @@ void ResourceDownloadDialog::confirm() }); for (auto& task : selected) { confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(), - ProviderCaps.name(task->getProvider()), getReqiredBy(selected, task->getPack()->addonId) }); + ProviderCaps.name(task->getProvider()), getRequiredBy(selected, task->getPack()->addonId) }); } if (confirm_dialog->exec()) { From 555cb40efdec7edf6ea66d0177f3c77a6eb29063 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Sun, 18 Jun 2023 14:45:35 +0200 Subject: [PATCH 137/429] chore: install appstream in appimage Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 90b6cc76e..b83259b4b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -191,7 +191,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get -y update - sudo apt-get -y install ninja-build extra-cmake-modules scdoc + sudo apt-get -y install ninja-build extra-cmake-modules scdoc appstream - name: Install Dependencies (macOS) if: runner.os == 'macOS' From d5b5f0503cc8d88809f82afc9407f89a4af604c6 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Sun, 18 Jun 2023 15:10:11 +0200 Subject: [PATCH 138/429] chore: change xml name to what linuxdeploy wants Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b83259b4b..c2966abe7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -468,7 +468,8 @@ jobs: shell: bash run: | cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr - + mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.appdata.xml + export "NO_APPSTREAM=1" # we have to skip appstream checking because appstream on ubuntu 20.04 is outdated export OUTPUT="PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage" chmod +x linuxdeploy-*.AppImage From 3ee0fec7298d467d5b8b48a5144794f58bc2ce28 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 12:22:22 +0300 Subject: [PATCH 139/429] Removed mods from lambda Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 1d090ef4d..90e7d0d62 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -100,7 +100,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); connect(mods.get(), &ModFolderModel::updateFinished, this, - [this, check_allow_update, mods] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); connect(m_instance, &BaseInstance::runningStatusChanged, this, &ModFolderPage::runningStateChanged); ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning()); From d02858040ef0d1f691b3456bb0ac271c484a7c57 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 13:09:37 +0300 Subject: [PATCH 140/429] Fixes #1212 Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ModPage.cpp | 16 +++++----- .../ui/pages/modplatform/ResourcePage.cpp | 31 +++++++++++-------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 95064d16a..60a43128a 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -89,17 +89,13 @@ 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(); - if (changed) { - m_ui->packView->clearSelection(); - m_ui->packDescription->clear(); - m_ui->versionSelectionBox->clear(); - updateSelectionButton(); - } - - static_cast(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt(), changed); + static_cast(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt(), m_filter_widget->changed()); m_fetch_progress.watch(m_model->activeSearchJob().get()); } @@ -122,6 +118,8 @@ void ModPage::updateVersionList() QString mcVersion = packProfile->getComponentVersion("net.minecraft"); 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; diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 1d2509d80..aab2ee89a 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -174,7 +174,11 @@ ModPlatform::IndexedPack::Ptr ResourcePage::getCurrentPack() const void ResourcePage::updateUi() { auto current_pack = getCurrentPack(); - + if (!current_pack) { + m_ui->packDescription->setHtml({}); + m_ui->packDescription->flush(); + return; + } QString text = ""; QString name = current_pack->name; @@ -240,8 +244,8 @@ void ResourcePage::updateSelectionButton() } m_ui->resourceSelectionButton->setEnabled(true); - if (getCurrentPack()) { - if (!getCurrentPack()->isVersionSelected(m_selected_version_index)) + if (auto current_pack = getCurrentPack(); current_pack) { + if (!current_pack->isVersionSelected(m_selected_version_index)) m_ui->resourceSelectionButton->setText(tr("Select %1 for download").arg(resourceString())); else m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString())); @@ -258,13 +262,14 @@ void ResourcePage::updateVersionList() m_ui->versionSelectionBox->clear(); m_ui->versionSelectionBox->blockSignals(false); - for (int i = 0; i < current_pack->versions.size(); i++) { - auto& version = current_pack->versions[i]; - if (optedOut(version)) - continue; + if (current_pack) + for (int i = 0; i < current_pack->versions.size(); i++) { + auto& version = current_pack->versions[i]; + if (optedOut(version)) + continue; - m_ui->versionSelectionBox->addItem(current_pack->versions[i].version, QVariant(i)); - } + m_ui->versionSelectionBox->addItem(current_pack->versions[i].version, QVariant(i)); + } if (m_ui->versionSelectionBox->count() == 0) { m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1)); @@ -283,7 +288,7 @@ void ResourcePage::onSelectionChanged(QModelIndex curr, QModelIndex prev) auto current_pack = getCurrentPack(); bool request_load = false; - if (!current_pack->versionsLoaded) { + if (!current_pack || !current_pack->versionsLoaded) { m_ui->resourceSelectionButton->setText(tr("Loading versions...")); m_ui->resourceSelectionButton->setEnabled(false); @@ -292,7 +297,7 @@ void ResourcePage::onSelectionChanged(QModelIndex curr, QModelIndex prev) updateVersionList(); } - if (!current_pack->extraDataLoaded) + if (current_pack && !current_pack->extraDataLoaded) request_load = true; if (request_load) @@ -340,7 +345,7 @@ void ResourcePage::onResourceSelected() return; auto current_pack = getCurrentPack(); - if (!current_pack->versionsLoaded) + if (!current_pack || !current_pack->versionsLoaded) return; auto& version = current_pack->versions[m_selected_version_index]; @@ -386,7 +391,7 @@ void ResourcePage::openUrl(const QUrl& url) const QString slug = match.captured(1); // ensure the user isn't opening the same mod - if (slug != getCurrentPack()->slug) { + if (auto current_pack = getCurrentPack(); current_pack && slug != current_pack->slug) { m_parent_dialog->selectPage(page); auto newPage = m_parent_dialog->getSelectedPage(); From 8ad9692daab303bba6f5337f6660d8437ec8f330 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 14:10:29 +0300 Subject: [PATCH 141/429] Changed qWarning to qDebug for raw data Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 54116e288..274ff3c9e 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -132,7 +132,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *responseInfo; + qDebug() << *responseInfo; return; } try { From 6fd729e285f67c74633d27575717070f3577a132 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 17:42:16 +0300 Subject: [PATCH 142/429] Fixed regresion regarding modrinth project_id in dependence array Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 63 ++++++++++++------- .../mod/tasks/GetModDependenciesTask.h | 1 + .../modrinth/ModrinthPackIndex.cpp | 2 +- .../ui/dialogs/ResourceDownloadDialog.cpp | 16 +++-- 4 files changed, 55 insertions(+), 27 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 274ff3c9e..02281a355 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -79,28 +79,34 @@ QList GetModDependenciesTask::getDependenciesForVersion if (ver_dep.type != ModPlatform::DependencyType::REQUIRED) continue; + auto isOnlyVersion = providerName == ModPlatform::ResourceProvider::MODRINTH && ver_dep.addonId.toString().isEmpty(); if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(), - [&ver_dep](const ModPlatform::Dependency& i) { return i.addonId == ver_dep.addonId; }); + [&ver_dep, isOnlyVersion](const ModPlatform::Dependency& i) { + return isOnlyVersion ? i.version == ver_dep.version : i.addonId == ver_dep.addonId; + }); dep != c_dependencies.end()) continue; // check the current dependency list if (auto dep = std::find_if(m_selected.begin(), m_selected.end(), - [&ver_dep, providerName](std::shared_ptr i) { - return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; + [&ver_dep, providerName, isOnlyVersion](std::shared_ptr i) { + return i->pack->provider == providerName && (isOnlyVersion ? i->version.version == ver_dep.version + : i->pack->addonId == ver_dep.addonId); }); dep != m_selected.end()) continue; // check the selected versions if (auto dep = std::find_if(m_mods.begin(), m_mods.end(), - [&ver_dep, providerName](std::shared_ptr i) { - return i->project_id == ver_dep.addonId && i->provider == providerName; + [&ver_dep, providerName, isOnlyVersion](std::shared_ptr i) { + return i->provider == providerName && + (isOnlyVersion ? i->file_id == ver_dep.version : i->project_id == ver_dep.addonId); }); dep != m_mods.end()) continue; // check the existing mods if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(), - [&ver_dep, providerName](std::shared_ptr i) { - return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName; + [&ver_dep, providerName, isOnlyVersion](std::shared_ptr i) { + return i->pack->provider == providerName && (isOnlyVersion ? i->version.version == ver_dep.addonId + : i->pack->addonId == ver_dep.addonId); }); dep != m_pack_dependencies.end()) // check loaded dependencies continue; @@ -110,22 +116,11 @@ QList GetModDependenciesTask::getDependenciesForVersion return c_dependencies; }; -Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Dependency& dep, - const ModPlatform::ResourceProvider providerName, - int level) +Task::Ptr GetModDependenciesTask::getProjectInfoTask(std::shared_ptr pDep) { - auto pDep = std::make_shared(); - pDep->dependency = dep; - pDep->pack = std::make_shared(); - pDep->pack->addonId = dep.addonId; - pDep->pack->provider = providerName; - m_pack_dependencies.append(pDep); - auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; - - auto tasks = makeShared(this, QString("DependencyInfo: %1").arg(dep.addonId.toString())); - + auto provider = pDep->pack->provider == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; auto responseInfo = new QByteArray(); - auto info = provider.api->getProject(dep.addonId.toString(), responseInfo); + auto info = provider.api->getProject(pDep->pack->addonId.toString(), responseInfo); QObject::connect(info.get(), &NetJob::succeeded, [responseInfo, provider, pDep] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*responseInfo, &parse_error); @@ -144,7 +139,27 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen qWarning() << "Error while reading mod info: " << e.cause(); } }); - tasks->addTask(info); + return info; +} + +Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Dependency& dep, + const ModPlatform::ResourceProvider providerName, + int level) +{ + auto pDep = std::make_shared(); + pDep->dependency = dep; + pDep->pack = std::make_shared(); + pDep->pack->addonId = dep.addonId; + pDep->pack->provider = providerName; + m_pack_dependencies.append(pDep); + auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; + + auto tasks = makeShared( + this, QString("DependencyInfo: %1").arg(dep.addonId.toString().isEmpty() ? dep.version : dep.addonId.toString())); + + if (!dep.addonId.toString().isEmpty()) { + tasks->addTask(getProjectInfoTask(pDep)); + } ResourceAPI::DependencySearchArgs args = { dep, m_version, m_loaderType }; ResourceAPI::DependencySearchCallbacks callbacks; @@ -176,6 +191,10 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen qWarning() << "Dependency cycle exeeded"; return; } + if (dep.addonId.toString().isEmpty() && !pDep->version.addonId.toString().isEmpty()) { + pDep->pack->addonId = pDep->version.addonId; + addTask(getProjectInfoTask(pDep)); + } for (auto dep : getDependenciesForVersion(pDep->version, provider.name)) { addTask(prepareDependencyTask(dep, provider.name, level - 1)); } diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 99d5afb03..f1876c613 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -68,6 +68,7 @@ class GetModDependenciesTask : public SequentialTask { QList getDependenciesForVersion(const ModPlatform::IndexedVersion&, const ModPlatform::ResourceProvider providerName); void prepare(); + Task::Ptr getProjectInfoTask(std::shared_ptr pDep); private: QList> m_pack_dependencies; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 92b48e5f1..b40373496 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -144,7 +144,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t for (auto d : dependencies) { auto dep = Json::ensureObject(d); ModPlatform::Dependency dependency; - dependency.addonId = Json::requireString(dep, "project_id"); + dependency.addonId = Json::ensureString(dep, "project_id"); dependency.version = Json::ensureString(dep, "version_id"); auto depType = Json::requireString(dep, "dependency_type"); diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index c7d9da4e0..4f59f5605 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -125,14 +125,22 @@ void ResourceDownloadDialog::connectButtons() static ModPlatform::ProviderCapabilities ProviderCaps; -QStringList getRequiredBy(QList tasks, QVariant addonId) +QStringList getRequiredBy(QList tasks, ResourceDownloadDialog::DownloadTaskPtr pack) { + auto addonId = pack->getPack()->addonId; + auto provider = pack->getPack()->provider; + auto version = pack->getVersionID(); auto req = QStringList(); for (auto& task : tasks) { + if (provider != task->getPack()->provider) + continue; auto deps = task->getVersion().dependencies; if (auto dep = std::find_if(deps.begin(), deps.end(), - [addonId](const ModPlatform::Dependency& d) { - return d.addonId == addonId && d.type == ModPlatform::DependencyType::REQUIRED; + [addonId, provider, version](const ModPlatform::Dependency& d) { + return d.type == ModPlatform::DependencyType::REQUIRED && + (provider == ModPlatform::ResourceProvider::MODRINTH && d.addonId.toString().isEmpty() + ? version == d.version + : d.addonId == addonId); }); dep != deps.end()) { req.append(task->getName()); @@ -179,7 +187,7 @@ void ResourceDownloadDialog::confirm() }); for (auto& task : selected) { confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(), - ProviderCaps.name(task->getProvider()), getRequiredBy(selected, task->getPack()->addonId) }); + ProviderCaps.name(task->getProvider()), getRequiredBy(selected, task) }); } if (confirm_dialog->exec()) { From c13a90540cf782debddd63f1d2da46e43ed48c7a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 21:20:35 +0300 Subject: [PATCH 143/429] Added overide for Quilt/Fabric Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 28 ++++++++++++++-- .../mod/tasks/GetModDependenciesTask.h | 1 + launcher/modplatform/ModIndex.h | 16 ++++++++++ launcher/modplatform/flame/FlameAPI.h | 32 ++++++++++++++++--- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 02281a355..093304b3d 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -25,11 +25,13 @@ #include "QObjectPtr.h" #include "minecraft/mod/MetadataHandler.h" #include "modplatform/ModIndex.h" +#include "modplatform/ResourceAPI.h" #include "modplatform/flame/FlameAPI.h" #include "modplatform/modrinth/ModrinthAPI.h" #include "tasks/ConcurrentTask.h" #include "tasks/SequentialTask.h" #include "ui/pages/modplatform/ModModel.h" +#include "ui/pages/modplatform/ResourceModel.h" #include "ui/pages/modplatform/flame/FlameResourceModels.h" #include "ui/pages/modplatform/modrinth/ModrinthResourceModels.h" @@ -71,6 +73,21 @@ void GetModDependenciesTask::prepare() } } +auto GetModDependenciesTask::getOverride(const ModPlatform::Dependency& dep, const ModPlatform::ResourceProvider providerName) + -> ModPlatform::Dependency +{ + if (auto isQuilt = m_loaderType & ResourceAPI::Quilt; isQuilt || m_loaderType & ResourceAPI::Fabric) { + auto overide = ModPlatform::getOverrideDeps(); + auto over = std::find_if(overide.cbegin(), overide.cend(), [dep, providerName, isQuilt](auto o) { + return o.provider == providerName && dep.addonId == (isQuilt ? o.fabric : o.quilt); + }); + if (over != overide.cend()) { + return { isQuilt ? over->quilt : over->fabric, dep.type }; + } + } + return dep; +} + QList GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version, const ModPlatform::ResourceProvider providerName) { @@ -111,7 +128,7 @@ QList GetModDependenciesTask::getDependenciesForVersion dep != m_pack_dependencies.end()) // check loaded dependencies continue; - c_dependencies.append(ver_dep); + c_dependencies.append(getOverride(ver_dep, providerName)); } return c_dependencies; }; @@ -151,6 +168,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen pDep->pack = std::make_shared(); pDep->pack->addonId = dep.addonId; pDep->pack->provider = providerName; + m_pack_dependencies.append(pDep); auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; @@ -193,7 +211,13 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen } if (dep.addonId.toString().isEmpty() && !pDep->version.addonId.toString().isEmpty()) { pDep->pack->addonId = pDep->version.addonId; - addTask(getProjectInfoTask(pDep)); + auto dep = getOverride({ pDep->version.addonId, pDep->dependency.type }, provider.name); + if (dep.addonId != pDep->version.addonId) { + auto toRemoveID = pDep->version.addonId; + m_pack_dependencies.removeIf([toRemoveID](auto v) { return v->pack->addonId == toRemoveID; }); + addTask(prepareDependencyTask(dep, provider.name, level)); + } else + addTask(getProjectInfoTask(pDep)); } for (auto dep : getDependenciesForVersion(pDep->version, provider.name)) { addTask(prepareDependencyTask(dep, provider.name, level - 1)); diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index f1876c613..7a4990f72 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -69,6 +69,7 @@ class GetModDependenciesTask : public SequentialTask { const ModPlatform::ResourceProvider providerName); void prepare(); Task::Ptr getProjectInfoTask(std::shared_ptr pDep); + auto getOverride(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider providerName) -> ModPlatform::Dependency; private: QList> m_pack_dependencies; diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 7236e63eb..3b0a03a18 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -129,6 +129,22 @@ struct IndexedPack { } }; +struct OverrideDep { + QString quilt; + QString fabric; + QString slug; + ModPlatform::ResourceProvider provider; +}; + +inline auto getOverrideDeps() -> QList +{ + return { { "634179", "306612", "API", ModPlatform::ResourceProvider::FLAME }, + { "720410", "308769", "KotlinLibraries", ModPlatform::ResourceProvider::FLAME }, + + { "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH }, + { "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } }; +}; + } // namespace ModPlatform Q_DECLARE_METATYPE(ModPlatform::IndexedPack) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 4ffc36d29..89561a895 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -4,7 +4,9 @@ #pragma once +#include #include "modplatform/ModIndex.h" +#include "modplatform/ResourceAPI.h" #include "modplatform/helpers/NetworkResourceAPI.h" class FlameAPI : public NetworkResourceAPI { @@ -74,22 +76,44 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getVersionsURL(VersionSearchArgs const& args) const override { - QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString()) }; + auto mappedModLoader = getMappedModLoader(args.loaders.value()); + auto addonId = args.pack.addonId.toString(); + if (args.loaders.value() & Quilt) { + auto overide = ModPlatform::getOverrideDeps(); + auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) { + return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt; + }); + if (over != overide.cend()) { + mappedModLoader = 5; + } + } + QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(addonId) }; QStringList get_parameters; if (args.mcVersions.has_value()) get_parameters.append(QString("gameVersion=%1").arg(args.mcVersions.value().front().toString())); if (args.loaders.has_value()) - get_parameters.append(QString("modLoaderType=%1").arg(getMappedModLoader(args.loaders.value()))); + get_parameters.append(QString("modLoaderType=%1").arg(mappedModLoader)); return url + get_parameters.join('&'); }; [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { + auto mappedModLoader = getMappedModLoader(args.loader); + auto addonId = args.dependency.addonId.toString(); + if (args.loader & Quilt) { + auto overide = ModPlatform::getOverrideDeps(); + auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) { + return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt; + }); + if (over != overide.cend()) { + mappedModLoader = 5; + } + } return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%3") - .arg(args.dependency.addonId.toString()) + .arg(addonId) .arg(args.mcVersion.toString()) - .arg(getMappedModLoader(args.loader)); + .arg(mappedModLoader); }; }; From f6f0fbbd9f16afad16b8a401f87d741eba4be677 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 21:23:48 +0300 Subject: [PATCH 144/429] Fixed removeIf Signed-off-by: Trial97 --- .../minecraft/mod/tasks/GetModDependenciesTask.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 093304b3d..93c7f2594 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -214,7 +214,17 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen auto dep = getOverride({ pDep->version.addonId, pDep->dependency.type }, provider.name); if (dep.addonId != pDep->version.addonId) { auto toRemoveID = pDep->version.addonId; - m_pack_dependencies.removeIf([toRemoveID](auto v) { return v->pack->addonId == toRemoveID; }); + + auto pred = [toRemoveID](auto v) { return v->pack->addonId == toRemoveID; }; +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) + m_pack_dependencies.removeIf(pred); +#else + for (auto it = m_pack_dependencies.begin(); it != m_pack_dependencies.end();) + if (pred(*it)) + it = m_pack_dependencies.erase(it); + else + ++it; +#endif addTask(prepareDependencyTask(dep, provider.name, level)); } else addTask(getProjectInfoTask(pDep)); From b62e4c0cc79d9d3074b37d879bb00df68c2973bc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jun 2023 21:32:19 +0300 Subject: [PATCH 145/429] Fixed build Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 6 +++--- launcher/minecraft/mod/tasks/GetModDependenciesTask.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 93c7f2594..00611f327 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -73,8 +73,8 @@ void GetModDependenciesTask::prepare() } } -auto GetModDependenciesTask::getOverride(const ModPlatform::Dependency& dep, const ModPlatform::ResourceProvider providerName) - -> ModPlatform::Dependency +ModPlatform::Dependency GetModDependenciesTask::getOverride(const ModPlatform::Dependency& dep, + const ModPlatform::ResourceProvider providerName) { if (auto isQuilt = m_loaderType & ResourceAPI::Quilt; isQuilt || m_loaderType & ResourceAPI::Fabric) { auto overide = ModPlatform::getOverrideDeps(); @@ -215,7 +215,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen if (dep.addonId != pDep->version.addonId) { auto toRemoveID = pDep->version.addonId; - auto pred = [toRemoveID](auto v) { return v->pack->addonId == toRemoveID; }; + auto pred = [toRemoveID](const std::shared_ptr& v) { return v->pack->addonId == toRemoveID; }; #if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) m_pack_dependencies.removeIf(pred); #else diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index 7a4990f72..e2ad48250 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -69,7 +69,7 @@ class GetModDependenciesTask : public SequentialTask { const ModPlatform::ResourceProvider providerName); void prepare(); Task::Ptr getProjectInfoTask(std::shared_ptr pDep); - auto getOverride(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider providerName) -> ModPlatform::Dependency; + ModPlatform::Dependency getOverride(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider providerName); private: QList> m_pack_dependencies; From d9b24f770561e3bb139955854ac7f3ca4d92a122 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 16:52:57 +1200 Subject: [PATCH 146/429] Screenshots: remove path from watcher if it no longer exists Signed-off-by: James Beddek --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index ca368d3b7..8f134efd3 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -145,7 +145,6 @@ public: m_thumbnailCache = std::make_shared(); m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); - // FIXME: the watched file set is not updated when files are removed } virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); } virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const @@ -214,10 +213,12 @@ private slots: void fileChanged(QString filepath) { m_thumbnailCache->setStale(filepath); - thumbnailImage(filepath); // reinsert the path... watcher.removePath(filepath); - watcher.addPath(filepath); + if (QFile::exists(filepath)) { + watcher.addPath(filepath); + thumbnailImage(filepath); + } } private: From f2471f0f68e436d25d27ccc750e6668c07a29070 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 16:54:15 +1200 Subject: [PATCH 147/429] Screenshots: clear the thumbnailing pool on page delete Removes pending QThreadPool jobs which linger after page delete. May help with #1201 by allowing the pool to finish earlier. Signed-off-by: James Beddek --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 8f134efd3..9d1f8421c 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -146,7 +146,11 @@ public: m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); } - virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); } + virtual ~FilterModel() { + m_thumbnailingPool.clear(); + if (!m_thumbnailingPool.waitForDone(500)) + qDebug() << "Thumbnail pool took longer than 500ms to finish"; + } virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const { auto model = sourceModel(); From 75bd626f33a5182facff2ef1f9938f60553c3352 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 16:59:59 +1200 Subject: [PATCH 148/429] Screenshots: do not retry image thumbnailing on null result This causes the thumbnailing thread pool to spend a lot of time attempting to retry an image that failed. A null result is common where the image is too large to be allocated (>128MiB alloc). The repeated retries continue after page delete, causing hangs if a user tries to exit the application. Fixes: #1201 Signed-off-by: James Beddek --- .../ui/pages/instance/ScreenshotsPage.cpp | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 9d1f8421c..75bb48b2d 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -96,37 +96,30 @@ public: return; if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0)) return; - int tries = 5; - while (tries) - { - if (!m_cache->stale(m_path)) - return; - QImage image(m_path); - if (image.isNull()) - { - QThread::msleep(500); - tries--; - continue; - } - QImage small; - if (image.width() > image.height()) - small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); - else - small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); - QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); - QImage square(QSize(256, 256), QImage::Format_ARGB32); - square.fill(Qt::transparent); - - QPainter painter(&square); - painter.drawImage(offset, small); - painter.end(); - - QIcon icon(QPixmap::fromImage(square)); - m_cache->add(m_path, icon); - m_resultEmitter.emitResultsReady(m_path); + if (!m_cache->stale(m_path)) + return; + QImage image(m_path); + if (image.isNull()) { + m_resultEmitter.emitResultsFailed(m_path); + qDebug() << "Error loading screenshot: " + m_path + ". Perhaps too large?"; return; } - m_resultEmitter.emitResultsFailed(m_path); + QImage small; + if (image.width() > image.height()) + small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); + else + small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); + QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); + QImage square(QSize(256, 256), QImage::Format_ARGB32); + square.fill(Qt::transparent); + + QPainter painter(&square); + painter.drawImage(offset, small); + painter.end(); + + QIcon icon(QPixmap::fromImage(square)); + m_cache->add(m_path, icon); + m_resultEmitter.emitResultsReady(m_path); } QString m_path; SharedIconCachePtr m_cache; From f769b0b4c63888ac95416a4cc834aad2395f9b74 Mon Sep 17 00:00:00 2001 From: Alfio Date: Tue, 20 Jun 2023 10:25:11 +0200 Subject: [PATCH 149/429] Remove inconsistent/unneeded question marks in UI Signed-off-by: P2 --- launcher/minecraft/auth/AccountList.cpp | 6 +++--- launcher/ui/pages/global/LauncherPage.ui | 8 ++++---- launcher/ui/pages/global/MinecraftPage.ui | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.ui | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 9e2fd1113..c27941472 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -333,13 +333,13 @@ QVariant AccountList::data(const QModelIndex &index, int role) const case MigrationColumn: { if(account->isMSA() || account->isOffline()) { - return tr("N/A", "Can Migrate?"); + return tr("N/A", "Can Migrate"); } if (account->canMigrate()) { - return tr("Yes", "Can Migrate?"); + return tr("Yes", "Can Migrate"); } else { - return tr("No", "Can Migrate?"); + return tr("No", "Can Migrate"); } } diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 55bd3eea7..d9116bfcf 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -172,7 +172,7 @@ Disable using metadata provided by mod providers (like Modrinth or Curseforge) for mods. - Disable using metadata for mods? + Disable using metadata for mods @@ -307,21 +307,21 @@ - Show console while the game is &running? + Show console while the game is &running - &Automatically close console when the game quits? + &Automatically close console when the game quits - Show console when the game &crashes? + Show console when the game &crashes diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 103881b57..8f5de725d 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -51,7 +51,7 @@ - Start Minecraft &maximized? + Start Minecraft &maximized diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 19d6dc02d..8427965de 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -269,7 +269,7 @@ - Start Minecraft maximized? + Start Minecraft maximized @@ -341,21 +341,21 @@ - Show console while the game is running? + Show console while the game is running - Automatically close console when the game quits? + Automatically close console when the game quits - Show console when the game crashes? + Show console when the game crashes From 3e3be9ae6f902cc292ee26e4d330b078ddbb2a46 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 20 Jun 2023 13:28:57 +0300 Subject: [PATCH 150/429] Added fallback for quilt if the API or Kotilin is not present Signed-off-by: Trial97 --- .../mod/tasks/GetModDependenciesTask.cpp | 38 ++++++++++++------- .../mod/tasks/GetModDependenciesTask.h | 1 + 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 00611f327..ebc9cf40a 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -31,7 +31,6 @@ #include "tasks/ConcurrentTask.h" #include "tasks/SequentialTask.h" #include "ui/pages/modplatform/ModModel.h" -#include "ui/pages/modplatform/ResourceModel.h" #include "ui/pages/modplatform/flame/FlameResourceModels.h" #include "ui/pages/modplatform/modrinth/ModrinthResourceModels.h" @@ -192,6 +191,16 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen } pDep->version = provider.mod->loadDependencyVersions(dep, arr); if (!pDep->version.addonId.isValid()) { + if (m_loaderType & ResourceAPI::Quilt) { // falback for quilt + auto overide = ModPlatform::getOverrideDeps(); + auto over = std::find_if(overide.cbegin(), overide.cend(), + [dep, provider](auto o) { return o.provider == provider.name && dep.addonId == o.quilt; }); + if (over != overide.cend()) { + removePack(dep.addonId); + addTask(prepareDependencyTask({ over->fabric, dep.type }, provider.name, level)); + return; + } + } qWarning() << "Error while reading mod version empty "; qDebug() << doc; return; @@ -213,18 +222,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen pDep->pack->addonId = pDep->version.addonId; auto dep = getOverride({ pDep->version.addonId, pDep->dependency.type }, provider.name); if (dep.addonId != pDep->version.addonId) { - auto toRemoveID = pDep->version.addonId; - - auto pred = [toRemoveID](const std::shared_ptr& v) { return v->pack->addonId == toRemoveID; }; -#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) - m_pack_dependencies.removeIf(pred); -#else - for (auto it = m_pack_dependencies.begin(); it != m_pack_dependencies.end();) - if (pred(*it)) - it = m_pack_dependencies.erase(it); - else - ++it; -#endif + removePack(pDep->version.addonId); addTask(prepareDependencyTask(dep, provider.name, level)); } else addTask(getProjectInfoTask(pDep)); @@ -238,3 +236,17 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen tasks->addTask(version); return tasks; }; + +void GetModDependenciesTask::removePack(const QVariant addonId) +{ + auto pred = [addonId](const std::shared_ptr& v) { return v->pack->addonId == addonId; }; +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) + m_pack_dependencies.removeIf(pred); +#else + for (auto it = m_pack_dependencies.begin(); it != m_pack_dependencies.end();) + if (pred(*it)) + it = m_pack_dependencies.erase(it); + else + ++it; +#endif +} diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index e2ad48250..50eba6afc 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -70,6 +70,7 @@ class GetModDependenciesTask : public SequentialTask { void prepare(); Task::Ptr getProjectInfoTask(std::shared_ptr pDep); ModPlatform::Dependency getOverride(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider providerName); + void removePack(const QVariant addonId); private: QList> m_pack_dependencies; From a32a3e25adbb20e31749828cca84a3ff3878f094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Wro=C5=84ski?= Date: Tue, 20 Jun 2023 12:11:28 +0200 Subject: [PATCH 151/429] Fix compiling on FreeBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub Wroński --- launcher/FileSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index d98526dfd..835ad925d 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -102,7 +102,7 @@ namespace fs = ghc::filesystem; #include #include #include -#elif defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) #include #include #elif defined(Q_OS_WIN) @@ -1151,7 +1151,7 @@ bool clone_file(const QString& src, const QString& dst, std::error_code& ec) return false; } -#elif defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) if (!macos_bsd_clonefile(src_path, dst_path, ec)) { qDebug() << "failed macos_bsd_clonefile:"; @@ -1380,7 +1380,7 @@ bool linux_ficlone(const std::string& src_path, const std::string& dst_path, std return true; } -#elif defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) bool macos_bsd_clonefile(const std::string& src_path, const std::string& dst_path, std::error_code& ec) { From 009623823d6036ea22b34b21812758666fb8f7ba Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 23:00:13 +1200 Subject: [PATCH 152/429] Modrinth: use default icon for non-managed packs Fixes: #317 Signed-off-by: James Beddek --- launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index bb8227aa2..76f072773 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -214,7 +214,7 @@ bool ModrinthCreationTask::createInstance() if (m_instIcon != "default") { instance.setIconKey(m_instIcon); - } else { + } else if (!m_managed_id.isEmpty()) { instance.setIconKey("modrinth"); } From f2692e60f3b7f1281750c4e97268830b9db30e95 Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Tue, 20 Jun 2023 12:44:44 +0100 Subject: [PATCH 153/429] Add missing space in java checker debug message Signed-off-by: Chris Lane --- launcher/java/JavaChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index b4c55b3d7..916a010c8 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -85,7 +85,7 @@ void JavaChecker::performCheck() process->setProgram(m_path); process->setProcessChannelMode(QProcess::SeparateChannels); process->setProcessEnvironment(CleanEnviroment()); - qDebug() << "Running java checker: " + m_path + args.join(" ");; + qDebug() << "Running java checker: " + m_path + " " + args.join(" ");; connect(process.get(), QOverload::of(&QProcess::finished), this, &JavaChecker::finished); connect(process.get(), &QProcess::errorOccurred, this, &JavaChecker::error); From 07f3d27fb89e1e5a32ca25e7111c98a29ab12e8c Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Tue, 20 Jun 2023 15:36:25 +0100 Subject: [PATCH 154/429] Clean up 'Running java checker' debug msg code Signed-off-by: Chris Lane --- launcher/java/JavaChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 916a010c8..755e34c6e 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -85,7 +85,7 @@ void JavaChecker::performCheck() process->setProgram(m_path); process->setProcessChannelMode(QProcess::SeparateChannels); process->setProcessEnvironment(CleanEnviroment()); - qDebug() << "Running java checker: " + m_path + " " + args.join(" ");; + qDebug() << "Running java checker:" << m_path << args.join(" "); connect(process.get(), QOverload::of(&QProcess::finished), this, &JavaChecker::finished); connect(process.get(), &QProcess::errorOccurred, this, &JavaChecker::error); From 9ad29e8d85d66b9008892bd3298cc7d709c2ad17 Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Tue, 20 Jun 2023 15:51:31 +0100 Subject: [PATCH 155/429] Remove extra spaces in one more Java checker debug Signed-off-by: Chris Lane --- launcher/java/JavaChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 755e34c6e..e4a686c27 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -128,7 +128,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) result.outLog = m_stdout; qDebug() << "STDOUT" << m_stdout; qWarning() << "STDERR" << m_stderr; - qDebug() << "Java checker finished with status " << status << " exit code " << exitcode; + qDebug() << "Java checker finished with status" << status << "exit code" << exitcode; if (status == QProcess::CrashExit || exitcode == 1) { From 470518eb3a3e0e43d67b7a15823c060755ad3284 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 21 Jun 2023 02:31:40 -0700 Subject: [PATCH 156/429] fix: resize columns on hide ^& uniform heights Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- launcher/minecraft/mod/ResourceFolderModel.cpp | 4 ++++ launcher/minecraft/mod/ResourceFolderModel.h | 2 +- launcher/ui/pages/instance/ExternalResourcesPage.ui | 3 +++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index e745f954a..af98d8348 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -60,7 +60,7 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool 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_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; } QVariant ModFolderModel::data(const QModelIndex &index, int role) const diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index b60f81825..7700fd36b 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -558,6 +558,10 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) connect(act, &QAction::toggled, tree, [this, col, tree](bool toggled){ tree->setColumnHidden(col, !toggled); + for(int c = 0; c < columnCount(); ++c) { + if (m_column_resize_modes.at(c) == QHeaderView::ResizeToContents) + tree->resizeColumnToContents(c); + } saveHiddenColumn(col, !toggled); }); diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 3c9c4d897..eb1d7c4f6 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -201,7 +201,7 @@ class ResourceFolderModel : public QAbstractListModel { QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; QStringList m_column_names = {"Enable", "Name", "Last Modified"}; QStringList m_column_names_translated = {tr("Enable"), tr("Name"), tr("Last Modified")}; - QList m_column_resize_modes = { QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; + QList m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents }; bool m_can_interact = true; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 33a033366..f676361c3 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -62,6 +62,9 @@ QAbstractItemView::DropOnly + + true + From 480faca5598b503eb130566061f06348e4a42b8f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 21:17:17 +0300 Subject: [PATCH 157/429] Removed unused variable Signed-off-by: Trial97 --- .../ui/pages/instance/ExternalResourcesPage.cpp | 15 --------------- .../ui/pages/instance/ExternalResourcesPage.h | 2 -- launcher/ui/pages/instance/ModFolderPage.cpp | 4 +--- launcher/ui/pages/instance/ResourcePackPage.cpp | 2 -- launcher/ui/pages/instance/ShaderPackPage.cpp | 3 --- launcher/ui/pages/instance/TexturePackPage.cpp | 2 -- 6 files changed, 1 insertion(+), 27 deletions(-) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index e50fa6353..e77e45726 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -135,9 +135,6 @@ void ExternalResourcesPage::retranslate() void ExternalResourcesPage::itemActivated(const QModelIndex&) { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::TOGGLE); } @@ -182,9 +179,6 @@ bool ExternalResourcesPage::eventFilter(QObject* obj, QEvent* ev) void ExternalResourcesPage::addItem() { - if (!m_controlsEnabled) - return; - auto list = GuiUtil::BrowseForFiles( helpPage(), tr("Select %1", "Select whatever type of files the page contains. Example: 'Loader Mods'").arg(displayName()), m_fileSelectionFilter.arg(displayName()), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); @@ -198,9 +192,6 @@ void ExternalResourcesPage::addItem() void ExternalResourcesPage::removeItem() { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); int count = 0; @@ -249,18 +240,12 @@ void ExternalResourcesPage::removeItems(const QItemSelection& selection) void ExternalResourcesPage::enableItem() { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::ENABLE); } void ExternalResourcesPage::disableItem() { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::DISABLE); } diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index fd2001938..acea81b59 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -72,7 +72,5 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { QString m_fileSelectionFilter; QString m_viewFilter; - bool m_controlsEnabled = true; - std::shared_ptr m_wide_bar_setting = nullptr; }; diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 90e7d0d62..ef7b1f2b8 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -133,15 +133,13 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI return true; } -void ModFolderPage::removeItems(const QItemSelection &selection) +void ModFolderPage::removeItems(const QItemSelection& selection) { m_model->deleteMods(selection.indexes()); } void ModFolderPage::installMods() { - if (!m_controlsEnabled) - return; if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance diff --git a/launcher/ui/pages/instance/ResourcePackPage.cpp b/launcher/ui/pages/instance/ResourcePackPage.cpp index 24bfb38dc..12b371df4 100644 --- a/launcher/ui/pages/instance/ResourcePackPage.cpp +++ b/launcher/ui/pages/instance/ResourcePackPage.cpp @@ -67,8 +67,6 @@ bool ResourcePackPage::onSelectionChanged(const QModelIndex& current, const QMod void ResourcePackPage::downloadRPs() { - if (!m_controlsEnabled) - return; if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance diff --git a/launcher/ui/pages/instance/ShaderPackPage.cpp b/launcher/ui/pages/instance/ShaderPackPage.cpp index 2d0c10aaf..dc8b0a05b 100644 --- a/launcher/ui/pages/instance/ShaderPackPage.cpp +++ b/launcher/ui/pages/instance/ShaderPackPage.cpp @@ -46,7 +46,6 @@ #include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/ResourceDownloadDialog.h" - ShaderPackPage::ShaderPackPage(MinecraftInstance* instance, std::shared_ptr model, QWidget* parent) : ExternalResourcesPage(instance, model, parent) { @@ -61,8 +60,6 @@ ShaderPackPage::ShaderPackPage(MinecraftInstance* instance, std::shared_ptrtypeName() != "Minecraft") return; // this is a null instance or a legacy instance diff --git a/launcher/ui/pages/instance/TexturePackPage.cpp b/launcher/ui/pages/instance/TexturePackPage.cpp index 427aba11a..e477ceda3 100644 --- a/launcher/ui/pages/instance/TexturePackPage.cpp +++ b/launcher/ui/pages/instance/TexturePackPage.cpp @@ -69,8 +69,6 @@ bool TexturePackPage::onSelectionChanged(const QModelIndex& current, const QMode void TexturePackPage::downloadTPs() { - if (!m_controlsEnabled) - return; if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance From 0d2105dec44bb1b5234e18ce6a8de5b2d26eb93a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 21:34:40 +0300 Subject: [PATCH 158/429] Made buttons on ModsFolderPage enabled all the time Signed-off-by: Trial97 --- launcher/minecraft/MinecraftInstance.cpp | 15 +--- launcher/minecraft/mod/ModFolderModel.cpp | 11 +-- .../minecraft/mod/ResourceFolderModel.cpp | 69 +++++++------------ launcher/minecraft/mod/ResourceFolderModel.h | 14 ++-- launcher/ui/pages/instance/ModFolderPage.cpp | 20 +----- launcher/ui/pages/instance/ModFolderPage.h | 3 +- 6 files changed, 39 insertions(+), 93 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index f8ed5214e..e896799a7 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1112,36 +1112,27 @@ JavaVersion MinecraftInstance::getJavaVersion() std::shared_ptr MinecraftInstance::loaderModList() { - if (!m_loader_mod_list) - { + if (!m_loader_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_loader_mod_list.reset(new ModFolderModel(modsRoot(), this, is_indexed)); - m_loader_mod_list->disableInteraction(isRunning()); - connect(this, &BaseInstance::runningStatusChanged, m_loader_mod_list.get(), &ModFolderModel::disableInteraction); } return m_loader_mod_list; } std::shared_ptr MinecraftInstance::coreModList() { - if (!m_core_mod_list) - { + if (!m_core_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_core_mod_list.reset(new ModFolderModel(coreModsDir(), this, is_indexed)); - m_core_mod_list->disableInteraction(isRunning()); - connect(this, &BaseInstance::runningStatusChanged, m_core_mod_list.get(), &ModFolderModel::disableInteraction); } return m_core_mod_list; } std::shared_ptr MinecraftInstance::nilModList() { - if (!m_nil_mod_list) - { + if (!m_nil_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_nil_mod_list.reset(new ModFolderModel(nilModsDir(), this, is_indexed, false)); - m_nil_mod_list->disableInteraction(isRunning()); - connect(this, &BaseInstance::runningStatusChanged, m_nil_mod_list.get(), &ModFolderModel::disableInteraction); } return m_nil_mod_list; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 5e3b31e08..0089cd8be 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -213,16 +213,11 @@ bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadat bool ModFolderModel::deleteMods(const QModelIndexList& indexes) { - if(!m_can_interact) { - return false; - } - - if(indexes.isEmpty()) + if (indexes.isEmpty()) return true; - for (auto i: indexes) - { - if(i.column() != 0) { + for (auto i : indexes) { + if (i.column() != 0) { continue; } auto m = at(i.row()); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index d2d875e48..c38e97d92 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -74,10 +74,6 @@ bool ResourceFolderModel::stopWatching(const QStringList paths) bool ResourceFolderModel::installResource(QString original_path) { - if (!m_can_interact) { - return false; - } - // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName original_path = FS::NormalizePath(original_path); QFileInfo file_info(original_path); @@ -168,9 +164,6 @@ bool ResourceFolderModel::uninstallResource(QString file_name) bool ResourceFolderModel::deleteResources(const QModelIndexList& indexes) { - if (!m_can_interact) - return false; - if (indexes.isEmpty()) return true; @@ -189,11 +182,8 @@ bool ResourceFolderModel::deleteResources(const QModelIndexList& indexes) return true; } -bool ResourceFolderModel::setResourceEnabled(const QModelIndexList &indexes, EnableAction action) +bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAction action) { - if (!m_can_interact) - return false; - if (indexes.isEmpty()) return true; @@ -246,15 +236,18 @@ bool ResourceFolderModel::update() connect(m_current_update_task.get(), &Task::succeeded, this, &ResourceFolderModel::onUpdateSucceeded, Qt::ConnectionType::QueuedConnection); connect(m_current_update_task.get(), &Task::failed, this, &ResourceFolderModel::onUpdateFailed, Qt::ConnectionType::QueuedConnection); - connect(m_current_update_task.get(), &Task::finished, this, [=] { - m_current_update_task.reset(); - if (m_scheduled_update) { - m_scheduled_update = false; - update(); - } else { - emit updateFinished(); - } - }, Qt::ConnectionType::QueuedConnection); + connect( + m_current_update_task.get(), &Task::finished, this, + [=] { + m_current_update_task.reset(); + if (m_scheduled_update) { + m_scheduled_update = false; + update(); + } else { + emit updateFinished(); + } + }, + Qt::ConnectionType::QueuedConnection); QThreadPool::globalInstance()->start(m_current_update_task.get()); @@ -344,15 +337,9 @@ Qt::DropActions ResourceFolderModel::supportedDropActions() const Qt::ItemFlags ResourceFolderModel::flags(const QModelIndex& index) const { Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index); - auto flags = defaultFlags; - if (!m_can_interact) { - flags &= ~Qt::ItemIsDropEnabled; - } else { - flags |= Qt::ItemIsDropEnabled; - if (index.isValid()) { - flags |= Qt::ItemIsUserCheckable; - } - } + auto flags = defaultFlags | Qt::ItemIsDropEnabled; + if (index.isValid()) + flags |= Qt::ItemIsUserCheckable; return flags; } @@ -425,16 +412,17 @@ QVariant ResourceFolderModel::data(const QModelIndex& index, int role) const if (column == NAME_COLUMN) { if (at(row).isSymLinkUnder(instDirPath())) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." - "\nCanonical Path: %1") - .arg(at(row).fileinfo().canonicalFilePath());; + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(at(row).fileinfo().canonicalFilePath()); + ; } if (at(row).isMoreThanOneHardLink()) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); } } - + return m_resources[row]->internal_id(); case Qt::DecorationRole: { if (column == NAME_COLUMN && (at(row).isSymLinkUnder(instDirPath()) || at(row).isMoreThanOneHardLink())) @@ -511,16 +499,6 @@ SortType ResourceFolderModel::columnToSortKey(size_t column) const return m_column_sort_keys.at(column); } -void ResourceFolderModel::enableInteraction(bool enabled) -{ - if (m_can_interact == enabled) - return; - - m_can_interact = enabled; - if (size()) - emit dataChanged(index(0), index(size() - 1)); -} - /* Standard Proxy Model for createFilterProxyModel */ [[nodiscard]] bool ResourceFolderModel::ProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { @@ -556,6 +534,7 @@ void ResourceFolderModel::enableInteraction(bool enabled) return (compare_result.first > 0); } -QString ResourceFolderModel::instDirPath() const { +QString ResourceFolderModel::instDirPath() const +{ return QFileInfo(m_instance->instanceRoot()).absoluteFilePath(); } diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 0a35e1bca..d5ca08e82 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -11,8 +11,8 @@ #include "BaseInstance.h" -#include "tasks/Task.h" #include "tasks/ConcurrentTask.h" +#include "tasks/Task.h" class QSortFilterProxyModel; @@ -129,10 +129,6 @@ class ResourceFolderModel : public QAbstractListModel { QString instDirPath() const; - public slots: - void enableInteraction(bool enabled); - void disableInteraction(bool disabled) { enableInteraction(!disabled); } - signals: void updateFinished(); @@ -181,15 +177,17 @@ class ResourceFolderModel : public QAbstractListModel { * if the resource is complex and has more stuff to parse. */ virtual void onParseSucceeded(int ticket, QString resource_id); - virtual void onParseFailed(int ticket, QString resource_id) { Q_UNUSED(ticket); Q_UNUSED(resource_id); } + virtual void onParseFailed(int ticket, QString resource_id) + { + Q_UNUSED(ticket); + Q_UNUSED(resource_id); + } protected: // Represents the relationship between a column's index (represented by the list index), and it's sorting key. // As such, the order in with they appear is very important! QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; - bool m_can_interact = true; - QDir m_dir; BaseInstance* m_instance; QFileSystemWatcher m_watcher; diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index ef7b1f2b8..9812bbe93 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -86,9 +86,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); - auto check_allow_update = [this] { - return (!m_instance || !m_instance->isRunning()) && (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); - }; + auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); }; connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); @@ -101,22 +99,9 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - - connect(m_instance, &BaseInstance::runningStatusChanged, this, &ModFolderPage::runningStateChanged); - ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning()); } } -void ModFolderPage::runningStateChanged(bool running) -{ - ui->actionDownloadItem->setEnabled(!running); - ui->actionUpdateItem->setEnabled(!running); - ui->actionAddItem->setEnabled(!running); - ui->actionEnableItem->setEnabled(!running); - ui->actionDisableItem->setEnabled(!running); - ui->actionRemoveItem->setEnabled(!running); -} - bool ModFolderPage::shouldDisplay() const { return true; @@ -205,8 +190,7 @@ void ModFolderPage::updateMods() message = tr("All selected mods are up-to-date! :)"); } } - CustomMessageBox::selectable(this, tr("Update checker"), message) - ->exec(); + CustomMessageBox::selectable(this, tr("Update checker"), message)->exec(); return; } diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 2fc7b5748..b59841959 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -59,8 +59,7 @@ class ModFolderPage : public ExternalResourcesPage { bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override; private slots: - void runningStateChanged(bool running); - void removeItems(const QItemSelection &selection) override; + void removeItems(const QItemSelection& selection) override; void installMods(); void updateMods(); From 820892d7cc7864315bd73dcd877cb0a1beb2b106 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 22:42:08 +0300 Subject: [PATCH 159/429] Made settings editable when instance is running Signed-off-by: Trial97 --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 13 ++----------- launcher/ui/pages/instance/InstanceSettingsPage.h | 3 +-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 08977841a..1108d2643 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -60,17 +60,13 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) m_settings = inst->settings(); ui->setupUi(this); - // As the signal will (probably) not be triggered once we click edit, let's update it manually instead. - updateRunningStatus(m_instance->isRunning()); - - connect(m_instance, &BaseInstance::runningStatusChanged, this, &InstanceSettingsPage::updateRunningStatus); connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); - connect(ui->instanceAccountSelector, QOverload::of(&QComboBox::currentIndexChanged), this, &InstanceSettingsPage::changeInstanceAccount); + connect(ui->instanceAccountSelector, QOverload::of(&QComboBox::currentIndexChanged), this, + &InstanceSettingsPage::changeInstanceAccount); loadSettings(); - updateThresholds(); } @@ -523,8 +519,3 @@ void InstanceSettingsPage::updateThresholds() ui->labelMaxMemIcon->setPixmap(pix); } } - -void InstanceSettingsPage::updateRunningStatus(bool running) -{ - setEnabled(!running); -} diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index 0438fe3b2..036b41818 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -79,8 +79,7 @@ public: void updateThresholds(); -private slots: - void updateRunningStatus(bool running); + private slots: void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); From 2e82c1d40cd43aef4745726d51dd6a9df2d8f78b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 23:22:25 +0300 Subject: [PATCH 160/429] Added regex expresion to exclude .DS_Store files Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportMrPackDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 239873f6d..561b92e40 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -53,6 +53,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); proxy->setSourceModel(model); + proxy->setFilterRegularExpression("^(?!\\.DS_Store).+$"); const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); From 9d2516a199ae4c33f773ab00ce59ecb2a6dfd0a5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 16:00:45 +0300 Subject: [PATCH 161/429] Added ExportModsToStringTask Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 3 + .../helpers/ExportModsToStringTask.cpp | 114 ++++++++++++++++++ .../helpers/ExportModsToStringTask.h | 33 +++++ 3 files changed, 150 insertions(+) create mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.cpp create mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index ce2771a49..c7efdad84 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -487,6 +487,9 @@ set(API_SOURCES modplatform/helpers/HashUtils.cpp modplatform/helpers/OverrideUtils.h modplatform/helpers/OverrideUtils.cpp + + modplatform/helpers/ExportModsToStringTask.h + modplatform/helpers/ExportModsToStringTask.cpp ) set(FTB_SOURCES diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp new file mode 100644 index 000000000..a105fc352 --- /dev/null +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -0,0 +1,114 @@ +// 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 "ExportModsToStringTask.h" +#include "modplatform/ModIndex.h" + +namespace ExportToString { +QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) +{ + switch (format) { + case HTML: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->homeurl(); + if (meta != nullptr) { + url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + meta->project_id.toString(); + } + if (!url.isEmpty()) + modName = QString("%2").arg(url, modName); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString("[%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines.append(QString("
    %1
").arg(line)); + } + return QString("\n\t%1\n").arg(lines.join("\n\t")); + } + case MARKDOWN: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->homeurl(); + if (meta != nullptr) { + url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + meta->project_id.toString(); + } + if (!url.isEmpty()) + modName = QString("[%1](%2)").arg(modName, url); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString("[%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines << line; + } + return lines.join("\n"); + } + default: { + return QString("unknown format:%1").arg(format); + } + } +} + +QString ExportModsToStringTask(QList mods, QString lineTemplate) +{ + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + + auto url = mod->homeurl(); + if (meta != nullptr) { + url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + meta->project_id.toString(); + } + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + auto authors = mod->authors().join(", "); + lines << QString(lineTemplate) + .replace("{name}", modName) + .replace("{url}", url) + .replace("{version}", ver) + .replace("{authors}", authors); + } + return lines.join("\n"); +} +} // namespace ExportToString \ No newline at end of file diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.h b/launcher/modplatform/helpers/ExportModsToStringTask.h new file mode 100644 index 000000000..756c69f77 --- /dev/null +++ b/launcher/modplatform/helpers/ExportModsToStringTask.h @@ -0,0 +1,33 @@ +// 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 +#include "minecraft/mod/Mod.h" + +namespace ExportToString { + +enum Formats { HTML, MARKDOWN }; +enum OptionalData { + Authors = 1 << 0, + Url = 1 << 1, + Version = 1 << 2, +}; +QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData); +QString ExportModsToStringTask(QList mods, QString lineTemplate); +} // namespace ExportToString From f7d502c68c530d66b385d530c838a9a6566828d0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 16:05:47 +0300 Subject: [PATCH 162/429] Added ExportModsToStringDialog Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 3 + launcher/ui/MainWindow.cpp | 10 + launcher/ui/MainWindow.h | 1 + launcher/ui/MainWindow.ui | 8 + .../ui/dialogs/ExportModsToStringDialog.cpp | 119 ++++++++++++ .../ui/dialogs/ExportModsToStringDialog.h | 45 +++++ .../ui/dialogs/ExportModsToStringDialog.ui | 171 ++++++++++++++++++ 7 files changed, 357 insertions(+) create mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.cpp create mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.h create mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.ui diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c7efdad84..5ef97f422 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -911,6 +911,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/ExportInstanceDialog.h ui/dialogs/ExportMrPackDialog.cpp ui/dialogs/ExportMrPackDialog.h + ui/dialogs/ExportModsToStringDialog.cpp + ui/dialogs/ExportModsToStringDialog.h ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.h ui/dialogs/ImportResourceDialog.cpp @@ -1058,6 +1060,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/SkinUploadDialog.ui ui/dialogs/ExportInstanceDialog.ui ui/dialogs/ExportMrPackDialog.ui + ui/dialogs/ExportModsToStringDialog.ui ui/dialogs/IconPickerDialog.ui ui/dialogs/ImportResourceDialog.ui ui/dialogs/MSALoginDialog.ui diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e04011cab..02ea30c36 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -43,6 +43,7 @@ #include "FileSystem.h" #include "MainWindow.h" +#include "ui/dialogs/ExportModsToStringDialog.h" #include "ui_MainWindow.h" #include @@ -205,6 +206,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto exportInstanceMenu = new QMenu(this); exportInstanceMenu->addAction(ui->actionExportInstanceZip); exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); + exportInstanceMenu->addAction(ui->actionExportInstanceToString); ui->actionExportInstance->setMenu(exportInstanceMenu); } @@ -1416,6 +1418,14 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() } } +void MainWindow::on_actionExportInstanceToString_triggered() +{ + if (m_selectedInstance) { + ExportModsToStringDialog dlg(m_selectedInstance, this); + dlg.exec(); + } +} + void MainWindow::on_actionRenameInstance_triggered() { if (m_selectedInstance) diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3bb20c4a4..9b38810f0 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -157,6 +157,7 @@ private slots: inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); + void on_actionExportInstanceToString_triggered(); void on_actionRenameInstance_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index f67fb1859..e6e52a912 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -479,6 +479,14 @@ Modrinth (mrpack)
+ + + + + + Text + + diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp new file mode 100644 index 000000000..d08a4c70c --- /dev/null +++ b/launcher/ui/dialogs/ExportModsToStringDialog.cpp @@ -0,0 +1,119 @@ +// 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 "ExportModsToStringDialog.h" +#include +#include +#include +#include "minecraft/MinecraftInstance.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/ExportModsToStringTask.h" +#include "ui_ExportModsToStringDialog.h" + +#include +#include +#include +#include +#include + +ExportModsToStringDialog::ExportModsToStringDialog(InstancePtr instance, QWidget* parent) + : QDialog(parent), m_template_selected(false), ui(new Ui::ExportModsToStringDialog) +{ + ui->setupUi(this); + ui->templateGroup->setDisabled(true); + + MinecraftInstance* mcInstance = dynamic_cast(instance.get()); + if (mcInstance) { + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { + m_allMods = mcInstance->loaderModList()->allMods(); + trigger(); + }); + } + + connect(ui->formatComboBox, &QComboBox::currentIndexChanged, this, &ExportModsToStringDialog::formatChanged); + connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->copyButton, &QPushButton::clicked, this, [this]() { + this->ui->finalText->selectAll(); + this->ui->finalText->copy(); + }); +} + +ExportModsToStringDialog::~ExportModsToStringDialog() +{ + delete ui; +} + +void ExportModsToStringDialog::formatChanged(int index) +{ + switch (index) { + case 0: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + break; + } + case 1: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + break; + } + case 2: { + ui->templateGroup->setDisabled(false); + ui->optionsGroup->setDisabled(true); + break; + } + } + trigger(); +} + +void ExportModsToStringDialog::trigger() +{ + ExportToString::Formats format; + switch (ui->formatComboBox->currentIndex()) { + case 2: { + m_template_selected = true; + ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, ui->templateText->toPlainText())); + return; + } + case 0: { + format = ExportToString::HTML; + break; + } + case 1: { + format = ExportToString::MARKDOWN; + break; + } + } + auto opt = 0; + if (ui->authorsCheckBox->isChecked()) + opt |= ExportToString::Authors; + if (ui->versionCheckBox->isChecked()) + opt |= ExportToString::Version; + if (ui->urlCheckBox->isChecked()) + opt |= ExportToString::Url; + ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, format, static_cast(opt))); + if (!m_template_selected) { + auto exampleLine = format == ExportToString::HTML ? "
    {name}[{version}] by {authors}
" + : "[{name}]({url})[{version}] by {authors}"; + if (ui->templateText->toPlainText() != exampleLine) + ui->templateText->setPlainText(exampleLine); + } +} diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.h b/launcher/ui/dialogs/ExportModsToStringDialog.h new file mode 100644 index 000000000..7fada4d54 --- /dev/null +++ b/launcher/ui/dialogs/ExportModsToStringDialog.h @@ -0,0 +1,45 @@ +// 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 +#include "BaseInstance.h" +#include "minecraft/mod/Mod.h" + +namespace Ui { +class ExportModsToStringDialog; +} + +class ExportModsToStringDialog : public QDialog { + Q_OBJECT + + public: + explicit ExportModsToStringDialog(InstancePtr instance, QWidget* parent = nullptr); + ~ExportModsToStringDialog(); + + protected slots: + void formatChanged(int index); + void trigger(); + + private: + QList m_allMods; + bool m_template_selected; + Ui::ExportModsToStringDialog* ui; +}; diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.ui b/launcher/ui/dialogs/ExportModsToStringDialog.ui new file mode 100644 index 000000000..4451a2785 --- /dev/null +++ b/launcher/ui/dialogs/ExportModsToStringDialog.ui @@ -0,0 +1,171 @@ + + + ExportModsToStringDialog + + + + 0 + 0 + 650 + 446 + + + + Export Modrinth Pack + + + true + + + + + + + + Settings + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + Format + + + + + + + + HTML + + + + + Markdown + + + + + Custom + + + + + + + + Template + + + + + + + + + + + + Optional Info + + + + + + Version + + + + + + + Authors + + + + + + + URL + + + + + + + + + + + + + Result + + + + + + + 0 + 143 + + + + true + + + + + + + + + + + + + + Copy + + + + + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ExportModsToStringDialog + accept() + + + 334 + 435 + + + 324 + 206 + + + + + From b84dc8551a13ed87d09e6f8ca8b401c57d549f95 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 16:49:19 +0300 Subject: [PATCH 163/429] Fixed trigger function Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportModsToStringDialog.cpp | 12 ++++++------ launcher/ui/dialogs/ExportModsToStringDialog.h | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp index d08a4c70c..ae793dcb3 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.cpp +++ b/launcher/ui/dialogs/ExportModsToStringDialog.cpp @@ -42,16 +42,16 @@ ExportModsToStringDialog::ExportModsToStringDialog(InstancePtr instance, QWidget mcInstance->loaderModList()->update(); connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { m_allMods = mcInstance->loaderModList()->allMods(); - trigger(); + triggerImp(); }); } - connect(ui->formatComboBox, &QComboBox::currentIndexChanged, this, &ExportModsToStringDialog::formatChanged); + connect(ui->formatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ExportModsToStringDialog::formatChanged); connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->copyButton, &QPushButton::clicked, this, [this]() { + connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::triggerImp); + connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { this->ui->finalText->selectAll(); this->ui->finalText->copy(); }); @@ -81,10 +81,10 @@ void ExportModsToStringDialog::formatChanged(int index) break; } } - trigger(); + triggerImp(); } -void ExportModsToStringDialog::trigger() +void ExportModsToStringDialog::triggerImp() { ExportToString::Formats format; switch (ui->formatComboBox->currentIndex()) { diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.h b/launcher/ui/dialogs/ExportModsToStringDialog.h index 7fada4d54..d195d1cec 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.h +++ b/launcher/ui/dialogs/ExportModsToStringDialog.h @@ -36,7 +36,8 @@ class ExportModsToStringDialog : public QDialog { protected slots: void formatChanged(int index); - void trigger(); + void triggerImp(); + void trigger(int) { triggerImp(); }; private: QList m_allMods; From 836e8d2e28b4ab63e6c4189410c38ad1a7fd2718 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 17:39:57 +0300 Subject: [PATCH 164/429] Fixed code quality Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportModsToStringDialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp index ae793dcb3..29d69918e 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.cpp +++ b/launcher/ui/dialogs/ExportModsToStringDialog.cpp @@ -86,7 +86,7 @@ void ExportModsToStringDialog::formatChanged(int index) void ExportModsToStringDialog::triggerImp() { - ExportToString::Formats format; + auto format = ExportToString::HTML; switch (ui->formatComboBox->currentIndex()) { case 2: { m_template_selected = true; @@ -101,6 +101,9 @@ void ExportModsToStringDialog::triggerImp() format = ExportToString::MARKDOWN; break; } + default: { + return; + } } auto opt = 0; if (ui->authorsCheckBox->isChecked()) From 9ad356d66f4c7bf1ccbbe251df800ebb1c4b67d4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 16:00:45 +0300 Subject: [PATCH 165/429] Added ExportModsToStringTask Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 3 + .../helpers/ExportModsToStringTask.cpp | 114 ++++++++++++++++++ .../helpers/ExportModsToStringTask.h | 33 +++++ 3 files changed, 150 insertions(+) create mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.cpp create mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index ce2771a49..c7efdad84 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -487,6 +487,9 @@ set(API_SOURCES modplatform/helpers/HashUtils.cpp modplatform/helpers/OverrideUtils.h modplatform/helpers/OverrideUtils.cpp + + modplatform/helpers/ExportModsToStringTask.h + modplatform/helpers/ExportModsToStringTask.cpp ) set(FTB_SOURCES diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp new file mode 100644 index 000000000..a105fc352 --- /dev/null +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -0,0 +1,114 @@ +// 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 "ExportModsToStringTask.h" +#include "modplatform/ModIndex.h" + +namespace ExportToString { +QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) +{ + switch (format) { + case HTML: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->homeurl(); + if (meta != nullptr) { + url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + meta->project_id.toString(); + } + if (!url.isEmpty()) + modName = QString("%2").arg(url, modName); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString("[%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines.append(QString("
    %1
").arg(line)); + } + return QString("\n\t%1\n").arg(lines.join("\n\t")); + } + case MARKDOWN: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->homeurl(); + if (meta != nullptr) { + url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + meta->project_id.toString(); + } + if (!url.isEmpty()) + modName = QString("[%1](%2)").arg(modName, url); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString("[%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines << line; + } + return lines.join("\n"); + } + default: { + return QString("unknown format:%1").arg(format); + } + } +} + +QString ExportModsToStringTask(QList mods, QString lineTemplate) +{ + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + + auto url = mod->homeurl(); + if (meta != nullptr) { + url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + meta->project_id.toString(); + } + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + auto authors = mod->authors().join(", "); + lines << QString(lineTemplate) + .replace("{name}", modName) + .replace("{url}", url) + .replace("{version}", ver) + .replace("{authors}", authors); + } + return lines.join("\n"); +} +} // namespace ExportToString \ No newline at end of file diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.h b/launcher/modplatform/helpers/ExportModsToStringTask.h new file mode 100644 index 000000000..756c69f77 --- /dev/null +++ b/launcher/modplatform/helpers/ExportModsToStringTask.h @@ -0,0 +1,33 @@ +// 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 +#include "minecraft/mod/Mod.h" + +namespace ExportToString { + +enum Formats { HTML, MARKDOWN }; +enum OptionalData { + Authors = 1 << 0, + Url = 1 << 1, + Version = 1 << 2, +}; +QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData); +QString ExportModsToStringTask(QList mods, QString lineTemplate); +} // namespace ExportToString From da6f846a496f70dd5339ed1bdba35842feaa1286 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 18:11:03 +0300 Subject: [PATCH 166/429] Use slug for url Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportModsToStringTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp index a105fc352..c10560c1c 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -32,7 +32,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex if (meta != nullptr) { url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" : "https://modrinth.com/mod/") + - meta->project_id.toString(); + meta->slug.remove(".pw.toml"); } if (!url.isEmpty()) modName = QString("%2").arg(url, modName); @@ -61,7 +61,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex if (meta != nullptr) { url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" : "https://modrinth.com/mod/") + - meta->project_id.toString(); + meta->slug.remove(".pw.toml"); } if (!url.isEmpty()) modName = QString("[%1](%2)").arg(modName, url); From 4e07f9574af10943577726f795fc8fad249e90e4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 18:11:03 +0300 Subject: [PATCH 167/429] Use slug for url Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportModsToStringTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp index a105fc352..c10560c1c 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -32,7 +32,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex if (meta != nullptr) { url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" : "https://modrinth.com/mod/") + - meta->project_id.toString(); + meta->slug.remove(".pw.toml"); } if (!url.isEmpty()) modName = QString("%2").arg(url, modName); @@ -61,7 +61,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex if (meta != nullptr) { url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" : "https://modrinth.com/mod/") + - meta->project_id.toString(); + meta->slug.remove(".pw.toml"); } if (!url.isEmpty()) modName = QString("[%1](%2)").arg(modName, url); From 58321f34915bd22ab8a2c195b64af3006d962be9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 20:03:44 +0300 Subject: [PATCH 168/429] Added curseforge export Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 2 + .../modplatform/flame/FlamePackExportTask.cpp | 223 ++++++++++++++++++ .../modplatform/flame/FlamePackExportTask.h | 74 ++++++ launcher/ui/MainWindow.cpp | 9 + launcher/ui/MainWindow.h | 1 + launcher/ui/MainWindow.ui | 8 + launcher/ui/dialogs/ExportMrPackDialog.cpp | 28 ++- launcher/ui/dialogs/ExportMrPackDialog.h | 6 +- 8 files changed, 341 insertions(+), 10 deletions(-) create mode 100644 launcher/modplatform/flame/FlamePackExportTask.cpp create mode 100644 launcher/modplatform/flame/FlamePackExportTask.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c7efdad84..df6c90129 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -517,6 +517,8 @@ set(FLAME_SOURCES modplatform/flame/FlameCheckUpdate.h modplatform/flame/FlameInstanceCreationTask.h modplatform/flame/FlameInstanceCreationTask.cpp + modplatform/flame/FlamePackExportTask.h + modplatform/flame/FlamePackExportTask.cpp ) set(MODRINTH_SOURCES diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp new file mode 100644 index 000000000..1ae13f72c --- /dev/null +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -0,0 +1,223 @@ +// 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 "FlamePackExportTask.h" +#include +#include + +#include +#include +#include +#include +#include "Json.h" +#include "MMCZip.h" +#include "minecraft/PackProfile.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/ExportModsToStringTask.h" + +const QStringList FlamePackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); +const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "zip" }); +const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; + +FlamePackExportTask::FlamePackExportTask(const QString& name, + const QString& version, + const QVariant& projectID, + InstancePtr instance, + const QString& output, + MMCZip::FilterFunction filter) + : name(name) + , version(version) + , projectID(projectID) + , instance(instance) + , mcInstance(dynamic_cast(instance.get())) + , gameRoot(instance->gameRoot()) + , output(output) + , filter(filter) +{} + +void FlamePackExportTask::executeTask() +{ + setStatus(tr("Searching for files...")); + setProgress(0, 0); + collectFiles(); +} + +bool FlamePackExportTask::abort() +{ + if (task != nullptr) { + task->abort(); + task = nullptr; + emitAborted(); + return true; + } + + if (buildZipFuture.isRunning()) { + buildZipFuture.cancel(); + // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur + // immediately. + return true; + } + + return false; +} + +void FlamePackExportTask::collectFiles() +{ + setAbortable(false); + QCoreApplication::processEvents(); + + files.clear(); + if (!MMCZip::collectFileListRecursively(instance->gameRoot(), nullptr, &files, filter)) { + emitFailed(tr("Could not search for files")); + return; + } + + resolvedFiles.clear(); + + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { + mods = mcInstance->loaderModList()->allMods(); + buildZip(); + }); +} + +void FlamePackExportTask::buildZip() +{ + setStatus(tr("Adding files...")); + + buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { + QuaZip zip(output); + if (!zip.open(QuaZip::mdCreate)) { + QFile::remove(output); + return BuildZipResult(tr("Could not create file")); + } + + if (buildZipFuture.isCanceled()) + return BuildZipResult(); + + QuaZipFile indexFile(&zip); + if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("manifest.json"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + indexFile.write(generateIndex()); + + QuaZipFile modlist(&zip); + if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + QString content = ExportToString::ExportModsToStringTask(mods, TEMPLATE); + content = "
      " + content + "
    "; + modlist.write(content.toUtf8()); + + size_t progress = 0; + for (const QFileInfo& file : files) { + if (buildZipFuture.isCanceled()) { + QFile::remove(output); + return BuildZipResult(); + } + + setProgress(progress, files.length()); + const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); + if (!resolvedFiles.contains(relative) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { + QFile::remove(output); + return BuildZipResult(tr("Could not read and compress %1").arg(relative)); + } + progress++; + } + + zip.close(); + + if (zip.getZipError() != 0) { + QFile::remove(output); + return BuildZipResult(tr("A zip error occurred")); + } + + return BuildZipResult(); + }); + connect(&buildZipWatcher, &QFutureWatcher::finished, this, &FlamePackExportTask::finish); + buildZipWatcher.setFuture(buildZipFuture); +} + +void FlamePackExportTask::finish() +{ + if (buildZipFuture.isCanceled()) + emitAborted(); + else { + const BuildZipResult result = buildZipFuture.result(); + if (result.has_value()) + emitFailed(result.value()); + else + emitSucceeded(); + } +} + +QByteArray FlamePackExportTask::generateIndex() +{ + QJsonObject obj; + obj["manifestType"] = "minecraftModpack"; + obj["manifestVersion"] = 1; + obj["name"] = name; + obj["version"] = version; + obj["author"] = author; + obj["projectID"] = projectID.toInt(); + obj["overrides"] = "overrides"; + if (mcInstance) { + QJsonObject version; + auto profile = mcInstance->getPackProfile(); + // collect all supported components + const ComponentPtr minecraft = profile->getComponent("net.minecraft"); + const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader"); + const ComponentPtr fabric = profile->getComponent("net.fabricmc.fabric-loader"); + const ComponentPtr forge = profile->getComponent("net.minecraftforge"); + + // convert all available components to mrpack dependencies + if (minecraft != nullptr) + version["version"] = minecraft->m_version; + + QJsonObject loader; + if (quilt != nullptr) + loader["id"] = quilt->getName(); + else if (fabric != nullptr) + loader["id"] = fabric->getName(); + else if (forge != nullptr) + loader["id"] = forge->getName(); + loader["primary"] = true; + + version["modLoaders"] = QJsonArray({ loader }); + obj["minecraft"] = version; + } + + QJsonArray files; + QMapIterator iterator(resolvedFiles); + while (iterator.hasNext()) { + iterator.next(); + + const ResolvedFile& value = iterator.value(); + + QJsonObject file; + file["projectID"] = value.projectID.toInt(); + file["fileID"] = value.fileID.toInt(); + file["required"] = value.required; + files << file; + } + obj["files"] = files; + + return QJsonDocument(obj).toJson(QJsonDocument::Compact); +} diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h new file mode 100644 index 000000000..83927099a --- /dev/null +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -0,0 +1,74 @@ +// 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 +#include "BaseInstance.h" +#include "MMCZip.h" +#include "minecraft/MinecraftInstance.h" +#include "tasks/Task.h" + +class FlamePackExportTask : public Task { + public: + FlamePackExportTask(const QString& name, + const QString& version, + const QVariant& projectID, + InstancePtr instance, + const QString& output, + MMCZip::FilterFunction filter); + + protected: + void executeTask() override; + bool abort() override; + + private: + struct ResolvedFile { + QVariant projectID, fileID; + bool required; + }; + + static const QStringList PREFIXES; + static const QStringList FILE_EXTENSIONS; + static const QString TEMPLATE; + + // inputs + const QString name, version, author; + const QVariant projectID; + const InstancePtr instance; + MinecraftInstance* mcInstance; + const QDir gameRoot; + const QString output; + const MMCZip::FilterFunction filter; + + typedef std::optional BuildZipResult; + + QFileInfoList files; + QMap resolvedFiles; + Task::Ptr task; + QFuture buildZipFuture; + QFutureWatcher buildZipWatcher; + QList mods; + + void collectFiles(); + void buildZip(); + void finish(); + + QByteArray generateIndex(); +}; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e04011cab..0027d1804 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -205,6 +205,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto exportInstanceMenu = new QMenu(this); exportInstanceMenu->addAction(ui->actionExportInstanceZip); exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); + exportInstanceMenu->addAction(ui->actionExportInstanceFlamePack); ui->actionExportInstance->setMenu(exportInstanceMenu); } @@ -1416,6 +1417,14 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() } } +void MainWindow::on_actionExportInstanceFlamePack_triggered() +{ + if (m_selectedInstance) { + ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); + dlg.exec(); + } +} + void MainWindow::on_actionRenameInstance_triggered() { if (m_selectedInstance) diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3bb20c4a4..5f74b501c 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -157,6 +157,7 @@ private slots: inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); + void on_actionExportInstanceFlamePack_triggered(); void on_actionRenameInstance_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index f67fb1859..f7e93f483 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -479,6 +479,14 @@ Modrinth (mrpack)
    + + + + + + Curseforge (zip) + + diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 561b92e40..16ef526a8 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -18,6 +18,8 @@ #include "ExportMrPackDialog.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" +#include "modplatform/flame/FlamePackExportTask.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" #include "ui_ExportMrPackDialog.h" @@ -32,12 +34,15 @@ #include "MMCZip.h" #include "modplatform/modrinth/ModrinthPackExportTask.h" -ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) - : QDialog(parent), instance(instance), ui(new Ui::ExportMrPackDialog) +ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider) + : QDialog(parent), instance(instance), ui(new Ui::ExportMrPackDialog), m_provider(provider) { ui->setupUi(this); ui->name->setText(instance->name()); - ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + else + ui->summaryLabel->setText("ProjectID"); // ensure a valid pack is generated // the name and version fields mustn't be empty @@ -97,20 +102,25 @@ void ExportMrPackDialog::done(int result) if (output.isEmpty()) return; + Task* task; + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + else + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + [this](const QString& path) { return proxy->blockedPaths().covers(path); }); - ModrinthPackExportTask task(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); - - connect(&task, &Task::failed, + connect(task, &Task::failed, [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); - connect(&task, &Task::aborted, [this] { + connect(task, &Task::aborted, [this] { CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information) ->show(); }); + connect(task, &Task::finished, [task] { task->deleteLater(); }); ProgressDialog progress(this); progress.setSkipButton(true, tr("Abort")); - if (progress.execWithTask(&task) != QDialog::Accepted) + if (progress.execWithTask(task) != QDialog::Accepted) return; } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.h b/launcher/ui/dialogs/ExportMrPackDialog.h index 1c70c4ae1..858a31bf9 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.h +++ b/launcher/ui/dialogs/ExportMrPackDialog.h @@ -22,6 +22,7 @@ #include "BaseInstance.h" #include "FastFileIconProvider.h" #include "FileIgnoreProxy.h" +#include "modplatform/ModIndex.h" namespace Ui { class ExportMrPackDialog; @@ -31,7 +32,9 @@ class ExportMrPackDialog : public QDialog { Q_OBJECT public: - explicit ExportMrPackDialog(InstancePtr instance, QWidget* parent = nullptr); + explicit ExportMrPackDialog(InstancePtr instance, + QWidget* parent = nullptr, + ModPlatform::ResourceProvider provider = ModPlatform::ResourceProvider::MODRINTH); ~ExportMrPackDialog(); void done(int result) override; @@ -42,4 +45,5 @@ class ExportMrPackDialog : public QDialog { Ui::ExportMrPackDialog* ui; FileIgnoreProxy* proxy; FastFileIconProvider icons; + const ModPlatform::ResourceProvider m_provider; }; From 377f27b16fbd8adb21d4907101d195ef6f3a9e88 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 20:04:06 +0300 Subject: [PATCH 169/429] Updated slug for url Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportModsToStringTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp index c10560c1c..e7be5ce13 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -97,7 +97,7 @@ QString ExportModsToStringTask(QList mods, QString lineTemplate) if (meta != nullptr) { url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" : "https://modrinth.com/mod/") + - meta->project_id.toString(); + meta->slug.remove(".pw.toml"); } auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) From 3c9c39cb890252f94d0c50caa00de5439881d7f6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 20:04:06 +0300 Subject: [PATCH 170/429] Updated slug for url Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportModsToStringTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp index c10560c1c..e7be5ce13 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -97,7 +97,7 @@ QString ExportModsToStringTask(QList mods, QString lineTemplate) if (meta != nullptr) { url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" : "https://modrinth.com/mod/") + - meta->project_id.toString(); + meta->slug.remove(".pw.toml"); } auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) From 049b02cee46358a3d1dd13769e2c6f4ba27bc55e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 21:06:01 +0300 Subject: [PATCH 171/429] finished up the curesforge export Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 28 +++++++++---------- .../modplatform/flame/FlamePackExportTask.h | 10 ++----- launcher/ui/dialogs/ExportMrPackDialog.cpp | 20 +++++++++---- launcher/ui/dialogs/ExportMrPackDialog.ui | 14 ++++++++-- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 1ae13f72c..4ac2c8ab8 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -28,20 +28,21 @@ #include "MMCZip.h" #include "minecraft/PackProfile.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" #include "modplatform/helpers/ExportModsToStringTask.h" -const QStringList FlamePackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); -const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "zip" }); const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, + const QString& author, const QVariant& projectID, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) : name(name) , version(version) + , author(author) , projectID(projectID) , instance(instance) , mcInstance(dynamic_cast(instance.get())) @@ -193,28 +194,27 @@ QByteArray FlamePackExportTask::generateIndex() QJsonObject loader; if (quilt != nullptr) - loader["id"] = quilt->getName(); + loader["id"] = "quilt-" + quilt->getVersion(); else if (fabric != nullptr) - loader["id"] = fabric->getName(); + loader["id"] = "fabric-" + fabric->getVersion(); else if (forge != nullptr) - loader["id"] = forge->getName(); + loader["id"] = "forge-" + forge->getVersion(); loader["primary"] = true; - version["modLoaders"] = QJsonArray({ loader }); obj["minecraft"] = version; } QJsonArray files; - QMapIterator iterator(resolvedFiles); - while (iterator.hasNext()) { - iterator.next(); - - const ResolvedFile& value = iterator.value(); + for (auto mod : mods) { + auto meta = mod->metadata(); + if (meta == nullptr || meta->provider != ModPlatform::ResourceProvider::FLAME) + continue; + resolvedFiles[gameRoot.relativeFilePath(mod->fileinfo().absoluteFilePath())] = {}; QJsonObject file; - file["projectID"] = value.projectID.toInt(); - file["fileID"] = value.fileID.toInt(); - file["required"] = value.required; + file["projectID"] = meta->project_id.toInt(); + file["fileID"] = meta->file_id.toInt(); + file["required"] = true; files << file; } obj["files"] = files; diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 83927099a..c3cda9267 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -29,6 +29,7 @@ class FlamePackExportTask : public Task { public: FlamePackExportTask(const QString& name, const QString& version, + const QString& author, const QVariant& projectID, InstancePtr instance, const QString& output, @@ -39,13 +40,6 @@ class FlamePackExportTask : public Task { bool abort() override; private: - struct ResolvedFile { - QVariant projectID, fileID; - bool required; - }; - - static const QStringList PREFIXES; - static const QStringList FILE_EXTENSIONS; static const QString TEMPLATE; // inputs @@ -60,7 +54,7 @@ class FlamePackExportTask : public Task { typedef std::optional BuildZipResult; QFileInfoList files; - QMap resolvedFiles; + QMap resolvedFiles; Task::Ptr task; QFuture buildZipFuture; QFutureWatcher buildZipWatcher; diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 16ef526a8..aaa528aa1 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -39,10 +39,13 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo { ui->setupUi(this); ui->name->setText(instance->name()); - if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); - else + ui->author->hide(); + ui->authorLabel->hide(); + } else { ui->summaryLabel->setText("ProjectID"); + } // ensure a valid pack is generated // the name and version fields mustn't be empty @@ -96,9 +99,14 @@ void ExportMrPackDialog::done(int result) { if (result == Accepted) { const QString filename = FS::RemoveInvalidFilenameChars(ui->name->text()); - const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), - FS::PathCombine(QDir::homePath(), filename + ".mrpack"), - "Modrinth pack (*.mrpack *.zip)", nullptr); + QString output; + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), + FS::PathCombine(QDir::homePath(), filename + ".mrpack"), "Modrinth pack (*.mrpack *.zip)", + nullptr); + else + output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), + FS::PathCombine(QDir::homePath(), filename + ".zip"), "Curseforge pack (*.zip)", nullptr); if (output.isEmpty()) return; @@ -107,7 +115,7 @@ void ExportMrPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index 9a7897378..59ecb17c0 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -24,7 +24,7 @@
    - + Summary @@ -41,7 +41,7 @@ - + Version @@ -57,6 +57,16 @@ + + + + Author + + + + + + From 85495c794de2b7c9ae64bbf43156b3e4e6ecfed0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 21:12:02 +0300 Subject: [PATCH 172/429] changed map tipe Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/modplatform/flame/FlamePackExportTask.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 4ac2c8ab8..6114f1b16 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -209,7 +209,7 @@ QByteArray FlamePackExportTask::generateIndex() auto meta = mod->metadata(); if (meta == nullptr || meta->provider != ModPlatform::ResourceProvider::FLAME) continue; - resolvedFiles[gameRoot.relativeFilePath(mod->fileinfo().absoluteFilePath())] = {}; + resolvedFiles[gameRoot.relativeFilePath(mod->fileinfo().absoluteFilePath())] = true; QJsonObject file; file["projectID"] = meta->project_id.toInt(); diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index c3cda9267..370cd67e4 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -54,7 +54,7 @@ class FlamePackExportTask : public Task { typedef std::optional BuildZipResult; QFileInfoList files; - QMap resolvedFiles; + QMap resolvedFiles; Task::Ptr task; QFuture buildZipFuture; QFutureWatcher buildZipWatcher; From 03361e51efb20802c419e15228e8dc086c4d273b Mon Sep 17 00:00:00 2001 From: seth Date: Thu, 22 Jun 2023 15:58:53 -0400 Subject: [PATCH 173/429] chore: add 'suggest a feature' message in help Signed-off-by: seth --- launcher/ui/MainWindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index f67fb1859..113dfc1e0 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -577,7 +577,7 @@ .. - Report a &Bug... + Report a Bug or Suggest a Feature Open the bug tracker to report a bug with %1. From a4521ac0bbd0472c0f8bbf184d1b2f5b54ed8e0b Mon Sep 17 00:00:00 2001 From: seth Date: Thu, 22 Jun 2023 16:15:03 -0400 Subject: [PATCH 174/429] chore: avoid confusion in file/url import dialog Signed-off-by: seth --- launcher/ui/pages/modplatform/ImportPage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/ImportPage.h b/launcher/ui/pages/modplatform/ImportPage.h index 8d13ac100..c2acb92da 100644 --- a/launcher/ui/pages/modplatform/ImportPage.h +++ b/launcher/ui/pages/modplatform/ImportPage.h @@ -57,7 +57,7 @@ public: virtual ~ImportPage(); virtual QString displayName() const override { - return tr("Import from zip"); + return tr("Import"); } virtual QIcon icon() const override { From bf95cfb30eee52f23d0279284f70931b2c968dd3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 01:37:28 +0300 Subject: [PATCH 175/429] Added CatPacks Signed-off-by: Trial97 --- launcher/Application.cpp | 12 +- launcher/Application.h | 9 +- launcher/CMakeLists.txt | 2 + launcher/ui/MainWindow.cpp | 4 +- launcher/ui/setupwizard/ThemeWizardPage.cpp | 2 +- launcher/ui/themes/CatPack.cpp | 109 ++++++++++++++++++ launcher/ui/themes/CatPack.h | 98 ++++++++++++++++ launcher/ui/themes/ThemeManager.cpp | 82 ++++++++++--- launcher/ui/themes/ThemeManager.h | 15 ++- .../ui/widgets/ThemeCustomizationWidget.cpp | 17 ++- .../ui/widgets/ThemeCustomizationWidget.h | 34 +++--- 11 files changed, 331 insertions(+), 53 deletions(-) create mode 100644 launcher/ui/themes/CatPack.cpp create mode 100644 launcher/ui/themes/CatPack.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 724e6e44d..d8ac2168d 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1173,7 +1173,17 @@ QIcon Application::getThemedIcon(const QString& name) return QIcon::fromTheme(name); } -bool Application::openJsonEditor(const QString &filename) +QList Application::getValidCatPacks() +{ + return m_themeManager->getValidCatPacks(); +} + +QString Application::getCatPack(QString catName) +{ + return m_themeManager->getCatPack(catName); +} + +bool Application::openJsonEditor(const QString& filename) { const QString file = QDir::current().absoluteFilePath(filename); if (m_settings->get("JsonEditor").toString().isEmpty()) diff --git a/launcher/Application.h b/launcher/Application.h index ced0af17d..55b01cd49 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -48,6 +48,7 @@ #include #include "minecraft/launch/MinecraftServerTarget.h" +#include "ui/themes/CatPack.h" class LaunchController; class LocalPeer; @@ -126,9 +127,11 @@ public: void setApplicationTheme(const QString& name); - shared_qobject_ptr updater() { - return m_updater; - } + QList getValidCatPacks(); + + QString getCatPack(QString catName = ""); + + shared_qobject_ptr updater() { return m_updater; } void triggerUpdateCheck(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index ce2771a49..4d0f7d06e 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -755,6 +755,8 @@ SET(LAUNCHER_SOURCES ui/themes/SystemTheme.h ui/themes/ThemeManager.cpp ui/themes/ThemeManager.h + ui/themes/CatPack.cpp + ui/themes/CatPack.h # Processes LaunchController.h diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e04011cab..8e1b56136 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -924,14 +924,14 @@ void MainWindow::setCatBackground(bool enabled) view->setStyleSheet(QString(R"( InstanceView { - background-image: url(:/backgrounds/%1); + background-image: url(%1); background-attachment: fixed; background-clip: padding; background-position: bottom right; background-repeat: none; background-color:palette(base); })") - .arg(ThemeManager::getCatImage())); + .arg(APPLICATION->getCatPack())); } else { view->setStyleSheet(QString()); } diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp index 42826aba1..282a01acb 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.cpp +++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp @@ -61,7 +61,7 @@ void ThemeWizardPage::updateIcons() void ThemeWizardPage::updateCat() { qDebug() << "Setting Cat"; - ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(ThemeManager::getCatImage()))); + ui->catImagePreviewButton->setIcon(QIcon(QString(R"(%1)").arg(APPLICATION->getCatPack()))); } void ThemeWizardPage::retranslate() diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp new file mode 100644 index 000000000..e74b9709a --- /dev/null +++ b/launcher/ui/themes/CatPack.cpp @@ -0,0 +1,109 @@ +// 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 "ui/themes/CatPack.h" +#include +#include +#include +#include +#include +#include +#include +#include "FileSystem.h" +#include "Json.h" +#include "ui/themes/ThemeManager.h" + +QString BasicCatPack::path() +{ + const QDateTime now = QDateTime::currentDateTime(); + const QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); + const QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); + const QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0)); + + QString cat = QString(":/backgrounds/%1").arg(m_id); + if (std::abs(now.daysTo(xmas)) <= 4) { + cat += "-xmas"; + } else if (std::abs(now.daysTo(halloween)) <= 4) { + cat += "-spooky"; + } else if (std::abs(now.daysTo(birthday)) <= 12) { + cat += "-bday"; + } + return cat; +} + +JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.dir().dirName()) +{ + QString path = FS::PathCombine("catpacks", m_id); + + if (!FS::ensureFolderPathExists(path)) { + themeWarningLog() << "couldn't create folder for catpack!"; + return; + } + + if (manifestInfo.exists() && manifestInfo.isFile()) { + try { + auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); + const auto root = doc.object(); + m_name = Json::requireString(root, "name", "Catpack name"); + m_id = Json::requireString(root, "id", "Catpack ID"); + m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); + auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); + for (auto v : variants) { + auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); + m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), + date(Json::requireString(variant, "startTime", "Variant startTime")), + date(Json::requireString(variant, "endTime", "Variant endTime")) }; + } + + } catch (const Exception& e) { + themeWarningLog() << "Couldn't load catpack json: " << e.cause(); + return; + } + } else { + themeDebugLog() << "No catpack json present."; + } +} + +QString JsonCatPack::path() +{ + const QDateTime now = QDateTime::currentDateTime(); + for (auto var : m_variants) { + QDateTime startDate(QDate(now.date().year(), var.startTime.mounth, var.startTime.day), QTime(0, 0)); + QDateTime endDate(QDate(now.date().year(), var.endTime.mounth, var.endTime.day), QTime(0, 0)); + if (startDate.daysTo(now) > 0 && now.daysTo(endDate) > 0) + return var.path; + } + return m_defaultPath; +} diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h new file mode 100644 index 000000000..d9010b8ea --- /dev/null +++ b/launcher/ui/themes/CatPack.h @@ -0,0 +1,98 @@ +// 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 +#include +#include +#include + +class CatPack { + public: + virtual ~CatPack() {} + virtual QString id() = 0; + virtual QString name() = 0; + virtual QString path() = 0; +}; + +class BasicCatPack : public CatPack { + public: + BasicCatPack(QString id, QString name) : m_id(id), m_name(name) {} + BasicCatPack(QString id) : BasicCatPack(id, id) {} + virtual QString id() { return m_id; }; + virtual QString name() { return m_name; }; + virtual QString path(); + + protected: + QString m_id; + QString m_name; +}; + +class FileCatPack : public BasicCatPack { + public: + FileCatPack(QString id, QFileInfo& fileInfo) : BasicCatPack(id), m_path(fileInfo.absoluteFilePath()) {} + FileCatPack(QFileInfo& fileInfo) : FileCatPack(fileInfo.baseName(), fileInfo) {} + virtual QString path() { return m_path; } + + private: + QString m_path; +}; + +class JsonCatPack : public BasicCatPack { + public: + struct date { + date(QString d) + { + auto sp = d.split("-"); + day = sp[0].toInt(); + if (sp.length() >= 2) + mounth = sp[1].length(); + } + int mounth; + int day; + }; + struct Variant { + QString path; + date startTime; + date endTime; + }; + JsonCatPack(QFileInfo& manifestInfo); + virtual QString path(); + + private: + QString m_defaultPath; + QList m_variants; +}; diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 94ac8a245..bfd0550a8 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -22,6 +22,7 @@ #include #include #include "ui/themes/BrightTheme.h" +#include "ui/themes/CatPack.h" #include "ui/themes/CustomTheme.h" #include "ui/themes/DarkTheme.h" #include "ui/themes/SystemTheme.h" @@ -32,6 +33,7 @@ ThemeManager::ThemeManager(MainWindow* mainWindow) { m_mainWindow = mainWindow; initializeThemes(); + initializeCatPacks(); } /// @brief Adds the Theme to the list of themes @@ -111,6 +113,16 @@ QList ThemeManager::getValidApplicationThemes() return ret; } +QList ThemeManager::getValidCatPacks() +{ + QList ret; + ret.reserve(m_catPacks.size()); + for (auto&& [id, theme] : m_catPacks) { + ret.append(theme.get()); + } + return ret; +} + void ThemeManager::setIconTheme(const QString& name) { QIcon::setThemeName(name); @@ -137,19 +149,63 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial) } } -QString ThemeManager::getCatImage(QString catName) +QString ThemeManager::getCatPack(QString catName) { - QDateTime now = QDateTime::currentDateTime(); - QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); - QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); - QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0)); - QString cat = !catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString(); - if (std::abs(now.daysTo(xmas)) <= 4) { - cat += "-xmas"; - } else if (std::abs(now.daysTo(halloween)) <= 4) { - cat += "-spooky"; - } else if (std::abs(now.daysTo(birthday)) <= 12) { - cat += "-bday"; + auto catIter = m_catPacks.find(!catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString()); + if (catIter != m_catPacks.end()) { + auto& catPack = catIter->second; + themeDebugLog() << "applying catpack" << catPack->id(); + return catPack->path(); + } else { + themeWarningLog() << "Tried to get invalid catPack:" << catName; + } + + return m_catPacks.begin()->second->path(); +} + +QString ThemeManager::addCatPack(std::unique_ptr catPack) +{ + QString id = catPack->id(); + m_catPacks.emplace(id, std::move(catPack)); + return id; +} + +void ThemeManager::initializeCatPacks() +{ + QList> defaultCats{ { "kitteh", QObject::tr("Background Cat (from MultiMC)") }, + { "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") }, + { "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") }, + { "teawie", QObject::tr("Teawie (drawn by SympathyTea)") } }; + for (auto [id, name] : defaultCats) { + addCatPack(std::unique_ptr(new BasicCatPack(id, name))); + } + QDir catpacksDir("./catpacks/"); + QString catpacksFolder = catpacksDir.absoluteFilePath(""); + themeDebugLog() << "CatPacks Folder Path: " << catpacksFolder; + + auto loadFiles = [this](QDir dir) { + // Load image files directly + QDirIterator ImageFileIterator(dir.absoluteFilePath(""), { "*.png", "*.gif", "*.jpg", "*.apng", "*.jxl", "*.avif" }, QDir::Files); + while (ImageFileIterator.hasNext()) { + QFile customCatFile(ImageFileIterator.next()); + QFileInfo customCatFileInfo(customCatFile); + themeDebugLog() << "Loading QSS Theme from:" << customCatFileInfo.absoluteFilePath(); + addCatPack(std::unique_ptr(new FileCatPack(customCatFileInfo))); + } + }; + + loadFiles(catpacksDir); + + QDirIterator directoryIterator(catpacksFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (directoryIterator.hasNext()) { + QDir dir(directoryIterator.next()); + QFileInfo manifest(dir.absoluteFilePath("catpack.json")); + if (manifest.exists()) { + // Load background manifest + themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); + addCatPack(std::unique_ptr(new JsonCatPack(manifest))); + } else { + loadFiles(dir); + } } - return cat; } diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index 87f36d9c1..bc0d31cd0 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -20,6 +20,7 @@ #include #include "ui/MainWindow.h" +#include "ui/themes/CatPack.h" #include "ui/themes/ITheme.h" inline auto themeDebugLog() @@ -40,18 +41,20 @@ class ThemeManager { void applyCurrentlySelectedTheme(bool initial = false); void setApplicationTheme(const QString& name, bool initial = false); - /// - /// Returns the cat based on selected cat and with events (Birthday, XMas, etc.) - /// - /// Optional, if you need a specific cat. - /// - static QString getCatImage(QString catName = ""); + /// @brief Returns the background based on selected and with events (Birthday, XMas, etc.) + /// @param catName Optional, if you need a specific background. + /// @return + QString getCatPack(QString catName = ""); + QList getValidCatPacks(); private: std::map> m_themes; + std::map> m_catPacks; MainWindow* m_mainWindow; void initializeThemes(); + void initializeCatPacks(); QString addTheme(std::unique_ptr theme); ITheme* getTheme(QString themeId); + QString addCatPack(std::unique_ptr catPack); }; diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp index dcf13303c..e2c5ce3d7 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp @@ -95,9 +95,14 @@ void ThemeCustomizationWidget::applyWidgetTheme(int index) { emit currentWidgetThemeChanged(index); } -void ThemeCustomizationWidget::applyCatTheme(int index) { +void ThemeCustomizationWidget::applyCatTheme(int index) +{ auto settings = APPLICATION->settings(); - settings->set("BackgroundCat", m_catOptions[index].first); + auto originalCat = settings->get("BackgroundCat").toString(); + auto newCat = ui->backgroundCatComboBox->currentData().toString(); + if (originalCat != newCat) { + settings->set("BackgroundCat", newCat); + } emit currentCatChanged(index); } @@ -135,10 +140,10 @@ void ThemeCustomizationWidget::loadSettings() } auto cat = settings->get("BackgroundCat").toString(); - for (auto& catFromList : m_catOptions) { - QIcon catIcon = QIcon(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage(catFromList.first))); - ui->backgroundCatComboBox->addItem(catIcon, catFromList.second); - if (cat == catFromList.first) { + for (auto& catFromList : APPLICATION->getValidCatPacks()) { + QIcon catIcon = QIcon(QString("%1").arg(catFromList->path())); + ui->backgroundCatComboBox->addItem(catIcon, catFromList->name(), catFromList->id()); + if (cat == catFromList->id()) { ui->backgroundCatComboBox->setCurrentIndex(ui->backgroundCatComboBox->count() - 1); } } diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h index d955a2665..be204e57c 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.h +++ b/launcher/ui/widgets/ThemeCustomizationWidget.h @@ -53,25 +53,17 @@ class ThemeCustomizationWidget : public QWidget { private: Ui::ThemeCustomizationWidget* ui; - //TODO finish implementing - QList> m_iconThemeOptions{ - { "pe_colored", QObject::tr("Simple (Colored Icons)") }, - { "pe_light", QObject::tr("Simple (Light Icons)") }, - { "pe_dark", QObject::tr("Simple (Dark Icons)") }, - { "pe_blue", QObject::tr("Simple (Blue Icons)") }, - { "breeze_light", QObject::tr("Breeze Light") }, - { "breeze_dark", QObject::tr("Breeze Dark") }, - { "OSX", QObject::tr("OSX") }, - { "iOS", QObject::tr("iOS") }, - { "flat", QObject::tr("Flat") }, - { "flat_white", QObject::tr("Flat (White)") }, - { "multimc", QObject::tr("Legacy") }, - { "custom", QObject::tr("Custom") } - }; - QList> m_catOptions{ - { "kitteh", QObject::tr("Background Cat (from MultiMC)") }, - { "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") }, - { "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") }, - { "teawie", QObject::tr("Teawie (drawn by SympathyTea)") } - }; + // TODO finish implementing + QList> m_iconThemeOptions{ { "pe_colored", QObject::tr("Simple (Colored Icons)") }, + { "pe_light", QObject::tr("Simple (Light Icons)") }, + { "pe_dark", QObject::tr("Simple (Dark Icons)") }, + { "pe_blue", QObject::tr("Simple (Blue Icons)") }, + { "breeze_light", QObject::tr("Breeze Light") }, + { "breeze_dark", QObject::tr("Breeze Dark") }, + { "OSX", QObject::tr("OSX") }, + { "iOS", QObject::tr("iOS") }, + { "flat", QObject::tr("Flat") }, + { "flat_white", QObject::tr("Flat (White)") }, + { "multimc", QObject::tr("Legacy") }, + { "custom", QObject::tr("Custom") } }; }; From 718aca3d066fc24c03b7ac6d625d68829fcaa427 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 09:24:18 +0300 Subject: [PATCH 176/429] Fixed date constructor Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index d9010b8ea..9f288d3dd 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -79,7 +79,7 @@ class JsonCatPack : public BasicCatPack { auto sp = d.split("-"); day = sp[0].toInt(); if (sp.length() >= 2) - mounth = sp[1].length(); + mounth = sp[1].toInt(); } int mounth; int day; From 763b3c323613473a1d9678e15f92a712884ab7c3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 10:38:26 +0300 Subject: [PATCH 177/429] Added Thumbs.db to excluded files in MrPackExport Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportMrPackDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 561b92e40..60ecefd5c 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -53,7 +53,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); proxy->setSourceModel(model); - proxy->setFilterRegularExpression("^(?!\\.DS_Store).+$"); + proxy->setFilterRegularExpression("^(?!(\\.DS_Store)|([tT]humbs\\.db)).+$"); const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); From f8adb508ab0152af76829e0fdee92b451dcc1acf Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 11:44:40 +0300 Subject: [PATCH 178/429] Made catpack id optional in catpack.json Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index e74b9709a..2d5653a67 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -77,7 +77,8 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); const auto root = doc.object(); m_name = Json::requireString(root, "name", "Catpack name"); - m_id = Json::requireString(root, "id", "Catpack ID"); + auto id = Json::ensureString(root, "id", "", "Catpack ID"); + m_id = id.isEmpty() ? m_id : id; m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); for (auto v : variants) { From c5ea8367aaf9d61a6362427a55206d8891f40cda Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Fri, 23 Jun 2023 14:25:21 +0300 Subject: [PATCH 179/429] Update launcher/ui/themes/CatPack.cpp Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/themes/CatPack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 2d5653a67..bee632029 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -78,7 +78,8 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di const auto root = doc.object(); m_name = Json::requireString(root, "name", "Catpack name"); auto id = Json::ensureString(root, "id", "", "Catpack ID"); - m_id = id.isEmpty() ? m_id : id; + if (!id.isEmpty()) + m_id = id; m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); for (auto v : variants) { From 67db141203864123f65d93723e7eed43328b8d97 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 14:38:23 +0300 Subject: [PATCH 180/429] Renamed getResults to resultsReady Signed-off-by: Trial97 --- launcher/modplatform/EnsureMetadataTask.cpp | 4 ++-- launcher/modplatform/atlauncher/ATLPackInstallTask.cpp | 2 +- launcher/modplatform/helpers/HashUtils.cpp | 2 +- launcher/modplatform/helpers/HashUtils.h | 2 +- launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index a04a2534c..93b5ce76c 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -25,7 +25,7 @@ EnsureMetadataTask::EnsureMetadataTask(Mod* mod, QDir dir, ModPlatform::Resource auto hash_task = createNewHash(mod); if (!hash_task) return; - connect(hash_task.get(), &Hashing::Hasher::getResults, [this, mod](QString hash) { m_mods.insert(hash, mod); }); + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { m_mods.insert(hash, mod); }); connect(hash_task.get(), &Task::failed, [this, mod] { emitFail(mod, "", RemoveFromList::No); }); hash_task->start(); } @@ -38,7 +38,7 @@ EnsureMetadataTask::EnsureMetadataTask(QList& mods, QDir dir, ModPlatform: auto hash_task = createNewHash(mod); if (!hash_task) continue; - connect(hash_task.get(), &Hashing::Hasher::getResults, [this, mod](QString hash) { m_mods.insert(hash, mod); }); + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { m_mods.insert(hash, mod); }); connect(hash_task.get(), &Task::failed, [this, mod] { emitFail(mod, "", RemoveFromList::No); }); m_hashing_task->addTask(hash_task); } diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 2522020da..22ea02da2 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -100,7 +100,7 @@ void PackInstallTask::onDownloadSucceeded() jobPtr.reset(); QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response.get(), &parse_error); + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from ATLauncher at " << parse_error.offset << " reason: " << parse_error.errorString(); diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index 6df1eaf98..7d188a2f1 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -71,7 +71,7 @@ void ModrinthHasher::executeTask() emitFailed("Empty hash!"); } else { emitSucceeded(); - emit getResults(m_hash); + emit resultsReady(m_hash); } } diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index a541ae8fa..73a2435a2 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -23,7 +23,7 @@ class Hasher : public Task { QString getPath() const { return m_path; }; signals: - void getResults(QString hash); + void resultsReady(QString hash); protected: QString m_hash; diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 36002bad9..a7c22832a 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -53,7 +53,7 @@ void ModrinthCheckUpdate::executeTask() // (though it will rarely happen, if at all) if (mod->metadata()->hash_format != best_hash_type) { auto hash_task = Hashing::createModrinthHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::getResults, [&hashes, &mappings, mod](QString hash) { + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [&hashes, &mappings, mod](QString hash) { hashes.append(hash); mappings.insert(hash, mod); }); From 0a566318315c4e1566cb4ef7c99321a025e998a2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 19:35:41 +0300 Subject: [PATCH 181/429] Added curseforge search Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 130 ++++++++++++++++-- .../modplatform/flame/FlamePackExportTask.h | 13 +- launcher/ui/dialogs/ExportMrPackDialog.cpp | 5 +- 3 files changed, 133 insertions(+), 15 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 6114f1b16..7130b502e 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -24,12 +24,15 @@ #include #include #include +#include #include "Json.h" #include "MMCZip.h" #include "minecraft/PackProfile.h" +#include "minecraft/mod/ModDetails.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" #include "modplatform/helpers/ExportModsToStringTask.h" +#include "modplatform/helpers/HashUtils.h" const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; @@ -88,13 +91,118 @@ void FlamePackExportTask::collectFiles() return; } + pendingHashes.clear(); resolvedFiles.clear(); - mcInstance->loaderModList()->update(); - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { - mods = mcInstance->loaderModList()->allMods(); + if (mcInstance) { + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { + mods = mcInstance->loaderModList()->allMods(); + collectHashes(); + }); + } else + collectHashes(); +} + +void FlamePackExportTask::collectHashes() +{ + ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); + for (auto* mod : mods) { + if (!mod || !mod->valid() || mod->type() == ResourceType::FOLDER) + continue; + if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { + resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled() }); + continue; + } + + auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); + connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { pendingHashes.insert(hash_task->getResult(), mod); }); + connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + connect(hash_task.get(), &Task::finished, [hash_task] { hash_task->deleteLater(); }); + hashing_task->addTask(hash_task); + } + connect(hashing_task.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); + connect(hashing_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + connect(hashing_task.get(), &Task::finished, [hashing_task] { hashing_task->deleteLater(); }); + hashing_task->start(); +} + +void FlamePackExportTask::makeApiRequest() +{ + setAbortable(true); + if (pendingHashes.isEmpty()) { + buildZip(); + return; + } + + auto response = std::make_shared(); + + QList fingerprints; + for (auto& murmur : pendingHashes.keys()) { + fingerprints.push_back(murmur.toUInt()); + } + + auto task = api.matchFingerprints(fingerprints, response.get()); + + connect(task.get(), &Task::succeeded, this, [this, response] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + + failed(parse_error.errorString()); + return; + } + + try { + auto doc_obj = Json::requireObject(doc); + auto data_obj = Json::requireObject(doc_obj, "data"); + auto data_arr = Json::requireArray(data_obj, "exactMatches"); + + if (data_arr.isEmpty()) { + qWarning() << "No matches found for fingerprint search!"; + + return; + } + + for (auto match : data_arr) { + auto match_obj = Json::ensureObject(match, {}); + auto file_obj = Json::ensureObject(match_obj, "file", {}); + + if (match_obj.isEmpty() || file_obj.isEmpty()) { + qWarning() << "Fingerprint match is empty!"; + + return; + } + + auto fingerprint = QString::number(Json::ensureVariant(file_obj, "fileFingerprint").toUInt()); + auto mod = pendingHashes.find(fingerprint); + if (mod == pendingHashes.end()) { + qWarning() << "Invalid fingerprint from the API response."; + continue; + } + + setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name())); + + resolvedFiles.insert( + mod.value()->fileinfo().absoluteFilePath(), + { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "modId"), mod.value()->enabled() }); + } + + } catch (Json::JsonException& e) { + qDebug() << e.cause(); + qDebug() << doc; + } + pendingHashes.clear(); buildZip(); }); + + connect(task.get(), &NetJob::finished, [task]() { task->deleteLater(); }); + connect(task.get(), &NetJob::failed, this, &FlamePackExportTask::emitFailed); + task->start(); } void FlamePackExportTask::buildZip() @@ -177,7 +285,8 @@ QByteArray FlamePackExportTask::generateIndex() obj["name"] = name; obj["version"] = version; obj["author"] = author; - obj["projectID"] = projectID.toInt(); + if (projectID.toInt() != 0) + obj["projectID"] = projectID.toInt(); obj["overrides"] = "overrides"; if (mcInstance) { QJsonObject version; @@ -205,16 +314,11 @@ QByteArray FlamePackExportTask::generateIndex() } QJsonArray files; - for (auto mod : mods) { - auto meta = mod->metadata(); - if (meta == nullptr || meta->provider != ModPlatform::ResourceProvider::FLAME) - continue; - resolvedFiles[gameRoot.relativeFilePath(mod->fileinfo().absoluteFilePath())] = true; - + for (auto mod : resolvedFiles) { QJsonObject file; - file["projectID"] = meta->project_id.toInt(); - file["fileID"] = meta->file_id.toInt(); - file["required"] = true; + file["projectID"] = mod.addonId; + file["fileID"] = mod.version; + file["required"] = mod.enabled; files << file; } obj["files"] = files; diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 370cd67e4..58f66cc52 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -23,6 +23,7 @@ #include "BaseInstance.h" #include "MMCZip.h" #include "minecraft/MinecraftInstance.h" +#include "modplatform/flame/FlameAPI.h" #include "tasks/Task.h" class FlamePackExportTask : public Task { @@ -52,15 +53,25 @@ class FlamePackExportTask : public Task { const MMCZip::FilterFunction filter; typedef std::optional BuildZipResult; + struct ResolvedFile { + int addonId; + int version; + bool enabled; + }; + + FlameAPI api; QFileInfoList files; - QMap resolvedFiles; + QMap pendingHashes; + QMap resolvedFiles; Task::Ptr task; QFuture buildZipFuture; QFutureWatcher buildZipWatcher; QList mods; void collectFiles(); + void collectHashes(); + void makeApiRequest(); void buildZip(); void finish(); diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index aaa528aa1..3711bb8fb 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -44,6 +44,8 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo ui->author->hide(); ui->authorLabel->hide(); } else { + setWindowTitle("Export CurseForge Pack"); + ui->version->setText(""); ui->summaryLabel->setText("ProjectID"); } @@ -137,6 +139,7 @@ void ExportMrPackDialog::done(int result) void ExportMrPackDialog::validate() { - const bool invalid = ui->name->text().isEmpty() || ui->version->text().isEmpty(); + const bool invalid = + ui->name->text().isEmpty() || ((m_provider == ModPlatform::ResourceProvider::MODRINTH) && ui->version->text().isEmpty()); ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(invalid); } From 222a10891c103d1357448d6aaff5da8d94e576af Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 19:41:55 +0300 Subject: [PATCH 182/429] Fixed merge Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 7130b502e..28c62f534 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -143,7 +143,7 @@ void FlamePackExportTask::makeApiRequest() fingerprints.push_back(murmur.toUInt()); } - auto task = api.matchFingerprints(fingerprints, response.get()); + auto task = api.matchFingerprints(fingerprints, response); connect(task.get(), &Task::succeeded, this, [this, response] { QJsonParseError parse_error{}; From 28de461067b0fec69ebcb9bdcd213d02244b39bb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 21:38:41 +0300 Subject: [PATCH 183/429] Fixed hashers Signed-off-by: Trial97 --- launcher/modplatform/helpers/HashUtils.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index 7d188a2f1..6ff1d1710 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -89,6 +89,7 @@ void FlameHasher::executeTask() emitFailed("Empty hash!"); } else { emitSucceeded(); + emit resultsReady(m_hash); } } @@ -120,6 +121,7 @@ void BlockedModHasher::executeTask() emitFailed("Empty hash!"); } else { emitSucceeded(); + emit resultsReady(m_hash); } } From 823cd3862d15f8e9d47cdc5fc8662a20f774567a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 22:41:01 +0300 Subject: [PATCH 184/429] Fixed hash checking Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 41 +++++++++++-------- .../modplatform/flame/FlamePackExportTask.h | 5 +-- launcher/modplatform/helpers/HashUtils.cpp | 2 + 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 28c62f534..880d4324c 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -28,11 +28,11 @@ #include "Json.h" #include "MMCZip.h" #include "minecraft/PackProfile.h" -#include "minecraft/mod/ModDetails.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" #include "modplatform/helpers/ExportModsToStringTask.h" #include "modplatform/helpers/HashUtils.h" +#include "tasks/Task.h" const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; @@ -94,43 +94,51 @@ void FlamePackExportTask::collectFiles() pendingHashes.clear(); resolvedFiles.clear(); - if (mcInstance) { + if (mcInstance != nullptr) { + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes); mcInstance->loaderModList()->update(); - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { - mods = mcInstance->loaderModList()->allMods(); - collectHashes(); - }); } else collectHashes(); } void FlamePackExportTask::collectHashes() { + setAbortable(true); + setStatus(tr("Find file hashes...")); + auto mods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); + task.reset(hashing_task); + setProgress(0, mods.count()); for (auto* mod : mods) { - if (!mod || !mod->valid() || mod->type() == ResourceType::FOLDER) + if (!mod || mod->type() == ResourceType::FOLDER) { + setProgress(m_progress + 1, mods.count()); continue; + } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled() }); + setProgress(m_progress + 1, mods.count()); continue; } auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { pendingHashes.insert(hash_task->getResult(), mod); }); + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, mods](QString hash) { + if (m_state == Task::State::Running) { + setProgress(m_progress + 1, mods.count()); + pendingHashes.insert(hash, mod); + } + }); connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); - connect(hash_task.get(), &Task::finished, [hash_task] { hash_task->deleteLater(); }); hashing_task->addTask(hash_task); } connect(hashing_task.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); connect(hashing_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); - connect(hashing_task.get(), &Task::finished, [hashing_task] { hashing_task->deleteLater(); }); hashing_task->start(); } void FlamePackExportTask::makeApiRequest() { - setAbortable(true); + setStatus(tr("Find versions for hashes...")); if (pendingHashes.isEmpty()) { buildZip(); return; @@ -143,7 +151,7 @@ void FlamePackExportTask::makeApiRequest() fingerprints.push_back(murmur.toUInt()); } - auto task = api.matchFingerprints(fingerprints, response); + task.reset(api.matchFingerprints(fingerprints, response)); connect(task.get(), &Task::succeeded, this, [this, response] { QJsonParseError parse_error{}; @@ -167,8 +175,9 @@ void FlamePackExportTask::makeApiRequest() return; } - + size_t progress = 0; for (auto match : data_arr) { + setProgress(progress++, data_arr.count()); auto match_obj = Json::ensureObject(match, {}); auto file_obj = Json::ensureObject(match_obj, "file", {}); @@ -200,7 +209,6 @@ void FlamePackExportTask::makeApiRequest() buildZip(); }); - connect(task.get(), &NetJob::finished, [task]() { task->deleteLater(); }); connect(task.get(), &NetJob::failed, this, &FlamePackExportTask::emitFailed); task->start(); } @@ -231,7 +239,7 @@ void FlamePackExportTask::buildZip() QFile::remove(output); return BuildZipResult(tr("Could not create index")); } - QString content = ExportToString::ExportModsToStringTask(mods, TEMPLATE); + QString content = ExportToString::ExportModsToStringTask(mcInstance->loaderModList()->allMods(), TEMPLATE); content = "
      " + content + "
    "; modlist.write(content.toUtf8()); @@ -244,7 +252,8 @@ void FlamePackExportTask::buildZip() setProgress(progress, files.length()); const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!resolvedFiles.contains(relative) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { + if (!resolvedFiles.contains(file.absoluteFilePath()) && + !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { QFile::remove(output); return BuildZipResult(tr("Could not read and compress %1").arg(relative)); } diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 58f66cc52..f00696788 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -62,12 +62,11 @@ class FlamePackExportTask : public Task { FlameAPI api; QFileInfoList files; - QMap pendingHashes; - QMap resolvedFiles; + QMap pendingHashes{}; + QMap resolvedFiles{}; Task::Ptr task; QFuture buildZipFuture; QFutureWatcher buildZipWatcher; - QList mods; void collectFiles(); void collectHashes(); diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index 7d188a2f1..6ff1d1710 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -89,6 +89,7 @@ void FlameHasher::executeTask() emitFailed("Empty hash!"); } else { emitSucceeded(); + emit resultsReady(m_hash); } } @@ -120,6 +121,7 @@ void BlockedModHasher::executeTask() emitFailed("Empty hash!"); } else { emitSucceeded(); + emit resultsReady(m_hash); } } From 750209b8bbeaf75b93a6ae6e55d9192c38fd6f7d Mon Sep 17 00:00:00 2001 From: leo78913 Date: Fri, 23 Jun 2023 16:55:51 -0300 Subject: [PATCH 185/429] fix: fix crash when hiding columns on resource packs page Signed-off-by: leo78913 --- launcher/minecraft/mod/ResourcePackFolderModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 14a28b471..41455599b 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -53,7 +53,7 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE}; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents}; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; } From d74a23d5b217195e71cce47a07e2141b0eaa9fc3 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 23 Jun 2023 21:00:55 +0100 Subject: [PATCH 186/429] Update developers Signed-off-by: TheKodeToad --- launcher/ui/dialogs/AboutDialog.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 76e3d8ed0..88739463f 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -71,13 +71,18 @@ QString getCreditsHtml() //: %1 is the name of the launcher, determined at build time, e.g. "Prism Launcher Developers" stream << "

    " << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "

    \n"; stream << QString("

    Sefa Eyeoglu (Scrumplex) %1

    \n") .arg(getWebsite("https://scrumplex.net")); - stream << QString("

    dada513 %1

    \n") .arg(getGitHub("dada513")); + stream << QString("

    d-513 %1

    \n") .arg(getGitHub("d-513")); stream << QString("

    txtsd %1

    \n") .arg(getWebsite("https://ihavea.quest")); stream << QString("

    timoreo %1

    \n") .arg(getGitHub("timoreo22")); stream << QString("

    Ezekiel Smith (ZekeSmith) %1

    \n") .arg(getGitHub("ZekeSmith")); stream << QString("

    cozyGalvinism %1

    \n") .arg(getGitHub("cozyGalvinism")); - stream << QString("

    DioEgizio %1

    \n") .arg(getGitHub("DioEgizio")); - stream << QString("

    flowln %1

    \n") .arg(getGitHub("flowln")); + stream << QString("

    DioEgizio %1

    \n") .arg(getGitHub("DioEgizio")); + stream << QString("

    flowln %1

    \n") .arg(getGitHub("flowln")); + stream << QString("

    ViRb3 %1

    \n") .arg(getGitHub("ViRb3")); + stream << QString("

    Rachel Powers (Ryex) %1

    \n") .arg(getGitHub("Ryex")); + stream << QString("

    TayouVR %1

    \n") .arg(getGitHub("TayouVR")); + stream << QString("

    TheKodeToad %1

    \n") .arg(getGitHub("TheKodeToad")); + stream << QString("

    getchoo %1

    \n") .arg(getGitHub("getchoo")); stream << "
    \n"; // TODO: possibly retrieve from git history at build time? From cf94adb363c1ae791ebd6f0149899f63c78bfb1b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 01:05:49 +0300 Subject: [PATCH 187/429] Added some warnings Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 7 + launcher/minecraft/mod/Mod.h | 1 + launcher/modplatform/ModIndex.cpp | 9 +- launcher/modplatform/ModIndex.h | 1 + .../modplatform/flame/FlamePackExportTask.cpp | 124 +++++++++++++++--- .../modplatform/flame/FlamePackExportTask.h | 7 + .../helpers/ExportModsToStringTask.cpp | 22 +--- launcher/ui/MainWindow.cpp | 13 +- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 +- launcher/ui/dialogs/ExportMrPackDialog.ui | 7 + 10 files changed, 158 insertions(+), 37 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e613ddeb7..e93ff8bcc 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,6 +166,13 @@ auto Mod::homeurl() const -> QString return details().homeurl; } +auto Mod::metaurl() const -> QString +{ + if (metadata() == nullptr) + return homeurl(); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->slug); +} + auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d4e419f4f..d6272f4d0 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,6 +70,7 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 6a507caf4..c68333c5d 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -70,11 +70,18 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t } QCryptographicHash hash(algo); - if(!hash.addData(device)) + 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, QString slug) +{ + return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + slug.remove(".pw.toml"); +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 82da2ab2f..7d8199b39 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -118,6 +118,7 @@ struct IndexedPack { return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); } }; +QString getMetaURL(ResourceProvider provider, QString slug); } // namespace ModPlatform diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 880d4324c..2f1201e11 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -24,13 +24,14 @@ #include #include #include +#include #include #include "Json.h" #include "MMCZip.h" #include "minecraft/PackProfile.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" -#include "modplatform/helpers/ExportModsToStringTask.h" +#include "modplatform/flame/FlameModIndex.h" #include "modplatform/helpers/HashUtils.h" #include "tasks/Task.h" @@ -40,6 +41,7 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, const QString& author, const QVariant& projectID, + const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) @@ -52,6 +54,7 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, , gameRoot(instance->gameRoot()) , output(output) , filter(filter) + , generateModList(generateModList) {} void FlamePackExportTask::executeTask() @@ -116,7 +119,8 @@ void FlamePackExportTask::collectHashes() } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), - { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled() }); + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), + mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); setProgress(m_progress + 1, mods.count()); continue; } @@ -195,10 +199,10 @@ void FlamePackExportTask::makeApiRequest() } setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name())); - - resolvedFiles.insert( - mod.value()->fileinfo().absoluteFilePath(), - { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "modId"), mod.value()->enabled() }); + if (Json::ensureBoolean(file_obj, "isAvailable", false)) + resolvedFiles.insert( + mod.value()->fileinfo().absoluteFilePath(), + { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod.value()->enabled() }); } } catch (Json::JsonException& e) { @@ -206,10 +210,91 @@ void FlamePackExportTask::makeApiRequest() qDebug() << doc; } pendingHashes.clear(); + }); + connect(task.get(), &Task::finished, this, &FlamePackExportTask::getProjectsInfo); + connect(task.get(), &NetJob::failed, this, &FlamePackExportTask::emitFailed); + task->start(); +} + +void FlamePackExportTask::getProjectsInfo() +{ + if (!generateModList) { + buildZip(); + return; + } + setStatus(tr("Find project info from curseforge...")); + QList addonIds; + for (auto resolved : resolvedFiles) { + if (resolved.slug.isEmpty()) { + addonIds << QString::number(resolved.addonId); + } + } + + auto response = std::make_shared(); + Task::Ptr proj_task; + + if (addonIds.isEmpty()) { + buildZip(); + return; + } else if (addonIds.size() == 1) { + proj_task = api.getProject(*addonIds.begin(), response); + } else { + proj_task = api.getProjects(addonIds, response); + } + + connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { + QJsonParseError parse_error{}; + auto doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth projects task at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + try { + QJsonArray entries; + if (addonIds.size() == 1) + entries = { Json::requireObject(Json::requireObject(doc), "data") }; + else + entries = Json::requireArray(Json::requireObject(doc), "data"); + + size_t progress = 0; + for (auto entry : entries) { + setProgress(progress++, entries.count()); + auto entry_obj = Json::requireObject(entry); + + try { + setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(Json::requireString(entry_obj, "name"))); + + ModPlatform::IndexedPack pack; + FlameMod::loadIndexedPack(pack, entry_obj); + for (auto key : resolvedFiles.keys()) { + auto val = resolvedFiles.value(key); + if (val.addonId == pack.addonId) { + val.name = pack.name; + val.slug = pack.slug; + QStringList authors; + for (auto author : pack.authors) + authors << author.name; + + val.authors = authors.join(", "); + resolvedFiles[key] = val; + } + } + + } catch (Json::JsonException& e) { + qDebug() << e.cause(); + qDebug() << entries; + } + } + } catch (Json::JsonException& e) { + qDebug() << e.cause(); + qDebug() << doc; + } buildZip(); }); - - connect(task.get(), &NetJob::failed, this, &FlamePackExportTask::emitFailed); + task.reset(proj_task); task->start(); } @@ -234,14 +319,23 @@ void FlamePackExportTask::buildZip() } indexFile.write(generateIndex()); - QuaZipFile modlist(&zip); - if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); + if (generateModList) { + QuaZipFile modlist(&zip); + if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + QString content = ""; + for (auto mod : resolvedFiles) { + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) + .replace("{authors}", mod.authors) + + "\n"; + } + content = "
      " + content + "
    "; + modlist.write(content.toUtf8()); } - QString content = ExportToString::ExportModsToStringTask(mcInstance->loaderModList()->allMods(), TEMPLATE); - content = "
      " + content + "
    "; - modlist.write(content.toUtf8()); size_t progress = 0; for (const QFileInfo& file : files) { diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index f00696788..7f27e0d04 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -32,6 +32,7 @@ class FlamePackExportTask : public Task { const QString& version, const QString& author, const QVariant& projectID, + const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter); @@ -51,12 +52,17 @@ class FlamePackExportTask : public Task { const QDir gameRoot; const QString output; const MMCZip::FilterFunction filter; + const bool generateModList; typedef std::optional BuildZipResult; struct ResolvedFile { int addonId; int version; bool enabled; + + QString name; + QString slug; + QString authors; }; FlameAPI api; @@ -71,6 +77,7 @@ class FlamePackExportTask : public Task { void collectFiles(); void collectHashes(); void makeApiRequest(); + void getProjectsInfo(); void buildZip(); void finish(); diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp index e7be5ce13..03e1f4baf 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -19,6 +19,7 @@ #include "modplatform/ModIndex.h" namespace ExportToString { + QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) { switch (format) { @@ -28,12 +29,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex auto meta = mod->metadata(); auto modName = mod->name(); if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); if (!url.isEmpty()) modName = QString("%2").arg(url, modName); } @@ -57,12 +53,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex auto meta = mod->metadata(); auto modName = mod->name(); if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); if (!url.isEmpty()) modName = QString("[%1](%2)").arg(modName, url); } @@ -93,12 +84,7 @@ QString ExportModsToStringTask(QList mods, QString lineTemplate) auto meta = mod->metadata(); auto modName = mod->name(); - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 0027d1804..eb09efbc3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1420,8 +1420,17 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() void MainWindow::on_actionExportInstanceFlamePack_triggered() { if (m_selectedInstance) { - ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); - dlg.exec(); + auto instance = dynamic_cast(m_selectedInstance.get()); + if (instance) { + if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { + QMessageBox msgBox; + msgBox.setText(tr("Quilt is not yet supported by curseforge.")); + msgBox.exec(); + return; + } + ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); + dlg.exec(); + } } } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 3711bb8fb..edd2148a2 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -43,6 +43,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); ui->author->hide(); ui->authorLabel->hide(); + ui->gnerateModlist->hide(); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); @@ -117,7 +118,8 @@ void ExportMrPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), + ui->gnerateModlist->isChecked(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index 59ecb17c0..1b137eb4b 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -67,6 +67,13 @@ + + + + Generate modlist + + + From 20ba6e5fb50177d5145459951a69edc7b3302e95 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Sat, 24 Jun 2023 15:42:58 +1200 Subject: [PATCH 188/429] modrinth: use encoded url when exporting pack Ensures that necessary url components such as spaces are encoded. Prevents an error when submitting the resulting file to modrinth. See https://discord.com/channels/734077874708938864/1120070731242410024 Fixes: #1226 Signed-off-by: James Beddek --- launcher/modplatform/modrinth/ModrinthPackExportTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index c607bb89d..4cd88aa69 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -134,8 +134,8 @@ void ModrinthPackExportTask::collectHashes() QCryptographicHash sha1(QCryptographicHash::Algorithm::Sha1); sha1.addData(data); - ResolvedFile file{ sha1.result().toHex(), sha512.result().toHex(), url.toString(), openFile.size() }; - resolvedFiles[relative] = file; + ResolvedFile resolvedFile{ sha1.result().toHex(), sha512.result().toHex(), url.toEncoded(), openFile.size() }; + resolvedFiles[relative] = resolvedFile; // nice! we've managed to resolve based on local metadata! // no need to enqueue it From 42bc04a0d2af26e97829e6b1afd87d550b9b44da Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 24 Jun 2023 11:01:23 +0300 Subject: [PATCH 189/429] Update launcher/ui/MainWindow.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index eb09efbc3..89c78539c 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1424,7 +1424,7 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() if (instance) { if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { QMessageBox msgBox; - msgBox.setText(tr("Quilt is not yet supported by curseforge.")); + msgBox.setText(tr("Quilt is currently not supported by CurseForge modpacks.")); msgBox.exec(); return; } From cd1e8dc8cc87acf905ab3140efc48ef482973c7e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 11:12:23 +0300 Subject: [PATCH 190/429] Removed modlist checkbox Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 36 ++++++++----------- .../modplatform/flame/FlamePackExportTask.h | 2 -- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 +-- launcher/ui/dialogs/ExportMrPackDialog.ui | 7 ---- 4 files changed, 15 insertions(+), 34 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 2f1201e11..927b2e461 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -41,7 +41,6 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, const QString& author, const QVariant& projectID, - const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) @@ -54,7 +53,6 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, , gameRoot(instance->gameRoot()) , output(output) , filter(filter) - , generateModList(generateModList) {} void FlamePackExportTask::executeTask() @@ -218,10 +216,6 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { - if (!generateModList) { - buildZip(); - return; - } setStatus(tr("Find project info from curseforge...")); QList addonIds; for (auto resolved : resolvedFiles) { @@ -319,23 +313,21 @@ void FlamePackExportTask::buildZip() } indexFile.write(generateIndex()); - if (generateModList) { - QuaZipFile modlist(&zip); - if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - QString content = ""; - for (auto mod : resolvedFiles) { - content += QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) - .replace("{authors}", mod.authors) + - "\n"; - } - content = "
      " + content + "
    "; - modlist.write(content.toUtf8()); + QuaZipFile modlist(&zip); + if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); } + QString content = ""; + for (auto mod : resolvedFiles) { + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) + .replace("{authors}", mod.authors) + + "\n"; + } + content = "
      " + content + "
    "; + modlist.write(content.toUtf8()); size_t progress = 0; for (const QFileInfo& file : files) { diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 7f27e0d04..9ec9a2308 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -32,7 +32,6 @@ class FlamePackExportTask : public Task { const QString& version, const QString& author, const QVariant& projectID, - const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter); @@ -52,7 +51,6 @@ class FlamePackExportTask : public Task { const QDir gameRoot; const QString output; const MMCZip::FilterFunction filter; - const bool generateModList; typedef std::optional BuildZipResult; struct ResolvedFile { diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 3c593d205..8a95997be 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -43,7 +43,6 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); ui->author->hide(); ui->authorLabel->hide(); - ui->gnerateModlist->hide(); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); @@ -118,8 +117,7 @@ void ExportMrPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), - ui->gnerateModlist->isChecked(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index 1b137eb4b..59ecb17c0 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -67,13 +67,6 @@ - - - - Generate modlist - - - From a325d814e242ee450141088513d9cd282d79141f Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 24 Jun 2023 11:13:08 +0300 Subject: [PATCH 191/429] Update launcher/modplatform/flame/FlamePackExportTask.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 927b2e461..cd2424912 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -35,7 +35,7 @@ #include "modplatform/helpers/HashUtils.h" #include "tasks/Task.h" -const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; +const QString FlamePackExportTask::TEMPLATE = "
  • {name} (by {authors})
  • "; FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, From 8939096db659d1df5c75b938fc011a24af36e488 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 13:24:40 +0300 Subject: [PATCH 192/429] Fixed windows build Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 927b2e461..2920cb86a 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -197,7 +197,7 @@ void FlamePackExportTask::makeApiRequest() } setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name())); - if (Json::ensureBoolean(file_obj, "isAvailable", false)) + if (Json::ensureBoolean(file_obj, "isAvailable", false, "isAvailable")) resolvedFiles.insert( mod.value()->fileinfo().absoluteFilePath(), { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod.value()->enabled() }); From 9804996db652eb719a0eb40c41157d0813372eb2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 14:37:02 +0300 Subject: [PATCH 193/429] Added resource packs to export Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 36 +++++++++++++------ .../modplatform/flame/FlamePackExportTask.h | 7 +++- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 0d7abc9f0..45fc2e638 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -109,25 +109,42 @@ void FlamePackExportTask::collectHashes() auto mods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); task.reset(hashing_task); - setProgress(0, mods.count()); + int totalProgres = mods.count(); + setProgress(0, totalProgres); for (auto* mod : mods) { if (!mod || mod->type() == ResourceType::FOLDER) { - setProgress(m_progress + 1, mods.count()); + setProgress(m_progress + 1, totalProgres); continue; } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); - setProgress(m_progress + 1, mods.count()); + setProgress(m_progress + 1, totalProgres); continue; } auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, mods](QString hash) { + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { if (m_state == Task::State::Running) { - setProgress(m_progress + 1, mods.count()); - pendingHashes.insert(hash, mod); + setProgress(m_progress + 1, totalProgres); + pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled() }); + } + }); + connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + hashing_task->addTask(hash_task); + } + + for (const QFileInfo& file : files) { + const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); + if (!relative.endsWith(".zip") || !relative.startsWith("resourcepacks/")) + continue; + totalProgres++; + auto hash_task = Hashing::createFlameHasher(file.absoluteFilePath()); + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, relative, file, totalProgres](QString hash) { + if (m_state == Task::State::Running) { + setProgress(m_progress + 1, totalProgres); + pendingHashes.insert(hash, { relative, file.absoluteFilePath(), true }); } }); connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); @@ -196,11 +213,10 @@ void FlamePackExportTask::makeApiRequest() continue; } - setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name())); + setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod->name)); if (Json::ensureBoolean(file_obj, "isAvailable", false, "isAvailable")) - resolvedFiles.insert( - mod.value()->fileinfo().absoluteFilePath(), - { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod.value()->enabled() }); + resolvedFiles.insert(mod->path, + { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod->enabled }); } } catch (Json::JsonException& e) { diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 9ec9a2308..629493d86 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -62,11 +62,16 @@ class FlamePackExportTask : public Task { QString slug; QString authors; }; + struct HashInfo { + QString name; + QString path; + bool enabled; + }; FlameAPI api; QFileInfoList files; - QMap pendingHashes{}; + QMap pendingHashes{}; QMap resolvedFiles{}; Task::Ptr task; QFuture buildZipFuture; From 30ef5475c75514c08a4d1b2c8e4c6ec5abba41ea Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 14:50:05 +0300 Subject: [PATCH 194/429] Made sure CurseForge string is corect Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/ui/MainWindow.ui | 2 +- launcher/ui/dialogs/ExportMrPackDialog.cpp | 2 +- launcher/ui/pages/global/LauncherPage.ui | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 45fc2e638..fb5bcc0b2 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -232,7 +232,7 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { - setStatus(tr("Find project info from curseforge...")); + setStatus(tr("Find project info from CurseForge...")); QList addonIds; for (auto resolved : resolvedFiles) { if (resolved.slug.isEmpty()) { diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 1cfb59cde..190219b9b 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -484,7 +484,7 @@
    - Curseforge (zip) + CurseForge (zip)
    diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 8a95997be..94987c7e6 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -108,7 +108,7 @@ void ExportMrPackDialog::done(int result) nullptr); else output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), - FS::PathCombine(QDir::homePath(), filename + ".zip"), "Curseforge pack (*.zip)", nullptr); + FS::PathCombine(QDir::homePath(), filename + ".zip"), "CurseForge pack (*.zip)", nullptr); if (output.isEmpty()) return; diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index d9116bfcf..26408f44f 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -169,7 +169,7 @@ - Disable using metadata provided by mod providers (like Modrinth or Curseforge) for mods. + Disable using metadata provided by mod providers (like Modrinth or CurseForge) for mods. Disable using metadata for mods From 59e1e5190310626109018d5aeed4782b347176ec Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 14:51:12 +0300 Subject: [PATCH 195/429] Removed unused files Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 3 - .../helpers/ExportModsToStringTask.cpp | 100 ------------------ .../helpers/ExportModsToStringTask.h | 33 ------ 3 files changed, 136 deletions(-) delete mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.cpp delete mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index df6c90129..8de616a6c 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -487,9 +487,6 @@ set(API_SOURCES modplatform/helpers/HashUtils.cpp modplatform/helpers/OverrideUtils.h modplatform/helpers/OverrideUtils.cpp - - modplatform/helpers/ExportModsToStringTask.h - modplatform/helpers/ExportModsToStringTask.cpp ) set(FTB_SOURCES diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp deleted file mode 100644 index 03e1f4baf..000000000 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// 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 "ExportModsToStringTask.h" -#include "modplatform/ModIndex.h" - -namespace ExportToString { - -QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) -{ - switch (format) { - case HTML: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - modName = QString("%2").arg(url, modName); - } - auto line = modName; - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines.append(QString("
      %1
    ").arg(line)); - } - return QString("\n\t%1\n").arg(lines.join("\n\t")); - } - case MARKDOWN: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - modName = QString("[%1](%2)").arg(modName, url); - } - auto line = modName; - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines << line; - } - return lines.join("\n"); - } - default: { - return QString("unknown format:%1").arg(format); - } - } -} - -QString ExportModsToStringTask(QList mods, QString lineTemplate) -{ - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - - auto url = mod->metaurl(); - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - auto authors = mod->authors().join(", "); - lines << QString(lineTemplate) - .replace("{name}", modName) - .replace("{url}", url) - .replace("{version}", ver) - .replace("{authors}", authors); - } - return lines.join("\n"); -} -} // namespace ExportToString \ No newline at end of file diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.h b/launcher/modplatform/helpers/ExportModsToStringTask.h deleted file mode 100644 index 756c69f77..000000000 --- a/launcher/modplatform/helpers/ExportModsToStringTask.h +++ /dev/null @@ -1,33 +0,0 @@ -// 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 -#include "minecraft/mod/Mod.h" - -namespace ExportToString { - -enum Formats { HTML, MARKDOWN }; -enum OptionalData { - Authors = 1 << 0, - Url = 1 << 1, - Version = 1 << 2, -}; -QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData); -QString ExportModsToStringTask(QList mods, QString lineTemplate); -} // namespace ExportToString From 25579fbedcfac6b36c6b30ad2447d702b601e1d6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 14:54:39 +0300 Subject: [PATCH 196/429] Renamed ExportMrPackDialog to ExportPackDialog Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 6 +++--- launcher/ui/MainWindow.cpp | 6 +++--- ...portMrPackDialog.cpp => ExportPackDialog.cpp} | 16 ++++++++-------- .../{ExportMrPackDialog.h => ExportPackDialog.h} | 14 +++++++------- ...ExportMrPackDialog.ui => ExportPackDialog.ui} | 8 ++++---- 5 files changed, 25 insertions(+), 25 deletions(-) rename launcher/ui/dialogs/{ExportMrPackDialog.cpp => ExportPackDialog.cpp} (91%) rename launcher/ui/dialogs/{ExportMrPackDialog.h => ExportPackDialog.h} (76%) rename launcher/ui/dialogs/{ExportMrPackDialog.ui => ExportPackDialog.ui} (95%) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 8de616a6c..0dc2b80a8 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -908,8 +908,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/EditAccountDialog.h ui/dialogs/ExportInstanceDialog.cpp ui/dialogs/ExportInstanceDialog.h - ui/dialogs/ExportMrPackDialog.cpp - ui/dialogs/ExportMrPackDialog.h + ui/dialogs/ExportPackDialog.cpp + ui/dialogs/ExportPackDialog.h ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.h ui/dialogs/ImportResourceDialog.cpp @@ -1056,7 +1056,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/ProfileSelectDialog.ui ui/dialogs/SkinUploadDialog.ui ui/dialogs/ExportInstanceDialog.ui - ui/dialogs/ExportMrPackDialog.ui + ui/dialogs/ExportPackDialog.ui ui/dialogs/IconPickerDialog.ui ui/dialogs/ImportResourceDialog.ui ui/dialogs/MSALoginDialog.ui diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 89c78539c..91809c7b3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -107,7 +107,7 @@ #include "ui/dialogs/CopyInstanceDialog.h" #include "ui/dialogs/EditAccountDialog.h" #include "ui/dialogs/ExportInstanceDialog.h" -#include "ui/dialogs/ExportMrPackDialog.h" +#include "ui/dialogs/ExportPackDialog.h" #include "ui/dialogs/ImportResourceDialog.h" #include "ui/themes/ITheme.h" #include "ui/themes/ThemeManager.h" @@ -1412,7 +1412,7 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() { if (m_selectedInstance) { - ExportMrPackDialog dlg(m_selectedInstance, this); + ExportPackDialog dlg(m_selectedInstance, this); dlg.exec(); } } @@ -1428,7 +1428,7 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() msgBox.exec(); return; } - ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); + ExportPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); dlg.exec(); } } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp similarity index 91% rename from launcher/ui/dialogs/ExportMrPackDialog.cpp rename to launcher/ui/dialogs/ExportPackDialog.cpp index 94987c7e6..8e921f89a 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include "ExportMrPackDialog.h" +#include "ExportPackDialog.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" #include "modplatform/flame/FlamePackExportTask.h" @@ -34,8 +34,8 @@ #include "MMCZip.h" #include "modplatform/modrinth/ModrinthPackExportTask.h" -ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider) - : QDialog(parent), instance(instance), ui(new Ui::ExportMrPackDialog), m_provider(provider) +ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider) + : QDialog(parent), instance(instance), ui(new Ui::ExportPackDialog), m_provider(provider) { ui->setupUi(this); ui->name->setText(instance->name()); @@ -51,8 +51,8 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo // ensure a valid pack is generated // the name and version fields mustn't be empty - connect(ui->name, &QLineEdit::textEdited, this, &ExportMrPackDialog::validate); - connect(ui->version, &QLineEdit::textEdited, this, &ExportMrPackDialog::validate); + connect(ui->name, &QLineEdit::textEdited, this, &ExportPackDialog::validate); + connect(ui->version, &QLineEdit::textEdited, this, &ExportPackDialog::validate); // the instance name can technically be empty validate(); @@ -92,12 +92,12 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo headerView->setSectionResizeMode(0, QHeaderView::Stretch); } -ExportMrPackDialog::~ExportMrPackDialog() +ExportPackDialog::~ExportPackDialog() { delete ui; } -void ExportMrPackDialog::done(int result) +void ExportPackDialog::done(int result) { if (result == Accepted) { const QString filename = FS::RemoveInvalidFilenameChars(ui->name->text()); @@ -137,7 +137,7 @@ void ExportMrPackDialog::done(int result) QDialog::done(result); } -void ExportMrPackDialog::validate() +void ExportPackDialog::validate() { const bool invalid = ui->name->text().isEmpty() || ((m_provider == ModPlatform::ResourceProvider::MODRINTH) && ui->version->text().isEmpty()); diff --git a/launcher/ui/dialogs/ExportMrPackDialog.h b/launcher/ui/dialogs/ExportPackDialog.h similarity index 76% rename from launcher/ui/dialogs/ExportMrPackDialog.h rename to launcher/ui/dialogs/ExportPackDialog.h index 858a31bf9..830c24d25 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.h +++ b/launcher/ui/dialogs/ExportPackDialog.h @@ -25,24 +25,24 @@ #include "modplatform/ModIndex.h" namespace Ui { -class ExportMrPackDialog; +class ExportPackDialog; } -class ExportMrPackDialog : public QDialog { +class ExportPackDialog : public QDialog { Q_OBJECT public: - explicit ExportMrPackDialog(InstancePtr instance, - QWidget* parent = nullptr, - ModPlatform::ResourceProvider provider = ModPlatform::ResourceProvider::MODRINTH); - ~ExportMrPackDialog(); + explicit ExportPackDialog(InstancePtr instance, + QWidget* parent = nullptr, + ModPlatform::ResourceProvider provider = ModPlatform::ResourceProvider::MODRINTH); + ~ExportPackDialog(); void done(int result) override; void validate(); private: const InstancePtr instance; - Ui::ExportMrPackDialog* ui; + Ui::ExportPackDialog* ui; FileIgnoreProxy* proxy; FastFileIconProvider icons; const ModPlatform::ResourceProvider m_provider; diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui similarity index 95% rename from launcher/ui/dialogs/ExportMrPackDialog.ui rename to launcher/ui/dialogs/ExportPackDialog.ui index 59ecb17c0..5762508af 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportPackDialog.ui @@ -1,7 +1,7 @@ - ExportMrPackDialog - + ExportPackDialog + 0 @@ -113,7 +113,7 @@ buttonBox accepted() - ExportMrPackDialog + ExportPackDialog accept() @@ -129,7 +129,7 @@ buttonBox rejected() - ExportMrPackDialog + ExportPackDialog reject() From 4a84084d9d605ae4fa9a8063f36bfdbcdc4c5c3d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 15:02:00 +0300 Subject: [PATCH 197/429] Added condition for modlist Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 20 ++++++++++--------- .../modplatform/flame/FlamePackExportTask.h | 2 ++ launcher/ui/dialogs/ExportPackDialog.cpp | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index fb5bcc0b2..dc407653b 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -118,7 +118,7 @@ void FlamePackExportTask::collectHashes() } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), - { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), true, mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); setProgress(m_progress + 1, totalProgres); continue; @@ -128,7 +128,7 @@ void FlamePackExportTask::collectHashes() connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { if (m_state == Task::State::Running) { setProgress(m_progress + 1, totalProgres); - pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled() }); + pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled(), true }); } }); connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); @@ -215,8 +215,8 @@ void FlamePackExportTask::makeApiRequest() setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod->name)); if (Json::ensureBoolean(file_obj, "isAvailable", false, "isAvailable")) - resolvedFiles.insert(mod->path, - { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod->enabled }); + resolvedFiles.insert(mod->path, { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), + mod->enabled, mod->isMod }); } } catch (Json::JsonException& e) { @@ -336,11 +336,13 @@ void FlamePackExportTask::buildZip() } QString content = ""; for (auto mod : resolvedFiles) { - content += QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) - .replace("{authors}", mod.authors) + - "\n"; + if (mod.isMod) { + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) + .replace("{authors}", mod.authors) + + "\n"; + } } content = "
      " + content + "
    "; modlist.write(content.toUtf8()); diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 629493d86..ee1f4e8df 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -57,6 +57,7 @@ class FlamePackExportTask : public Task { int addonId; int version; bool enabled; + bool isMod; QString name; QString slug; @@ -66,6 +67,7 @@ class FlamePackExportTask : public Task { QString name; QString path; bool enabled; + bool isMod; }; FlameAPI api; diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index 8e921f89a..fb71f4a5c 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -22,7 +22,7 @@ #include "modplatform/flame/FlamePackExportTask.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" -#include "ui_ExportMrPackDialog.h" +#include "ui_ExportPackDialog.h" #include #include From 19cb6ad5883c59c27f954042025bf89d44bed096 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 15:04:18 +0300 Subject: [PATCH 198/429] Updated Modrinth esport messages Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackExportTask.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index dc407653b..837ded0fb 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -157,12 +157,12 @@ void FlamePackExportTask::collectHashes() void FlamePackExportTask::makeApiRequest() { - setStatus(tr("Find versions for hashes...")); if (pendingHashes.isEmpty()) { buildZip(); return; } + setStatus(tr("Find versions for hashes...")); auto response = std::make_shared(); QList fingerprints; diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index c607bb89d..dd7486873 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -64,7 +64,8 @@ bool ModrinthPackExportTask::abort() if (buildZipFuture.isRunning()) { buildZipFuture.cancel(); - // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur immediately. + // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur + // immediately. return true; } @@ -94,6 +95,7 @@ void ModrinthPackExportTask::collectFiles() void ModrinthPackExportTask::collectHashes() { + setStatus(tr("Find file hashes...")); for (const QFileInfo& file : files) { QCoreApplication::processEvents(); @@ -157,6 +159,7 @@ void ModrinthPackExportTask::makeApiRequest() if (pendingHashes.isEmpty()) buildZip(); else { + setStatus(tr("Find versions for hashes...")); auto response = std::make_shared(); task = api.currentVersions(pendingHashes.values(), "sha512", response); connect(task.get(), &NetJob::succeeded, [this, response]() { parseApiResponse(response); }); From f825d7753afd6c00111c9ff9deedeee8ded5b27a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 15:11:15 +0300 Subject: [PATCH 199/429] Updated copyright headers Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 1 + launcher/modplatform/flame/FlamePackExportTask.h | 1 + 2 files changed, 2 insertions(+) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 837ded0fb..2759ae090 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 TheKodeToad * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index ee1f4e8df..cf67ed5f5 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 TheKodeToad * Copyright (c) 2023 Trial97 * * This program is free software: you can redistribute it and/or modify From 8b576fd2bd442a61092de870b4323c280b04d2d6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 15:59:55 +0300 Subject: [PATCH 200/429] Added translation Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 2 +- launcher/modplatform/flame/FlameModIndex.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index b1058ee60..f8ecdb33e 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -48,7 +48,7 @@ GetModDependenciesTask::GetModDependenciesTask(QObject* parent, BaseInstance* instance, ModFolderModel* folder, QList> selected) - : SequentialTask(parent, "Get dependencies") + : SequentialTask(parent, tr("Get dependencies")) , m_selected(selected) , m_flame_provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared(*instance), std::make_shared() } diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 9c8eb832a..227ce4898 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -160,10 +160,9 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> case 6: // Include dependency.type = ModPlatform::DependencyType::INCLUDE; break; - default: + default: dependency.type = ModPlatform::DependencyType::UNKNOWN; break; - } file.dependencies.append(dependency); } From df932c65875a20fd95a47c3394a802d131e93993 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 20:22:18 +0300 Subject: [PATCH 201/429] Updated authors string in modlist Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 2759ae090..54294d7b9 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -36,7 +36,7 @@ #include "modplatform/helpers/HashUtils.h" #include "tasks/Task.h" -const QString FlamePackExportTask::TEMPLATE = "
  • {name} (by {authors})
  • "; +const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • "; FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, @@ -338,11 +338,12 @@ void FlamePackExportTask::buildZip() QString content = ""; for (auto mod : resolvedFiles) { if (mod.isMod) { - content += QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) - .replace("{authors}", mod.authors) + - "\n"; + auto line = QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)); + if (!mod.authors.isEmpty()) + line = line.replace("{authors}", QString(" (by {%1})").arg(mod.authors)); + content += line + "\n"; } } content = "
      " + content + "
    "; From f0e4e07c05bdf68994c9d6a460f4ec4c03a2e627 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 20:43:45 +0300 Subject: [PATCH 202/429] Updated url function Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 2 +- launcher/modplatform/ModIndex.cpp | 7 +++---- launcher/modplatform/ModIndex.h | 2 +- launcher/modplatform/flame/FlamePackExportTask.cpp | 12 +++++------- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e93ff8bcc..d5b96badd 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -170,7 +170,7 @@ auto Mod::metaurl() const -> QString { if (metadata() == nullptr) return homeurl(); - return ModPlatform::getMetaURL(metadata()->provider, metadata()->slug); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); } auto Mod::description() const -> QString diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index c68333c5d..a1c4d8917 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -77,11 +77,10 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t return { hash.result().toHex() }; } -QString getMetaURL(ResourceProvider provider, QString slug) +QString getMetaURL(ResourceProvider provider, QVariant projectID) { - return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - slug.remove(".pw.toml"); + return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/projects/" : "https://modrinth.com/mod/") + + projectID.toString(); } } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 83412169e..773ee9346 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -128,7 +128,7 @@ struct IndexedPack { return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); } }; -QString getMetaURL(ResourceProvider provider, QString slug); +QString getMetaURL(ResourceProvider provider, QVariant projectID); struct OverrideDep { QString quilt; diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 54294d7b9..d729e977c 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -36,7 +36,7 @@ #include "modplatform/helpers/HashUtils.h" #include "tasks/Task.h" -const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • "; +const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • \n"; FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, @@ -338,12 +338,10 @@ void FlamePackExportTask::buildZip() QString content = ""; for (auto mod : resolvedFiles) { if (mod.isMod) { - auto line = QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)); - if (!mod.authors.isEmpty()) - line = line.replace("{authors}", QString(" (by {%1})").arg(mod.authors)); - content += line + "\n"; + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId)) + .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by {%1})").arg(mod.authors) : ""); } } content = "
      " + content + "
    "; From 69c21454ecf683b1794aec55ddad66d53d3afc7c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 22:15:18 +0300 Subject: [PATCH 203/429] removed projectID Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 6 +----- launcher/modplatform/flame/FlamePackExportTask.h | 2 -- launcher/ui/dialogs/ExportPackDialog.cpp | 6 ++---- launcher/ui/dialogs/ExportPackDialog.ui | 11 +---------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index d729e977c..ac85a6287 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -41,14 +41,12 @@ const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors} FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, const QString& author, - const QVariant& projectID, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) : name(name) , version(version) , author(author) - , projectID(projectID) , instance(instance) , mcInstance(dynamic_cast(instance.get())) , gameRoot(instance->gameRoot()) @@ -341,7 +339,7 @@ void FlamePackExportTask::buildZip() content += QString(TEMPLATE) .replace("{name}", mod.name) .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId)) - .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by {%1})").arg(mod.authors) : ""); + .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors) : ""); } } content = "
      " + content + "
    "; @@ -398,8 +396,6 @@ QByteArray FlamePackExportTask::generateIndex() obj["name"] = name; obj["version"] = version; obj["author"] = author; - if (projectID.toInt() != 0) - obj["projectID"] = projectID.toInt(); obj["overrides"] = "overrides"; if (mcInstance) { QJsonObject version; diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index cf67ed5f5..5c8caa458 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -32,7 +32,6 @@ class FlamePackExportTask : public Task { FlamePackExportTask(const QString& name, const QString& version, const QString& author, - const QVariant& projectID, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter); @@ -46,7 +45,6 @@ class FlamePackExportTask : public Task { // inputs const QString name, version, author; - const QVariant projectID; const InstancePtr instance; MinecraftInstance* mcInstance; const QDir gameRoot; diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index fb71f4a5c..ea3649397 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -41,12 +41,10 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla ui->name->setText(instance->name()); if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); - ui->author->hide(); - ui->authorLabel->hide(); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); - ui->summaryLabel->setText("ProjectID"); + ui->summaryLabel->setText("Author"); } // ensure a valid pack is generated @@ -117,7 +115,7 @@ void ExportPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui index 5762508af..658e21994 100644 --- a/launcher/ui/dialogs/ExportPackDialog.ui +++ b/launcher/ui/dialogs/ExportPackDialog.ui @@ -57,16 +57,7 @@ - - - - Author - - - - - - + From 932531c8ba1197e38dcd66c1ad146aeebc9ca177 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 23:48:18 +0300 Subject: [PATCH 204/429] fixed authors Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/ui/dialogs/ExportPackDialog.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index ac85a6287..e73f3de59 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -95,8 +95,8 @@ void FlamePackExportTask::collectFiles() resolvedFiles.clear(); if (mcInstance != nullptr) { - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes); mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes); } else collectHashes(); } diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index ea3649397..fd374246d 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -73,6 +73,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla MinecraftInstance* mcInstance = dynamic_cast(instance.get()); if (mcInstance) { + mcInstance->loaderModList()->update(); const QDir index = mcInstance->loaderModList()->indexDir(); if (index.exists()) proxy->blockedPaths().insert(root.relativeFilePath(index.absolutePath())); From 529e2054eadf4c97231a51d7bd2d25cb75bd74c9 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 22:54:05 +0100 Subject: [PATCH 205/429] A few tweaks, with inspiration from Zeke :3 Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 6 +- launcher/ui/dialogs/NewInstanceDialog.cpp | 4 +- launcher/ui/pages/instance/VersionPage.cpp | 1 - launcher/ui/pages/instance/VersionPage.ui | 10 --- .../{VanillaPage.cpp => CustomPage.cpp} | 66 +++++++++---------- .../{VanillaPage.h => CustomPage.h} | 12 ++-- .../{VanillaPage.ui => CustomPage.ui} | 4 +- 7 files changed, 46 insertions(+), 57 deletions(-) rename launcher/ui/pages/modplatform/{VanillaPage.cpp => CustomPage.cpp} (79%) rename launcher/ui/pages/modplatform/{VanillaPage.h => CustomPage.h} (92%) rename launcher/ui/pages/modplatform/{VanillaPage.ui => CustomPage.ui} (99%) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 9bad2a670..c10064c00 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -827,8 +827,8 @@ SET(LAUNCHER_SOURCES ui/pages/global/APIPage.h # GUI - platform pages - ui/pages/modplatform/VanillaPage.cpp - ui/pages/modplatform/VanillaPage.h + ui/pages/modplatform/CustomPage.cpp + ui/pages/modplatform/CustomPage.h ui/pages/modplatform/ResourcePage.cpp ui/pages/modplatform/ResourcePage.h @@ -1034,7 +1034,7 @@ qt_wrap_ui(LAUNCHER_UI ui/pages/instance/ScreenshotsPage.ui ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui ui/pages/modplatform/atlauncher/AtlPage.ui - ui/pages/modplatform/VanillaPage.ui + ui/pages/modplatform/CustomPage.ui ui/pages/modplatform/ResourcePage.ui ui/pages/modplatform/flame/FlamePage.ui ui/pages/modplatform/legacy_ftb/Page.ui diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index aafaf2202..7b9bb944c 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -54,7 +54,7 @@ #include #include "ui/widgets/PageContainer.h" -#include "ui/pages/modplatform/VanillaPage.h" +#include "ui/pages/modplatform/CustomPage.h" #include "ui/pages/modplatform/atlauncher/AtlPage.h" #include "ui/pages/modplatform/legacy_ftb/Page.h" #include "ui/pages/modplatform/flame/FlamePage.h" @@ -162,7 +162,7 @@ QList NewInstanceDialog::getPages() importPage = new ImportPage(this); - pages.append(new VanillaPage(this)); + pages.append(new CustomPage(this)); pages.append(importPage); pages.append(new AtlPage(this)); if (APPLICATION->capabilities() & Application::SupportsFlame) diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 74b7ec7c2..59107c53a 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -287,7 +287,6 @@ void VersionPage::updateButtons(int row) ui->actionAdd_Empty->setEnabled(controlsEnabled); ui->actionImport_Components->setEnabled(controlsEnabled); ui->actionReload->setEnabled(controlsEnabled); - ui->actionInstall_mods->setEnabled(controlsEnabled); ui->actionReplace_Minecraft_jar->setEnabled(controlsEnabled); ui->actionAdd_to_Minecraft_jar->setEnabled(controlsEnabled); ui->actionAdd_Agents->setEnabled(controlsEnabled); diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index 4777eafe0..a73c42d6c 100644 --- a/launcher/ui/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -102,7 +102,6 @@ - @@ -112,7 +111,6 @@ - @@ -204,14 +202,6 @@ Install the LiteLoader package. - - - Install mods - - - Install normal mods. - - Add to Minecraft.jar diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/CustomPage.cpp similarity index 79% rename from launcher/ui/pages/modplatform/VanillaPage.cpp rename to launcher/ui/pages/modplatform/CustomPage.cpp index 29fecb854..e164171a4 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.cpp +++ b/launcher/ui/pages/modplatform/CustomPage.cpp @@ -33,8 +33,8 @@ * limitations under the License. */ -#include "VanillaPage.h" -#include "ui_VanillaPage.h" +#include "CustomPage.h" +#include "ui_CustomPage.h" #include @@ -46,32 +46,32 @@ #include "minecraft/VanillaInstanceCreationTask.h" #include "ui/dialogs/NewInstanceDialog.h" -VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent) - : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage) +CustomPage::CustomPage(NewInstanceDialog *dialog, QWidget *parent) + : QWidget(parent), dialog(dialog), ui(new Ui::CustomPage) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); - connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion); + connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &CustomPage::setSelectedVersion); filterChanged(); - connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->refreshBtn, &QPushButton::clicked, this, &VanillaPage::refresh); + connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->betaFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->refreshBtn, &QPushButton::clicked, this, &CustomPage::refresh); - connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedLoaderVersion); - connect(ui->noneFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->forgeFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->fabricFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->quiltFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &VanillaPage::loaderRefresh); + connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &CustomPage::setSelectedLoaderVersion); + connect(ui->noneFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->forgeFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->fabricFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->quiltFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &CustomPage::loaderRefresh); } -void VanillaPage::openedImpl() +void CustomPage::openedImpl() { if(!initialized) { @@ -85,19 +85,19 @@ void VanillaPage::openedImpl() } } -void VanillaPage::refresh() +void CustomPage::refresh() { ui->versionList->loadList(); } -void VanillaPage::loaderRefresh() +void CustomPage::loaderRefresh() { if(ui->noneFilter->isChecked()) return; ui->loaderVersionList->loadList(); } -void VanillaPage::filterChanged() +void CustomPage::filterChanged() { QStringList out; if(ui->alphaFilter->isChecked()) @@ -116,7 +116,7 @@ void VanillaPage::filterChanged() ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); } -void VanillaPage::loaderFilterChanged() +void CustomPage::loaderFilterChanged() { QString minecraftVersion; if (m_selectedVersion) @@ -172,37 +172,37 @@ void VanillaPage::loaderFilterChanged() ui->loaderVersionList->setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); } -VanillaPage::~VanillaPage() +CustomPage::~CustomPage() { delete ui; } -bool VanillaPage::shouldDisplay() const +bool CustomPage::shouldDisplay() const { return true; } -void VanillaPage::retranslate() +void CustomPage::retranslate() { ui->retranslateUi(this); } -BaseVersion::Ptr VanillaPage::selectedVersion() const +BaseVersion::Ptr CustomPage::selectedVersion() const { return m_selectedVersion; } -BaseVersion::Ptr VanillaPage::selectedLoaderVersion() const +BaseVersion::Ptr CustomPage::selectedLoaderVersion() const { return m_selectedLoaderVersion; } -QString VanillaPage::selectedLoader() const +QString CustomPage::selectedLoader() const { return m_selectedLoader; } -void VanillaPage::suggestCurrent() +void CustomPage::suggestCurrent() { if (!isOpened) { @@ -227,14 +227,14 @@ void VanillaPage::suggestCurrent() dialog->setSuggestedIcon("default"); } -void VanillaPage::setSelectedVersion(BaseVersion::Ptr version) +void CustomPage::setSelectedVersion(BaseVersion::Ptr version) { m_selectedVersion = version; suggestCurrent(); loaderFilterChanged(); } -void VanillaPage::setSelectedLoaderVersion(BaseVersion::Ptr version) +void CustomPage::setSelectedLoaderVersion(BaseVersion::Ptr version) { m_selectedLoaderVersion = version; suggestCurrent(); diff --git a/launcher/ui/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/CustomPage.h similarity index 92% rename from launcher/ui/pages/modplatform/VanillaPage.h rename to launcher/ui/pages/modplatform/CustomPage.h index 39aba760b..8b5a5011c 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.h +++ b/launcher/ui/pages/modplatform/CustomPage.h @@ -43,21 +43,21 @@ namespace Ui { -class VanillaPage; +class CustomPage; } class NewInstanceDialog; -class VanillaPage : public QWidget, public BasePage +class CustomPage : public QWidget, public BasePage { Q_OBJECT public: - explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0); - virtual ~VanillaPage(); + explicit CustomPage(NewInstanceDialog *dialog, QWidget *parent = 0); + virtual ~CustomPage(); virtual QString displayName() const override { - return tr("Vanilla"); + return tr("Custom"); } virtual QIcon icon() const override { @@ -96,7 +96,7 @@ private: private: bool initialized = false; NewInstanceDialog *dialog = nullptr; - Ui::VanillaPage *ui = nullptr; + Ui::CustomPage *ui = nullptr; bool m_versionSetByUser = false; BaseVersion::Ptr m_selectedVersion; BaseVersion::Ptr m_selectedLoaderVersion; diff --git a/launcher/ui/pages/modplatform/VanillaPage.ui b/launcher/ui/pages/modplatform/CustomPage.ui similarity index 99% rename from launcher/ui/pages/modplatform/VanillaPage.ui rename to launcher/ui/pages/modplatform/CustomPage.ui index 431109273..0d89b5956 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.ui +++ b/launcher/ui/pages/modplatform/CustomPage.ui @@ -1,7 +1,7 @@ - VanillaPage - + CustomPage + 0 From bb8e6ef35ec4d911d199b06d3337dfcd1ab8b202 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:26:02 +0100 Subject: [PATCH 206/429] Fix flat white launcher icon Signed-off-by: TheKodeToad --- .../flat_white/scalable/launcher.svg | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg index 54131b657..aeee84338 100644 --- a/launcher/resources/flat_white/scalable/launcher.svg +++ b/launcher/resources/flat_white/scalable/launcher.svg @@ -1,2 +1,57 @@ - + + + Prism Launcher Logo + + + + + + + + + + + + + + + + + + + + + + + Prism Launcher Logo + 19/10/2022 + + + Prism Launcher + + + + + AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke + + + https://github.com/PrismLauncher/PrismLauncher + + + Prism Launcher + + + + + + + + + + + + + + + From 8a3aba1634ca9f8b86c995687c7e2f99740d9111 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:30:51 +0100 Subject: [PATCH 207/429] Fix Open Global Settings, why not Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 08977841a..893fe2a52 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -86,11 +86,11 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) APPLICATION->ShowGlobalSettings(this, "java-settings"); return; case 1: - APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); - return; - case 2: APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; + default: + APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); + return; } } From 5eb71fc6a96690e3d9a658f383b0937446ec3f9e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:34:37 +0100 Subject: [PATCH 208/429] Revert "feat(Mods): hide 'Provider' column when no mods have providers" With Ryex's change, this causes issues. Apparently you need to sign off reverts! That's just weird... Signed-off-by: TheKodeToad --- launcher/ui/widgets/ModListView.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index 893cd120a..80a918b64 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -14,9 +14,6 @@ */ #include "ModListView.h" - -#include "minecraft/mod/ModFolderModel.h" - #include #include #include @@ -65,19 +62,6 @@ void ModListView::setModel ( QAbstractItemModel* model ) for(int i = 1; i < head->count(); i++) head->setSectionResizeMode(i, QHeaderView::ResizeToContents); } - - auto real_model = model; - if (auto proxy_model = dynamic_cast(model); proxy_model) - real_model = proxy_model->sourceModel(); - - if (auto mod_model = dynamic_cast(real_model); mod_model) { - connect(mod_model, &ModFolderModel::updateFinished, this, [this, mod_model]{ - auto mods = mod_model->allMods(); - // Hide the 'Provider' column if no mod has a defined provider! - setColumnHidden(ModFolderModel::Columns::ProviderColumn, - std::none_of(mods.constBegin(), mods.constEnd(), [](auto const mod){ return mod->provider().has_value(); })); - }); - } } void ModListView::setResizeModes(const QList &modes) From ce4a86fbcd0c891472b842e76066d285de3aef7b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 10:41:29 +0300 Subject: [PATCH 209/429] Made custom url function Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 7 +++++++ launcher/minecraft/mod/Mod.h | 1 + launcher/modplatform/ModIndex.cpp | 8 +++++++- launcher/modplatform/ModIndex.h | 1 + launcher/ui/pages/instance/ModFolderPage.cpp | 18 +++++------------ launcher/ui/widgets/InfoFrame.cpp | 21 +++----------------- 6 files changed, 24 insertions(+), 32 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e613ddeb7..d5b96badd 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,6 +166,13 @@ auto Mod::homeurl() const -> QString return details().homeurl; } +auto Mod::metaurl() const -> QString +{ + if (metadata() == nullptr) + return homeurl(); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); +} + auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d4e419f4f..d6272f4d0 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,6 +70,7 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 6a507caf4..a1c4d8917 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -70,11 +70,17 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t } QCryptographicHash hash(algo); - if(!hash.addData(device)) + 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/") + + projectID.toString(); +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 3b0a03a18..3f51e700f 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -144,6 +144,7 @@ inline auto getOverrideDeps() -> QList { "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH }, { "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } }; }; +QString getMetaURL(ResourceProvider provider, QVariant projectID); } // namespace ModPlatform diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 9722d4830..1d31a2925 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -298,17 +298,9 @@ bool NilModFolderPage::shouldDisplay() const void ModFolderPage::visitModPages() { auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); - for (auto mod : m_model->selectedMods(selection)) - if (auto meta = mod->metadata(); meta != nullptr) { - auto slug = meta->slug.remove(".pw.toml"); - switch (meta->provider) { - case ModPlatform::ResourceProvider::MODRINTH: - DesktopServices::openUrl(QString("https://modrinth.com/mod/%1").arg(slug)); - break; - case ModPlatform::ResourceProvider::FLAME: - DesktopServices::openUrl(QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug)); - break; - } - } else if (mod->homeurl().size() != 0) - DesktopServices::openUrl(mod->homeurl()); + for (auto mod : m_model->selectedMods(selection)) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + DesktopServices::openUrl(url); + } } \ No newline at end of file diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 52e79dc01..57562a931 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -41,9 +41,7 @@ #include "ui/dialogs/CustomMessageBox.h" -InfoFrame::InfoFrame(QWidget *parent) : - QFrame(parent), - ui(new Ui::InfoFrame) +InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) { ui->setupUi(this); ui->descriptionLabel->setHidden(true); @@ -67,31 +65,18 @@ void InfoFrame::updateWithMod(Mod const& m) QString text = ""; QString name = ""; - QString link = ""; + QString link = m.metaurl(); QString toolTip = ""; if (m.name().isEmpty()) name = m.internal_id(); else name = m.name(); - if (auto meta = m.metadata(); meta != nullptr) { - auto slug = meta->slug.remove(".pw.toml"); - switch (meta->provider) { - case ModPlatform::ResourceProvider::MODRINTH: - link = QString("https://modrinth.com/mod/%1").arg(slug); - break; - case ModPlatform::ResourceProvider::FLAME: - link = QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug); - break; - } - } else if (!m.homeurl().isEmpty()) - link = m.homeurl(); - if (link.isEmpty()) text = name; else { text = "
    " + name + ""; - toolTip = tr("Go to mod's home page"); + toolTip = link; } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); From 40fbae8ff684b6613ff073ec1992587b38dcdf8c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 11:36:37 +0300 Subject: [PATCH 210/429] Fixed links tooltip Signed-off-by: Trial97 --- launcher/ui/widgets/InfoFrame.cpp | 36 ++++++++++++++++++++----------- launcher/ui/widgets/InfoFrame.h | 2 +- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 57562a931..243490140 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -34,13 +34,24 @@ * limitations under the License. */ +#include #include +#include #include "InfoFrame.h" #include "ui_InfoFrame.h" #include "ui/dialogs/CustomMessageBox.h" +void setupLinkTooTip(QLabel* label) +{ + QObject::connect(label, &QLabel::linkHovered, [label](const QString& link) { + if (!link.isEmpty() && !link.startsWith("http")) + return; + label->setToolTip(link); + }); +} + InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) { ui->setupUi(this); @@ -48,6 +59,12 @@ InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) ui->nameLabel->setHidden(true); ui->licenseLabel->setHidden(true); ui->issueTrackerLabel->setHidden(true); + + setupLinkTooTip(ui->iconLabel); + setupLinkTooTip(ui->descriptionLabel); + setupLinkTooTip(ui->nameLabel); + setupLinkTooTip(ui->licenseLabel); + setupLinkTooTip(ui->issueTrackerLabel); updateHiddenState(); } @@ -66,7 +83,6 @@ void InfoFrame::updateWithMod(Mod const& m) QString text = ""; QString name = ""; QString link = m.metaurl(); - QString toolTip = ""; if (m.name().isEmpty()) name = m.internal_id(); else @@ -76,12 +92,11 @@ void InfoFrame::updateWithMod(Mod const& m) text = name; else { text = "" + name + ""; - toolTip = link; } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); - setName(text, toolTip); + setName(text); if (m.description().isEmpty()) { setDescription(QString()); @@ -89,14 +104,14 @@ void InfoFrame::updateWithMod(Mod const& m) setDescription(m.description()); } - setImage(m.icon({64,64})); + setImage(m.icon({ 64, 64 })); auto licenses = m.licenses(); QString licenseText = ""; if (!licenses.empty()) { for (auto l : licenses) { if (!licenseText.isEmpty()) { - licenseText += "\n"; // add newline between licenses + licenseText += "\n"; // add newline between licenses } if (!l.name.isEmpty()) { if (l.url.isEmpty()) { @@ -226,29 +241,24 @@ void InfoFrame::updateHiddenState() } } -void InfoFrame::setName(QString text, QString toolTip) +void InfoFrame::setName(QString text) { if (text.isEmpty()) { ui->nameLabel->setHidden(true); - ui->nameLabel->setToolTip({}); } else { ui->nameLabel->setText(text); ui->nameLabel->setHidden(false); - ui->nameLabel->setToolTip(toolTip); } updateHiddenState(); } void InfoFrame::setDescription(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->descriptionLabel->setHidden(true); updateHiddenState(); return; - } - else - { + } else { ui->descriptionLabel->setHidden(false); updateHiddenState(); } diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h index b8c7e9a0b..d6764baa2 100644 --- a/launcher/ui/widgets/InfoFrame.h +++ b/launcher/ui/widgets/InfoFrame.h @@ -52,7 +52,7 @@ class InfoFrame : public QFrame { InfoFrame(QWidget* parent = nullptr); ~InfoFrame() override; - void setName(QString text = {}, QString toolTip = {}); + void setName(QString text = {}); void setDescription(QString text = {}); void setImage(QPixmap img = {}); void setLicense(QString text = {}); From fd5b155ee7d796015c84c8b348f384bf21d8328d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 12:24:59 +0300 Subject: [PATCH 211/429] Added error message when exporting snapshots with curseforge Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 18 +++++++++++------- launcher/ui/MainWindow.cpp | 9 ++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index e73f3de59..e5eeb0980 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -409,16 +409,20 @@ QByteArray FlamePackExportTask::generateIndex() // convert all available components to mrpack dependencies if (minecraft != nullptr) version["version"] = minecraft->m_version; - - QJsonObject loader; + QString id; if (quilt != nullptr) - loader["id"] = "quilt-" + quilt->getVersion(); + id = "quilt-" + quilt->getVersion(); else if (fabric != nullptr) - loader["id"] = "fabric-" + fabric->getVersion(); + id = "fabric-" + fabric->getVersion(); else if (forge != nullptr) - loader["id"] = "forge-" + forge->getVersion(); - loader["primary"] = true; - version["modLoaders"] = QJsonArray({ loader }); + id = "forge-" + forge->getVersion(); + version["modLoaders"] = QJsonArray(); + if (!id.isEmpty()) { + QJsonObject loader; + loader["id"] = id; + loader["primary"] = true; + version["modLoaders"] = QJsonArray({ loader }); + } obj["minecraft"] = version; } diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 91809c7b3..50eb9e64f 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1422,9 +1422,16 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() if (m_selectedInstance) { auto instance = dynamic_cast(m_selectedInstance.get()); if (instance) { + QString errorMsg; if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { + errorMsg = tr("Quilt is currently not supported by CurseForge modpacks."); + } else if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft"); + cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") { + errorMsg = tr("Snapshots are currently not supported by CurseForge modpacks."); + } + if (!errorMsg.isEmpty()) { QMessageBox msgBox; - msgBox.setText(tr("Quilt is currently not supported by CurseForge modpacks.")); + msgBox.setText(errorMsg); msgBox.exec(); return; } From 603ed220151345f44a43e14538ea449bae843958 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 10:36:54 +0100 Subject: [PATCH 212/429] Replace accidental usages of QAbstractButton::pressed This signal is not usually what you want, and creates an inconsistent experience. Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ManagedPackPage.cpp | 4 ++-- launcher/ui/pages/modplatform/legacy_ftb/Page.cpp | 4 ++-- launcher/ui/setupwizard/SetupWizard.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index e0a7314ff..d89c5bfc0 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -205,7 +205,7 @@ ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWin { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); - connect(ui->updateButton, &QPushButton::pressed, this, &ModrinthManagedPackPage::update); + connect(ui->updateButton, &QPushButton::clicked, this, &ModrinthManagedPackPage::update); } // MODRINTH @@ -332,7 +332,7 @@ FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, InstanceWindow* i { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); - connect(ui->updateButton, &QPushButton::pressed, this, &FlameManagedPackPage::update); + connect(ui->updateButton, &QPushButton::clicked, this, &FlameManagedPackPage::update); } void FlameManagedPackPage::parseManagedPack() diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp index 98ab87999..b3f6261fe 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp @@ -116,8 +116,8 @@ Page::Page(NewInstanceDialog* dialog, QWidget *parent) connect(ui->thirdPartyPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onThirdPartyPackSelectionChanged); connect(ui->privatePackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onPrivatePackSelectionChanged); - connect(ui->addPackBtn, &QPushButton::pressed, this, &Page::onAddPackClicked); - connect(ui->removePackBtn, &QPushButton::pressed, this, &Page::onRemovePackClicked); + connect(ui->addPackBtn, &QPushButton::clicked, this, &Page::onAddPackClicked); + connect(ui->removePackBtn, &QPushButton::clicked, this, &Page::onRemovePackClicked); connect(ui->tabWidget, &QTabWidget::currentChanged, this, &Page::onTabChanged); diff --git a/launcher/ui/setupwizard/SetupWizard.cpp b/launcher/ui/setupwizard/SetupWizard.cpp index 3fd9bb233..0a47334fc 100644 --- a/launcher/ui/setupwizard/SetupWizard.cpp +++ b/launcher/ui/setupwizard/SetupWizard.cpp @@ -59,7 +59,7 @@ void SetupWizard::pageChanged(int id) { setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton}); auto customButton = button(QWizard::CustomButton1); - connect(customButton, &QAbstractButton::pressed, [&](){ + connect(customButton, &QAbstractButton::clicked, [&](){ auto basePagePtr = getCurrentBasePage(); if(basePagePtr) { From 514080653f2a862c6d3b2f1efb279a6707ccfb1c Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 11:56:28 +0100 Subject: [PATCH 213/429] Fix unsafe usage of std::optional::value in FlameAPI Signed-off-by: TheKodeToad --- launcher/modplatform/flame/FlameAPI.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index a0611957c..0a6dc78f8 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -77,24 +77,28 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getVersionsURL(VersionSearchArgs const& args) const override { - auto mappedModLoader = getMappedModLoader(args.loaders.value()); auto addonId = args.pack.addonId.toString(); - if (args.loaders.value() & Quilt) { - auto overide = ModPlatform::getOverrideDeps(); - auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) { - return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt; - }); - if (over != overide.cend()) { - mappedModLoader = 5; - } - } QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(addonId) }; QStringList get_parameters; if (args.mcVersions.has_value()) get_parameters.append(QString("gameVersion=%1").arg(args.mcVersions.value().front().toString())); - if (args.loaders.has_value()) + + if (args.loaders.has_value()) { + int mappedModLoader = getMappedModLoader(args.loaders.value()); + + if (args.loaders.value() & Quilt) { + auto overide = ModPlatform::getOverrideDeps(); + auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) { + return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt; + }); + if (over != overide.cend()) { + mappedModLoader = 5; + } + } + get_parameters.append(QString("modLoaderType=%1").arg(mappedModLoader)); + } return url + get_parameters.join('&'); }; From 84c63f4f017324b42c2470fb2e7a1ac5858fcaa0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 14:11:41 +0300 Subject: [PATCH 214/429] Added plantxt export Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 10 +- launcher/minecraft/mod/Mod.cpp | 7 + launcher/minecraft/mod/Mod.h | 1 + launcher/modplatform/ModIndex.cpp | 8 +- launcher/modplatform/ModIndex.h | 1 + ...dsToStringTask.cpp => ExportToModList.cpp} | 60 +++--- ...rtModsToStringTask.h => ExportToModList.h} | 10 +- launcher/ui/MainWindow.cpp | 8 +- launcher/ui/MainWindow.h | 2 +- launcher/ui/MainWindow.ui | 4 +- .../ui/dialogs/ExportModsToStringDialog.cpp | 122 ------------- launcher/ui/dialogs/ExportToModListDialog.cpp | 171 ++++++++++++++++++ ...StringDialog.h => ExportToModListDialog.h} | 16 +- ...ringDialog.ui => ExportToModListDialog.ui} | 38 +++- 14 files changed, 282 insertions(+), 176 deletions(-) rename launcher/modplatform/helpers/{ExportModsToStringTask.cpp => ExportToModList.cpp} (67%) rename launcher/modplatform/helpers/{ExportModsToStringTask.h => ExportToModList.h} (77%) delete mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.cpp create mode 100644 launcher/ui/dialogs/ExportToModListDialog.cpp rename launcher/ui/dialogs/{ExportModsToStringDialog.h => ExportToModListDialog.h} (71%) rename launcher/ui/dialogs/{ExportModsToStringDialog.ui => ExportToModListDialog.ui} (82%) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index aab7e90d1..a4e82576f 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -490,8 +490,8 @@ set(API_SOURCES modplatform/helpers/OverrideUtils.h modplatform/helpers/OverrideUtils.cpp - modplatform/helpers/ExportModsToStringTask.h - modplatform/helpers/ExportModsToStringTask.cpp + modplatform/helpers/ExportToModList.h + modplatform/helpers/ExportToModList.cpp ) set(FTB_SOURCES @@ -913,8 +913,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/ExportInstanceDialog.h ui/dialogs/ExportMrPackDialog.cpp ui/dialogs/ExportMrPackDialog.h - ui/dialogs/ExportModsToStringDialog.cpp - ui/dialogs/ExportModsToStringDialog.h + ui/dialogs/ExportToModListDialog.cpp + ui/dialogs/ExportToModListDialog.h ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.h ui/dialogs/ImportResourceDialog.cpp @@ -1062,7 +1062,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/SkinUploadDialog.ui ui/dialogs/ExportInstanceDialog.ui ui/dialogs/ExportMrPackDialog.ui - ui/dialogs/ExportModsToStringDialog.ui + ui/dialogs/ExportToModListDialog.ui ui/dialogs/IconPickerDialog.ui ui/dialogs/ImportResourceDialog.ui ui/dialogs/MSALoginDialog.ui diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e613ddeb7..d5b96badd 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,6 +166,13 @@ auto Mod::homeurl() const -> QString return details().homeurl; } +auto Mod::metaurl() const -> QString +{ + if (metadata() == nullptr) + return homeurl(); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); +} + auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d4e419f4f..d6272f4d0 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,6 +70,7 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 6a507caf4..a1c4d8917 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -70,11 +70,17 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t } QCryptographicHash hash(algo); - if(!hash.addData(device)) + 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/") + + projectID.toString(); +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 3b0a03a18..3f51e700f 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -144,6 +144,7 @@ inline auto getOverrideDeps() -> QList { "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH }, { "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } }; }; +QString getMetaURL(ResourceProvider provider, QVariant projectID); } // namespace ModPlatform diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportToModList.cpp similarity index 67% rename from launcher/modplatform/helpers/ExportModsToStringTask.cpp rename to launcher/modplatform/helpers/ExportToModList.cpp index e7be5ce13..5e01367f9 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -15,11 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "ExportModsToStringTask.h" -#include "modplatform/ModIndex.h" +#include "ExportToModList.h" -namespace ExportToString { -QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) +namespace ExportToModList { +QString ExportToModList(QList mods, Formats format, OptionalData extraData) { switch (format) { case HTML: { @@ -28,12 +27,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex auto meta = mod->metadata(); auto modName = mod->name(); if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); if (!url.isEmpty()) modName = QString("%2").arg(url, modName); } @@ -49,7 +43,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex line += " by " + mod->authors().join(", "); lines.append(QString("
      %1
    ").arg(line)); } - return QString("\n\t%1\n").arg(lines.join("\n\t")); + return QString("
  • \n\t%1\n
  • ").arg(lines.join("\n\t")); } case MARKDOWN: { QStringList lines; @@ -57,12 +51,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex auto meta = mod->metadata(); auto modName = mod->name(); if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); if (!url.isEmpty()) modName = QString("[%1](%2)").arg(modName, url); } @@ -76,6 +65,31 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex } if (extraData & Authors && !mod->authors().isEmpty()) line += " by " + mod->authors().join(", "); + lines << "- " + line; + } + return lines.join("\n"); + } + case PLAINTXT: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + + auto line = "name: " + modName + ";"; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + line += " url: " + url + ";"; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += " version: " + QString("[%1]").arg(ver) + ";"; + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " authors " + mod->authors().join(", ") + ";"; lines << line; } return lines.join("\n"); @@ -86,19 +100,13 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex } } -QString ExportModsToStringTask(QList mods, QString lineTemplate) +QString ExportToModList(QList mods, QString lineTemplate) { QStringList lines; for (auto mod : mods) { auto meta = mod->metadata(); auto modName = mod->name(); - - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); @@ -111,4 +119,4 @@ QString ExportModsToStringTask(QList mods, QString lineTemplate) } return lines.join("\n"); } -} // namespace ExportToString \ No newline at end of file +} // namespace ExportToModList \ No newline at end of file diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.h b/launcher/modplatform/helpers/ExportToModList.h similarity index 77% rename from launcher/modplatform/helpers/ExportModsToStringTask.h rename to launcher/modplatform/helpers/ExportToModList.h index 756c69f77..9ff8d25a1 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -20,14 +20,14 @@ #include #include "minecraft/mod/Mod.h" -namespace ExportToString { +namespace ExportToModList { -enum Formats { HTML, MARKDOWN }; +enum Formats { HTML, MARKDOWN, PLAINTXT, CUSTOM }; enum OptionalData { Authors = 1 << 0, Url = 1 << 1, Version = 1 << 2, }; -QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData); -QString ExportModsToStringTask(QList mods, QString lineTemplate); -} // namespace ExportToString +QString ExportToModList(QList mods, Formats format, OptionalData extraData); +QString ExportToModList(QList mods, QString lineTemplate); +} // namespace ExportToModList diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 02ea30c36..37f4d4ed5 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -43,7 +43,7 @@ #include "FileSystem.h" #include "MainWindow.h" -#include "ui/dialogs/ExportModsToStringDialog.h" +#include "ui/dialogs/ExportToModListDialog.h" #include "ui_MainWindow.h" #include @@ -206,7 +206,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto exportInstanceMenu = new QMenu(this); exportInstanceMenu->addAction(ui->actionExportInstanceZip); exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); - exportInstanceMenu->addAction(ui->actionExportInstanceToString); + exportInstanceMenu->addAction(ui->actionExportInstanceToModList); ui->actionExportInstance->setMenu(exportInstanceMenu); } @@ -1418,10 +1418,10 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() } } -void MainWindow::on_actionExportInstanceToString_triggered() +void MainWindow::on_actionExportInstanceToModList_triggered() { if (m_selectedInstance) { - ExportModsToStringDialog dlg(m_selectedInstance, this); + ExportToModListDialog dlg(m_selectedInstance, this); dlg.exec(); } } diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 9b38810f0..f62e39e15 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -157,7 +157,7 @@ private slots: inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); - void on_actionExportInstanceToString_triggered(); + void on_actionExportInstanceToModList_triggered(); void on_actionRenameInstance_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index ecc7e2362..027742ba4 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -479,12 +479,12 @@ Modrinth (mrpack)
    - + - Text + ModList (txt) diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp deleted file mode 100644 index 29d69918e..000000000 --- a/launcher/ui/dialogs/ExportModsToStringDialog.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// 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 "ExportModsToStringDialog.h" -#include -#include -#include -#include "minecraft/MinecraftInstance.h" -#include "minecraft/mod/ModFolderModel.h" -#include "modplatform/helpers/ExportModsToStringTask.h" -#include "ui_ExportModsToStringDialog.h" - -#include -#include -#include -#include -#include - -ExportModsToStringDialog::ExportModsToStringDialog(InstancePtr instance, QWidget* parent) - : QDialog(parent), m_template_selected(false), ui(new Ui::ExportModsToStringDialog) -{ - ui->setupUi(this); - ui->templateGroup->setDisabled(true); - - MinecraftInstance* mcInstance = dynamic_cast(instance.get()); - if (mcInstance) { - mcInstance->loaderModList()->update(); - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { - m_allMods = mcInstance->loaderModList()->allMods(); - triggerImp(); - }); - } - - connect(ui->formatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ExportModsToStringDialog::formatChanged); - connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::triggerImp); - connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { - this->ui->finalText->selectAll(); - this->ui->finalText->copy(); - }); -} - -ExportModsToStringDialog::~ExportModsToStringDialog() -{ - delete ui; -} - -void ExportModsToStringDialog::formatChanged(int index) -{ - switch (index) { - case 0: { - ui->templateGroup->setDisabled(true); - ui->optionsGroup->setDisabled(false); - break; - } - case 1: { - ui->templateGroup->setDisabled(true); - ui->optionsGroup->setDisabled(false); - break; - } - case 2: { - ui->templateGroup->setDisabled(false); - ui->optionsGroup->setDisabled(true); - break; - } - } - triggerImp(); -} - -void ExportModsToStringDialog::triggerImp() -{ - auto format = ExportToString::HTML; - switch (ui->formatComboBox->currentIndex()) { - case 2: { - m_template_selected = true; - ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, ui->templateText->toPlainText())); - return; - } - case 0: { - format = ExportToString::HTML; - break; - } - case 1: { - format = ExportToString::MARKDOWN; - break; - } - default: { - return; - } - } - auto opt = 0; - if (ui->authorsCheckBox->isChecked()) - opt |= ExportToString::Authors; - if (ui->versionCheckBox->isChecked()) - opt |= ExportToString::Version; - if (ui->urlCheckBox->isChecked()) - opt |= ExportToString::Url; - ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, format, static_cast(opt))); - if (!m_template_selected) { - auto exampleLine = format == ExportToString::HTML ? "
      {name}[{version}] by {authors}
    " - : "[{name}]({url})[{version}] by {authors}"; - if (ui->templateText->toPlainText() != exampleLine) - ui->templateText->setPlainText(exampleLine); - } -} diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp new file mode 100644 index 000000000..0550725f6 --- /dev/null +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -0,0 +1,171 @@ +// 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 "ExportToModListDialog.h" +#include +#include +#include +#include "FileSystem.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/ExportToModList.h" +#include "ui_ExportToModListDialog.h" + +#include +#include +#include +#include +#include + +ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* parent) + : QDialog(parent), m_template_selected(false), name(instance->name()), ui(new Ui::ExportToModListDialog) +{ + ui->setupUi(this); + ui->templateGroup->setDisabled(true); + + MinecraftInstance* mcInstance = dynamic_cast(instance.get()); + if (mcInstance) { + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { + m_allMods = mcInstance->loaderModList()->allMods(); + triggerImp(); + }); + } + + connect(ui->formatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ExportToModListDialog::formatChanged); + connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->templateText, &QTextEdit::textChanged, this, &ExportToModListDialog::triggerImp); + connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { + this->ui->finalText->selectAll(); + this->ui->finalText->copy(); + }); +} + +ExportToModListDialog::~ExportToModListDialog() +{ + delete ui; +} + +void ExportToModListDialog::formatChanged(int index) +{ + switch (index) { + case 0: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->show(); + format = ExportToModList::HTML; + break; + } + case 1: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->show(); + format = ExportToModList::MARKDOWN; + break; + } + case 2: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->hide(); + format = ExportToModList::PLAINTXT; + break; + } + case 3: { + ui->templateGroup->setDisabled(false); + ui->optionsGroup->setDisabled(true); + ui->resultText->hide(); + format = ExportToModList::CUSTOM; + break; + } + } + triggerImp(); +} + +void ExportToModListDialog::triggerImp() +{ + if (format == ExportToModList::CUSTOM) { + m_template_selected = true; + ui->finalText->setPlainText(ExportToModList::ExportToModList(m_allMods, ui->templateText->toPlainText())); + return; + } + auto opt = 0; + if (ui->authorsCheckBox->isChecked()) + opt |= ExportToModList::Authors; + if (ui->versionCheckBox->isChecked()) + opt |= ExportToModList::Version; + if (ui->urlCheckBox->isChecked()) + opt |= ExportToModList::Url; + auto txt = ExportToModList::ExportToModList(m_allMods, format, static_cast(opt)); + ui->finalText->setPlainText(txt); + QString exampleLine; + switch (format) { + case ExportToModList::HTML: { + exampleLine = "
      {name}[{version}] by {authors}
    "; + ui->resultText->setHtml(txt); + break; + } + case ExportToModList::MARKDOWN: { + exampleLine = "[{name}]({url})[{version}] by {authors}"; + ui->resultText->setMarkdown(txt); + break; + } + case ExportToModList::PLAINTXT: { + exampleLine = "name: {name}; url: {url}; version: {version}; authors: {authors};"; + break; + } + case ExportToModList::CUSTOM: + return; + } + if (!m_template_selected) { + if (ui->templateText->toPlainText() != exampleLine) + ui->templateText->setPlainText(exampleLine); + } +} + +void ExportToModListDialog::done(int result) +{ + if (result == Accepted) { + const QString filename = FS::RemoveInvalidFilenameChars(name); + const QString output = + QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + extension()), + "File (*.txt *.html *.md)", nullptr); + + if (output.isEmpty()) + return; + FS::write(output, ui->finalText->toPlainText().toUtf8()); + } + + QDialog::done(result); +} + +QString ExportToModListDialog::extension() +{ + switch (format) { + case ExportToModList::HTML: + return ".html"; + case ExportToModList::MARKDOWN: + return ".md"; + case ExportToModList::PLAINTXT: + return ".txt"; + case ExportToModList::CUSTOM: + return ".txt"; + } + return ".txt"; +} diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h similarity index 71% rename from launcher/ui/dialogs/ExportModsToStringDialog.h rename to launcher/ui/dialogs/ExportToModListDialog.h index d195d1cec..a7a6bcdce 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.h +++ b/launcher/ui/dialogs/ExportToModListDialog.h @@ -22,17 +22,20 @@ #include #include "BaseInstance.h" #include "minecraft/mod/Mod.h" +#include "modplatform/helpers/ExportToModList.h" namespace Ui { -class ExportModsToStringDialog; +class ExportToModListDialog; } -class ExportModsToStringDialog : public QDialog { +class ExportToModListDialog : public QDialog { Q_OBJECT public: - explicit ExportModsToStringDialog(InstancePtr instance, QWidget* parent = nullptr); - ~ExportModsToStringDialog(); + explicit ExportToModListDialog(InstancePtr instance, QWidget* parent = nullptr); + ~ExportToModListDialog(); + + void done(int result) override; protected slots: void formatChanged(int index); @@ -40,7 +43,10 @@ class ExportModsToStringDialog : public QDialog { void trigger(int) { triggerImp(); }; private: + QString extension(); QList m_allMods; bool m_template_selected; - Ui::ExportModsToStringDialog* ui; + QString name; + ExportToModList::Formats format = ExportToModList::Formats::HTML; + Ui::ExportToModListDialog* ui; }; diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui similarity index 82% rename from launcher/ui/dialogs/ExportModsToStringDialog.ui rename to launcher/ui/dialogs/ExportToModListDialog.ui index 4451a2785..640b17665 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -1,7 +1,7 @@ - ExportModsToStringDialog - + ExportToModListDialog + 0 @@ -11,7 +11,7 @@ - Export Modrinth Pack + Export Pack to ModList true @@ -53,6 +53,11 @@ Markdown + + + Plaintext + + Custom @@ -124,6 +129,13 @@ + + + + true + + + @@ -141,7 +153,7 @@ - QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Save @@ -154,7 +166,7 @@ buttonBox accepted() - ExportModsToStringDialog + ExportToModListDialog accept() @@ -167,5 +179,21 @@ + + buttonBox + rejected() + ExportToModListDialog + reject() + + + 324 + 390 + + + 324 + 206 + + + From d1603f19459a499e5278f38b69222e3f4e0875b4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 14:43:11 +0300 Subject: [PATCH 215/429] Made it more similar to mrpack export Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 67 ++++++++++++++----- .../modplatform/flame/FlamePackExportTask.h | 2 + 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index e5eeb0980..b14c6eb4b 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -37,6 +37,8 @@ #include "tasks/Task.h" const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • \n"; +const QStringList FlamePackExportTask::PREFIXES({ "mods/", "resourcepacks/" }); +const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "zip" }); FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, @@ -105,33 +107,62 @@ void FlamePackExportTask::collectHashes() { setAbortable(true); setStatus(tr("Find file hashes...")); - auto mods = mcInstance->loaderModList()->allMods(); + auto allMods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); task.reset(hashing_task); - int totalProgres = mods.count(); + int totalProgres = allMods.count(); setProgress(0, totalProgres); - for (auto* mod : mods) { - if (!mod || mod->type() == ResourceType::FOLDER) { - setProgress(m_progress + 1, totalProgres); + + for (const QFileInfo& file : files) { + const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); + // require sensible file types + if (!std::any_of(PREFIXES.begin(), PREFIXES.end(), [&relative](const QString& prefix) { return relative.startsWith(prefix); })) continue; - } - if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { - resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), - { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), true, - mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); - setProgress(m_progress + 1, totalProgres); + if (!std::any_of(FILE_EXTENSIONS.begin(), FILE_EXTENSIONS.end(), [&relative](const QString& extension) { + return relative.endsWith('.' + extension) || relative.endsWith('.' + extension + ".disabled"); + })) + continue; + + if (relative.startsWith("resourcepacks/") && + (relative.endsWith(".zip") || relative.endsWith(".zip.disabled"))) { // is resourcepack + totalProgres++; + auto hash_task = Hashing::createFlameHasher(file.absoluteFilePath()); + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, relative, file, totalProgres](QString hash) { + if (m_state == Task::State::Running) { + setProgress(m_progress + 1, totalProgres); + pendingHashes.insert(hash, { relative, file.absoluteFilePath(), relative.endsWith(".zip") }); + } + }); + connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + hashing_task->addTask(hash_task); continue; } - auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { - if (m_state == Task::State::Running) { + if (auto modIter = std::find_if(allMods.begin(), allMods.end(), [&file](Mod* mod) { return mod->fileinfo() == file; }); + modIter != allMods.end()) { + const Mod* mod = *modIter; + if (!mod || mod->type() == ResourceType::FOLDER) { setProgress(m_progress + 1, totalProgres); - pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled(), true }); + continue; } - }); - connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); - hashing_task->addTask(hash_task); + if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { + resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), true, + mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); + setProgress(m_progress + 1, totalProgres); + continue; + } + + auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { + if (m_state == Task::State::Running) { + setProgress(m_progress + 1, totalProgres); + pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled(), true }); + } + }); + connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + hashing_task->addTask(hash_task); + } } for (const QFileInfo& file : files) { diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 5c8caa458..b6a6c3529 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -42,6 +42,8 @@ class FlamePackExportTask : public Task { private: static const QString TEMPLATE; + static const QStringList PREFIXES; + static const QStringList FILE_EXTENSIONS; // inputs const QString name, version, author; From c75ba0f8551e911b72152ebdd8b2fe1f8bd8f64f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 12:46:07 +0100 Subject: [PATCH 216/429] Fix big mistake :iea: Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 893fe2a52..2a7c5b271 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -85,7 +85,7 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) case 0: APPLICATION->ShowGlobalSettings(this, "java-settings"); return; - case 1: + case 2: APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; default: From 8d3bc6b6b94ff5fb2dba0c06bf6d108794af7d8f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 14:58:54 +0300 Subject: [PATCH 217/429] Added markdown QT version check Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportToModListDialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 0550725f6..715a62c34 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -76,7 +76,11 @@ void ExportToModListDialog::formatChanged(int index) case 1: { ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) ui->resultText->show(); +#else + ui->resultText->hide(); +#endif format = ExportToModList::MARKDOWN; break; } @@ -123,7 +127,9 @@ void ExportToModListDialog::triggerImp() } case ExportToModList::MARKDOWN: { exampleLine = "[{name}]({url})[{version}] by {authors}"; +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) ui->resultText->setMarkdown(txt); +#endif break; } case ExportToModList::PLAINTXT: { From 3546f57a42eb23053772eb5b84cb864f9c83b166 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 15:17:09 +0300 Subject: [PATCH 218/429] Use internal markdown implementation Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportToModListDialog.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 715a62c34..57ee44537 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -21,6 +21,7 @@ #include #include #include "FileSystem.h" +#include "Markdown.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/helpers/ExportToModList.h" @@ -76,11 +77,7 @@ void ExportToModListDialog::formatChanged(int index) case 1: { ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); -#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) ui->resultText->show(); -#else - ui->resultText->hide(); -#endif format = ExportToModList::MARKDOWN; break; } @@ -127,9 +124,7 @@ void ExportToModListDialog::triggerImp() } case ExportToModList::MARKDOWN: { exampleLine = "[{name}]({url})[{version}] by {authors}"; -#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) - ui->resultText->setMarkdown(txt); -#endif + ui->resultText->setHtml(markdownToHTML(txt)); break; } case ExportToModList::PLAINTXT: { From 02b628653b4d2574766e1148ebd71b426b52a5d2 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 13:42:45 +0100 Subject: [PATCH 219/429] Fix markdown header Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 1 + launcher/Markdown.cpp | 31 +++++++++++++++++++++++++++++++ launcher/Markdown.h | 12 +----------- 3 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 launcher/Markdown.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c10064c00..3cc8b6e11 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -684,6 +684,7 @@ SET(LAUNCHER_SOURCES VersionProxyModel.h VersionProxyModel.cpp Markdown.h + Markdown.cpp # Super secret! KonamiCode.h diff --git a/launcher/Markdown.cpp b/launcher/Markdown.cpp new file mode 100644 index 000000000..426067bf6 --- /dev/null +++ b/launcher/Markdown.cpp @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 Joshua Goins + * + * 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 "Markdown.h" + +QString markdownToHTML(const QString& markdown) +{ + const QByteArray markdownData = markdown.toUtf8(); + char* buffer = cmark_markdown_to_html(markdownData.constData(), markdownData.length(), CMARK_OPT_NOBREAKS | CMARK_OPT_UNSAFE); + + QString htmlStr(buffer); + + free(buffer); + + return htmlStr; +} \ No newline at end of file diff --git a/launcher/Markdown.h b/launcher/Markdown.h index f115dd570..6b261e60c 100644 --- a/launcher/Markdown.h +++ b/launcher/Markdown.h @@ -21,14 +21,4 @@ #include #include -static QString markdownToHTML(const QString& markdown) -{ - const QByteArray markdownData = markdown.toUtf8(); - char* buffer = cmark_markdown_to_html(markdownData.constData(), markdownData.length(), CMARK_OPT_NOBREAKS | CMARK_OPT_UNSAFE); - - QString htmlStr(buffer); - - free(buffer); - - return htmlStr; -} \ No newline at end of file +QString markdownToHTML(const QString& markdown); \ No newline at end of file From 953a2590e27954a3b1d163224bd343bb75a62b69 Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 25 Jun 2023 10:11:58 -0300 Subject: [PATCH 220/429] Add fixme comment for no SSD detection Co-authored-by: Sefa Eyeoglu Signed-off-by: Leo --- launcher/ui/MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 9b8db1ae5..7e2c4acf7 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -221,6 +221,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi setInstanceActionsEnabled(false); // add a close button at the end of the main toolbar when running on gamescope / steam deck + // FIXME: detect if we don't have server side decorations instead if (qgetenv("XDG_CURRENT_DESKTOP") == "gamescope") { ui->mainToolBar->addAction(ui->actionCloseWindow); } From fa3a46498f7fe4a7d6e26558c03b0485126b377c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 16:23:50 +0300 Subject: [PATCH 221/429] Removed dupliacte code Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index b14c6eb4b..cbb57afa6 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -165,21 +165,6 @@ void FlamePackExportTask::collectHashes() } } - for (const QFileInfo& file : files) { - const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!relative.endsWith(".zip") || !relative.startsWith("resourcepacks/")) - continue; - totalProgres++; - auto hash_task = Hashing::createFlameHasher(file.absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, relative, file, totalProgres](QString hash) { - if (m_state == Task::State::Running) { - setProgress(m_progress + 1, totalProgres); - pendingHashes.insert(hash, { relative, file.absoluteFilePath(), true }); - } - }); - connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); - hashing_task->addTask(hash_task); - } connect(hashing_task.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); connect(hashing_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); hashing_task->start(); From 8ade44c9a3b186fb5ab19d9802a4d7b4187b7258 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 14:39:45 +0100 Subject: [PATCH 222/429] Simplify Signed-off-by: TheKodeToad --- launcher/modplatform/flame/FlamePackExportTask.cpp | 3 --- launcher/modplatform/flame/FlamePackExportTask.h | 1 - 2 files changed, 4 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index cbb57afa6..1460a4c3b 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -37,7 +37,6 @@ #include "tasks/Task.h" const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • \n"; -const QStringList FlamePackExportTask::PREFIXES({ "mods/", "resourcepacks/" }); const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "zip" }); FlamePackExportTask::FlamePackExportTask(const QString& name, @@ -116,8 +115,6 @@ void FlamePackExportTask::collectHashes() for (const QFileInfo& file : files) { const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); // require sensible file types - if (!std::any_of(PREFIXES.begin(), PREFIXES.end(), [&relative](const QString& prefix) { return relative.startsWith(prefix); })) - continue; if (!std::any_of(FILE_EXTENSIONS.begin(), FILE_EXTENSIONS.end(), [&relative](const QString& extension) { return relative.endsWith('.' + extension) || relative.endsWith('.' + extension + ".disabled"); })) diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index b6a6c3529..3dee0a7ea 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -42,7 +42,6 @@ class FlamePackExportTask : public Task { private: static const QString TEMPLATE; - static const QStringList PREFIXES; static const QStringList FILE_EXTENSIONS; // inputs From 288ea3d19b6edbd2b4570408e71e635df0d7abfe Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 14:52:33 +0100 Subject: [PATCH 223/429] Remove metaurl function Signed-off-by: TheKodeToad --- launcher/minecraft/mod/Mod.cpp | 7 ------- launcher/minecraft/mod/Mod.h | 1 - 2 files changed, 8 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index d5b96badd..e613ddeb7 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,13 +166,6 @@ auto Mod::homeurl() const -> QString return details().homeurl; } -auto Mod::metaurl() const -> QString -{ - if (metadata() == nullptr) - return homeurl(); - return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); -} - auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d6272f4d0..d4e419f4f 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,7 +70,6 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; - auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; From 4745ab64cdf073b781515f43f7b10cd7f776078b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 15:02:25 +0100 Subject: [PATCH 224/429] Deduplicate launcher icon Signed-off-by: TheKodeToad --- launcher/resources/OSX/OSX.qrc | 1 - launcher/resources/OSX/scalable/launcher.svg | 57 ------------------- .../breeze_dark/scalable/launcher.svg | 57 ------------------- launcher/resources/flat/flat.qrc | 1 - launcher/resources/flat/scalable/launcher.svg | 57 ------------------- launcher/resources/flat_white/flat_white.qrc | 1 - .../flat_white/scalable/launcher.svg | 57 ------------------- launcher/resources/iOS/iOS.qrc | 1 - launcher/resources/iOS/scalable/launcher.svg | 57 ------------------- launcher/resources/pe_blue/pe_blue.qrc | 1 - .../resources/pe_blue/scalable/launcher.svg | 57 ------------------- launcher/resources/pe_colored/pe_colored.qrc | 1 - .../pe_colored/scalable/launcher.svg | 57 ------------------- launcher/resources/pe_dark/pe_dark.qrc | 1 - .../resources/pe_dark/scalable/launcher.svg | 57 ------------------- launcher/resources/pe_light/pe_light.qrc | 1 - .../resources/pe_light/scalable/launcher.svg | 57 ------------------- 17 files changed, 521 deletions(-) delete mode 100644 launcher/resources/OSX/scalable/launcher.svg delete mode 100644 launcher/resources/breeze_dark/scalable/launcher.svg delete mode 100644 launcher/resources/flat/scalable/launcher.svg delete mode 100644 launcher/resources/flat_white/scalable/launcher.svg delete mode 100644 launcher/resources/iOS/scalable/launcher.svg delete mode 100644 launcher/resources/pe_blue/scalable/launcher.svg delete mode 100644 launcher/resources/pe_colored/scalable/launcher.svg delete mode 100644 launcher/resources/pe_dark/scalable/launcher.svg delete mode 100644 launcher/resources/pe_light/scalable/launcher.svg diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc index 9d4511d1a..49f56b0c1 100644 --- a/launcher/resources/OSX/OSX.qrc +++ b/launcher/resources/OSX/OSX.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/OSX/scalable/launcher.svg b/launcher/resources/OSX/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/OSX/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/breeze_dark/scalable/launcher.svg b/launcher/resources/breeze_dark/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/breeze_dark/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc index cadf87364..2fd5daefe 100644 --- a/launcher/resources/flat/flat.qrc +++ b/launcher/resources/flat/flat.qrc @@ -18,7 +18,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/flat/scalable/launcher.svg b/launcher/resources/flat/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/flat/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index 2701462fe..a1c940da0 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -18,7 +18,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/flat_white/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc index 0b79efb2a..9b8d84f50 100644 --- a/launcher/resources/iOS/iOS.qrc +++ b/launcher/resources/iOS/iOS.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/iOS/scalable/launcher.svg b/launcher/resources/iOS/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/iOS/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc index 1b2b62915..da45ef9a1 100644 --- a/launcher/resources/pe_blue/pe_blue.qrc +++ b/launcher/resources/pe_blue/pe_blue.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_blue/scalable/launcher.svg b/launcher/resources/pe_blue/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/pe_blue/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc index 084fca930..ba5bd44f9 100644 --- a/launcher/resources/pe_colored/pe_colored.qrc +++ b/launcher/resources/pe_colored/pe_colored.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_colored/scalable/launcher.svg b/launcher/resources/pe_colored/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/pe_colored/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc index 5c49b75a3..2bfec42cb 100644 --- a/launcher/resources/pe_dark/pe_dark.qrc +++ b/launcher/resources/pe_dark/pe_dark.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_dark/scalable/launcher.svg b/launcher/resources/pe_dark/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/pe_dark/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc index a8e3f1572..25d5da73b 100644 --- a/launcher/resources/pe_light/pe_light.qrc +++ b/launcher/resources/pe_light/pe_light.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_light/scalable/launcher.svg b/launcher/resources/pe_light/scalable/launcher.svg deleted file mode 100644 index aeee84338..000000000 --- a/launcher/resources/pe_light/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - From d344ffe37047037bd3bca070557a49fbfadcb361 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 17:50:56 +0300 Subject: [PATCH 225/429] Removed some setProgress calls Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index cbb57afa6..c781ece5b 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -110,8 +110,7 @@ void FlamePackExportTask::collectHashes() auto allMods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); task.reset(hashing_task); - int totalProgres = allMods.count(); - setProgress(0, totalProgres); + int totalProgres = 0; for (const QFileInfo& file : files) { const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); @@ -142,17 +141,16 @@ void FlamePackExportTask::collectHashes() modIter != allMods.end()) { const Mod* mod = *modIter; if (!mod || mod->type() == ResourceType::FOLDER) { - setProgress(m_progress + 1, totalProgres); continue; } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), true, mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); - setProgress(m_progress + 1, totalProgres); continue; } + totalProgres++; auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { if (m_state == Task::State::Running) { @@ -209,9 +207,7 @@ void FlamePackExportTask::makeApiRequest() return; } - size_t progress = 0; for (auto match : data_arr) { - setProgress(progress++, data_arr.count()); auto match_obj = Json::ensureObject(match, {}); auto file_obj = Json::ensureObject(match_obj, "file", {}); @@ -284,9 +280,7 @@ void FlamePackExportTask::getProjectsInfo() else entries = Json::requireArray(Json::requireObject(doc), "data"); - size_t progress = 0; for (auto entry : entries) { - setProgress(progress++, entries.count()); auto entry_obj = Json::requireObject(entry); try { From 87155e346c33288fccb68c3b9029a11b658395b2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 19:44:18 +0300 Subject: [PATCH 226/429] Complicated a little task progress Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index dfad364f3..13308b50a 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -58,7 +58,7 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, void FlamePackExportTask::executeTask() { setStatus(tr("Searching for files...")); - setProgress(0, 0); + setProgress(0, 5); collectFiles(); } @@ -106,11 +106,10 @@ void FlamePackExportTask::collectHashes() { setAbortable(true); setStatus(tr("Find file hashes...")); + setProgress(1, 5); auto allMods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); task.reset(hashing_task); - int totalProgres = 0; - for (const QFileInfo& file : files) { const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); // require sensible file types @@ -121,11 +120,9 @@ void FlamePackExportTask::collectHashes() if (relative.startsWith("resourcepacks/") && (relative.endsWith(".zip") || relative.endsWith(".zip.disabled"))) { // is resourcepack - totalProgres++; auto hash_task = Hashing::createFlameHasher(file.absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, relative, file, totalProgres](QString hash) { + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, relative, file](QString hash) { if (m_state == Task::State::Running) { - setProgress(m_progress + 1, totalProgres); pendingHashes.insert(hash, { relative, file.absoluteFilePath(), relative.endsWith(".zip") }); } }); @@ -147,11 +144,9 @@ void FlamePackExportTask::collectHashes() continue; } - totalProgres++; auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { + connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { if (m_state == Task::State::Running) { - setProgress(m_progress + 1, totalProgres); pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled(), true }); } }); @@ -159,9 +154,28 @@ void FlamePackExportTask::collectHashes() hashing_task->addTask(hash_task); } } + auto step_progress = std::make_shared(); + connect(hashing_task.get(), &Task::finished, this, [this, step_progress] { + step_progress->state = TaskStepState::Succeeded; + stepProgress(*step_progress); + }); connect(hashing_task.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); - connect(hashing_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + connect(hashing_task.get(), &Task::failed, this, [this, step_progress](QString reason) { + step_progress->state = TaskStepState::Failed; + stepProgress(*step_progress); + emitFailed(reason); + }); + connect(hashing_task.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); + + connect(hashing_task.get(), &Task::progress, this, [this, step_progress](qint64 current, qint64 total) { + step_progress->update(current, total); + stepProgress(*step_progress); + }); + connect(hashing_task.get(), &Task::status, this, [this, step_progress](QString status) { + step_progress->status = status; + stepProgress(*step_progress); + }); hashing_task->start(); } @@ -173,6 +187,7 @@ void FlamePackExportTask::makeApiRequest() } setStatus(tr("Find versions for hashes...")); + setProgress(2, 5); auto response = std::make_shared(); QList fingerprints; @@ -186,7 +201,7 @@ void FlamePackExportTask::makeApiRequest() QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at " << parse_error.offset + qWarning() << "Error while parsing JSON response from CurseForge::CurrentVersions at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; @@ -241,6 +256,7 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { setStatus(tr("Find project info from CurseForge...")); + setProgress(3, 5); QList addonIds; for (auto resolved : resolvedFiles) { if (resolved.slug.isEmpty()) { @@ -264,9 +280,10 @@ void FlamePackExportTask::getProjectsInfo() QJsonParseError parse_error{}; auto doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth projects task at " << parse_error.offset + qWarning() << "Error while parsing JSON response from CurseForge projects task at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; + failed(parse_error.errorString()); return; } @@ -317,6 +334,7 @@ void FlamePackExportTask::getProjectsInfo() void FlamePackExportTask::buildZip() { setStatus(tr("Adding files...")); + setProgress(4, 5); buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { QuaZip zip(output); @@ -352,14 +370,19 @@ void FlamePackExportTask::buildZip() content = "
      " + content + "
    "; modlist.write(content.toUtf8()); + auto step_progress = std::make_shared(); + size_t progress = 0; for (const QFileInfo& file : files) { if (buildZipFuture.isCanceled()) { QFile::remove(output); + step_progress->state = TaskStepState::Failed; + stepProgress(*step_progress); return BuildZipResult(); } + step_progress->update(progress, files.length()); + stepProgress(*step_progress); - setProgress(progress, files.length()); const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); if (!resolvedFiles.contains(file.absoluteFilePath()) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { @@ -373,9 +396,12 @@ void FlamePackExportTask::buildZip() if (zip.getZipError() != 0) { QFile::remove(output); + step_progress->state = TaskStepState::Failed; + stepProgress(*step_progress); return BuildZipResult(tr("A zip error occurred")); } - + step_progress->state = TaskStepState::Succeeded; + stepProgress(*step_progress); return BuildZipResult(); }); connect(&buildZipWatcher, &QFutureWatcher::finished, this, &FlamePackExportTask::finish); From 6d0e255ca18b1934d6eb514b6324cde67bb87d60 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 22:00:33 +0300 Subject: [PATCH 227/429] fix: Page container extra info set on logs page Signed-off-by: Trial97 --- launcher/ui/pages/BasePage.h | 2 +- launcher/ui/pages/instance/ExternalResourcesPage.cpp | 2 +- launcher/ui/widgets/PageContainer.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/ui/pages/BasePage.h b/launcher/ui/pages/BasePage.h index 5537c28f7..dc2bde992 100644 --- a/launcher/ui/pages/BasePage.h +++ b/launcher/ui/pages/BasePage.h @@ -44,7 +44,7 @@ class BasePage { public: - using updateExtraInfoFunc = std::function; + using updateExtraInfoFunc = std::function; virtual ~BasePage() {} virtual QString id() const = 0; virtual QString displayName() const = 0; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 8e5226efb..173bcb663 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -83,7 +83,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared connect(selection_model, &QItemSelectionModel::currentChanged, this, &ExternalResourcesPage::current); auto updateExtra = [this]() { if (updateExtraInfo) - updateExtraInfo(extraHeaderInfoString()); + updateExtraInfo(id(), extraHeaderInfoString()); }; connect(selection_model, &QItemSelectionModel::selectionChanged, this, updateExtra); connect(model.get(), &ResourceFolderModel::updateFinished, this, updateExtra); diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 34df42ece..b98c9796f 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -93,8 +93,8 @@ PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, page->listIndex = counter; page->setParentContainer(this); counter++; - page->updateExtraInfo = [this](QString info) { - if (m_currentPage) + page->updateExtraInfo = [this](QString id, QString info) { + if (m_currentPage && id == m_currentPage->id()) m_header->setText(m_currentPage->displayName() + info); }; } From 8bebd7f042fc912dedb652c613a76a346c29a38f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 26 Jun 2023 01:18:55 +0100 Subject: [PATCH 228/429] Generate special signature :sparkles: composed of multiple elements instead of relying on timestamp for Java version cache invalidation Signed-off-by: TheKodeToad --- launcher/Application.cpp | 2 +- launcher/launch/steps/CheckJava.cpp | 15 ++++++++++----- launcher/launch/steps/CheckJava.h | 2 +- launcher/minecraft/MinecraftInstance.cpp | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 724e6e44d..1d97a5f2e 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -594,7 +594,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Java Settings m_settings->registerSetting("JavaPath", ""); - m_settings->registerSetting("JavaTimestamp", 0); + m_settings->registerSetting("JavaSignature", ""); m_settings->registerSetting("JavaArchitecture", ""); m_settings->registerSetting("JavaRealArchitecture", ""); m_settings->registerSetting("JavaVersion", ""); diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index f01875861..7d697ba96 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -81,15 +81,20 @@ void CheckJava::executeTask() } QFileInfo javaInfo(realJavaPath); - qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch(); - auto storedUnixTime = settings->get("JavaTimestamp").toLongLong(); + qint64 javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch(); + auto storedSignature = settings->get("JavaSignature").toString(); auto storedArchitecture = settings->get("JavaArchitecture").toString(); auto storedRealArchitecture = settings->get("JavaRealArchitecture").toString(); auto storedVersion = settings->get("JavaVersion").toString(); auto storedVendor = settings->get("JavaVendor").toString(); - m_javaUnixTime = javaUnixTime; + + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(QByteArray::number(javaUnixTime)); + hash.addData(m_javaPath.toUtf8()); + m_javaSignature = hash.result().toHex(); + // if timestamps are not the same, or something is missing, check! - if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 + if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 || storedRealArchitecture.size() == 0 || storedVendor.size() == 0) { @@ -140,7 +145,7 @@ void CheckJava::checkJavaFinished(JavaCheckResult result) instance->settings()->set("JavaArchitecture", result.mojangPlatform); instance->settings()->set("JavaRealArchitecture", result.realPlatform); instance->settings()->set("JavaVendor", result.javaVendor); - instance->settings()->set("JavaTimestamp", m_javaUnixTime); + instance->settings()->set("JavaSignature", m_javaSignature); emitSucceeded(); return; } diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h index d084b1321..bbf06b7c7 100644 --- a/launcher/launch/steps/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h @@ -40,6 +40,6 @@ private: private: QString m_javaPath; - qlonglong m_javaUnixTime; + QString m_javaSignature; JavaCheckerPtr m_JavaChecker; }; diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index f8ed5214e..aab930de0 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -148,7 +148,7 @@ void MinecraftInstance::loadSpecificSettings() m_settings->registerOverride(global_settings->getSetting("IgnoreJavaCompatibility"), javaOrLocation); // special! - m_settings->registerPassthrough(global_settings->getSetting("JavaTimestamp"), javaOrLocation); + m_settings->registerPassthrough(global_settings->getSetting("JavaSignature"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaArchitecture"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaRealArchitecture"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), javaOrLocation); From ed4dce2fb658de726435b06f1d8973b447279f1e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 08:59:23 +0200 Subject: [PATCH 229/429] fix: install logo to multimc theme in genicons.sh Signed-off-by: Sefa Eyeoglu --- program_info/genicons.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/program_info/genicons.sh b/program_info/genicons.sh index 42592c4ee..fe8d2e35e 100755 --- a/program_info/genicons.sh +++ b/program_info/genicons.sh @@ -67,7 +67,4 @@ else fi # replace icon in themes -for dir in ../launcher/resources/*/scalable -do - cp -v org.prismlauncher.PrismLauncher.svg "$dir/launcher.svg" -done +cp -v org.prismlauncher.PrismLauncher.svg "../launcher/resources/multimc/scalable/launcher.svg" From f8f1c3cf231835de5fdee76532180d02d08e6a28 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 09:08:03 +0200 Subject: [PATCH 230/429] chore: add Git Blame ignore file Signed-off-by: Sefa Eyeoglu --- .git-blame-ignore-revs | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..2163db45b --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,4 @@ +# .git-blame-ignore-revs + +# tabs -> spaces +bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9 From f2015eee8059fa68af4ca9415cc8a11f13b65922 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:44:47 +0300 Subject: [PATCH 231/429] Update launcher/ui/MainWindow.ui Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/MainWindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 027742ba4..22721fcdb 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -484,7 +484,7 @@ - ModList (txt) + Mod List
    From cf5c01a5b1a9a91d41fb343d2d2abc9bac07f1ec Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:44:55 +0300 Subject: [PATCH 232/429] Update launcher/ui/dialogs/ExportToModListDialog.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 57ee44537..d53e8db3a 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -118,7 +118,7 @@ void ExportToModListDialog::triggerImp() QString exampleLine; switch (format) { case ExportToModList::HTML: { - exampleLine = "
      {name}[{version}] by {authors}
    "; + exampleLine = "
      {name} [{version}] by {authors}
    "; ui->resultText->setHtml(txt); break; } From d82ae31fc1dc75693e3a6270f0b733fcf7bdaadd Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:45:05 +0300 Subject: [PATCH 233/429] Update launcher/ui/dialogs/ExportToModListDialog.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index d53e8db3a..b399dc178 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -123,7 +123,7 @@ void ExportToModListDialog::triggerImp() break; } case ExportToModList::MARKDOWN: { - exampleLine = "[{name}]({url})[{version}] by {authors}"; + exampleLine = "[{name}]({url}) [{version}] by {authors}"; ui->resultText->setHtml(markdownToHTML(txt)); break; } From 22bb260ae3ccdc17840047cbef49f0af09b809bd Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:45:26 +0300 Subject: [PATCH 234/429] Update launcher/ui/dialogs/ExportToModListDialog.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index b399dc178..149f6b358 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -128,7 +128,7 @@ void ExportToModListDialog::triggerImp() break; } case ExportToModList::PLAINTXT: { - exampleLine = "name: {name}; url: {url}; version: {version}; authors: {authors};"; + exampleLine = "{name} ({url}) [{version}] by {authors}"; break; } case ExportToModList::CUSTOM: From 0aaec9ae4fb8a2f9e00d81acf85ab66e60ad2639 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 11:53:14 +0200 Subject: [PATCH 235/429] chore: remove obsolete macOS warning We don't support that macOS version. This check also never worked, as we never set the platform to that value. Signed-off-by: Sefa Eyeoglu --- buildconfig/BuildConfig.cpp.in | 2 +- buildconfig/BuildConfig.h | 2 +- launcher/ui/pages/global/AccountListPage.cpp | 13 ------------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 8a412b7ff..140731fe0 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -65,7 +65,7 @@ Config::Config() MAC_SPARKLE_PUB_KEY = "@MACOSX_SPARKLE_UPDATE_PUBLIC_KEY@"; MAC_SPARKLE_APPCAST_URL = "@MACOSX_SPARKLE_UPDATE_FEED_URL@"; - if (BUILD_PLATFORM == "macOS" && !MAC_SPARKLE_PUB_KEY.isEmpty() && !MAC_SPARKLE_APPCAST_URL.isEmpty()) + if (!MAC_SPARKLE_PUB_KEY.isEmpty() && !MAC_SPARKLE_APPCAST_URL.isEmpty()) { UPDATER_ENABLED = true; } diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index 8543d7241..11773d887 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -68,7 +68,7 @@ class Config { bool UPDATER_ENABLED = false; - /// A short string identifying this build's platform. For example, "lin64" or "win32". + /// A short string identifying this build's platform or distribution. QString BUILD_PLATFORM; /// A string containing the build timestamp diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index 278f45c49..fced5ff4a 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -159,19 +159,6 @@ void AccountListPage::on_actionAddMojang_triggered() void AccountListPage::on_actionAddMicrosoft_triggered() { - if(BuildConfig.BUILD_PLATFORM == "osx64") { - CustomMessageBox::selectable( - this, - tr("Microsoft Accounts not available"), - //: %1 refers to the launcher itself - tr( - "Microsoft accounts are only usable on macOS 10.13 or newer, with fully updated %1.\n\n" - "Please update both your operating system and %1." - ).arg(BuildConfig.LAUNCHER_DISPLAYNAME), - QMessageBox::Warning - )->exec(); - return; - } MinecraftAccountPtr account = MSALoginDialog::newAccount( this, tr("Please enter your Mojang account email and password to add your account.") From f5e4171df4f8990955b10d538809730abded32f8 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 11:54:22 +0200 Subject: [PATCH 236/429] feat: print build platform in log Signed-off-by: Sefa Eyeoglu --- launcher/LaunchController.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 070ee283c..8fadf446c 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -390,7 +390,10 @@ void LaunchController::launchInstance() m_launcher->prependStep(makeShared(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher)); // Prepend Version - m_launcher->prependStep(makeShared(m_launcher.get(), BuildConfig.LAUNCHER_DISPLAYNAME + " version: " + BuildConfig.printableVersionString() + "\n\n", MessageLevel::Launcher)); + { + auto versionString = QString("%1 version: %2 (%3)").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM); + m_launcher->prependStep(makeShared(m_launcher.get(), versionString + "\n\n", MessageLevel::Launcher)); + } m_launcher->start(); } From fce000206f9a866b70c50f2b6ea860bded19383b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 11:55:23 +0200 Subject: [PATCH 237/429] feat: print build platform in application log Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 1d97a5f2e..45e340260 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -471,6 +471,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; qDebug() << "Version : " << BuildConfig.printableVersionString(); + qDebug() << "Platform : " << BuildConfig.BUILD_PLATFORM; qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; if (adjustedBy.size()) From 63acf0a7b4492334ad2d5b8c623a5ae6a54bb13d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 11:55:48 +0200 Subject: [PATCH 238/429] fix: set default platform to "unknown" Signed-off-by: Sefa Eyeoglu --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70a553190..48995bedf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,7 +146,7 @@ set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}. set(Launcher_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},0,0") # Build platform. -set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.") +set(Launcher_BUILD_PLATFORM "unknown" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.") # Channel list URL set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") From 40fb387185527db5eb03be34ea35f24d3e7bedcd Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 11:58:47 +0200 Subject: [PATCH 239/429] fix(actions): set all build platforms to official Signed-off-by: Sefa Eyeoglu --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2966abe7..bbfe4ab44 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -264,23 +264,23 @@ jobs: - name: Configure CMake (macOS) if: runner.os == 'macOS' && matrix.qt_ver == 6 run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja - name: Configure CMake (macOS-Legacy) if: runner.os == 'macOS' && matrix.qt_ver == 5 run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DMACOSX_SPARKLE_UPDATE_PUBLIC_KEY="" -DMACOSX_SPARKLE_UPDATE_FEED_URL="" -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DMACOSX_SPARKLE_UPDATE_PUBLIC_KEY="" -DMACOSX_SPARKLE_UPDATE_FEED_URL="" -G Ninja - name: Configure CMake (Windows MinGW-w64) if: runner.os == 'Windows' && matrix.msystem != '' shell: msys2 {0} run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=6 -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=6 -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -G Ninja - name: Configure CMake (Windows MSVC) if: runner.os == 'Windows' && matrix.msystem == '' run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON # https://github.com/ccache/ccache/wiki/MS-Visual-Studio (I coudn't figure out the compiler prefix) if ("${{ env.CCACHE_VAR }}") { @@ -295,7 +295,7 @@ jobs: - name: Configure CMake (Linux) if: runner.os == 'Linux' run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=Linux -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -G Ninja ## # BUILD From dffffc784e0f9d250613a879c1ebe017b782cf77 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 26 Jun 2023 22:33:10 +0300 Subject: [PATCH 240/429] Removed unused files Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 2 - launcher/mojang/PackageManifest.cpp | 427 ---------------------------- launcher/mojang/PackageManifest.h | 171 ----------- tests/CMakeLists.txt | 3 - tests/PackageManifest_test.cpp | 343 ---------------------- 5 files changed, 946 deletions(-) delete mode 100644 launcher/mojang/PackageManifest.cpp delete mode 100644 launcher/mojang/PackageManifest.h delete mode 100644 tests/PackageManifest_test.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 9bad2a670..6ca31d468 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -377,8 +377,6 @@ set(MINECRAFT_SOURCES minecraft/services/SkinDelete.cpp minecraft/services/SkinDelete.h - mojang/PackageManifest.h - mojang/PackageManifest.cpp minecraft/Agent.h) # the screenshots feature diff --git a/launcher/mojang/PackageManifest.cpp b/launcher/mojang/PackageManifest.cpp deleted file mode 100644 index b3dfd7fc1..000000000 --- a/launcher/mojang/PackageManifest.cpp +++ /dev/null @@ -1,427 +0,0 @@ -#include "PackageManifest.h" -#include -#include -#include -#include -#include - -#ifndef Q_OS_WIN32 -#include -#include -#include -#endif - -namespace mojang_files { - -const Hash hash_of_empty_string = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; - -int Path::compare(const Path& rhs) const -{ - auto left_cursor = begin(); - auto left_end = end(); - auto right_cursor = rhs.begin(); - auto right_end = rhs.end(); - - while (left_cursor != left_end && right_cursor != right_end) - { - if(*left_cursor < *right_cursor) - { - return -1; - } - else if(*left_cursor > *right_cursor) - { - return 1; - } - left_cursor++; - right_cursor++; - } - - if(left_cursor == left_end) - { - if(right_cursor == right_end) - { - return 0; - } - return -1; - } - return 1; -} - -void Package::addFile(const Path& path, const File& file) { - addFolder(path.parent_path()); - files[path] = file; -} - -void Package::addFolder(Path folder) { - if(!folder.has_parent_path()) { - return; - } - do { - folders.insert(folder); - folder = folder.parent_path(); - } while(folder.has_parent_path()); -} - -void Package::addLink(const Path& path, const Path& target) { - addFolder(path.parent_path()); - symlinks[path] = target; -} - -void Package::addSource(const FileSource& source) { - sources[source.hash] = source; -} - - -namespace { -void fromJson(QJsonDocument & doc, Package & out) { - std::set seen_paths; - if (!doc.isObject()) - { - throw JSONValidationError("file manifest is not an object"); - } - QJsonObject root = doc.object(); - - auto filesObj = Json::ensureObject(root, "files"); - auto iter = filesObj.begin(); - while (iter != filesObj.end()) - { - Path objectPath = Path(iter.key()); - auto value = iter.value(); - iter++; - if(seen_paths.count(objectPath)) { - throw JSONValidationError("duplicate path inside manifest, the manifest is invalid"); - } - if (!value.isObject()) - { - throw JSONValidationError("file entry inside manifest is not an an object"); - } - seen_paths.insert(objectPath); - - auto fileObject = value.toObject(); - auto type = Json::requireString(fileObject, "type"); - if(type == "directory") { - out.addFolder(objectPath); - continue; - } - else if(type == "file") { - FileSource bestSource; - File file; - file.executable = Json::ensureBoolean(fileObject, QString("executable"), false); - auto downloads = Json::requireObject(fileObject, "downloads"); - for(auto iter2 = downloads.begin(); iter2 != downloads.end(); iter2++) { - FileSource source; - - auto downloadObject = Json::requireObject(iter2.value()); - source.hash = Json::requireString(downloadObject, "sha1"); - source.size = Json::requireInteger(downloadObject, "size"); - source.url = Json::requireString(downloadObject, "url"); - - auto compression = iter2.key(); - if(compression == "raw") { - file.hash = source.hash; - file.size = source.size; - source.compression = Compression::Raw; - } - else if (compression == "lzma") { - source.compression = Compression::Lzma; - } - else { - continue; - } - bestSource.upgrade(source); - } - if(bestSource.isBad()) { - throw JSONValidationError("No valid compression method for file " + iter.key()); - } - out.addFile(objectPath, file); - out.addSource(bestSource); - } - else if(type == "link") { - auto target = Json::requireString(fileObject, "target"); - out.symlinks[objectPath] = target; - out.addLink(objectPath, target); - } - else { - throw JSONValidationError("Invalid item type in manifest: " + type); - } - } - // make sure the containing folder exists - out.folders.insert(Path()); -} -} - -Package Package::fromManifestContents(const QByteArray& contents) -{ - Package out; - try - { - auto doc = Json::requireDocument(contents, "Manifest"); - fromJson(doc, out); - return out; - } - catch (const Exception &e) - { - qDebug() << QString("Unable to parse manifest: %1").arg(e.cause()); - out.valid = false; - return out; - } -} - -Package Package::fromManifestFile(const QString & filename) { - Package out; - try - { - auto doc = Json::requireDocument(filename, filename); - fromJson(doc, out); - return out; - } - catch (const Exception &e) - { - qDebug() << QString("Unable to parse manifest file %1: %2").arg(filename, e.cause()); - out.valid = false; - return out; - } -} - -#ifndef Q_OS_WIN32 - -#include -#include -#include - -namespace { -// FIXME: Qt obscures symlink targets by making them absolute. that is useless. this is the workaround - we do it ourselves -bool actually_read_symlink_target(const QString & filepath, Path & out) -{ - struct ::stat st; - // FIXME: here, we assume the native filesystem encoding. May the Gods have mercy upon our Souls. - QByteArray nativePath = filepath.toUtf8(); - const char * filepath_cstr = nativePath.data(); - - if (lstat(filepath_cstr, &st) != 0) - { - return false; - } - - auto size = st.st_size ? st.st_size + 1 : PATH_MAX; - std::string temp(size, '\0'); - // because we don't realiably know how long the damn thing actually is, we loop and expand. POSIX is naff - do - { - auto link_length = ::readlink(filepath_cstr, &temp[0], temp.size()); - if(link_length == -1) - { - return false; - } - if(std::string::size_type(link_length) < temp.size()) - { - // buffer was long enough and we managed to read the link target. RETURN here. - temp.resize(link_length); - out = Path(QString::fromUtf8(temp.c_str())); - return true; - } - temp.resize(temp.size() * 2); - } while (true); -} -} -#endif - -// FIXME: Qt filesystem abstraction is bad, but ... let's hope it doesn't break too much? -// FIXME: The error handling is just DEFICIENT -Package Package::fromInspectedFolder(const QString& folderPath) -{ - QDir root(folderPath); - - Package out; - QDirIterator iterator(folderPath, QDir::NoDotAndDotDot | QDir::AllEntries | QDir::System | QDir::Hidden, QDirIterator::Subdirectories); - while(iterator.hasNext()) { - iterator.next(); - - auto fileInfo = iterator.fileInfo(); - auto relPath = root.relativeFilePath(fileInfo.filePath()); - // FIXME: this is probably completely busted on Windows anyway, so just disable it. - // Qt makes shit up and doesn't understand the platform details - // TODO: Actually use a filesystem library that isn't terrible and has decen license. - // I only know one, and I wrote it. Sadly, currently proprietary. PAIN. -#ifndef Q_OS_WIN32 - if(fileInfo.isSymLink()) { - Path targetPath; - if(!actually_read_symlink_target(fileInfo.filePath(), targetPath)) { - qCritical() << "Folder inspection: Unknown filesystem object:" << fileInfo.absoluteFilePath(); - out.valid = false; - } - out.addLink(relPath, targetPath); - } - else -#endif - if(fileInfo.isDir()) { - out.addFolder(relPath); - } - else if(fileInfo.isFile()) { - File f; - f.executable = fileInfo.isExecutable(); - f.size = fileInfo.size(); - // FIXME: async / optimize the hashing - QFile input(fileInfo.absoluteFilePath()); - if(!input.open(QIODevice::ReadOnly)) { - qCritical() << "Folder inspection: Failed to open file:" << fileInfo.absoluteFilePath(); - out.valid = false; - break; - } - f.hash = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1).toHex().constData(); - out.addFile(relPath, f); - } - else { - // Something else... oh my - qCritical() << "Folder inspection: Unknown filesystem object:" << fileInfo.absoluteFilePath(); - out.valid = false; - break; - } - } - out.folders.insert(Path(".")); - out.valid = true; - return out; -} - -namespace { -struct shallow_first_sort -{ - bool operator()(const Path &lhs, const Path &rhs) const - { - auto lhs_depth = lhs.length(); - auto rhs_depth = rhs.length(); - if(lhs_depth < rhs_depth) - { - return true; - } - else if(lhs_depth == rhs_depth) - { - if(lhs < rhs) - { - return true; - } - } - return false; - } -}; - -struct deep_first_sort -{ - bool operator()(const Path &lhs, const Path &rhs) const - { - auto lhs_depth = lhs.length(); - auto rhs_depth = rhs.length(); - if(lhs_depth > rhs_depth) - { - return true; - } - else if(lhs_depth == rhs_depth) - { - if(lhs < rhs) - { - return true; - } - } - return false; - } -}; -} - -UpdateOperations UpdateOperations::resolve(const Package& from, const Package& to) -{ - UpdateOperations out; - - if(!from.valid || !to.valid) { - out.valid = false; - return out; - } - - // Files - for(auto iter = from.files.begin(); iter != from.files.end(); iter++) { - const auto ¤t_hash = iter->second.hash; - const auto ¤t_executable = iter->second.executable; - const auto &path = iter->first; - - auto iter2 = to.files.find(path); - if(iter2 == to.files.end()) { - // removed - out.deletes.push_back(path); - continue; - } - auto new_hash = iter2->second.hash; - auto new_executable = iter2->second.executable; - if (current_hash != new_hash) { - out.deletes.push_back(path); - out.downloads.emplace( - std::pair{ - path, - FileDownload(to.sources.at(iter2->second.hash), iter2->second.executable) - } - ); - } - else if (current_executable != new_executable) { - out.executable_fixes[path] = new_executable; - } - } - for(auto iter = to.files.begin(); iter != to.files.end(); iter++) { - auto path = iter->first; - if(!from.files.count(path)) { - out.downloads.emplace( - std::pair{ - path, - FileDownload(to.sources.at(iter->second.hash), iter->second.executable) - } - ); - } - } - - // Folders - std::set remove_folders; - std::set make_folders; - for(auto from_path: from.folders) { - auto iter = to.folders.find(from_path); - if(iter == to.folders.end()) { - remove_folders.insert(from_path); - } - } - for(auto & rmdir: remove_folders) { - out.rmdirs.push_back(rmdir); - } - for(auto to_path: to.folders) { - auto iter = from.folders.find(to_path); - if(iter == from.folders.end()) { - make_folders.insert(to_path); - } - } - for(auto & mkdir: make_folders) { - out.mkdirs.push_back(mkdir); - } - - // Symlinks - for(auto iter = from.symlinks.begin(); iter != from.symlinks.end(); iter++) { - const auto ¤t_target = iter->second; - const auto &path = iter->first; - - auto iter2 = to.symlinks.find(path); - if(iter2 == to.symlinks.end()) { - // removed - out.deletes.push_back(path); - continue; - } - const auto &new_target = iter2->second; - if (current_target != new_target) { - out.deletes.push_back(path); - out.mklinks[path] = iter2->second; - } - } - for(auto iter = to.symlinks.begin(); iter != to.symlinks.end(); iter++) { - auto path = iter->first; - if(!from.symlinks.count(path)) { - out.mklinks[path] = iter->second; - } - } - out.valid = true; - return out; -} - -} diff --git a/launcher/mojang/PackageManifest.h b/launcher/mojang/PackageManifest.h deleted file mode 100644 index fd7ab0ad4..000000000 --- a/launcher/mojang/PackageManifest.h +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "tasks/Task.h" - -namespace mojang_files { - -using Hash = QString; -extern const Hash empty_hash; - -// simple-ish path implementation. assumes always relative and does not allow '..' entries -class Path -{ -public: - using parts_type = QStringList; - - Path() = default; - Path(QString string) { - auto parts_in = string.split('/'); - for(auto & part: parts_in) { - if(part.isEmpty() || part == ".") { - continue; - } - if(part == "..") { - if(parts.size()) { - parts.pop_back(); - } - continue; - } - parts.push_back(part); - } - } - - bool has_parent_path() const - { - return parts.size() > 0; - } - - Path parent_path() const - { - if (parts.empty()) - return Path(); - return Path(parts.begin(), std::prev(parts.end())); - } - - bool empty() const - { - return parts.empty(); - } - - int length() const - { - return parts.length(); - } - - bool operator==(const Path & rhs) const { - return parts == rhs.parts; - } - - bool operator!=(const Path & rhs) const { - return parts != rhs.parts; - } - - inline bool operator<(const Path& rhs) const - { - return compare(rhs) < 0; - } - - parts_type::const_iterator begin() const - { - return parts.begin(); - } - - parts_type::const_iterator end() const - { - return parts.end(); - } - - QString toString() const { - return parts.join("/"); - } - -private: - Path(const parts_type::const_iterator & start, const parts_type::const_iterator & end) { - auto cursor = start; - while(cursor != end) { - parts.push_back(*cursor); - cursor++; - } - } - int compare(const Path& p) const; - - parts_type parts; -}; - - -enum class Compression { - Raw, - Lzma, - Unknown -}; - - -struct FileSource -{ - Compression compression = Compression::Unknown; - Hash hash; - QString url; - std::size_t size = 0; - void upgrade(const FileSource & other) { - if(compression == Compression::Unknown || other.size < size) { - *this = other; - } - } - bool isBad() const { - return compression == Compression::Unknown; - } -}; - -struct File -{ - Hash hash; - bool executable; - std::uint64_t size = 0; -}; - -struct Package { - static Package fromInspectedFolder(const QString &folderPath); - static Package fromManifestFile(const QString &path); - static Package fromManifestContents(const QByteArray& contents); - - explicit operator bool() const - { - return valid; - } - void addFolder(Path folder); - void addFile(const Path & path, const File & file); - void addLink(const Path & path, const Path & target); - void addSource(const FileSource & source); - - std::map sources; - bool valid = true; - std::set folders; - std::map files; - std::map symlinks; -}; - -struct FileDownload : FileSource -{ - FileDownload(const FileSource& source, bool executable) { - static_cast (*this) = source; - this->executable = executable; - } - bool executable = false; -}; - -struct UpdateOperations { - static UpdateOperations resolve(const Package & from, const Package & to); - bool valid = false; - std::vector deletes; - std::vector rmdirs; - std::vector mkdirs; - std::map downloads; - std::map mklinks; - std::map executable_fixes; -}; - -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 36a3b0f8d..a26a49fec 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,9 +9,6 @@ ecm_add_test(GZip_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}:: ecm_add_test(GradleSpecifier_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test TEST_NAME GradleSpecifier) -ecm_add_test(PackageManifest_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test - TEST_NAME PackageManifest) - ecm_add_test(MojangVersionFormat_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test TEST_NAME MojangVersionFormat) diff --git a/tests/PackageManifest_test.cpp b/tests/PackageManifest_test.cpp deleted file mode 100644 index e38abf808..000000000 --- a/tests/PackageManifest_test.cpp +++ /dev/null @@ -1,343 +0,0 @@ -#include -#include - -#include - -using namespace mojang_files; - -QDebug operator<<(QDebug debug, const Path &path) -{ - debug << path.toString(); - return debug; -} - -class PackageManifestTest : public QObject -{ - Q_OBJECT - -private slots: - void test_parse(); - void test_parse_file(); - void test_inspect(); -#ifndef Q_OS_WIN32 - void test_inspect_symlinks(); -#endif - void mkdir_deep(); - void rmdir_deep(); - - void identical_file(); - void changed_file(); - void added_file(); - void removed_file(); -}; - -namespace { -QByteArray basic_manifest = R"END( -{ - "files": { - "a/b.txt": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/b.txt", - "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "size": 0 - } - }, - "executable": true - }, - "a/b/c": { - "type": "directory" - }, - "a/b/c.txt": { - "type": "link", - "target": "../b.txt" - } - } -} -)END"; -} - -void PackageManifestTest::test_parse() -{ - auto manifest = Package::fromManifestContents(basic_manifest); - QVERIFY(manifest.valid == true); - QVERIFY(manifest.files.size() == 1); - QVERIFY(manifest.files.count(Path("a/b.txt"))); - auto &file = manifest.files[Path("a/b.txt")]; - QVERIFY(file.executable == true); - QVERIFY(file.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file.size == 0); - QVERIFY(manifest.folders.size() == 4); - QVERIFY(manifest.folders.count(Path("."))); - QVERIFY(manifest.folders.count(Path("a"))); - QVERIFY(manifest.folders.count(Path("a/b"))); - QVERIFY(manifest.folders.count(Path("a/b/c"))); - QVERIFY(manifest.symlinks.size() == 1); - auto symlinkPath = Path("a/b/c.txt"); - QVERIFY(manifest.symlinks.count(symlinkPath)); - auto &symlink = manifest.symlinks[symlinkPath]; - QVERIFY(symlink == Path("../b.txt")); - QVERIFY(manifest.sources.size() == 1); -} - -void PackageManifestTest::test_parse_file() { - auto path = QFINDTESTDATA("testdata/PackageManifest/1.8.0_202-x64.json"); - auto manifest = Package::fromManifestFile(path); - QVERIFY(manifest.valid == true); -} - - -void PackageManifestTest::test_inspect() { - auto path = QFINDTESTDATA("testdata/PackageManifest/inspect_win/"); - auto manifest = Package::fromInspectedFolder(path); - QVERIFY(manifest.valid == true); - QVERIFY(manifest.files.size() == 2); - QVERIFY(manifest.files.count(Path("a/b.txt"))); - auto &file1 = manifest.files[Path("a/b.txt")]; - QVERIFY(file1.executable == false); - QVERIFY(file1.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file1.size == 0); - QVERIFY(manifest.files.count(Path("a/b/b.txt"))); - auto &file2 = manifest.files[Path("a/b/b.txt")]; - QVERIFY(file2.executable == false); - QVERIFY(file2.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file2.size == 0); - QVERIFY(manifest.folders.size() == 3); - QVERIFY(manifest.folders.count(Path("."))); - QVERIFY(manifest.folders.count(Path("a"))); - QVERIFY(manifest.folders.count(Path("a/b"))); - QVERIFY(manifest.symlinks.size() == 0); -} - -#ifndef Q_OS_WIN32 -void PackageManifestTest::test_inspect_symlinks() { - auto path = QFINDTESTDATA("testdata/PackageManifest/inspect/"); - auto manifest = Package::fromInspectedFolder(path); - QVERIFY(manifest.valid == true); - QVERIFY(manifest.files.size() == 1); - QVERIFY(manifest.files.count(Path("a/b.txt"))); - auto &file = manifest.files[Path("a/b.txt")]; - QVERIFY(file.executable == true); - QVERIFY(file.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file.size == 0); - QVERIFY(manifest.folders.size() == 3); - QVERIFY(manifest.folders.count(Path("."))); - QVERIFY(manifest.folders.count(Path("a"))); - QVERIFY(manifest.folders.count(Path("a/b"))); - QVERIFY(manifest.symlinks.size() == 1); - QVERIFY(manifest.symlinks.count(Path("a/b/b.txt"))); - qDebug() << manifest.symlinks[Path("a/b/b.txt")]; - QVERIFY(manifest.symlinks[Path("a/b/b.txt")] == Path("../b.txt")); -} -#endif - -void PackageManifestTest::mkdir_deep() { - - Package from; - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/e": { - "type": "directory" - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - QVERIFY(operations.rmdirs.size() == 0); - - QVERIFY(operations.mkdirs.size() == 6); - QVERIFY(operations.mkdirs[0] == Path(".")); - QVERIFY(operations.mkdirs[1] == Path("a")); - QVERIFY(operations.mkdirs[2] == Path("a/b")); - QVERIFY(operations.mkdirs[3] == Path("a/b/c")); - QVERIFY(operations.mkdirs[4] == Path("a/b/c/d")); - QVERIFY(operations.mkdirs[5] == Path("a/b/c/d/e")); - - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::rmdir_deep() { - - Package to; - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/e": { - "type": "directory" - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - - QVERIFY(operations.rmdirs.size() == 6); - QVERIFY(operations.rmdirs[0] == Path("a/b/c/d/e")); - QVERIFY(operations.rmdirs[1] == Path("a/b/c/d")); - QVERIFY(operations.rmdirs[2] == Path("a/b/c")); - QVERIFY(operations.rmdirs[3] == Path("a/b")); - QVERIFY(operations.rmdirs[4] == Path("a")); - QVERIFY(operations.rmdirs[5] == Path(".")); - - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::identical_file() { - QByteArray manifest = R"END( -{ - "files": { - "a/b/c/d/empty.txt": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/empty.txt", - "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "size": 0 - } - }, - "executable": false - } - } -} -)END"; - auto from = Package::fromManifestContents(manifest); - auto to = Package::fromManifestContents(manifest); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::changed_file() { - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/empty.txt", - "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "size": 0 - } - }, - "executable": false - } - } -} -)END"); - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/space.txt", - "sha1": "dd122581c8cd44d0227f9c305581ffcb4b6f1b46", - "size": 1 - } - }, - "executable": false - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 1); - QCOMPARE(operations.deletes[0], Path("a/b/c/d/file")); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 1); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::added_file() { - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d": { - "type": "directory" - } - } -} -)END"); - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/space.txt", - "sha1": "dd122581c8cd44d0227f9c305581ffcb4b6f1b46", - "size": 1 - } - }, - "executable": false - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 1); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::removed_file() { - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/space.txt", - "sha1": "dd122581c8cd44d0227f9c305581ffcb4b6f1b46", - "size": 1 - } - }, - "executable": false - } - } -} -)END"); - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d": { - "type": "directory" - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 1); - QCOMPARE(operations.deletes[0], Path("a/b/c/d/file")); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -QTEST_GUILESS_MAIN(PackageManifestTest) - -#include "PackageManifest_test.moc" - From 6e5716f097d89b4b7b4c48ae18e37474ef23b3e8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:05:32 +0300 Subject: [PATCH 241/429] Fixed illegal characters in shortcuts name Signed-off-by: Trial97 --- launcher/FileSystem.cpp | 11 +- launcher/ui/MainWindow.cpp | 203 ++++++++++++++++--------------------- 2 files changed, 95 insertions(+), 119 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 835ad925d..1ea9f755a 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -372,7 +372,7 @@ void create_link::make_link_list(const QString& offset) auto src_path = source_it.next(); auto relative_path = src_dir.relativeFilePath(src_path); - if (m_max_depth >= 0 && pathDepth(relative_path) > m_max_depth){ + if (m_max_depth >= 0 && pathDepth(relative_path) > m_max_depth) { relative_path = pathTruncate(relative_path, m_max_depth); src_path = src_dir.filePath(relative_path); if (linkedPaths.contains(src_path)) { @@ -663,7 +663,7 @@ QString pathTruncate(const QString& path, int depth) QString trunc = QFileInfo(path).path(); - if (pathDepth(trunc) > depth ) { + if (pathDepth(trunc) > depth) { return pathTruncate(trunc, depth); } @@ -769,6 +769,9 @@ QString getDesktopDir() // Cross-platform Shortcut creation bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon) { + if (destination.isEmpty()) { + destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); + } #if defined(Q_OS_MACOS) destination += ".command"; @@ -791,6 +794,8 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri return true; #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated + destination += ".desktop"; QFile f(destination); f.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&f); @@ -974,7 +979,7 @@ FilesystemType getFilesystemType(const QString& name) { for (auto iter = s_filesystem_type_names.constBegin(); iter != s_filesystem_type_names.constEnd(); ++iter) { auto fs_names = iter.value(); - if(fs_names.contains(name.toUpper())) + if (fs_names.contains(name.toUpper())) return iter.key(); } return FilesystemType::UNKNOWN; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index eeb78c53e..7407483f5 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1510,140 +1510,111 @@ void MainWindow::on_actionKillInstance_triggered() void MainWindow::on_actionCreateInstanceShortcut_triggered() { - if (m_selectedInstance) - { - auto desktopPath = FS::getDesktopDir(); - if (desktopPath.isEmpty()) { - // TODO come up with an alternative solution (open "save file" dialog) - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); - return; - } + if (!m_selectedInstance) + return; + auto desktopPath = FS::getDesktopDir(); + if (desktopPath.isEmpty()) { + // TODO come up with an alternative solution (open "save file" dialog) + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); + return; + } + QString desktopFilePath; + QString appPath = QApplication::applicationFilePath(); + QString iconPath; + QStringList args; #if defined(Q_OS_MACOS) - QString appPath = QApplication::applicationFilePath(); - if (appPath.startsWith("/private/var/")) { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); - return; - } - - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - appPath, { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), "")) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } + if (appPath.startsWith("/private/var/")) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); + return; + } #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - QString appPath = QApplication::applicationFilePath(); - if (appPath.startsWith("/tmp/.mount_")) { - // AppImage! - appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE")); - if (appPath.isEmpty()) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)")); - } - else if (appPath.endsWith("/")) - { - appPath.chop(1); - } + if (appPath.startsWith("/tmp/.mount_")) { + // AppImage! + appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE")); + if (appPath.isEmpty()) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)")); + } else if (appPath.endsWith("/")) { + appPath.chop(1); } + } - auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); - if (icon == nullptr) - { - icon = APPLICATION->icons()->icon("grass"); - } + auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (icon == nullptr) { + icon = APPLICATION->icons()->icon("grass"); + } - QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png"); + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png"); - QFile iconFile(iconPath); - if (!iconFile.open(QFile::WriteOnly)) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } - bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); - iconFile.close(); + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); + iconFile.close(); - if (!success) - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } + if (!success) { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + + if (DesktopServices::isFlatpak()) { + desktopFilePath = FS::PathCombine(desktopPath, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()) + ".desktop"); + 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)")); + if (desktopFilePath.isEmpty()) + return; // file dialog canceled by user + appPath = "flatpak"; + QString flatpakAppId = BuildConfig.LAUNCHER_DESKTOPFILENAME; + flatpakAppId.remove(".desktop"); + args.append({ "run", flatpakAppId }); + } - QString desktopFilePath = FS::PathCombine(desktopPath, m_selectedInstance->name() + ".desktop"); - QStringList args; - if (DesktopServices::isFlatpak()) { - 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)")); - if (desktopFilePath.isEmpty()) - return; // file dialog canceled by user - appPath = "flatpak"; - QString flatpakAppId = BuildConfig.LAUNCHER_DESKTOPFILENAME; - flatpakAppId.remove(".desktop"); - args.append({ "run", flatpakAppId }); - } - args.append({ "--launch", m_selectedInstance->id() }); - if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } #elif defined(Q_OS_WIN) - auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); - if (icon == nullptr) - { - icon = APPLICATION->icons()->icon("grass"); - } + auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (icon == nullptr) { + icon = APPLICATION->icons()->icon("grass"); + } - QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico"); + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico"); - // part of fix for weird bug involving the window icon being replaced - // dunno why it happens, but this 2-line fix seems to be enough, so w/e - auto appIcon = APPLICATION->getThemedIcon("logo"); + // part of fix for weird bug involving the window icon being replaced + // dunno why it happens, but this 2-line fix seems to be enough, so w/e + auto appIcon = APPLICATION->getThemedIcon("logo"); - QFile iconFile(iconPath); - if (!iconFile.open(QFile::WriteOnly)) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } - bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); - iconFile.close(); + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); + iconFile.close(); - // restore original window icon - QGuiApplication::setWindowIcon(appIcon); + // restore original window icon + QGuiApplication::setWindowIcon(appIcon); - if (!success) - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } + if (!success) { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - QApplication::applicationFilePath(), { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), iconPath)) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } #else - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!")); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!")); + return; #endif + args.append({ "--launch", m_selectedInstance->id() }); + if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); + } else { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); } } From 92847b977409f4f4b4daa1e34196596e40becc05 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:15:20 +0300 Subject: [PATCH 242/429] omit icon remove on macos Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7407483f5..496738e32 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1613,7 +1613,9 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); } else { +#if not defined(Q_OS_MACOS) iconFile.remove(); +#endif QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); } } From 54cb077b40b1785174a9bd111d055a399b725e52 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:31:36 +0300 Subject: [PATCH 243/429] Added more information to the screenshot upload warning Signed-off-by: Trial97 --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index ca368d3b7..352375941 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -36,6 +36,7 @@ */ #include "ScreenshotsPage.h" +#include "BuildConfig.h" #include "ui_ScreenshotsPage.h" #include @@ -380,16 +381,18 @@ void ScreenshotsPage::on_actionUpload_triggered() if (selection.isEmpty()) return; - QString text; + QUrl baseUrl(BuildConfig.IMGUR_BASE_URL); if (selection.size() > 1) - text = tr("You are about to upload %1 screenshots.\n\n" + text = tr("You are about to upload %1 screenshots to %2.\n" + "You should double-check for personal information.\n\n" "Are you sure?") - .arg(selection.size()); + .arg(QString::number(selection.size()), baseUrl.host()); else - text = - tr("You are about to upload the selected screenshot.\n\n" - "Are you sure?"); + text = tr("You are about to upload the selected screenshot to %1.\n" + "You should double-check for personal information.\n\n" + "Are you sure?") + .arg(baseUrl.host()); auto response = CustomMessageBox::selectable(this, "Confirm Upload", text, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) From 23b3711f96bd93171eebc401f983ccf0fb862772 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 27 Jun 2023 12:41:36 -0700 Subject: [PATCH 244/429] fix(filesystem): track failed copies and clones Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.cpp | 9 +++++++++ launcher/FileSystem.h | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 835ad925d..0554cab86 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -36,6 +36,7 @@ */ #include "FileSystem.h" +#include #include "BuildConfig.h" @@ -246,6 +247,7 @@ bool copy::operator()(const QString& offset, bool dryRun) { using copy_opts = fs::copy_options; m_copied = 0; // reset counter + m_failedPaths.clear(); // NOTE always deep copy on windows. the alternatives are too messy. #if defined Q_OS_WIN32 @@ -277,6 +279,9 @@ bool copy::operator()(const QString& offset, bool dryRun) qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); qDebug() << "Source file:" << src_path; qDebug() << "Destination file:" << dst_path; + m_failedPaths.append(dst_path); + emit copyFailed(relative_dst_path); + return; } m_copied++; emit fileCopied(relative_dst_path); @@ -1072,6 +1077,7 @@ bool clone::operator()(const QString& offset, bool dryRun) } m_cloned = 0; // reset counter + m_failedClones.clear(); auto src = PathCombine(m_src.absolutePath(), offset); auto dst = PathCombine(m_dst.absolutePath(), offset); @@ -1092,6 +1098,9 @@ bool clone::operator()(const QString& offset, bool dryRun) qDebug() << "Failed to clone files: error" << err.value() << "message" << QString::fromStdString(err.message()); qDebug() << "Source file:" << src_path; qDebug() << "Destination file:" << dst_path; + m_failedClones.append(qMakePair(src_path, dst_path)); + emit cloneFailed(src_path, dst_path); + return; } m_cloned++; emit fileCloned(src_path, dst_path); diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index cb581d0c5..f8a82baef 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -112,9 +113,12 @@ class copy : public QObject { bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); } int totalCopied() { return m_copied; } + int totalFailed() { return m_failedPaths.length(); } + QStringList failed() { return m_failedPaths; } signals: void fileCopied(const QString& relativeName); + void copyFailed(const QString& relativeName); // TODO: maybe add a "shouldCopy" signal in the future? private: @@ -127,6 +131,7 @@ class copy : public QObject { QDir m_src; QDir m_dst; int m_copied; + QStringList m_failedPaths; }; struct LinkPair { @@ -471,6 +476,9 @@ class clone : public QObject { bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); } int totalCloned() { return m_cloned; } + int totalFailed() { return m_failedClones.length(); } + + QList> failed() { return m_failedClones; } signals: void fileCloned(const QString& src, const QString& dst); @@ -485,6 +493,7 @@ class clone : public QObject { QDir m_src; QDir m_dst; int m_cloned; + QList> m_failedClones; }; /** From 00be211169134022813562cd09c69f831d0e400e Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 27 Jun 2023 13:01:28 -0700 Subject: [PATCH 245/429] Update launcher/FileSystem.cpp Co-authored-by: TheKodeToad Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 0554cab86..8a417831b 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -36,7 +36,7 @@ */ #include "FileSystem.h" -#include +#include #include "BuildConfig.h" From 0f64ee6a5f6d157e493d474b74004a4ebd0dae43 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 28 Jun 2023 18:28:25 +0300 Subject: [PATCH 246/429] Added warnings for running instances Signed-off-by: Trial97 --- .../minecraft/mod/ResourceFolderModel.cpp | 18 +++++++++++++++-- .../pages/instance/ExternalResourcesPage.cpp | 20 +++++++++++++++++++ launcher/ui/pages/instance/ModFolderPage.cpp | 10 ++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 1a56b6793..c2c0d1785 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -1,14 +1,15 @@ #include "ResourceFolderModel.h" +#include #include #include #include #include +#include #include #include #include #include -#include #include "Application.h" #include "FileSystem.h" @@ -18,6 +19,7 @@ #include "settings/Setting.h" #include "tasks/Task.h" +#include "ui/dialogs/CustomMessageBox.h" ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObject* parent, bool create_dir) : QAbstractListModel(parent), m_dir(dir), m_instance(instance), m_watcher(this) @@ -451,8 +453,20 @@ bool ResourceFolderModel::setData(const QModelIndex& index, const QVariant& valu if (row < 0 || row >= rowCount(index.parent()) || !index.isValid()) return false; - if (role == Qt::CheckStateRole) + if (role == Qt::CheckStateRole) { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = + CustomMessageBox::selectable(nullptr, "Confirm toggle", + "If you enable/disable this resource while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return false; + } return setResourceEnabled({ index }, EnableAction::TOGGLE); + } return false; } diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 87a3df102..12038f88f 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -250,6 +250,16 @@ void ExternalResourcesPage::removeItem() void ExternalResourcesPage::removeItems(const QItemSelection& selection) { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = CustomMessageBox::selectable(this, "Confirm Delete", + "If you remove this resource while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return; + } m_model->deleteResources(selection.indexes()); } @@ -261,6 +271,16 @@ void ExternalResourcesPage::enableItem() void ExternalResourcesPage::disableItem() { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = CustomMessageBox::selectable(this, "Confirm disable", + "If you disable this resource while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return; + } auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::DISABLE); } diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 9812bbe93..3176396f8 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -120,6 +120,16 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI void ModFolderPage::removeItems(const QItemSelection& selection) { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = CustomMessageBox::selectable(this, "Confirm Delete", + "If you remove mods while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return; + } m_model->deleteMods(selection.indexes()); } From 0008b22d8b352e3591ee7ba7c6d9313ed23cbd4a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 28 Jun 2023 18:41:47 +0300 Subject: [PATCH 247/429] Renamed function Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 2 +- launcher/ui/instanceview/InstanceView.cpp | 9 ++++++--- launcher/ui/instanceview/InstanceView.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 26fcb3a3c..515abf070 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -927,7 +927,7 @@ void MainWindow::onCatToggled(bool state) void MainWindow::setCatBackground(bool enabled) { - view->setCatVisible(enabled); + view->setPaintCat(enabled); view->viewport()->repaint(); } diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 4c83e94a0..1911dd59a 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -74,7 +74,7 @@ InstanceView::InstanceView(QWidget *parent) setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setAcceptDrops(true); setAutoScroll(true); - setCatVisible(APPLICATION->settings()->get("TheCat").toBool()); + setPaintCat(APPLICATION->settings()->get("TheCat").toBool()); } InstanceView::~InstanceView() @@ -500,10 +500,13 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent *event) } } -void InstanceView::setCatVisible(bool visible) +void InstanceView::setPaintCat(bool visible) { m_catVisible = visible; - m_catPixmap.load(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage())); + if (visible) + m_catPixmap.load(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage())); + else + m_catPixmap = QPixmap(); } void InstanceView::paintEvent(QPaintEvent* event) diff --git a/launcher/ui/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index a9bd0bd7e..364056751 100644 --- a/launcher/ui/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h @@ -86,7 +86,7 @@ public: virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override; int spacing() const { return m_spacing; }; - void setCatVisible(bool visible); + void setPaintCat(bool visible); public slots: virtual void updateGeometries() override; From 7033e2857268a314971ea9a29a5dbc83d3b2d978 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:00:40 +0200 Subject: [PATCH 248/429] update instance group header to more modern style Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 136 ++++++----------------- 1 file changed, 34 insertions(+), 102 deletions(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index e6bca17d6..f2d1ca14a 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -157,133 +157,65 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option) { - painter->setRenderHint(QPainter::Antialiasing); - const QRect optRect = option.rect; QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - QColor outlineColor = option.palette.text().color(); - outlineColor.setAlphaF(0.35); + int centerHeight = option.rect.top() + fontMetrics.height()/2; - //BEGIN: top left corner - { - painter->save(); - painter->setPen(outlineColor); - const QPointF topLeft(optRect.topLeft()); - QRectF arc(topLeft, QSizeF(4, 4)); - arc.translate(0.5, 0.5); - painter->drawArc(arc, 1440, 1440); - painter->restore(); - } - //END: top left corner + QPen pen; + pen.setWidth(2); + QColor penColor = option.palette.text().color(); + penColor.setAlphaF(0.6); + pen.setColor(penColor); + painter->setPen(pen); - //BEGIN: left vertical line + //BEGIN: arrow { - QPoint start(optRect.topLeft()); - start.ry() += 3; - QPoint verticalGradBottom(optRect.topLeft()); - verticalGradBottom.ry() += fontMetrics.height() + 5; - QLinearGradient gradient(start, verticalGradBottom); - gradient.setColorAt(0, outlineColor); - gradient.setColorAt(1, Qt::transparent); - painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); - } - //END: left vertical line - - //BEGIN: horizontal line - { - QPoint start(optRect.topLeft()); - start.rx() += 3; - QPoint horizontalGradTop(optRect.topLeft()); - horizontalGradTop.rx() += optRect.width() - 6; - painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor); - } - //END: horizontal line - - //BEGIN: top right corner - { - painter->save(); - painter->setPen(outlineColor); - QPointF topRight(optRect.topRight()); - topRight.rx() -= 4; - QRectF arc(topRight, QSizeF(4, 4)); - arc.translate(0.5, 0.5); - painter->drawArc(arc, 0, 1440); - painter->restore(); - } - //END: top right corner - - //BEGIN: right vertical line - { - QPoint start(optRect.topRight()); - start.ry() += 3; - QPoint verticalGradBottom(optRect.topRight()); - verticalGradBottom.ry() += fontMetrics.height() + 5; - QLinearGradient gradient(start, verticalGradBottom); - gradient.setColorAt(0, outlineColor); - gradient.setColorAt(1, Qt::transparent); - painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); - } - //END: right vertical line - - //BEGIN: checkboxy thing - { - painter->save(); painter->setRenderHint(QPainter::Antialiasing, false); - painter->setFont(font); - QColor penColor(option.palette.text().color()); - penColor.setAlphaF(0.6); - painter->setPen(penColor); - QRect iconSubRect(option.rect); - iconSubRect.setTop(iconSubRect.top() + 7); - iconSubRect.setLeft(iconSubRect.left() + 7); + painter->save(); - int sizing = fontMetrics.height(); - int even = ( (sizing - 1) % 2 ); + int offsetLeft = fontMetrics.height()/2; + int offsetTop = centerHeight; + int arrowSize = 6; - iconSubRect.setHeight(sizing - even); - iconSubRect.setWidth(sizing - even); - painter->drawRect(iconSubRect); - - - /* - if(collapsed) - painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "+"); - else - painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "-"); - */ - painter->setBrush(option.palette.text()); - painter->fillRect(iconSubRect.x(), iconSubRect.y() + iconSubRect.height() / 2, - iconSubRect.width(), 2, penColor); - if (collapsed) - { - painter->fillRect(iconSubRect.x() + iconSubRect.width() / 2, iconSubRect.y(), 2, - iconSubRect.height(), penColor); + QPolygon polygon; + if (collapsed) { + polygon << QPoint(offsetLeft - arrowSize/2, offsetTop - arrowSize) << QPoint(offsetLeft + arrowSize/2, offsetTop) << QPoint(offsetLeft - arrowSize/2, offsetTop + arrowSize); + painter->drawPolyline(polygon); + } else { + polygon << QPoint(offsetLeft - arrowSize, offsetTop - arrowSize/2) << QPoint(offsetLeft, offsetTop + arrowSize/2) << QPoint(offsetLeft + arrowSize, offsetTop - arrowSize/2); + painter->drawPolyline(polygon); } - - painter->restore(); } - //END: checkboxy thing + //END: arrow //BEGIN: text { + painter->setRenderHint(QPainter::Antialiasing); QRect textRect(option.rect); - textRect.setTop(textRect.top() + 7); - textRect.setLeft(textRect.left() + 7 + fontMetrics.height() + 7); + textRect.setTop(textRect.top()); + textRect.setLeft(textRect.left() + fontMetrics.height()); textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); painter->save(); painter->setFont(font); - QColor penColor(option.palette.text().color()); - penColor.setAlphaF(0.6); - painter->setPen(penColor); painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); - painter->restore(); } //END: text + + //BEGIN: horizontal line + { + // startPoint is left + arrow + text + space + int startPoint = optRect.left() + fontMetrics.height() + fontMetrics.size(Qt::AlignLeft | Qt::AlignVCenter, text).width() + 7; + painter->setRenderHint(QPainter::Antialiasing, false); + QPolygon polygon; + polygon << QPoint(startPoint, centerHeight) << QPoint(optRect.right() - 3, centerHeight); + painter->drawPolyline(polygon); + } + //END: horizontal line } int VisualGroup::totalHeight() const From 66461ac500ded75d1d3f4df580296936b85e08b2 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:42:49 +0200 Subject: [PATCH 249/429] some positioning adjustments, deleted the line Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 34 +++++++++--------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index f2d1ca14a..f544c3dc7 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -157,12 +157,13 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option) { - const QRect optRect = option.rect; + QRect optRect = option.rect; + optRect.setTop(optRect.top() + 7); QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - int centerHeight = option.rect.top() + fontMetrics.height()/2; + int centerHeight = optRect.top() + fontMetrics.height()/2; QPen pen; pen.setWidth(2); @@ -171,21 +172,21 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti pen.setColor(penColor); painter->setPen(pen); + int arrowOffsetLeft = fontMetrics.height()/2 + 7; + int textOffsetLeft = arrowOffsetLeft *2; + int arrowSize = 6; + //BEGIN: arrow { painter->setRenderHint(QPainter::Antialiasing, false); painter->save(); - int offsetLeft = fontMetrics.height()/2; - int offsetTop = centerHeight; - int arrowSize = 6; - QPolygon polygon; if (collapsed) { - polygon << QPoint(offsetLeft - arrowSize/2, offsetTop - arrowSize) << QPoint(offsetLeft + arrowSize/2, offsetTop) << QPoint(offsetLeft - arrowSize/2, offsetTop + arrowSize); + polygon << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight - arrowSize) << QPoint(arrowOffsetLeft + arrowSize/2, centerHeight) << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight + arrowSize); painter->drawPolyline(polygon); } else { - polygon << QPoint(offsetLeft - arrowSize, offsetTop - arrowSize/2) << QPoint(offsetLeft, offsetTop + arrowSize/2) << QPoint(offsetLeft + arrowSize, offsetTop - arrowSize/2); + polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize/2) << QPoint(arrowOffsetLeft, centerHeight + arrowSize/2) << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize/2); painter->drawPolyline(polygon); } } @@ -194,9 +195,9 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti //BEGIN: text { painter->setRenderHint(QPainter::Antialiasing); - QRect textRect(option.rect); + QRect textRect(optRect); textRect.setTop(textRect.top()); - textRect.setLeft(textRect.left() + fontMetrics.height()); + textRect.setLeft(textOffsetLeft); textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); @@ -205,22 +206,11 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); } //END: text - - //BEGIN: horizontal line - { - // startPoint is left + arrow + text + space - int startPoint = optRect.left() + fontMetrics.height() + fontMetrics.size(Qt::AlignLeft | Qt::AlignVCenter, text).width() + 7; - painter->setRenderHint(QPainter::Antialiasing, false); - QPolygon polygon; - polygon << QPoint(startPoint, centerHeight) << QPoint(optRect.right() - 3, centerHeight); - painter->drawPolyline(polygon); - } - //END: horizontal line } int VisualGroup::totalHeight() const { - return headerHeight() + 5 + contentHeight(); // FIXME: wtf is that '5'? + return headerHeight() + contentHeight(); } int VisualGroup::headerHeight() const From 6b3b119db07b229e22e33313a92a0c81a530f45c Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:50:44 +0200 Subject: [PATCH 250/429] give ungrouped instances a group header Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index f544c3dc7..9d8dd2b9e 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -189,6 +189,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize/2) << QPoint(arrowOffsetLeft, centerHeight + arrowSize/2) << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize/2); painter->drawPolyline(polygon); } + painter->restore(); } //END: arrow @@ -203,7 +204,8 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->save(); painter->setFont(font); - painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); + painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text != "" ? text : QObject::tr("Ungrouped")); + painter->restore(); } //END: text } From 54d88e4dbf058fe32e92becb5af7eab8c1eb051c Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:57:10 +0200 Subject: [PATCH 251/429] use QString.isEmpty() oops Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 9d8dd2b9e..edf487f19 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -204,7 +204,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->save(); painter->setFont(font); - painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text != "" ? text : QObject::tr("Ungrouped")); + painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, !text.isEmpty() ? text : QObject::tr("Ungrouped")); painter->restore(); } //END: text From 534d156b1239aed19c9d36a88ff23d84127ac002 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 20:06:17 +0200 Subject: [PATCH 252/429] format VisualGroup.cpp file Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 94 ++++++++++-------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index edf487f19..9b2189b85 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -35,22 +35,17 @@ #include "VisualGroup.h" +#include +#include #include #include #include -#include -#include #include "InstanceView.h" -VisualGroup::VisualGroup(const QString &text, InstanceView *view) : view(view), text(text), collapsed(false) -{ -} +VisualGroup::VisualGroup(const QString& text, InstanceView* view) : view(view), text(text), collapsed(false) {} -VisualGroup::VisualGroup(const VisualGroup *other) - : view(other->view), text(other->text), collapsed(other->collapsed) -{ -} +VisualGroup::VisualGroup(const VisualGroup* other) : view(other->view), text(other->text), collapsed(other->collapsed) {} void VisualGroup::update() { @@ -64,13 +59,11 @@ void VisualGroup::update() int positionInRow = 0; int currentRow = 0; int offsetFromTop = 0; - for (auto item: temp_items) - { - if(positionInRow == itemsPerRow) - { + for (auto item : temp_items) { + if (positionInRow == itemsPerRow) { rows[currentRow].height = maxRowHeight; rows[currentRow].top = offsetFromTop; - currentRow ++; + currentRow++; offsetFromTop += maxRowHeight + 5; positionInRow = 0; maxRowHeight = 0; @@ -83,8 +76,7 @@ void VisualGroup::update() #endif auto itemHeight = view->itemDelegate()->sizeHint(viewItemOption, item).height(); - if(itemHeight > maxRowHeight) - { + if (itemHeight > maxRowHeight) { maxRowHeight = itemHeight; } rows[currentRow].items.append(item); @@ -94,16 +86,13 @@ void VisualGroup::update() rows[currentRow].top = offsetFromTop; } -QPair VisualGroup::positionOf(const QModelIndex &index) const +QPair VisualGroup::positionOf(const QModelIndex& index) const { int y = 0; - for (auto & row: rows) - { - for(auto x = 0; x < row.items.size(); x++) - { - if(row.items[x] == index) - { - return qMakePair(x,y); + for (auto& row : rows) { + for (auto x = 0; x < row.items.size(); x++) { + if (row.items[x] == index) { + return qMakePair(x, y); } } y++; @@ -112,50 +101,44 @@ QPair VisualGroup::positionOf(const QModelIndex &index) const return qMakePair(0, 0); } -int VisualGroup::rowTopOf(const QModelIndex &index) const +int VisualGroup::rowTopOf(const QModelIndex& index) const { auto position = positionOf(index); return rows[position.second].top; } -int VisualGroup::rowHeightOf(const QModelIndex &index) const +int VisualGroup::rowHeightOf(const QModelIndex& index) const { auto position = positionOf(index); return rows[position.second].height; } -VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const +VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const { VisualGroup::HitResults results = VisualGroup::NoHit; int y_start = verticalPosition(); int body_start = y_start + headerHeight(); - int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5? + int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5? int y = pos.y(); // int x = pos.x(); - if (y < y_start) - { + if (y < y_start) { results = VisualGroup::NoHit; - } - else if (y < body_start) - { + } else if (y < body_start) { results = VisualGroup::HeaderHit; int collapseSize = headerHeight() - 4; // the icon QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize); - if (iconRect.contains(pos)) - { + if (iconRect.contains(pos)) { results |= VisualGroup::CheckboxHit; } - } - else if (y < body_end) - { + } else if (y < body_end) { results |= VisualGroup::BodyHit; } return results; } -void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option) +void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& option) { QRect optRect = option.rect; optRect.setTop(optRect.top() + 7); @@ -163,7 +146,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - int centerHeight = optRect.top() + fontMetrics.height()/2; + int centerHeight = optRect.top() + fontMetrics.height() / 2; QPen pen; pen.setWidth(2); @@ -172,28 +155,32 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti pen.setColor(penColor); painter->setPen(pen); - int arrowOffsetLeft = fontMetrics.height()/2 + 7; - int textOffsetLeft = arrowOffsetLeft *2; + int arrowOffsetLeft = fontMetrics.height() / 2 + 7; + int textOffsetLeft = arrowOffsetLeft * 2; int arrowSize = 6; - //BEGIN: arrow + // BEGIN: arrow { painter->setRenderHint(QPainter::Antialiasing, false); painter->save(); QPolygon polygon; if (collapsed) { - polygon << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight - arrowSize) << QPoint(arrowOffsetLeft + arrowSize/2, centerHeight) << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight + arrowSize); + polygon << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight - arrowSize) + << QPoint(arrowOffsetLeft + arrowSize / 2, centerHeight) + << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight + arrowSize); painter->drawPolyline(polygon); } else { - polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize/2) << QPoint(arrowOffsetLeft, centerHeight + arrowSize/2) << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize/2); + polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize / 2) + << QPoint(arrowOffsetLeft, centerHeight + arrowSize / 2) + << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); painter->drawPolyline(polygon); } painter->restore(); } - //END: arrow + // END: arrow - //BEGIN: text + // BEGIN: text { painter->setRenderHint(QPainter::Antialiasing); QRect textRect(optRect); @@ -207,7 +194,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, !text.isEmpty() ? text : QObject::tr("Ungrouped")); painter->restore(); } - //END: text + // END: text } int VisualGroup::totalHeight() const @@ -222,7 +209,7 @@ int VisualGroup::headerHeight() const QFontMetrics fontMetrics(font); const int height = fontMetrics.height() + 1 /* 1 pixel-width gradient */ - + 11 /* top and bottom separation */; + + 11 /* top and bottom separation */; return height; /* int raw = view->viewport()->fontMetrics().height() + 4; @@ -235,8 +222,7 @@ int VisualGroup::headerHeight() const int VisualGroup::contentHeight() const { - if (collapsed) - { + if (collapsed) { return 0; } auto last = rows[numRows() - 1]; @@ -256,11 +242,9 @@ int VisualGroup::verticalPosition() const QList VisualGroup::items() const { QList indices; - for (int i = 0; i < view->model()->rowCount(); ++i) - { + for (int i = 0; i < view->model()->rowCount(); ++i) { const QModelIndex index = view->model()->index(i, 0); - if (index.data(InstanceViewRoles::GroupRole).toString() == text) - { + if (index.data(InstanceViewRoles::GroupRole).toString() == text) { indices.append(index); } } From 1dc7f800347d6b4e179a12de14af7f4ad87b7f27 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 23:02:34 +0200 Subject: [PATCH 253/429] 4 clang-tidy changes, update copyright info while already at it I updated all my emails to use one from my domain Signed-off-by: Tayou --- launcher/Application.cpp | 2 +- launcher/Application.h | 2 +- launcher/ui/instanceview/VisualGroup.cpp | 12 +++-- launcher/ui/instanceview/VisualGroup.h | 48 +++++++++++++------ launcher/ui/pages/global/LauncherPage.cpp | 2 +- launcher/ui/setupwizard/ThemeWizardPage.cpp | 2 +- launcher/ui/setupwizard/ThemeWizardPage.h | 2 +- launcher/ui/themes/CustomTheme.cpp | 2 +- launcher/ui/themes/CustomTheme.h | 2 +- launcher/ui/themes/ITheme.cpp | 2 +- launcher/ui/themes/ITheme.h | 2 +- launcher/ui/themes/SystemTheme.cpp | 2 +- launcher/ui/themes/SystemTheme.h | 2 +- launcher/ui/themes/ThemeManager.cpp | 2 +- launcher/ui/themes/ThemeManager.h | 2 +- .../ui/widgets/ThemeCustomizationWidget.cpp | 2 +- .../ui/widgets/ThemeCustomizationWidget.h | 2 +- 17 files changed, 56 insertions(+), 34 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 1d97a5f2e..8e1d0cbdd 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -6,7 +6,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Lenny McLennington - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * Copyright (C) 2023 TheKodeToad * Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> * diff --git a/launcher/Application.h b/launcher/Application.h index ced0af17d..527c536b3 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -2,7 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 9b2189b85..8663633b4 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 Tayou * * 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 @@ -40,10 +41,11 @@ #include #include #include +#include #include "InstanceView.h" -VisualGroup::VisualGroup(const QString& text, InstanceView* view) : view(view), text(text), collapsed(false) {} +VisualGroup::VisualGroup(QString text, InstanceView* view) : view(view), text(std::move(text)), collapsed(false) {} VisualGroup::VisualGroup(const VisualGroup* other) : view(other->view), text(other->text), collapsed(other->collapsed) {} @@ -138,7 +140,7 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const return results; } -void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& option) +void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& option) const { QRect optRect = option.rect; optRect.setTop(optRect.top() + 7); @@ -202,7 +204,7 @@ int VisualGroup::totalHeight() const return headerHeight() + contentHeight(); } -int VisualGroup::headerHeight() const +int VisualGroup::headerHeight() { QFont font(QApplication::font()); font.setBold(true); @@ -231,7 +233,7 @@ int VisualGroup::contentHeight() const int VisualGroup::numRows() const { - return rows.size(); + return (int)rows.size(); } int VisualGroup::verticalPosition() const diff --git a/launcher/ui/instanceview/VisualGroup.h b/launcher/ui/instanceview/VisualGroup.h index 5a743aa18..697298c2d 100644 --- a/launcher/ui/instanceview/VisualGroup.h +++ b/launcher/ui/instanceview/VisualGroup.h @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 Tayou * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * 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 @@ -42,8 +62,8 @@ struct VisualRow struct VisualGroup { /* constructors */ - VisualGroup(const QString &text, InstanceView *view); - VisualGroup(const VisualGroup *other); + VisualGroup(QString text, InstanceView *view); + explicit VisualGroup(const VisualGroup *other); /* data */ InstanceView *view = nullptr; @@ -58,13 +78,13 @@ struct VisualGroup void update(); /// draw the header at y-position. - void drawHeader(QPainter *painter, const QStyleOptionViewItem &option); + void drawHeader(QPainter *painter, const QStyleOptionViewItem &option) const; /// height of the group, in total. includes a small bit of padding. int totalHeight() const; /// height of the group header, in pixels - int headerHeight() const; + static int headerHeight() ; /// height of the group content, in pixels int contentHeight() const; diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 816dde723..2080b56f0 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -3,7 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (c) 2022 dada513 - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp index 42826aba1..c3e0a5241 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.cpp +++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h index 61a3d0c01..f3d40b6d8 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.h +++ b/launcher/ui/setupwizard/ThemeWizardPage.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 198e76ba1..177edefad 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index f2b1b06ed..3ec4cafa2 100644 --- a/launcher/ui/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/ITheme.cpp b/launcher/ui/themes/ITheme.cpp index 8f0757e1a..42d63b113 100644 --- a/launcher/ui/themes/ITheme.cpp +++ b/launcher/ui/themes/ITheme.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/ITheme.h b/launcher/ui/themes/ITheme.h index a0a638bd0..d85e7f983 100644 --- a/launcher/ui/themes/ITheme.h +++ b/launcher/ui/themes/ITheme.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index 3a746d027..3b8cb24a4 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h index 05f31233e..4f7d83e57 100644 --- a/launcher/ui/themes/SystemTheme.h +++ b/launcher/ui/themes/SystemTheme.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 94ac8a245..b50c6157f 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index 87f36d9c1..d2a6fb70a 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp index dcf13303c..3bfcd8213 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h index d955a2665..6c33c3c50 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.h +++ b/launcher/ui/widgets/ThemeCustomizationWidget.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 From 8211befc29a4a5b05e1ff1bdd3e7fc2dfb90fc82 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 23:24:57 +0200 Subject: [PATCH 254/429] removed magic 5, removed unnecessary QPainter function calls Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 8663633b4..7d52e4ad7 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -120,7 +120,7 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const VisualGroup::HitResults results = VisualGroup::NoHit; int y_start = verticalPosition(); int body_start = y_start + headerHeight(); - int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5? + int body_end = body_start + contentHeight(); int y = pos.y(); // int x = pos.x(); if (y < y_start) { @@ -147,8 +147,7 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - - int centerHeight = optRect.top() + fontMetrics.height() / 2; + painter->setFont(font); QPen pen; pen.setWidth(2); @@ -157,14 +156,15 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti pen.setColor(penColor); painter->setPen(pen); + // sizes and offsets, to keep things consistent below int arrowOffsetLeft = fontMetrics.height() / 2 + 7; int textOffsetLeft = arrowOffsetLeft * 2; int arrowSize = 6; + int centerHeight = optRect.top() + fontMetrics.height() / 2; // BEGIN: arrow { painter->setRenderHint(QPainter::Antialiasing, false); - painter->save(); QPolygon polygon; if (collapsed) { @@ -178,7 +178,6 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); painter->drawPolyline(polygon); } - painter->restore(); } // END: arrow @@ -191,10 +190,7 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); - painter->save(); - painter->setFont(font); painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, !text.isEmpty() ? text : QObject::tr("Ungrouped")); - painter->restore(); } // END: text } From 87efa700ab53148f0555605fa21c683f3a9c3d15 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 00:01:36 +0300 Subject: [PATCH 255/429] Removed logs from instance export Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 14 ++++++++++ launcher/FileIgnoreProxy.h | 8 ++++++ launcher/ui/dialogs/ExportInstanceDialog.cpp | 28 +++++++++++--------- launcher/ui/dialogs/ExportMrPackDialog.cpp | 3 ++- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index a3b7d5054..1f6b664c2 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "FileSystem.h" #include "SeparatorPrefixTree.h" #include "StringUtils.h" @@ -254,3 +255,16 @@ bool FileIgnoreProxy::filterAcceptsColumn(int source_column, const QModelIndex& return true; } + +bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + QFileSystemModel* fsm = qobject_cast(sourceModel()); + + auto fileInfo = fsm->fileInfo(index); + auto fileName = fileInfo.fileName(); + auto path = relPath(fileInfo.absoluteFilePath()); + return !(path.startsWith("..") || // just in case ignore files outside the gameroot + std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + std::any_of(m_ignoreFilePaths.cbegin(), m_ignoreFilePaths.cend(), [path](auto iPath) { return path == iPath; })); +} diff --git a/launcher/FileIgnoreProxy.h b/launcher/FileIgnoreProxy.h index a5a1153d8..dbd353e0b 100644 --- a/launcher/FileIgnoreProxy.h +++ b/launcher/FileIgnoreProxy.h @@ -63,10 +63,18 @@ class FileIgnoreProxy : public QSortFilterProxyModel { inline const SeparatorPrefixTree<'/'>& blockedPaths() const { return blocked; } inline SeparatorPrefixTree<'/'>& blockedPaths() { return blocked; } + // list of file names that need to be removed completely from model + inline QStringList& ignoreFilesWithName() { return m_ignoreFiles; } + // list of relative paths that need to be removed completely from model + inline QStringList& ignoreFilesWithPath() { return m_ignoreFilePaths; } + protected: bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; private: const QString root; SeparatorPrefixTree<'/'> blocked; + QStringList m_ignoreFiles; + QStringList m_ignoreFilePaths; }; diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 8ecd91a90..8d0e05a20 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -35,24 +35,24 @@ */ #include "ExportInstanceDialog.h" -#include "ui_ExportInstanceDialog.h" #include #include #include -#include #include +#include +#include "ui_ExportInstanceDialog.h" -#include -#include -#include -#include -#include -#include "SeparatorPrefixTree.h" -#include "Application.h" -#include #include +#include +#include +#include +#include +#include +#include +#include "Application.h" +#include "SeparatorPrefixTree.h" -ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent) +ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent) : QDialog(parent), ui(new Ui::ExportInstanceDialog), m_instance(instance) { ui->setupUi(this); @@ -60,8 +60,12 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent model->setIconProvider(&icons); auto root = instance->instanceRoot(); proxyModel = new FileIgnoreProxy(root, this); - loadPackIgnore(); proxyModel->setSourceModel(model); + auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); + proxyModel->ignoreFilesWithPath().append({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); + proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); + loadPackIgnore(); + ui->treeView->setModel(proxyModel); ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); ui->treeView->sortByColumn(0, Qt::AscendingOrder); diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 60ecefd5c..f1d2610a6 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -52,8 +52,9 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); + proxy->ignoreFilesWithPath().append({ "logs", "crash-reports" }); + proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); - proxy->setFilterRegularExpression("^(?!(\\.DS_Store)|([tT]humbs\\.db)).+$"); const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); From 6c374f5f08ad873ae23aab057751d9defc95d12b Mon Sep 17 00:00:00 2001 From: ashuntu <101582426+ashuntu@users.noreply.github.com> Date: Thu, 29 Jun 2023 21:09:31 -0500 Subject: [PATCH 256/429] Add snapcraft.yaml Signed-off-by: ashuntu <101582426+ashuntu@users.noreply.github.com> --- snap/snapcraft.yaml | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 snap/snapcraft.yaml diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 000000000..41c0ce078 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,64 @@ +name: prismlauncher +license: GPL-3.0-only +base: core22 +website: https://prismlauncher.org/ +source-code: https://github.com/PrismLauncher/PrismLauncher +issues: https://github.com/PrismLauncher/PrismLauncher/issues +donation: https://opencollective.com/prismlauncher +contact: https://discord.gg/prismlauncher +summary: A custom Minecraft launcher with modpack support +adopt-info: prismlauncher + +grade: devel +confinement: strict + +architectures: + - build-on: amd64 + - build-on: arm64 + +parts: + prismlauncher: + parse-info: + - usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml + plugin: cmake + build-packages: + - zlib1g-dev + - openjdk-17-jdk + - scdoc + - libgl1-mesa-dev + - extra-cmake-modules + build-snaps: + - kf5-5-106-qt-5-15-9-core22 + - kf5-5-106-qt-5-15-9-core22-sdk + stage-packages: + - openjdk-17-jre + - openjdk-8-jre + source: . + override-pull: | + craftctl default + # Fix the icon reference in the desktop file + sed -i.bak -e 's|Icon=org.prismlauncher.PrismLauncher|Icon=/usr/share/icons/hicolor/scalable/apps/org.prismlauncher.PrismLauncher.svg|g' program_info/org.prismlauncher.PrismLauncher.desktop.in + # Remove the build directory so that local development doesn't interfere with Snap compilation + rm -rf build + git submodule update --init --recursive + cmake-generator: Ninja + cmake-parameters: + - "-DCMAKE_INSTALL_PREFIX=/usr" + - "-DCMAKE_BUILD_TYPE=RelWithDebInfo" + - "-DENABLE_LTO=ON" + - "-DLauncher_BUILD_PLATFORM=snap" + - "-DLauncher_QT_VERSION_MAJOR='5'" + +apps: + prismlauncher: + common-id: org.prismlauncher.PrismLauncher + desktop: usr/share/applications/org.prismlauncher.PrismLauncher.desktop + command: usr/bin/prismlauncher + extensions: + - kde-neon + plugs: + - home + - opengl + - network + - network-bind + - audio-playback From b6e9a5495162c0ffedf99b0d96d1c4daf08c51e9 Mon Sep 17 00:00:00 2001 From: ashuntu <101582426+ashuntu@users.noreply.github.com> Date: Thu, 29 Jun 2023 21:15:07 -0500 Subject: [PATCH 257/429] Add snap github action Signed-off-by: ashuntu <101582426+ashuntu@users.noreply.github.com> --- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2966abe7..696acdbab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -569,6 +569,31 @@ jobs: run: | ccache -s + snap: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + if: inputs.build_type == 'Debug' + uses: actions/checkout@v3 + with: + submodules: 'true' + - name: Set short version + shell: bash + if: inputs.build_type == 'Debug' + run: | + ver_short=`git rev-parse --short HEAD` + echo "VERSION=$ver_short" >> $GITHUB_ENV + - name: Package Snap (Linux) + id: snapcraft + if: inputs.build_type == 'Debug' + uses: snapcore/action-build@v1 + - name: Upload Snap (Linux) + if: inputs.build_type == 'Debug' + uses: actions/upload-artifact@v3 + with: + name: prismlauncher_${{ env.VERSION }}_amd64.snap + path: ${{ steps.snapcraft.outputs.snap }} + flatpak: runs-on: ubuntu-latest container: From 81207c65027a35d37394abe3ba6e3ef43777910a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 10:52:10 +0300 Subject: [PATCH 258/429] Made sure the logs are ignored when collecting files Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 16 +++++++++++++--- launcher/FileIgnoreProxy.h | 9 +++++++-- launcher/ui/dialogs/ExportInstanceDialog.cpp | 8 ++++---- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 ++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index 1f6b664c2..556e992c2 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -262,9 +262,19 @@ bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceP QFileSystemModel* fsm = qobject_cast(sourceModel()); auto fileInfo = fsm->fileInfo(index); + return !ignoreFile(fileInfo); +} + +bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const +{ auto fileName = fileInfo.fileName(); auto path = relPath(fileInfo.absoluteFilePath()); - return !(path.startsWith("..") || // just in case ignore files outside the gameroot - std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || - std::any_of(m_ignoreFilePaths.cbegin(), m_ignoreFilePaths.cend(), [path](auto iPath) { return path == iPath; })); + return (path.startsWith("..") || // just in case ignore files outside the gameroot + std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + m_ignoreFilePaths.covers(path)); +} + +bool FileIgnoreProxy::filterFile(const QString& fileName) const +{ + return blocked.covers(fileName) || ignoreFile(QFileInfo(QDir(root), fileName)); } diff --git a/launcher/FileIgnoreProxy.h b/launcher/FileIgnoreProxy.h index dbd353e0b..e01a2651e 100644 --- a/launcher/FileIgnoreProxy.h +++ b/launcher/FileIgnoreProxy.h @@ -36,6 +36,7 @@ #pragma once +#include #include #include "SeparatorPrefixTree.h" @@ -66,15 +67,19 @@ class FileIgnoreProxy : public QSortFilterProxyModel { // list of file names that need to be removed completely from model inline QStringList& ignoreFilesWithName() { return m_ignoreFiles; } // list of relative paths that need to be removed completely from model - inline QStringList& ignoreFilesWithPath() { return m_ignoreFilePaths; } + inline SeparatorPrefixTree<'/'>& ignoreFilesWithPath() { return m_ignoreFilePaths; } + + bool filterFile(const QString& fileName) const; protected: bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; + bool ignoreFile(QFileInfo file) const; + private: const QString root; SeparatorPrefixTree<'/'> blocked; QStringList m_ignoreFiles; - QStringList m_ignoreFilePaths; + SeparatorPrefixTree<'/'> m_ignoreFilePaths; }; diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 8d0e05a20..cc41c394d 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -40,6 +40,7 @@ #include #include #include +#include "FileIgnoreProxy.h" #include "ui_ExportInstanceDialog.h" #include @@ -49,6 +50,7 @@ #include #include #include +#include #include "Application.h" #include "SeparatorPrefixTree.h" @@ -62,7 +64,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent proxyModel = new FileIgnoreProxy(root, this); proxyModel->setSourceModel(model); auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); - proxyModel->ignoreFilesWithPath().append({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); + proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); loadPackIgnore(); @@ -137,11 +139,9 @@ bool ExportInstanceDialog::doExport() SaveIcon(m_instance); - auto & blocked = proxyModel->blockedPaths(); - using std::placeholders::_1; auto files = QFileInfoList(); if (!MMCZip::collectFileListRecursively(m_instance->instanceRoot(), nullptr, &files, - std::bind(&SeparatorPrefixTree<'/'>::covers, blocked, _1))) { + std::bind(&FileIgnoreProxy::filterFile, proxyModel, std::placeholders::_1))) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false; } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index f1d2610a6..b302f7ba5 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -52,7 +52,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); - proxy->ignoreFilesWithPath().append({ "logs", "crash-reports" }); + proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports" }); proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); @@ -100,7 +100,7 @@ void ExportMrPackDialog::done(int result) return; ModrinthPackExportTask task(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1)); connect(&task, &Task::failed, [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); From 18e628e8733df2f49f20cc1989817b2272cdf151 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 12:10:00 +0300 Subject: [PATCH 259/429] removed extra condition Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index 556e992c2..4c8c64c72 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -269,9 +269,8 @@ bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const { auto fileName = fileInfo.fileName(); auto path = relPath(fileInfo.absoluteFilePath()); - return (path.startsWith("..") || // just in case ignore files outside the gameroot - std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || - m_ignoreFilePaths.covers(path)); + return std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + m_ignoreFilePaths.covers(path); } bool FileIgnoreProxy::filterFile(const QString& fileName) const From 3fe518ff2b9ef902ff44b2c8249bafdf61f8e5eb Mon Sep 17 00:00:00 2001 From: Finian Wright Date: Sun, 2 Jul 2023 00:35:37 -0400 Subject: [PATCH 260/429] Fix compiling on OpenBSD Signed-off-by: Finian Wright --- launcher/FileSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 1ea9f755a..3ce8dd2c7 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -102,7 +102,7 @@ namespace fs = ghc::filesystem; #include #include #include -#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) #include #include #elif defined(Q_OS_WIN) @@ -1156,7 +1156,7 @@ bool clone_file(const QString& src, const QString& dst, std::error_code& ec) return false; } -#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) if (!macos_bsd_clonefile(src_path, dst_path, ec)) { qDebug() << "failed macos_bsd_clonefile:"; @@ -1385,7 +1385,7 @@ bool linux_ficlone(const std::string& src_path, const std::string& dst_path, std return true; } -#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) bool macos_bsd_clonefile(const std::string& src_path, const std::string& dst_path, std::error_code& ec) { From 7579fff532629643384d9b8011e885028ca9a8f0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 2 Jul 2023 13:34:04 +0300 Subject: [PATCH 261/429] Added more options for variants planing Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 10 ++++++---- launcher/ui/themes/CatPack.h | 4 ++-- launcher/ui/themes/ThemeManager.cpp | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 2d5653a67..a0b06a600 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -99,11 +99,13 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di QString JsonCatPack::path() { - const QDateTime now = QDateTime::currentDateTime(); + const QDate now = QDate::currentDate(); for (auto var : m_variants) { - QDateTime startDate(QDate(now.date().year(), var.startTime.mounth, var.startTime.day), QTime(0, 0)); - QDateTime endDate(QDate(now.date().year(), var.endTime.mounth, var.endTime.day), QTime(0, 0)); - if (startDate.daysTo(now) > 0 && now.daysTo(endDate) > 0) + QDate startDate(now.year(), var.startTime.month, var.startTime.day); + QDate endDate(now.year(), var.endTime.month, var.endTime.day); + if (startDate.daysTo(endDate) < 0) // in this case end date should be next year + endDate = endDate.addYears(1); + if (startDate.daysTo(now) >= 0 && now.daysTo(endDate) >= 0) return var.path; } return m_defaultPath; diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index 9f288d3dd..e22df1f42 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -79,9 +79,9 @@ class JsonCatPack : public BasicCatPack { auto sp = d.split("-"); day = sp[0].toInt(); if (sp.length() >= 2) - mounth = sp[1].toInt(); + month = sp[1].toInt(); } - int mounth; + int month; int day; }; struct Variant { diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index bfd0550a8..d00b3a992 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -189,7 +189,7 @@ void ThemeManager::initializeCatPacks() while (ImageFileIterator.hasNext()) { QFile customCatFile(ImageFileIterator.next()); QFileInfo customCatFileInfo(customCatFile); - themeDebugLog() << "Loading QSS Theme from:" << customCatFileInfo.absoluteFilePath(); + themeDebugLog() << "Loading CatPack from:" << customCatFileInfo.absoluteFilePath(); addCatPack(std::unique_ptr(new FileCatPack(customCatFileInfo))); } }; From 81c0a1c4bd3b26c24a506e6d84c878b0786cf14a Mon Sep 17 00:00:00 2001 From: Tayou Date: Sun, 2 Jul 2023 14:01:56 +0200 Subject: [PATCH 262/429] antialiasing for all painting, make hitbox fullwidth Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 7d52e4ad7..aaf31941d 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -130,7 +130,7 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const int collapseSize = headerHeight() - 4; // the icon - QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize); + QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, view->width() - 4, collapseSize); if (iconRect.contains(pos)) { results |= VisualGroup::CheckboxHit; } @@ -155,6 +155,7 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti penColor.setAlphaF(0.6); pen.setColor(penColor); painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing); // sizes and offsets, to keep things consistent below int arrowOffsetLeft = fontMetrics.height() / 2 + 7; @@ -164,26 +165,23 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti // BEGIN: arrow { - painter->setRenderHint(QPainter::Antialiasing, false); - - QPolygon polygon; + QPolygon arrowPolygon; if (collapsed) { - polygon << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight - arrowSize) - << QPoint(arrowOffsetLeft + arrowSize / 2, centerHeight) - << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight + arrowSize); - painter->drawPolyline(polygon); + arrowPolygon << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight - arrowSize) + << QPoint(arrowOffsetLeft + arrowSize / 2, centerHeight) + << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight + arrowSize); + painter->drawPolyline(arrowPolygon); } else { - polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize / 2) - << QPoint(arrowOffsetLeft, centerHeight + arrowSize / 2) - << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); - painter->drawPolyline(polygon); + arrowPolygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize / 2) + << QPoint(arrowOffsetLeft, centerHeight + arrowSize / 2) + << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); + painter->drawPolyline(arrowPolygon); } } // END: arrow // BEGIN: text { - painter->setRenderHint(QPainter::Antialiasing); QRect textRect(optRect); textRect.setTop(textRect.top()); textRect.setLeft(textOffsetLeft); From aad5ca5474ff015da30809260fe0f9d6cb503d61 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 2 Jul 2023 16:45:15 +0300 Subject: [PATCH 263/429] fixed typos Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 10 +++++----- launcher/ui/dialogs/ExportPackDialog.cpp | 1 + launcher/ui/dialogs/ExportPackDialog.ui | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 13308b50a..927146e1d 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -105,7 +105,7 @@ void FlamePackExportTask::collectFiles() void FlamePackExportTask::collectHashes() { setAbortable(true); - setStatus(tr("Find file hashes...")); + setStatus(tr("Finding file hashes...")); setProgress(1, 5); auto allMods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); @@ -186,7 +186,7 @@ void FlamePackExportTask::makeApiRequest() return; } - setStatus(tr("Find versions for hashes...")); + setStatus(tr("Finding versions for hashes...")); setProgress(2, 5); auto response = std::make_shared(); @@ -255,10 +255,10 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { - setStatus(tr("Find project info from CurseForge...")); + setStatus(tr("Finding project info from CurseForge...")); setProgress(3, 5); - QList addonIds; - for (auto resolved : resolvedFiles) { + QStringList addonIds; + for (const auto& resolved : resolvedFiles) { if (resolved.slug.isEmpty()) { addonIds << QString::number(resolved.addonId); } diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index a54a3c86f..2abe2805b 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -41,6 +41,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla ui->name->setText(instance->name()); if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + setWindowTitle("Export Modrinth Pack"); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); diff --git a/launcher/ui/dialogs/ExportPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui index 658e21994..3976e28f8 100644 --- a/launcher/ui/dialogs/ExportPackDialog.ui +++ b/launcher/ui/dialogs/ExportPackDialog.ui @@ -11,7 +11,7 @@ - Export Modrinth Pack + Export Pack true From 5f63c781b400aab29298b1eb2822477e35d87c01 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 2 Jul 2023 18:50:29 +0300 Subject: [PATCH 264/429] resolved local vaiables names Signed-off-by: Trial97 --- .../modplatform/flame/FlamePackExportTask.cpp | 132 +++++++++--------- .../modrinth/ModrinthPackExportTask.cpp | 4 +- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 927146e1d..1b75908ad 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -108,8 +108,8 @@ void FlamePackExportTask::collectHashes() setStatus(tr("Finding file hashes...")); setProgress(1, 5); auto allMods = mcInstance->loaderModList()->allMods(); - ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); - task.reset(hashing_task); + ConcurrentTask::Ptr hashingTask(new ConcurrentTask(this, "MakeHashesTask", 10)); + task.reset(hashingTask); for (const QFileInfo& file : files) { const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); // require sensible file types @@ -120,14 +120,14 @@ void FlamePackExportTask::collectHashes() if (relative.startsWith("resourcepacks/") && (relative.endsWith(".zip") || relative.endsWith(".zip.disabled"))) { // is resourcepack - auto hash_task = Hashing::createFlameHasher(file.absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, relative, file](QString hash) { + auto hashTask = Hashing::createFlameHasher(file.absoluteFilePath()); + 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") }); } }); - connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); - hashing_task->addTask(hash_task); + connect(hashTask.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + hashingTask->addTask(hashTask); continue; } @@ -144,39 +144,39 @@ void FlamePackExportTask::collectHashes() continue; } - auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { + auto hashTask = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); + 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 }); } }); - connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); - hashing_task->addTask(hash_task); + connect(hashTask.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + hashingTask->addTask(hashTask); } } - auto step_progress = std::make_shared(); - connect(hashing_task.get(), &Task::finished, this, [this, step_progress] { - step_progress->state = TaskStepState::Succeeded; - stepProgress(*step_progress); + auto progressStep = std::make_shared(); + connect(hashingTask.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); }); - connect(hashing_task.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); - connect(hashing_task.get(), &Task::failed, this, [this, step_progress](QString reason) { - step_progress->state = TaskStepState::Failed; - stepProgress(*step_progress); + connect(hashingTask.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); + connect(hashingTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); emitFailed(reason); }); - connect(hashing_task.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); + connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); - connect(hashing_task.get(), &Task::progress, this, [this, step_progress](qint64 current, qint64 total) { - step_progress->update(current, total); - stepProgress(*step_progress); + connect(hashingTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); }); - connect(hashing_task.get(), &Task::status, this, [this, step_progress](QString status) { - step_progress->status = status; - stepProgress(*step_progress); + connect(hashingTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); }); - hashing_task->start(); + hashingTask->start(); } void FlamePackExportTask::makeApiRequest() @@ -198,38 +198,38 @@ void FlamePackExportTask::makeApiRequest() task.reset(api.matchFingerprints(fingerprints, response)); connect(task.get(), &Task::succeeded, this, [this, response] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from CurseForge::CurrentVersions at " << parse_error.offset - << " reason: " << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from CurseForge::CurrentVersions at " << parseError.offset + << " reason: " << parseError.errorString(); qWarning() << *response; - failed(parse_error.errorString()); + failed(parseError.errorString()); return; } try { - auto doc_obj = Json::requireObject(doc); - auto data_obj = Json::requireObject(doc_obj, "data"); - auto data_arr = Json::requireArray(data_obj, "exactMatches"); + auto docObj = Json::requireObject(doc); + auto dataObj = Json::requireObject(docObj, "data"); + auto dataArr = Json::requireArray(dataObj, "exactMatches"); - if (data_arr.isEmpty()) { + if (dataArr.isEmpty()) { qWarning() << "No matches found for fingerprint search!"; return; } - for (auto match : data_arr) { - auto match_obj = Json::ensureObject(match, {}); - auto file_obj = Json::ensureObject(match_obj, "file", {}); + for (auto match : dataArr) { + auto matchObj = Json::ensureObject(match, {}); + auto fileObj = Json::ensureObject(matchObj, "file", {}); - if (match_obj.isEmpty() || file_obj.isEmpty()) { + if (matchObj.isEmpty() || fileObj.isEmpty()) { qWarning() << "Fingerprint match is empty!"; return; } - auto fingerprint = QString::number(Json::ensureVariant(file_obj, "fileFingerprint").toUInt()); + auto fingerprint = QString::number(Json::ensureVariant(fileObj, "fileFingerprint").toUInt()); auto mod = pendingHashes.find(fingerprint); if (mod == pendingHashes.end()) { qWarning() << "Invalid fingerprint from the API response."; @@ -237,8 +237,8 @@ void FlamePackExportTask::makeApiRequest() } setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod->name)); - if (Json::ensureBoolean(file_obj, "isAvailable", false, "isAvailable")) - resolvedFiles.insert(mod->path, { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), + if (Json::ensureBoolean(fileObj, "isAvailable", false, "isAvailable")) + resolvedFiles.insert(mod->path, { Json::requireInteger(fileObj, "modId"), Json::requireInteger(fileObj, "id"), mod->enabled, mod->isMod }); } @@ -265,25 +265,25 @@ void FlamePackExportTask::getProjectsInfo() } auto response = std::make_shared(); - Task::Ptr proj_task; + Task::Ptr projTask; if (addonIds.isEmpty()) { buildZip(); return; } else if (addonIds.size() == 1) { - proj_task = api.getProject(*addonIds.begin(), response); + projTask = api.getProject(*addonIds.begin(), response); } else { - proj_task = api.getProjects(addonIds, response); + projTask = api.getProjects(addonIds, response); } - connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { - QJsonParseError parse_error{}; - auto doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from CurseForge projects task at " << parse_error.offset - << " reason: " << parse_error.errorString(); + connect(projTask.get(), &Task::succeeded, this, [this, response, addonIds] { + QJsonParseError parseError{}; + auto doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from CurseForge projects task at " << parseError.offset + << " reason: " << parseError.errorString(); qWarning() << *response; - failed(parse_error.errorString()); + failed(parseError.errorString()); return; } @@ -295,13 +295,13 @@ void FlamePackExportTask::getProjectsInfo() entries = Json::requireArray(Json::requireObject(doc), "data"); for (auto entry : entries) { - auto entry_obj = Json::requireObject(entry); + auto entryObj = Json::requireObject(entry); try { - setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(Json::requireString(entry_obj, "name"))); + setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(Json::requireString(entryObj, "name"))); ModPlatform::IndexedPack pack; - FlameMod::loadIndexedPack(pack, entry_obj); + FlameMod::loadIndexedPack(pack, entryObj); for (auto key : resolvedFiles.keys()) { auto val = resolvedFiles.value(key); if (val.addonId == pack.addonId) { @@ -327,7 +327,7 @@ void FlamePackExportTask::getProjectsInfo() } buildZip(); }); - task.reset(proj_task); + task.reset(projTask); task->start(); } @@ -370,18 +370,18 @@ void FlamePackExportTask::buildZip() content = "
      " + content + "
    "; modlist.write(content.toUtf8()); - auto step_progress = std::make_shared(); + auto progressStep = std::make_shared(); size_t progress = 0; for (const QFileInfo& file : files) { if (buildZipFuture.isCanceled()) { QFile::remove(output); - step_progress->state = TaskStepState::Failed; - stepProgress(*step_progress); + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); return BuildZipResult(); } - step_progress->update(progress, files.length()); - stepProgress(*step_progress); + progressStep->update(progress, files.length()); + stepProgress(*progressStep); const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); if (!resolvedFiles.contains(file.absoluteFilePath()) && @@ -396,12 +396,12 @@ void FlamePackExportTask::buildZip() if (zip.getZipError() != 0) { QFile::remove(output); - step_progress->state = TaskStepState::Failed; - stepProgress(*step_progress); + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); return BuildZipResult(tr("A zip error occurred")); } - step_progress->state = TaskStepState::Succeeded; - stepProgress(*step_progress); + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); return BuildZipResult(); }); connect(&buildZipWatcher, &QFutureWatcher::finished, this, &FlamePackExportTask::finish); diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index a9a1f1c40..c8206f1e3 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -95,7 +95,7 @@ void ModrinthPackExportTask::collectFiles() void ModrinthPackExportTask::collectHashes() { - setStatus(tr("Find file hashes...")); + setStatus(tr("Finding file hashes...")); for (const QFileInfo& file : files) { QCoreApplication::processEvents(); @@ -159,7 +159,7 @@ void ModrinthPackExportTask::makeApiRequest() if (pendingHashes.isEmpty()) buildZip(); else { - setStatus(tr("Find versions for hashes...")); + setStatus(tr("Finding versions for hashes...")); auto response = std::make_shared(); task = api.currentVersions(pendingHashes.values(), "sha512", response); connect(task.get(), &NetJob::succeeded, [this, response]() { parseApiResponse(response); }); From 4004e0faeed99b3deb0ffb0b0f469594843ca14b Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 20:22:25 -0700 Subject: [PATCH 265/429] fix: segfault in progress dialog - dialog tries to resize after unhiding the subtask scroll area - after resize attempts to recenter on parent - `calls parentWidget()->{x|y}()` - what if there is no parent? nullptr->() = segfault - recenter on last pos, don't access parent Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 246a0fd49..84f9db7e5 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -34,6 +34,7 @@ */ #include "ProgressDialog.h" +#include #include "ui_ProgressDialog.h" #include @@ -96,21 +97,30 @@ ProgressDialog::~ProgressDialog() void ProgressDialog::updateSize() { QSize lastSize = this->size(); - QSize qSize = QSize(480, minimumSizeHint().height()); + QPoint lastPos = this->pos(); + int minHeight = minimumSizeHint().height(); + if (ui->taskProgressScrollArea->isHidden()) + minHeight -= ui->taskProgressScrollArea->minimumSizeHint().height(); + QSize labelMinSize = ui->globalStatusLabel->minimumSize(); + int labelHeight = ui->globalStatusLabel->height(); + if (labelHeight > labelMinSize.height()) + minHeight += labelHeight - labelMinSize.height(); // account for multiline label + minHeight = std::max(minHeight, 0); + QSize minSize = QSize(480, minHeight); // if the current window is too small - if ((lastSize != qSize) && (lastSize.height() < qSize.height())) + if ((lastSize != minSize) && (lastSize.height() < minSize.height())) { - resize(qSize); - - // keep the dialog in the center after a resize - this->move( - this->parentWidget()->x() + (this->parentWidget()->width() - this->width()) / 2, - this->parentWidget()->y() + (this->parentWidget()->height() - this->height()) / 2 - ); + resize(minSize); + + QSize newSize = this->size(); + QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative + // center on old position after resize + QPoint newPos(lastPos.x() + (sizeDiff.width() / 2), lastPos.y() + (sizeDiff.height() / 2)); + this->move(newPos); } - setMinimumSize(qSize); + setMinimumSize(minSize); } From 3960eb7d32af6ea776634b9f94e12f8df2397627 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 21:24:43 -0700 Subject: [PATCH 266/429] fix: properly calculate min size for progress dialog, apply it at creation Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 84f9db7e5..f70eee49a 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -69,6 +69,7 @@ ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Pr setAttribute(Qt::WidgetAttribute::WA_QuitOnClose, true); setSkipButton(false); changeProgress(0, 100); + updateSize(); } void ProgressDialog::setSkipButton(bool present, QString label) @@ -98,30 +99,28 @@ void ProgressDialog::updateSize() { QSize lastSize = this->size(); QPoint lastPos = this->pos(); - int minHeight = minimumSizeHint().height(); - if (ui->taskProgressScrollArea->isHidden()) - minHeight -= ui->taskProgressScrollArea->minimumSizeHint().height(); - QSize labelMinSize = ui->globalStatusLabel->minimumSize(); - int labelHeight = ui->globalStatusLabel->height(); - if (labelHeight > labelMinSize.height()) - minHeight += labelHeight - labelMinSize.height(); // account for multiline label - minHeight = std::max(minHeight, 0); + int minHeight = ui->globalStatusDetailsLabel->minimumSize().height() + (ui->verticalLayout->spacing() * 2); + minHeight += ui->globalProgressBar->minimumSize().height() + ui->verticalLayout->spacing(); + if (!ui->taskProgressScrollArea->isHidden()) + minHeight += ui->taskProgressScrollArea->minimumSizeHint().height() + ui->verticalLayout->spacing(); + if (ui->skipButton->isVisible()) + minHeight += ui->skipButton->height() + ui->verticalLayout->spacing(); + minHeight = std::max(minHeight, 60); QSize minSize = QSize(480, minHeight); + setMinimumSize(minSize); + adjustSize(); + + QSize newSize = this->size(); // if the current window is too small if ((lastSize != minSize) && (lastSize.height() < minSize.height())) { - resize(minSize); - - QSize newSize = this->size(); QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize QPoint newPos(lastPos.x() + (sizeDiff.width() / 2), lastPos.y() + (sizeDiff.height() / 2)); this->move(newPos); } - setMinimumSize(minSize); - } int ProgressDialog::execWithTask(Task* task) @@ -211,7 +210,9 @@ void ProgressDialog::onTaskSucceeded() void ProgressDialog::changeStatus(const QString& status) { ui->globalStatusLabel->setText(task->getStatus()); + ui->globalStatusLabel->adjustSize(); ui->globalStatusDetailsLabel->setText(task->getDetails()); + ui->globalStatusDetailsLabel->adjustSize(); updateSize(); } From 73d83439140377a7ece34e262ca4efab1608a03d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:27:24 -0700 Subject: [PATCH 267/429] fix: header `` -> `` Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index f70eee49a..c6d8e573f 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -34,7 +34,7 @@ */ #include "ProgressDialog.h" -#include +#include #include "ui_ProgressDialog.h" #include From 8cb8273e67d4770300fdb7c3ce61feb19b1a899b Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:29:45 -0700 Subject: [PATCH 268/429] fix: update if new size is larger Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index c6d8e573f..f422d91e3 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -113,7 +113,7 @@ void ProgressDialog::updateSize() QSize newSize = this->size(); // if the current window is too small - if ((lastSize != minSize) && (lastSize.height() < minSize.height())) + if ((lastSize != minSize) && (lastSize.height() < newSize.height())) { QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize From e5b9bfb2e78ca86917d91fd41de1e797e570cf83 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:30:25 -0700 Subject: [PATCH 269/429] fix: update if new size is larger Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index f422d91e3..3368a8c47 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -113,7 +113,7 @@ void ProgressDialog::updateSize() QSize newSize = this->size(); // if the current window is too small - if ((lastSize != minSize) && (lastSize.height() < newSize.height())) + if ((lastSize != newSize) && (lastSize.height() < newSize.height())) { QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize From 5d5f1b86fdaa865bf8627acd86163469389ebb83 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 09:21:25 +0300 Subject: [PATCH 270/429] fixed logic regarding range over multiple years Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 29 +++++++++++++++-------------- launcher/ui/themes/CatPack.h | 10 +++++----- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 4170febd7..435ccdb88 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -34,11 +34,7 @@ */ #include "ui/themes/CatPack.h" -#include -#include -#include -#include -#include +#include #include #include #include "FileSystem.h" @@ -47,10 +43,10 @@ QString BasicCatPack::path() { - const QDateTime now = QDateTime::currentDateTime(); - const QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); - const QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); - const QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0)); + const auto now = QDate::currentDate(); + const auto birthday = QDate(now.year(), 11, 30); + const auto xmas = QDate(now.year(), 12, 25); + const auto halloween = QDate(now.year(), 10, 31); QString cat = QString(":/backgrounds/%1").arg(m_id); if (std::abs(now.daysTo(xmas)) <= 4) { @@ -85,8 +81,8 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di for (auto v : variants) { auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), - date(Json::requireString(variant, "startTime", "Variant startTime")), - date(Json::requireString(variant, "endTime", "Variant endTime")) }; + PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), + PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; } } catch (const Exception& e) { @@ -104,9 +100,14 @@ QString JsonCatPack::path() for (auto var : m_variants) { QDate startDate(now.year(), var.startTime.month, var.startTime.day); QDate endDate(now.year(), var.endTime.month, var.endTime.day); - if (startDate.daysTo(endDate) < 0) // in this case end date should be next year - endDate = endDate.addYears(1); - if (startDate.daysTo(now) >= 0 && now.daysTo(endDate) >= 0) + if (startDate > endDate) { // it's spans over multiple years + if (endDate <= now) // end date is in the past so jump one year into the future for endDate + endDate = endDate.addYears(1); + else // end date is in the future so jump one year into the past for startDate + startDate = startDate.addYears(-1); + } + + if (startDate >= now && now >= endDate) return var.path; } return m_defaultPath; diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index e22df1f42..20cb8f61e 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -35,7 +35,7 @@ #pragma once -#include +#include #include #include #include @@ -73,8 +73,8 @@ class FileCatPack : public BasicCatPack { class JsonCatPack : public BasicCatPack { public: - struct date { - date(QString d) + struct PartialDate { + PartialDate(QString d) { auto sp = d.split("-"); day = sp[0].toInt(); @@ -86,8 +86,8 @@ class JsonCatPack : public BasicCatPack { }; struct Variant { QString path; - date startTime; - date endTime; + PartialDate startTime; + PartialDate endTime; }; JsonCatPack(QFileInfo& manifestInfo); virtual QString path(); From 026293f7731181b1198c3c5a9552dd340d13b4b5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 14:17:39 +0300 Subject: [PATCH 271/429] updated option text Signed-off-by: Trial97 --- launcher/ui/pages/instance/ExternalResourcesPage.ui | 2 +- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 351aaf75c..3c8366917 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -162,7 +162,7 @@ false
    - Visit on mod's page + Visit mod's page Go to mods home page diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 1d31a2925..ce6968f53 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -104,7 +104,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(), [](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; }); if (selected <= 1) { - ui->actionVisitItemPage->setText(tr("Visit on mod's page")); + ui->actionVisitItemPage->setText(tr("Visit mod's page")); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); } else { ui->actionVisitItemPage->setText(tr("Visit the pages of the selected mods")); From f0aab541f817347a932c65d3b06d2d4c1e7b90c1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 15:09:35 +0300 Subject: [PATCH 272/429] fixed typo Signed-off-by: Trial97 --- launcher/ui/widgets/InfoFrame.cpp | 91 ++++++++++++------------------- 1 file changed, 34 insertions(+), 57 deletions(-) diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 243490140..b16bc097f 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -43,7 +43,7 @@ #include "ui/dialogs/CustomMessageBox.h" -void setupLinkTooTip(QLabel* label) +void setupLinkToolTip(QLabel* label) { QObject::connect(label, &QLabel::linkHovered, [label](const QString& link) { if (!link.isEmpty() && !link.startsWith("http")) @@ -60,11 +60,11 @@ InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) ui->licenseLabel->setHidden(true); ui->issueTrackerLabel->setHidden(true); - setupLinkTooTip(ui->iconLabel); - setupLinkTooTip(ui->descriptionLabel); - setupLinkTooTip(ui->nameLabel); - setupLinkTooTip(ui->licenseLabel); - setupLinkTooTip(ui->issueTrackerLabel); + setupLinkToolTip(ui->iconLabel); + setupLinkToolTip(ui->descriptionLabel); + setupLinkToolTip(ui->nameLabel); + setupLinkToolTip(ui->licenseLabel); + setupLinkToolTip(ui->issueTrackerLabel); updateHiddenState(); } @@ -123,9 +123,9 @@ void InfoFrame::updateWithMod(Mod const& m) licenseText += "" + l.url + ""; } if (!l.description.isEmpty() && l.description != l.name) { - licenseText += " " + l.description; + licenseText += " " + l.description; } - } + } } if (!licenseText.isEmpty()) { setLicense(tr("License: %1").arg(licenseText)); @@ -137,7 +137,7 @@ void InfoFrame::updateWithMod(Mod const& m) if (!m.issueTracker().isEmpty()) { issueTracker += tr("Report issues to: "); issueTracker += "" + m.issueTracker() + ""; - } + } setIssueTracker(issueTracker); } @@ -147,7 +147,8 @@ void InfoFrame::updateWithResource(const Resource& resource) setImage(); } -QString InfoFrame::renderColorCodes(QString input) { +QString InfoFrame::renderColorCodes(QString input) +{ // We have to manually set the colors for use. // // A color is set using §x, with x = a hex number from 0 to f. @@ -158,16 +159,12 @@ QString InfoFrame::renderColorCodes(QString input) { // TODO: Wrap links inside tags // https://minecraft.fandom.com/wiki/Formatting_codes#Color_codes - const QMap color_codes_map = { - {'0', "#000000"}, {'1', "#0000AA"}, {'2', "#00AA00"}, {'3', "#00AAAA"}, {'4', "#AA0000"}, - {'5', "#AA00AA"}, {'6', "#FFAA00"}, {'7', "#AAAAAA"}, {'8', "#555555"}, {'9', "#5555FF"}, - {'a', "#55FF55"}, {'b', "#55FFFF"}, {'c', "#FF5555"}, {'d', "#FF55FF"}, {'e', "#FFFF55"}, - {'f', "#FFFFFF"} - }; + const QMap color_codes_map = { { '0', "#000000" }, { '1', "#0000AA" }, { '2', "#00AA00" }, { '3', "#00AAAA" }, + { '4', "#AA0000" }, { '5', "#AA00AA" }, { '6', "#FFAA00" }, { '7', "#AAAAAA" }, + { '8', "#555555" }, { '9', "#5555FF" }, { 'a', "#55FF55" }, { 'b', "#55FFFF" }, + { 'c', "#FF5555" }, { 'd', "#FF55FF" }, { 'e', "#FFFF55" }, { 'f', "#FFFFFF" } }; // https://minecraft.fandom.com/wiki/Formatting_codes#Formatting_codes - const QMap formatting_codes_map = { - {'l', "b"}, {'m', "s"}, {'n', "u"}, {'o', "i"} - }; + const QMap formatting_codes_map = { { 'l', "b" }, { 'm', "s" }, { 'n', "u" }, { 'o', "i" } }; QString html(""); QList tags{}; @@ -212,14 +209,14 @@ void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack) { setName(renderColorCodes(resource_pack.name())); setDescription(renderColorCodes(resource_pack.description())); - setImage(resource_pack.image({64, 64})); + setImage(resource_pack.image({ 64, 64 })); } void InfoFrame::updateWithTexturePack(TexturePack& texture_pack) { setName(renderColorCodes(texture_pack.name())); setDescription(renderColorCodes(texture_pack.description())); - setImage(texture_pack.image({64, 64})); + setImage(texture_pack.image({ 64, 64 })); } void InfoFrame::clear() @@ -268,9 +265,8 @@ void InfoFrame::setDescription(QString text) QChar rem('\n'); QString finaltext; finaltext.reserve(intermediatetext.size()); - foreach(const QChar& c, intermediatetext) - { - if(c == rem && prev){ + foreach (const QChar& c, intermediatetext) { + if (c == rem && prev) { continue; } prev = c == rem; @@ -278,17 +274,14 @@ void InfoFrame::setDescription(QString text) } QString labeltext; labeltext.reserve(300); - if(finaltext.length() > 290) - { + if (finaltext.length() > 290) { ui->descriptionLabel->setOpenExternalLinks(false); ui->descriptionLabel->setTextFormat(Qt::TextFormat::RichText); m_description = text; // This allows injecting HTML here. labeltext.append("" + finaltext.left(287) + "..."); QObject::connect(ui->descriptionLabel, &QLabel::linkActivated, this, &InfoFrame::descriptionEllipsisHandler); - } - else - { + } else { ui->descriptionLabel->setTextFormat(Qt::TextFormat::AutoText); labeltext.append(finaltext); } @@ -297,14 +290,11 @@ void InfoFrame::setDescription(QString text) void InfoFrame::setLicense(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->licenseLabel->setHidden(true); updateHiddenState(); return; - } - else - { + } else { ui->licenseLabel->setHidden(false); updateHiddenState(); } @@ -314,9 +304,8 @@ void InfoFrame::setLicense(QString text) QChar rem('\n'); QString finaltext; finaltext.reserve(intermediatetext.size()); - foreach(const QChar& c, intermediatetext) - { - if(c == rem && prev){ + foreach (const QChar& c, intermediatetext) { + if (c == rem && prev) { continue; } prev = c == rem; @@ -324,17 +313,14 @@ void InfoFrame::setLicense(QString text) } QString labeltext; labeltext.reserve(300); - if(finaltext.length() > 290) - { + if (finaltext.length() > 290) { ui->licenseLabel->setOpenExternalLinks(false); ui->licenseLabel->setTextFormat(Qt::TextFormat::RichText); m_description = text; // This allows injecting HTML here. labeltext.append("" + finaltext.left(287) + "..."); QObject::connect(ui->licenseLabel, &QLabel::linkActivated, this, &InfoFrame::licenseEllipsisHandler); - } - else - { + } else { ui->licenseLabel->setTextFormat(Qt::TextFormat::AutoText); labeltext.append(finaltext); } @@ -343,12 +329,9 @@ void InfoFrame::setLicense(QString text) void InfoFrame::setIssueTracker(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->issueTrackerLabel->setHidden(true); - } - else - { + } else { ui->issueTrackerLabel->setText(text); ui->issueTrackerLabel->setHidden(false); } @@ -367,28 +350,22 @@ void InfoFrame::setImage(QPixmap img) void InfoFrame::descriptionEllipsisHandler(QString link) { - if(!m_current_box) - { + if (!m_current_box) { m_current_box = CustomMessageBox::selectable(this, "", m_description); connect(m_current_box, &QMessageBox::finished, this, &InfoFrame::boxClosed); m_current_box->show(); - } - else - { + } else { m_current_box->setText(m_description); } } void InfoFrame::licenseEllipsisHandler(QString link) { - if(!m_current_box) - { + if (!m_current_box) { m_current_box = CustomMessageBox::selectable(this, "", m_license); connect(m_current_box, &QMessageBox::finished, this, &InfoFrame::boxClosed); m_current_box->show(); - } - else - { + } else { m_current_box->setText(m_license); } } From 14692eed4052ae550d046278f559e66d3a77fb40 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 3 Jul 2023 14:25:54 +0200 Subject: [PATCH 273/429] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'flake-parts': 'github:hercules-ci/flake-parts/006c75898cf814ef9497252b022e91c946ba8e17' (2023-05-08) → 'github:hercules-ci/flake-parts/267149c58a14d15f7f81b4d737308421de9d7152' (2023-07-01) • Updated input 'flake-parts/nixpkgs-lib': 'github:NixOS/nixpkgs/da45bf6ec7bbcc5d1e14d3795c025199f28e0de0?dir=lib' (2023-04-30) → 'github:NixOS/nixpkgs/4bc72cae107788bf3f24f30db2e2f685c9298dc9?dir=lib' (2023-06-29) • Updated input 'nixpkgs': 'github:nixos/nixpkgs/aeb75dba965e790de427b73315d5addf91a54955' (2023-05-25) → 'github:nixos/nixpkgs/cd99c2b3c9f160cd004318e0697f90bbd5960825' (2023-07-01) • Updated input 'pre-commit-hooks': 'github:cachix/pre-commit-hooks.nix/61e567d6497bc9556f391faebe5e410e6623217f' (2023-05-23) → 'github:cachix/pre-commit-hooks.nix/42587d3414d1747999a5f71e92a83cf6547b62da' (2023-07-03) • Updated input 'pre-commit-hooks/flake-utils': 'github:numtide/flake-utils/5aed5285a952e0b949eb3ba02c12fa4fcfef535f' (2022-11-02) → 'github:numtide/flake-utils/a1720a10a6cfe8234c0e93907ffe81be440f4cef' (2023-05-31) • Added input 'pre-commit-hooks/flake-utils/systems': 'github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e' (2023-04-09) Signed-off-by: Sefa Eyeoglu --- flake.lock | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index 875866438..91a67f087 100644 --- a/flake.lock +++ b/flake.lock @@ -21,11 +21,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1683560683, - "narHash": "sha256-XAygPMN5Xnk/W2c1aW0jyEa6lfMDZWlQgiNtmHXytPc=", + "lastModified": 1688254665, + "narHash": "sha256-8FHEgBrr7gYNiS/NzCxIO3m4hvtLRW9YY1nYo1ivm3o=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "006c75898cf814ef9497252b022e91c946ba8e17", + "rev": "267149c58a14d15f7f81b4d737308421de9d7152", "type": "github" }, "original": { @@ -35,12 +35,15 @@ } }, "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { @@ -88,11 +91,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1685012353, - "narHash": "sha256-U3oOge4cHnav8OLGdRVhL45xoRj4Ppd+It6nPC9nNIU=", + "lastModified": 1688221086, + "narHash": "sha256-cdW6qUL71cNWhHCpMPOJjlw0wzSRP0pVlRn2vqX/VVg=", "owner": "nixos", "repo": "nixpkgs", - "rev": "aeb75dba965e790de427b73315d5addf91a54955", + "rev": "cd99c2b3c9f160cd004318e0697f90bbd5960825", "type": "github" }, "original": { @@ -105,11 +108,11 @@ "nixpkgs-lib": { "locked": { "dir": "lib", - "lastModified": 1682879489, - "narHash": "sha256-sASwo8gBt7JDnOOstnps90K1wxmVfyhsTPPNTGBPjjg=", + "lastModified": 1688049487, + "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0", + "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", "type": "github" }, "original": { @@ -135,11 +138,11 @@ ] }, "locked": { - "lastModified": 1684842236, - "narHash": "sha256-rYWsIXHvNhVQ15RQlBUv67W3YnM+Pd+DuXGMvCBq2IE=", + "lastModified": 1688386108, + "narHash": "sha256-Vffto9QaVonzYAcPlAzd0soqWYpPpKk60dfNLSIXcFA=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "61e567d6497bc9556f391faebe5e410e6623217f", + "rev": "42587d3414d1747999a5f71e92a83cf6547b62da", "type": "github" }, "original": { @@ -156,6 +159,21 @@ "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", From fa7cfc77d8b723a53577734a0a3c76df7d9dc6d7 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 16:08:20 +0300 Subject: [PATCH 274/429] fixed template Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 1b75908ad..b8edf7df8 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -36,7 +36,7 @@ #include "modplatform/helpers/HashUtils.h" #include "tasks/Task.h" -const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • \n"; +const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors}
  • \n"; const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "zip" }); FlamePackExportTask::FlamePackExportTask(const QString& name, From 96c118779daff9ea099710957a62c83115c149ef Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 3 Jul 2023 17:42:57 -0700 Subject: [PATCH 275/429] build: enable address sanitiser in debug builds Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70a553190..dd84daf3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,28 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0") # set CXXFLAGS for build targets set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}") +option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" on) + +# If this is a Debug build turn on address sanitiser +if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) + message(STATUS "Address Sanitizer enabeled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off") + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + # AppleClang and Clang + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + # GCC + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + # Intell compiler ? why? + # no address sanitiser here though + message(STATUS "Address Sanitizer not available on Intell compilers") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address") + else() + message(STATUS "Address Sanitizer not available on unknown compiler ${CMAKE_CXX_COMPILER_ID}") + endif() +endif() + option(ENABLE_LTO "Enable Link Time Optimization" off) if(ENABLE_LTO) From 50eff80ca16a351ec80f75f0f6cf5f0f87207fb1 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 3 Jul 2023 18:07:59 -0700 Subject: [PATCH 276/429] build: optimize address-sanitizer Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd84daf3d..11e4c6286 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,16 +92,16 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) message(STATUS "Address Sanitizer enabeled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AppleClang and Clang - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faddress-sanitizer -O1 -fno-omit-frame-pointer") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") # Intell compiler ? why? # no address sanitiser here though message(STATUS "Address Sanitizer not available on Intell compilers") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") else() message(STATUS "Address Sanitizer not available on unknown compiler ${CMAKE_CXX_COMPILER_ID}") endif() From 03a1d68b742b8ec74b472e5fb32d3f9c34594b5e Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 3 Jul 2023 18:18:48 -0700 Subject: [PATCH 277/429] fix: memory leaks in filesystem test Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- tests/FileSystem_test.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp index ec1f0bcff..a41345c2e 100644 --- a/tests/FileSystem_test.cpp +++ b/tests/FileSystem_test.cpp @@ -42,6 +42,10 @@ class LinkTask : public Task { m_lnk->debug(true); } + ~LinkTask() { + delete m_lnk; + } + void matcher(const IPathMatcher *filter) { m_lnk->matcher(filter); @@ -219,7 +223,8 @@ slots: qDebug() << tempDir.path(); qDebug() << target_dir.path(); FS::copy c(folder, target_dir.path()); - c.matcher(new RegexpMatcher("[.]?mcmeta")); + RegexpMatcher re("[.]?mcmeta"); + c.matcher(&re); c(); for(auto entry: target_dir.entryList()) @@ -253,7 +258,8 @@ slots: qDebug() << tempDir.path(); qDebug() << target_dir.path(); FS::copy c(folder, target_dir.path()); - c.matcher(new RegexpMatcher("[.]?mcmeta")); + RegexpMatcher re("[.]?mcmeta"); + c.matcher(&re); c.whitelist(true); c(); @@ -460,7 +466,8 @@ slots: qDebug() << target_dir.path(); LinkTask lnk_tsk(folder, target_dir.path()); - lnk_tsk.matcher(new RegexpMatcher("[.]?mcmeta")); + RegexpMatcher re("[.]?mcmeta"); + lnk_tsk.matcher(&re); lnk_tsk.linkRecursively(true); QObject::connect(&lnk_tsk, &Task::finished, [&]{ QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); @@ -511,7 +518,8 @@ slots: qDebug() << target_dir.path(); LinkTask lnk_tsk(folder, target_dir.path()); - lnk_tsk.matcher(new RegexpMatcher("[.]?mcmeta")); + RegexpMatcher re("[.]?mcmeta"); + lnk_tsk.matcher(&re); lnk_tsk.linkRecursively(true); lnk_tsk.whitelist(true); QObject::connect(&lnk_tsk, &Task::finished, [&]{ From c5705705d5b40e8157a88612c8a7e83f32f6745b Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 3 Jul 2023 18:35:42 -0700 Subject: [PATCH 278/429] fix: memory leaks in ResourceModel Test Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- tests/ResourceModel_test.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/ResourceModel_test.cpp b/tests/ResourceModel_test.cpp index c0d9cd95d..30353d3f9 100644 --- a/tests/ResourceModel_test.cpp +++ b/tests/ResourceModel_test.cpp @@ -38,6 +38,7 @@ class DummyResourceModel : public ResourceModel { public: DummyResourceModel() : ResourceModel(new DummyResourceAPI) {} + ~DummyResourceModel() {} [[nodiscard]] auto metaEntryBase() const -> QString override { return ""; }; @@ -58,7 +59,10 @@ class DummyResourceModel : public ResourceModel { class ResourceModelTest : public QObject { Q_OBJECT private slots: - void test_abstract_item_model() { [[maybe_unused]] auto tester = new QAbstractItemModelTester(new DummyResourceModel); } + void test_abstract_item_model() { + auto dummy = DummyResourceModel(); + auto tester = QAbstractItemModelTester(&dummy); + } void test_search() { @@ -78,6 +82,8 @@ class ResourceModelTest : public QObject { QVERIFY(processed_pack->addonId.toString() == Json::requireString(processed_response, "project_id")); QVERIFY(processed_pack->description == Json::requireString(processed_response, "description")); QVERIFY(processed_pack->authors.first().name == Json::requireString(processed_response, "author")); + + delete model; } }; From 3c96d5e0d568408e0505841af39aa2d539ebaf36 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 3 Jul 2023 20:04:24 -0700 Subject: [PATCH 279/429] fix: memory leaks in tests Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 15 ++++++++++++--- tests/Task_test.cpp | 1 + tests/Version_test.cpp | 25 +++++++++++++++---------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11e4c6286..bb9906691 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,16 +91,25 @@ option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" on) if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) message(STATUS "Address Sanitizer enabeled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # AppleClang and Clang - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faddress-sanitizer -O1 -fno-omit-frame-pointer") + if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") + # using clang with clang-cl front end + message(STATUS "Address Sanitizer available on Clang MSVC frontend") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") + else() + # AppleClang and Clang + message(STATUS "Address Sanitizer available on Clang") + set(cmake_cxx_flags "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") + endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") + message(STATUS "Address Sanitizer available on GCC") + set(cmake_cxx_flags "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") # Intell compiler ? why? # no address sanitiser here though message(STATUS "Address Sanitizer not available on Intell compilers") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + message(STATUS "Address Sanitizer available on MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") else() message(STATUS "Address Sanitizer not available on unknown compiler ${CMAKE_CXX_COMPILER_ID}") diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index dabe5da26..a57102d6d 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -80,6 +80,7 @@ class BigConcurrentTaskThread : public QThread { QCoreApplication::processEvents(); emit finished(); + delete[] sub_tasks; } public: diff --git a/tests/Version_test.cpp b/tests/Version_test.cpp index afb4c6102..0f8c1652d 100644 --- a/tests/Version_test.cpp +++ b/tests/Version_test.cpp @@ -20,6 +20,8 @@ class VersionTest : public QObject { Q_OBJECT + QStringList m_flex_test_names = {}; + void addDataColumns() { QTest::addColumn("first"); @@ -101,8 +103,9 @@ class VersionTest : public QObject { QString first{split_line.first().simplified()}; QString second{split_line.last().simplified()}; - auto new_test_name = test_name_template.arg(QString::number(test_number), "lessThan").toLatin1().data(); - QTest::newRow(new_test_name) << first << second << true << false; + auto new_test_name = test_name_template.arg(QString::number(test_number), "lessThan"); + m_flex_test_names.append(new_test_name); + QTest::newRow(m_flex_test_names.last().toLatin1().data()) << first << second << true << false; continue; } @@ -112,8 +115,9 @@ class VersionTest : public QObject { QString first{split_line.first().simplified()}; QString second{split_line.last().simplified()}; - auto new_test_name = test_name_template.arg(QString::number(test_number), "equals").toLatin1().data(); - QTest::newRow(new_test_name) << first << second << false << true; + auto new_test_name = test_name_template.arg(QString::number(test_number), "equals"); + m_flex_test_names.append(new_test_name); + QTest::newRow(m_flex_test_names.last().toLatin1().data()) << first << second << false << true; continue; } @@ -123,8 +127,9 @@ class VersionTest : public QObject { QString first{split_line.first().simplified()}; QString second{split_line.last().simplified()}; - auto new_test_name = test_name_template.arg(QString::number(test_number), "greaterThan").toLatin1().data(); - QTest::newRow(new_test_name) << first << second << false << false; + auto new_test_name = test_name_template.arg(QString::number(test_number), "greaterThan"); + m_flex_test_names.append(new_test_name); + QTest::newRow(m_flex_test_names.last().toLatin1().data()) << first << second << false << false; continue; } @@ -140,10 +145,10 @@ class VersionTest : public QObject { void test_flexVerTestVector() { - QFETCH(QString, first); - QFETCH(QString, second); - QFETCH(bool, lessThan); - QFETCH(bool, equal); + QString first = *static_cast(QTest ::qData("first", ::qMetaTypeId::type>())); + QString second = *static_cast(QTest ::qData("second", ::qMetaTypeId::type>())); + bool lessThan = *static_cast(QTest ::qData("lessThan", ::qMetaTypeId::type>())); + bool equal = *static_cast(QTest ::qData("equal", ::qMetaTypeId::type>())); const auto v1 = Version(first); const auto v2 = Version(second); From 908ac813e0f96126a643851e99379956faa08cda Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 4 Jul 2023 15:16:54 +0300 Subject: [PATCH 280/429] escaped modlist inner html Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index b8edf7df8..ac0da2142 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -362,9 +362,9 @@ void FlamePackExportTask::buildZip() for (auto mod : resolvedFiles) { if (mod.isMod) { content += QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId)) - .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors) : ""); + .replace("{name}", mod.name.toHtmlEscaped()) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped()) + .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : ""); } } content = "
      " + content + "
    "; From 1fbc17d275b99d194906302f98412f78fbb77538 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Tue, 4 Jul 2023 16:38:04 -0400 Subject: [PATCH 281/429] Remove break and add fallthrough comment in WorldListPage.cpp Signed-off-by: PandaNinjas --- launcher/ui/pages/instance/WorldListPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index b5dc5a17c..b2200b1a7 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -338,8 +338,8 @@ void WorldListPage::mceditState(LoggedProcess::State state) case LoggedProcess::Aborted: { failed = true; - break; } + /* fallthrough */ case LoggedProcess::Running: case LoggedProcess::Finished: { From 34cf28712c254ba378bdbf728471d0dfbb4ab58f Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Tue, 4 Jul 2023 16:39:24 -0400 Subject: [PATCH 282/429] Replace break with return true; Signed-off-by: PandaNinjas --- launcher/ui/setupwizard/JavaWizardPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index e88335355..2b70c47c3 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -69,7 +69,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::AllOK: { settings->set("JavaPath", m_java_widget->javaPath()); - break; + return true; } case JavaSettingsWidget::ValidationStatus::JavaBad: { From 817ecf822583caf3a510f177d40fe8c6b3218165 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Tue, 4 Jul 2023 17:19:08 -0400 Subject: [PATCH 283/429] Fix VersionProxyModel.cpp Signed-off-by: PandaNinjas --- launcher/VersionProxyModel.cpp | 51 +++++++++------------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 03130b239..91f94f412 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -191,36 +191,21 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return QVariant(); } } - case Qt::ToolTipRole: { + case Qt::ToolTipRole: + { if (column == Name && hasRecommended) { - auto recommendedValue = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(recommendedValue.toBool()) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if (value.toBool()) { return tr("Recommended"); - } - else if(hasLatest) { - auto latestValue = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(latestValue.toBool()) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { - return tr("Recommended"); - } - else if(hasLatest) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { - return tr("Latest"); - } - } + } else if(hasLatest) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(value.toBool()) { + return tr("Latest"); } } - else if(index.row() == 0) { - return tr("Latest"); - } + } else { + return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); } - return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); } case Qt::DecorationRole: { @@ -255,20 +240,10 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return pixmap; } } - else if(index.row() == 0) { - return APPLICATION->getThemedIcon("bug"); + default: + { + return QVariant(); } - QPixmap pixmap; - QPixmapCache::find("placeholder", &pixmap); - if(!pixmap) { - QPixmap px(16,16); - px.fill(Qt::transparent); - QPixmapCache::insert("placeholder", px); - return px; - } - return pixmap; - } else { - return QVariant(); } } default: From 24b9ed106f3c217271468de565ff6706fd832ea5 Mon Sep 17 00:00:00 2001 From: seth Date: Tue, 4 Jul 2023 18:49:17 -0400 Subject: [PATCH 284/429] feat(actions): add update-flake-lock Signed-off-by: seth --- .github/workflows/update-flake.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/update-flake.yml diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml new file mode 100644 index 000000000..c790c9c69 --- /dev/null +++ b/.github/workflows/update-flake.yml @@ -0,0 +1,26 @@ +name: Update Flake Lockfile + +on: + schedule: + # run weekly on sunday + - cron: "0 0 * * 0" + workflow_dispatch: + +permissions: + pull-requests: write + +jobs: + update-flake: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v22 + + - uses: DeterminateSystems/update-flake-lock@v19 + with: + commit-msg: "chore(nix): update lockfile" + pr-title: "chore(nix): update lockfile" + pr-labels: | + Linux + simple change From 183ed7b90bbe015b09f545087387e1345ccaf927 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 4 Jul 2023 19:43:22 -0700 Subject: [PATCH 285/429] chore: cleanup compiler type branches Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb9906691..0abedab92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,21 +98,17 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) else() # AppleClang and Clang message(STATUS "Address Sanitizer available on Clang") - set(cmake_cxx_flags "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC message(STATUS "Address Sanitizer available on GCC") - set(cmake_cxx_flags "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - # Intell compiler ? why? - # no address sanitiser here though - message(STATUS "Address Sanitizer not available on Intell compilers") + set(CMAKE_CXX_FLAGS "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") message(STATUS "Address Sanitizer available on MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") else() - message(STATUS "Address Sanitizer not available on unknown compiler ${CMAKE_CXX_COMPILER_ID}") + message(STATUS "Address Sanitizer not available on compiler ${CMAKE_CXX_COMPILER_ID}") endif() endif() From a028894855f29c49d4bf8b0f745c66e1ea7dd4c6 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 4 Jul 2023 23:43:39 -0700 Subject: [PATCH 286/429] Apply suggestions from code review Co-authored-by: seth Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 6 +++--- tests/Version_test.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0abedab92..bc988b4ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" on) # If this is a Debug build turn on address sanitiser if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) - message(STATUS "Address Sanitizer enabeled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off") + message(STATUS "Address Sanitizer enabled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") # using clang with clang-cl front end @@ -98,12 +98,12 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) else() # AppleClang and Clang message(STATUS "Address Sanitizer available on Clang") - set(CMAKE_CXX_FLAGS "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}} -fsanitize=address -O1 -fno-omit-frame-pointer") endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC message(STATUS "Address Sanitizer available on GCC") - set(CMAKE_CXX_FLAGS "${cmake_cxx_flags} -fsanitize=address -O1 -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") message(STATUS "Address Sanitizer available on MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") diff --git a/tests/Version_test.cpp b/tests/Version_test.cpp index 0f8c1652d..f5488cbce 100644 --- a/tests/Version_test.cpp +++ b/tests/Version_test.cpp @@ -145,10 +145,10 @@ class VersionTest : public QObject { void test_flexVerTestVector() { - QString first = *static_cast(QTest ::qData("first", ::qMetaTypeId::type>())); - QString second = *static_cast(QTest ::qData("second", ::qMetaTypeId::type>())); - bool lessThan = *static_cast(QTest ::qData("lessThan", ::qMetaTypeId::type>())); - bool equal = *static_cast(QTest ::qData("equal", ::qMetaTypeId::type>())); + QFETCH(QString, first); + QFETCH(QString, second); + QFETCH(bool, lessThan); + QFETCH(bool, equal); const auto v1 = Version(first); const auto v2 = Version(second); From 5fe9a7a6c352735801fbbea69f8d2a6cd3b884f4 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 5 Jul 2023 03:02:20 -0700 Subject: [PATCH 287/429] fix: extra } in CXX args Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc988b4ff..4f8befcc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,7 +98,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) else() # AppleClang and Clang message(STATUS "Address Sanitizer available on Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}} -fsanitize=address -O1 -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC From 4dbcedd03f6d90a9557cd401c2236f9cda60cf9f Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:51:37 -0700 Subject: [PATCH 288/429] fix: Task test memory leaks again Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 5 ++ tests/Task_test.cpp | 138 +++++++++++++++++++++----------------------- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f8befcc3..afa67546d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,18 +95,23 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) # using clang with clang-cl front end message(STATUS "Address Sanitizer available on Clang MSVC frontend") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address /O1 /Oy-") else() # AppleClang and Clang message(STATUS "Address Sanitizer available on Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC message(STATUS "Address Sanitizer available on GCC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer") + link_libraries("asan") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") message(STATUS "Address Sanitizer available on MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address /O1 /Oy-") else() message(STATUS "Address Sanitizer not available on compiler ${CMAKE_CXX_COMPILER_ID}") endif() diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index a57102d6d..b6bd7edf2 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -1,6 +1,6 @@ #include -#include #include +#include #include #include @@ -19,10 +19,7 @@ class BasicTask : public Task { BasicTask(bool show_debug_log = true) : Task(nullptr, show_debug_log) {} private: - void executeTask() override - { - emitSucceeded(); - }; + void executeTask() override { emitSucceeded(); }; }; /* Does nothing. Only used for testing. */ @@ -34,7 +31,7 @@ class BasicTask_MultiStep : public Task { private: auto isMultiStep() const -> bool override { return true; } - void executeTask() override {}; + void executeTask() override{}; }; class BigConcurrentTask : public ConcurrentTask { @@ -44,7 +41,7 @@ class BigConcurrentTask : public ConcurrentTask { { // This is here only to help fill the stack a bit more quickly (if there's an issue, of course :^)) // Each tasks thus adds 1024 * 4 bytes to the stack, at the very least. - [[maybe_unused]] volatile std::array some_data_on_the_stack {}; + [[maybe_unused]] volatile std::array some_data_on_the_stack{}; ConcurrentTask::startNext(); } @@ -59,28 +56,28 @@ class BigConcurrentTaskThread : public QThread { { QTimer deadline; deadline.setInterval(10000); - connect(&deadline, &QTimer::timeout, this, [this]{ passed_the_deadline = true; }); + connect(&deadline, &QTimer::timeout, this, [this] { passed_the_deadline = true; }); deadline.start(); // NOTE: Arbitrary value that manages to trigger a problem when there is one. // Considering each tasks, in a problematic state, adds 1024 * 4 bytes to the stack, // this number is enough to fill up 16 MiB of stack, more than enough to cause a problem. static const unsigned s_num_tasks = 1 << 12; - auto sub_tasks = new BasicTask::Ptr[s_num_tasks]; + { + auto sub_tasks = std::array(); - for (unsigned i = 0; i < s_num_tasks; i++) { - auto sub_task = makeShared(false); - sub_tasks[i] = sub_task; - big_task.addTask(sub_task); - } + for (unsigned i = 0; i < s_num_tasks; i++) { + auto sub_task = makeShared(false); + sub_tasks[i] = sub_task; + big_task.addTask(sub_task); + } - big_task.run(); - - while (!big_task.isFinished() && !passed_the_deadline) - QCoreApplication::processEvents(); + big_task.run(); + while (!big_task.isFinished() && !passed_the_deadline) + QCoreApplication::processEvents(); + } // drop before emit emit finished(); - delete[] sub_tasks; } public: @@ -94,9 +91,10 @@ class TaskTest : public QObject { Q_OBJECT private slots: - void test_SetStatus_NoMultiStep(){ + void test_SetStatus_NoMultiStep() + { BasicTask t; - QString status {"test status"}; + QString status{ "test status" }; t.setStatus(status); @@ -104,9 +102,10 @@ class TaskTest : public QObject { QCOMPARE(t.getStepProgress().isEmpty(), TaskStepProgressList{}.isEmpty()); } - void test_SetStatus_MultiStep(){ + void test_SetStatus_MultiStep() + { BasicTask_MultiStep t; - QString status {"test status"}; + QString status{ "test status" }; t.setStatus(status); @@ -116,7 +115,8 @@ class TaskTest : public QObject { QCOMPARE(t.getStepProgress().isEmpty(), TaskStepProgressList{}.isEmpty()); } - void test_SetProgress(){ + void test_SetProgress() + { BasicTask t; int current = 42; int total = 207; @@ -127,17 +127,18 @@ class TaskTest : public QObject { QCOMPARE(t.getTotalProgress(), total); } - void test_basicRun(){ + void test_basicRun() + { BasicTask t; - QObject::connect(&t, &Task::finished, [&]{ QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); }); + QObject::connect(&t, &Task::finished, + [&] { QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); }); t.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return t.isFinished(); - }, 1000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should."); } - void test_basicConcurrentRun(){ + void test_basicConcurrentRun() + { auto t1 = makeShared(); auto t2 = makeShared(); auto t3 = makeShared(); @@ -148,21 +149,20 @@ class TaskTest : public QObject { t.addTask(t2); t.addTask(t3); - QObject::connect(&t, &Task::finished, [&]{ - QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); - QVERIFY(t1->wasSuccessful()); - QVERIFY(t2->wasSuccessful()); - QVERIFY(t3->wasSuccessful()); + QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3] { + QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); + QVERIFY(t1->wasSuccessful()); + QVERIFY(t2->wasSuccessful()); + QVERIFY(t3->wasSuccessful()); }); t.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return t.isFinished(); - }, 1000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should."); } // Tests if starting new tasks after the 6 initial ones is working - void test_moreConcurrentRun(){ + void test_moreConcurrentRun() + { auto t1 = makeShared(); auto t2 = makeShared(); auto t3 = makeShared(); @@ -185,26 +185,25 @@ class TaskTest : public QObject { t.addTask(t8); t.addTask(t9); - QObject::connect(&t, &Task::finished, [&]{ - QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); - QVERIFY(t1->wasSuccessful()); - QVERIFY(t2->wasSuccessful()); - QVERIFY(t3->wasSuccessful()); - QVERIFY(t4->wasSuccessful()); - QVERIFY(t5->wasSuccessful()); - QVERIFY(t6->wasSuccessful()); - QVERIFY(t7->wasSuccessful()); - QVERIFY(t8->wasSuccessful()); - QVERIFY(t9->wasSuccessful()); + QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9] { + QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); + QVERIFY(t1->wasSuccessful()); + QVERIFY(t2->wasSuccessful()); + QVERIFY(t3->wasSuccessful()); + QVERIFY(t4->wasSuccessful()); + QVERIFY(t5->wasSuccessful()); + QVERIFY(t6->wasSuccessful()); + QVERIFY(t7->wasSuccessful()); + QVERIFY(t8->wasSuccessful()); + QVERIFY(t9->wasSuccessful()); }); t.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return t.isFinished(); - }, 1000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should."); } - void test_basicSequentialRun(){ + void test_basicSequentialRun() + { auto t1 = makeShared(); auto t2 = makeShared(); auto t3 = makeShared(); @@ -215,20 +214,19 @@ class TaskTest : public QObject { t.addTask(t2); t.addTask(t3); - QObject::connect(&t, &Task::finished, [&]{ - QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); - QVERIFY(t1->wasSuccessful()); - QVERIFY(t2->wasSuccessful()); - QVERIFY(t3->wasSuccessful()); + QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3] { + QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); + QVERIFY(t1->wasSuccessful()); + QVERIFY(t2->wasSuccessful()); + QVERIFY(t3->wasSuccessful()); }); t.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return t.isFinished(); - }, 1000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should."); } - void test_basicMultipleOptionsRun(){ + void test_basicMultipleOptionsRun() + { auto t1 = makeShared(); auto t2 = makeShared(); auto t3 = makeShared(); @@ -239,17 +237,15 @@ class TaskTest : public QObject { t.addTask(t2); t.addTask(t3); - QObject::connect(&t, &Task::finished, [&]{ - QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); - QVERIFY(t1->wasSuccessful()); - QVERIFY(!t2->wasSuccessful()); - QVERIFY(!t3->wasSuccessful()); + QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3] { + QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); + QVERIFY(t1->wasSuccessful()); + QVERIFY(!t2->wasSuccessful()); + QVERIFY(!t3->wasSuccessful()); }); t.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return t.isFinished(); - }, 1000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should."); } void test_stackOverflowInConcurrentTask() From 965ee5687a475aa0a7e3756f0e5a7e1db26c6a16 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 5 Jul 2023 20:05:18 -0700 Subject: [PATCH 289/429] fix(test): task test memory leak *again* - put Big thread on the stack so stack will clean it up. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- tests/Task_test.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index b6bd7edf2..ef7042a59 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -252,16 +252,15 @@ class TaskTest : public QObject { { QEventLoop loop; - auto thread = new BigConcurrentTaskThread; + BigConcurrentTaskThread thread{}; - connect(thread, &BigConcurrentTaskThread::finished, &loop, &QEventLoop::quit); + connect(&thread, &BigConcurrentTaskThread::finished, &loop, &QEventLoop::quit); - thread->start(); + thread.start(); loop.exec(); - QVERIFY(!thread->passed_the_deadline); - thread->deleteLater(); + QVERIFY(!thread.passed_the_deadline); } }; From 8638076aa1cf3f1a975ac59ddaf0286acc7d39e2 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 5 Jul 2023 20:19:22 -0700 Subject: [PATCH 290/429] fix(test): tasks test memmory leak. don't store local task copy. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- tests/Task_test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index ef7042a59..41e51f838 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -64,11 +64,9 @@ class BigConcurrentTaskThread : public QThread { // this number is enough to fill up 16 MiB of stack, more than enough to cause a problem. static const unsigned s_num_tasks = 1 << 12; { - auto sub_tasks = std::array(); for (unsigned i = 0; i < s_num_tasks; i++) { auto sub_task = makeShared(false); - sub_tasks[i] = sub_task; big_task.addTask(sub_task); } From 71e73bb6f8c4a695e39f0c0fec901d8a5e5121b3 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 5 Jul 2023 21:18:49 -0700 Subject: [PATCH 291/429] fix(tests): linux big task memory leak. - move big_task into function scope Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- tests/Task_test.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index 41e51f838..00d067947 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -50,31 +50,34 @@ class BigConcurrentTask : public ConcurrentTask { class BigConcurrentTaskThread : public QThread { Q_OBJECT - BigConcurrentTask big_task; void run() override { QTimer deadline; + BigConcurrentTask big_task; deadline.setInterval(10000); - connect(&deadline, &QTimer::timeout, this, [this] { passed_the_deadline = true; }); + bool* pt_deadline = &passed_the_deadline; + QMetaObject::Connection conn = connect(&deadline, &QTimer::timeout, this, [pt_deadline] { *pt_deadline = true; }); deadline.start(); // NOTE: Arbitrary value that manages to trigger a problem when there is one. // Considering each tasks, in a problematic state, adds 1024 * 4 bytes to the stack, // this number is enough to fill up 16 MiB of stack, more than enough to cause a problem. static const unsigned s_num_tasks = 1 << 12; - { + for (unsigned i = 0; i < s_num_tasks; i++) { + auto sub_task = makeShared(false); + big_task.addTask(sub_task); + } - for (unsigned i = 0; i < s_num_tasks; i++) { - auto sub_task = makeShared(false); - big_task.addTask(sub_task); - } + big_task.run(); - big_task.run(); - - while (!big_task.isFinished() && !passed_the_deadline) - QCoreApplication::processEvents(); - } // drop before emit + while (!big_task.isFinished() && !passed_the_deadline) + QCoreApplication::processEvents(); + // don't fire timer after this point + disconnect(conn); + if (deadline.isActive()) + deadline.stop(); + // task finished emit finished(); } From 13d67c6524a29daea51242d17ba0c6a2b8593747 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Thu, 6 Jul 2023 08:51:42 -0400 Subject: [PATCH 292/429] Keep formatting consistent Signed-off-by: PandaNinjas --- launcher/VersionProxyModel.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 91f94f412..63a43465c 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -193,13 +193,16 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const } case Qt::ToolTipRole: { - if (column == Name && hasRecommended) { + if(column == Name && hasRecommended) + { auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if (value.toBool()) { + if(value.toBool()) + { return tr("Recommended"); } else if(hasLatest) { auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) { + if(value.toBool()) + { return tr("Latest"); } } From 93870c315f84d2bb599d669be8205990ee48907d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 6 Jul 2023 18:46:59 +0300 Subject: [PATCH 293/429] better url handling Signed-off-by: Trial97 --- launcher/ui/widgets/InfoFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index b16bc097f..a0fda952f 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -46,7 +46,7 @@ void setupLinkToolTip(QLabel* label) { QObject::connect(label, &QLabel::linkHovered, [label](const QString& link) { - if (!link.isEmpty() && !link.startsWith("http")) + if (auto url = QUrl(link); !url.isValid() || (url.scheme() != "http" && url.scheme() != "https")) return; label->setToolTip(link); }); From b8b8c8d4acab8c794555956fae699d5706e222f3 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 6 Jul 2023 06:38:36 -0300 Subject: [PATCH 294/429] fix(tests): Fix abort of Task test on Linux Not sure exactly what caused the issue, though I suppose using QThread's exec instead of our own thingie is nice. I can't remember why I didn't use that before, so I hope there's no issue with that! :^) Signed-off-by: flow --- tests/Task_test.cpp | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index 00d067947..c59d4bb73 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -50,15 +50,11 @@ class BigConcurrentTask : public ConcurrentTask { class BigConcurrentTaskThread : public QThread { Q_OBJECT - + QTimer m_deadline; void run() override { - QTimer deadline; BigConcurrentTask big_task; - deadline.setInterval(10000); - bool* pt_deadline = &passed_the_deadline; - QMetaObject::Connection conn = connect(&deadline, &QTimer::timeout, this, [pt_deadline] { *pt_deadline = true; }); - deadline.start(); + m_deadline.setInterval(10000); // NOTE: Arbitrary value that manages to trigger a problem when there is one. // Considering each tasks, in a problematic state, adds 1024 * 4 bytes to the stack, @@ -69,23 +65,17 @@ class BigConcurrentTaskThread : public QThread { big_task.addTask(sub_task); } + connect(&big_task, &Task::finished, this, &QThread::quit); + connect(&m_deadline, &QTimer::timeout, this, [&] { passed_the_deadline = true; quit(); }); + + m_deadline.start(); big_task.run(); - while (!big_task.isFinished() && !passed_the_deadline) - QCoreApplication::processEvents(); - // don't fire timer after this point - disconnect(conn); - if (deadline.isActive()) - deadline.stop(); - // task finished - emit finished(); + exec(); } public: bool passed_the_deadline = false; - - signals: - void finished(); }; class TaskTest : public QObject { @@ -253,7 +243,7 @@ class TaskTest : public QObject { { QEventLoop loop; - BigConcurrentTaskThread thread{}; + BigConcurrentTaskThread thread; connect(&thread, &BigConcurrentTaskThread::finished, &loop, &QEventLoop::quit); From 8ae67b84dbf154bef957bfba1342eac27cd4837e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 6 Jul 2023 20:03:25 +0100 Subject: [PATCH 295/429] Optional mods in mrpack export Signed-off-by: TheKodeToad --- .../modrinth/ModrinthPackExportTask.cpp | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 4cd88aa69..cbdfd04f0 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -263,13 +263,13 @@ void ModrinthPackExportTask::finish() QByteArray ModrinthPackExportTask::generateIndex() { - QJsonObject obj; - obj["formatVersion"] = 1; - obj["game"] = "minecraft"; - obj["name"] = name; - obj["versionId"] = version; + QJsonObject out; + out["formatVersion"] = 1; + out["game"] = "minecraft"; + out["name"] = name; + out["versionId"] = version; if (!summary.isEmpty()) - obj["summary"] = summary; + out["summary"] = summary; if (mcInstance) { auto profile = mcInstance->getPackProfile(); @@ -290,30 +290,40 @@ QByteArray ModrinthPackExportTask::generateIndex() if (forge != nullptr) dependencies["forge"] = forge->m_version; - obj["dependencies"] = dependencies; + out["dependencies"] = dependencies; } - QJsonArray files; - QMapIterator iterator(resolvedFiles); - while (iterator.hasNext()) { - iterator.next(); + QJsonArray filesOut; + for (auto iterator = resolvedFiles.constBegin(); iterator != resolvedFiles.constEnd(); iterator++) { + QJsonObject fileOut; + QString path = iterator.key(); const ResolvedFile& value = iterator.value(); - QJsonObject file; - file["path"] = iterator.key(); - file["downloads"] = QJsonArray({ iterator.value().url }); + // detect disabled mod + QString disabledSuffix = ".disabled"; + if (path.endsWith(disabledSuffix)) { + // rename it + path = path.left(path.length() - disabledSuffix.length()); + // ...and make it optional + QJsonObject env; + env["client"] = "optional"; + env["server"] = "optional"; + fileOut["env"] = env; + } + + fileOut["path"] = path; + fileOut["downloads"] = QJsonArray{ iterator.value().url }; QJsonObject hashes; hashes["sha1"] = value.sha1; hashes["sha512"] = value.sha512; + fileOut["hashes"] = hashes; - file["hashes"] = hashes; - file["fileSize"] = value.size; - - files << file; + fileOut["fileSize"] = value.size; + filesOut << fileOut; } - obj["files"] = files; + out["files"] = filesOut; - return QJsonDocument(obj).toJson(QJsonDocument::Compact); + return QJsonDocument(out).toJson(QJsonDocument::Compact); } From 073cb91f885b780ae04b6d9a4b94702307f07321 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 7 Jul 2023 15:56:04 +0200 Subject: [PATCH 296/429] fix(ui): validate meta override url Signed-off-by: Sefa Eyeoglu --- launcher/ui/pages/global/APIPage.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index dca1b3a63..fab31dbd9 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -81,6 +81,8 @@ APIPage::APIPage(QWidget *parent) : connect(ui->pasteTypeComboBox, currentIndexChangedSignal, this, &APIPage::updateBaseURLPlaceholder); // This function needs to be called even when the ComboBox's index is still in its default state. updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex()); + // NOTE: this allows http://, but we replace that with https later anyway + ui->metaURL->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->metaURL)); ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry)); ui->msaClientID->setValidator(new QRegularExpressionValidator(validMSAClientID, ui->msaClientID)); ui->flameKey->setValidator(new QRegularExpressionValidator(validFlameKey, ui->flameKey)); From 6fcdac0d36865eadc2454244ce03c77e6eed767b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 7 Jul 2023 15:57:24 +0200 Subject: [PATCH 297/429] fix: reset invalid meta url on launch Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 1d97a5f2e..34e1320a2 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -687,8 +687,16 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->reset("PastebinCustomAPIBase"); } } - // meta URL - m_settings->registerSetting("MetaURLOverride", ""); + { + // Meta URL + m_settings->registerSetting("MetaURLOverride", ""); + + QUrl metaUrl = m_settings->get("MetaURLOverride").toString(); + + // get rid of invalid meta urls + if (!metaUrl.isValid() || metaUrl.scheme() != "http" || metaUrl.scheme() != "https") + m_settings->reset("MetaURLOverride"); + } m_settings->registerSetting("CloseAfterLaunch", false); m_settings->registerSetting("QuitAfterGameStop", false); From 3139af8487ae8ea20468023e477be02cf0b96a4d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 7 Jul 2023 17:12:10 +0300 Subject: [PATCH 298/429] Made action text simpler Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index ce6968f53..fe2f21c90 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -107,7 +107,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionVisitItemPage->setText(tr("Visit mod's page")); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); } else { - ui->actionVisitItemPage->setText(tr("Visit the pages of the selected mods")); + ui->actionVisitItemPage->setText(tr("Visit mods pages")); ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); } ui->actionVisitItemPage->setEnabled(selected != 0); From b8482a5d89b4044482e7b55aa1c2e2547b41f4fd Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 7 Jul 2023 15:53:50 +0100 Subject: [PATCH 299/429] Update ModFolderPage.cpp Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ModFolderPage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index fe2f21c90..041d1bfd2 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -107,7 +107,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr 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->setText(tr("Visit mods' pages")); ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); } ui->actionVisitItemPage->setEnabled(selected != 0); @@ -303,4 +303,4 @@ void ModFolderPage::visitModPages() if (!url.isEmpty()) DesktopServices::openUrl(url); } -} \ No newline at end of file +} From 51e62761ee8e8cd868c5f2a7eb63d54de5b71d6a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 7 Jul 2023 19:25:12 +0200 Subject: [PATCH 300/429] fix: improve QUrl construction Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 2 +- launcher/ui/pages/global/APIPage.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 34e1320a2..7858d7132 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -691,7 +691,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Meta URL m_settings->registerSetting("MetaURLOverride", ""); - QUrl metaUrl = m_settings->get("MetaURLOverride").toString(); + QUrl metaUrl(m_settings->get("MetaURLOverride").toString()); // get rid of invalid meta urls if (!metaUrl.isValid() || metaUrl.scheme() != "http" || metaUrl.scheme() != "https") diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index fab31dbd9..668aa0078 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -165,7 +165,7 @@ void APIPage::applySettings() QString msaClientID = ui->msaClientID->text(); s->set("MSAClientIDOverride", msaClientID); - QUrl metaURL = ui->metaURL->text(); + QUrl metaURL(ui->metaURL->text()); // Add required trailing slash if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) { From 10678096e57eb5b344f0dd39ad178403640b722a Mon Sep 17 00:00:00 2001 From: ashuntu <101582426+ashuntu@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:20:15 -0500 Subject: [PATCH 301/429] Persist app data between install versions --- launcher/Application.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 1d97a5f2e..b91b3157a 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -280,7 +280,16 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) } else { - QDir foo(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); + QDir foo; + if (DesktopServices::isSnap()) + { + foo = QDir(getenv("SNAP_USER_COMMON")); + } + else + { + foo = QDir(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); + } + dataPath = foo.absolutePath(); adjustedBy = "Persistent data path"; From 51d7a6289e1cf2df463ae8d7c0b08b4a61faea3c Mon Sep 17 00:00:00 2001 From: ashuntu <101582426+ashuntu@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:23:05 -0500 Subject: [PATCH 302/429] Fix URL open crash (#596) --- launcher/DesktopServices.cpp | 24 +++++++++++++++++++----- launcher/DesktopServices.h | 13 +++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp index 2984a1b4f..81362f099 100644 --- a/launcher/DesktopServices.cpp +++ b/launcher/DesktopServices.cpp @@ -118,7 +118,7 @@ bool openDirectory(const QString &path, bool ensureExists) return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isFlatpak()) + if(!isSandbox()) { return IndirectOpen(f); } @@ -139,7 +139,7 @@ bool openFile(const QString &path) return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isFlatpak()) + if(!isSandbox()) { return IndirectOpen(f); } @@ -157,7 +157,7 @@ bool openFile(const QString &application, const QString &path, const QString &wo qDebug() << "Opening file" << path << "using" << application; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave - if(!isFlatpak()) + if(!isSandbox()) { return IndirectOpen([&]() { @@ -177,7 +177,7 @@ bool run(const QString &application, const QStringList &args, const QString &wor { qDebug() << "Running" << application << "with args" << args.join(' '); #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isFlatpak()) + if(!isSandbox()) { // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave return IndirectOpen([&]() @@ -202,7 +202,7 @@ bool openUrl(const QUrl &url) return QDesktopServices::openUrl(url); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isFlatpak()) + if(!isSandbox()) { return IndirectOpen(f); } @@ -224,4 +224,18 @@ bool isFlatpak() #endif } +bool isSnap() +{ +#ifdef Q_OS_LINUX + return getenv("SNAP"); +#else + return false; +#endif +} + +bool isSandbox() +{ + return isSnap() || isFlatpak(); +} + } diff --git a/launcher/DesktopServices.h b/launcher/DesktopServices.h index 21c9cae0b..b1948cc2b 100644 --- a/launcher/DesktopServices.h +++ b/launcher/DesktopServices.h @@ -34,5 +34,18 @@ namespace DesktopServices */ bool openUrl(const QUrl &url); + /** + * Determine whether the launcher is running in a Flatpak environment + */ bool isFlatpak(); + + /** + * Determine whether the launcher is running in a Snap environment + */ + bool isSnap(); + + /** + * Determine whether the launcher is running in a sandboxed (Flatpak or Snap) environment + */ + bool isSandbox(); } From 20c781b23b0d2bd2be8bed0c015eb6c82312c29a Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 8 Jul 2023 02:28:37 -0700 Subject: [PATCH 303/429] fix(progress dialog): if there is a parent center on creation Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 23 +++++++++++++++-------- launcher/ui/dialogs/ProgressDialog.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 3368a8c47..4243e2917 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -67,9 +67,9 @@ ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Pr ui->taskProgressScrollArea->setHidden(true); this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); setAttribute(Qt::WidgetAttribute::WA_QuitOnClose, true); - setSkipButton(false); changeProgress(0, 100); - updateSize(); + updateSize(true); + setSkipButton(false); } void ProgressDialog::setSkipButton(bool present, QString label) @@ -95,7 +95,7 @@ ProgressDialog::~ProgressDialog() delete ui; } -void ProgressDialog::updateSize() +void ProgressDialog::updateSize(bool recenterParent) { QSize lastSize = this->size(); QPoint lastPos = this->pos(); @@ -112,13 +112,20 @@ void ProgressDialog::updateSize() adjustSize(); QSize newSize = this->size(); - // if the current window is too small - if ((lastSize != newSize) && (lastSize.height() < newSize.height())) + // if the current window is a different size + auto parent = this->parentWidget(); + if (recenterParent && parent) { + auto newX = std::max(0, parent->x() + ((parent->width() - newSize.width()) / 2)); + auto newY = std::max(0, parent->y() + ((parent->height() - newSize.height()) / 2)); + this->move(newX, newY); + } + else if (lastSize != newSize) { - QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize - QPoint newPos(lastPos.x() + (sizeDiff.width() / 2), lastPos.y() + (sizeDiff.height() / 2)); - this->move(newPos); + QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative + auto newX = std::max(0, lastPos.x() + (sizeDiff.width() / 2)); + auto newY = std::max(0, lastPos.y() + (sizeDiff.height() / 2)); + this->move(newX, newY); } } diff --git a/launcher/ui/dialogs/ProgressDialog.h b/launcher/ui/dialogs/ProgressDialog.h index fc9a0fbc3..f062be084 100644 --- a/launcher/ui/dialogs/ProgressDialog.h +++ b/launcher/ui/dialogs/ProgressDialog.h @@ -62,7 +62,7 @@ public: explicit ProgressDialog(QWidget *parent = 0); ~ProgressDialog(); - void updateSize(); + void updateSize(bool recenterParent = false); int execWithTask(Task* task); int execWithTask(std::unique_ptr &&task); From 0c6362f28d1caec4d256c538d2874b226390ad85 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 8 Jul 2023 18:51:28 +0100 Subject: [PATCH 304/429] Make trash hungry Signed-off-by: TheKodeToad --- launcher/minecraft/mod/Mod.cpp | 4 ++-- launcher/minecraft/mod/Mod.h | 2 +- launcher/minecraft/mod/ModFolderModel.cpp | 6 +++--- launcher/minecraft/mod/Resource.cpp | 8 ++------ launcher/minecraft/mod/Resource.h | 2 +- launcher/minecraft/mod/ResourceFolderModel.cpp | 2 +- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 2 +- 7 files changed, 11 insertions(+), 15 deletions(-) diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index fa1a02534..880dacb15 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -126,7 +126,7 @@ bool Mod::applyFilter(QRegularExpression filter) const return Resource::applyFilter(filter); } -auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool +auto Mod::destroy(QDir& index_dir, bool preserve_metadata, bool attempt_trash) -> bool { if (!preserve_metadata) { qDebug() << QString("Destroying metadata for '%1' on purpose").arg(name()); @@ -139,7 +139,7 @@ auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool } } - return Resource::destroy(); + return Resource::destroy(attempt_trash); } auto Mod::details() const -> const ModDetails& diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d6272f4d0..b67bd4659 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -93,7 +93,7 @@ public: [[nodiscard]] bool applyFilter(QRegularExpression filter) const override; // Delete all the files of this mod - auto destroy(QDir& index_dir, bool preserve_metadata = false) -> bool; + auto destroy(QDir& index_dir, bool preserve_metadata = false, bool attempt_trash = true) -> bool; void finishResolvingWithDetails(ModDetails&& details); diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index af98d8348..50f96b72c 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -199,10 +199,10 @@ Task* ModFolderModel::createParseTask(Resource& resource) bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadata) { - for(auto mod : allMods()){ - if(mod->fileinfo().fileName() == filename){ + for(auto mod : allMods()) { + if(mod->fileinfo().fileName() == filename) { auto index_dir = indexDir(); - mod->destroy(index_dir, preserve_metadata); + mod->destroy(index_dir, preserve_metadata, false); update(); diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index e50772601..098a617f8 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -148,14 +148,10 @@ bool Resource::enable(EnableAction action) return true; } -bool Resource::destroy() +bool Resource::destroy(bool attemptTrash) { m_type = ResourceType::UNKNOWN; - - if (FS::trash(m_file_info.filePath())) - return true; - - return FS::deletePath(m_file_info.filePath()); + return (attemptTrash && FS::trash(m_file_info.filePath())) || FS::deletePath(m_file_info.filePath()); } bool Resource::isSymLinkUnder(const QString& instPath) const diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index a5e9ae91e..94f3160c3 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -92,7 +92,7 @@ class Resource : public QObject { } // Delete all files of this resource. - bool destroy(); + bool destroy(bool attemptTrash = true); [[nodiscard]] auto isSymLink() const -> bool { return m_file_info.isSymLink(); } diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 7700fd36b..79169ae84 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -159,7 +159,7 @@ bool ResourceFolderModel::uninstallResource(QString file_name) { for (auto& resource : m_resources) { if (resource->fileinfo().fileName() == file_name) { - auto res = resource->destroy(); + auto res = resource->destroy(false); update(); diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 3677a1dca..ef353c701 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -103,7 +103,7 @@ void ModFolderLoadTask::executeTask() while (iter.hasNext()) { auto mod = iter.next().value(); if (mod->status() == ModStatus::NotInstalled) { - mod->destroy(m_index_dir, false); + mod->destroy(m_index_dir, false, false); iter.remove(); } } From 08c140b9b45b1a8afd134793acedf867526d6432 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 8 Jul 2023 20:51:27 +0100 Subject: [PATCH 305/429] Fix actionVisitItemPage insersion, and prevent widebar segfault Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- launcher/ui/widgets/WideBar.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 041d1bfd2..9f0776189 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -89,7 +89,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); - ui->actionsToolbar->insertActionAfter(ui->actionViewFolder, ui->actionVisitItemPage); + ui->actionsToolbar->addAction(ui->actionVisitItemPage); connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); auto check_allow_update = [this] { diff --git a/launcher/ui/widgets/WideBar.cpp b/launcher/ui/widgets/WideBar.cpp index ac34e3aaa..a77c45fee 100644 --- a/launcher/ui/widgets/WideBar.cpp +++ b/launcher/ui/widgets/WideBar.cpp @@ -116,12 +116,21 @@ void WideBar::insertActionAfter(QAction* after, QAction* action) if (iter == m_entries.end()) return; + iter++; + // the action to insert after is present + // however, the element after it isn't valid + if (iter == m_entries.end()) { + // append the action instead of inserting it + addAction(action); + return; + } + BarEntry entry; - entry.bar_action = insertWidget((iter + 1)->bar_action, new ActionButton(action, this, m_use_default_action)); + entry.bar_action = insertWidget(iter->bar_action, new ActionButton(action, this, m_use_default_action)); entry.menu_action = action; entry.type = BarEntry::Type::Action; - m_entries.insert(iter + 1, entry); + m_entries.insert(iter, entry); m_menu_state = MenuState::Dirty; } From a54bbae62282e8adce76df9626c58b6bb3e12967 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 8 Jul 2023 12:59:55 -0700 Subject: [PATCH 306/429] fix(instance edit): don't allow editing if no selected instance or instance doesn't support editing Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 515abf070..254f229da 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1279,7 +1279,17 @@ void MainWindow::globalSettingsClosed() void MainWindow::on_actionEditInstance_triggered() { - APPLICATION->showInstanceWindow(m_selectedInstance); + + if (!m_selectedInstance) + return; + + if (m_selectedInstance->canEdit()) { + APPLICATION->showInstanceWindow(m_selectedInstance); + } else { + CustomMessageBox::selectable(this, tr("Instance not editable"), + tr("This instance is not editable. it may be broken, invalid, or too old. Check logs for details,"), + QMessageBox::Critical)->show(); + } } void MainWindow::on_actionManageAccounts_triggered() From e70407289266a205147bfb1293763e64dacb0f3e Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 8 Jul 2023 13:38:00 -0700 Subject: [PATCH 307/429] fix(flame install): don't assume .zip is a resource pack. default to mod let identifier move it if needed Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/tasks/LocalResourceParse.cpp | 9 +++++---- launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 8 +++++--- launcher/modplatform/flame/PackManifest.cpp | 9 ++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index 4d760df2b..6d9b4d97a 100644 --- a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp @@ -44,7 +44,11 @@ static const QMap s_packed_type_names = { namespace ResourceUtils { PackedResourceType identify(QFileInfo file){ if (file.exists() && file.isFile()) { - if (ResourcePackUtils::validate(file)) { + if (ModUtils::validate(file)) { + // mods can contain resource and data packs so they much be tested first + qDebug() << file.fileName() << "is a mod"; + return PackedResourceType::Mod; + } else if (ResourcePackUtils::validate(file)) { qDebug() << file.fileName() << "is a resource pack"; return PackedResourceType::ResourcePack; } else if (TexturePackUtils::validate(file)) { @@ -53,9 +57,6 @@ PackedResourceType identify(QFileInfo file){ } else if (DataPackUtils::validate(file)) { qDebug() << file.fileName() << "is a data pack"; return PackedResourceType::DataPack; - } else if (ModUtils::validate(file)) { - qDebug() << file.fileName() << "is a mod"; - return PackedResourceType::Mod; } else if (WorldSaveUtils::validate(file)) { qDebug() << file.fileName() << "is a world save"; return PackedResourceType::WorldSave; diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index e7641d644..b57db288a 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -563,6 +563,8 @@ void FlameCreationTask::validateZIPResouces() if (FS::move(localPath, destPath)) { return destPath; } + } else { + qDebug() << "Target folder of" << fileName << "is correct at" << targetFolder; } return localPath; }; @@ -584,6 +586,9 @@ void FlameCreationTask::validateZIPResouces() QString worldPath; switch (type) { + case PackedResourceType::Mod : + validatePath(fileName, targetFolder, "mods"); + break; case PackedResourceType::ResourcePack : validatePath(fileName, targetFolder, "resourcepacks"); break; @@ -593,9 +598,6 @@ void FlameCreationTask::validateZIPResouces() case PackedResourceType::DataPack : validatePath(fileName, targetFolder, "datapacks"); break; - case PackedResourceType::Mod : - validatePath(fileName, targetFolder, "mods"); - break; case PackedResourceType::ShaderPack : // in theroy flame API can't do this but who knows, that *may* change ? // better to handle it if it *does* occure in the future diff --git a/launcher/modplatform/flame/PackManifest.cpp b/launcher/modplatform/flame/PackManifest.cpp index 22008297f..ee4d07662 100644 --- a/launcher/modplatform/flame/PackManifest.cpp +++ b/launcher/modplatform/flame/PackManifest.cpp @@ -76,13 +76,8 @@ bool Flame::File::parseFromObject(const QJsonObject& obj, bool throw_on_blocked // It is also optional type = File::Type::SingleFile; - if (fileName.endsWith(".zip")) { - // this is probably a resource pack - targetFolder = "resourcepacks"; - } else { - // this is probably a mod, dunno what else could modpacks download - targetFolder = "mods"; - } + targetFolder = "mods"; + // get the hash hash = QString(); auto hashes = Json::ensureArray(obj, "hashes"); From d53d58a5d42684c5151680016f38a0f4bd1c0298 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 8 Jul 2023 22:03:47 +0100 Subject: [PATCH 308/429] LiteMod downloading Signed-off-by: TheKodeToad --- launcher/minecraft/PackProfile.cpp | 3 ++- launcher/modplatform/flame/FlameAPI.h | 2 ++ launcher/modplatform/modrinth/ModrinthAPI.h | 6 +++--- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 9 +++++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index aff05dbc8..e8fd21572 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -65,7 +65,8 @@ static const QMap modloaderMapping{ {"net.minecraftforge", ResourceAPI::Forge}, {"net.fabricmc.fabric-loader", ResourceAPI::Fabric}, - {"org.quiltmc.quilt-loader", ResourceAPI::Quilt} + {"org.quiltmc.quilt-loader", ResourceAPI::Quilt}, + {"com.mumfrey.liteloader", ResourceAPI::LiteLoader} }; PackProfile::PackProfile(MinecraftInstance * instance) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 0a6dc78f8..49bc316f2 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -23,6 +23,8 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] auto getSortingMethods() const -> QList override; + static inline auto validateModLoaders(ModLoaderTypes loaders) -> bool { return loaders & (Forge | Fabric | Quilt); } + private: static int getClassId(ModPlatform::ResourceType type) { diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index e83ed2bf7..58af14cc7 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -38,7 +38,7 @@ class ModrinthAPI : public NetworkResourceAPI { static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList { QStringList l; - for (auto loader : { Forge, Fabric, Quilt }) { + for (auto loader : { Forge, Fabric, Quilt, LiteLoader }) { if (types & loader) { l << getModLoaderString(loader); } @@ -92,7 +92,7 @@ class ModrinthAPI : public NetworkResourceAPI { { if (args.loaders.has_value()) { if (!validateModLoaders(args.loaders.value())) { - qWarning() << "Modrinth only have Forge and Fabric-compatible mods!"; + qWarning() << "Modrinth - or our interface - does not support any the provided mod loaders!"; return {}; } } @@ -141,7 +141,7 @@ class ModrinthAPI : public NetworkResourceAPI { return s.isEmpty() ? QString() : s; } - inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool { return loaders & (Forge | Fabric | Quilt); } + static inline auto validateModLoaders(ModLoaderTypes loaders) -> bool { return loaders & (Forge | Fabric | Quilt | LiteLoader); } [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 4f59f5605..b17eced35 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -43,6 +43,8 @@ #include "ui/pages/modplatform/flame/FlameResourcePages.h" #include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h" +#include "modplatform/flame/FlameAPI.h" +#include "modplatform/modrinth/ModrinthAPI.h" #include "ui/widgets/PageContainer.h" namespace ResourceDownload { @@ -281,8 +283,11 @@ QList ModDownloadDialog::getPages() { QList pages; - pages.append(ModrinthModPage::create(this, *m_instance)); - if (APPLICATION->capabilities() & Application::SupportsFlame) + auto loaders = static_cast(m_instance)->getPackProfile()->getModLoaders().value(); + + if (ModrinthAPI::validateModLoaders(loaders)) + pages.append(ModrinthModPage::create(this, *m_instance)); + if (APPLICATION->capabilities() & Application::SupportsFlame && FlameAPI::validateModLoaders(loaders)) pages.append(FlameModPage::create(this, *m_instance)); m_selectedPage = dynamic_cast(pages[0]); From 4dc4c589ba21df9c5e04081e35788862b498f29d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 8 Jul 2023 15:44:09 -0700 Subject: [PATCH 309/429] packaging: fix duplicate share directories (use only lowercase) Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 2 +- launcher/Application.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70a553190..0defd5e0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -345,7 +345,7 @@ elseif(UNIX) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION "${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_mrpack_MIMEInfo} DESTINATION ${KDE_INSTALL_MIMEDIR}) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "${KDE_INSTALL_DATADIR}/${Launcher_Name}") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "share/${Launcher_APP_BINARY_NAME}") if(Launcher_ManPage) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_ManPage} DESTINATION "${KDE_INSTALL_MANDIR}/man6") diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 7858d7132..8c60f6974 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -433,7 +433,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) } // seach root path if(!foundLoggingRules) { +#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + logRulesPath = FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_APP_BINARY_NAME, logRulesFile); +#else logRulesPath = FS::PathCombine(m_rootPath, logRulesFile); +#endif qDebug() << "Testing" << logRulesPath << "..."; foundLoggingRules = QFile::exists(logRulesPath); } From 0d31e31282008e2b6df6b551facb64a2dfc98db8 Mon Sep 17 00:00:00 2001 From: seth Date: Sun, 9 Jul 2023 01:56:21 -0400 Subject: [PATCH 310/429] fix(actions): give update-flake content write perms Signed-off-by: seth --- .github/workflows/update-flake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml index c790c9c69..e79040ab4 100644 --- a/.github/workflows/update-flake.yml +++ b/.github/workflows/update-flake.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + contents: write pull-requests: write jobs: From 6e2fcc9e1102d3955a509c3346b8df15ce52a6a1 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 9 Jul 2023 12:08:15 +0100 Subject: [PATCH 311/429] Replace string manipulation in favour of QFileInfo Signed-off-by: TheKodeToad --- launcher/modplatform/modrinth/ModrinthPackExportTask.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index cbdfd04f0..50f6a33c6 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -301,10 +301,10 @@ QByteArray ModrinthPackExportTask::generateIndex() const ResolvedFile& value = iterator.value(); // detect disabled mod - QString disabledSuffix = ".disabled"; - if (path.endsWith(disabledSuffix)) { + const QFileInfo pathInfo(path); + if (pathInfo.suffix() == "disabled") { // rename it - path = path.left(path.length() - disabledSuffix.length()); + path = pathInfo.dir().filePath(pathInfo.completeBaseName()); // ...and make it optional QJsonObject env; env["client"] = "optional"; From 8e4de055b841a6a2ca93b758344ddb72d2ea0f59 Mon Sep 17 00:00:00 2001 From: seth Date: Sun, 9 Jul 2023 15:19:11 -0400 Subject: [PATCH 312/429] chore(actions): only run update-flake in our repo Signed-off-by: seth --- .github/workflows/update-flake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml index e79040ab4..ad22120ee 100644 --- a/.github/workflows/update-flake.yml +++ b/.github/workflows/update-flake.yml @@ -12,6 +12,7 @@ permissions: jobs: update-flake: + if: github.repository == 'PrismLauncher/PrismLauncher' runs-on: ubuntu-latest steps: From 159f14c0768a1cd8ab99b8a46f2021d163e6740c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 9 Jul 2023 22:47:38 +0300 Subject: [PATCH 313/429] feat:unlocked versions page Signed-off-by: Trial97 --- launcher/ui/pages/instance/VersionPage.cpp | 315 ++++++++------------- launcher/ui/pages/instance/VersionPage.h | 55 ++-- 2 files changed, 139 insertions(+), 231 deletions(-) diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 59107c53a..7db1b19f6 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -40,14 +40,13 @@ #include "Application.h" -#include -#include +#include #include #include -#include -#include -#include +#include #include +#include +#include #include #include @@ -55,49 +54,42 @@ #include "ui_VersionPage.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/dialogs/VersionSelectDialog.h" #include "ui/dialogs/NewComponentDialog.h" #include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/VersionSelectDialog.h" #include "ui/GuiUtil.h" +#include "DesktopServices.h" +#include "Exception.h" +#include "Version.h" +#include "icons/IconList.h" #include "minecraft/PackProfile.h" #include "minecraft/auth/AccountList.h" #include "minecraft/mod/Mod.h" -#include "icons/IconList.h" -#include "Exception.h" -#include "Version.h" -#include "DesktopServices.h" #include "meta/Index.h" #include "meta/VersionList.h" -class IconProxy : public QIdentityProxyModel -{ +class IconProxy : public QIdentityProxyModel { Q_OBJECT -public: - - IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget) + public: + IconProxy(QWidget* parentWidget) : QIdentityProxyModel(parentWidget) { connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone); m_parentWidget = parentWidget; } - virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override + virtual QVariant data(const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const override { QVariant var = QIdentityProxyModel::data(proxyIndex, role); int column = proxyIndex.column(); - if(column == 0 && role == Qt::DecorationRole && m_parentWidget) - { - if(!var.isNull()) - { + if (column == 0 && role == Qt::DecorationRole && m_parentWidget) { + if (!var.isNull()) { auto string = var.toString(); - if(string == "warning") - { + if (string == "warning") { return APPLICATION->getThemedIcon("status-yellow"); - } - else if(string == "error") - { + } else if (string == "error") { return APPLICATION->getThemedIcon("status-bad"); } } @@ -105,14 +97,11 @@ public: } return var; } -private slots: - void widgetGone() - { - m_parentWidget = nullptr; - } + private slots: + void widgetGone() { m_parentWidget = nullptr; } -private: - QWidget *m_parentWidget = nullptr; + private: + QWidget* m_parentWidget = nullptr; }; QIcon VersionPage::icon() const @@ -144,15 +133,14 @@ void VersionPage::closedImpl() m_wide_bar_setting->set(ui->toolBar->getVisibilityState()); } -QMenu * VersionPage::createPopupMenu() +QMenu* VersionPage::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); - filteredMenu->removeAction( ui->toolBar->toggleViewAction() ); + filteredMenu->removeAction(ui->toolBar->toggleViewAction()); return filteredMenu; } -VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent) - : QMainWindow(parent), ui(new Ui::VersionPage), m_inst(inst) +VersionPage::VersionPage(MinecraftInstance* inst, QWidget* parent) : QMainWindow(parent), ui(new Ui::VersionPage), m_inst(inst) { ui->setupUi(this); @@ -182,10 +170,8 @@ VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent) connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent); connect(m_profile.get(), &PackProfile::minecraftChanged, this, &VersionPage::updateVersionControls); - controlsEnabled = !m_inst->isRunning(); updateVersionControls(); preselect(0); - connect(m_inst, &BaseInstance::runningStatusChanged, this, &VersionPage::updateRunningStatus); connect(ui->packageView, &ModListView::customContextMenuRequested, this, &VersionPage::showContextMenu); connect(ui->filterEdit, &QLineEdit::textChanged, this, &VersionPage::onFilterTextChanged); } @@ -202,18 +188,16 @@ void VersionPage::showContextMenu(const QPoint& pos) delete menu; } -void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex &previous) +void VersionPage::packageCurrent(const QModelIndex& current, const QModelIndex& previous) { - if (!current.isValid()) - { + if (!current.isValid()) { ui->frame->clear(); return; } int row = current.row(); auto patch = m_profile->getComponent(row); auto severity = patch->getProblemSeverity(); - switch(severity) - { + switch (severity) { case ProblemSeverity::Warning: ui->frame->setName(tr("%1 possibly has issues.").arg(patch->getName())); break; @@ -226,16 +210,12 @@ void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex & return; } - auto &problems = patch->getProblems(); + auto& problems = patch->getProblems(); QString problemOut; - for (auto &problem: problems) - { - if(problem.m_severity == ProblemSeverity::Error) - { + for (auto& problem : problems) { + if (problem.m_severity == ProblemSeverity::Error) { problemOut += tr("Error: "); - } - else if(problem.m_severity == ProblemSeverity::Warning) - { + } else if (problem.m_severity == ProblemSeverity::Warning) { problemOut += tr("Warning: "); } problemOut += problem.m_description; @@ -244,71 +224,56 @@ void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex & ui->frame->setDescription(problemOut); } -void VersionPage::updateRunningStatus(bool running) -{ - if(controlsEnabled == running) { - controlsEnabled = !running; - updateVersionControls(); - } -} - void VersionPage::updateVersionControls() { // FIXME: this is a dirty hack auto minecraftVersion = Version(m_profile->getComponentVersion("net.minecraft")); - ui->actionInstall_Forge->setEnabled(controlsEnabled); + ui->actionInstall_Forge->setEnabled(true); bool supportsFabric = minecraftVersion >= Version("1.14"); - ui->actionInstall_Fabric->setEnabled(controlsEnabled && supportsFabric); + ui->actionInstall_Fabric->setEnabled(supportsFabric); bool supportsQuilt = minecraftVersion >= Version("1.14"); - ui->actionInstall_Quilt->setEnabled(controlsEnabled && supportsQuilt); + ui->actionInstall_Quilt->setEnabled(supportsQuilt); bool supportsLiteLoader = minecraftVersion <= Version("1.12.2"); - ui->actionInstall_LiteLoader->setEnabled(controlsEnabled && supportsLiteLoader); + ui->actionInstall_LiteLoader->setEnabled(supportsLiteLoader); updateButtons(); } void VersionPage::updateButtons(int row) { - if(row == -1) + if (row == -1) row = currentRow(); auto patch = m_profile->getComponent(row); - ui->actionRemove->setEnabled(controlsEnabled && patch && patch->isRemovable()); - ui->actionMove_down->setEnabled(controlsEnabled && patch && patch->isMoveable()); - ui->actionMove_up->setEnabled(controlsEnabled && patch && patch->isMoveable()); - ui->actionChange_version->setEnabled(controlsEnabled && patch && patch->isVersionChangeable()); - ui->actionEdit->setEnabled(controlsEnabled && patch && patch->isCustom()); - ui->actionCustomize->setEnabled(controlsEnabled && patch && patch->isCustomizable()); - ui->actionRevert->setEnabled(controlsEnabled && patch && patch->isRevertible()); - ui->actionDownload_All->setEnabled(controlsEnabled); - ui->actionAdd_Empty->setEnabled(controlsEnabled); - ui->actionImport_Components->setEnabled(controlsEnabled); - ui->actionReload->setEnabled(controlsEnabled); - ui->actionReplace_Minecraft_jar->setEnabled(controlsEnabled); - ui->actionAdd_to_Minecraft_jar->setEnabled(controlsEnabled); - ui->actionAdd_Agents->setEnabled(controlsEnabled); + ui->actionRemove->setEnabled(patch && patch->isRemovable()); + ui->actionMove_down->setEnabled(patch && patch->isMoveable()); + ui->actionMove_up->setEnabled(patch && patch->isMoveable()); + ui->actionChange_version->setEnabled(patch && patch->isVersionChangeable()); + ui->actionEdit->setEnabled(patch && patch->isCustom()); + ui->actionCustomize->setEnabled(patch && patch->isCustomizable()); + ui->actionRevert->setEnabled(patch && patch->isRevertible()); + ui->actionDownload_All->setEnabled(true); + ui->actionAdd_Empty->setEnabled(true); + ui->actionImport_Components->setEnabled(true); + ui->actionReload->setEnabled(true); + ui->actionReplace_Minecraft_jar->setEnabled(true); + ui->actionAdd_to_Minecraft_jar->setEnabled(true); + ui->actionAdd_Agents->setEnabled(true); } bool VersionPage::reloadPackProfile() { - try - { + try { m_profile->reload(Net::Mode::Online); return true; - } - catch (const Exception &e) - { + } catch (const Exception& e) { QMessageBox::critical(this, tr("Error"), e.cause()); return false; - } - catch (...) - { - QMessageBox::critical( - this, tr("Error"), - tr("Couldn't load the instance profile.")); + } catch (...) { + QMessageBox::critical(this, tr("Error"), tr("Couldn't load the instance profile.")); return false; } } @@ -321,14 +286,12 @@ void VersionPage::on_actionReload_triggered() void VersionPage::on_actionRemove_triggered() { - if (!ui->packageView->currentIndex().isValid()) - { + if (!ui->packageView->currentIndex().isValid()) { return; } int index = ui->packageView->currentIndex().row(); auto component = m_profile->getComponent(index); - if (component->isCustom()) - { + if (component->isCustom()) { auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"), tr("You are about to remove \"%1\".\n" "This is permanent and will completely remove the custom component.\n\n" @@ -341,8 +304,7 @@ void VersionPage::on_actionRemove_triggered() return; } // FIXME: use actual model, not reloading. - if (!m_profile->remove(index)) - { + if (!m_profile->remove(index)) { QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file")); } updateButtons(); @@ -352,17 +314,16 @@ void VersionPage::on_actionRemove_triggered() void VersionPage::on_actionInstall_mods_triggered() { - if(m_container) - { + if (m_container) { m_container->selectPage("mods"); } } void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() { - 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()) - { + 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); } updateButtons(); @@ -370,9 +331,9 @@ 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)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); - if(!jarPath.isEmpty()) - { + 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); } updateButtons(); @@ -406,12 +367,9 @@ void VersionPage::on_actionAdd_Agents_triggered() void VersionPage::on_actionMove_up_triggered() { - try - { + try { m_profile->move(currentRow(), PackProfile::MoveUp); - } - catch (const Exception &e) - { + } catch (const Exception& e) { QMessageBox::critical(this, tr("Error"), e.cause()); } updateButtons(); @@ -419,12 +377,9 @@ void VersionPage::on_actionMove_up_triggered() void VersionPage::on_actionMove_down_triggered() { - try - { + try { m_profile->move(currentRow(), PackProfile::MoveDown); - } - catch (const Exception &e) - { + } catch (const Exception& e) { QMessageBox::critical(this, tr("Error"), e.cause()); } updateButtons(); @@ -433,39 +388,32 @@ void VersionPage::on_actionMove_down_triggered() void VersionPage::on_actionChange_version_triggered() { auto versionRow = currentRow(); - if(versionRow == -1) - { + if (versionRow == -1) { return; } auto patch = m_profile->getComponent(versionRow); auto name = patch->getName(); auto list = patch->getVersionList(); - if(!list) - { + if (!list) { return; } auto uid = list->uid(); // FIXME: this is a horrible HACK. Get version filtering information from the actual metadata... - if(uid == "net.minecraftforge") - { + if (uid == "net.minecraftforge") { on_actionInstall_Forge_triggered(); return; - } - else if (uid == "com.mumfrey.liteloader") - { + } else if (uid == "com.mumfrey.liteloader") { on_actionInstall_LiteLoader_triggered(); return; } VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this); - if (uid == "net.fabricmc.intermediary" || uid == "org.quiltmc.hashed") - { + if (uid == "net.fabricmc.intermediary" || uid == "org.quiltmc.hashed") { vselect.setEmptyString(tr("No intermediary mappings versions are currently available.")); vselect.setEmptyErrorString(tr("Couldn't load or download the intermediary mappings version lists!")); vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); } auto currentVersion = patch->getVersion(); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } if (!vselect.exec() || !vselect.selectedVersion()) @@ -473,8 +421,7 @@ void VersionPage::on_actionChange_version_triggered() qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor(); bool important = false; - if(uid == "net.minecraft") - { + if (uid == "net.minecraft") { important = true; } m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important); @@ -484,19 +431,17 @@ void VersionPage::on_actionChange_version_triggered() void VersionPage::on_actionDownload_All_triggered() { - if (!APPLICATION->accounts()->anyAccountIsValid()) - { - CustomMessageBox::selectable( - this, tr("Error"), - tr("Cannot download Minecraft or update instances unless you have at least " - "one account added.\nPlease add your Mojang or Minecraft account."), - QMessageBox::Warning)->show(); + if (!APPLICATION->accounts()->anyAccountIsValid()) { + CustomMessageBox::selectable(this, tr("Error"), + tr("Cannot download Minecraft or update instances unless you have at least " + "one account added.\nPlease add your Mojang or Minecraft account."), + QMessageBox::Warning) + ->show(); return; } auto updateTask = m_inst->createUpdateTask(Net::Mode::Online); - if (!updateTask) - { + if (!updateTask) { return; } ProgressDialog tDialog(this); @@ -510,28 +455,26 @@ void VersionPage::on_actionDownload_All_triggered() void VersionPage::on_actionInstall_Forge_triggered() { auto vlist = APPLICATION->metadataIndex()->get("net.minecraftforge"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this); vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); - vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + + m_profile->getComponentVersion("net.minecraft")); vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!")); auto currentVersion = m_profile->getComponentVersion("net.minecraftforge"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); // m_profile->installVersion(); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -539,8 +482,7 @@ void VersionPage::on_actionInstall_Forge_triggered() void VersionPage::on_actionInstall_Fabric_triggered() { auto vlist = APPLICATION->metadataIndex()->get("net.fabricmc.fabric-loader"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select Fabric Loader version"), this); @@ -548,17 +490,15 @@ void VersionPage::on_actionInstall_Fabric_triggered() vselect.setEmptyErrorString(tr("Couldn't load or download the Fabric Loader version lists!")); auto currentVersion = m_profile->getComponentVersion("net.fabricmc.fabric-loader"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("net.fabricmc.fabric-loader", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -566,8 +506,7 @@ void VersionPage::on_actionInstall_Fabric_triggered() void VersionPage::on_actionInstall_Quilt_triggered() { auto vlist = APPLICATION->metadataIndex()->get("org.quiltmc.quilt-loader"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select Quilt Loader version"), this); @@ -575,17 +514,15 @@ void VersionPage::on_actionInstall_Quilt_triggered() vselect.setEmptyErrorString(tr("Couldn't load or download the Quilt Loader version lists!")); auto currentVersion = m_profile->getComponentVersion("org.quiltmc.quilt-loader"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("org.quiltmc.quilt-loader", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -594,14 +531,12 @@ void VersionPage::on_actionAdd_Empty_triggered() { NewComponentDialog compdialog(QString(), QString(), this); QStringList blacklist; - for(int i = 0; i < m_profile->rowCount(); i++) - { + for (int i = 0; i < m_profile->rowCount(); i++) { auto comp = m_profile->getComponent(i); blacklist.push_back(comp->getID()); } compdialog.setBlacklist(blacklist); - if (compdialog.exec()) - { + if (compdialog.exec()) { qDebug() << "name:" << compdialog.name(); qDebug() << "uid:" << compdialog.uid(); m_profile->installEmpty(compdialog.uid(), compdialog.name()); @@ -611,28 +546,26 @@ void VersionPage::on_actionAdd_Empty_triggered() void VersionPage::on_actionInstall_LiteLoader_triggered() { auto vlist = APPLICATION->metadataIndex()->get("com.mumfrey.liteloader"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this); vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); - vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + + m_profile->getComponentVersion("net.minecraft")); vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!")); auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); // m_profile->installVersion(vselect.selectedVersion()); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -647,7 +580,7 @@ void VersionPage::on_actionMinecraftFolder_triggered() DesktopServices::openDirectory(m_inst->gameRoot(), true); } -void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous) +void VersionPage::versionCurrent(const QModelIndex& current, const QModelIndex& previous) { currentIdx = current.row(); updateButtons(currentIdx); @@ -655,16 +588,13 @@ void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex & void VersionPage::preselect(int row) { - if(row < 0) - { + if (row < 0) { row = 0; } - if(row >= m_profile->rowCount(QModelIndex())) - { + if (row >= m_profile->rowCount(QModelIndex())) { row = m_profile->rowCount(QModelIndex()) - 1; } - if(row < 0) - { + if (row < 0) { return; } auto model_index = m_profile->index(row); @@ -680,8 +610,7 @@ void VersionPage::onGameUpdateError(QString error) ComponentPtr VersionPage::current() { auto row = currentRow(); - if(row < 0) - { + if (row < 0) { return nullptr; } return m_profile->getComponent(row); @@ -689,8 +618,7 @@ ComponentPtr VersionPage::current() int VersionPage::currentRow() { - if (ui->packageView->selectionModel()->selectedRows().isEmpty()) - { + if (ui->packageView->selectionModel()->selectedRows().isEmpty()) { return -1; } return ui->packageView->selectionModel()->selectedRows().first().row(); @@ -699,18 +627,15 @@ int VersionPage::currentRow() void VersionPage::on_actionCustomize_triggered() { auto version = currentRow(); - if(version == -1) - { + if (version == -1) { return; } auto patch = m_profile->getComponent(version); - if(!patch->getVersionFile()) - { + if (!patch->getVersionFile()) { // TODO: wait for the update task to finish here... return; } - if(!m_profile->customize(version)) - { + if (!m_profile->customize(version)) { // TODO: some error box here } updateButtons(); @@ -720,13 +645,11 @@ void VersionPage::on_actionCustomize_triggered() void VersionPage::on_actionEdit_triggered() { auto version = current(); - if(!version) - { + if (!version) { return; } auto filename = version->getFilename(); - if(!QFileInfo::exists(filename)) - { + if (!QFileInfo::exists(filename)) { qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!"; return; } @@ -736,8 +659,7 @@ void VersionPage::on_actionEdit_triggered() void VersionPage::on_actionRevert_triggered() { auto version = currentRow(); - if(version == -1) - { + if (version == -1) { return; } auto component = m_profile->getComponent(version); @@ -753,8 +675,7 @@ void VersionPage::on_actionRevert_triggered() if (response != QMessageBox::Yes) return; - if(!m_profile->revertToBase(version)) - { + if (!m_profile->revertToBase(version)) { // TODO: some error box here } updateButtons(); @@ -762,7 +683,7 @@ void VersionPage::on_actionRevert_triggered() m_container->refreshContainer(); } -void VersionPage::onFilterTextChanged(const QString &newContents) +void VersionPage::onFilterTextChanged(const QString& newContents) { m_filterModel->setFilterFixedString(newContents); } diff --git a/launcher/ui/pages/instance/VersionPage.h b/launcher/ui/pages/instance/VersionPage.h index d00877142..45d383f41 100644 --- a/launcher/ui/pages/instance/VersionPage.h +++ b/launcher/ui/pages/instance/VersionPage.h @@ -46,38 +46,27 @@ #include "minecraft/PackProfile.h" #include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class VersionPage; } -class VersionPage : public QMainWindow, public BasePage -{ +class VersionPage : public QMainWindow, public BasePage { Q_OBJECT -public: - explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0); + public: + explicit VersionPage(MinecraftInstance* inst, QWidget* parent = 0); virtual ~VersionPage(); - virtual QString displayName() const override - { - return tr("Version"); - } + virtual QString displayName() const override { return tr("Version"); } virtual QIcon icon() const override; - virtual QString id() const override - { - return "version"; - } - virtual QString helpPage() const override - { - return "Instance-Version"; - } + virtual QString id() const override { return "version"; } + virtual QString helpPage() const override { return "Instance-Version"; } virtual bool shouldDisplay() const override; void retranslate() override; void openedImpl() override; void closedImpl() override; -private slots: + private slots: void on_actionChange_version_triggered(); void on_actionInstall_Forge_triggered(); void on_actionInstall_Fabric_triggered(); @@ -103,36 +92,34 @@ private slots: void updateVersionControls(); -private: + private: ComponentPtr current(); int currentRow(); void updateButtons(int row = -1); void preselect(int row = 0); int doUpdate(); -protected: - QMenu * createPopupMenu() override; + protected: + QMenu* createPopupMenu() override; /// FIXME: this shouldn't be necessary! bool reloadPackProfile(); -private: - Ui::VersionPage *ui; - QSortFilterProxyModel *m_filterModel; + private: + Ui::VersionPage* ui; + QSortFilterProxyModel* m_filterModel; std::shared_ptr m_profile; - MinecraftInstance *m_inst; + MinecraftInstance* m_inst; int currentIdx = 0; - bool controlsEnabled = false; std::shared_ptr m_wide_bar_setting = nullptr; -public slots: - void versionCurrent(const QModelIndex ¤t, const QModelIndex &previous); + public slots: + void versionCurrent(const QModelIndex& current, const QModelIndex& previous); -private slots: - void updateRunningStatus(bool running); + private slots: void onGameUpdateError(QString error); - void packageCurrent(const QModelIndex ¤t, const QModelIndex &previous); - void showContextMenu(const QPoint &pos); - void onFilterTextChanged(const QString & newContents); + void packageCurrent(const QModelIndex& current, const QModelIndex& previous); + void showContextMenu(const QPoint& pos); + void onFilterTextChanged(const QString& newContents); }; From 308877aa8f105de408c4c8fe87d3476116b23cf4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 9 Jul 2023 23:18:38 +0300 Subject: [PATCH 314/429] removed redundant code Signed-off-by: Trial97 --- launcher/ui/pages/instance/VersionPage.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 7db1b19f6..a180c8041 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -229,8 +229,6 @@ void VersionPage::updateVersionControls() // FIXME: this is a dirty hack auto minecraftVersion = Version(m_profile->getComponentVersion("net.minecraft")); - ui->actionInstall_Forge->setEnabled(true); - bool supportsFabric = minecraftVersion >= Version("1.14"); ui->actionInstall_Fabric->setEnabled(supportsFabric); @@ -255,13 +253,6 @@ void VersionPage::updateButtons(int row) ui->actionEdit->setEnabled(patch && patch->isCustom()); ui->actionCustomize->setEnabled(patch && patch->isCustomizable()); ui->actionRevert->setEnabled(patch && patch->isRevertible()); - ui->actionDownload_All->setEnabled(true); - ui->actionAdd_Empty->setEnabled(true); - ui->actionImport_Components->setEnabled(true); - ui->actionReload->setEnabled(true); - ui->actionReplace_Minecraft_jar->setEnabled(true); - ui->actionAdd_to_Minecraft_jar->setEnabled(true); - ui->actionAdd_Agents->setEnabled(true); } bool VersionPage::reloadPackProfile() From e21756ea8c35d04d78046fea44ac5e52f069f699 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 10 Jul 2023 16:10:58 +0100 Subject: [PATCH 315/429] Remove direct launch Signed-off-by: TheKodeToad --- launcher/Application.cpp | 3 - launcher/CMakeLists.txt | 2 - launcher/minecraft/MinecraftInstance.cpp | 41 +---- launcher/minecraft/MinecraftInstance.h | 2 - .../minecraft/launch/DirectJavaLaunch.cpp | 166 ------------------ launcher/minecraft/launch/DirectJavaLaunch.h | 58 ------ 6 files changed, 5 insertions(+), 267 deletions(-) delete mode 100644 launcher/minecraft/launch/DirectJavaLaunch.cpp delete mode 100644 launcher/minecraft/launch/DirectJavaLaunch.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 7858d7132..aa0eeb8e3 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -618,9 +618,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("ShowGlobalGameTime", true); m_settings->registerSetting("RecordGameTime", true); - // Minecraft launch method - m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); - // Minecraft mods m_settings->registerSetting("ModMetadataDisabled", false); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index af3bc28e3..0bf60dc78 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -262,8 +262,6 @@ set(MINECRAFT_SOURCES minecraft/launch/CreateGameFolders.h minecraft/launch/ModMinecraftJar.cpp minecraft/launch/ModMinecraftJar.h - minecraft/launch/DirectJavaLaunch.cpp - minecraft/launch/DirectJavaLaunch.h minecraft/launch/ExtractNatives.cpp minecraft/launch/ExtractNatives.h minecraft/launch/LauncherPartLaunch.cpp diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 4867cc7a3..2796872a9 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -60,7 +60,6 @@ #include "launch/steps/QuitAfterGameStop.h" #include "minecraft/launch/LauncherPartLaunch.h" -#include "minecraft/launch/DirectJavaLaunch.h" #include "minecraft/launch/ModMinecraftJar.h" #include "minecraft/launch/ClaimAccount.h" #include "minecraft/launch/ReconstructAssets.h" @@ -166,10 +165,6 @@ void MinecraftInstance::loadSpecificSettings() m_settings->registerOverride(global_settings->getSetting("MaxMemAlloc"), memorySetting); m_settings->registerOverride(global_settings->getSetting("PermGen"), memorySetting); - // Minecraft launch method - auto launchMethodOverride = m_settings->registerSetting("OverrideMCLaunchMethod", false); - m_settings->registerOverride(global_settings->getSetting("MCLaunchMethod"), launchMethodOverride); - // Native library workarounds auto nativeLibraryWorkaroundsOverride = m_settings->registerSetting("OverrideNativeWorkarounds", false); m_settings->registerOverride(global_settings->getSetting("UseNativeOpenAL"), nativeLibraryWorkaroundsOverride); @@ -979,15 +974,6 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt process->appendStep(makeShared(pptr)); } - // check launch method - QStringList validMethods = {"LauncherPart", "DirectJava"}; - QString method = launchMethod(); - if(!validMethods.contains(method)) - { - process->appendStep(makeShared(pptr, "Selected launch method \"" + method + "\" is not valid.\n", MessageLevel::Fatal)); - return process; - } - // create the .minecraft folder and server-resource-packs (workaround for Minecraft bug MCL-3732) { process->appendStep(makeShared(pptr)); @@ -1061,23 +1047,11 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt { // actually launch the game - auto method = launchMethod(); - if(method == "LauncherPart") - { - auto step = makeShared(pptr); - step->setWorkingDirectory(gameRoot()); - step->setAuthSession(session); - step->setServerToJoin(serverToJoin); - process->appendStep(step); - } - else if (method == "DirectJava") - { - auto step = makeShared(pptr); - step->setWorkingDirectory(gameRoot()); - step->setAuthSession(session); - step->setServerToJoin(serverToJoin); - process->appendStep(step); - } + auto step = makeShared(pptr); + step->setWorkingDirectory(gameRoot()); + step->setAuthSession(session); + step->setServerToJoin(serverToJoin); + process->appendStep(step); } // run post-exit command if that's needed @@ -1100,11 +1074,6 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt return m_launchProcess; } -QString MinecraftInstance::launchMethod() -{ - return settings()->get("MCLaunchMethod").toString(); -} - JavaVersion MinecraftInstance::getJavaVersion() { return JavaVersion(settings()->get("JavaVersion").toString()); diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 068b30082..4afcf04b8 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -165,8 +165,6 @@ public: protected: QMap createCensorFilterFromSession(AuthSessionPtr session); - QStringList validLaunchMethods(); - QString launchMethod(); protected: // data std::shared_ptr m_components; diff --git a/launcher/minecraft/launch/DirectJavaLaunch.cpp b/launcher/minecraft/launch/DirectJavaLaunch.cpp deleted file mode 100644 index ca55cd2ed..000000000 --- a/launcher/minecraft/launch/DirectJavaLaunch.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* 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 "DirectJavaLaunch.h" - -#include - -#include -#include -#include -#include - -#include "Application.h" - -#ifdef Q_OS_LINUX -#include "gamemode_client.h" -#endif - -DirectJavaLaunch::DirectJavaLaunch(LaunchTask *parent) : LaunchStep(parent) -{ - connect(&m_process, &LoggedProcess::log, this, &DirectJavaLaunch::logLines); - connect(&m_process, &LoggedProcess::stateChanged, this, &DirectJavaLaunch::on_state); -} - -void DirectJavaLaunch::executeTask() -{ - auto instance = m_parent->instance(); - std::shared_ptr minecraftInstance = std::dynamic_pointer_cast(instance); - QStringList args = minecraftInstance->javaArguments(); - - args.append("-Djava.library.path=" + minecraftInstance->getNativePath()); - - auto classPathEntries = minecraftInstance->getClassPath(); - args.append("-cp"); - QString classpath; -#ifdef Q_OS_WIN32 - classpath = classPathEntries.join(';'); -#else - classpath = classPathEntries.join(':'); -#endif - args.append(classpath); - args.append(minecraftInstance->getMainClass()); - - QString allArgs = args.join(", "); - emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::Launcher); - - auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString()); - - m_process.setProcessEnvironment(instance->createLaunchEnvironment()); - - // make detachable - this will keep the process running even if the object is destroyed - m_process.setDetachable(true); - - auto mcArgs = minecraftInstance->processMinecraftArgs(m_session, m_serverToJoin); - args.append(mcArgs); - - QString wrapperCommandStr = instance->getWrapperCommand().trimmed(); - if(!wrapperCommandStr.isEmpty()) - { - auto wrapperArgs = Commandline::splitArgs(wrapperCommandStr); - auto wrapperCommand = wrapperArgs.takeFirst(); - auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand); - if (realWrapperCommand.isEmpty()) - { - const char *reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); - emit logLine(QString(reason).arg(wrapperCommand), MessageLevel::Fatal); - emitFailed(tr(reason).arg(wrapperCommand)); - return; - } - emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::Launcher); - args.prepend(javaPath); - m_process.start(wrapperCommand, wrapperArgs + args); - } - else - { - m_process.start(javaPath, args); - } - -#ifdef Q_OS_LINUX - if (instance->settings()->get("EnableFeralGamemode").toBool() && APPLICATION->capabilities() & Application::SupportsGameMode) - { - auto pid = m_process.processId(); - if (pid) - { - gamemode_request_start_for(pid); - } - } -#endif -} - -void DirectJavaLaunch::on_state(LoggedProcess::State state) -{ - switch(state) - { - case LoggedProcess::FailedToStart: - { - //: Error message displayed if instance can't start - const char *reason = QT_TR_NOOP("Could not launch Minecraft!"); - emit logLine(reason, MessageLevel::Fatal); - emitFailed(tr(reason)); - return; - } - case LoggedProcess::Aborted: - case LoggedProcess::Crashed: - { - m_parent->setPid(-1); - emitFailed(tr("Game crashed.")); - return; - } - case LoggedProcess::Finished: - { - m_parent->setPid(-1); - // if the exit code wasn't 0, report this as a crash - auto exitCode = m_process.exitCode(); - if(exitCode != 0) - { - emitFailed(tr("Game crashed.")); - return; - } - //FIXME: make this work again - // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode)); - // run post-exit - emitSucceeded(); - break; - } - 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(); - break; - default: - break; - } -} - -void DirectJavaLaunch::setWorkingDirectory(const QString &wd) -{ - m_process.setWorkingDirectory(wd); -} - -void DirectJavaLaunch::proceed() -{ - // nil -} - -bool DirectJavaLaunch::abort() -{ - auto state = m_process.state(); - if (state == LoggedProcess::Running || state == LoggedProcess::Starting) - { - m_process.kill(); - } - return true; -} - diff --git a/launcher/minecraft/launch/DirectJavaLaunch.h b/launcher/minecraft/launch/DirectJavaLaunch.h deleted file mode 100644 index 58b119b8c..000000000 --- a/launcher/minecraft/launch/DirectJavaLaunch.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 -#include -#include - -#include "MinecraftServerTarget.h" - -class DirectJavaLaunch: public LaunchStep -{ - Q_OBJECT -public: - explicit DirectJavaLaunch(LaunchTask *parent); - virtual ~DirectJavaLaunch() {}; - - virtual void executeTask(); - virtual bool abort(); - virtual void proceed(); - virtual bool canAbort() const - { - return true; - } - void setWorkingDirectory(const QString &wd); - void setAuthSession(AuthSessionPtr session) - { - m_session = session; - } - - void setServerToJoin(MinecraftServerTargetPtr serverToJoin) - { - m_serverToJoin = std::move(serverToJoin); - } - -private slots: - void on_state(LoggedProcess::State state); - -private: - LoggedProcess m_process; - QString m_command; - AuthSessionPtr m_session; - MinecraftServerTargetPtr m_serverToJoin; -}; - From 99ba02afb6a7af1bc0800552338ab811b027eb9e Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 10 Jul 2023 11:26:25 -0700 Subject: [PATCH 316/429] Shortcuts on macOS (#1081) Co-authored-by: TheKodeToad --- launcher/FileSystem.cpp | 60 ++++++++++++++++++++++++++++++++++++-- launcher/ui/MainWindow.cpp | 44 ++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 812d45eb5..4538702f2 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -778,9 +778,43 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); } #if defined(Q_OS_MACOS) - destination += ".command"; + // Create the Application + QDir applicationDirectory = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/"; - QFile f(destination); + if (!applicationDirectory.mkpath(".")) { + qWarning() << "Couldn't create application directory"; + return false; + } + + QDir application = applicationDirectory.path() + "/" + name + ".app/"; + + if (application.exists()) { + qWarning() << "Application already exists!"; + return false; + } + + if (!application.mkpath(".")) { + qWarning() << "Couldn't create application"; + return false; + } + + QDir content = application.path() + "/Contents/"; + QDir resources = content.path() + "/Resources/"; + QDir binaryDir = content.path() + "/MacOS/"; + QFile info = content.path() + "/Info.plist"; + + if (!(content.mkpath(".") && resources.mkpath(".") && binaryDir.mkpath("."))) { + qWarning() << "Couldn't create directories within application"; + return false; + } + info.open(QIODevice::WriteOnly | QIODevice::Text); + + QFile(icon).rename(resources.path() + "/Icon.icns"); + + // Create the Command file + QString exec = binaryDir.path() + "/Run.command"; + + QFile f(exec); f.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&f); @@ -797,6 +831,28 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther); + // Generate the Info.plist + QTextStream infoStream(&info); + infoStream << " \n" + "" + "\n" + "\n" + " CFBundleExecutable\n" + " Run.command\n" // The path to the executable + " CFBundleIconFile\n" + " Icon.icns\n" + " CFBundleName\n" + " " << name << "\n" // Name of the application + " CFBundlePackageType\n" + " APPL\n" + " CFBundleShortVersionString\n" + " 1.0\n" + " CFBundleVersion\n" + " 1.0\n" + "\n" + ""; + return true; #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 2f944472e..fe3649379 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1536,11 +1536,39 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() QString iconPath; QStringList args; #if defined(Q_OS_MACOS) - if (appPath.startsWith("/private/var/")) { - QMessageBox::critical(this, tr("Create instance shortcut"), - tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); - return; - } + appPath = QApplication::applicationFilePath(); + if (appPath.startsWith("/private/var/")) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); + return; + } + + auto pIcon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (pIcon == nullptr) + { + pIcon = APPLICATION->icons()->icon("grass"); + } + + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "Icon.icns"); + + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) + { + QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application.")); + return; + } + + QIcon icon = pIcon->icon(); + + bool success = icon.pixmap(1024, 1024).save(iconPath, "ICNS"); + iconFile.close(); + + if (!success) + { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application.")); + return; + } #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) if (appPath.startsWith("/tmp/.mount_")) { // AppImage! @@ -1623,7 +1651,11 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() #endif args.append({ "--launch", m_selectedInstance->id() }); if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); +#if not defined(Q_OS_MACOS) + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); +#else + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!")); +#endif } else { #if not defined(Q_OS_MACOS) iconFile.remove(); From 1aa5fa03f94438ce53899e4660f12e794fd8bc35 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 10 Jul 2023 12:05:01 -0700 Subject: [PATCH 317/429] Update launcher/ui/MainWindow.cpp Co-authored-by: TheKodeToad Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 254f229da..5a8fcc78f 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1287,7 +1287,7 @@ void MainWindow::on_actionEditInstance_triggered() APPLICATION->showInstanceWindow(m_selectedInstance); } else { CustomMessageBox::selectable(this, tr("Instance not editable"), - tr("This instance is not editable. it may be broken, invalid, or too old. Check logs for details,"), + tr("This instance is not editable. It may be broken, invalid, or too old. Check logs for details."), QMessageBox::Critical)->show(); } } From f0d2aab784fd0ff0fc495d5f0c44715887741eb1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 11 Jul 2023 18:05:43 +0300 Subject: [PATCH 318/429] feat:Added option to use system locale Signed-off-by: Trial97 --- launcher/Application.cpp | 8 ++--- launcher/translations/TranslationsModel.cpp | 29 ++++++++++--------- launcher/translations/TranslationsModel.h | 29 +++++++++---------- .../ui/widgets/LanguageSelectionWidget.cpp | 28 +++++++++++------- launcher/ui/widgets/LanguageSelectionWidget.h | 25 ++++++++-------- 5 files changed, 61 insertions(+), 58 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 7858d7132..86005ef79 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -568,6 +568,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Language m_settings->registerSetting("Language", QString()); + m_settings->registerSetting("UseSystemLocales", false); // Console m_settings->registerSetting("ShowConsole", false); @@ -918,12 +919,7 @@ bool Application::createSetupWizard() } return false; }(); - bool languageRequired = [&]() - { - if (settings()->get("Language").toString().isEmpty()) - return true; - return false; - }(); + bool languageRequired = settings()->get("Language").toString().isEmpty(); bool pasteInterventionRequired = settings()->get("PastebinURL") != ""; bool themeInterventionRequired = settings()->get("ApplicationTheme") == ""; bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired; diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 489dff86d..838155a49 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -527,34 +527,34 @@ Language * TranslationsModel::findLanguage(const QString& key) } } +void TranslationsModel::setUseSystemLocale(bool useSystemLocale) +{ + APPLICATION->settings()->set("UseSystemLocales", useSystemLocale); + QLocale::setDefault(QLocale(useSystemLocale ? QString::fromStdString(std::locale().name()) : defaultLangCode)); +} + bool TranslationsModel::selectLanguage(QString key) { - QString &langCode = key; + QString& langCode = key; auto langPtr = findLanguage(key); - if (langCode.isEmpty()) - { + if (langCode.isEmpty()) { d->no_language_set = true; } - if(!langPtr) - { + if (!langPtr) { qWarning() << "Selected invalid language" << key << ", defaulting to" << defaultLangCode; langCode = defaultLangCode; - } - else - { + } else { langCode = langPtr->key; } // uninstall existing translators if there are any - if (d->m_app_translator) - { + if (d->m_app_translator) { QCoreApplication::removeTranslator(d->m_app_translator.get()); d->m_app_translator.reset(); } - if (d->m_qt_translator) - { + if (d->m_qt_translator) { QCoreApplication::removeTranslator(d->m_qt_translator.get()); d->m_qt_translator.reset(); } @@ -564,8 +564,9 @@ bool TranslationsModel::selectLanguage(QString key) * In a multithreaded application, the default locale should be set at application startup, before any non-GUI threads are created. * This function is not reentrant. */ - QLocale locale = QLocale(langCode); - QLocale::setDefault(locale); + QLocale::setDefault( + QLocale(APPLICATION->settings()->get("UseSystemLocales").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); + // if it's the default UI language, finish if(langCode == defaultLangCode) diff --git a/launcher/translations/TranslationsModel.h b/launcher/translations/TranslationsModel.h index 3abf84e6e..cff23ce74 100644 --- a/launcher/translations/TranslationsModel.h +++ b/launcher/translations/TranslationsModel.h @@ -20,17 +20,16 @@ struct Language; -class TranslationsModel : public QAbstractListModel -{ +class TranslationsModel : public QAbstractListModel { Q_OBJECT -public: - explicit TranslationsModel(QString path, QObject *parent = 0); + public: + explicit TranslationsModel(QString path, QObject* parent = 0); virtual ~TranslationsModel(); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex & parent) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent) const override; bool selectLanguage(QString key); void updateLanguage(QString key); @@ -38,27 +37,27 @@ public: QString selectedLanguage(); void downloadIndex(); + void setUseSystemLocale(bool useSystemLocale); -private: - Language *findLanguage(const QString & key); + private: + Language* findLanguage(const QString& key); void reloadLocalFiles(); void downloadTranslation(QString key); void downloadNext(); // hide copy constructor - TranslationsModel(const TranslationsModel &) = delete; + TranslationsModel(const TranslationsModel&) = delete; // hide assign op - TranslationsModel &operator=(const TranslationsModel &) = delete; + TranslationsModel& operator=(const TranslationsModel&) = delete; -private slots: + private slots: void indexReceived(); void indexFailed(QString reason); void dlFailed(QString reason); void dlGood(); - void translationDirChanged(const QString &path); + void translationDirChanged(const QString& path); - -private: /* data */ + private: /* data */ struct Private; std::unique_ptr d; }; diff --git a/launcher/ui/widgets/LanguageSelectionWidget.cpp b/launcher/ui/widgets/LanguageSelectionWidget.cpp index 256b09dad..8b95999d2 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.cpp +++ b/launcher/ui/widgets/LanguageSelectionWidget.cpp @@ -1,16 +1,16 @@ #include "LanguageSelectionWidget.h" -#include -#include +#include #include #include +#include +#include #include "Application.h" #include "BuildConfig.h" -#include "translations/TranslationsModel.h" #include "settings/Setting.h" +#include "translations/TranslationsModel.h" -LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : - QWidget(parent) +LanguageSelectionWidget::LanguageSelectionWidget(QWidget* parent) : QWidget(parent) { verticalLayout = new QVBoxLayout(this); verticalLayout->setObjectName(QStringLiteral("verticalLayout")); @@ -31,6 +31,13 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : helpUsLabel->setWordWrap(true); verticalLayout->addWidget(helpUsLabel); + formatCheckbox = new QCheckBox(this); + formatCheckbox->setObjectName(QStringLiteral("formatCheckbox")); + formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocales").toBool() ? Qt::Checked : Qt::Unchecked); + connect(formatCheckbox, &QCheckBox::stateChanged, + [this]() { APPLICATION->translations()->setUseSystemLocale(formatCheckbox->isChecked()); }); + verticalLayout->addWidget(formatCheckbox); + auto translations = APPLICATION->translations(); auto index = translations->selectedIndex(); languageView->setModel(translations.get()); @@ -38,7 +45,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : languageView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); languageView->header()->setSectionResizeMode(0, QHeaderView::Stretch); connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageSelectionWidget::languageRowChanged); - verticalLayout->setContentsMargins(0,0,0,0); + verticalLayout->setContentsMargins(0, 0, 0, 0); auto language_setting = APPLICATION->settings()->getSetting("Language"); connect(language_setting.get(), &Setting::SettingChanged, this, &LanguageSelectionWidget::languageSettingChanged); @@ -53,15 +60,14 @@ QString LanguageSelectionWidget::getSelectedLanguageKey() const void LanguageSelectionWidget::retranslate() { QString text = tr("Don't see your language or the quality is poor?
    Help us with translations!") - .arg(BuildConfig.TRANSLATIONS_URL); + .arg(BuildConfig.TRANSLATIONS_URL); helpUsLabel->setText(text); - + formatCheckbox->setText(tr("Use system locales")); } void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, const QModelIndex& previous) { - if (current == previous) - { + if (current == previous) { return; } auto translations = APPLICATION->translations(); @@ -70,7 +76,7 @@ void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, con translations->updateLanguage(key); } -void LanguageSelectionWidget::languageSettingChanged(const Setting &, const QVariant) +void LanguageSelectionWidget::languageSettingChanged(const Setting&, const QVariant) { auto translations = APPLICATION->translations(); auto index = translations->selectedIndex(); diff --git a/launcher/ui/widgets/LanguageSelectionWidget.h b/launcher/ui/widgets/LanguageSelectionWidget.h index 4a88924c4..5e86a288f 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.h +++ b/launcher/ui/widgets/LanguageSelectionWidget.h @@ -21,23 +21,24 @@ class QVBoxLayout; class QTreeView; class QLabel; class Setting; +class QCheckBox; -class LanguageSelectionWidget: public QWidget -{ +class LanguageSelectionWidget : public QWidget { Q_OBJECT -public: - explicit LanguageSelectionWidget(QWidget *parent = 0); - virtual ~LanguageSelectionWidget() { }; + public: + explicit LanguageSelectionWidget(QWidget* parent = 0); + virtual ~LanguageSelectionWidget(){}; QString getSelectedLanguageKey() const; void retranslate(); -protected slots: - void languageRowChanged(const QModelIndex ¤t, const QModelIndex &previous); - void languageSettingChanged(const Setting &, const QVariant); + protected slots: + void languageRowChanged(const QModelIndex& current, const QModelIndex& previous); + void languageSettingChanged(const Setting&, const QVariant); -private: - QVBoxLayout *verticalLayout = nullptr; - QTreeView *languageView = nullptr; - QLabel *helpUsLabel = nullptr; + private: + QVBoxLayout* verticalLayout = nullptr; + QTreeView* languageView = nullptr; + QLabel* helpUsLabel = nullptr; + QCheckBox* formatCheckbox = nullptr; }; From 634612ae816f2c8687efa43aa204b361dc0bc274 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 11 Jul 2023 18:20:44 +0300 Subject: [PATCH 319/429] added missing header Signed-off-by: Trial97 --- launcher/translations/TranslationsModel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 838155a49..e6bc06a64 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include "FileSystem.h" #include "net/NetJob.h" From 766e833a7386c9b027c02687ce345b985b4a256d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 16:25:05 +0300 Subject: [PATCH 320/429] fixed crash if no version is loaded Signed-off-by: Trial97 --- .../ui/pages/instance/ManagedPackPage.cpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index d89c5bfc0..0fc0c9867 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -69,7 +69,6 @@ class NoBigComboBoxStyle : public QProxyStyle { private: NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {} - }; ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent) @@ -91,13 +90,13 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi // NOTE: GTK2 themes crash with the proxy style. // This seems like an upstream bug, so there's not much else that can be done. - if (!QStyleFactory::keys().contains("gtk2")){ + if (!QStyleFactory::keys().contains("gtk2")) { auto comboStyle = NoBigComboBoxStyle::getInstance(ui->versionsComboBox->style()); ui->versionsComboBox->setStyle(comboStyle); } ui->reloadButton->setVisible(false); - connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool){ + connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool) { ui->reloadButton->setVisible(false); m_loaded = false; @@ -226,7 +225,8 @@ void ModrinthManagedPackPage::parseManagedPack() QString id = m_inst->getManagedPackID(); - m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response)); + m_fetch_job->addNetAction( + Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response)); QObject::connect(m_fetch_job.get(), &NetJob::succeeded, this, [this, response, id] { QJsonParseError parse_error{}; @@ -267,7 +267,6 @@ void ModrinthManagedPackPage::parseManagedPack() if (version.version == m_inst->getManagedPackVersionName()) name = tr("%1 (Current)").arg(name); - ui->versionsComboBox->addItem(name, QVariant(version.id)); } @@ -291,6 +290,10 @@ QString ModrinthManagedPackPage::url() const void ModrinthManagedPackPage::suggestVersion() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); ui->changelogTextBrowser->setHtml(markdownToHTML(version.changelog.toUtf8())); @@ -301,6 +304,10 @@ void ModrinthManagedPackPage::suggestVersion() void ModrinthManagedPackPage::update() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); QMap extra_info; @@ -429,6 +436,10 @@ QString FlameManagedPackPage::url() const void FlameManagedPackPage::suggestVersion() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); ui->changelogTextBrowser->setHtml(m_api.getModFileChangelog(m_inst->getManagedPackID().toInt(), version.fileId)); @@ -439,6 +450,10 @@ void FlameManagedPackPage::suggestVersion() void FlameManagedPackPage::update() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); QMap extra_info; From 9ee68b926829495b4b87e7044bd31352ef6a6a84 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 18:12:31 +0300 Subject: [PATCH 321/429] small pointer check Signed-off-by: Trial97 --- launcher/modplatform/EnsureMetadataTask.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index 93b5ce76c..d76497007 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -154,7 +154,8 @@ void EnsureMetadataTask::executeTask() connect(version_task.get(), &Task::finished, [=] { version_task->deleteLater(); - m_current_task = nullptr; + if (m_current_task) + m_current_task.reset(); }); if (m_mods.size() > 1) From 25f7cf23d3572e444617c347ade71fffddd8af8b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 19:55:11 +0300 Subject: [PATCH 322/429] the other place Signed-off-by: Trial97 --- launcher/modplatform/EnsureMetadataTask.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index d76497007..c3eadd06d 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -145,7 +145,8 @@ void EnsureMetadataTask::executeTask() connect(project_task.get(), &Task::finished, this, [=] { invalidade_leftover(); project_task->deleteLater(); - m_current_task = nullptr; + if (m_current_task) + m_current_task.reset(); }); m_current_task = project_task; From 76cc8ce0437b7047ee984993daab57b2605f52a6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 21:05:13 +0300 Subject: [PATCH 323/429] renamed setting Signed-off-by: Trial97 --- launcher/Application.cpp | 2 +- launcher/translations/TranslationsModel.cpp | 4 ++-- launcher/ui/widgets/LanguageSelectionWidget.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 86005ef79..5aa9efc4a 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -568,7 +568,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Language m_settings->registerSetting("Language", QString()); - m_settings->registerSetting("UseSystemLocales", false); + m_settings->registerSetting("UseSystemLocale", false); // Console m_settings->registerSetting("ShowConsole", false); diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index e6bc06a64..2763cca26 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -530,7 +530,7 @@ Language * TranslationsModel::findLanguage(const QString& key) void TranslationsModel::setUseSystemLocale(bool useSystemLocale) { - APPLICATION->settings()->set("UseSystemLocales", useSystemLocale); + APPLICATION->settings()->set("UseSystemLocale", useSystemLocale); QLocale::setDefault(QLocale(useSystemLocale ? QString::fromStdString(std::locale().name()) : defaultLangCode)); } @@ -566,7 +566,7 @@ bool TranslationsModel::selectLanguage(QString key) * This function is not reentrant. */ QLocale::setDefault( - QLocale(APPLICATION->settings()->get("UseSystemLocales").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); + QLocale(APPLICATION->settings()->get("UseSystemLocale").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); // if it's the default UI language, finish diff --git a/launcher/ui/widgets/LanguageSelectionWidget.cpp b/launcher/ui/widgets/LanguageSelectionWidget.cpp index 8b95999d2..37d053478 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.cpp +++ b/launcher/ui/widgets/LanguageSelectionWidget.cpp @@ -33,7 +33,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget* parent) : QWidget(pare formatCheckbox = new QCheckBox(this); formatCheckbox->setObjectName(QStringLiteral("formatCheckbox")); - formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocales").toBool() ? Qt::Checked : Qt::Unchecked); + formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocale").toBool() ? Qt::Checked : Qt::Unchecked); connect(formatCheckbox, &QCheckBox::stateChanged, [this]() { APPLICATION->translations()->setUseSystemLocale(formatCheckbox->isChecked()); }); verticalLayout->addWidget(formatCheckbox); From 89aaedc06c3eb7a035d8be593a7bbe417cb2f712 Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 12 Jul 2023 21:10:48 -0400 Subject: [PATCH 324/429] feat: add toggle for quilt beacon Signed-off-by: seth --- launcher/Application.cpp | 4 ++++ launcher/minecraft/MinecraftInstance.cpp | 10 ++++++++- launcher/ui/pages/global/MinecraftPage.cpp | 6 +++++ launcher/ui/pages/global/MinecraftPage.ui | 16 ++++++++++++++ .../pages/instance/InstanceSettingsPage.cpp | 15 ++++++++++++- .../ui/pages/instance/InstanceSettingsPage.ui | 22 +++++++++++++++++++ 6 files changed, 71 insertions(+), 2 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5aa9efc4a..f98594292 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -9,6 +9,7 @@ * Copyright (C) 2022 Tayou * Copyright (C) 2023 TheKodeToad * Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * Copyright (C) 2023 seth * * 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 @@ -605,6 +606,9 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("IgnoreJavaCompatibility", false); m_settings->registerSetting("IgnoreJavaWizard", false); + // Mod loader settings + m_settings->registerSetting("DisableQuiltBeacon", false); + // Native library workarounds m_settings->registerSetting("UseNativeOpenAL", false); m_settings->registerSetting("UseNativeGLFW", false); diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 4867cc7a3..180838ad2 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -3,7 +3,8 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Jamie Mansfield - * Copyright (C) 2022 TheKodeToad + * Copyright (C) 2022 TheKodeToad \ + * Copyright (c) 2023 seth * * 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 @@ -186,6 +187,10 @@ void MinecraftInstance::loadSpecificSettings() m_settings->registerOverride(global_settings->getSetting("CloseAfterLaunch"), miscellaneousOverride); m_settings->registerOverride(global_settings->getSetting("QuitAfterGameStop"), miscellaneousOverride); + // Mod loader specific options + auto modLoaderSettings = m_settings->registerSetting("OverrideModLoaderSettings", false); + m_settings->registerOverride(global_settings->getSetting("DisableQuiltBeacon"), modLoaderSettings); + m_settings->set("InstanceType", "OneSix"); } @@ -391,6 +396,9 @@ QStringList MinecraftInstance::extraArguments() agent->library()->getApplicableFiles(runtimeContext(), jar, temp1, temp2, temp3, getLocalLibraryPath()); list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument())); } + if (version->getModLoaders().value() & ResourceAPI::Quilt && settings()->get("DisableQuiltBeacon").toBool()) { + list.append("-Dloader.disable_beacon=true"); + } return list; } diff --git a/launcher/ui/pages/global/MinecraftPage.cpp b/launcher/ui/pages/global/MinecraftPage.cpp index eca3e8657..954823564 100644 --- a/launcher/ui/pages/global/MinecraftPage.cpp +++ b/launcher/ui/pages/global/MinecraftPage.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield + * Copyright (C) 2023 seth * * 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 @@ -99,6 +100,9 @@ void MinecraftPage::applySettings() // Miscellaneous s->set("CloseAfterLaunch", ui->closeAfterLaunchCheck->isChecked()); s->set("QuitAfterGameStop", ui->quitAfterGameStopCheck->isChecked()); + + // Mod loader settings + s->set("DisableQuiltBeacon", ui->disableQuiltBeaconCheckBox->isChecked()); } void MinecraftPage::loadSettings() @@ -137,6 +141,8 @@ void MinecraftPage::loadSettings() ui->closeAfterLaunchCheck->setChecked(s->get("CloseAfterLaunch").toBool()); ui->quitAfterGameStopCheck->setChecked(s->get("QuitAfterGameStop").toBool()); + + ui->disableQuiltBeaconCheckBox->setChecked(s->get("DisableQuiltBeacon").toBool()); } void MinecraftPage::retranslate() diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 8f5de725d..7a8f107b0 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -190,6 +190,22 @@ Tweaks + + + + Mod loader settings + + + + + + Disable Quilt's Beacon + + + + + + diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 943ff17f1..25cc1a0de 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -3,6 +3,7 @@ * PolyMC - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 seth * * 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 @@ -50,9 +51,9 @@ #include "Application.h" #include "minecraft/auth/AccountList.h" +#include "FileSystem.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" -#include "FileSystem.h" InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) @@ -280,6 +281,14 @@ void InstanceSettingsPage::applySettings() m_settings->reset("InstanceAccountId"); } + bool overrideModLoaderSettings = ui->modLoaderSettingsGroupBox->isChecked(); + m_settings->set("OverrideModLoaderSettings", overrideModLoaderSettings); + if (overrideModLoaderSettings) { + m_settings->set("DisableQuiltBeacon", ui->disableQuiltBeaconCheckBox->isChecked()); + } else { + m_settings->reset("DisableQuiltBeacon"); + } + // FIXME: This should probably be called by a signal instead m_instance->updateRuntimeContext(); } @@ -380,6 +389,10 @@ void InstanceSettingsPage::loadSettings() ui->instanceAccountGroupBox->setChecked(m_settings->get("UseAccountForInstance").toBool()); updateAccountsMenu(); + + // Mod loader specific settings + ui->modLoaderSettingsGroupBox->setChecked(m_settings->get("OverrideModLoaderSettings").toBool()); + ui->disableQuiltBeaconCheckBox->setChecked(m_settings->get("DisableQuiltBeacon").toBool()); } void InstanceSettingsPage::on_javaDetectBtn_clicked() diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 8427965de..5c6f74d47 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -541,6 +541,28 @@ Miscellaneous + + + + true + + + false + + + Mod loader settings + + + + + + Disable Quilt's Beacon + + + + + + From 843c2d67eb04ecd215c9bc3de6f458c8d293b54f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 13 Jul 2023 18:41:29 +0300 Subject: [PATCH 325/429] Added FTBAPP Import Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 11 ++ .../modplatform/import_ftb/PackHelpers.cpp | 87 +++++++++++++++ launcher/modplatform/import_ftb/PackHelpers.h | 55 +++++++++ .../import_ftb/PackInstallTask.cpp | 102 +++++++++++++++++ .../modplatform/import_ftb/PackInstallTask.h | 49 +++++++++ launcher/ui/dialogs/NewInstanceDialog.cpp | 26 ++--- .../modplatform/import_ftb/ImportFTBPage.cpp | 104 ++++++++++++++++++ .../modplatform/import_ftb/ImportFTBPage.h | 67 +++++++++++ .../modplatform/import_ftb/ImportFTBPage.ui | 28 +++++ .../modplatform/import_ftb/ListModel.cpp | 89 +++++++++++++++ .../pages/modplatform/import_ftb/ListModel.h | 46 ++++++++ 11 files changed, 651 insertions(+), 13 deletions(-) create mode 100644 launcher/modplatform/import_ftb/PackHelpers.cpp create mode 100644 launcher/modplatform/import_ftb/PackHelpers.h create mode 100644 launcher/modplatform/import_ftb/PackInstallTask.cpp create mode 100644 launcher/modplatform/import_ftb/PackInstallTask.h create mode 100644 launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp create mode 100644 launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h create mode 100644 launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.ui create mode 100644 launcher/ui/pages/modplatform/import_ftb/ListModel.cpp create mode 100644 launcher/ui/pages/modplatform/import_ftb/ListModel.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index af3bc28e3..6544e65b0 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -498,6 +498,11 @@ set(FTB_SOURCES modplatform/legacy_ftb/PrivatePackManager.cpp modplatform/legacy_ftb/PackHelpers.h + + modplatform/import_ftb/PackInstallTask.h + modplatform/import_ftb/PackInstallTask.cpp + modplatform/import_ftb/PackHelpers.h + modplatform/import_ftb/PackHelpers.cpp ) set(FLAME_SOURCES @@ -867,6 +872,11 @@ SET(LAUNCHER_SOURCES ui/pages/modplatform/legacy_ftb/ListModel.h ui/pages/modplatform/legacy_ftb/ListModel.cpp + ui/pages/modplatform/import_ftb/ImportFTBPage.cpp + ui/pages/modplatform/import_ftb/ImportFTBPage.h + ui/pages/modplatform/import_ftb/ListModel.h + ui/pages/modplatform/import_ftb/ListModel.cpp + ui/pages/modplatform/flame/FlameModel.cpp ui/pages/modplatform/flame/FlameModel.h ui/pages/modplatform/flame/FlamePage.cpp @@ -1039,6 +1049,7 @@ qt_wrap_ui(LAUNCHER_UI ui/pages/modplatform/ResourcePage.ui ui/pages/modplatform/flame/FlamePage.ui ui/pages/modplatform/legacy_ftb/Page.ui + ui/pages/modplatform/import_ftb/ImportFTBPage.ui ui/pages/modplatform/ImportPage.ui ui/pages/modplatform/modrinth/ModrinthPage.ui ui/pages/modplatform/technic/TechnicPage.ui diff --git a/launcher/modplatform/import_ftb/PackHelpers.cpp b/launcher/modplatform/import_ftb/PackHelpers.cpp new file mode 100644 index 000000000..26b6eafe1 --- /dev/null +++ b/launcher/modplatform/import_ftb/PackHelpers.cpp @@ -0,0 +1,87 @@ +// 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 "modplatform/import_ftb/PackHelpers.h" + +#include +#include +#include + +#include "FileSystem.h" +#include "Json.h" + +namespace FTBImportAPP { + +Modpack parseDirectory(QString path) +{ + Modpack modpack{ path }; + auto instanceFile = QFileInfo(FS::PathCombine(path, "instance.json")); + if (!instanceFile.exists() || !instanceFile.isFile()) + return {}; + try { + auto doc = Json::requireDocument(instanceFile.absoluteFilePath(), "FTB_APP instance JSON file"); + const auto root = doc.object(); + modpack.uuid = Json::requireString(root, "uuid", "uuid"); + modpack.id = Json::requireInteger(root, "id", "id"); + modpack.versionId = Json::requireInteger(root, "versionId", "versionId"); + modpack.name = Json::requireString(root, "name", "name"); + modpack.version = Json::requireString(root, "version", "version"); + modpack.mcVersion = Json::requireString(root, "mcVersion", "mcVersion"); + modpack.jvmArgs = Json::requireVariant(root, "jvmArgs", "jvmArgs"); + } catch (const Exception& e) { + qDebug() << "Couldn't load ftb instance json: " << e.cause(); + return {}; + } + auto versionsFile = QFileInfo(FS::PathCombine(path, "version.json")); + if (!versionsFile.exists() || !versionsFile.isFile()) + return {}; + try { + auto doc = Json::requireDocument(versionsFile.absoluteFilePath(), "FTB_APP version JSON file"); + const auto root = doc.object(); + auto targets = Json::requireArray(root, "targets", "targets"); + + for (auto target : targets) { + auto obj = Json::requireObject(target, "target"); + auto name = Json::requireString(obj, "name", "name"); + auto version = Json::requireString(obj, "version", "version"); + if (name == "forge") { + modpack.loaderType = ResourceAPI::Forge; + modpack.version = version; + break; + } else if (name == "fabric") { + modpack.loaderType = ResourceAPI::Fabric; + modpack.version = version; + break; + } else if (name == "quilt") { + modpack.loaderType = ResourceAPI::Quilt; + modpack.version = version; + break; + } + } + } catch (const Exception& e) { + qDebug() << "Couldn't load ftb version json: " << e.cause(); + return {}; + } + auto iconFile = QFileInfo(FS::PathCombine(path, "folder.jpg")); + if (iconFile.exists() && iconFile.isFile()) { + modpack.icon = QIcon(iconFile.absoluteFilePath()); + } + return modpack; +} + +} // namespace FTBImportAPP diff --git a/launcher/modplatform/import_ftb/PackHelpers.h b/launcher/modplatform/import_ftb/PackHelpers.h new file mode 100644 index 000000000..8ea4f3faf --- /dev/null +++ b/launcher/modplatform/import_ftb/PackHelpers.h @@ -0,0 +1,55 @@ +// 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 +#include +#include +#include +#include "modplatform/ResourceAPI.h" + +namespace FTBImportAPP { + +struct Modpack { + QString path; + + // json data + QString uuid; + int id; + int versionId; + QString name; + QString version; + QString mcVersion; + // not needed for instance creation + QVariant jvmArgs; + + std::optional loaderType; + QString loaderVersion; + + QIcon icon; +}; + +typedef QList ModpackList; + +Modpack parseDirectory(QString path); + +} // namespace FTBImportAPP + +// We need it for the proxy model +Q_DECLARE_METATYPE(FTBImportAPP::Modpack) diff --git a/launcher/modplatform/import_ftb/PackInstallTask.cpp b/launcher/modplatform/import_ftb/PackInstallTask.cpp new file mode 100644 index 000000000..7b01b66bb --- /dev/null +++ b/launcher/modplatform/import_ftb/PackInstallTask.cpp @@ -0,0 +1,102 @@ +// 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 "PackInstallTask.h" + +#include + +#include "BaseInstance.h" +#include "FileSystem.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" +#include "modplatform/ResourceAPI.h" +#include "modplatform/import_ftb/PackHelpers.h" +#include "settings/INISettingsObject.h" + +namespace FTBImportAPP { + +void PackInstallTask::executeTask() +{ + setStatus(tr("Copy files")); + setAbortable(false); + progress(1, 2); + + m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this] { + FS::copy folderCopy(m_pack.path, FS::PathCombine(m_stagingPath, ".minecraft")); + folderCopy.followSymlinks(true); + return folderCopy(); + }); + connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &PackInstallTask::copySettings); + connect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &PackInstallTask::emitAborted); + m_copyFutureWatcher.setFuture(m_copyFuture); +} + +void PackInstallTask::copySettings() +{ + setStatus(tr("Copy settings")); + progress(2, 2); + QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg"); + auto instanceSettings = std::make_shared(instanceConfigPath); + instanceSettings->suspendSave(); + instanceSettings->registerSetting("InstanceType", "OneSix"); + instanceSettings->set("InstanceType", "OneSix"); + + if (m_pack.jvmArgs.isValid() && !m_pack.jvmArgs.toString().isEmpty()) { + instanceSettings->registerSetting("OverrideJavaArgs", true); + instanceSettings->set("OverrideJavaArgs", true); + instanceSettings->registerSetting("JvmArgs", m_pack.jvmArgs.toString()); + instanceSettings->set("JvmArgs", m_pack.jvmArgs.toString()); + } + + MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); + auto components = instance.getPackProfile(); + components->buildingFromScratch(); + components->setComponentVersion("net.minecraft", m_pack.mcVersion, true); + + auto modloader = m_pack.loaderType; + if (modloader.has_value()) + switch (modloader.value()) { + case ResourceAPI::Forge: { + components->setComponentVersion("net.minecraftforge", m_pack.version, true); + break; + } + case ResourceAPI::Fabric: { + components->setComponentVersion("net.fabricmc.fabric-loader", m_pack.version, true); + break; + } + case ResourceAPI::Quilt: { + components->setComponentVersion("org.quiltmc.quilt-loader", m_pack.version, true); + break; + } + case ResourceAPI::Cauldron: + break; + case ResourceAPI::LiteLoader: + break; + } + components->saveNow(); + + instance.setName(name()); + if (m_instIcon == "default") + m_instIcon = "ftb_logo"; + instance.setIconKey(m_instIcon); + instanceSettings->resumeSave(); + + emitSucceeded(); +} + +} // namespace FTBImportAPP diff --git a/launcher/modplatform/import_ftb/PackInstallTask.h b/launcher/modplatform/import_ftb/PackInstallTask.h new file mode 100644 index 000000000..4d453ee64 --- /dev/null +++ b/launcher/modplatform/import_ftb/PackInstallTask.h @@ -0,0 +1,49 @@ +// 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 + +#include "InstanceTask.h" +#include "PackHelpers.h" + +namespace FTBImportAPP { + +class PackInstallTask : public InstanceTask { + Q_OBJECT + + public: + explicit PackInstallTask(Modpack pack) : m_pack(pack) {} + virtual ~PackInstallTask() = default; + + protected: + virtual void executeTask() override; + + private slots: + void copySettings(); + + private: + QFuture m_copyFuture; + QFutureWatcher m_copyFutureWatcher; + + Modpack m_pack; +}; + +} // namespace FTBImportAPP diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index 7b9bb944c..76b139fc7 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -33,38 +33,37 @@ * limitations under the License. */ -#include "Application.h" #include "NewInstanceDialog.h" +#include "Application.h" +#include "ui/pages/modplatform/import_ftb/ImportFTBPage.h" #include "ui_NewInstanceDialog.h" #include +#include #include #include -#include -#include "VersionSelectDialog.h" -#include "ProgressDialog.h" #include "IconPickerDialog.h" +#include "ProgressDialog.h" +#include "VersionSelectDialog.h" +#include +#include #include #include -#include #include -#include #include -#include "ui/widgets/PageContainer.h" #include "ui/pages/modplatform/CustomPage.h" -#include "ui/pages/modplatform/atlauncher/AtlPage.h" -#include "ui/pages/modplatform/legacy_ftb/Page.h" -#include "ui/pages/modplatform/flame/FlamePage.h" #include "ui/pages/modplatform/ImportPage.h" +#include "ui/pages/modplatform/atlauncher/AtlPage.h" +#include "ui/pages/modplatform/flame/FlamePage.h" +#include "ui/pages/modplatform/legacy_ftb/Page.h" #include "ui/pages/modplatform/modrinth/ModrinthPage.h" #include "ui/pages/modplatform/technic/TechnicPage.h" +#include "ui/widgets/PageContainer.h" - - -NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent) +NewInstanceDialog::NewInstanceDialog(const QString& initialGroup, const QString& url, QWidget* parent) : QDialog(parent), ui(new Ui::NewInstanceDialog) { ui->setupUi(this); @@ -168,6 +167,7 @@ QList NewInstanceDialog::getPages() if (APPLICATION->capabilities() & Application::SupportsFlame) pages.append(new FlamePage(this)); pages.append(new LegacyFTB::Page(this)); + pages.append(new FTBImportAPP::ImportFTBPage(this)); pages.append(new ModrinthPage(this)); pages.append(new TechnicPage(this)); diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp new file mode 100644 index 000000000..5c9ff63b2 --- /dev/null +++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp @@ -0,0 +1,104 @@ +// 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 "ImportFTBPage.h" +#include "ui_ImportFTBPage.h" + +#include +#include "FileSystem.h" +#include "ListModel.h" +#include "modplatform/import_ftb/PackInstallTask.h" +#include "ui/dialogs/NewInstanceDialog.h" + +namespace FTBImportAPP { + +ImportFTBPage::ImportFTBPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), dialog(dialog), ui(new Ui::ImportFTBPage) +{ + ui->setupUi(this); + + { + listModel = new ListModel(this); + + ui->modpackList->setModel(listModel); + ui->modpackList->setSortingEnabled(true); + ui->modpackList->header()->hide(); + ui->modpackList->setIndentation(0); + ui->modpackList->setIconSize(QSize(42, 42)); + } + + connect(ui->modpackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &ImportFTBPage::onPublicPackSelectionChanged); + + ui->modpackList->selectionModel()->reset(); +} + +ImportFTBPage::~ImportFTBPage() +{ + delete ui; +} + +void ImportFTBPage::openedImpl() +{ + if (!initialized) { + listModel->update(); + initialized = true; + } + suggestCurrent(); +} + +void ImportFTBPage::retranslate() +{ + ui->retranslateUi(this); +} + +void ImportFTBPage::suggestCurrent() +{ + if (!isOpened) + return; + + if (selected.path.isEmpty()) { + dialog->setSuggestedPack(); + return; + } + + dialog->setSuggestedPack(selected.name, new PackInstallTask(selected)); + QString editedLogoName = QString("ftb_%1").arg(selected.id); + dialog->setSuggestedIconFromFile(FS::PathCombine(selected.path, "folder.jpg"), editedLogoName); +} + +void ImportFTBPage::onPublicPackSelectionChanged(QModelIndex now, QModelIndex prev) +{ + if (!now.isValid()) { + onPackSelectionChanged(); + return; + } + Modpack selectedPack = listModel->data(now, Qt::UserRole).value(); + onPackSelectionChanged(&selectedPack); +} + +void ImportFTBPage::onPackSelectionChanged(Modpack* pack) +{ + if (pack) { + selected = *pack; + suggestCurrent(); + return; + } + if (isOpened) + dialog->setSuggestedPack(); +} + +} // namespace FTBImportAPP diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h new file mode 100644 index 000000000..437fb62a8 --- /dev/null +++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h @@ -0,0 +1,67 @@ +// 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 +#include +#include + +#include +#include "modplatform/import_ftb/PackHelpers.h" +#include "ui/pages/BasePage.h" +#include "ui/pages/modplatform/import_ftb/ListModel.h" + +class NewInstanceDialog; + +namespace FTBImportAPP { +namespace Ui { +class ImportFTBPage; +} + +class ImportFTBPage : public QWidget, public BasePage { + Q_OBJECT + + public: + explicit ImportFTBPage(NewInstanceDialog* dialog, QWidget* parent = 0); + virtual ~ImportFTBPage(); + QString displayName() const override { return "FTB App Import"; } + QIcon icon() const override { return APPLICATION->getThemedIcon("ftb_logo"); } + QString id() const override { return "import_ftb"; } + QString helpPage() const override { return "FTB-platform"; } + bool shouldDisplay() const override { return true; } + void openedImpl() override; + void retranslate() override; + + private: + void suggestCurrent(); + void onPackSelectionChanged(Modpack* pack = nullptr); + private slots: + void onPublicPackSelectionChanged(QModelIndex first, QModelIndex second); + + private: + bool initialized = false; + Modpack selected; + ListModel* listModel = nullptr; + + NewInstanceDialog* dialog = nullptr; + Ui::ImportFTBPage* ui = nullptr; +}; + +} // namespace FTBImportAPP diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.ui b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.ui new file mode 100644 index 000000000..32d548b0d --- /dev/null +++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.ui @@ -0,0 +1,28 @@ + + + FTBImportAPP::ImportFTBPage + + + + 0 + 0 + 1461 + 1011 + + + + + + + + 16777215 + 16777215 + + + + + + + + + diff --git a/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp new file mode 100644 index 000000000..35d0334bf --- /dev/null +++ b/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp @@ -0,0 +1,89 @@ +// 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 "ListModel.h" +#include +#include +#include +#include +#include +#include +#include "FileSystem.h" +#include "modplatform/import_ftb/PackHelpers.h" + +namespace FTBImportAPP { + +QString getPath() +{ + QString partialPath; +#if defined(Q_OS_OSX) + partialPath = FS::PathCombine(QDir::homePath(), "Library/Application Support"); +#elif defined(Q_OS_WIN32) + partialPath = QProcessEnvironment::systemEnvironment().value("LOCALAPPDATA", ""); +#else + partialPath = QDir::homePath(); +#endif + return FS::PathCombine(partialPath, ".ftba"); +} + +const QString ListModel::FTB_APP_PATH = getPath(); + +void ListModel::update() +{ + beginResetModel(); + modpacks.clear(); + + QString instancesPath = FS::PathCombine(FTB_APP_PATH, "instances"); + if (auto instancesInfo = QFileInfo(instancesPath); instancesInfo.exists() && instancesInfo.isDir()) { + QDirIterator directoryIterator(instancesPath, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable | QDir::Hidden, + QDirIterator::FollowSymlinks); + while (directoryIterator.hasNext()) { + auto modpack = parseDirectory(directoryIterator.next()); + if (!modpack.path.isEmpty()) + modpacks.append(modpack); + } + } else { + qDebug() << "Couldn't find ftb instances folder: " << instancesPath; + } + + endResetModel(); +} + +QVariant ListModel::data(const QModelIndex& index, int role) const +{ + int pos = index.row(); + if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { + return QVariant(); + } + + auto pack = modpacks.at(pos); + if (role == Qt::DisplayRole) { + return pack.name; + } else if (role == Qt::DecorationRole) { + return pack.icon; + } else if (role == Qt::UserRole) { + QVariant v; + v.setValue(pack); + return v; + } else if (role == Qt::ToolTipRole) { + return tr("Minecraft %1").arg(pack.mcVersion); + } + + return QVariant(); +} +} // namespace FTBImportAPP \ No newline at end of file diff --git a/launcher/ui/pages/modplatform/import_ftb/ListModel.h b/launcher/ui/pages/modplatform/import_ftb/ListModel.h new file mode 100644 index 000000000..c67aa8963 --- /dev/null +++ b/launcher/ui/pages/modplatform/import_ftb/ListModel.h @@ -0,0 +1,46 @@ +// 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 +#include +#include "modplatform/import_ftb/PackHelpers.h" + +namespace FTBImportAPP { + +class ListModel : public QAbstractListModel { + Q_OBJECT + + public: + ListModel(QObject* parent) : QAbstractListModel(parent) {} + virtual ~ListModel() = default; + + int rowCount(const QModelIndex& parent) const { return modpacks.size(); } + int columnCount(const QModelIndex& parent) const { return 1; } + QVariant data(const QModelIndex& index, int role) const; + + void update(); + + static const QString FTB_APP_PATH; + + private: + ModpackList modpacks; +}; +} // namespace FTBImportAPP \ No newline at end of file From bd6e8533adbce78d7cf791d323662af70d052fff Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 13 Jul 2023 19:58:08 +0300 Subject: [PATCH 326/429] send by reference Signed-off-by: Trial97 --- launcher/modplatform/import_ftb/PackInstallTask.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/import_ftb/PackInstallTask.h b/launcher/modplatform/import_ftb/PackInstallTask.h index 4d453ee64..842e4b35e 100644 --- a/launcher/modplatform/import_ftb/PackInstallTask.h +++ b/launcher/modplatform/import_ftb/PackInstallTask.h @@ -30,7 +30,7 @@ class PackInstallTask : public InstanceTask { Q_OBJECT public: - explicit PackInstallTask(Modpack pack) : m_pack(pack) {} + explicit PackInstallTask(const Modpack& pack) : m_pack(pack) {} virtual ~PackInstallTask() = default; protected: @@ -43,7 +43,7 @@ class PackInstallTask : public InstanceTask { QFuture m_copyFuture; QFutureWatcher m_copyFutureWatcher; - Modpack m_pack; + const Modpack m_pack; }; } // namespace FTBImportAPP From 95b300f1ea7791a7a358d95abb473699d1f016b7 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 13 Jul 2023 19:56:36 -0700 Subject: [PATCH 327/429] packaging: use PascalCase folder name instead Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- CMakeLists.txt | 4 ++-- launcher/Application.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0defd5e0b..5358d1a8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,7 +332,7 @@ elseif(UNIX) set(BINARY_DEST_DIR "bin") set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") - set(JARS_DEST_DIR "share/${Launcher_APP_BINARY_NAME}") + set(JARS_DEST_DIR "share/${Launcher_Name}") # install as bundle with no dependencies included set(INSTALL_BUNDLE "nodeps") @@ -345,7 +345,7 @@ elseif(UNIX) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION "${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_mrpack_MIMEInfo} DESTINATION ${KDE_INSTALL_MIMEDIR}) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "share/${Launcher_APP_BINARY_NAME}") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "share/${Launcher_Name}") if(Launcher_ManPage) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_ManPage} DESTINATION "${KDE_INSTALL_MANDIR}/man6") diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 8c60f6974..372a4fc67 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -434,7 +434,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // seach root path if(!foundLoggingRules) { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - logRulesPath = FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_APP_BINARY_NAME, logRulesFile); + logRulesPath = FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME, logRulesFile); #else logRulesPath = FS::PathCombine(m_rootPath, logRulesFile); #endif @@ -1571,7 +1571,7 @@ QString Application::getJarPath(QString jarFile) { QStringList potentialPaths = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_APP_BINARY_NAME), + FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_NAME), #endif FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"), From cde85947c7dd4c2508938490789fef60cd464828 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 13 Jul 2023 21:12:12 -0700 Subject: [PATCH 328/429] Update launcher/minecraft/mod/tasks/LocalResourceParse.cpp Co-authored-by: seth Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/minecraft/mod/tasks/LocalResourceParse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index 6d9b4d97a..0894049cd 100644 --- a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp @@ -45,7 +45,7 @@ namespace ResourceUtils { PackedResourceType identify(QFileInfo file){ if (file.exists() && file.isFile()) { if (ModUtils::validate(file)) { - // mods can contain resource and data packs so they much be tested first + // mods can contain resource and data packs so they must be tested first qDebug() << file.fileName() << "is a mod"; return PackedResourceType::Mod; } else if (ResourcePackUtils::validate(file)) { From b0a018d8239df32272a7145f2cf71d1413333060 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jul 2023 12:28:23 +0300 Subject: [PATCH 329/429] format Signed-off-by: Trial97 --- .../legacy_ftb/PackInstallTask.cpp | 57 ++++++++----------- .../modplatform/legacy_ftb/PackInstallTask.h | 23 ++++---- 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index 36c142acb..4b01e4690 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -37,16 +37,16 @@ #include -#include "MMCZip.h" #include "BaseInstance.h" #include "FileSystem.h" -#include "settings/INISettingsObject.h" +#include "MMCZip.h" +#include "minecraft/GradleSpecifier.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "minecraft/GradleSpecifier.h" +#include "settings/INISettingsObject.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" namespace LegacyFTB { @@ -120,16 +120,17 @@ void PackInstallTask::unzip() QDir extractDir(m_stagingPath); m_packZip.reset(new QuaZip(archivePath)); - if(!m_packZip->open(QuaZip::mdUnzip)) - { + if (!m_packZip->open(QuaZip::mdUnzip)) { emitFailed(tr("Failed to open modpack file %1!").arg(archivePath)); return; } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload::of(MMCZip::extractDir), archivePath, extractDir.absolutePath() + "/unzip"); + m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload::of(MMCZip::extractDir), archivePath, + extractDir.absolutePath() + "/unzip"); #else - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip"); + m_extractFuture = + QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip"); #endif connect(&m_extractFutureWatcher, &QFutureWatcher::finished, this, &PackInstallTask::onUnzipFinished); connect(&m_extractFutureWatcher, &QFutureWatcher::canceled, this, &PackInstallTask::onUnzipCanceled); @@ -151,11 +152,9 @@ void PackInstallTask::install() setStatus(tr("Installing modpack")); progress(3, 4); QDir unzipMcDir(m_stagingPath + "/unzip/minecraft"); - if(unzipMcDir.exists()) - { - //ok, found minecraft dir, move contents to instance dir - if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft")) - { + if (unzipMcDir.exists()) { + // ok, found minecraft dir, move contents to instance dir + if (!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft")) { emitFailed(tr("Failed to move unzipped Minecraft!")); return; } @@ -172,23 +171,20 @@ void PackInstallTask::install() bool fallback = true; - //handle different versions + // handle different versions QFile packJson(m_stagingPath + "/.minecraft/pack.json"); QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods"); - if(packJson.exists()) - { + if (packJson.exists()) { packJson.open(QIODevice::ReadOnly | QIODevice::Text); QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll()); packJson.close(); - //we only care about the libs + // we only care about the libs QJsonArray libs = doc.object().value("libraries").toArray(); - foreach (const QJsonValue &value, libs) - { + foreach (const QJsonValue& value, libs) { QString nameValue = value.toObject().value("name").toString(); - if(!nameValue.startsWith("net.minecraftforge")) - { + if (!nameValue.startsWith("net.minecraftforge")) { continue; } @@ -199,16 +195,13 @@ void PackInstallTask::install() fallback = false; break; } - } - if(jarmodDir.exists()) - { + if (jarmodDir.exists()) { qDebug() << "Found jarmods, installing..."; QStringList jarmods; - for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) - { + for (auto info : jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) { qDebug() << "Jarmod:" << info.fileName(); jarmods.push_back(info.absoluteFilePath()); } @@ -217,12 +210,11 @@ void PackInstallTask::install() fallback = false; } - //just nuke unzip directory, it s not needed anymore + // just nuke unzip directory, it s not needed anymore FS::deletePath(m_stagingPath + "/unzip"); - if(fallback) - { - //TODO: Some fallback mechanism... or just keep failing! + if (fallback) { + // TODO: Some fallback mechanism... or just keep failing! emitFailed(tr("No installation method found!")); return; } @@ -232,8 +224,7 @@ void PackInstallTask::install() progress(4, 4); instance.setName(name()); - if(m_instIcon == "default") - { + if (m_instIcon == "default") { m_instIcon = "ftb_logo"; } instance.setIconKey(m_instIcon); @@ -252,4 +243,4 @@ bool PackInstallTask::abort() return InstanceTask::abort(); } -} +} // namespace LegacyFTB diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.h b/launcher/modplatform/legacy_ftb/PackInstallTask.h index da791e065..94bb2901a 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.h +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.h @@ -1,12 +1,12 @@ #pragma once -#include "InstanceTask.h" -#include "net/NetJob.h" #include #include +#include "InstanceTask.h" +#include "PackHelpers.h" #include "meta/Index.h" #include "meta/Version.h" #include "meta/VersionList.h" -#include "PackHelpers.h" +#include "net/NetJob.h" #include "net/NetJob.h" @@ -14,27 +14,26 @@ namespace LegacyFTB { -class PackInstallTask : public InstanceTask -{ +class PackInstallTask : public InstanceTask { Q_OBJECT -public: + public: explicit PackInstallTask(shared_qobject_ptr network, Modpack pack, QString version); - virtual ~PackInstallTask(){} + virtual ~PackInstallTask() {} bool canAbort() const override { return true; } bool abort() override; -protected: + protected: //! Entry point for tasks. virtual void executeTask() override; -private: + private: void downloadPack(); void unzip(); void install(); -private slots: + private slots: void onDownloadSucceeded(); void onDownloadFailed(QString reason); void onDownloadProgress(qint64 current, qint64 total); @@ -43,7 +42,7 @@ private slots: void onUnzipFinished(); void onUnzipCanceled(); -private: /* data */ + private: /* data */ shared_qobject_ptr m_network; bool abortable = false; std::unique_ptr m_packZip; @@ -56,4 +55,4 @@ private: /* data */ QString m_version; }; -} +} // namespace LegacyFTB From c8533c0b0d4e510bfe6c6818a25f5c45bc796a53 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 17:58:24 +0300 Subject: [PATCH 330/429] fixed substatus on ftb_import Signed-off-by: Trial97 --- .../legacy_ftb/PackInstallTask.cpp | 29 +++---------------- .../modplatform/legacy_ftb/PackInstallTask.h | 4 --- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index 4b01e4690..a4c78397b 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -65,6 +65,7 @@ void PackInstallTask::executeTask() void PackInstallTask::downloadPack() { setStatus(tr("Downloading zip for %1").arg(m_pack.name)); + setProgress(1, 4); setAbortable(false); archivePath = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file); @@ -78,11 +79,10 @@ void PackInstallTask::downloadPack() } netJobContainer->addNetAction(Net::Download::makeFile(url, archivePath)); - connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); - connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed); - connect(netJobContainer.get(), &NetJob::progress, this, &PackInstallTask::onDownloadProgress); + connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::unzip); + connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::emitFailed); connect(netJobContainer.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); - connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::onDownloadAborted); + connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::emitAborted); netJobContainer->start(); @@ -90,27 +90,6 @@ void PackInstallTask::downloadPack() progress(1, 4); } -void PackInstallTask::onDownloadSucceeded() -{ - unzip(); -} - -void PackInstallTask::onDownloadFailed(QString reason) -{ - emitFailed(reason); -} - -void PackInstallTask::onDownloadProgress(qint64 current, qint64 total) -{ - progress(current, total * 4); - setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10)); -} - -void PackInstallTask::onDownloadAborted() -{ - emitAborted(); -} - void PackInstallTask::unzip() { setStatus(tr("Extracting modpack")); diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.h b/launcher/modplatform/legacy_ftb/PackInstallTask.h index 94bb2901a..30ff48597 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.h +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.h @@ -34,10 +34,6 @@ class PackInstallTask : public InstanceTask { void install(); private slots: - void onDownloadSucceeded(); - void onDownloadFailed(QString reason); - void onDownloadProgress(qint64 current, qint64 total); - void onDownloadAborted(); void onUnzipFinished(); void onUnzipCanceled(); From fc4a1ef1935059b3c8e4f5d7bdac9fa2311485ac Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jul 2023 13:31:13 +0300 Subject: [PATCH 331/429] format Signed-off-by: Trial97 --- launcher/BaseVersion.h | 19 ++++++------------- launcher/java/JavaInstall.cpp | 14 ++++++-------- launcher/java/JavaInstall.h | 31 +++++++++---------------------- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/launcher/BaseVersion.h b/launcher/BaseVersion.h index ca0e45027..c7cedbe10 100644 --- a/launcher/BaseVersion.h +++ b/launcher/BaseVersion.h @@ -15,16 +15,15 @@ #pragma once -#include -#include #include +#include +#include /*! * An abstract base class for versions. */ -class BaseVersion -{ -public: +class BaseVersion { + public: using Ptr = std::shared_ptr; virtual ~BaseVersion() {} /*! @@ -45,14 +44,8 @@ public: */ virtual QString typeString() const = 0; - virtual bool operator<(BaseVersion &a) - { - return name() < a.name(); - }; - virtual bool operator>(BaseVersion &a) - { - return name() > a.name(); - }; + virtual bool operator<(BaseVersion& a) { return name() < a.name(); }; + virtual bool operator>(BaseVersion& a) { return name() > a.name(); }; }; Q_DECLARE_METATYPE(BaseVersion::Ptr) diff --git a/launcher/java/JavaInstall.cpp b/launcher/java/JavaInstall.cpp index d5932bcb9..f095aa37f 100644 --- a/launcher/java/JavaInstall.cpp +++ b/launcher/java/JavaInstall.cpp @@ -2,28 +2,26 @@ #include "StringUtils.h" -bool JavaInstall::operator<(const JavaInstall &rhs) +bool JavaInstall::operator<(const JavaInstall& rhs) { auto archCompare = StringUtils::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive); - if(archCompare != 0) + if (archCompare != 0) return archCompare < 0; - if(id < rhs.id) - { + if (id < rhs.id) { return true; } - if(id > rhs.id) - { + if (id > rhs.id) { return false; } return StringUtils::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0; } -bool JavaInstall::operator==(const JavaInstall &rhs) +bool JavaInstall::operator==(const JavaInstall& rhs) { return arch == rhs.arch && id == rhs.id && path == rhs.path; } -bool JavaInstall::operator>(const JavaInstall &rhs) +bool JavaInstall::operator>(const JavaInstall& rhs) { return (!operator<(rhs)) && (!operator==(rhs)); } diff --git a/launcher/java/JavaInstall.h b/launcher/java/JavaInstall.h index 64be40d19..2d6e4d537 100644 --- a/launcher/java/JavaInstall.h +++ b/launcher/java/JavaInstall.h @@ -3,31 +3,18 @@ #include "BaseVersion.h" #include "JavaVersion.h" -struct JavaInstall : public BaseVersion -{ - JavaInstall(){} - JavaInstall(QString id, QString arch, QString path) - : id(id), arch(arch), path(path) - { - } - virtual QString descriptor() - { - return id.toString(); - } +struct JavaInstall : public BaseVersion { + JavaInstall() {} + JavaInstall(QString id, QString arch, QString path) : id(id), arch(arch), path(path) {} + virtual QString descriptor() { return id.toString(); } - virtual QString name() - { - return id.toString(); - } + virtual QString name() { return id.toString(); } - virtual QString typeString() const - { - return arch; - } + virtual QString typeString() const { return arch; } - bool operator<(const JavaInstall & rhs); - bool operator==(const JavaInstall & rhs); - bool operator>(const JavaInstall & rhs); + bool operator<(const JavaInstall& rhs); + bool operator==(const JavaInstall& rhs); + bool operator>(const JavaInstall& rhs); JavaVersion id; QString arch; From b0a21c9389dfb6962713b61cdb28fa0022c25eeb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jul 2023 13:31:28 +0300 Subject: [PATCH 332/429] insert header Signed-off-by: Trial97 --- launcher/java/JavaInstall.cpp | 18 ++++++++++++++++++ launcher/java/JavaInstall.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/launcher/java/JavaInstall.cpp b/launcher/java/JavaInstall.cpp index f095aa37f..2931a0deb 100644 --- a/launcher/java/JavaInstall.cpp +++ b/launcher/java/JavaInstall.cpp @@ -1,3 +1,21 @@ +// 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 "JavaInstall.h" #include "StringUtils.h" diff --git a/launcher/java/JavaInstall.h b/launcher/java/JavaInstall.h index 2d6e4d537..aa673dad6 100644 --- a/launcher/java/JavaInstall.h +++ b/launcher/java/JavaInstall.h @@ -1,3 +1,21 @@ +// 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 "BaseVersion.h" From 440afcedb02bd878deb2053d2905170763df673d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jul 2023 13:32:18 +0300 Subject: [PATCH 333/429] fixed warning Signed-off-by: Trial97 --- launcher/java/JavaInstall.cpp | 19 +++++++++++++++++++ launcher/java/JavaInstall.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/launcher/java/JavaInstall.cpp b/launcher/java/JavaInstall.cpp index 2931a0deb..cfa471402 100644 --- a/launcher/java/JavaInstall.cpp +++ b/launcher/java/JavaInstall.cpp @@ -18,6 +18,7 @@ #include "JavaInstall.h" +#include "BaseVersion.h" #include "StringUtils.h" bool JavaInstall::operator<(const JavaInstall& rhs) @@ -43,3 +44,21 @@ bool JavaInstall::operator>(const JavaInstall& rhs) { return (!operator<(rhs)) && (!operator==(rhs)); } + +bool JavaInstall::operator<(BaseVersion& a) +{ + try { + return operator<(dynamic_cast(a)); + } catch (const std::bad_cast& e) { + return BaseVersion::operator<(a); + } +} + +bool JavaInstall::operator>(BaseVersion& a) +{ + try { + return operator>(dynamic_cast(a)); + } catch (const std::bad_cast& e) { + return BaseVersion::operator>(a); + } +} diff --git a/launcher/java/JavaInstall.h b/launcher/java/JavaInstall.h index aa673dad6..30815b5a8 100644 --- a/launcher/java/JavaInstall.h +++ b/launcher/java/JavaInstall.h @@ -30,6 +30,8 @@ struct JavaInstall : public BaseVersion { virtual QString typeString() const { return arch; } + virtual bool operator<(BaseVersion& a) override; + virtual bool operator>(BaseVersion& a) override; bool operator<(const JavaInstall& rhs); bool operator==(const JavaInstall& rhs); bool operator>(const JavaInstall& rhs); From 3487e1cb640962ee95520309d5e4b00d6f629c3f Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 14 Jul 2023 03:56:18 -0700 Subject: [PATCH 334/429] Update launcher/Application.cpp Co-authored-by: Sefa Eyeoglu Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 372a4fc67..a30409684 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1571,7 +1571,7 @@ QString Application::getJarPath(QString jarFile) { QStringList potentialPaths = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_NAME), + FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME), #endif FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"), From 515197fba2da1d674dbe7bd17dae4e0f22f64097 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 26 Jun 2023 11:57:21 +0300 Subject: [PATCH 335/429] fix: html sintax for modlist export Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.cpp | 16 ++++++++-------- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index 5e01367f9..d837fb0ba 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -37,13 +37,13 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); + line += QString(" [%1]").arg(ver); } if (extraData & Authors && !mod->authors().isEmpty()) line += " by " + mod->authors().join(", "); - lines.append(QString("
      %1
    ").arg(line)); + lines.append(QString("
  • %1
  • ").arg(line)); } - return QString("
  • \n\t%1\n
  • ").arg(lines.join("\n\t")); + return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); } case MARKDOWN: { QStringList lines; @@ -61,7 +61,7 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); + line += QString(" [%1]").arg(ver); } if (extraData & Authors && !mod->authors().isEmpty()) line += " by " + mod->authors().join(", "); @@ -75,21 +75,21 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData auto meta = mod->metadata(); auto modName = mod->name(); - auto line = "name: " + modName + ";"; + auto line = modName; if (extraData & Url) { auto url = mod->metaurl(); if (!url.isEmpty()) - line += " url: " + url + ";"; + line += QString(" (%1)").arg(url); } if (extraData & Version) { auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += " version: " + QString("[%1]").arg(ver) + ";"; + line += QString(" [%1]").arg(ver); } if (extraData & Authors && !mod->authors().isEmpty()) - line += " authors " + mod->authors().join(", ") + ";"; + line += " by " + mod->authors().join(", "); lines << line; } return lines.join("\n"); diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 149f6b358..700e7178a 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -118,7 +118,7 @@ void ExportToModListDialog::triggerImp() QString exampleLine; switch (format) { case ExportToModList::HTML: { - exampleLine = "
      {name} [{version}] by {authors}
    "; + exampleLine = "
  • {name} [{version}] by {authors}
  • "; ui->resultText->setHtml(txt); break; } From 9a3931dac6e75a79989f13b10604a142dbafcfbb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 16:57:30 +0300 Subject: [PATCH 336/429] Added json and csv format Signed-off-by: Trial97 --- .../modplatform/helpers/ExportToModList.cpp | 56 +++++++++++++++++++ .../modplatform/helpers/ExportToModList.h | 2 +- launcher/ui/dialogs/ExportToModListDialog.cpp | 26 ++++++++- launcher/ui/dialogs/ExportToModListDialog.ui | 10 ++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index d837fb0ba..86bb9c419 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -16,6 +16,9 @@ * along with this program. If not, see . */ #include "ExportToModList.h" +#include +#include +#include namespace ExportToModList { QString ExportToModList(QList mods, Formats format, OptionalData extraData) @@ -94,6 +97,59 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData } return lines.join("\n"); } + case JSON: { + QJsonArray lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + QJsonObject line; + line["name"] = modName; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + line["url"] = url; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line["version"] = ver; + } + if (extraData & Authors && !mod->authors().isEmpty()) + line["authors"] = QJsonArray::fromStringList(mod->authors()); + lines << line; + } + QJsonDocument doc; + doc.setArray(lines); + return doc.toJson(); + } + case CSV: { + QStringList lines; + for (auto mod : mods) { + QStringList data; + auto meta = mod->metadata(); + auto modName = mod->name(); + + data << modName; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + data << url; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + data << ver; + } + if (extraData & Authors && !mod->authors().isEmpty()) + data << QString("\"%1\"").arg(mod->authors().join(",")); + lines << data.join(","); + } + return lines.join("\n"); + } default: { return QString("unknown format:%1").arg(format); } diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h index 9ff8d25a1..abd6e9bc6 100644 --- a/launcher/modplatform/helpers/ExportToModList.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -22,7 +22,7 @@ namespace ExportToModList { -enum Formats { HTML, MARKDOWN, PLAINTXT, CUSTOM }; +enum Formats { HTML, MARKDOWN, PLAINTXT, JSON, CSV, CUSTOM }; enum OptionalData { Authors = 1 << 0, Url = 1 << 1, diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 700e7178a..cfd28cf85 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -89,6 +89,20 @@ void ExportToModListDialog::formatChanged(int index) break; } case 3: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->hide(); + format = ExportToModList::JSON; + break; + } + case 4: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->hide(); + format = ExportToModList::CSV; + break; + } + case 5: { ui->templateGroup->setDisabled(false); ui->optionsGroup->setDisabled(true); ui->resultText->hide(); @@ -133,6 +147,12 @@ void ExportToModListDialog::triggerImp() } case ExportToModList::CUSTOM: return; + case ExportToModList::JSON: + exampleLine = "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"},"; + break; + case ExportToModList::CSV: + exampleLine = "{name},{url},{version},\"{authors}\""; + break; } if (!m_template_selected) { if (ui->templateText->toPlainText() != exampleLine) @@ -146,7 +166,7 @@ void ExportToModListDialog::done(int result) const QString filename = FS::RemoveInvalidFilenameChars(name); const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + extension()), - "File (*.txt *.html *.md)", nullptr); + "File (*.txt *.html *.md *.json *.csv)", nullptr); if (output.isEmpty()) return; @@ -167,6 +187,10 @@ QString ExportToModListDialog::extension() return ".txt"; case ExportToModList::CUSTOM: return ".txt"; + case ExportToModList::JSON: + return ".json"; + case ExportToModList::CSV: + return ".csv"; } return ".txt"; } diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index 640b17665..e0f138f9e 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -58,6 +58,16 @@ Plaintext
    + + + JSON + + + + + CSV + + Custom From 50dae9d4f38d84f168922552e9f87bf2d1130d98 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 18:09:29 +0300 Subject: [PATCH 337/429] Moved to separate functions Signed-off-by: Trial97 --- .../modplatform/helpers/ExportToModList.cpp | 274 ++++++++++-------- 1 file changed, 148 insertions(+), 126 deletions(-) diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index 86bb9c419..a8a015e34 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -21,135 +21,157 @@ #include namespace ExportToModList { +QString toHTML(QList mods, OptionalData extraData) +{ + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + modName = QString("%2").arg(url, modName); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString(" [%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines.append(QString("
  • %1
  • ").arg(line)); + } + return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); +} + +QString toMARKDOWN(QList mods, OptionalData extraData) +{ + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + modName = QString("[%1](%2)").arg(modName, url); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString(" [%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines << "- " + line; + } + return lines.join("\n"); +} + +QString toPLAINTXT(QList mods, OptionalData extraData) +{ + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + + auto line = modName; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + line += QString(" (%1)").arg(url); + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString(" [%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines << line; + } + return lines.join("\n"); +} + +QString toJSON(QList mods, OptionalData extraData) +{ + QJsonArray lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + QJsonObject line; + line["name"] = modName; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + line["url"] = url; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line["version"] = ver; + } + if (extraData & Authors && !mod->authors().isEmpty()) + line["authors"] = QJsonArray::fromStringList(mod->authors()); + lines << line; + } + QJsonDocument doc; + doc.setArray(lines); + return doc.toJson(); +} + +QString toCSV(QList mods, OptionalData extraData) +{ + QStringList lines; + for (auto mod : mods) { + QStringList data; + auto meta = mod->metadata(); + auto modName = mod->name(); + + data << modName; + if (extraData & Url) + data << mod->metaurl(); + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + data << ver; + } + if (extraData & Authors) { + QString authors; + if (mod->authors().length() == 1) + authors = mod->authors().back(); + else if (mod->authors().length() > 1) + authors = QString("\"%1\"").arg(mod->authors().join(",")); + data << authors; + } + lines << data.join(","); + } + return lines.join("\n"); +} + QString ExportToModList(QList mods, Formats format, OptionalData extraData) { switch (format) { - case HTML: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - modName = QString("%2").arg(url, modName); - } - auto line = modName; - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString(" [%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines.append(QString("
  • %1
  • ").arg(line)); - } - return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); - } - case MARKDOWN: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - modName = QString("[%1](%2)").arg(modName, url); - } - auto line = modName; - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString(" [%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines << "- " + line; - } - return lines.join("\n"); - } - case PLAINTXT: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - - auto line = modName; - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - line += QString(" (%1)").arg(url); - } - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString(" [%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines << line; - } - return lines.join("\n"); - } - case JSON: { - QJsonArray lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - QJsonObject line; - line["name"] = modName; - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - line["url"] = url; - } - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line["version"] = ver; - } - if (extraData & Authors && !mod->authors().isEmpty()) - line["authors"] = QJsonArray::fromStringList(mod->authors()); - lines << line; - } - QJsonDocument doc; - doc.setArray(lines); - return doc.toJson(); - } - case CSV: { - QStringList lines; - for (auto mod : mods) { - QStringList data; - auto meta = mod->metadata(); - auto modName = mod->name(); - - data << modName; - if (extraData & Url) { - auto url = mod->metaurl(); - if (!url.isEmpty()) - data << url; - } - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - data << ver; - } - if (extraData & Authors && !mod->authors().isEmpty()) - data << QString("\"%1\"").arg(mod->authors().join(",")); - lines << data.join(","); - } - return lines.join("\n"); - } + case HTML: + return toHTML(mods, extraData); + case MARKDOWN: + return toMARKDOWN(mods, extraData); + case PLAINTXT: + return toPLAINTXT(mods, extraData); + case JSON: + return toJSON(mods, extraData); + case CSV: + return toCSV(mods, extraData); default: { return QString("unknown format:%1").arg(format); } From 9b02c31f8dab0f36f3d0c30115ab323dabe21541 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 4 Jul 2023 17:48:20 +0300 Subject: [PATCH 338/429] escaped text for html export Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index a8a015e34..e7bafac47 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -26,9 +26,9 @@ QString toHTML(QList mods, OptionalData extraData) QStringList lines; for (auto mod : mods) { auto meta = mod->metadata(); - auto modName = mod->name(); + auto modName = mod->name().toHtmlEscaped(); if (extraData & Url) { - auto url = mod->metaurl(); + auto url = mod->metaurl().toHtmlEscaped(); if (!url.isEmpty()) modName = QString("%2").arg(url, modName); } @@ -38,10 +38,10 @@ QString toHTML(QList mods, OptionalData extraData) if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += QString(" [%1]").arg(ver); + line += QString(" [%1]").arg(ver.toHtmlEscaped()); } if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); + line += " by " + mod->authors().join(", ").toHtmlEscaped(); lines.append(QString("
  • %1
  • ").arg(line)); } return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); From 1495bfb73ead50b45942e94a8e3b18e111820b4b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 11 Jul 2023 22:43:27 +0300 Subject: [PATCH 339/429] Made custom template enabled all time Signed-off-by: Trial97 --- .../modplatform/helpers/ExportToModList.h | 2 +- launcher/ui/dialogs/ExportToModListDialog.cpp | 59 +++++++++---------- launcher/ui/dialogs/ExportToModListDialog.h | 3 +- launcher/ui/dialogs/ExportToModListDialog.ui | 14 ++++- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h index abd6e9bc6..49252fc4f 100644 --- a/launcher/modplatform/helpers/ExportToModList.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ #pragma once -#include +#include #include #include "minecraft/mod/Mod.h" diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index cfd28cf85..b86b10561 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -33,11 +33,19 @@ #include #include +const QHash ExportToModListDialog::exampleLines = { + { ExportToModList::HTML, "
  • {name} [{version}] by {authors}
  • " }, + { ExportToModList::MARKDOWN, "[{name}]({url}) [{version}] by {authors}" }, + { ExportToModList::PLAINTXT, "{name} ({url}) [{version}] by {authors}" }, + { ExportToModList::JSON, "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"}," }, + { ExportToModList::CSV, "{name},{url},{version},\"{authors}\"" }, +}; + ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* parent) - : QDialog(parent), m_template_selected(false), name(instance->name()), ui(new Ui::ExportToModListDialog) + : QDialog(parent), m_template_changed(false), name(instance->name()), ui(new Ui::ExportToModListDialog) { ui->setupUi(this); - ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); MinecraftInstance* mcInstance = dynamic_cast(instance.get()); if (mcInstance) { @@ -52,7 +60,12 @@ ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* pare connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); - connect(ui->templateText, &QTextEdit::textChanged, this, &ExportToModListDialog::triggerImp); + connect(ui->templateText, &QTextEdit::textChanged, this, [this] { + if (ui->templateText->toPlainText() != exampleLines[format]) + ui->formatComboBox->setCurrentIndex(5); + else + triggerImp(); + }); connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { this->ui->finalText->selectAll(); this->ui->finalText->copy(); @@ -68,42 +81,37 @@ void ExportToModListDialog::formatChanged(int index) { switch (index) { case 0: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->show(); format = ExportToModList::HTML; break; } case 1: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->show(); format = ExportToModList::MARKDOWN; break; } case 2: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->hide(); format = ExportToModList::PLAINTXT; break; } case 3: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->hide(); format = ExportToModList::JSON; break; } case 4: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->hide(); format = ExportToModList::CSV; break; } case 5: { - ui->templateGroup->setDisabled(false); + m_template_changed = true; ui->optionsGroup->setDisabled(true); ui->resultText->hide(); format = ExportToModList::CUSTOM; @@ -116,7 +124,6 @@ void ExportToModListDialog::formatChanged(int index) void ExportToModListDialog::triggerImp() { if (format == ExportToModList::CUSTOM) { - m_template_selected = true; ui->finalText->setPlainText(ExportToModList::ExportToModList(m_allMods, ui->templateText->toPlainText())); return; } @@ -129,35 +136,25 @@ void ExportToModListDialog::triggerImp() opt |= ExportToModList::Url; auto txt = ExportToModList::ExportToModList(m_allMods, format, static_cast(opt)); ui->finalText->setPlainText(txt); - QString exampleLine; switch (format) { - case ExportToModList::HTML: { - exampleLine = "
  • {name} [{version}] by {authors}
  • "; - ui->resultText->setHtml(txt); - break; - } - case ExportToModList::MARKDOWN: { - exampleLine = "[{name}]({url}) [{version}] by {authors}"; - ui->resultText->setHtml(markdownToHTML(txt)); - break; - } - case ExportToModList::PLAINTXT: { - exampleLine = "{name} ({url}) [{version}] by {authors}"; - break; - } case ExportToModList::CUSTOM: return; + case ExportToModList::HTML: + ui->resultText->setHtml(txt); + break; + case ExportToModList::MARKDOWN: + ui->resultText->setHtml(markdownToHTML(txt)); + break; + case ExportToModList::PLAINTXT: + break; case ExportToModList::JSON: - exampleLine = "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"},"; break; case ExportToModList::CSV: - exampleLine = "{name},{url},{version},\"{authors}\""; break; } - if (!m_template_selected) { - if (ui->templateText->toPlainText() != exampleLine) - ui->templateText->setPlainText(exampleLine); - } + auto exampleLine = exampleLines[format]; + if (!m_template_changed && ui->templateText->toPlainText() != exampleLine) + ui->templateText->setPlainText(exampleLine); } void ExportToModListDialog::done(int result) diff --git a/launcher/ui/dialogs/ExportToModListDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h index a7a6bcdce..b8a83d830 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.h +++ b/launcher/ui/dialogs/ExportToModListDialog.h @@ -45,8 +45,9 @@ class ExportToModListDialog : public QDialog { private: QString extension(); QList m_allMods; - bool m_template_selected; + bool m_template_changed; QString name; ExportToModList::Formats format = ExportToModList::Formats::HTML; Ui::ExportToModListDialog* ui; + static const QHash exampleLines; }; diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index e0f138f9e..90f179a63 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -18,7 +18,7 @@
    - + @@ -149,6 +149,16 @@
    + + + + This depends on the mods meta data. To ensure the meta data run at least one time the mods update on the selected instance(no need to update the mods). + + + true + + +
    @@ -189,7 +199,7 @@ - + buttonBox rejected() ExportToModListDialog From b9ed8283b7e22fff5920dcd81ae347822d31353a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 13 Jul 2023 20:38:08 +0300 Subject: [PATCH 340/429] Added buttons Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportToModListDialog.cpp | 44 ++++++++++++--- launcher/ui/dialogs/ExportToModListDialog.h | 2 + launcher/ui/dialogs/ExportToModListDialog.ui | 53 +++++++++++++------ 3 files changed, 76 insertions(+), 23 deletions(-) diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index b86b10561..a0f8ee7b0 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -45,7 +45,7 @@ ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* pare : QDialog(parent), m_template_changed(false), name(instance->name()), ui(new Ui::ExportToModListDialog) { ui->setupUi(this); - ui->optionsGroup->setDisabled(false); + enableCustom(false); MinecraftInstance* mcInstance = dynamic_cast(instance.get()); if (mcInstance) { @@ -60,6 +60,9 @@ ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* pare connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->authorsButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Authors); }); + connect(ui->versionButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Version); }); + connect(ui->urlButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Url); }); connect(ui->templateText, &QTextEdit::textChanged, this, [this] { if (ui->templateText->toPlainText() != exampleLines[format]) ui->formatComboBox->setCurrentIndex(5); @@ -81,38 +84,38 @@ void ExportToModListDialog::formatChanged(int index) { switch (index) { case 0: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->show(); format = ExportToModList::HTML; break; } case 1: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->show(); format = ExportToModList::MARKDOWN; break; } case 2: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->hide(); format = ExportToModList::PLAINTXT; break; } case 3: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->hide(); format = ExportToModList::JSON; break; } case 4: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->hide(); format = ExportToModList::CSV; break; } case 5: { m_template_changed = true; - ui->optionsGroup->setDisabled(true); + enableCustom(true); ui->resultText->hide(); format = ExportToModList::CUSTOM; break; @@ -191,3 +194,30 @@ QString ExportToModListDialog::extension() } return ".txt"; } + +void ExportToModListDialog::addExtra(ExportToModList::OptionalData option) +{ + if (format != ExportToModList::CUSTOM) + return; + switch (option) { + case ExportToModList::Authors: + ui->templateText->insertPlainText("{authors}"); + break; + case ExportToModList::Url: + ui->templateText->insertPlainText("{url}"); + break; + case ExportToModList::Version: + ui->templateText->insertPlainText("{version}"); + break; + } +} +void ExportToModListDialog::enableCustom(bool enabled) +{ + ui->authorsCheckBox->setHidden(enabled); + ui->versionCheckBox->setHidden(enabled); + ui->urlCheckBox->setHidden(enabled); + + ui->authorsButton->setHidden(!enabled); + ui->versionButton->setHidden(!enabled); + ui->urlButton->setHidden(!enabled); +} diff --git a/launcher/ui/dialogs/ExportToModListDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h index b8a83d830..9886ae5a0 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.h +++ b/launcher/ui/dialogs/ExportToModListDialog.h @@ -41,9 +41,11 @@ class ExportToModListDialog : public QDialog { void formatChanged(int index); void triggerImp(); void trigger(int) { triggerImp(); }; + void addExtra(ExportToModList::OptionalData option); private: QString extension(); + void enableCustom(bool enabled); QList m_allMods; bool m_template_changed; QString name; diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index 90f179a63..fc72f9a99 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -25,22 +25,6 @@ Settings
    - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - Format - - - @@ -114,9 +98,46 @@ + + + + Version + + + + + + + Authors + + + + + + + URL + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + Format + + + From 1ccfba13ebe11a1d6ea2897db45b47c2452931f5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jul 2023 23:39:54 +0300 Subject: [PATCH 341/429] renames Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.cpp | 12 ++++++------ launcher/modplatform/helpers/ExportToModList.h | 4 ++-- launcher/ui/dialogs/ExportToModListDialog.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index e7bafac47..1f01c4a89 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -47,7 +47,7 @@ QString toHTML(QList mods, OptionalData extraData) return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); } -QString toMARKDOWN(QList mods, OptionalData extraData) +QString toMarkdown(QList mods, OptionalData extraData) { QStringList lines; for (auto mod : mods) { @@ -73,7 +73,7 @@ QString toMARKDOWN(QList mods, OptionalData extraData) return lines.join("\n"); } -QString toPLAINTXT(QList mods, OptionalData extraData) +QString toPlainTXT(QList mods, OptionalData extraData) { QStringList lines; for (auto mod : mods) { @@ -159,15 +159,15 @@ QString toCSV(QList mods, OptionalData extraData) return lines.join("\n"); } -QString ExportToModList(QList mods, Formats format, OptionalData extraData) +QString exportToModList(QList mods, Formats format, OptionalData extraData) { switch (format) { case HTML: return toHTML(mods, extraData); case MARKDOWN: - return toMARKDOWN(mods, extraData); + return toMarkdown(mods, extraData); case PLAINTXT: - return toPLAINTXT(mods, extraData); + return toPlainTXT(mods, extraData); case JSON: return toJSON(mods, extraData); case CSV: @@ -178,7 +178,7 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData } } -QString ExportToModList(QList mods, QString lineTemplate) +QString exportToModList(QList mods, QString lineTemplate) { QStringList lines; for (auto mod : mods) { diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h index 49252fc4f..7ea4ba9c2 100644 --- a/launcher/modplatform/helpers/ExportToModList.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -28,6 +28,6 @@ enum OptionalData { Url = 1 << 1, Version = 1 << 2, }; -QString ExportToModList(QList mods, Formats format, OptionalData extraData); -QString ExportToModList(QList mods, QString lineTemplate); +QString exportToModList(QList mods, Formats format, OptionalData extraData); +QString exportToModList(QList mods, QString lineTemplate); } // namespace ExportToModList diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index a0f8ee7b0..c811bfe6a 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -127,7 +127,7 @@ void ExportToModListDialog::formatChanged(int index) void ExportToModListDialog::triggerImp() { if (format == ExportToModList::CUSTOM) { - ui->finalText->setPlainText(ExportToModList::ExportToModList(m_allMods, ui->templateText->toPlainText())); + ui->finalText->setPlainText(ExportToModList::exportToModList(m_allMods, ui->templateText->toPlainText())); return; } auto opt = 0; @@ -137,7 +137,7 @@ void ExportToModListDialog::triggerImp() opt |= ExportToModList::Version; if (ui->urlCheckBox->isChecked()) opt |= ExportToModList::Url; - auto txt = ExportToModList::ExportToModList(m_allMods, format, static_cast(opt)); + auto txt = ExportToModList::exportToModList(m_allMods, format, static_cast(opt)); ui->finalText->setPlainText(txt); switch (format) { case ExportToModList::CUSTOM: From 0692cbe701723e203d16154fa97f67fc5c22198c Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 15 Jul 2023 00:17:32 +0300 Subject: [PATCH 342/429] Update launcher/modplatform/import_ftb/PackInstallTask.cpp Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/modplatform/import_ftb/PackInstallTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/import_ftb/PackInstallTask.cpp b/launcher/modplatform/import_ftb/PackInstallTask.cpp index 7b01b66bb..1877afe9f 100644 --- a/launcher/modplatform/import_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/import_ftb/PackInstallTask.cpp @@ -32,7 +32,7 @@ namespace FTBImportAPP { void PackInstallTask::executeTask() { - setStatus(tr("Copy files")); + setStatus(tr("Copying files...")); setAbortable(false); progress(1, 2); From 2c2c39b42c61011698c14869dda71dc1fe3cda64 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 15 Jul 2023 00:17:48 +0300 Subject: [PATCH 343/429] Update launcher/modplatform/import_ftb/PackInstallTask.cpp Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/modplatform/import_ftb/PackInstallTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/import_ftb/PackInstallTask.cpp b/launcher/modplatform/import_ftb/PackInstallTask.cpp index 1877afe9f..e55f6ffa6 100644 --- a/launcher/modplatform/import_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/import_ftb/PackInstallTask.cpp @@ -48,7 +48,7 @@ void PackInstallTask::executeTask() void PackInstallTask::copySettings() { - setStatus(tr("Copy settings")); + setStatus(tr("Copying settings...")); progress(2, 2); QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg"); auto instanceSettings = std::make_shared(instanceConfigPath); From 7befd63ccedd96c52b94c1845fff36f24ee3f1d1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jul 2023 00:28:58 +0300 Subject: [PATCH 344/429] fixed settings Signed-off-by: Trial97 --- launcher/modplatform/import_ftb/PackInstallTask.cpp | 11 ++++------- .../ui/pages/modplatform/import_ftb/ListModel.cpp | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/launcher/modplatform/import_ftb/PackInstallTask.cpp b/launcher/modplatform/import_ftb/PackInstallTask.cpp index e55f6ffa6..b5e424d12 100644 --- a/launcher/modplatform/import_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/import_ftb/PackInstallTask.cpp @@ -53,17 +53,14 @@ void PackInstallTask::copySettings() QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg"); auto instanceSettings = std::make_shared(instanceConfigPath); instanceSettings->suspendSave(); - instanceSettings->registerSetting("InstanceType", "OneSix"); - instanceSettings->set("InstanceType", "OneSix"); + MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); + instance.settings()->set("InstanceType", "OneSix"); if (m_pack.jvmArgs.isValid() && !m_pack.jvmArgs.toString().isEmpty()) { - instanceSettings->registerSetting("OverrideJavaArgs", true); - instanceSettings->set("OverrideJavaArgs", true); - instanceSettings->registerSetting("JvmArgs", m_pack.jvmArgs.toString()); - instanceSettings->set("JvmArgs", m_pack.jvmArgs.toString()); + instance.settings()->set("OverrideJavaArgs", true); + instance.settings()->set("JvmArgs", m_pack.jvmArgs.toString()); } - MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); auto components = instance.getPackProfile(); components->buildingFromScratch(); components->setComponentVersion("net.minecraft", m_pack.mcVersion, true); diff --git a/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp index 35d0334bf..dc78f451c 100644 --- a/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp @@ -17,7 +17,6 @@ */ #include "ListModel.h" -#include #include #include #include From da87e825a154bc87a6017270d80e4afc1b3c2e64 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 15 Jul 2023 15:59:19 +0300 Subject: [PATCH 345/429] Update launcher/ui/dialogs/ExportToModListDialog.ui Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index fc72f9a99..25eb43429 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -173,7 +173,7 @@ - This depends on the mods meta data. To ensure the meta data run at least one time the mods update on the selected instance(no need to update the mods). + This depends on the mods' metadata. To ensure it is available, run an update on the instance. Installing the updates isn't necessary. true From a2a09ffe01fe8eb6cd1f557b0feb98ed0271151e Mon Sep 17 00:00:00 2001 From: seth Date: Thu, 13 Jul 2023 20:57:38 -0400 Subject: [PATCH 346/429] chore: better explain quilt loader beacon Signed-off-by: seth --- launcher/minecraft/MinecraftInstance.cpp | 2 +- launcher/ui/pages/global/MinecraftPage.ui | 5 ++++- launcher/ui/pages/instance/InstanceSettingsPage.ui | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 180838ad2..0833d5912 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -3,7 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Jamie Mansfield - * Copyright (C) 2022 TheKodeToad \ + * Copyright (C) 2022 TheKodeToad * Copyright (c) 2023 seth * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 7a8f107b0..a3188dccb 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -199,7 +199,10 @@ - Disable Quilt's Beacon + Disable Quilt Loader Beacon + + + Disable Quilt loader's beacon for counting monthly active users diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 5c6f74d47..323890b90 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -556,7 +556,10 @@ - Disable Quilt's Beacon + Disable Quilt Loader Beacon + + + Disable Quilt loader's beacon for counting monthly active users From c346d875a2d26435f680efb07f785c43af5ad95a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jul 2023 23:26:52 +0300 Subject: [PATCH 347/429] make FileResolvingTask accept empty modlist Signed-off-by: Trial97 --- .../modplatform/flame/FileResolvingTask.cpp | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index ce7a60551..34bd401d3 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -21,6 +21,10 @@ bool Flame::FileResolvingTask::abort() void Flame::FileResolvingTask::executeTask() { + if (m_toProcess.files.isEmpty()) { // no file to resolve so leave it empty and emit success immediately + emitSucceeded(); + return; + } setStatus(tr("Resolving mod IDs...")); setProgress(0, 3); m_dljob.reset(new NetJob("Mod id resolver", m_network)); @@ -128,12 +132,13 @@ void Flame::FileResolvingTask::netJobFinished() m_checkJob->start(); } -void Flame::FileResolvingTask::modrinthCheckFinished() { +void Flame::FileResolvingTask::modrinthCheckFinished() +{ setProgress(2, 3); qDebug() << "Finished with blocked mods : " << blockedProjects.size(); for (auto it = blockedProjects.keyBegin(); it != blockedProjects.keyEnd(); it++) { - auto &out = *it; + auto& out = *it; auto bytes = blockedProjects[out]; if (!out->resolved) { continue; @@ -153,15 +158,13 @@ void Flame::FileResolvingTask::modrinthCheckFinished() { out->resolved = false; } } - //copy to an output list and filter out projects found on modrinth + // copy to an output list and filter out projects found on modrinth auto block = std::make_shared>(); auto it = blockedProjects.keys(); - std::copy_if(it.begin(), it.end(), std::back_inserter(*block), [](File *f) { - return !f->resolved; - }); - //Display not found mods early + std::copy_if(it.begin(), it.end(), std::back_inserter(*block), [](File* f) { return !f->resolved; }); + // Display not found mods early if (!block->empty()) { - //blocked mods found, we need the slug for displaying.... we need another job :D ! + // blocked mods found, we need the slug for displaying.... we need another job :D ! m_slugJob.reset(new NetJob("Slug Job", m_network)); int index = 0; for (auto mod : *block) { @@ -173,8 +176,8 @@ void Flame::FileResolvingTask::modrinthCheckFinished() { QObject::connect(dl.get(), &Net::Download::succeeded, [block, index, output]() { auto mod = block->at(index); // use the shared_ptr so it is captured and only freed when we are done auto json = QJsonDocument::fromJson(*output); - auto base = Json::requireString(Json::requireObject(Json::requireObject(Json::requireObject(json),"data"),"links"), - "websiteUrl"); + auto base = + Json::requireString(Json::requireObject(Json::requireObject(Json::requireObject(json), "data"), "links"), "websiteUrl"); auto link = QString("%1/download/%2").arg(base, QString::number(mod->fileId)); mod->websiteUrl = link; }); From 06fc8358d9836a203cd31580fa57f055c9bcef05 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jul 2023 23:57:32 +0300 Subject: [PATCH 348/429] auto focus search line on resource download Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourcePage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index aab2ee89a..48afbd900 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -104,6 +104,7 @@ void ResourcePage::openedImpl() updateSelectionButton(); triggerSearch(); + m_ui->searchEdit->setFocus(); } auto ResourcePage::eventFilter(QObject* watched, QEvent* event) -> bool From a3ffa6455021b69bd1940b65fefb3b6177c96730 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 01:59:08 +0300 Subject: [PATCH 349/429] Upgraded pack changelog Signed-off-by: Trial97 --- launcher/ui/pages/instance/ManagedPackPage.cpp | 16 ++++++++++++++++ launcher/ui/pages/instance/ManagedPackPage.ui | 12 +++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 0fc0c9867..0443baf19 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -3,6 +3,9 @@ // SPDX-License-Identifier: GPL-3.0-only #include "ManagedPackPage.h" +#include +#include +#include #include "ui_ManagedPackPage.h" #include @@ -103,6 +106,19 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi // Pretend we're opening the page again openedImpl(); }); + + connect(ui->changelogTextBrowser, &QTextBrowser::anchorClicked, this, [](const QUrl url) { + if (url.scheme().isEmpty()) { + auto querry = + QUrlQuery(url.query()).queryItemValue("remoteUrl", QUrl::FullyDecoded); // curseforge workaround for linkout?remoteUrl= + auto decoded = QUrl::fromPercentEncoding(querry.toUtf8()); + auto newUrl = QUrl(decoded); + if (newUrl.isValid() && (newUrl.scheme() == "http" || newUrl.scheme() == "https")) + QDesktopServices ::openUrl(newUrl); + return; + } + QDesktopServices::openUrl(url); + }); } ManagedPackPage::~ManagedPackPage() diff --git a/launcher/ui/pages/instance/ManagedPackPage.ui b/launcher/ui/pages/instance/ManagedPackPage.ui index bbe44a940..05e91bbca 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.ui +++ b/launcher/ui/pages/instance/ManagedPackPage.ui @@ -168,10 +168,13 @@ - + No changelog available for this version! + + false + @@ -188,6 +191,13 @@ + + + ProjectDescriptionPage + QTextBrowser +
    ui/widgets/ProjectDescriptionPage.h
    +
    +
    From 6597a5c8604c580994958c2fff87ccbe90988df4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 16 Jul 2023 00:23:55 +0000 Subject: [PATCH 350/429] 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 'flake-parts': 'github:hercules-ci/flake-parts/267149c58a14d15f7f81b4d737308421de9d7152' (2023-07-01) → 'github:hercules-ci/flake-parts/8e8d955c22df93dbe24f19ea04f47a74adbdc5ec' (2023-07-04) • Updated input 'nixpkgs': 'github:nixos/nixpkgs/cd99c2b3c9f160cd004318e0697f90bbd5960825' (2023-07-01) → 'github:nixos/nixpkgs/46ed466081b9cad1125b11f11a2af5cc40b942c7' (2023-07-15) • Updated input 'pre-commit-hooks': 'github:cachix/pre-commit-hooks.nix/42587d3414d1747999a5f71e92a83cf6547b62da' (2023-07-03) → 'github:cachix/pre-commit-hooks.nix/5e28316db471d1ac234beb70031b635437421dd6' (2023-07-14) --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index 91a67f087..370250c4b 100644 --- a/flake.lock +++ b/flake.lock @@ -21,11 +21,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1688254665, - "narHash": "sha256-8FHEgBrr7gYNiS/NzCxIO3m4hvtLRW9YY1nYo1ivm3o=", + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "267149c58a14d15f7f81b4d737308421de9d7152", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", "type": "github" }, "original": { @@ -91,11 +91,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1688221086, - "narHash": "sha256-cdW6qUL71cNWhHCpMPOJjlw0wzSRP0pVlRn2vqX/VVg=", + "lastModified": 1689413807, + "narHash": "sha256-exuzOvOhGAEKWQKwDuZAL4N8a1I837hH5eocaTcIbLc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "cd99c2b3c9f160cd004318e0697f90bbd5960825", + "rev": "46ed466081b9cad1125b11f11a2af5cc40b942c7", "type": "github" }, "original": { @@ -138,11 +138,11 @@ ] }, "locked": { - "lastModified": 1688386108, - "narHash": "sha256-Vffto9QaVonzYAcPlAzd0soqWYpPpKk60dfNLSIXcFA=", + "lastModified": 1689328505, + "narHash": "sha256-9B3+OeUn1a/CvzE3GW6nWNwS5J7PDHTyHGlpL3wV5oA=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "42587d3414d1747999a5f71e92a83cf6547b62da", + "rev": "5e28316db471d1ac234beb70031b635437421dd6", "type": "github" }, "original": { From 18ebc858fdebbd08703d9e5ddeaf23abcfceaa94 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 16 Jul 2023 11:47:47 +0200 Subject: [PATCH 351/429] feat(actions): add backport action Signed-off-by: Sefa Eyeoglu --- .github/workflows/backport.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 000000000..77c1a8802 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,32 @@ +name: Backport +on: + pull_request_target: + types: [closed, labeled] + +# WARNING: +# When extending this action, be aware that $GITHUB_TOKEN allows write access to +# the GitHub repository. This means that it should not evaluate user input in a +# way that allows code injection. + +permissions: + contents: read + +jobs: + backport: + permissions: + contents: write # for korthout/backport-action to create branch + pull-requests: write # for korthout/backport-action to create PR to backport + name: Backport Pull Request + if: github.repository_owner == 'PrismLauncher' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name)) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Create backport PRs + uses: korthout/backport-action@v1.3.1 + with: + # Config README: https://github.com/korthout/backport-action#backport-action + pull_description: |- + Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}. + From 1e9a596908ba85dea974e6d041b53c675f8d7b78 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 14:18:17 +0300 Subject: [PATCH 352/429] simplified code in cat packs Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 45 ++++++++++------------------- launcher/ui/themes/ThemeManager.cpp | 15 ++++++---- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 435ccdb88..e1f2caf3c 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -61,36 +61,23 @@ QString BasicCatPack::path() JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.dir().dirName()) { - QString path = FS::PathCombine("catpacks", m_id); - - if (!FS::ensureFolderPathExists(path)) { - themeWarningLog() << "couldn't create folder for catpack!"; - return; - } - - if (manifestInfo.exists() && manifestInfo.isFile()) { - try { - auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); - const auto root = doc.object(); - m_name = Json::requireString(root, "name", "Catpack name"); - auto id = Json::ensureString(root, "id", "", "Catpack ID"); - if (!id.isEmpty()) - m_id = id; - m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); - auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); - for (auto v : variants) { - auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); - m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), - PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), - PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; - } - - } catch (const Exception& e) { - themeWarningLog() << "Couldn't load catpack json: " << e.cause(); - return; + QString path = manifestInfo.path(); + try { + auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); + const auto root = doc.object(); + m_name = Json::requireString(root, "name", "Catpack name"); + m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat")); + auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); + for (auto v : variants) { + auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); + m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), + PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), + PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; } - } else { - themeDebugLog() << "No catpack json present."; + + } catch (const Exception& e) { + themeWarningLog() << "Couldn't load catpack json:" << e.cause(); + return; } } diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index d00b3a992..ba09f6276 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "ui/themes/BrightTheme.h" #include "ui/themes/CatPack.h" #include "ui/themes/CustomTheme.h" @@ -179,13 +180,17 @@ void ThemeManager::initializeCatPacks() for (auto [id, name] : defaultCats) { addCatPack(std::unique_ptr(new BasicCatPack(id, name))); } - QDir catpacksDir("./catpacks/"); + QDir catpacksDir("catpacks"); QString catpacksFolder = catpacksDir.absoluteFilePath(""); - themeDebugLog() << "CatPacks Folder Path: " << catpacksFolder; + themeDebugLog() << "CatPacks Folder Path:" << catpacksFolder; - auto loadFiles = [this](QDir dir) { + QStringList supportedImageFormats; + for (auto format : QImageReader::supportedImageFormats()) { + supportedImageFormats.append("*." + format); + } + auto loadFiles = [this, supportedImageFormats](QDir dir) { // Load image files directly - QDirIterator ImageFileIterator(dir.absoluteFilePath(""), { "*.png", "*.gif", "*.jpg", "*.apng", "*.jxl", "*.avif" }, QDir::Files); + QDirIterator ImageFileIterator(dir.absoluteFilePath(""), supportedImageFormats, QDir::Files); while (ImageFileIterator.hasNext()) { QFile customCatFile(ImageFileIterator.next()); QFileInfo customCatFileInfo(customCatFile); @@ -200,7 +205,7 @@ void ThemeManager::initializeCatPacks() while (directoryIterator.hasNext()) { QDir dir(directoryIterator.next()); QFileInfo manifest(dir.absoluteFilePath("catpack.json")); - if (manifest.exists()) { + if (manifest.isFile()) { // Load background manifest themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); addCatPack(std::unique_ptr(new JsonCatPack(manifest))); From de30a72c4e1f051eef2a0bd389fc51e6a64d54c3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 15:16:16 +0300 Subject: [PATCH 353/429] made the date a object Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 58 ++++++++++++++++++----------- launcher/ui/themes/CatPack.h | 7 ---- launcher/ui/themes/ThemeManager.cpp | 21 ++++++++--- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index e1f2caf3c..ebb100a40 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -39,7 +39,6 @@ #include #include "FileSystem.h" #include "Json.h" -#include "ui/themes/ThemeManager.h" QString BasicCatPack::path() { @@ -59,39 +58,56 @@ QString BasicCatPack::path() return cat; } +JsonCatPack::PartialDate partialDate(QJsonObject date) +{ + auto month = Json::ensureInteger(date, "month", 1); + if (month > 12) + month = 12; + else if (month <= 0) + month = 1; + auto day = Json::ensureInteger(date, "day", 1); + if (day > 31) + day = 31; + else if (day <= 0) + day = 1; + return { month, day }; +}; + JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.dir().dirName()) { QString path = manifestInfo.path(); - try { - auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); - const auto root = doc.object(); - m_name = Json::requireString(root, "name", "Catpack name"); - m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat")); - auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); - for (auto v : variants) { - auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); - m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), - PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), - PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; - } - - } catch (const Exception& e) { - themeWarningLog() << "Couldn't load catpack json:" << e.cause(); - return; + auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); + const auto root = doc.object(); + m_name = Json::requireString(root, "name", "Catpack name"); + m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat")); + auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); + for (auto v : variants) { + auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); + m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), + partialDate(Json::requireObject(variant, "startTime", "Variant startTime")), + partialDate(Json::requireObject(variant, "endTime", "Variant endTime")) }; } } +QDate ensureDay(int year, int month, int day) +{ + QDate date(year, month, 1); + if (day > date.daysInMonth()) + day = date.daysInMonth(); + return QDate(year, month, day); +} + QString JsonCatPack::path() { const QDate now = QDate::currentDate(); for (auto var : m_variants) { - QDate startDate(now.year(), var.startTime.month, var.startTime.day); - QDate endDate(now.year(), var.endTime.month, var.endTime.day); + QDate startDate = ensureDay(now.year(), var.startTime.month, var.startTime.day); + QDate endDate = ensureDay(now.year(), var.endTime.month, var.endTime.day); if (startDate > endDate) { // it's spans over multiple years if (endDate <= now) // end date is in the past so jump one year into the future for endDate - endDate = endDate.addYears(1); + endDate = ensureDay(now.year() + 1, var.endTime.month, var.endTime.day); else // end date is in the future so jump one year into the past for startDate - startDate = startDate.addYears(-1); + startDate = ensureDay(now.year() - 1, var.startTime.month, var.startTime.day); } if (startDate >= now && now >= endDate) diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index 20cb8f61e..b03a19f03 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -74,13 +74,6 @@ class FileCatPack : public BasicCatPack { class JsonCatPack : public BasicCatPack { public: struct PartialDate { - PartialDate(QString d) - { - auto sp = d.split("-"); - day = sp[0].toInt(); - if (sp.length() >= 2) - month = sp[1].toInt(); - } int month; int day; }; diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index ba09f6276..683642d79 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "Exception.h" #include "ui/themes/BrightTheme.h" #include "ui/themes/CatPack.h" #include "ui/themes/CustomTheme.h" @@ -43,7 +44,10 @@ ThemeManager::ThemeManager(MainWindow* mainWindow) QString ThemeManager::addTheme(std::unique_ptr theme) { QString id = theme->id(); - m_themes.emplace(id, std::move(theme)); + if (m_themes.find(id) == m_themes.end()) + m_themes.emplace(id, std::move(theme)); + else + themeWarningLog() << "Theme(" << id << ") not added to prevent id duplication"; return id; } @@ -167,7 +171,10 @@ QString ThemeManager::getCatPack(QString catName) QString ThemeManager::addCatPack(std::unique_ptr catPack) { QString id = catPack->id(); - m_catPacks.emplace(id, std::move(catPack)); + if (m_catPacks.find(id) == m_catPacks.end()) + m_catPacks.emplace(id, std::move(catPack)); + else + themeWarningLog() << "CatPack(" << id << ") not added to prevent id duplication"; return id; } @@ -206,9 +213,13 @@ void ThemeManager::initializeCatPacks() QDir dir(directoryIterator.next()); QFileInfo manifest(dir.absoluteFilePath("catpack.json")); if (manifest.isFile()) { - // Load background manifest - themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); - addCatPack(std::unique_ptr(new JsonCatPack(manifest))); + try { + // Load background manifest + themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); + addCatPack(std::unique_ptr(new JsonCatPack(manifest))); + } catch (const Exception& e) { + themeWarningLog() << "Couldn't load catpack json:" << e.cause(); + } } else { loadFiles(dir); } From 002430db4668df1816feba550f5c2f432683996c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 15:43:47 +0300 Subject: [PATCH 354/429] added path to flatpack Signed-off-by: Trial97 --- flatpak/org.prismlauncher.PrismLauncher.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flatpak/org.prismlauncher.PrismLauncher.yml b/flatpak/org.prismlauncher.PrismLauncher.yml index 0524946f0..725e54da4 100644 --- a/flatpak/org.prismlauncher.PrismLauncher.yml +++ b/flatpak/org.prismlauncher.PrismLauncher.yml @@ -25,6 +25,8 @@ finish-args: - --filesystem=xdg-run/app/com.discordapp.Discord:create # Mod drag&drop - --filesystem=xdg-download:ro + # FTBApp import + - --filesystem=~/.ftba:ro modules: - name: prismlauncher @@ -38,8 +40,8 @@ modules: JAVA_HOME: /usr/lib/sdk/openjdk17/jvm/openjdk-17 JAVA_COMPILER: /usr/lib/sdk/openjdk17/jvm/openjdk-17/bin/javac sources: - - type: dir - path: ../ + - type: dir + path: ../ builddir: true - name: openjdk buildsystem: simple From 251055302eec0232a89f0466efe3e7e7f3fa7de3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 20:53:58 +0300 Subject: [PATCH 355/429] format Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 148 +++++++--------- launcher/MMCZip.h | 174 +++++++++---------- launcher/ui/dialogs/ExportInstanceDialog.cpp | 70 +++----- launcher/ui/dialogs/ExportInstanceDialog.h | 22 ++- 4 files changed, 184 insertions(+), 230 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 1a336375b..4e932a768 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -33,56 +33,48 @@ * limitations under the License. */ +#include "MMCZip.h" #include #include #include -#include "MMCZip.h" #include "FileSystem.h" #include #include // ours -bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet &contained, const FilterFunction filter) +bool MMCZip::mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter) { QuaZip modZip(from.filePath()); modZip.open(QuaZip::mdUnzip); QuaZipFile fileInsideMod(&modZip); QuaZipFile zipOutFile(into); - for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) - { + for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) { QString filename = modZip.getCurrentFileName(); - if (filter && !filter(filename)) - { - qDebug() << "Skipping file " << filename << " from " - << from.fileName() << " - filtered"; + if (filter && !filter(filename)) { + qDebug() << "Skipping file " << filename << " from " << from.fileName() << " - filtered"; continue; } - if (contained.contains(filename)) - { - qDebug() << "Skipping already contained file " << filename << " from " - << from.fileName(); + if (contained.contains(filename)) { + qDebug() << "Skipping already contained file " << filename << " from " << from.fileName(); continue; } contained.insert(filename); - if (!fileInsideMod.open(QIODevice::ReadOnly)) - { + if (!fileInsideMod.open(QIODevice::ReadOnly)) { qCritical() << "Failed to open " << filename << " from " << from.fileName(); return false; } QuaZipNewInfo info_out(fileInsideMod.getActualFileName()); - if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) - { + if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) { qCritical() << "Failed to open " << filename << " in the jar"; fileInsideMod.close(); return false; } - if (!JlCompress::copyData(fileInsideMod, zipOutFile)) - { + if (!JlCompress::copyData(fileInsideMod, zipOutFile)) { zipOutFile.close(); fileInsideMod.close(); qCritical() << "Failed to copy data of " << filename << " into the jar"; @@ -94,10 +86,11 @@ bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet &containe return true; } -bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks) +bool MMCZip::compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks) { QDir directory(dir); - if (!directory.exists()) return false; + if (!directory.exists()) + return false; for (auto e : files) { auto filePath = directory.relativeFilePath(e.absoluteFilePath()); @@ -109,7 +102,8 @@ bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, boo srcPath = e.canonicalFilePath(); } } - if( !JlCompress::compressFile(zip, srcPath, filePath)) return false; + if (!JlCompress::compressFile(zip, srcPath, filePath)) + return false; } return true; @@ -119,7 +113,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList { QuaZip zip(fileCompressed); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); - if(!zip.open(QuaZip::mdCreate)) { + if (!zip.open(QuaZip::mdCreate)) { QFile::remove(fileCompressed); return false; } @@ -127,7 +121,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList auto result = compressDirFiles(&zip, dir, files, followSymlinks); zip.close(); - if(zip.getZipError()!=0) { + if (zip.getZipError() != 0) { QFile::remove(fileCompressed); return false; } @@ -139,8 +133,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods) { QuaZip zipOut(targetJarPath); - if (!zipOut.open(QuaZip::mdCreate)) - { + if (!zipOut.open(QuaZip::mdCreate)) { QFile::remove(targetJarPath); qCritical() << "Failed to open the minecraft.jar for modding"; return false; @@ -151,37 +144,29 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const // Modify the jar // This needs to be done in reverse-order to ensure we respect the loading order of components - for (auto i = mods.crbegin(); i != mods.crend(); i++) - { + for (auto i = mods.crbegin(); i != mods.crend(); i++) { const auto* mod = *i; // do not merge disabled mods. if (!mod->enabled()) continue; - if (mod->type() == ResourceType::ZIPFILE) - { - if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles)) - { + if (mod->type() == ResourceType::ZIPFILE) { + if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles)) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; return false; } - } - else if (mod->type() == ResourceType::SINGLEFILE) - { + } else if (mod->type() == ResourceType::SINGLEFILE) { // FIXME: buggy - does not work with addedFiles auto filename = mod->fileinfo(); - if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) - { + if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; return false; } addedFiles.insert(filename.fileName()); - } - else if (mod->type() == ResourceType::FOLDER) - { + } else if (mod->type() == ResourceType::FOLDER) { // untested, but seems to be unused / not possible to reach // FIXME: buggy - does not work with addedFiles auto filename = mod->fileinfo(); @@ -197,18 +182,14 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const files.removeAll(e); } - if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) - { + if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; return false; } - qDebug() << "Adding folder " << filename.fileName() << " from " - << filename.absoluteFilePath(); - } - else - { + qDebug() << "Adding folder " << filename.fileName() << " from " << filename.absoluteFilePath(); + } else { // Make sure we do not continue launching when something is missing or undefined... zipOut.close(); QFile::remove(targetJarPath); @@ -217,8 +198,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const } } - if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key){return !key.contains("META-INF");})) - { + if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key) { return !key.contains("META-INF"); })) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to insert minecraft.jar contents."; @@ -227,8 +207,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const // Recompress the jar zipOut.close(); - if (zipOut.getZipError() != 0) - { + if (zipOut.getZipError() != 0) { QFile::remove(targetJarPath); qCritical() << "Failed to finalize minecraft.jar!"; return false; @@ -261,27 +240,23 @@ QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QS } // ours -bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root) +bool MMCZip::findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root) { QuaZipDir rootDir(zip, root); - for(auto fileName: rootDir.entryList(QDir::Files)) - { - if(fileName == what) - { + for (auto fileName : rootDir.entryList(QDir::Files)) { + if (fileName == what) { result.append(root); return true; } } - for(auto fileName: rootDir.entryList(QDir::Dirs)) - { + for (auto fileName : rootDir.entryList(QDir::Dirs)) { findFilesInZip(zip, what, result, root + fileName); } return !result.isEmpty(); } - // ours -std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target) +std::optional MMCZip::extractSubDir(QuaZip* zip, const QString& subdir, const QString& target) { auto target_top_dir = QUrl::fromLocalFile(target); @@ -289,16 +264,13 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target; auto numEntries = zip->getEntriesCount(); - if(numEntries < 0) { + if (numEntries < 0) { qWarning() << "Failed to enumerate files in archive"; return std::nullopt; - } - else if(numEntries == 0) { + } else if (numEntries == 0) { qDebug() << "Extracting empty archives seems odd..."; return extracted; - } - else if (!zip->goToFirstFile()) - { + } else if (!zip->goToFirstFile()) { qWarning() << "Failed to seek to first file in zip"; return std::nullopt; } @@ -334,7 +306,8 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su } if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) { - qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" << target; + qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" + << target; return std::nullopt; } @@ -345,7 +318,8 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su } extracted.append(target_file_path); - QFile::setPermissions(target_file_path, QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); + QFile::setPermissions(target_file_path, + QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path; } while (zip->goToNextFile()); @@ -354,7 +328,7 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su } // ours -bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &target) +bool MMCZip::extractRelFile(QuaZip* zip, const QString& file, const QString& target) { return JlCompress::extractFile(zip, file, target); } @@ -363,14 +337,14 @@ bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &tar std::optional MMCZip::extractDir(QString fileCompressed, QString dir) { QuaZip zip(fileCompressed); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { // check if this is a minimum size empty zip file... QFileInfo fileInfo(fileCompressed); - if(fileInfo.size() == 22) { + if (fileInfo.size() == 22) { return QStringList(); } - qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();; + qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); + ; return std::nullopt; } return MMCZip::extractSubDir(&zip, "", dir); @@ -380,14 +354,14 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString di std::optional MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir) { QuaZip zip(fileCompressed); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { // check if this is a minimum size empty zip file... QFileInfo fileInfo(fileCompressed); - if(fileInfo.size() == 22) { + if (fileInfo.size() == 22) { return QStringList(); } - qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();; + qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); + ; return std::nullopt; } return MMCZip::extractSubDir(&zip, subdir, dir); @@ -397,11 +371,10 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString su bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) { QuaZip zip(fileCompressed); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { // check if this is a minimum size empty zip file... QFileInfo fileInfo(fileCompressed); - if(fileInfo.size() == 22) { + if (fileInfo.size() == 22) { return true; } qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); @@ -410,10 +383,14 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) return MMCZip::extractRelFile(&zip, file, target); } -bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList *files, - MMCZip::FilterFunction excludeFilter) { +bool MMCZip::collectFileListRecursively(const QString& rootDir, + const QString& subDir, + QFileInfoList* files, + MMCZip::FilterFunction excludeFilter) +{ QDir rootDirectory(rootDir); - if (!rootDirectory.exists()) return false; + if (!rootDirectory.exists()) + return false; QDir directory; if (subDir == nullptr) @@ -421,18 +398,19 @@ bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& s else directory = QDir(subDir); - if (!directory.exists()) return false; // shouldn't ever happen + if (!directory.exists()) + return false; // shouldn't ever happen // recurse directories QFileInfoList entries = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); - for (const auto& e: entries) { + for (const auto& e : entries) { if (!collectFileListRecursively(rootDir, e.filePath(), files, excludeFilter)) return false; } // collect files entries = directory.entryInfoList(QDir::Files); - for (const auto& e: entries) { + for (const auto& e : entries) { QString relativeFilePath = rootDirectory.relativeFilePath(e.absoluteFilePath()); if (excludeFilter && excludeFilter(relativeFilePath)) { qDebug() << "Skipping file " << relativeFilePath; diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 2a78f830f..c7cabdc56 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -35,110 +35,108 @@ #pragma once -#include #include #include -#include "minecraft/mod/Mod.h" +#include #include +#include "minecraft/mod/Mod.h" #include #include -namespace MMCZip -{ - using FilterFunction = std::function; +namespace MMCZip { +using FilterFunction = std::function; - /** - * Merge two zip files, using a filter function - */ - bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet &contained, - const FilterFunction filter = nullptr); +/** + * Merge two zip files, using a filter function + */ +bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter = nullptr); - /** - * Compress directory, by providing a list of files to compress - * \param zip target archive - * \param dir directory that will be compressed (to compress with relative paths) - * \param files list of files to compress - * \param followSymlinks should follow symlinks when compressing file data - * \return true for success or false for failure - */ - bool compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks = false); +/** + * Compress directory, by providing a list of files to compress + * \param zip target archive + * \param dir directory that will be compressed (to compress with relative paths) + * \param files list of files to compress + * \param followSymlinks should follow symlinks when compressing file data + * \return true for success or false for failure + */ +bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks = false); - /** - * Compress directory, by providing a list of files to compress - * \param fileCompressed target archive file - * \param dir directory that will be compressed (to compress with relative paths) - * \param files list of files to compress - * \param followSymlinks should follow symlinks when compressing file data - * \return true for success or false for failure - */ - bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false); +/** + * Compress directory, by providing a list of files to compress + * \param fileCompressed target archive file + * \param dir directory that will be compressed (to compress with relative paths) + * \param files list of files to compress + * \param followSymlinks should follow symlinks when compressing file data + * \return true for success or false for failure + */ +bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false); - /** - * take a source jar, add mods to it, resulting in target jar - */ - bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods); +/** + * take a source jar, add mods to it, resulting in target jar + */ +bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods); - /** - * Find a single file in archive by file name (not path) - * - * \param ignore_paths paths to skip when recursing the search - * - * \return the path prefix where the file is - */ - QString findFolderOfFileInZip(QuaZip * zip, const QString & what, const QStringList& ignore_paths = {}, const QString &root = QString("")); +/** + * Find a single file in archive by file name (not path) + * + * \param ignore_paths paths to skip when recursing the search + * + * \return the path prefix where the file is + */ +QString findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths = {}, const QString& root = QString("")); - /** - * Find a multiple files of the same name in archive by file name - * If a file is found in a path, no deeper paths are searched - * - * \return true if anything was found - */ - bool findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root = QString()); +/** + * Find a multiple files of the same name in archive by file name + * If a file is found in a path, no deeper paths are searched + * + * \return true if anything was found + */ +bool findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root = QString()); - /** - * Extract a subdirectory from an archive - */ - std::optional extractSubDir(QuaZip *zip, const QString & subdir, const QString &target); +/** + * Extract a subdirectory from an archive + */ +std::optional extractSubDir(QuaZip* zip, const QString& subdir, const QString& target); - bool extractRelFile(QuaZip *zip, const QString & file, const QString &target); +bool extractRelFile(QuaZip* zip, const QString& file, const QString& target); - /** - * Extract a whole archive. - * - * \param fileCompressed The name of the archive. - * \param dir The directory to extract to, the current directory if left empty. - * \return The list of the full paths of the files extracted, empty on failure. - */ - std::optional extractDir(QString fileCompressed, QString dir); +/** + * Extract a whole archive. + * + * \param fileCompressed The name of the archive. + * \param dir The directory to extract to, the current directory if left empty. + * \return The list of the full paths of the files extracted, empty on failure. + */ +std::optional extractDir(QString fileCompressed, QString dir); - /** - * Extract a subdirectory from an archive - * - * \param fileCompressed The name of the archive. - * \param subdir The directory within the archive to extract - * \param dir The directory to extract to, the current directory if left empty. - * \return The list of the full paths of the files extracted, empty on failure. - */ - std::optional extractDir(QString fileCompressed, QString subdir, QString dir); +/** + * Extract a subdirectory from an archive + * + * \param fileCompressed The name of the archive. + * \param subdir The directory within the archive to extract + * \param dir The directory to extract to, the current directory if left empty. + * \return The list of the full paths of the files extracted, empty on failure. + */ +std::optional extractDir(QString fileCompressed, QString subdir, QString dir); - /** - * Extract a single file from an archive into a directory - * - * \param fileCompressed The name of the archive. - * \param file The file within the archive to extract - * \param dir The directory to extract to, the current directory if left empty. - * \return true for success or false for failure - */ - bool extractFile(QString fileCompressed, QString file, QString dir); +/** + * Extract a single file from an archive into a directory + * + * \param fileCompressed The name of the archive. + * \param file The file within the archive to extract + * \param dir The directory to extract to, the current directory if left empty. + * \return true for success or false for failure + */ +bool extractFile(QString fileCompressed, QString file, QString dir); - /** - * Populate a QFileInfoList with a directory tree recursively, while allowing to excludeFilter what shouldn't be included. - * \param rootDir directory to start off - * \param subDir subdirectory, should be nullptr for first invocation - * \param files resulting list of QFileInfo - * \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude) - * \return true for success or false for failure - */ - bool collectFileListRecursively(const QString &rootDir, const QString &subDir, QFileInfoList *files, FilterFunction excludeFilter); -} +/** + * Populate a QFileInfoList with a directory tree recursively, while allowing to excludeFilter what shouldn't be included. + * \param rootDir directory to start off + * \param subDir subdirectory, should be nullptr for first invocation + * \param files resulting list of QFileInfo + * \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude) + * \return true for success or false for failure + */ +bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter); +} // namespace MMCZip diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index cc41c394d..379ec79f9 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -72,7 +72,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); ui->treeView->sortByColumn(0, Qt::AscendingOrder); - connect(proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int))); + connect(proxyModel, SIGNAL(rowsInserted(QModelIndex, int, int)), SLOT(rowsInserted(QModelIndex, int, int))); model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); model->setRootPath(root); @@ -92,32 +92,26 @@ void SaveIcon(InstancePtr m_instance) auto iconKey = m_instance->iconKey(); auto iconList = APPLICATION->icons(); auto mmcIcon = iconList->icon(iconKey); - if(!mmcIcon || mmcIcon->isBuiltIn()) { + if (!mmcIcon || mmcIcon->isBuiltIn()) { return; } auto path = mmcIcon->getFilePath(); - if(!path.isNull()) { - QFileInfo inInfo (path); - FS::copy(path, FS::PathCombine(m_instance->instanceRoot(), inInfo.fileName())) (); + if (!path.isNull()) { + QFileInfo inInfo(path); + FS::copy(path, FS::PathCombine(m_instance->instanceRoot(), inInfo.fileName()))(); return; } - auto & image = mmcIcon->m_images[mmcIcon->type()]; - auto & icon = image.icon; + auto& image = mmcIcon->m_images[mmcIcon->type()]; + auto& icon = image.icon; auto sizes = icon.availableSizes(); - if(sizes.size() == 0) - { + if (sizes.size() == 0) { return; } - auto areaOf = [](QSize size) - { - return size.width() * size.height(); - }; + auto areaOf = [](QSize size) { return size.width() * size.height(); }; QSize largest = sizes[0]; // find variant with largest area - for(auto size: sizes) - { - if(areaOf(largest) < areaOf(size)) - { + for (auto size : sizes) { + if (areaOf(largest) < areaOf(size)) { largest = size; } } @@ -129,11 +123,9 @@ bool ExportInstanceDialog::doExport() { auto name = FS::RemoveInvalidFilenameChars(m_instance->name()); - const QString output = QFileDialog::getSaveFileName( - this, tr("Export %1").arg(m_instance->name()), - FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr); - if (output.isEmpty()) - { + const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(m_instance->name()), + FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr); + if (output.isEmpty()) { return false; } @@ -146,8 +138,7 @@ bool ExportInstanceDialog::doExport() return false; } - if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) - { + if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false; } @@ -157,15 +148,11 @@ bool ExportInstanceDialog::doExport() void ExportInstanceDialog::done(int result) { savePackIgnore(); - if (result == QDialog::Accepted) - { - if (doExport()) - { + if (result == QDialog::Accepted) { + if (doExport()) { QDialog::done(QDialog::Accepted); return; - } - else - { + } else { return; } } @@ -174,15 +161,12 @@ void ExportInstanceDialog::done(int result) void ExportInstanceDialog::rowsInserted(QModelIndex parent, int top, int bottom) { - //WARNING: possible off-by-one? - for(int i = top; i < bottom; i++) - { + // WARNING: possible off-by-one? + for (int i = top; i < bottom; i++) { auto node = proxyModel->index(i, 0, parent); - if(proxyModel->shouldExpand(node)) - { + if (proxyModel->shouldExpand(node)) { auto expNode = node.parent(); - if(!expNode.isValid()) - { + if (!expNode.isValid()) { continue; } ui->treeView->expand(node); @@ -199,8 +183,7 @@ void ExportInstanceDialog::loadPackIgnore() { auto filename = ignoreFileName(); QFile ignoreFile(filename); - if(!ignoreFile.open(QIODevice::ReadOnly)) - { + if (!ignoreFile.open(QIODevice::ReadOnly)) { return; } auto data = ignoreFile.readAll(); @@ -216,12 +199,9 @@ void ExportInstanceDialog::savePackIgnore() { auto data = proxyModel->blockedPaths().toStringList().join('\n').toUtf8(); auto filename = ignoreFileName(); - try - { + try { FS::write(filename, data); - } - catch (const Exception &e) - { + } catch (const Exception& e) { qWarning() << e.cause(); } } diff --git a/launcher/ui/dialogs/ExportInstanceDialog.h b/launcher/ui/dialogs/ExportInstanceDialog.h index 5e8018751..20a92807b 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.h +++ b/launcher/ui/dialogs/ExportInstanceDialog.h @@ -38,39 +38,37 @@ #include #include #include -#include "FileIgnoreProxy.h" #include "FastFileIconProvider.h" +#include "FileIgnoreProxy.h" class BaseInstance; typedef std::shared_ptr InstancePtr; -namespace Ui -{ +namespace Ui { class ExportInstanceDialog; } -class ExportInstanceDialog : public QDialog -{ +class ExportInstanceDialog : public QDialog { Q_OBJECT -public: - explicit ExportInstanceDialog(InstancePtr instance, QWidget *parent = 0); + public: + explicit ExportInstanceDialog(InstancePtr instance, QWidget* parent = 0); ~ExportInstanceDialog(); virtual void done(int result); -private: + private: bool doExport(); void loadPackIgnore(); void savePackIgnore(); QString ignoreFileName(); -private: - Ui::ExportInstanceDialog *ui; + private: + Ui::ExportInstanceDialog* ui; InstancePtr m_instance; - FileIgnoreProxy * proxyModel; + FileIgnoreProxy* proxyModel; FastFileIconProvider icons; -private slots: + private slots: void rowsInserted(QModelIndex parent, int top, int bottom); }; From cadb7142f0fe5eab16198ca8079d544456a977cc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 20:57:57 +0300 Subject: [PATCH 356/429] Added progress bar to Prism instance export Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 87 +++++++++++++++----- launcher/MMCZip.h | 47 ++++++++++- launcher/ui/dialogs/ExportInstanceDialog.cpp | 38 +++++---- launcher/ui/dialogs/ExportInstanceDialog.h | 3 +- 4 files changed, 136 insertions(+), 39 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 4e932a768..f272bc031 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -2,6 +2,7 @@ /* * PolyMC - 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 @@ -41,9 +42,11 @@ #include #include +#include +namespace MMCZip { // ours -bool MMCZip::mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter) +bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter) { QuaZip modZip(from.filePath()); modZip.open(QuaZip::mdUnzip); @@ -86,7 +89,7 @@ bool MMCZip::mergeZipFiles(QuaZip* into, QFileInfo from, QSet& containe return true; } -bool MMCZip::compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks) +bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks) { QDir directory(dir); if (!directory.exists()) @@ -109,7 +112,7 @@ bool MMCZip::compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, boo return true; } -bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks) +bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks) { QuaZip zip(fileCompressed); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); @@ -130,7 +133,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList } // ours -bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods) +bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods) { QuaZip zipOut(targetJarPath); if (!zipOut.open(QuaZip::mdCreate)) { @@ -175,14 +178,14 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const dir.cdUp(); QString parent_dir = dir.absolutePath(); auto files = QFileInfoList(); - MMCZip::collectFileListRecursively(what_to_zip, nullptr, &files, nullptr); + collectFileListRecursively(what_to_zip, nullptr, &files, nullptr); for (auto e : files) { if (addedFiles.contains(e.filePath())) files.removeAll(e); } - if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) { + if (!compressDirFiles(&zipOut, parent_dir, files)) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; @@ -216,7 +219,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const } // ours -QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root) +QString findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root) { QuaZipDir rootDir(zip, root); for (auto&& fileName : rootDir.entryList(QDir::Files)) { @@ -240,7 +243,7 @@ QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QS } // ours -bool MMCZip::findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root) +bool findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root) { QuaZipDir rootDir(zip, root); for (auto fileName : rootDir.entryList(QDir::Files)) { @@ -256,7 +259,7 @@ bool MMCZip::findFilesInZip(QuaZip* zip, const QString& what, QStringList& resul } // ours -std::optional MMCZip::extractSubDir(QuaZip* zip, const QString& subdir, const QString& target) +std::optional extractSubDir(QuaZip* zip, const QString& subdir, const QString& target) { auto target_top_dir = QUrl::fromLocalFile(target); @@ -328,13 +331,13 @@ std::optional MMCZip::extractSubDir(QuaZip* zip, const QString& sub } // ours -bool MMCZip::extractRelFile(QuaZip* zip, const QString& file, const QString& target) +bool extractRelFile(QuaZip* zip, const QString& file, const QString& target) { return JlCompress::extractFile(zip, file, target); } // ours -std::optional MMCZip::extractDir(QString fileCompressed, QString dir) +std::optional extractDir(QString fileCompressed, QString dir) { QuaZip zip(fileCompressed); if (!zip.open(QuaZip::mdUnzip)) { @@ -347,11 +350,11 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString di ; return std::nullopt; } - return MMCZip::extractSubDir(&zip, "", dir); + return extractSubDir(&zip, "", dir); } // ours -std::optional MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir) +std::optional extractDir(QString fileCompressed, QString subdir, QString dir) { QuaZip zip(fileCompressed); if (!zip.open(QuaZip::mdUnzip)) { @@ -364,11 +367,11 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString su ; return std::nullopt; } - return MMCZip::extractSubDir(&zip, subdir, dir); + return extractSubDir(&zip, subdir, dir); } // ours -bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) +bool extractFile(QString fileCompressed, QString file, QString target) { QuaZip zip(fileCompressed); if (!zip.open(QuaZip::mdUnzip)) { @@ -380,13 +383,10 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); return false; } - return MMCZip::extractRelFile(&zip, file, target); + return extractRelFile(&zip, file, target); } -bool MMCZip::collectFileListRecursively(const QString& rootDir, - const QString& subDir, - QFileInfoList* files, - MMCZip::FilterFunction excludeFilter) +bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter) { QDir rootDirectory(rootDir); if (!rootDirectory.exists()) @@ -417,7 +417,52 @@ bool MMCZip::collectFileListRecursively(const QString& rootDir, continue; } - files->append(e); // we want the original paths for MMCZip::compressDirFiles + files->append(e); // we want the original paths for compressDirFiles } return true; } + +void ExportToZipTask::executeTask() +{ + (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { + setStatus("Adding files..."); + setProgress(0, m_files.length()); + if (!m_dir.exists()) { + emitFailed(tr("Folder doesn't exist")); + return; + } + if (!m_output->isOpen() && !m_output->open(QuaZip::mdCreate)) { + emitFailed(tr("Could not create file")); + return; + } + + for (const QFileInfo& file : m_files) { + if (!isRunning()) + return; + + auto absolute = file.absoluteFilePath(); + auto relative = m_dir.relativeFilePath(absolute); + setStatus("Compresing: " + relative); + setProgress(m_progress + 1, m_progressTotal); + if (m_followSymlinks) { + if (file.isSymLink()) + absolute = file.symLinkTarget(); + else + absolute = file.canonicalFilePath(); + } + + if (!JlCompress::compressFile(m_output, absolute, m_destinationPrefix + relative)) { + emitFailed(tr("Could not read and compress %1").arg(relative)); + return; + } + } + + m_output->close(); + if (m_output->getZipError() != 0) { + emitFailed(tr("A zip error occurred")); + return; + } + emitSucceeded(); + }); +} +} // namespace MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index c7cabdc56..728dd3c89 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -2,6 +2,7 @@ /* * PolyMC - 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 @@ -35,14 +36,16 @@ #pragma once +#include +#include +#include #include #include #include #include -#include "minecraft/mod/Mod.h" - -#include #include +#include "minecraft/mod/Mod.h" +#include "tasks/Task.h" namespace MMCZip { using FilterFunction = std::function; @@ -139,4 +142,42 @@ bool extractFile(QString fileCompressed, QString file, QString dir); * \return true for success or false for failure */ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter); + +class ExportToZipTask : public Task { + public: + ExportToZipTask(QuaZip* output, + QDir dir, + QFileInfoList files, + QString destinationPrefix = "", + bool followSymlinks = false, + bool cleanUp = false) + : m_output(output) + , m_dir(dir) + , m_files(files) + , m_destinationPrefix(destinationPrefix) + , m_followSymlinks(followSymlinks) + , m_cleanUp(cleanUp) + { + setAbortable(true); + }; + ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) + : ExportToZipTask(new QuaZip(outputPath), QDir(dir), files, destinationPrefix, followSymlinks, true){}; + + virtual ~ExportToZipTask() + { + if (m_cleanUp) + delete m_output; + } + + protected: + virtual void executeTask() override; + + private: + QuaZip* m_output; + QDir m_dir; + QFileInfoList m_files; + QString m_destinationPrefix; + bool m_followSymlinks; + bool m_cleanUp; +}; } // namespace MMCZip diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 379ec79f9..1a3f8cd41 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -3,6 +3,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 @@ -41,6 +42,9 @@ #include #include #include "FileIgnoreProxy.h" +#include "QObjectPtr.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" #include "ui_ExportInstanceDialog.h" #include @@ -119,14 +123,15 @@ void SaveIcon(InstancePtr m_instance) pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png")); } -bool ExportInstanceDialog::doExport() +void ExportInstanceDialog::doExport() { auto name = FS::RemoveInvalidFilenameChars(m_instance->name()); const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(m_instance->name()), FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr); if (output.isEmpty()) { - return false; + QDialog::done(QDialog::Rejected); + return; } SaveIcon(m_instance); @@ -135,26 +140,31 @@ bool ExportInstanceDialog::doExport() if (!MMCZip::collectFileListRecursively(m_instance->instanceRoot(), nullptr, &files, std::bind(&FileIgnoreProxy::filterFile, proxyModel, std::placeholders::_1))) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); - return false; + QDialog::done(QDialog::Rejected); + return; } - if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) { - QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); - return false; - } - return true; + auto task = makeShared(output, m_instance->instanceRoot(), files, "", true); + + connect(task.get(), &Task::failed, this, [this, output](QString reason) { + CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); + QFile::remove(output); + }); + connect(task.get(), &Task::aborted, this, [output] { QFile::remove(output); }); + connect(task.get(), &Task::finished, this, [task] { task->deleteLater(); }); + + ProgressDialog progress(this); + progress.setSkipButton(true, tr("Abort")); + auto result = progress.execWithTask(task.get()); + QDialog::done(result); } void ExportInstanceDialog::done(int result) { savePackIgnore(); if (result == QDialog::Accepted) { - if (doExport()) { - QDialog::done(QDialog::Accepted); - return; - } else { - return; - } + doExport(); + return; } QDialog::done(result); } diff --git a/launcher/ui/dialogs/ExportInstanceDialog.h b/launcher/ui/dialogs/ExportInstanceDialog.h index 20a92807b..02f38f63d 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.h +++ b/launcher/ui/dialogs/ExportInstanceDialog.h @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * 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 @@ -58,7 +59,7 @@ class ExportInstanceDialog : public QDialog { virtual void done(int result); private: - bool doExport(); + void doExport(); void loadPackIgnore(); void savePackIgnore(); QString ignoreFileName(); From 79222a56e38a696168dddcc92a970242e0f34053 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 21:12:53 +0300 Subject: [PATCH 357/429] use shared pointer Signed-off-by: Trial97 use shared pointer --- launcher/MMCZip.cpp | 2 +- launcher/MMCZip.h | 24 +++++++----------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index f272bc031..ec1c4b07d 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -451,7 +451,7 @@ void ExportToZipTask::executeTask() absolute = file.canonicalFilePath(); } - if (!JlCompress::compressFile(m_output, absolute, m_destinationPrefix + relative)) { + if (!JlCompress::compressFile(m_output.get(), absolute, m_destinationPrefix + relative)) { emitFailed(tr("Could not read and compress %1").arg(relative)); return; } diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 728dd3c89..ded169cd9 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "minecraft/mod/Mod.h" #include "tasks/Task.h" @@ -145,39 +146,28 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q class ExportToZipTask : public Task { public: - ExportToZipTask(QuaZip* output, + ExportToZipTask(std::shared_ptr output, QDir dir, QFileInfoList files, QString destinationPrefix = "", - bool followSymlinks = false, - bool cleanUp = false) - : m_output(output) - , m_dir(dir) - , m_files(files) - , m_destinationPrefix(destinationPrefix) - , m_followSymlinks(followSymlinks) - , m_cleanUp(cleanUp) + bool followSymlinks = false) + : m_output(output), m_dir(dir), m_files(files), m_destinationPrefix(destinationPrefix), m_followSymlinks(followSymlinks) { setAbortable(true); }; ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : ExportToZipTask(new QuaZip(outputPath), QDir(dir), files, destinationPrefix, followSymlinks, true){}; + : ExportToZipTask(std::make_shared(outputPath), QDir(dir), files, destinationPrefix, followSymlinks){}; - virtual ~ExportToZipTask() - { - if (m_cleanUp) - delete m_output; - } + virtual ~ExportToZipTask() = default; protected: virtual void executeTask() override; private: - QuaZip* m_output; + std::shared_ptr m_output; QDir m_dir; QFileInfoList m_files; QString m_destinationPrefix; bool m_followSymlinks; - bool m_cleanUp; }; } // namespace MMCZip From 4df9df03ab2e6eddae08f95ec2d34b4e811158ed Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sun, 16 Jul 2023 23:47:47 +0300 Subject: [PATCH 358/429] Update launcher/MMCZip.cpp Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/MMCZip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index ec1c4b07d..0a334a83f 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2023 Trial97 * From ec41252535d9432d0b15228dc301e3a57e1c281d Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sun, 16 Jul 2023 23:47:54 +0300 Subject: [PATCH 359/429] Update launcher/MMCZip.h Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/MMCZip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index ded169cd9..531f4a38a 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2023 Trial97 * From ed2f680202316c2ecf33a8926866a47da17f44e2 Mon Sep 17 00:00:00 2001 From: seth Date: Sun, 16 Jul 2023 17:28:14 -0400 Subject: [PATCH 360/429] chore(docs): add backporting info to CONTRIBUTING.md Signed-off-by: seth --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4bca126f8..b2795ce49 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,3 +61,10 @@ As a bonus, you can also [cryptographically sign your commits][gh-signing-commit [gh-signing-commits]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits [gh-vigilant-mode]: https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits + + +## Backporting to Release Branches + +We use [automated backports](https://github.com/PrismLauncher/PrismLauncher/blob/develop/.github/workflows/backport.yml) to merge specific contributions from develop into `release` branches. + +This is done when pull requests are merged and have labels such as `backport release-7.x` - which should be added along with the milestone for the release. From ec32618e1158beba1cf5b4c91c3835a233eceeeb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 10:20:22 +0300 Subject: [PATCH 361/429] reveted back to add years Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index ebb100a40..f0d8ddd55 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -105,9 +105,9 @@ QString JsonCatPack::path() QDate endDate = ensureDay(now.year(), var.endTime.month, var.endTime.day); if (startDate > endDate) { // it's spans over multiple years if (endDate <= now) // end date is in the past so jump one year into the future for endDate - endDate = ensureDay(now.year() + 1, var.endTime.month, var.endTime.day); + endDate = endDate.addYears(1); else // end date is in the future so jump one year into the past for startDate - startDate = ensureDay(now.year() - 1, var.startTime.month, var.startTime.day); + startDate = startDate.addYears(-1); } if (startDate >= now && now >= endDate) From 54a091ca597608e732f00eb7f086fe26448daea1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 17 Jul 2023 10:09:01 +0200 Subject: [PATCH 362/429] fix: check if any modloader is installed Signed-off-by: Sefa Eyeoglu --- launcher/minecraft/MinecraftInstance.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 0833d5912..83b50f0bd 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -396,8 +396,11 @@ QStringList MinecraftInstance::extraArguments() agent->library()->getApplicableFiles(runtimeContext(), jar, temp1, temp2, temp3, getLocalLibraryPath()); list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument())); } - if (version->getModLoaders().value() & ResourceAPI::Quilt && settings()->get("DisableQuiltBeacon").toBool()) { - list.append("-Dloader.disable_beacon=true"); + + { + const auto& loaders = version->getModLoaders(); + if (loaders.has_value() && loaders.value() & ResourceAPI::Quilt && settings()->get("DisableQuiltBeacon").toBool()) + list.append("-Dloader.disable_beacon=true"); } return list; } From 2be630904f89c9308d3e0bab94eb9e5a4fa6ae03 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 17 Jul 2023 14:33:01 +0200 Subject: [PATCH 363/429] fix: don't take modloaders by reference Co-authored-by: TheKodeToad Signed-off-by: Sefa Eyeoglu --- launcher/minecraft/MinecraftInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 83b50f0bd..342e634f7 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -398,7 +398,7 @@ QStringList MinecraftInstance::extraArguments() } { - const auto& loaders = version->getModLoaders(); + const auto loaders = version->getModLoaders(); if (loaders.has_value() && loaders.value() & ResourceAPI::Quilt && settings()->get("DisableQuiltBeacon").toBool()) list.append("-Dloader.disable_beacon=true"); } From 0bf70d677e5cc2e72907d7df5dbb54020a1e32a9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:24:43 +0300 Subject: [PATCH 364/429] Upgraded ExportToZipTask Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 95 ++++++++++++++++++++++++++------------------- launcher/MMCZip.h | 23 ++++++----- 2 files changed, 68 insertions(+), 50 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 0a334a83f..cc7491971 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -424,45 +424,60 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q void ExportToZipTask::executeTask() { - (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - setStatus("Adding files..."); - setProgress(0, m_files.length()); - if (!m_dir.exists()) { - emitFailed(tr("Folder doesn't exist")); - return; - } - if (!m_output->isOpen() && !m_output->open(QuaZip::mdCreate)) { - emitFailed(tr("Could not create file")); - return; - } - - for (const QFileInfo& file : m_files) { - if (!isRunning()) - return; - - auto absolute = file.absoluteFilePath(); - auto relative = m_dir.relativeFilePath(absolute); - setStatus("Compresing: " + relative); - setProgress(m_progress + 1, m_progressTotal); - if (m_followSymlinks) { - if (file.isSymLink()) - absolute = file.symLinkTarget(); - else - absolute = file.canonicalFilePath(); - } - - if (!JlCompress::compressFile(m_output.get(), absolute, m_destinationPrefix + relative)) { - emitFailed(tr("Could not read and compress %1").arg(relative)); - return; - } - } - - m_output->close(); - if (m_output->getZipError() != 0) { - emitFailed(tr("A zip error occurred")); - return; - } - emitSucceeded(); - }); + (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { exportZip(); }); } + +void ExportToZipTask::exportZip() +{ + setStatus("Adding files..."); + setProgress(0, m_files.length()); + if (!m_dir.exists()) { + emitFailed(tr("Folder doesn't exist")); + return; + } + if (!m_output.isOpen() && !m_output.open(QuaZip::mdCreate)) { + emitFailed(tr("Could not create file")); + return; + } + + for (auto fileName : m_extra_files.keys()) { + if (!isRunning()) + return; + QuaZipFile indexFile(&m_output); + if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName))) { + emitFailed(tr("Could not create:") + fileName); + return; + } + indexFile.write(m_extra_files[fileName]); + } + + for (const QFileInfo& file : m_files) { + if (!isRunning()) + return; + + auto absolute = file.absoluteFilePath(); + auto relative = m_dir.relativeFilePath(absolute); + setStatus("Compresing: " + relative); + setProgress(m_progress + 1, m_progressTotal); + if (m_follow_symlinks) { + if (file.isSymLink()) + absolute = file.symLinkTarget(); + else + absolute = file.canonicalFilePath(); + } + + if (!m_exclude_files.contains(relative) && !JlCompress::compressFile(&m_output, absolute, m_destination_prefix + relative)) { + emitFailed(tr("Could not read and compress %1").arg(relative)); + return; + } + } + + m_output.close(); + if (m_output.getZipError() != 0) { + emitFailed(tr("A zip error occurred")); + return; + } + emitSucceeded(); +} + } // namespace MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 531f4a38a..60b3490fe 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -146,28 +147,30 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q class ExportToZipTask : public Task { public: - ExportToZipTask(std::shared_ptr output, - QDir dir, - QFileInfoList files, - QString destinationPrefix = "", - bool followSymlinks = false) - : m_output(output), m_dir(dir), m_files(files), m_destinationPrefix(destinationPrefix), m_followSymlinks(followSymlinks) + ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) + : m_output(outputPath), m_dir(dir), m_files(files), m_destination_prefix(destinationPrefix), m_follow_symlinks(followSymlinks) { setAbortable(true); }; ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : ExportToZipTask(std::make_shared(outputPath), QDir(dir), files, destinationPrefix, followSymlinks){}; + : ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks){}; virtual ~ExportToZipTask() = default; + void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } + void addExtraFile(QString fileName, QByteArray data) { m_extra_files.emplace(fileName, data); } + protected: virtual void executeTask() override; + void exportZip(); private: - std::shared_ptr m_output; + QuaZip m_output; QDir m_dir; QFileInfoList m_files; - QString m_destinationPrefix; - bool m_followSymlinks; + QString m_destination_prefix; + bool m_follow_symlinks; + QStringList m_exclude_files; + QHash m_extra_files; }; } // namespace MMCZip From 455c4953382b0548804ce45b5bb850641cff90f2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:25:51 +0300 Subject: [PATCH 365/429] simplify flame export Signed-off-by: Trial97 s --- .../modplatform/flame/FlamePackExportTask.cpp | 134 +++++++----------- .../modplatform/flame/FlamePackExportTask.h | 7 +- 2 files changed, 49 insertions(+), 92 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index ac0da2142..fc2cbc36d 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "Json.h" #include "MMCZip.h" @@ -64,20 +65,11 @@ void FlamePackExportTask::executeTask() bool FlamePackExportTask::abort() { - if (task != nullptr) { + if (task) { task->abort(); - task = nullptr; emitAborted(); return true; } - - if (buildZipFuture.isRunning()) { - buildZipFuture.cancel(); - // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur - // immediately. - return true; - } - return false; } @@ -336,89 +328,44 @@ void FlamePackExportTask::buildZip() setStatus(tr("Adding files...")); setProgress(4, 5); - buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - QuaZip zip(output); - if (!zip.open(QuaZip::mdCreate)) { - QFile::remove(output); - return BuildZipResult(tr("Could not create file")); - } + auto zipTask = makeShared(output, gameRoot, files, "overrides/", true); + zipTask->addExtraFile("manifest.json", generateIndex()); + zipTask->addExtraFile("modlist.html", generateHTML()); - if (buildZipFuture.isCanceled()) - return BuildZipResult(); + QStringList exclude; + std::transform(resolvedFiles.keyBegin(), resolvedFiles.keyEnd(), std::back_insert_iterator(exclude), + [this](QString file) { return gameRoot.relativeFilePath(file); }); + zipTask->setExcludeFiles(exclude); - QuaZipFile indexFile(&zip); - if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("manifest.json"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - indexFile.write(generateIndex()); - - QuaZipFile modlist(&zip); - if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - QString content = ""; - for (auto mod : resolvedFiles) { - if (mod.isMod) { - content += QString(TEMPLATE) - .replace("{name}", mod.name.toHtmlEscaped()) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped()) - .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : ""); - } - } - content = "
      " + content + "
    "; - modlist.write(content.toUtf8()); - - auto progressStep = std::make_shared(); - - size_t progress = 0; - for (const QFileInfo& file : files) { - if (buildZipFuture.isCanceled()) { - QFile::remove(output); - progressStep->state = TaskStepState::Failed; - stepProgress(*progressStep); - return BuildZipResult(); - } - progressStep->update(progress, files.length()); - stepProgress(*progressStep); - - const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!resolvedFiles.contains(file.absoluteFilePath()) && - !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { - QFile::remove(output); - return BuildZipResult(tr("Could not read and compress %1").arg(relative)); - } - progress++; - } - - zip.close(); - - if (zip.getZipError() != 0) { - QFile::remove(output); - progressStep->state = TaskStepState::Failed; - stepProgress(*progressStep); - return BuildZipResult(tr("A zip error occurred")); - } + auto progressStep = std::make_shared(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { progressStep->state = TaskStepState::Succeeded; stepProgress(*progressStep); - return BuildZipResult(); }); - connect(&buildZipWatcher, &QFutureWatcher::finished, this, &FlamePackExportTask::finish); - buildZipWatcher.setFuture(buildZipFuture); -} -void FlamePackExportTask::finish() -{ - if (buildZipFuture.isCanceled()) + connect(zipTask.get(), &Task::succeeded, this, &FlamePackExportTask::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, [this]() { + QFile::remove(output); emitAborted(); - else { - const BuildZipResult result = buildZipFuture.result(); - if (result.has_value()) - emitFailed(result.value()); - else - emitSucceeded(); - } + }); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + QFile::remove(output); + emitFailed(reason); + }); + connect(zipTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); + + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + task.reset(zipTask); + zipTask->start(); } QByteArray FlamePackExportTask::generateIndex() @@ -471,3 +418,18 @@ QByteArray FlamePackExportTask::generateIndex() return QJsonDocument(obj).toJson(QJsonDocument::Compact); } + +QByteArray FlamePackExportTask::generateHTML() +{ + QString content = ""; + for (auto mod : resolvedFiles) { + if (mod.isMod) { + content += QString(TEMPLATE) + .replace("{name}", mod.name.toHtmlEscaped()) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped()) + .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : ""); + } + } + content = "
      " + content + "
    "; + return content.toUtf8(); +} \ No newline at end of file diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 3dee0a7ea..d3dc6281e 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -19,8 +19,6 @@ #pragma once -#include -#include #include "BaseInstance.h" #include "MMCZip.h" #include "minecraft/MinecraftInstance.h" @@ -52,7 +50,6 @@ class FlamePackExportTask : public Task { const QString output; const MMCZip::FilterFunction filter; - typedef std::optional BuildZipResult; struct ResolvedFile { int addonId; int version; @@ -76,15 +73,13 @@ class FlamePackExportTask : public Task { QMap pendingHashes{}; QMap resolvedFiles{}; Task::Ptr task; - QFuture buildZipFuture; - QFutureWatcher buildZipWatcher; void collectFiles(); void collectHashes(); void makeApiRequest(); void getProjectsInfo(); void buildZip(); - void finish(); QByteArray generateIndex(); + QByteArray generateHTML(); }; From 78ee63af388ec53871cd3505a64a5d2059dbb922 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:40:01 +0300 Subject: [PATCH 366/429] simplify modrinth export Signed-off-by: Trial97 --- .../modrinth/ModrinthPackExportTask.cpp | 92 ++++++------------- .../modrinth/ModrinthPackExportTask.h | 5 - 2 files changed, 30 insertions(+), 67 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 30fe566da..0470f8319 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -55,20 +55,11 @@ void ModrinthPackExportTask::executeTask() bool ModrinthPackExportTask::abort() { - if (task != nullptr) { + if (task) { task->abort(); - task = nullptr; emitAborted(); return true; } - - if (buildZipFuture.isRunning()) { - buildZipFuture.cancel(); - // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur - // immediately. - return true; - } - return false; } @@ -205,63 +196,40 @@ void ModrinthPackExportTask::buildZip() { setStatus(tr("Adding files...")); - buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - QuaZip zip(output); - if (!zip.open(QuaZip::mdCreate)) { - QFile::remove(output); - return BuildZipResult(tr("Could not create file")); - } + auto zipTask = makeShared(output, gameRoot, files, "overrides/", true); + zipTask->addExtraFile("modrinth.index.json", generateIndex()); - if (buildZipFuture.isCanceled()) - return BuildZipResult(); + zipTask->setExcludeFiles(resolvedFiles.keys()); - QuaZipFile indexFile(&zip); - if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("modrinth.index.json"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - indexFile.write(generateIndex()); - - size_t progress = 0; - for (const QFileInfo& file : files) { - if (buildZipFuture.isCanceled()) { - QFile::remove(output); - return BuildZipResult(); - } - - setProgress(progress, files.length()); - const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!resolvedFiles.contains(relative) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { - QFile::remove(output); - return BuildZipResult(tr("Could not read and compress %1").arg(relative)); - } - progress++; - } - - zip.close(); - - if (zip.getZipError() != 0) { - QFile::remove(output); - return BuildZipResult(tr("A zip error occurred")); - } - - return BuildZipResult(); + auto progressStep = std::make_shared(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); }); - connect(&buildZipWatcher, &QFutureWatcher::finished, this, &ModrinthPackExportTask::finish); - buildZipWatcher.setFuture(buildZipFuture); -} -void ModrinthPackExportTask::finish() -{ - if (buildZipFuture.isCanceled()) + connect(zipTask.get(), &Task::succeeded, this, &ModrinthPackExportTask::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, [this]() { + QFile::remove(output); emitAborted(); - else { - const BuildZipResult result = buildZipFuture.result(); - if (result.has_value()) - emitFailed(result.value()); - else - emitSucceeded(); - } + }); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + QFile::remove(output); + emitFailed(reason); + }); + connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propogateStepProgress); + + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + task.reset(zipTask); + zipTask->start(); } QByteArray ModrinthPackExportTask::generateIndex() diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.h b/launcher/modplatform/modrinth/ModrinthPackExportTask.h index 96f292c1b..1f9e0eb77 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.h +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.h @@ -56,22 +56,17 @@ class ModrinthPackExportTask : public Task { const QString output; const MMCZip::FilterFunction filter; - typedef std::optional BuildZipResult; - ModrinthAPI api; QFileInfoList files; QMap pendingHashes; QMap resolvedFiles; Task::Ptr task; - QFuture buildZipFuture; - QFutureWatcher buildZipWatcher; void collectFiles(); void collectHashes(); void makeApiRequest(); void parseApiResponse(const std::shared_ptr response); void buildZip(); - void finish(); QByteArray generateIndex(); }; From 64041a84a2da2d0ba07d6eb663ff7cbc3b351b7b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:55:26 +0300 Subject: [PATCH 367/429] handle file removal in ExportToZipTask Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 11 +++++++++++ launcher/MMCZip.h | 12 +++++++++++- launcher/modplatform/flame/FlamePackExportTask.cpp | 6 +----- .../modplatform/modrinth/ModrinthPackExportTask.cpp | 6 +----- launcher/ui/dialogs/ExportInstanceDialog.cpp | 7 ++----- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index cc7491971..84d357874 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -480,4 +480,15 @@ void ExportToZipTask::exportZip() emitSucceeded(); } +void ExportToZipTask::emitAborted() +{ + QFile::remove(m_output_path); + Task::emitAborted(); +} +void ExportToZipTask::emitFailed(QString reason) +{ + QFile::remove(m_output_path); + Task::emitFailed(reason); +} + } // namespace MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 60b3490fe..cb49e0c0f 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -148,7 +148,12 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q class ExportToZipTask : public Task { public: ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : m_output(outputPath), m_dir(dir), m_files(files), m_destination_prefix(destinationPrefix), m_follow_symlinks(followSymlinks) + : m_output_path(outputPath) + , m_output(outputPath) + , m_dir(dir) + , m_files(files) + , m_destination_prefix(destinationPrefix) + , m_follow_symlinks(followSymlinks) { setAbortable(true); }; @@ -164,7 +169,12 @@ class ExportToZipTask : public Task { virtual void executeTask() override; void exportZip(); + protected slots: + virtual void emitAborted() override; + virtual void emitFailed(QString reason = "") override; + private: + QString m_output_path; QuaZip m_output; QDir m_dir; QFileInfoList m_files; diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index fc2cbc36d..a4efaf7cf 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -344,14 +344,10 @@ void FlamePackExportTask::buildZip() }); connect(zipTask.get(), &Task::succeeded, this, &FlamePackExportTask::emitSucceeded); - connect(zipTask.get(), &Task::aborted, this, [this]() { - QFile::remove(output); - emitAborted(); - }); + connect(zipTask.get(), &Task::aborted, this, &FlamePackExportTask::emitAborted); connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { progressStep->state = TaskStepState::Failed; stepProgress(*progressStep); - QFile::remove(output); emitFailed(reason); }); connect(zipTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 0470f8319..7290f4542 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -208,14 +208,10 @@ void ModrinthPackExportTask::buildZip() }); connect(zipTask.get(), &Task::succeeded, this, &ModrinthPackExportTask::emitSucceeded); - connect(zipTask.get(), &Task::aborted, this, [this]() { - QFile::remove(output); - emitAborted(); - }); + connect(zipTask.get(), &Task::aborted, this, &ModrinthPackExportTask::emitAborted); connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { progressStep->state = TaskStepState::Failed; stepProgress(*progressStep); - QFile::remove(output); emitFailed(reason); }); connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propogateStepProgress); diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 1a3f8cd41..d1a69b932 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -146,11 +146,8 @@ void ExportInstanceDialog::doExport() auto task = makeShared(output, m_instance->instanceRoot(), files, "", true); - connect(task.get(), &Task::failed, this, [this, output](QString reason) { - CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); - QFile::remove(output); - }); - connect(task.get(), &Task::aborted, this, [output] { QFile::remove(output); }); + connect(task.get(), &Task::failed, this, + [this, output](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); connect(task.get(), &Task::finished, this, [task] { task->deleteLater(); }); ProgressDialog progress(this); From cd9310afedace04a887a82ea1856672a26647935 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:57:52 +0300 Subject: [PATCH 368/429] replace emplace with insert Signed-off-by: Trial97 --- launcher/MMCZip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index cb49e0c0f..465550d59 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -163,7 +163,7 @@ class ExportToZipTask : public Task { virtual ~ExportToZipTask() = default; void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } - void addExtraFile(QString fileName, QByteArray data) { m_extra_files.emplace(fileName, data); } + void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); } protected: virtual void executeTask() override; From 2ea4a78541c5d6dc682ec76c2e0846fe11fe1cf9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:24:43 +0300 Subject: [PATCH 369/429] Upgraded ExportToZipTask Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 95 ++++++++++++++++++++++++++------------------- launcher/MMCZip.h | 23 ++++++----- 2 files changed, 68 insertions(+), 50 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 0a334a83f..cc7491971 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -424,45 +424,60 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q void ExportToZipTask::executeTask() { - (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - setStatus("Adding files..."); - setProgress(0, m_files.length()); - if (!m_dir.exists()) { - emitFailed(tr("Folder doesn't exist")); - return; - } - if (!m_output->isOpen() && !m_output->open(QuaZip::mdCreate)) { - emitFailed(tr("Could not create file")); - return; - } - - for (const QFileInfo& file : m_files) { - if (!isRunning()) - return; - - auto absolute = file.absoluteFilePath(); - auto relative = m_dir.relativeFilePath(absolute); - setStatus("Compresing: " + relative); - setProgress(m_progress + 1, m_progressTotal); - if (m_followSymlinks) { - if (file.isSymLink()) - absolute = file.symLinkTarget(); - else - absolute = file.canonicalFilePath(); - } - - if (!JlCompress::compressFile(m_output.get(), absolute, m_destinationPrefix + relative)) { - emitFailed(tr("Could not read and compress %1").arg(relative)); - return; - } - } - - m_output->close(); - if (m_output->getZipError() != 0) { - emitFailed(tr("A zip error occurred")); - return; - } - emitSucceeded(); - }); + (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { exportZip(); }); } + +void ExportToZipTask::exportZip() +{ + setStatus("Adding files..."); + setProgress(0, m_files.length()); + if (!m_dir.exists()) { + emitFailed(tr("Folder doesn't exist")); + return; + } + if (!m_output.isOpen() && !m_output.open(QuaZip::mdCreate)) { + emitFailed(tr("Could not create file")); + return; + } + + for (auto fileName : m_extra_files.keys()) { + if (!isRunning()) + return; + QuaZipFile indexFile(&m_output); + if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName))) { + emitFailed(tr("Could not create:") + fileName); + return; + } + indexFile.write(m_extra_files[fileName]); + } + + for (const QFileInfo& file : m_files) { + if (!isRunning()) + return; + + auto absolute = file.absoluteFilePath(); + auto relative = m_dir.relativeFilePath(absolute); + setStatus("Compresing: " + relative); + setProgress(m_progress + 1, m_progressTotal); + if (m_follow_symlinks) { + if (file.isSymLink()) + absolute = file.symLinkTarget(); + else + absolute = file.canonicalFilePath(); + } + + if (!m_exclude_files.contains(relative) && !JlCompress::compressFile(&m_output, absolute, m_destination_prefix + relative)) { + emitFailed(tr("Could not read and compress %1").arg(relative)); + return; + } + } + + m_output.close(); + if (m_output.getZipError() != 0) { + emitFailed(tr("A zip error occurred")); + return; + } + emitSucceeded(); +} + } // namespace MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 531f4a38a..60b3490fe 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -146,28 +147,30 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q class ExportToZipTask : public Task { public: - ExportToZipTask(std::shared_ptr output, - QDir dir, - QFileInfoList files, - QString destinationPrefix = "", - bool followSymlinks = false) - : m_output(output), m_dir(dir), m_files(files), m_destinationPrefix(destinationPrefix), m_followSymlinks(followSymlinks) + ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) + : m_output(outputPath), m_dir(dir), m_files(files), m_destination_prefix(destinationPrefix), m_follow_symlinks(followSymlinks) { setAbortable(true); }; ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : ExportToZipTask(std::make_shared(outputPath), QDir(dir), files, destinationPrefix, followSymlinks){}; + : ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks){}; virtual ~ExportToZipTask() = default; + void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } + void addExtraFile(QString fileName, QByteArray data) { m_extra_files.emplace(fileName, data); } + protected: virtual void executeTask() override; + void exportZip(); private: - std::shared_ptr m_output; + QuaZip m_output; QDir m_dir; QFileInfoList m_files; - QString m_destinationPrefix; - bool m_followSymlinks; + QString m_destination_prefix; + bool m_follow_symlinks; + QStringList m_exclude_files; + QHash m_extra_files; }; } // namespace MMCZip From fe73d696cb714d724948176f0bfbb356412b0f11 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 16:57:52 +0300 Subject: [PATCH 370/429] replace emplace with insert Signed-off-by: Trial97 --- launcher/MMCZip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 60b3490fe..ce76bc773 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -158,7 +158,7 @@ class ExportToZipTask : public Task { virtual ~ExportToZipTask() = default; void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } - void addExtraFile(QString fileName, QByteArray data) { m_extra_files.emplace(fileName, data); } + void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); } protected: virtual void executeTask() override; From b0940d696baa24ddcf29a5d3393196c1047dcd3f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 17:42:15 +0300 Subject: [PATCH 371/429] Added QFutureWatcher Signed-off-by: Trial97 abort forgot Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 61 +++++++++++++------- launcher/MMCZip.h | 20 ++++++- launcher/ui/dialogs/ExportInstanceDialog.cpp | 7 +-- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index cc7491971..acd6bf7e4 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -423,37 +423,36 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q } void ExportToZipTask::executeTask() -{ - (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { exportZip(); }); -} - -void ExportToZipTask::exportZip() { setStatus("Adding files..."); setProgress(0, m_files.length()); + m_build_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return exportZip(); }); + connect(&m_build_zip_watcher, &QFutureWatcher::finished, this, &ExportToZipTask::finish); + m_build_zip_watcher.setFuture(m_build_zip_future); +} + +auto ExportToZipTask::exportZip() -> ZipResult +{ if (!m_dir.exists()) { - emitFailed(tr("Folder doesn't exist")); - return; + return ZipResult(tr("Folder doesn't exist")); } if (!m_output.isOpen() && !m_output.open(QuaZip::mdCreate)) { - emitFailed(tr("Could not create file")); - return; + return ZipResult(tr("Could not create file")); } for (auto fileName : m_extra_files.keys()) { - if (!isRunning()) - return; + if (m_build_zip_future.isCanceled()) + return ZipResult(); QuaZipFile indexFile(&m_output); if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName))) { - emitFailed(tr("Could not create:") + fileName); - return; + return ZipResult(tr("Could not create:") + fileName); } indexFile.write(m_extra_files[fileName]); } for (const QFileInfo& file : m_files) { - if (!isRunning()) - return; + if (m_build_zip_future.isCanceled()) + return ZipResult(); auto absolute = file.absoluteFilePath(); auto relative = m_dir.relativeFilePath(absolute); @@ -467,17 +466,39 @@ void ExportToZipTask::exportZip() } if (!m_exclude_files.contains(relative) && !JlCompress::compressFile(&m_output, absolute, m_destination_prefix + relative)) { - emitFailed(tr("Could not read and compress %1").arg(relative)); - return; + return ZipResult(tr("Could not read and compress %1").arg(relative)); } } m_output.close(); if (m_output.getZipError() != 0) { - emitFailed(tr("A zip error occurred")); - return; + return ZipResult(tr("A zip error occurred")); } - emitSucceeded(); + return ZipResult(); +} + +void ExportToZipTask::finish() +{ + if (m_build_zip_future.isCanceled()) { + QFile::remove(m_output_path); + emitAborted(); + } else if (auto result = m_build_zip_future.result(); result.has_value()) { + QFile::remove(m_output_path); + emitFailed(result.value()); + } else { + emitSucceeded(); + } +} + +bool ExportToZipTask::abort() +{ + if (m_build_zip_future.isRunning()) { + m_build_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 MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index ce76bc773..bc527ad1b 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include @@ -148,7 +150,12 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q class ExportToZipTask : public Task { public: ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : m_output(outputPath), m_dir(dir), m_files(files), m_destination_prefix(destinationPrefix), m_follow_symlinks(followSymlinks) + : m_output_path(outputPath) + , m_output(outputPath) + , m_dir(dir) + , m_files(files) + , m_destination_prefix(destinationPrefix) + , m_follow_symlinks(followSymlinks) { setAbortable(true); }; @@ -160,11 +167,17 @@ class ExportToZipTask : public Task { void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); } + typedef std::optional ZipResult; + protected: virtual void executeTask() override; - void exportZip(); + bool abort() override; + + ZipResult exportZip(); + void finish(); private: + QString m_output_path; QuaZip m_output; QDir m_dir; QFileInfoList m_files; @@ -172,5 +185,8 @@ class ExportToZipTask : public Task { bool m_follow_symlinks; QStringList m_exclude_files; QHash m_extra_files; + + QFuture m_build_zip_future; + QFutureWatcher m_build_zip_watcher; }; } // namespace MMCZip diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 1a3f8cd41..d1a69b932 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -146,11 +146,8 @@ void ExportInstanceDialog::doExport() auto task = makeShared(output, m_instance->instanceRoot(), files, "", true); - connect(task.get(), &Task::failed, this, [this, output](QString reason) { - CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); - QFile::remove(output); - }); - connect(task.get(), &Task::aborted, this, [output] { QFile::remove(output); }); + connect(task.get(), &Task::failed, this, + [this, output](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); connect(task.get(), &Task::finished, this, [task] { task->deleteLater(); }); ProgressDialog progress(this); From 1fbb41f5e2c4426b1b1e469c78cfbc7e1c4d7999 Mon Sep 17 00:00:00 2001 From: Josiah Glosson Date: Mon, 17 Jul 2023 17:07:06 -0500 Subject: [PATCH 372/429] Make Launch Offline not launch online in 1.6+ Signed-off-by: Josiah Glosson --- launcher/minecraft/auth/AuthSession.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/minecraft/auth/AuthSession.cpp b/launcher/minecraft/auth/AuthSession.cpp index 6bea74a37..2c06beaa2 100644 --- a/launcher/minecraft/auth/AuthSession.cpp +++ b/launcher/minecraft/auth/AuthSession.cpp @@ -26,6 +26,7 @@ bool AuthSession::MakeOffline(QString offline_playername) return false; } session = "-"; + access_token = "0"; player_name = offline_playername; status = PlayableOffline; return true; From 2eff1de560c9b4ac76316d2c6d812438b4488222 Mon Sep 17 00:00:00 2001 From: Dallas Strouse Date: Mon, 17 Jul 2023 00:29:24 -0500 Subject: [PATCH 373/429] Update Flatpak manifest Signed-off-by: Dallas Strouse --- .gitmodules | 3 + flatpak/libdecor.json | 22 ++++ flatpak/org.prismlauncher.PrismLauncher.yml | 115 ++++++++++++++---- ...on-t-crash-on-calls-to-focus-or-icon.patch | 24 ++++ ...ning-about-being-an-unofficial-patch.patch | 17 +++ ...007-Platform-Prefer-Wayland-over-X11.patch | 20 +++ flatpak/patches/weird_libdecor.patch | 40 ++++++ flatpak/prismlauncher | 4 +- flatpak/shared-modules | 1 + 9 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 flatpak/libdecor.json create mode 100644 flatpak/patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch create mode 100644 flatpak/patches/0005-Add-warning-about-being-an-unofficial-patch.patch create mode 100644 flatpak/patches/0007-Platform-Prefer-Wayland-over-X11.patch create mode 100644 flatpak/patches/weird_libdecor.patch create mode 160000 flatpak/shared-modules diff --git a/.gitmodules b/.gitmodules index 87703fee5..0f437d277 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "libraries/cmark"] path = libraries/cmark url = https://github.com/commonmark/cmark.git +[submodule "flatpak/shared-modules"] + path = flatpak/shared-modules + url = https://github.com/flathub/shared-modules.git diff --git a/flatpak/libdecor.json b/flatpak/libdecor.json new file mode 100644 index 000000000..12afad69f --- /dev/null +++ b/flatpak/libdecor.json @@ -0,0 +1,22 @@ +{ + "name": "libdecor", + "buildsystem": "meson", + "config-opts": [ + "-Ddemo=false" + ], + "sources": [ + { + "type": "git", + "url": "https://gitlab.freedesktop.org/libdecor/libdecor.git", + "commit": "73260393a97291c887e1074ab7f318e031be0ac6" + }, + { + "type": "patch", + "path": "patches/weird_libdecor.patch" + } + ], + "cleanup": [ + "/include", + "/lib/pkgconfig" + ] +} diff --git a/flatpak/org.prismlauncher.PrismLauncher.yml b/flatpak/org.prismlauncher.PrismLauncher.yml index 0524946f0..a9b9762f5 100644 --- a/flatpak/org.prismlauncher.PrismLauncher.yml +++ b/flatpak/org.prismlauncher.PrismLauncher.yml @@ -5,13 +5,6 @@ sdk: org.kde.Sdk sdk-extensions: - org.freedesktop.Sdk.Extension.openjdk17 - org.freedesktop.Sdk.Extension.openjdk8 -add-extensions: - com.valvesoftware.Steam.Utility.gamescope: - version: stable - add-ld-path: lib - no-autodownload: true - autodelete: false - directory: utils/gamescope command: prismlauncher finish-args: @@ -26,21 +19,31 @@ finish-args: # Mod drag&drop - --filesystem=xdg-download:ro +cleanup: + - /lib/libGLU* + modules: + # Might be needed by some Controller mods (see https://github.com/isXander/Controlify/issues/31) + - shared-modules/libusb/libusb.json + + # Needed for proper Wayland support + - libdecor.json + - name: prismlauncher buildsystem: cmake-ninja + builddir: true config-opts: - -DLauncher_BUILD_PLATFORM=flatpak - - -DCMAKE_BUILD_TYPE=Debug + - -DCMAKE_BUILD_TYPE=RelWithDebInfo - -DLauncher_QT_VERSION_MAJOR=5 build-options: env: JAVA_HOME: /usr/lib/sdk/openjdk17/jvm/openjdk-17 JAVA_COMPILER: /usr/lib/sdk/openjdk17/jvm/openjdk-17/bin/javac sources: - - type: dir - path: ../ - builddir: true + - type: dir + path: ../ + - name: openjdk buildsystem: simple build-commands: @@ -49,14 +52,45 @@ modules: - mv /app/jre /app/jdk/17 - /usr/lib/sdk/openjdk8/install.sh - mv /app/jre /app/jdk/8 - cleanup: [/jre] + cleanup: + - /jre + + - name: glfw + buildsystem: cmake-ninja + config-opts: + - -DCMAKE_BUILD_TYPE=RelWithDebInfo + - -DBUILD_SHARED_LIBS:BOOL=ON + - -DGLFW_USE_WAYLAND=ON + sources: + - type: git + url: https://github.com/glfw/glfw.git + commit: 3fa2360720eeba1964df3c0ecf4b5df8648a8e52 + - type: patch + path: patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch + - type: patch + path: patches/0005-Add-warning-about-being-an-unofficial-patch.patch + - type: patch + path: patches/0007-Platform-Prefer-Wayland-over-X11.patch + cleanup: + - /include + - /lib/cmake + - /lib/pkgconfig + - name: xrandr buildsystem: autotools sources: - type: archive - url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.1.tar.xz - sha256: 7bc76daf9d72f8aff885efad04ce06b90488a1a169d118dea8a2b661832e8762 - cleanup: [/share/man, /bin/xkeystone] + url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.2.tar.xz + sha256: c8bee4790d9058bacc4b6246456c58021db58a87ddda1a9d0139bf5f18f1f240 + x-checker-data: + type: anitya + project-id: 14957 + stable-only: true + url-template: https://xorg.freedesktop.org/archive/individual/app/xrandr-$version.tar.xz + cleanup: + - /share/man + - /bin/xkeystone + - name: gamemode buildsystem: meson config-opts: @@ -67,19 +101,56 @@ modules: # post-install is running inside the build dir, we need it from the source though - install -Dm755 ../data/gamemoderun -t /app/bin sources: - - type: git - url: https://github.com/FeralInteractive/gamemode - tag: "1.7" - commit: 4dc99dff76218718763a6b07fc1900fa6d1dafd9 + - type: archive + archive-type: tar-gzip + url: https://api.github.com/repos/FeralInteractive/gamemode/tarball/1.7 + sha256: 57ce73ba605d1cf12f8d13725006a895182308d93eba0f69f285648449641803 + x-checker-data: + type: json + url: https://api.github.com/repos/FeralInteractive/gamemode/releases/latest + version-query: .tag_name + url-query: .tarball_url + timestamp-query: .published_at + cleanup: + - /include + - /lib/pkgconfig + - /lib/libgamemodeauto.a + + - name: glxinfo + buildsystem: meson + config-opts: + - --bindir=/app/mesa-demos + - -Degl=disabled + - -Dglut=disabled + - -Dosmesa=disabled + - -Dvulkan=disabled + - -Dwayland=disabled + post-install: + - mv -v /app/mesa-demos/glxinfo /app/bin + sources: + - type: archive + url: https://archive.mesa3d.org/demos/mesa-demos-9.0.0.tar.xz + sha256: 3046a3d26a7b051af7ebdd257a5f23bfeb160cad6ed952329cdff1e9f1ed496b + x-checker-data: + type: anitya + project-id: 16781 + stable-only: true + url-template: https://archive.mesa3d.org/demos/mesa-demos-$version.tar.xz + cleanup: + - /include + - /mesa-demos + - /share + modules: + - shared-modules/glu/glu-9.json + - name: enhance buildsystem: simple build-commands: - - mkdir -p /app/utils/gamescope - install -Dm755 prime-run /app/bin/prime-run - mv /app/bin/prismlauncher /app/bin/prismrun - install -Dm755 prismlauncher /app/bin/prismlauncher sources: - type: file - path: ../flatpak/prime-run + path: prime-run - type: file - path: ../flatpak/prismlauncher + path: prismlauncher diff --git a/flatpak/patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch b/flatpak/patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch new file mode 100644 index 000000000..9130e856c --- /dev/null +++ b/flatpak/patches/0003-Don-t-crash-on-calls-to-focus-or-icon.patch @@ -0,0 +1,24 @@ +diff --git a/src/wl_window.c b/src/wl_window.c +index 52d3b9eb..4ac4eb5d 100644 +--- a/src/wl_window.c ++++ b/src/wl_window.c +@@ -2117,8 +2117,7 @@ void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title) + void _glfwSetWindowIconWayland(_GLFWwindow* window, + int count, const GLFWimage* images) + { +- _glfwInputError(GLFW_FEATURE_UNAVAILABLE, +- "Wayland: The platform does not support setting the window icon"); ++ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the window icon\n"); + } + + void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos) +@@ -2361,8 +2360,7 @@ void _glfwRequestWindowAttentionWayland(_GLFWwindow* window) + + void _glfwFocusWindowWayland(_GLFWwindow* window) + { +- _glfwInputError(GLFW_FEATURE_UNAVAILABLE, +- "Wayland: The platform does not support setting the input focus"); ++ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the input focus\n"); + } + + void _glfwSetWindowMonitorWayland(_GLFWwindow* window, diff --git a/flatpak/patches/0005-Add-warning-about-being-an-unofficial-patch.patch b/flatpak/patches/0005-Add-warning-about-being-an-unofficial-patch.patch new file mode 100644 index 000000000..b031d739f --- /dev/null +++ b/flatpak/patches/0005-Add-warning-about-being-an-unofficial-patch.patch @@ -0,0 +1,17 @@ +diff --git a/src/init.c b/src/init.c +index 06dbb3f2..a7c6da86 100644 +--- a/src/init.c ++++ b/src/init.c +@@ -449,6 +449,12 @@ GLFWAPI int glfwInit(void) + _glfw.initialized = GLFW_TRUE; + + glfwDefaultWindowHints(); ++ ++ fprintf(stderr, "!!! Patched GLFW from https://github.com/Admicos/minecraft-wayland\n" ++ "!!! If any issues with the window, or some issues with rendering, occur, " ++ "first try with the built-in GLFW, and if that solves the issue, report there first.\n" ++ "!!! Use outside Minecraft is untested, and things might break.\n"); ++ + return GLFW_TRUE; + } + diff --git a/flatpak/patches/0007-Platform-Prefer-Wayland-over-X11.patch b/flatpak/patches/0007-Platform-Prefer-Wayland-over-X11.patch new file mode 100644 index 000000000..4eeb81309 --- /dev/null +++ b/flatpak/patches/0007-Platform-Prefer-Wayland-over-X11.patch @@ -0,0 +1,20 @@ +diff --git a/src/platform.c b/src/platform.c +index c5966ae7..3e7442f9 100644 +--- a/src/platform.c ++++ b/src/platform.c +@@ -49,12 +49,12 @@ static const struct + #if defined(_GLFW_COCOA) + { GLFW_PLATFORM_COCOA, _glfwConnectCocoa }, + #endif +-#if defined(_GLFW_X11) +- { GLFW_PLATFORM_X11, _glfwConnectX11 }, +-#endif + #if defined(_GLFW_WAYLAND) + { GLFW_PLATFORM_WAYLAND, _glfwConnectWayland }, + #endif ++#if defined(_GLFW_X11) ++ { GLFW_PLATFORM_X11, _glfwConnectX11 }, ++#endif + }; + + GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) diff --git a/flatpak/patches/weird_libdecor.patch b/flatpak/patches/weird_libdecor.patch new file mode 100644 index 000000000..3a400b820 --- /dev/null +++ b/flatpak/patches/weird_libdecor.patch @@ -0,0 +1,40 @@ +diff --git a/src/libdecor.c b/src/libdecor.c +index a9c1106..1aa38b3 100644 +--- a/src/libdecor.c ++++ b/src/libdecor.c +@@ -1391,22 +1391,32 @@ calculate_priority(const struct libdecor_plugin_description *plugin_description) + static bool + check_symbol_conflicts(const struct libdecor_plugin_description *plugin_description) + { ++ bool ret = true; + char * const *symbol; ++ void* main_prog = dlopen(NULL, RTLD_LAZY); ++ if (!main_prog) { ++ fprintf(stderr, "Plugin \"%s\" couldn't check conflicting symbols: \"%s\".\n", ++ plugin_description->description, dlerror()); ++ return false; ++ } ++ + + symbol = plugin_description->conflicting_symbols; + while (*symbol) { + dlerror(); +- dlsym (RTLD_DEFAULT, *symbol); ++ dlsym (main_prog, *symbol); + if (!dlerror()) { + fprintf(stderr, "Plugin \"%s\" uses conflicting symbol \"%s\".\n", + plugin_description->description, *symbol); +- return false; ++ ret = false; ++ break; + } + + symbol++; + } + +- return true; ++ dlclose(main_prog); ++ return ret; + } + + static struct plugin_loader * diff --git a/flatpak/prismlauncher b/flatpak/prismlauncher index bb8767113..039d890d2 100644 --- a/flatpak/prismlauncher +++ b/flatpak/prismlauncher @@ -5,7 +5,7 @@ for i in {0..9}; do test -S "$XDG_RUNTIME_DIR"/discord-ipc-"$i" || ln -sf {app/com.discordapp.Discord,"$XDG_RUNTIME_DIR"}/discord-ipc-"$i"; done -export PATH="${PATH}${PATH:+:}/app/utils/gamescope/bin:/usr/lib/extensions/vulkan/MangoHud/bin" -export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${LD_LIBRARY_PATH:+:}/usr/lib/extensions/vulkan/MangoHud/\$LIB/" +export PATH="${PATH}${PATH:+:}/usr/lib/extensions/vulkan/gamescope/bin:/usr/lib/extensions/vulkan/MangoHud/bin" +export VK_LAYER_PATH="/usr/lib/extensions/vulkan/share/vulkan/implicit_layer.d/" exec /app/bin/prismrun "$@" diff --git a/flatpak/shared-modules b/flatpak/shared-modules new file mode 160000 index 000000000..45094ca57 --- /dev/null +++ b/flatpak/shared-modules @@ -0,0 +1 @@ +Subproject commit 45094ca570be383d06df729b6972830ec63bd3df From f8fcb98c6837c0bf66c2175ea98198449c36b165 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 18 Jul 2023 09:06:49 +0200 Subject: [PATCH 374/429] fix: generate predictable UUIDs for offline accounts Signed-off-by: Sefa Eyeoglu --- launcher/minecraft/auth/MinecraftAccount.cpp | 32 +++++++++++++++++++- launcher/minecraft/auth/MinecraftAccount.h | 2 ++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index 3b050ac0f..d7b061e5e 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -37,6 +37,7 @@ #include "MinecraftAccount.h" +#include #include #include #include @@ -100,7 +101,7 @@ MinecraftAccountPtr MinecraftAccount::createOffline(const QString &username) account->data.yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]")); account->data.minecraftEntitlement.ownsMinecraft = true; account->data.minecraftEntitlement.canPlayMinecraft = true; - account->data.minecraftProfile.id = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]")); + account->data.minecraftProfile.id = uuidFromUsername(username).toString().remove(QRegularExpression("[{}-]")); account->data.minecraftProfile.name = username; account->data.minecraftProfile.validity = Katabasis::Validity::Certain; return account; @@ -334,3 +335,32 @@ void MinecraftAccount::incrementUses() qWarning() << "Profile" << data.profileId() << "is now in use."; } } + +QUuid MinecraftAccount::uuidFromUsername(QString username) { + auto input = QString("OfflinePlayer:%1").arg(username).toUtf8(); + + // basically a reimplementation of Java's UUID#nameUUIDFromBytes + QByteArray digest = QCryptographicHash::hash(input, QCryptographicHash::Md5); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + auto bOr = [](QByteArray& array, int index, char value) { + array[index] = array.at(index) | value; + }; + auto bAnd = [](QByteArray& array, int index, char value) { + array[index] = array.at(index) & value; + }; +#else + auto bOr = [](QByteArray& array, qsizetype index, char value) { + array[index] |= value; + }; + auto bAnd = [](QByteArray& array, qsizetype index, char value) { + array[index] &= value; + }; +#endif + bAnd(digest, 6, (char) 0x0f); // clear version + bOr(digest, 6, (char) 0x30); // set to version 3 + bAnd(digest, 8, (char) 0x3f); // clear variant + bOr(digest, 8, (char) 0x80); // set to IETF variant + + return QUuid::fromRfc4122(digest); +} diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h index 0dcaeb531..67623a5ab 100644 --- a/launcher/minecraft/auth/MinecraftAccount.h +++ b/launcher/minecraft/auth/MinecraftAccount.h @@ -98,6 +98,8 @@ public: /* construction */ static MinecraftAccountPtr loadFromJsonV2(const QJsonObject &json); static MinecraftAccountPtr loadFromJsonV3(const QJsonObject &json); + static QUuid uuidFromUsername(QString username); + //! Saves a MinecraftAccount to a JSON object and returns it. QJsonObject saveToJson() const; From 391497645ff2054dbc1eac48c8bc49133b86b319 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jul 2023 22:33:39 +0300 Subject: [PATCH 375/429] feat:made flame instace creation use metadata for recommended version Signed-off-by: Trial97 --- .../flame/FlameInstanceCreationTask.cpp | 116 ++++++++++++------ .../flame/FlameInstanceCreationTask.h | 6 +- 2 files changed, 80 insertions(+), 42 deletions(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index b57db288a..710ec06ac 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -57,15 +57,11 @@ #include #include +#include "meta/Index.h" +#include "meta/VersionList.h" #include "minecraft/World.h" #include "minecraft/mod/tasks/LocalResourceParse.h" - -const static QMap forgemap = { { "1.2.5", "3.4.9.171" }, - { "1.4.2", "6.0.1.355" }, - { "1.4.7", "6.6.2.534" }, - { "1.5.2", "7.8.1.737" } }; - static const FlameAPI api; bool FlameCreationTask::abort() @@ -259,6 +255,51 @@ bool FlameCreationTask::updateInstance() return false; } +QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, QString version, QString mcVersion) +{ + if (version == "recommended") { + auto vlist = APPLICATION->metadataIndex()->get(uid); + if (!vlist) { + setError(tr("Failed to get local metadata index for %1").arg(uid)); + return Q_NULLPTR; + } + + if (!vlist->isLoaded()) { + vlist->load(Net::Mode::Online); + } + + for (int i = 0; i < vlist->versions().size(); i++) { + auto version = vlist->versions().at(i); + // first recommended build we find, we use. + if (!version->isRecommended()) + continue; + auto reqs = version->requiredSet(); + + // filter by minecraft version, if the loader depends on a certain version. + // not all mod loaders depend on a given Minecraft version, so we won't do this + // filtering for those loaders. + if (loaderType == "forge") { + auto iter = std::find_if(reqs.begin(), reqs.end(), [mcVersion](const Meta::Require& req) { + return req.uid == "net.minecraft" && req.equalsVersion == mcVersion; + }); + if (iter == reqs.end()) + continue; + } + return version->descriptor(); + } + + setError(tr("Failed to find version for %1 loader").arg(loaderType)); + return Q_NULLPTR; + } + + if (version == Q_NULLPTR || version.isEmpty()) { + emitFailed(tr("No loader version set for modpack!")); + return Q_NULLPTR; + } + + return version; +} + bool FlameCreationTask::createInstance() { QEventLoop loop; @@ -297,22 +338,29 @@ bool FlameCreationTask::createInstance() } } - QString forgeVersion; - QString fabricVersion; - // TODO: is Quilt relevant here? + QString loaderType; + QString loaderUid; + QString loaderVersion; + for (auto& loader : m_pack.minecraft.modLoaders) { auto id = loader.id; if (id.startsWith("forge-")) { id.remove("forge-"); - forgeVersion = id; - continue; - } - if (id.startsWith("fabric-")) { + loaderType = "forge"; + loaderUid = "net.minecraftforge"; + } else if (loaderType == "fabric") { id.remove("fabric-"); - fabricVersion = id; + loaderType = "fabric"; + loaderUid = "net.fabricmc.fabric-loader"; + } else if (loaderType == "quilt") { + id.remove("quilt-"); + loaderType = "quilt"; + loaderUid = "org.quiltmc.quilt-loader"; + } else { + logWarning(tr("Unknown mod loader in manifest: %1").arg(id)); continue; } - logWarning(tr("Unknown mod loader in manifest: %1").arg(id)); + loaderVersion = id; } QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg"); @@ -329,19 +377,12 @@ bool FlameCreationTask::createInstance() auto components = instance.getPackProfile(); components->buildingFromScratch(); components->setComponentVersion("net.minecraft", mcVersion, true); - if (!forgeVersion.isEmpty()) { - // FIXME: dirty, nasty, hack. Proper solution requires dependency resolution and knowledge of the metadata. - if (forgeVersion == "recommended") { - if (forgemap.contains(mcVersion)) { - forgeVersion = forgemap[mcVersion]; - } else { - logWarning(tr("Could not map recommended Forge version for Minecraft %1").arg(mcVersion)); - } - } - components->setComponentVersion("net.minecraftforge", forgeVersion); + if (!loaderType.isEmpty()) { + auto version = getVersionForLoader(loaderUid, loaderType, loaderVersion, mcVersion); + if (version == Q_NULLPTR || version.isEmpty()) + return false; + components->setComponentVersion(loaderUid, version); } - if (!fabricVersion.isEmpty()) - components->setComponentVersion("net.fabricmc.fabric-loader", fabricVersion); if (m_instIcon != "default") { instance.setIconKey(m_instIcon); @@ -502,7 +543,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) m_files_job.reset(); setError(reason); }); - connect(m_files_job.get(), &NetJob::progress, this, [this](qint64 current, qint64 total){ + connect(m_files_job.get(), &NetJob::progress, this, [this](qint64 current, qint64 total) { setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); setProgress(current, total); }); @@ -545,7 +586,6 @@ void FlameCreationTask::copyBlockedMods(QList const& blocked_mods) setAbortable(true); } - void FlameCreationTask::validateZIPResouces() { qDebug() << "Validating whether resources stored as .zip are in the right place"; @@ -569,7 +609,7 @@ void FlameCreationTask::validateZIPResouces() return localPath; }; - auto installWorld = [this](QString worldPath){ + auto installWorld = [this](QString worldPath) { qDebug() << "Installing World from" << worldPath; QFileInfo worldFileInfo(worldPath); World w(worldFileInfo); @@ -586,29 +626,29 @@ void FlameCreationTask::validateZIPResouces() QString worldPath; switch (type) { - case PackedResourceType::Mod : + case PackedResourceType::Mod: validatePath(fileName, targetFolder, "mods"); break; - case PackedResourceType::ResourcePack : + case PackedResourceType::ResourcePack: validatePath(fileName, targetFolder, "resourcepacks"); break; - case PackedResourceType::TexturePack : + case PackedResourceType::TexturePack: validatePath(fileName, targetFolder, "texturepacks"); break; - case PackedResourceType::DataPack : + case PackedResourceType::DataPack: validatePath(fileName, targetFolder, "datapacks"); break; - case PackedResourceType::ShaderPack : + case PackedResourceType::ShaderPack: // in theroy flame API can't do this but who knows, that *may* change ? // better to handle it if it *does* occure in the future validatePath(fileName, targetFolder, "shaderpacks"); break; - case PackedResourceType::WorldSave : + case PackedResourceType::WorldSave: worldPath = validatePath(fileName, targetFolder, "saves"); installWorld(worldPath); break; - case PackedResourceType::UNKNOWN : - default : + case PackedResourceType::UNKNOWN: + default: qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is."; break; } diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h index 0ae4735bf..603d3693e 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.h +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h @@ -57,10 +57,7 @@ class FlameCreationTask final : public InstanceCreationTask { QString id, QString version_id, QString original_instance_id = {}) - : InstanceCreationTask() - , m_parent(parent) - , m_managed_id(std::move(id)) - , m_managed_version_id(std::move(version_id)) + : InstanceCreationTask(), m_parent(parent), m_managed_id(std::move(id)), m_managed_version_id(std::move(version_id)) { setStagingPath(staging_path); setParentSettings(global_settings); @@ -78,6 +75,7 @@ class FlameCreationTask final : public InstanceCreationTask { void setupDownloadJob(QEventLoop&); void copyBlockedMods(QList const& blocked_mods); void validateZIPResouces(); + QString getVersionForLoader(QString uid, QString loaderType, QString version, QString mcVersion); private: QWidget* m_parent = nullptr; From f393aa684e74ca870eb2108e2b74a7c93a70c366 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jul 2023 23:59:43 +0300 Subject: [PATCH 376/429] wait to load metadata Signed-off-by: Trial97 --- .../flame/FlameInstanceCreationTask.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 710ec06ac..e8453c603 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -255,17 +255,23 @@ bool FlameCreationTask::updateInstance() return false; } -QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, QString version, QString mcVersion) +QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, QString loaderVersion, QString mcVersion) { - if (version == "recommended") { + if (loaderVersion == "recommended") { auto vlist = APPLICATION->metadataIndex()->get(uid); if (!vlist) { setError(tr("Failed to get local metadata index for %1").arg(uid)); - return Q_NULLPTR; + return {}; } if (!vlist->isLoaded()) { - vlist->load(Net::Mode::Online); + QEventLoop loadVersionLoop; + auto task = vlist->getLoadTask(); + connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit); + if (!task->isRunning()) + task->start(); + + loadVersionLoop.exec(); } for (int i = 0; i < vlist->versions().size(); i++) { @@ -289,15 +295,15 @@ QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, } setError(tr("Failed to find version for %1 loader").arg(loaderType)); - return Q_NULLPTR; + return {}; } - if (version == Q_NULLPTR || version.isEmpty()) { + if (loaderVersion.isEmpty()) { emitFailed(tr("No loader version set for modpack!")); - return Q_NULLPTR; + return {}; } - return version; + return loaderVersion; } bool FlameCreationTask::createInstance() @@ -379,7 +385,7 @@ bool FlameCreationTask::createInstance() components->setComponentVersion("net.minecraft", mcVersion, true); if (!loaderType.isEmpty()) { auto version = getVersionForLoader(loaderUid, loaderType, loaderVersion, mcVersion); - if (version == Q_NULLPTR || version.isEmpty()) + if (version.isEmpty()) return false; components->setComponentVersion(loaderUid, version); } From b7bccb905829eebea039a32edf93606f5fc5defa Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 19 Jul 2023 12:27:02 +0300 Subject: [PATCH 377/429] removed subdirectory flag Signed-off-by: Trial97 --- launcher/ui/themes/ThemeManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 9ed8e1297..321f7db4a 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -84,7 +84,7 @@ void ThemeManager::initializeThemes() QString themeFolder = QDir("./themes/").absoluteFilePath(""); themeDebugLog() << "Theme Folder Path: " << themeFolder; - QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot); while (directoryIterator.hasNext()) { QDir dir(directoryIterator.next()); QFileInfo themeJson(dir.absoluteFilePath("theme.json")); @@ -208,7 +208,7 @@ void ThemeManager::initializeCatPacks() loadFiles(catpacksDir); - QDirIterator directoryIterator(catpacksFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QDirIterator directoryIterator(catpacksFolder, QDir::Dirs | QDir::NoDotAndDotDot); while (directoryIterator.hasNext()) { QDir dir(directoryIterator.next()); QFileInfo manifest(dir.absoluteFilePath("catpack.json")); From f8d9cd9a0344d8afa806e7b3b73e8b3c59315d17 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 19 Jul 2023 23:08:16 +0300 Subject: [PATCH 378/429] use range for Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index e8453c603..29145d898 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -274,8 +274,7 @@ QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, loadVersionLoop.exec(); } - for (int i = 0; i < vlist->versions().size(); i++) { - auto version = vlist->versions().at(i); + for (auto version : vlist->versions()) { // first recommended build we find, we use. if (!version->isRecommended()) continue; From ef21879df4f7c2822381e1b6af4901e0e6b0d339 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 21 Jul 2023 19:30:00 +0300 Subject: [PATCH 379/429] replaced require with ensure for jvmArgs Signed-off-by: Trial97 --- launcher/modplatform/import_ftb/PackHelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/import_ftb/PackHelpers.cpp b/launcher/modplatform/import_ftb/PackHelpers.cpp index 26b6eafe1..4a1bbef96 100644 --- a/launcher/modplatform/import_ftb/PackHelpers.cpp +++ b/launcher/modplatform/import_ftb/PackHelpers.cpp @@ -42,7 +42,7 @@ Modpack parseDirectory(QString path) modpack.name = Json::requireString(root, "name", "name"); modpack.version = Json::requireString(root, "version", "version"); modpack.mcVersion = Json::requireString(root, "mcVersion", "mcVersion"); - modpack.jvmArgs = Json::requireVariant(root, "jvmArgs", "jvmArgs"); + modpack.jvmArgs = Json::ensureVariant(root, "jvmArgs", {}, "jvmArgs"); } catch (const Exception& e) { qDebug() << "Couldn't load ftb instance json: " << e.cause(); return {}; From 2253100ac6a5dd58f9413b8e82a474e36e0929f0 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Sat, 22 Jul 2023 14:26:49 -0400 Subject: [PATCH 380/429] Update libnbtplusplus submodule Signed-off-by: PandaNinjas --- libraries/libnbtplusplus | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libnbtplusplus b/libraries/libnbtplusplus index 2203af7ee..a5e8fd52b 160000 --- a/libraries/libnbtplusplus +++ b/libraries/libnbtplusplus @@ -1 +1 @@ -Subproject commit 2203af7eeb48c45398139b583615134efd8d407f +Subproject commit a5e8fd52b8bf4ab5d5bcc042b2a247867589985f From 6f6b0b9661fb2d211ea4437b54717d7fced79373 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 23 Jul 2023 00:21:25 +0000 Subject: [PATCH 381/429] 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 'libnbtplusplus': 'github:PrismLauncher/libnbtplusplus/2203af7eeb48c45398139b583615134efd8d407f' (2022-04-15) → 'github:PrismLauncher/libnbtplusplus/a5e8fd52b8bf4ab5d5bcc042b2a247867589985f' (2023-07-22) • Updated input 'nixpkgs': 'github:nixos/nixpkgs/46ed466081b9cad1125b11f11a2af5cc40b942c7' (2023-07-15) → 'github:nixos/nixpkgs/f465da166263bc0d4b39dfd4ca28b777c92d4b73' (2023-07-22) • Updated input 'pre-commit-hooks': 'github:cachix/pre-commit-hooks.nix/5e28316db471d1ac234beb70031b635437421dd6' (2023-07-14) → 'github:cachix/pre-commit-hooks.nix/eb433bff05b285258be76513add6f6c57b441775' (2023-07-18) --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index 370250c4b..13a3e0a44 100644 --- a/flake.lock +++ b/flake.lock @@ -76,11 +76,11 @@ "libnbtplusplus": { "flake": false, "locked": { - "lastModified": 1650031308, - "narHash": "sha256-TvVOjkUobYJD9itQYueELJX3wmecvEdCbJ0FinW2mL4=", + "lastModified": 1690036783, + "narHash": "sha256-A5kTgICnx+Qdq3Fir/bKTfdTt/T1NQP2SC+nhN1ENug=", "owner": "PrismLauncher", "repo": "libnbtplusplus", - "rev": "2203af7eeb48c45398139b583615134efd8d407f", + "rev": "a5e8fd52b8bf4ab5d5bcc042b2a247867589985f", "type": "github" }, "original": { @@ -91,11 +91,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1689413807, - "narHash": "sha256-exuzOvOhGAEKWQKwDuZAL4N8a1I837hH5eocaTcIbLc=", + "lastModified": 1690026219, + "narHash": "sha256-oOduRk/kzQxOBknZXTLSEYd7tk+GoKvr8wV6Ab+t4AU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "46ed466081b9cad1125b11f11a2af5cc40b942c7", + "rev": "f465da166263bc0d4b39dfd4ca28b777c92d4b73", "type": "github" }, "original": { @@ -138,11 +138,11 @@ ] }, "locked": { - "lastModified": 1689328505, - "narHash": "sha256-9B3+OeUn1a/CvzE3GW6nWNwS5J7PDHTyHGlpL3wV5oA=", + "lastModified": 1689668210, + "narHash": "sha256-XAATwDkaUxH958yXLs1lcEOmU6pSEIkatY3qjqk8X0E=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "5e28316db471d1ac234beb70031b635437421dd6", + "rev": "eb433bff05b285258be76513add6f6c57b441775", "type": "github" }, "original": { From 6a01c277e8f98797e3325a2b249e59ee95f43c7e Mon Sep 17 00:00:00 2001 From: tjw123hh Date: Mon, 24 Jul 2023 20:41:22 +0800 Subject: [PATCH 382/429] Delete some incorrect tags --- launcher/ui/pages/global/APIPage.ui | 2 +- launcher/ui/pages/global/JavaPage.ui | 2 +- launcher/ui/pages/global/MinecraftPage.ui | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.ui | 2 +- program_info/org.prismlauncher.PrismLauncher.desktop.in | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) mode change 100644 => 100755 program_info/org.prismlauncher.PrismLauncher.desktop.in diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 40b89d914..492741ba4 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -30,7 +30,7 @@ - Services + Services diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 6749cbe41..561cf79b7 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -58,7 +58,7 @@ - &PermGen: + &PermGen: permGenSpinBox diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index a3188dccb..393b0f358 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -39,7 +39,7 @@ - General + General diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 323890b90..245433fe8 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -116,7 +116,7 @@ - PermGen: + PermGen: diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in old mode 100644 new mode 100755 index 20fabe9d4..c85c2573f --- a/program_info/org.prismlauncher.PrismLauncher.desktop.in +++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in @@ -1,3 +1,4 @@ +#!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Name=Prism Launcher From f505d43fc0399d944cad9e51ab6cc7189052cba1 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Jul 2023 13:43:26 +0100 Subject: [PATCH 383/429] Fix token "0" being replaced Signed-off-by: TheKodeToad --- launcher/minecraft/MinecraftInstance.cpp | 2 +- launcher/minecraft/auth/AccountData.cpp | 4 ++++ launcher/minecraft/auth/MinecraftAccount.cpp | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 342e634f7..3bcd4df8c 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -843,7 +843,7 @@ QMap MinecraftInstance::createCensorFilterFromSession(AuthSess { addToFilter(sessionRef.session, tr("")); } - if (sessionRef.access_token != "offline") { + if (sessionRef.access_token != "0") { addToFilter(sessionRef.access_token, tr("")); } if(sessionRef.client_token.size()) { diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp index 44f7e2563..0b78cb0c1 100644 --- a/launcher/minecraft/auth/AccountData.cpp +++ b/launcher/minecraft/auth/AccountData.cpp @@ -374,6 +374,10 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { } yggdrasilToken = tokenFromJSONV3(data, "ygg"); + // versions before 7.2 used "offline" as the offline token + if (yggdrasilToken.token == "offline") + yggdrasilToken.token = "0"; + minecraftProfile = profileFromJSONV3(data, "profile"); if(!entitlementFromJSONV3(data, minecraftEntitlement)) { if(minecraftProfile.validity != Katabasis::Validity::None) { diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index d7b061e5e..5d279af1c 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -94,7 +94,7 @@ MinecraftAccountPtr MinecraftAccount::createOffline(const QString &username) { auto account = makeShared(); account->data.type = AccountType::Offline; - account->data.yggdrasilToken.token = "offline"; + account->data.yggdrasilToken.token = "0"; account->data.yggdrasilToken.validity = Katabasis::Validity::Certain; account->data.yggdrasilToken.issueInstant = QDateTime::currentDateTimeUtc(); account->data.yggdrasilToken.extra["userName"] = username; From 4ab630b832db9adb6b2b77a229cb845e63fc9336 Mon Sep 17 00:00:00 2001 From: tjw123hh <56749271+tjw123hh@users.noreply.github.com> Date: Mon, 24 Jul 2023 20:50:11 +0800 Subject: [PATCH 385/429] Update org.prismlauncher.PrismLauncher.desktop.in Signed-off-by: tjw123hh <56749271+tjw123hh@users.noreply.github.com> --- program_info/org.prismlauncher.PrismLauncher.desktop.in | 1 - 1 file changed, 1 deletion(-) diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in index c85c2573f..20fabe9d4 100755 --- a/program_info/org.prismlauncher.PrismLauncher.desktop.in +++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in @@ -1,4 +1,3 @@ -#!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Name=Prism Launcher From 280f041acb449d8eafc138c48339b258a6e99c64 Mon Sep 17 00:00:00 2001 From: tjw123hh Date: Tue, 25 Jul 2023 17:35:31 +0800 Subject: [PATCH 386/429] Delete some incorrect `notr="true"` tags Signed-off-by: tjw123hh --- launcher/ui/pages/global/LauncherPage.h | 2 +- program_info/org.prismlauncher.PrismLauncher.desktop.in | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index 33f66f1be..e06d98971 100644 --- a/launcher/ui/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -62,7 +62,7 @@ public: QString displayName() const override { - return "Launcher"; + return tr("Launcher"); } QIcon icon() const override { diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in index c85c2573f..20fabe9d4 100755 --- a/program_info/org.prismlauncher.PrismLauncher.desktop.in +++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in @@ -1,4 +1,3 @@ -#!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Name=Prism Launcher From b4159d30fc24ce248804bd0abd5a68934f3d4739 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 25 Jul 2023 15:17:20 +0100 Subject: [PATCH 387/429] Revert permission change Signed-off-by: TheKodeToad --- program_info/org.prismlauncher.PrismLauncher.desktop.in | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 program_info/org.prismlauncher.PrismLauncher.desktop.in diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in old mode 100755 new mode 100644 From 3c35d647b87f774877b7c090186622801bd75f10 Mon Sep 17 00:00:00 2001 From: seth Date: Tue, 25 Jul 2023 19:04:22 -0400 Subject: [PATCH 388/429] feat(ci): init garnix.yaml Signed-off-by: seth --- garnix.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 garnix.yaml diff --git a/garnix.yaml b/garnix.yaml new file mode 100644 index 000000000..755396f72 --- /dev/null +++ b/garnix.yaml @@ -0,0 +1,5 @@ +builds: + exclude: [] + include: + - "devShells.*-linux.*" + - "packages.*-linux.*" From fbf29274e8c0f9b362e1630c3cee1199a889fa9f Mon Sep 17 00:00:00 2001 From: seth Date: Tue, 25 Jul 2023 19:22:48 -0400 Subject: [PATCH 389/429] chore(ci): remove nix job we're using garnix now Signed-off-by: seth --- .github/workflows/build.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bbfe4ab44..c710d54bd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -586,33 +586,3 @@ jobs: with: bundle: "Prism Launcher.flatpak" manifest-path: flatpak/org.prismlauncher.PrismLauncher.yml - - nix: - runs-on: ubuntu-latest - strategy: - matrix: - package: - - prismlauncher - - prismlauncher-qt5 - steps: - - name: Clone repository - if: inputs.build_type == 'Debug' - uses: actions/checkout@v3 - with: - submodules: 'true' - - name: Install nix - if: inputs.build_type == 'Debug' - uses: cachix/install-nix-action@v22 - with: - install_url: https://nixos.org/nix/install - extra_nix_config: | - auto-optimise-store = true - experimental-features = nix-command flakes - - uses: cachix/cachix-action@v12 - if: inputs.build_type == 'Debug' - with: - name: prismlauncher - authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - name: Build - if: inputs.build_type == 'Debug' - run: nix build .#${{ matrix.package }} --print-build-logs From 361583edfcf7e647b7bdf6ba9b82dd810a50b845 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Wed, 26 Jul 2023 03:08:38 +0200 Subject: [PATCH 390/429] Ignore cache files when exporting instances Signed-off-by: LostLuma --- launcher/ui/dialogs/ExportInstanceDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index d1a69b932..f17a57792 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -70,6 +70,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); + proxyModel->blockedPaths().insert({ FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric") }); loadPackIgnore(); ui->treeView->setModel(proxyModel); From 6f652e1d2fbe362387c886bf7047f425cc25004d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 26 Jul 2023 14:38:32 +0200 Subject: [PATCH 391/429] chore: update information for downstreams Signed-off-by: Sefa Eyeoglu --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 993f02f5d..f4a1d3d29 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Feel free to create a GitHub issue if you find a bug or want to suggest a new fe - **Our Matrix space:** -[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&label=Matrix%20Space&logo=matrix&color=purple)](https://prismlauncher.org/matrix) +[![Prism Launcher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&label=Matrix%20Space&logo=matrix&color=purple)](https://prismlauncher.org/matrix) - **Our Subreddit:** @@ -50,7 +50,7 @@ Feel free to create a GitHub issue if you find a bug or want to suggest a new fe ## Translations -The translation effort for PrismLauncher is hosted on [Weblate](https://hosted.weblate.org/projects/prismlauncher/launcher/) and information about translating Prism Launcher is available at +The translation effort for Prism Launcher is hosted on [Weblate](https://hosted.weblate.org/projects/prismlauncher/launcher/) and information about translating Prism Launcher is available at ## Building @@ -82,14 +82,16 @@ Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), ## Forking/Redistributing/Custom builds policy -We don't care what you do with your fork/custom build as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy: +You are free to fork, redistribute and provide cusstom builds as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy: -- Make it clear that your fork is not PrismLauncher and is not endorsed by or affiliated with the PrismLauncher project (). -- Go through [CMakeLists.txt](CMakeLists.txt) and change PrismLauncher's API keys to your own or set them to empty strings (`""`) to disable them (this way the program will still compile but the functionality requiring those keys will be disabled). +- Make it clear that your fork is not Prism Launcher and is not endorsed by or affiliated with the Prism Launcher project (). +- Go through [CMakeLists.txt](CMakeLists.txt) and change Prism Launcher's API keys to your own or set them to empty strings (`""`) to disable them (this way the program will still compile but the functionality requiring those keys will be disabled). If you have any questions or want any clarification on the above conditions please make an issue and ask us. -Be aware that if you build this software without removing the provided API keys in [CMakeLists.txt](CMakeLists.txt) you are accepting the following terms and conditions: +If you are just building Prism Launcher for your distribution, please make sure to set the `Launcher_BUILD_PLATFORM` to a slug representing your distribution. Examples are `archlinux`, `fedora` and `nixpkgs`. + +Note that if you build this software without removing the provided API keys in [CMakeLists.txt](CMakeLists.txt) you are accepting the following terms and conditions: - [Microsoft Identity Platform Terms of Use](https://docs.microsoft.com/en-us/legal/microsoft-identity-platform/terms-of-use) - [CurseForge 3rd Party API Terms and Conditions](https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions) From 4ad448993c01a41a6af23b1154c5ae64649eef91 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 26 Jul 2023 14:48:53 +0200 Subject: [PATCH 392/429] fix: fix typo in README Co-authored-by: Tayou <31988415+TayouVR@users.noreply.github.com> Signed-off-by: Sefa Eyeoglu --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4a1d3d29..641622b5c 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), ## Forking/Redistributing/Custom builds policy -You are free to fork, redistribute and provide cusstom builds as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy: +You are free to fork, redistribute and provide custom builds as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy: - Make it clear that your fork is not Prism Launcher and is not endorsed by or affiliated with the Prism Launcher project (). - Go through [CMakeLists.txt](CMakeLists.txt) and change Prism Launcher's API keys to your own or set them to empty strings (`""`) to disable them (this way the program will still compile but the functionality requiring those keys will be disabled). From a9fefb2eebf8ded7322b778d9a3f36bfc65cf113 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Wed, 26 Jul 2023 15:22:22 +0200 Subject: [PATCH 393/429] Address review comments Signed-off-by: LostLuma --- launcher/ui/dialogs/ExportInstanceDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index f17a57792..7b64467ac 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -70,7 +70,8 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); - proxyModel->blockedPaths().insert({ FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric") }); + proxyModel->blockedPaths().insert( + { FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric"), FS::PathCombine(prefix, ".quilt") }); loadPackIgnore(); ui->treeView->setModel(proxyModel); From e6b4fc918250b415762b525ebce763b81f7d5cf9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 26 Jul 2023 21:36:40 +0300 Subject: [PATCH 394/429] removed quilt warning Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index da572fc34..c8373bab2 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1342,16 +1342,10 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() if (m_selectedInstance) { auto instance = dynamic_cast(m_selectedInstance.get()); if (instance) { - QString errorMsg; - if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { - errorMsg = tr("Quilt is currently not supported by CurseForge modpacks."); - } else if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft"); - cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") { - errorMsg = tr("Snapshots are currently not supported by CurseForge modpacks."); - } - if (!errorMsg.isEmpty()) { + if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft"); + cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") { QMessageBox msgBox; - msgBox.setText(errorMsg); + msgBox.setText("Snapshots are currently not supported by CurseForge modpacks."); msgBox.exec(); return; } From 1974bb7e59803fc9fc219a8d7f59896320bd58ea Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 26 Jul 2023 14:34:11 -0400 Subject: [PATCH 395/429] chore(ci): cleanup garnix.yaml Signed-off-by: seth --- garnix.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/garnix.yaml b/garnix.yaml index 755396f72..3bf145248 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -1,5 +1,6 @@ builds: exclude: [] include: - - "devShells.*-linux.*" - - "packages.*-linux.*" + - "checks.x86_64-linux.*" + - "devShells.*.*" + - "packages.*.*" From 342a0d0091fafece11f2b18e38c3786f112ac20b Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 26 Jul 2023 14:47:47 -0400 Subject: [PATCH 396/429] fix(nix): disable x86_64-darwin Signed-off-by: seth --- nix/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/default.nix b/nix/default.nix index 7bad1440c..47172927a 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -24,9 +24,9 @@ # Supported systems. systems = [ "x86_64-linux" - "x86_64-darwin" "aarch64-linux" - # Disabled due to qtbase being currently broken for "aarch64-darwin." + # Disabled due to our packages not supporting darwin yet. + # "x86_64-darwin" # "aarch64-darwin" ]; } From f7ffbcca6c5490e24ee74486cfc6698a38512561 Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 26 Jul 2023 14:45:30 -0400 Subject: [PATCH 397/429] chore(docs): correct markdownlint warnings Signed-off-by: seth --- CONTRIBUTING.md | 5 ++--- libraries/README.md | 2 +- nix/NIX.md | 10 ++++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b2795ce49..072916772 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ In an effort to ensure that the code you contribute is actually compatible with This can be done by appending `-s` to your `git commit` call, or by manually appending the following text to your commit message: -``` +```text Signed-off-by: Author name @@ -27,7 +27,7 @@ Signed-off-by: Author name By signing off your work, you agree to the terms below: -``` +```text Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: @@ -62,7 +62,6 @@ As a bonus, you can also [cryptographically sign your commits][gh-signing-commit [gh-signing-commits]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits [gh-vigilant-mode]: https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits - ## Backporting to Release Branches We use [automated backports](https://github.com/PrismLauncher/PrismLauncher/blob/develop/.github/workflows/backport.yml) to merge specific contributions from develop into `release` branches. diff --git a/libraries/README.md b/libraries/README.md index 4da11314d..e75a381ee 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -61,7 +61,7 @@ The `standard` and `legacy` launchers are available. Example (some parts have been censored): -``` +```text mod legacyjavafixer-1.0 mainClass net.minecraft.launchwrapper.Launch param --username diff --git a/nix/NIX.md b/nix/NIX.md index 980d20e87..aa945acc6 100644 --- a/nix/NIX.md +++ b/nix/NIX.md @@ -53,7 +53,8 @@ home.packages = [ pkgs.prismlauncher ]; ### Without flakes-enabled nix -#### Using channels +
    +Using channels ```sh nix-channel --add https://github.com/PrismLauncher/PrismLauncher/archive/master.tar.gz prismlauncher @@ -61,7 +62,10 @@ nix-channel --update prismlauncher nix-env -iA prismlauncher ``` -#### Using the overlay +
    + +
    +Using the overlay ```nix # In your configuration.nix: @@ -74,6 +78,8 @@ nix-env -iA prismlauncher } ``` +
    + ## Running ad-hoc If you're on a flakes-enabled nix you can run the launcher in one-line From af59c4171344d6727c8d67205cc02406729250a3 Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 26 Jul 2023 16:20:30 -0400 Subject: [PATCH 398/429] fix: typo in task.h Signed-off-by: seth --- launcher/InstanceImportTask.cpp | 6 +++--- launcher/InstanceList.cpp | 2 +- launcher/ResourceDownloadTask.cpp | 2 +- launcher/launch/steps/Update.cpp | 2 +- launcher/minecraft/MinecraftLoadAndCheck.cpp | 2 +- launcher/minecraft/MinecraftUpdate.cpp | 4 ++-- launcher/minecraft/update/AssetUpdateTask.cpp | 4 ++-- launcher/minecraft/update/FMLLibrariesTask.cpp | 2 +- launcher/minecraft/update/LibrariesTask.cpp | 2 +- launcher/modplatform/atlauncher/ATLPackInstallTask.cpp | 4 ++-- launcher/modplatform/flame/FileResolvingTask.cpp | 6 +++--- launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 4 ++-- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/modplatform/legacy_ftb/PackInstallTask.cpp | 2 +- .../modplatform/modrinth/ModrinthInstanceCreationTask.cpp | 2 +- launcher/modplatform/technic/SingleZipPackInstallTask.cpp | 2 +- launcher/modplatform/technic/SolderPackInstallTask.cpp | 2 +- launcher/tasks/Task.cpp | 2 +- launcher/tasks/Task.h | 2 +- 19 files changed, 27 insertions(+), 27 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 352848f02..d6a96deb1 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -99,7 +99,7 @@ void InstanceImportTask::executeTask() connect(m_filesNetJob.get(), &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); - connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress); + connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(m_filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::downloadFailed); connect(m_filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::downloadAborted); @@ -293,7 +293,7 @@ void InstanceImportTask::processFlame() }); connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress); - connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propogateStepProgress); + connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails); @@ -385,7 +385,7 @@ void InstanceImportTask::processModrinth() }); connect(inst_creation_task, &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task, &Task::progress, this, &InstanceImportTask::setProgress); - connect(inst_creation_task, &Task::stepProgress, this, &InstanceImportTask::propogateStepProgress); + connect(inst_creation_task, &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(inst_creation_task, &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task, &Task::details, this, &InstanceImportTask::setDetails); connect(inst_creation_task, &Task::finished, inst_creation_task, &InstanceCreationTask::deleteLater); diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index b4c520cd9..0485db19e 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -799,7 +799,7 @@ class InstanceStaging : public Task { connect(child, &Task::status, this, &InstanceStaging::setStatus); connect(child, &Task::details, this, &InstanceStaging::setDetails); connect(child, &Task::progress, this, &InstanceStaging::setProgress); - connect(child, &Task::stepProgress, this, &InstanceStaging::propogateStepProgress); + connect(child, &Task::stepProgress, this, &InstanceStaging::propagateStepProgress); connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceded); } diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp index 06c03c779..8bb9b64e9 100644 --- a/launcher/ResourceDownloadTask.cpp +++ b/launcher/ResourceDownloadTask.cpp @@ -54,7 +54,7 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, m_filesNetJob->addNetAction(Net::Download::makeFile(m_pack_version.downloadUrl, dir.absoluteFilePath(getFilename()))); connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ResourceDownloadTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::progress, this, &ResourceDownloadTask::downloadProgressChanged); - connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &ResourceDownloadTask::propogateStepProgress); + connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &ResourceDownloadTask::propagateStepProgress); connect(m_filesNetJob.get(), &NetJob::failed, this, &ResourceDownloadTask::downloadFailed); addTask(m_filesNetJob); diff --git a/launcher/launch/steps/Update.cpp b/launcher/launch/steps/Update.cpp index 77c8a18ea..8df2bc67c 100644 --- a/launcher/launch/steps/Update.cpp +++ b/launcher/launch/steps/Update.cpp @@ -28,7 +28,7 @@ void Update::executeTask() { connect(m_updateTask.get(), &Task::finished, this, &Update::updateFinished); connect(m_updateTask.get(), &Task::progress, this, &Update::setProgress); - connect(m_updateTask.get(), &Task::stepProgress, this, &Update::propogateStepProgress); + connect(m_updateTask.get(), &Task::stepProgress, this, &Update::propagateStepProgress); connect(m_updateTask.get(), &Task::status, this, &Update::setStatus); connect(m_updateTask.get(), &Task::details, this, &Update::setDetails); emit progressReportingRequest(); diff --git a/launcher/minecraft/MinecraftLoadAndCheck.cpp b/launcher/minecraft/MinecraftLoadAndCheck.cpp index 1c3f6fb71..2a3698798 100644 --- a/launcher/minecraft/MinecraftLoadAndCheck.cpp +++ b/launcher/minecraft/MinecraftLoadAndCheck.cpp @@ -22,7 +22,7 @@ void MinecraftLoadAndCheck::executeTask() connect(m_task.get(), &Task::failed, this, &MinecraftLoadAndCheck::subtaskFailed); connect(m_task.get(), &Task::aborted, this, [this]{ subtaskFailed(tr("Aborted")); }); connect(m_task.get(), &Task::progress, this, &MinecraftLoadAndCheck::progress); - connect(m_task.get(), &Task::stepProgress, this, &MinecraftLoadAndCheck::propogateStepProgress); + connect(m_task.get(), &Task::stepProgress, this, &MinecraftLoadAndCheck::propagateStepProgress); connect(m_task.get(), &Task::status, this, &MinecraftLoadAndCheck::setStatus); } diff --git a/launcher/minecraft/MinecraftUpdate.cpp b/launcher/minecraft/MinecraftUpdate.cpp index 35430bb0f..236d0224b 100644 --- a/launcher/minecraft/MinecraftUpdate.cpp +++ b/launcher/minecraft/MinecraftUpdate.cpp @@ -100,7 +100,7 @@ void MinecraftUpdate::next() disconnect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed); disconnect(task.get(), &Task::aborted, this, &Task::abort); disconnect(task.get(), &Task::progress, this, &MinecraftUpdate::progress); - disconnect(task.get(), &Task::stepProgress, this, &MinecraftUpdate::propogateStepProgress); + disconnect(task.get(), &Task::stepProgress, this, &MinecraftUpdate::propagateStepProgress); disconnect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus); disconnect(task.get(), &Task::details, this, &MinecraftUpdate::setDetails); } @@ -120,7 +120,7 @@ void MinecraftUpdate::next() connect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed); connect(task.get(), &Task::aborted, this, &Task::abort); connect(task.get(), &Task::progress, this, &MinecraftUpdate::progress); - connect(task.get(), &Task::stepProgress, this, &MinecraftUpdate::propogateStepProgress); + connect(task.get(), &Task::stepProgress, this, &MinecraftUpdate::propagateStepProgress); connect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus); connect(task.get(), &Task::details, this, &MinecraftUpdate::setDetails); // if the task is already running, do not start it again diff --git a/launcher/minecraft/update/AssetUpdateTask.cpp b/launcher/minecraft/update/AssetUpdateTask.cpp index 31fd5eb11..fda85ba8a 100644 --- a/launcher/minecraft/update/AssetUpdateTask.cpp +++ b/launcher/minecraft/update/AssetUpdateTask.cpp @@ -45,7 +45,7 @@ void AssetUpdateTask::executeTask() connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetIndexFailed); connect(downloadJob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress); - connect(downloadJob.get(), &NetJob::stepProgress, this, &AssetUpdateTask::propogateStepProgress); + connect(downloadJob.get(), &NetJob::stepProgress, this, &AssetUpdateTask::propagateStepProgress); qDebug() << m_inst->name() << ": Starting asset index download"; downloadJob->start(); @@ -84,7 +84,7 @@ void AssetUpdateTask::assetIndexFinished() connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed); connect(downloadJob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress); - connect(downloadJob.get(), &NetJob::stepProgress, this, &AssetUpdateTask::propogateStepProgress); + connect(downloadJob.get(), &NetJob::stepProgress, this, &AssetUpdateTask::propagateStepProgress); downloadJob->start(); return; } diff --git a/launcher/minecraft/update/FMLLibrariesTask.cpp b/launcher/minecraft/update/FMLLibrariesTask.cpp index 75e5c5720..d9fa0595d 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.cpp +++ b/launcher/minecraft/update/FMLLibrariesTask.cpp @@ -75,7 +75,7 @@ void FMLLibrariesTask::executeTask() connect(dljob.get(), &NetJob::failed, this, &FMLLibrariesTask::fmllibsFailed); connect(dljob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); connect(dljob.get(), &NetJob::progress, this, &FMLLibrariesTask::progress); - connect(dljob.get(), &NetJob::stepProgress, this, &FMLLibrariesTask::propogateStepProgress); + connect(dljob.get(), &NetJob::stepProgress, this, &FMLLibrariesTask::propagateStepProgress); downloadJob.reset(dljob); downloadJob->start(); } diff --git a/launcher/minecraft/update/LibrariesTask.cpp b/launcher/minecraft/update/LibrariesTask.cpp index 415b9a660..9d1c02957 100644 --- a/launcher/minecraft/update/LibrariesTask.cpp +++ b/launcher/minecraft/update/LibrariesTask.cpp @@ -70,7 +70,7 @@ void LibrariesTask::executeTask() connect(downloadJob.get(), &NetJob::failed, this, &LibrariesTask::jarlibFailed); connect(downloadJob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); connect(downloadJob.get(), &NetJob::progress, this, &LibrariesTask::progress); - connect(downloadJob.get(), &NetJob::stepProgress, this, &LibrariesTask::propogateStepProgress); + connect(downloadJob.get(), &NetJob::stepProgress, this, &LibrariesTask::propagateStepProgress); downloadJob->start(); } diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 22ea02da2..82a51c274 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -684,7 +684,7 @@ void PackInstallTask::installConfigs() abortable = true; setProgress(current, total); }); - connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); + connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); connect(jobPtr.get(), &NetJob::aborted, [&]{ abortable = false; jobPtr.reset(); @@ -852,7 +852,7 @@ void PackInstallTask::downloadMods() abortable = true; setProgress(current, total); }); - connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); + connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); connect(jobPtr.get(), &NetJob::aborted, [&] { abortable = false; diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 34bd401d3..ae168bbd6 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -52,7 +52,7 @@ void Flame::FileResolvingTask::executeTask() stepProgress(*step_progress); emitFailed(reason); }); - connect(m_dljob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress); + connect(m_dljob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propagateStepProgress); connect(m_dljob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; step_progress->update(current, total); @@ -118,7 +118,7 @@ void Flame::FileResolvingTask::netJobFinished() stepProgress(*step_progress); emitFailed(reason); }); - connect(m_checkJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress); + connect(m_checkJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propagateStepProgress); connect(m_checkJob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; step_progress->update(current, total); @@ -195,7 +195,7 @@ void Flame::FileResolvingTask::modrinthCheckFinished() stepProgress(*step_progress); emitFailed(reason); }); - connect(m_slugJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress); + connect(m_slugJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propagateStepProgress); connect(m_slugJob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; step_progress->update(current, total); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 29145d898..e17cf1c2e 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -432,7 +432,7 @@ bool FlameCreationTask::createInstance() }); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::progress, this, &FlameCreationTask::setProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::status, this, &FlameCreationTask::setStatus); - connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propogateStepProgress); + connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propagateStepProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::details, this, &FlameCreationTask::setDetails); m_mod_id_resolver->start(); @@ -552,7 +552,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); setProgress(current, total); }); - connect(m_files_job.get(), &NetJob::stepProgress, this, &FlameCreationTask::propogateStepProgress); + connect(m_files_job.get(), &NetJob::stepProgress, this, &FlameCreationTask::propagateStepProgress); connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); setStatus(tr("Downloading mods...")); diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index ac0da2142..87bf780ce 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -166,7 +166,7 @@ void FlamePackExportTask::collectHashes() stepProgress(*progressStep); emitFailed(reason); }); - connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); + connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propagateStepProgress); connect(hashingTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index a4c78397b..1afe57830 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -81,7 +81,7 @@ void PackInstallTask::downloadPack() connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::unzip); connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::emitFailed); - connect(netJobContainer.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); + connect(netJobContainer.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::emitAborted); netJobContainer->start(); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 76f072773..bd0b828c6 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -267,7 +267,7 @@ bool ModrinthCreationTask::createInstance() setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); setProgress(current, total); }); - connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propogateStepProgress); + connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propagateStepProgress); setStatus(tr("Downloading mods...")); m_files_job->start(); diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp index f07ca24af..ab91c4668 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp @@ -50,7 +50,7 @@ void Technic::SingleZipPackInstallTask::executeTask() auto job = m_filesNetJob.get(); connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded); connect(job, &NetJob::progress, this, &Technic::SingleZipPackInstallTask::downloadProgressChanged); - connect(job, &NetJob::stepProgress, this, &Technic::SingleZipPackInstallTask::propogateStepProgress); + connect(job, &NetJob::stepProgress, this, &Technic::SingleZipPackInstallTask::propagateStepProgress); connect(job, &NetJob::failed, this, &Technic::SingleZipPackInstallTask::downloadFailed); m_filesNetJob->start(); } diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index 6a05d17ae..cc1d261e2 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -126,7 +126,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded() connect(m_filesNetJob.get(), &NetJob::succeeded, this, &Technic::SolderPackInstallTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::progress, this, &Technic::SolderPackInstallTask::downloadProgressChanged); - connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &Technic::SolderPackInstallTask::propogateStepProgress); + connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &Technic::SolderPackInstallTask::propagateStepProgress); connect(m_filesNetJob.get(), &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed); connect(m_filesNetJob.get(), &NetJob::aborted, this, &Technic::SolderPackInstallTask::downloadAborted); m_filesNetJob->start(); diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index 29c55cd48..fd82ec001 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -161,7 +161,7 @@ void Task::emitSucceeded() emit finished(); } -void Task::propogateStepProgress(TaskStepProgress const& task_progress) +void Task::propagateStepProgress(TaskStepProgress const& task_progress) { emit stepProgress(task_progress); } diff --git a/launcher/tasks/Task.h b/launcher/tasks/Task.h index 6d8bbbb46..57177697e 100644 --- a/launcher/tasks/Task.h +++ b/launcher/tasks/Task.h @@ -167,7 +167,7 @@ class Task : public QObject, public QRunnable { virtual void emitAborted(); virtual void emitFailed(QString reason = ""); - virtual void propogateStepProgress(TaskStepProgress const& task_progress); + virtual void propagateStepProgress(TaskStepProgress const& task_progress); public slots: void setStatus(const QString& status); From 31b62203a77c9e480e8ea51b9c8ff366211f5b58 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Wed, 26 Jul 2023 23:44:35 +0300 Subject: [PATCH 399/429] Update launcher/ui/MainWindow.cpp Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index c8373bab2..e342e833e 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1344,7 +1344,7 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() if (instance) { if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft"); cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") { - QMessageBox msgBox; + QMessageBox msgBox(this); msgBox.setText("Snapshots are currently not supported by CurseForge modpacks."); msgBox.exec(); return; From 1e82cb6a7c9c7e8d0a9bfa3d2505b4b8eb132944 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 26 Jul 2023 23:56:01 +0300 Subject: [PATCH 400/429] fix: add support for QByteArray inifile Signed-off-by: Trial97 --- .../minecraft/mod/tasks/LocalModParseTask.cpp | 9 ++++---- launcher/settings/INIFile.cpp | 23 +++++++++++++++---- launcher/settings/INIFile.h | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 264019f84..60389753e 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -1,9 +1,9 @@ #include "LocalModParseTask.h" +#include #include #include #include -#include #include #include #include @@ -369,12 +369,11 @@ ModDetails ReadQuiltModInfo(QByteArray contents) details.icon_file = icon.toString(); } } - } return details; } -ModDetails ReadForgeInfo(QString fileName) +ModDetails ReadForgeInfo(QByteArray contents) { ModDetails details; // Read the data @@ -382,7 +381,7 @@ ModDetails ReadForgeInfo(QString fileName) details.mod_id = "Forge"; details.homeurl = "http://www.minecraftforge.net/forum/"; INIFile ini; - if (!ini.loadFile(fileName)) + if (!ini.loadFile(contents)) return details; QString major = ini.get("forge.major.number", "0").toString(); @@ -554,7 +553,7 @@ bool processZIP(Mod& mod, ProcessingLevel level) return false; } - details = ReadForgeInfo(file.getFileName()); + details = ReadForgeInfo(file.readAll()); file.close(); zip.close(); diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index d16256b96..4fb11ed35 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -37,11 +37,12 @@ #include "settings/INIFile.h" #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include @@ -71,6 +72,7 @@ bool INIFile::saveFile(QString fileName) return true; } + QString unescape(QString orig) { QString out; @@ -185,6 +187,19 @@ bool INIFile::loadFile(QString fileName) return true; } +bool INIFile::loadFile(QByteArray data) +{ + QTemporaryFile file; + if (!file.open()) + return false; + file.write(data); + file.flush(); + file.close(); + auto loaded = loadFile(file.fileName()); + file.remove(); + return loaded; +} + QVariant INIFile::get(QString key, QVariant def) const { if (!this->contains(key)) diff --git a/launcher/settings/INIFile.h b/launcher/settings/INIFile.h index 0d5c05ebb..4ee543cf1 100644 --- a/launcher/settings/INIFile.h +++ b/launcher/settings/INIFile.h @@ -50,6 +50,7 @@ public: explicit INIFile(); bool loadFile(QString fileName); + bool loadFile(QByteArray data); bool saveFile(QString fileName); QVariant get(QString key, QVariant def) const; From 62aa7a52c4f10848b5645b57332afd26421a1f4e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 27 Jul 2023 00:07:38 +0300 Subject: [PATCH 401/429] fiexed conflicts Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackExportTask.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 139c9d951..f5f3af372 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -350,7 +350,7 @@ void FlamePackExportTask::buildZip() stepProgress(*progressStep); emitFailed(reason); }); - connect(zipTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); + connect(zipTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propagateStepProgress); connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 7290f4542..7bf296398 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -214,7 +214,7 @@ void ModrinthPackExportTask::buildZip() stepProgress(*progressStep); emitFailed(reason); }); - connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propogateStepProgress); + connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propagateStepProgress); connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); From 48e50401968a72846350c6fbd76cc957b64a6b5a Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 26 Jul 2023 17:27:52 -0400 Subject: [PATCH 402/429] feat: disable sparkle when update url is empty Signed-off-by: seth --- CMakeLists.txt | 4 ++-- launcher/CMakeLists.txt | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41634f68a..e0c84093e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,8 +343,8 @@ if(UNIX AND APPLE) set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) set(MACOSX_BUNDLE_COPYRIGHT "© 2022 ${Launcher_Copyright_Mac}") - set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") - set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") + set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=" CACHE STRING "Public key for Sparkle update feed") + set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml" CACHE STRING "URL for Sparkle update feed") set(MACOSX_SPARKLE_DOWNLOAD_URL "https://github.com/sparkle-project/Sparkle/releases/download/2.1.0/Sparkle-2.1.0.tar.xz" CACHE STRING "URL to Sparkle release archive") set(MACOSX_SPARKLE_SHA256 "bf6ac1caa9f8d321d5784859c88da874f28412f37fb327bc21b7b14c5d61ef94" CACHE STRING "SHA256 checksum for Sparkle release archive") diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 2d06dbf4e..af82464a1 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -668,7 +668,7 @@ set(LOGIC_SOURCES ${ATLAUNCHER_SOURCES} ) -if(APPLE) +if(APPLE AND NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") set (LOGIC_SOURCES ${LOGIC_SOURCES} ${MAC_UPDATE_SOURCES}) endif() @@ -1141,17 +1141,22 @@ if(APPLE) set(CMAKE_MACOSX_RPATH 1) set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/") - file(DOWNLOAD ${MACOSX_SPARKLE_DOWNLOAD_URL} ${CMAKE_BINARY_DIR}/Sparkle.tar.xz EXPECTED_HASH SHA256=${MACOSX_SPARKLE_SHA256}) - file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/Sparkle.tar.xz DESTINATION ${CMAKE_BINARY_DIR}/frameworks/Sparkle) + if(NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") + file(DOWNLOAD ${MACOSX_SPARKLE_DOWNLOAD_URL} ${CMAKE_BINARY_DIR}/Sparkle.tar.xz EXPECTED_HASH SHA256=${MACOSX_SPARKLE_SHA256}) + file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/Sparkle.tar.xz DESTINATION ${CMAKE_BINARY_DIR}/frameworks/Sparkle) + + find_library(SPARKLE_FRAMEWORK Sparkle "${CMAKE_BINARY_DIR}/frameworks/Sparkle") + endif() - find_library(SPARKLE_FRAMEWORK Sparkle "${CMAKE_BINARY_DIR}/frameworks/Sparkle") target_link_libraries(Launcher_logic "-framework AppKit" "-framework Carbon" "-framework Foundation" "-framework ApplicationServices" ) - target_link_libraries(Launcher_logic ${SPARKLE_FRAMEWORK}) + if(NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") + target_link_libraries(Launcher_logic ${SPARKLE_FRAMEWORK}) + endif() endif() target_link_libraries(Launcher_logic) @@ -1213,7 +1218,7 @@ if(WIN32) ) endif() -if (UNIX AND APPLE) +if (UNIX AND APPLE AND NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") # Add Sparkle updater # It has to be copied here instead of just allowing fixup_bundle to install it, otherwise essential parts of # the framework aren't installed From a8498b0dab94d0ab6c9e5cf395e5003db541b749 Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 26 Jul 2023 19:03:14 -0400 Subject: [PATCH 403/429] chore: make INSTALL_BUNDLE a cached variable Signed-off-by: seth --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0c84093e..b4910d1bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -354,7 +354,7 @@ if(UNIX AND APPLE) set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${MACOSX_SPARKLE_DIR}) # install as bundle - set(INSTALL_BUNDLE "full") + set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies") # Add the icon install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR} RENAME ${Launcher_Name}.icns) @@ -367,7 +367,7 @@ elseif(UNIX) set(JARS_DEST_DIR "share/${Launcher_Name}") # install as bundle with no dependencies included - set(INSTALL_BUNDLE "nodeps") + set(INSTALL_BUNDLE "nodeps" CACHE STRING "Use fixup_bundle to bundle dependencies") # Set RPATH SET(Launcher_BINARY_RPATH "$ORIGIN/") @@ -401,7 +401,7 @@ elseif(WIN32) set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # install as bundle - set(INSTALL_BUNDLE "full") + set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies") else() message(FATAL_ERROR "Platform not supported") endif() From 4a9ea832ff63a3f1f6f779b35b8a7a3e705fc6a3 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Thu, 27 Jul 2023 01:42:14 +0200 Subject: [PATCH 404/429] Ignore cache files entirely, also apply to modpack export Signed-off-by: LostLuma --- launcher/ui/dialogs/ExportInstanceDialog.cpp | 2 +- launcher/ui/dialogs/ExportPackDialog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 7b64467ac..d6a503ccd 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -70,7 +70,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); - proxyModel->blockedPaths().insert( + proxyModel->ignoreFilesWithPath().insert( { FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric"), FS::PathCombine(prefix, ".quilt") }); loadPackIgnore(); diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index 2abe2805b..ad8db5ffb 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -61,7 +61,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); - proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports" }); + proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports", ".cache", ".fabric", ".quilt" }); proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); From 51bfda937d47837ed426150ed6f43a60b4ca0ce1 Mon Sep 17 00:00:00 2001 From: seth Date: Thu, 27 Jul 2023 00:59:01 -0400 Subject: [PATCH 405/429] chore: don't include sparkle when not enabled Signed-off-by: seth --- launcher/Application.cpp | 4 ++-- launcher/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index aeea90f13..27a8756d9 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -131,7 +131,7 @@ #include "MangoHud.h" #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && defined(SPARKLE_ENABLED) #include "updater/MacSparkleUpdater.h" #endif @@ -776,7 +776,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) if(BuildConfig.UPDATER_ENABLED) { qDebug() << "Initializing updater"; -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && defined(SPARKLE_ENABLED) m_updater.reset(new MacSparkleUpdater()); #endif qDebug() << "<> Updater started."; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index af82464a1..74a939092 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1146,6 +1146,7 @@ if(APPLE) file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/Sparkle.tar.xz DESTINATION ${CMAKE_BINARY_DIR}/frameworks/Sparkle) find_library(SPARKLE_FRAMEWORK Sparkle "${CMAKE_BINARY_DIR}/frameworks/Sparkle") + add_compile_definitions(SPARKLE_ENABLED) endif() target_link_libraries(Launcher_logic From b1aa9e584624a0732dd55fc6c459524a8abfe6ba Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 27 Jul 2023 09:37:56 +0200 Subject: [PATCH 406/429] refactor: introduce internal Launcher_ENABLE_UPDATER variable Signed-off-by: Sefa Eyeoglu --- CMakeLists.txt | 6 ++++++ launcher/CMakeLists.txt | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4910d1bc..05ada3b47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,8 @@ add_subdirectory(program_info) ####################################### Install layout ####################################### +set(Launcher_ENABLE_UPDATER NO) + if(NOT (UNIX AND APPLE)) # Install "portable.txt" if selected component is "portable" install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_Portable_File}" DESTINATION "." COMPONENT portable EXCLUDE_FROM_ALL) @@ -353,6 +355,10 @@ if(UNIX AND APPLE) # directories to look for dependencies set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${MACOSX_SPARKLE_DIR}) + if(NOT MACOSX_SPARKLE_UPDATE_PUBLIC_KEY STREQUAL "" AND NOT MACOSX_SPARKLE_UPDATE_FEED_URL STREQUAL "") + set(Launcher_ENABLE_UPDATER YES) + endif() + # install as bundle set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies") diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 74a939092..490dccf0f 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -668,7 +668,7 @@ set(LOGIC_SOURCES ${ATLAUNCHER_SOURCES} ) -if(APPLE AND NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") +if(APPLE AND Launcher_ENABLE_UPDATER) set (LOGIC_SOURCES ${LOGIC_SOURCES} ${MAC_UPDATE_SOURCES}) endif() @@ -1141,7 +1141,7 @@ if(APPLE) set(CMAKE_MACOSX_RPATH 1) set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/") - if(NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") + if(Launcher_ENABLE_UPDATER) file(DOWNLOAD ${MACOSX_SPARKLE_DOWNLOAD_URL} ${CMAKE_BINARY_DIR}/Sparkle.tar.xz EXPECTED_HASH SHA256=${MACOSX_SPARKLE_SHA256}) file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/Sparkle.tar.xz DESTINATION ${CMAKE_BINARY_DIR}/frameworks/Sparkle) @@ -1155,7 +1155,7 @@ if(APPLE) "-framework Foundation" "-framework ApplicationServices" ) - if(NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") + if(Launcher_ENABLE_UPDATER) target_link_libraries(Launcher_logic ${SPARKLE_FRAMEWORK}) endif() endif() @@ -1219,7 +1219,7 @@ if(WIN32) ) endif() -if (UNIX AND APPLE AND NOT "${MACOSX_SPARKLE_UPDATE_FEED_URL}" STREQUAL "") +if (UNIX AND APPLE AND Launcher_ENABLE_UPDATER) # Add Sparkle updater # It has to be copied here instead of just allowing fixup_bundle to install it, otherwise essential parts of # the framework aren't installed From 1467072f3dcd6ea5d2e3375ad5d69f3ee6d58af2 Mon Sep 17 00:00:00 2001 From: ashuntu <101582426+ashuntu@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:25:32 -0500 Subject: [PATCH 407/429] Removed snapcraft.yaml in favor of dedicated repo: https://github.com/ashuntu/prismlauncher-snap --- .github/workflows/build.yml | 25 --------------- snap/snapcraft.yaml | 64 ------------------------------------- 2 files changed, 89 deletions(-) delete mode 100644 snap/snapcraft.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a234cd29d..c710d54bd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -569,31 +569,6 @@ jobs: run: | ccache -s - snap: - runs-on: ubuntu-22.04 - steps: - - name: Checkout - if: inputs.build_type == 'Debug' - uses: actions/checkout@v3 - with: - submodules: 'true' - - name: Set short version - shell: bash - if: inputs.build_type == 'Debug' - run: | - ver_short=`git rev-parse --short HEAD` - echo "VERSION=$ver_short" >> $GITHUB_ENV - - name: Package Snap (Linux) - id: snapcraft - if: inputs.build_type == 'Debug' - uses: snapcore/action-build@v1 - - name: Upload Snap (Linux) - if: inputs.build_type == 'Debug' - uses: actions/upload-artifact@v3 - with: - name: prismlauncher_${{ env.VERSION }}_amd64.snap - path: ${{ steps.snapcraft.outputs.snap }} - flatpak: runs-on: ubuntu-latest container: diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml deleted file mode 100644 index 41c0ce078..000000000 --- a/snap/snapcraft.yaml +++ /dev/null @@ -1,64 +0,0 @@ -name: prismlauncher -license: GPL-3.0-only -base: core22 -website: https://prismlauncher.org/ -source-code: https://github.com/PrismLauncher/PrismLauncher -issues: https://github.com/PrismLauncher/PrismLauncher/issues -donation: https://opencollective.com/prismlauncher -contact: https://discord.gg/prismlauncher -summary: A custom Minecraft launcher with modpack support -adopt-info: prismlauncher - -grade: devel -confinement: strict - -architectures: - - build-on: amd64 - - build-on: arm64 - -parts: - prismlauncher: - parse-info: - - usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml - plugin: cmake - build-packages: - - zlib1g-dev - - openjdk-17-jdk - - scdoc - - libgl1-mesa-dev - - extra-cmake-modules - build-snaps: - - kf5-5-106-qt-5-15-9-core22 - - kf5-5-106-qt-5-15-9-core22-sdk - stage-packages: - - openjdk-17-jre - - openjdk-8-jre - source: . - override-pull: | - craftctl default - # Fix the icon reference in the desktop file - sed -i.bak -e 's|Icon=org.prismlauncher.PrismLauncher|Icon=/usr/share/icons/hicolor/scalable/apps/org.prismlauncher.PrismLauncher.svg|g' program_info/org.prismlauncher.PrismLauncher.desktop.in - # Remove the build directory so that local development doesn't interfere with Snap compilation - rm -rf build - git submodule update --init --recursive - cmake-generator: Ninja - cmake-parameters: - - "-DCMAKE_INSTALL_PREFIX=/usr" - - "-DCMAKE_BUILD_TYPE=RelWithDebInfo" - - "-DENABLE_LTO=ON" - - "-DLauncher_BUILD_PLATFORM=snap" - - "-DLauncher_QT_VERSION_MAJOR='5'" - -apps: - prismlauncher: - common-id: org.prismlauncher.PrismLauncher - desktop: usr/share/applications/org.prismlauncher.PrismLauncher.desktop - command: usr/bin/prismlauncher - extensions: - - kde-neon - plugs: - - home - - opengl - - network - - network-bind - - audio-playback From d1513732be63a0aed8f97c5bcf1bd5ecd94a423c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 30 Jul 2023 00:20:33 +0000 Subject: [PATCH 408/429] 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/f465da166263bc0d4b39dfd4ca28b777c92d4b73' (2023-07-22) → 'github:nixos/nixpkgs/d2b52322f35597c62abf56de91b0236746b2a03d' (2023-07-29) • Updated input 'pre-commit-hooks': 'github:cachix/pre-commit-hooks.nix/eb433bff05b285258be76513add6f6c57b441775' (2023-07-18) → 'github:cachix/pre-commit-hooks.nix/1e2443dd3f669eb65433b2fc26a3065e05a7dc9c' (2023-07-29) --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 13a3e0a44..af7ecae7c 100644 --- a/flake.lock +++ b/flake.lock @@ -91,11 +91,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1690026219, - "narHash": "sha256-oOduRk/kzQxOBknZXTLSEYd7tk+GoKvr8wV6Ab+t4AU=", + "lastModified": 1690630721, + "narHash": "sha256-Y04onHyBQT4Erfr2fc82dbJTfXGYrf4V0ysLUYnPOP8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "f465da166263bc0d4b39dfd4ca28b777c92d4b73", + "rev": "d2b52322f35597c62abf56de91b0236746b2a03d", "type": "github" }, "original": { @@ -138,11 +138,11 @@ ] }, "locked": { - "lastModified": 1689668210, - "narHash": "sha256-XAATwDkaUxH958yXLs1lcEOmU6pSEIkatY3qjqk8X0E=", + "lastModified": 1690628027, + "narHash": "sha256-OTSbA2hM6VmxyZ/4siYPANffMBzIsKu04GLjXcv8ST0=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "eb433bff05b285258be76513add6f6c57b441775", + "rev": "1e2443dd3f669eb65433b2fc26a3065e05a7dc9c", "type": "github" }, "original": { From 16e6a01881815e7cc1db4a8d9746f1eaa5daaa15 Mon Sep 17 00:00:00 2001 From: Apix Date: Wed, 2 Aug 2023 11:35:54 +0200 Subject: [PATCH 409/429] fix: fix copyright year Signed-off-by: Apix --- CMakeLists.txt | 2 +- launcher/ui/dialogs/AboutDialog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41634f68a..af49f6654 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,7 +342,7 @@ if(UNIX AND APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) - set(MACOSX_BUNDLE_COPYRIGHT "© 2022 ${Launcher_Copyright_Mac}") + set(MACOSX_BUNDLE_COPYRIGHT "© 2022-2023 ${Launcher_Copyright_Mac}") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 88739463f..b1734eff3 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -170,7 +170,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia QString urlText("

    %1

    "); ui->urlLabel->setText(urlText.arg(BuildConfig.LAUNCHER_GIT)); - QString copyText("© 2022 %1"); + QString copyText("© 2022-2023 %1"); ui->copyLabel->setText(copyText.arg(BuildConfig.LAUNCHER_COPYRIGHT)); connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); From f13eccb03d053453fd063850a35d7d17d76f9ce3 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Wed, 2 Aug 2023 19:24:58 +0300 Subject: [PATCH 411/429] Update launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h Co-authored-by: Sefa Eyeoglu Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h index 437fb62a8..54c49f7b7 100644 --- a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h +++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h @@ -41,7 +41,7 @@ class ImportFTBPage : public QWidget, public BasePage { public: explicit ImportFTBPage(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~ImportFTBPage(); - QString displayName() const override { return "FTB App Import"; } + QString displayName() const override { return tr("FTB App Import"); } QIcon icon() const override { return APPLICATION->getThemedIcon("ftb_logo"); } QString id() const override { return "import_ftb"; } QString helpPage() const override { return "FTB-platform"; } From 9d5818916af39b32f64e20381a4530efa6247e38 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 28 Jul 2023 16:09:43 +0200 Subject: [PATCH 412/429] fix(nix): enable clang-format Signed-off-by: Sefa Eyeoglu --- nix/dev.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nix/dev.nix b/nix/dev.nix index 635c6bb41..e42ac5b4a 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -19,8 +19,7 @@ nil.enable = true; clang-format = { - enable = - false; # As most of the codebase is **not** formatted, we don't want clang-format yet + enable = true; types_or = ["c" "c++"]; }; }; From a545f67a211173ae0649e7dda59e1e0fecb2e160 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 29 Jul 2023 11:00:33 +0200 Subject: [PATCH 413/429] fix: take JavaCheckResult by const reference Signed-off-by: Sefa Eyeoglu --- launcher/JavaCommon.cpp | 6 +++--- launcher/JavaCommon.h | 6 +++--- launcher/java/JavaVersion.cpp | 2 +- launcher/java/JavaVersion.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index e29e22709..30a7dbacc 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -68,7 +68,7 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent) return true; } -void JavaCommon::javaWasOk(QWidget *parent, JavaCheckResult result) +void JavaCommon::javaWasOk(QWidget *parent, const JavaCheckResult &result) { QString text; text += QObject::tr("Java test succeeded!
    Platform reported: %1
    Java version " @@ -83,7 +83,7 @@ void JavaCommon::javaWasOk(QWidget *parent, JavaCheckResult result) CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show(); } -void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result) +void JavaCommon::javaArgsWereBad(QWidget *parent, const JavaCheckResult &result) { auto htmlError = result.errorLog; QString text; @@ -93,7 +93,7 @@ void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result) CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); } -void JavaCommon::javaBinaryWasBad(QWidget *parent, JavaCheckResult result) +void JavaCommon::javaBinaryWasBad(QWidget *parent, const JavaCheckResult &result) { QString text; text += QObject::tr( diff --git a/launcher/JavaCommon.h b/launcher/JavaCommon.h index 59cb7a67d..2ba64c0cd 100644 --- a/launcher/JavaCommon.h +++ b/launcher/JavaCommon.h @@ -11,11 +11,11 @@ namespace JavaCommon bool checkJVMArgs(QString args, QWidget *parent); // Show a dialog saying that the Java binary was usable - void javaWasOk(QWidget *parent, JavaCheckResult result); + void javaWasOk(QWidget *parent, const JavaCheckResult &result); // Show a dialog saying that the Java binary was not usable because of bad options - void javaArgsWereBad(QWidget *parent, JavaCheckResult result); + void javaArgsWereBad(QWidget *parent, const JavaCheckResult &result); // Show a dialog saying that the Java binary was not usable - void javaBinaryWasBad(QWidget *parent, JavaCheckResult result); + void javaBinaryWasBad(QWidget *parent, const JavaCheckResult &result); // Show a dialog if we couldn't find Java Checker void javaCheckNotFound(QWidget *parent); diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index 0e4fc1d3c..7124e22fb 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -43,7 +43,7 @@ JavaVersion::JavaVersion(const QString &rhs) operator=(rhs); } -QString JavaVersion::toString() +QString JavaVersion::toString() const { return m_string; } diff --git a/launcher/java/JavaVersion.h b/launcher/java/JavaVersion.h index 9bbf06425..c051a794a 100644 --- a/launcher/java/JavaVersion.h +++ b/launcher/java/JavaVersion.h @@ -25,7 +25,7 @@ public: bool requiresPermGen(); - QString toString(); + QString toString() const; int major() { From 76df836378aa5dd90b0d039358d9927628d48878 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 29 Jul 2023 11:02:10 +0200 Subject: [PATCH 414/429] fix: simplify switch statement Signed-off-by: Sefa Eyeoglu --- launcher/minecraft/PackProfile.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index e8fd21572..7cdd47ae6 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -591,10 +591,7 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const } case Qt::DecorationRole: { - switch(column) - { - case NameColumn: - { + if (column == NameColumn) { auto severity = patch->getProblemSeverity(); switch (severity) { @@ -606,11 +603,7 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const return QVariant(); } } - default: - { - return QVariant(); - } - } + return QVariant(); } } return QVariant(); From c07a8573590f9d0daf82bebe053411e0b9e6ad9f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 29 Jul 2023 11:05:40 +0200 Subject: [PATCH 415/429] fix: remove irregular enum initialization Signed-off-by: Sefa Eyeoglu --- launcher/minecraft/World.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/World.h b/launcher/minecraft/World.h index 10328cce8..dc3733d5f 100644 --- a/launcher/minecraft/World.h +++ b/launcher/minecraft/World.h @@ -28,7 +28,7 @@ struct GameType { enum { Unknown = -1, - Survival = 0, + Survival, Creative, Adventure, Spectator From 9f66f6495ad1f91d7cdb1677431069f27bc24f58 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 29 Jul 2023 11:10:16 +0200 Subject: [PATCH 416/429] fix: fix undisciplined multiple inheritance Signed-off-by: Sefa Eyeoglu --- launcher/InstancePageProvider.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index b4b6e739d..d25cd330e 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -16,9 +16,8 @@ #include "ui/pages/instance/OtherLogsPage.h" #include "ui/pages/instance/WorldListPage.h" #include "ui/pages/instance/ServersPage.h" -#include "ui/pages/instance/GameOptionsPage.h" -class InstancePageProvider : public QObject, public BasePageProvider +class InstancePageProvider : protected QObject, public BasePageProvider { Q_OBJECT public: From 076c189948b89787b34a2a4aded7a9c88f580ee1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 29 Jul 2023 11:30:33 +0200 Subject: [PATCH 417/429] fix: format all languages using clang-format Signed-off-by: Sefa Eyeoglu --- .clang-format | 9 +++++---- nix/dev.nix | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.clang-format b/.clang-format index 51ca0e1c1..4f99858ad 100644 --- a/.clang-format +++ b/.clang-format @@ -1,16 +1,17 @@ --- -Language: Cpp -BasedOnStyle: Chromium +BasedOnStyle: Chromium IndentWidth: 4 +--- +Language: Cpp AlignConsecutiveMacros: false AlignConsecutiveAssignments: false AllowShortIfStatementsOnASingleLine: false BraceWrapping: - AfterFunction: true + AfterFunction: true SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false BreakBeforeBraces: Custom BreakConstructorInitializers: BeforeComma -ColumnLimit: 140 +ColumnLimit: 140 Cpp11BracedListStyle: false diff --git a/nix/dev.nix b/nix/dev.nix index e42ac5b4a..c39e15653 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -20,7 +20,7 @@ clang-format = { enable = true; - types_or = ["c" "c++"]; + types_or = ["c" "c++" "java" "json" "objective-c"]; }; }; }; From 71fb38c91f16ce46a7103d8a606de2e0aeb04395 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 29 Jul 2023 13:01:09 +0100 Subject: [PATCH 418/429] Fix alignment properties Signed-off-by: TheKodeToad --- .clang-format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index 4f99858ad..83cfeb86d 100644 --- a/.clang-format +++ b/.clang-format @@ -3,8 +3,8 @@ BasedOnStyle: Chromium IndentWidth: 4 --- Language: Cpp -AlignConsecutiveMacros: false -AlignConsecutiveAssignments: false +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None AllowShortIfStatementsOnASingleLine: false BraceWrapping: AfterFunction: true From f256b836f4ea88e253d3a54e10faa124bc5c04f9 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 29 Jul 2023 13:16:21 +0100 Subject: [PATCH 419/429] Make more options generic Signed-off-by: TheKodeToad --- .clang-format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index 83cfeb86d..114bcba50 100644 --- a/.clang-format +++ b/.clang-format @@ -1,11 +1,12 @@ --- BasedOnStyle: Chromium IndentWidth: 4 +AllowShortIfStatementsOnASingleLine: false +ColumnLimit: 140 --- Language: Cpp AlignConsecutiveMacros: None AlignConsecutiveAssignments: None -AllowShortIfStatementsOnASingleLine: false BraceWrapping: AfterFunction: true SplitEmptyFunction: false @@ -13,5 +14,4 @@ BraceWrapping: SplitEmptyNamespace: false BreakBeforeBraces: Custom BreakConstructorInitializers: BeforeComma -ColumnLimit: 140 Cpp11BracedListStyle: false From ce2ca1381519a2e261d7f76dffa874d559d979c2 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 31 Jul 2023 15:37:35 +0200 Subject: [PATCH 420/429] fix: add missing headers Signed-off-by: Sefa Eyeoglu --- launcher/ProblemProvider.h | 3 +++ launcher/ui/instanceview/AccessibleInstanceView.h | 1 + 2 files changed, 4 insertions(+) diff --git a/launcher/ProblemProvider.h b/launcher/ProblemProvider.h index cd4745fa1..2d3b43380 100644 --- a/launcher/ProblemProvider.h +++ b/launcher/ProblemProvider.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + enum class ProblemSeverity { None, diff --git a/launcher/ui/instanceview/AccessibleInstanceView.h b/launcher/ui/instanceview/AccessibleInstanceView.h index 9bfd17453..eb4222f50 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView.h +++ b/launcher/ui/instanceview/AccessibleInstanceView.h @@ -1,6 +1,7 @@ #pragma once #include +#include class QAccessibleInterface; QAccessibleInterface *groupViewAccessibleFactory(const QString &classname, QObject *object); From 1d468ac35ad88d8c77cc83f25e3704d9bd7df01b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 2 Aug 2023 18:35:35 +0200 Subject: [PATCH 421/429] chore: reformat Signed-off-by: Sefa Eyeoglu --- buildconfig/BuildConfig.h | 6 +- flatpak/libdecor.json | 40 +- launcher/Application.cpp | 662 +-- launcher/Application.h | 123 +- launcher/ApplicationMessage.cpp | 8 +- launcher/ApplicationMessage.h | 6 +- launcher/BaseInstaller.cpp | 24 +- launcher/BaseInstaller.h | 19 +- launcher/BaseInstance.cpp | 58 +- launcher/BaseInstance.h | 91 +- launcher/BaseVersionList.cpp | 40 +- launcher/BaseVersionList.h | 27 +- launcher/Commandline.cpp | 28 +- launcher/Commandline.h | 5 +- launcher/DefaultVariable.h | 30 +- launcher/DesktopServices.cpp | 115 +- launcher/DesktopServices.h | 71 +- launcher/Exception.h | 29 +- launcher/ExponentialSeries.h | 17 +- launcher/FileSystem.cpp | 7 +- launcher/FileSystem.h | 39 +- launcher/Filter.cpp | 15 +- launcher/Filter.h | 45 +- launcher/GZip.cpp | 44 +- launcher/GZip.h | 10 +- launcher/InstanceCopyPrefs.cpp | 36 +- launcher/InstanceCopyPrefs.h | 2 +- launcher/InstanceCopyTask.cpp | 5 +- launcher/InstanceCopyTask.h | 9 +- launcher/InstanceImportTask.cpp | 62 +- launcher/InstanceImportTask.h | 35 +- launcher/InstanceList.cpp | 119 +- launcher/InstanceList.h | 114 +- launcher/InstancePageProvider.h | 44 +- launcher/InstanceTask.cpp | 10 +- launcher/JavaCommon.cpp | 55 +- launcher/JavaCommon.h | 69 +- launcher/Json.cpp | 159 +- launcher/Json.h | 202 +- launcher/KonamiCode.cpp | 36 +- launcher/KonamiCode.h | 13 +- launcher/LaunchController.cpp | 239 +- launcher/LaunchController.h | 62 +- launcher/LoggedProcess.cpp | 62 +- launcher/LoggedProcess.h | 31 +- launcher/MMCTime.cpp | 37 +- launcher/MMCTime.h | 6 +- launcher/MTPixmapCache.h | 6 +- launcher/MangoHud.cpp | 4 +- launcher/Markdown.h | 2 +- launcher/MessageLevel.cpp | 5 +- launcher/MessageLevel.h | 30 +- launcher/NullInstance.h | 92 +- launcher/ProblemProvider.h | 41 +- launcher/QVariantUtils.h | 23 +- launcher/RWStorage.h | 31 +- launcher/RecursiveFileSystemWatcher.cpp | 59 +- launcher/RecursiveFileSystemWatcher.h | 53 +- launcher/SeparatorPrefixTree.h | 182 +- launcher/SkinUtils.cpp | 17 +- launcher/SkinUtils.h | 3 +- launcher/StringUtils.h | 5 +- launcher/Usable.h | 48 +- launcher/Version.cpp | 8 +- launcher/Version.h | 32 +- launcher/VersionProxyModel.cpp | 221 +- launcher/VersionProxyModel.h | 67 +- launcher/WatchLock.h | 15 +- launcher/icons/IconList.cpp | 164 +- launcher/icons/IconList.h | 64 +- launcher/icons/IconUtils.cpp | 32 +- launcher/icons/IconUtils.h | 4 +- launcher/icons/MMCIcon.cpp | 47 +- launcher/icons/MMCIcon.h | 24 +- launcher/java/JavaChecker.cpp | 56 +- launcher/java/JavaChecker.h | 25 +- launcher/java/JavaCheckerJob.cpp | 9 +- launcher/java/JavaCheckerJob.h | 23 +- launcher/java/JavaInstallList.cpp | 46 +- launcher/java/JavaInstallList.h | 40 +- launcher/java/JavaUtils.cpp | 197 +- launcher/java/JavaUtils.h | 5 +- launcher/java/JavaVersion.cpp | 65 +- launcher/java/JavaVersion.h | 40 +- launcher/launch/LaunchStep.cpp | 2 +- launcher/launch/LaunchStep.h | 30 +- launcher/launch/LaunchTask.cpp | 106 +- launcher/launch/LaunchTask.h | 66 +- launcher/launch/LogModel.cpp | 56 +- launcher/launch/LogModel.h | 29 +- launcher/launch/steps/CheckJava.cpp | 67 +- launcher/launch/steps/CheckJava.h | 24 +- launcher/launch/steps/LookupServerAddress.cpp | 41 +- launcher/launch/steps/LookupServerAddress.h | 27 +- launcher/launch/steps/PostLaunchCommand.cpp | 30 +- launcher/launch/steps/PostLaunchCommand.h | 22 +- launcher/launch/steps/PreLaunchCommand.cpp | 30 +- launcher/launch/steps/PreLaunchCommand.h | 22 +- launcher/launch/steps/QuitAfterGameStop.h | 14 +- launcher/launch/steps/TextPrint.cpp | 4 +- launcher/launch/steps/TextPrint.h | 13 +- launcher/launch/steps/Update.cpp | 23 +- launcher/launch/steps/Update.h | 19 +- launcher/main.cpp | 59 +- launcher/meta/BaseEntity.cpp | 83 +- launcher/meta/BaseEntity.h | 33 +- launcher/meta/Index.cpp | 97 +- launcher/meta/Index.h | 44 +- launcher/meta/JsonFormat.cpp | 114 +- launcher/meta/JsonFormat.h | 52 +- launcher/meta/Version.cpp | 44 +- launcher/meta/Version.h | 72 +- launcher/meta/VersionList.cpp | 154 +- launcher/meta/VersionList.h | 69 +- launcher/minecraft/Agent.h | 19 +- launcher/minecraft/AssetsUtils.cpp | 123 +- launcher/minecraft/AssetsUtils.h | 17 +- launcher/minecraft/Component.cpp | 192 +- launcher/minecraft/Component.h | 45 +- launcher/minecraft/ComponentUpdateTask.cpp | 408 +- launcher/minecraft/ComponentUpdateTask.h | 25 +- launcher/minecraft/ComponentUpdateTask_p.h | 19 +- launcher/minecraft/GradleSpecifier.h | 108 +- launcher/minecraft/LaunchProfile.cpp | 126 +- launcher/minecraft/LaunchProfile.h | 66 +- launcher/minecraft/Library.cpp | 189 +- launcher/minecraft/Library.h | 130 +- launcher/minecraft/MinecraftInstance.cpp | 331 +- launcher/minecraft/MinecraftInstance.h | 31 +- launcher/minecraft/MinecraftLoadAndCheck.cpp | 15 +- launcher/minecraft/MinecraftLoadAndCheck.h | 20 +- launcher/minecraft/MinecraftUpdate.cpp | 61 +- launcher/minecraft/MinecraftUpdate.h | 24 +- launcher/minecraft/MojangDownloadInfo.h | 36 +- launcher/minecraft/MojangVersionFormat.cpp | 218 +- launcher/minecraft/MojangVersionFormat.h | 25 +- launcher/minecraft/OneSixVersionFormat.cpp | 233 +- launcher/minecraft/OneSixVersionFormat.h | 34 +- launcher/minecraft/PackProfile.cpp | 435 +- launcher/minecraft/PackProfile.h | 64 +- launcher/minecraft/PackProfile_p.h | 12 +- launcher/minecraft/ParseUtils.cpp | 6 +- launcher/minecraft/ParseUtils.h | 2 +- launcher/minecraft/ProfileUtils.cpp | 88 +- launcher/minecraft/ProfileUtils.h | 14 +- launcher/minecraft/Rule.cpp | 14 +- launcher/minecraft/Rule.h | 73 +- .../minecraft/VanillaInstanceCreationTask.cpp | 8 +- launcher/minecraft/VersionFile.cpp | 20 +- launcher/minecraft/VersionFile.h | 29 +- launcher/minecraft/VersionFilterData.cpp | 65 +- launcher/minecraft/VersionFilterData.h | 12 +- launcher/minecraft/World.cpp | 282 +- launcher/minecraft/World.h | 97 +- launcher/minecraft/WorldList.cpp | 350 +- launcher/minecraft/WorldList.h | 87 +- launcher/minecraft/auth/AccountData.cpp | 207 +- launcher/minecraft/auth/AccountData.h | 23 +- launcher/minecraft/auth/AccountList.cpp | 430 +- launcher/minecraft/auth/AccountList.h | 54 +- launcher/minecraft/auth/AccountTask.cpp | 52 +- launcher/minecraft/auth/AccountTask.h | 45 +- launcher/minecraft/auth/AuthRequest.cpp | 53 +- launcher/minecraft/auth/AuthRequest.h | 41 +- launcher/minecraft/auth/AuthSession.cpp | 9 +- launcher/minecraft/auth/AuthSession.h | 10 +- launcher/minecraft/auth/AuthStep.cpp | 4 +- launcher/minecraft/auth/AuthStep.h | 20 +- launcher/minecraft/auth/MinecraftAccount.cpp | 144 +- launcher/minecraft/auth/MinecraftAccount.h | 118 +- launcher/minecraft/auth/Parsers.cpp | 190 +- launcher/minecraft/auth/Parsers.h | 27 +- launcher/minecraft/auth/Yggdrasil.cpp | 162 +- launcher/minecraft/auth/Yggdrasil.h | 40 +- launcher/minecraft/auth/flows/AuthFlow.cpp | 46 +- launcher/minecraft/auth/flows/AuthFlow.h | 31 +- launcher/minecraft/auth/flows/MSA.cpp | 21 +- launcher/minecraft/auth/flows/MSA.h | 20 +- launcher/minecraft/auth/flows/Mojang.cpp | 19 +- launcher/minecraft/auth/flows/Mojang.h | 23 +- launcher/minecraft/auth/flows/Offline.cpp | 12 +- launcher/minecraft/auth/flows/Offline.h | 20 +- .../minecraft/auth/steps/EntitlementsStep.cpp | 21 +- .../minecraft/auth/steps/EntitlementsStep.h | 9 +- launcher/minecraft/auth/steps/GetSkinStep.cpp | 24 +- launcher/minecraft/auth/steps/GetSkinStep.h | 7 +- .../auth/steps/LauncherLoginStep.cpp | 44 +- .../minecraft/auth/steps/LauncherLoginStep.h | 7 +- launcher/minecraft/auth/steps/MSAStep.cpp | 25 +- launcher/minecraft/auth/steps/MSAStep.h | 18 +- .../auth/steps/MigrationEligibilityStep.cpp | 26 +- .../auth/steps/MigrationEligibilityStep.h | 7 +- .../auth/steps/MinecraftProfileStep.cpp | 61 +- .../auth/steps/MinecraftProfileStep.h | 7 +- .../auth/steps/MinecraftProfileStepMojang.cpp | 63 +- .../auth/steps/MinecraftProfileStepMojang.h | 7 +- launcher/minecraft/auth/steps/OfflineStep.cpp | 9 +- launcher/minecraft/auth/steps/OfflineStep.h | 4 +- .../auth/steps/XboxAuthorizationStep.cpp | 132 +- .../auth/steps/XboxAuthorizationStep.h | 19 +- .../minecraft/auth/steps/XboxProfileStep.cpp | 54 +- .../minecraft/auth/steps/XboxProfileStep.h | 7 +- .../minecraft/auth/steps/XboxUserStep.cpp | 41 +- launcher/minecraft/auth/steps/XboxUserStep.h | 7 +- .../minecraft/auth/steps/YggdrasilStep.cpp | 25 +- launcher/minecraft/auth/steps/YggdrasilStep.h | 10 +- .../minecraft/gameoptions/GameOptions.cpp | 65 +- launcher/minecraft/gameoptions/GameOptions.h | 20 +- launcher/minecraft/launch/ClaimAccount.cpp | 8 +- launcher/minecraft/launch/ClaimAccount.h | 17 +- .../minecraft/launch/CreateGameFolders.cpp | 14 +- launcher/minecraft/launch/CreateGameFolders.h | 18 +- launcher/minecraft/launch/ExtractNatives.cpp | 46 +- launcher/minecraft/launch/ExtractNatives.h | 14 +- .../minecraft/launch/LauncherPartLaunch.cpp | 104 +- .../minecraft/launch/LauncherPartLaunch.h | 32 +- .../launch/MinecraftServerTarget.cpp | 31 +- .../minecraft/launch/MinecraftServerTarget.h | 2 +- launcher/minecraft/launch/ModMinecraftJar.cpp | 25 +- launcher/minecraft/launch/ModMinecraftJar.h | 15 +- .../minecraft/launch/PrintInstanceInfo.cpp | 79 +- launcher/minecraft/launch/PrintInstanceInfo.h | 18 +- .../minecraft/launch/ReconstructAssets.cpp | 7 +- launcher/minecraft/launch/ReconstructAssets.h | 12 +- launcher/minecraft/launch/ScanModFolders.cpp | 12 +- launcher/minecraft/launch/ScanModFolders.h | 19 +- .../minecraft/launch/VerifyJavaInstall.cpp | 22 +- launcher/minecraft/launch/VerifyJavaInstall.h | 9 +- launcher/minecraft/mod/DataPack.cpp | 8 +- launcher/minecraft/mod/MetadataHandler.h | 55 +- launcher/minecraft/mod/Mod.cpp | 81 +- launcher/minecraft/mod/Mod.h | 96 +- launcher/minecraft/mod/ModDetails.h | 109 +- launcher/minecraft/mod/ModFolderModel.cpp | 255 +- launcher/minecraft/mod/ModFolderModel.h | 107 +- launcher/minecraft/mod/Resource.cpp | 8 +- launcher/minecraft/mod/Resource.h | 21 +- .../minecraft/mod/ResourceFolderModel.cpp | 18 +- launcher/minecraft/mod/ResourceFolderModel.h | 15 +- launcher/minecraft/mod/ResourcePack.cpp | 2 +- .../minecraft/mod/ResourcePackFolderModel.cpp | 22 +- .../minecraft/mod/ResourcePackFolderModel.h | 21 +- .../minecraft/mod/ShaderPackFolderModel.h | 6 +- launcher/minecraft/mod/TexturePack.cpp | 2 +- .../minecraft/mod/TexturePackFolderModel.cpp | 24 +- .../minecraft/mod/TexturePackFolderModel.h | 23 +- .../minecraft/mod/tasks/BasicFolderLoadTask.h | 12 +- .../minecraft/mod/tasks/LocalModParseTask.cpp | 24 +- .../minecraft/mod/tasks/LocalModUpdateTask.h | 30 +- .../mod/tasks/LocalResourcePackParseTask.cpp | 8 +- .../mod/tasks/LocalResourceParse.cpp | 29 +- .../mod/tasks/LocalTexturePackParseTask.cpp | 11 +- .../mod/tasks/LocalWorldSaveParseTask.cpp | 8 +- .../mod/tasks/LocalWorldSaveParseTask.h | 2 +- .../minecraft/mod/tasks/ModFolderLoadTask.cpp | 77 +- .../minecraft/mod/tasks/ModFolderLoadTask.h | 82 +- launcher/minecraft/services/CapeChange.cpp | 30 +- launcher/minecraft/services/CapeChange.h | 20 +- launcher/minecraft/services/SkinDelete.cpp | 15 +- launcher/minecraft/services/SkinDelete.h | 13 +- launcher/minecraft/services/SkinUpload.cpp | 19 +- launcher/minecraft/services/SkinUpload.h | 20 +- launcher/minecraft/update/AssetUpdateTask.cpp | 30 +- launcher/minecraft/update/AssetUpdateTask.h | 17 +- .../minecraft/update/FMLLibrariesTask.cpp | 53 +- launcher/minecraft/update/FMLLibrariesTask.h | 22 +- launcher/minecraft/update/FoldersTask.cpp | 8 +- launcher/minecraft/update/FoldersTask.h | 15 +- launcher/minecraft/update/LibrariesTask.cpp | 35 +- launcher/minecraft/update/LibrariesTask.h | 19 +- launcher/modplatform/CheckUpdateTask.h | 17 +- launcher/modplatform/EnsureMetadataTask.h | 5 +- launcher/modplatform/ModIndex.cpp | 30 +- .../modplatform/atlauncher/ATLPackIndex.cpp | 11 +- .../modplatform/atlauncher/ATLPackIndex.h | 15 +- .../atlauncher/ATLPackInstallTask.cpp | 345 +- .../atlauncher/ATLPackManifest.cpp | 114 +- .../modplatform/atlauncher/ATLPackManifest.h | 48 +- .../modplatform/atlauncher/ATLShareCode.cpp | 2 +- .../modplatform/atlauncher/ATLShareCode.h | 4 +- launcher/modplatform/flame/FlameCheckUpdate.h | 5 +- launcher/modplatform/flame/FlamePackIndex.cpp | 9 +- launcher/modplatform/flame/PackManifest.cpp | 7 +- launcher/modplatform/flame/PackManifest.h | 34 +- .../modplatform/legacy_ftb/PackFetchTask.cpp | 2 +- launcher/modplatform/legacy_ftb/PackHelpers.h | 22 +- .../legacy_ftb/PrivatePackManager.cpp | 19 +- .../legacy_ftb/PrivatePackManager.h | 30 +- .../modrinth/ModrinthCheckUpdate.h | 5 +- .../modrinth/ModrinthInstanceCreationTask.cpp | 24 +- .../modrinth/ModrinthInstanceCreationTask.h | 5 +- .../modrinth/ModrinthPackManifest.cpp | 25 +- .../modrinth/ModrinthPackManifest.h | 9 +- launcher/modplatform/packwiz/Packwiz.h | 54 +- .../technic/SingleZipPackInstallTask.cpp | 39 +- .../technic/SingleZipPackInstallTask.h | 16 +- .../technic/SolderPackInstallTask.cpp | 36 +- .../technic/SolderPackManifest.cpp | 2 +- .../modplatform/technic/SolderPackManifest.h | 4 +- .../technic/TechnicPackProcessor.cpp | 102 +- .../technic/TechnicPackProcessor.h | 29 +- launcher/net/Download.cpp | 5 +- launcher/net/HttpMetaCache.cpp | 5 +- launcher/net/Logging.h | 4 +- launcher/net/MetaCacheSink.cpp | 31 +- launcher/net/NetAction.h | 4 +- launcher/net/NetJob.h | 4 +- launcher/net/NetUtils.h | 37 +- launcher/net/PasteUpload.cpp | 247 +- launcher/net/PasteUpload.h | 28 +- launcher/net/Validator.h | 19 +- launcher/news/NewsChecker.cpp | 5 +- launcher/news/NewsChecker.h | 16 +- launcher/news/NewsEntry.cpp | 16 +- launcher/news/NewsEntry.h | 15 +- launcher/pathmatcher/FSTreeMatcher.h | 20 +- launcher/pathmatcher/IPathMatcher.h | 11 +- launcher/pathmatcher/MultiMatcher.h | 23 +- launcher/pathmatcher/RegexpMatcher.h | 28 +- launcher/screenshots/ImgurAlbumCreation.cpp | 28 +- launcher/screenshots/ImgurAlbumCreation.h | 25 +- launcher/screenshots/ImgurUpload.cpp | 31 +- launcher/screenshots/ImgurUpload.h | 16 +- launcher/screenshots/Screenshot.h | 6 +- launcher/settings/INIFile.h | 9 +- launcher/settings/INISettingsObject.cpp | 50 +- launcher/settings/INISettingsObject.h | 26 +- launcher/settings/OverrideSetting.cpp | 6 +- launcher/settings/OverrideSetting.h | 11 +- launcher/settings/PassthroughSetting.cpp | 15 +- launcher/settings/PassthroughSetting.h | 11 +- launcher/settings/Setting.cpp | 14 +- launcher/settings/Setting.h | 31 +- launcher/settings/SettingsObject.cpp | 67 +- launcher/settings/SettingsObject.h | 77 +- launcher/tasks/ConcurrentTask.cpp | 13 +- launcher/tasks/Task.cpp | 48 +- launcher/tasks/Task.h | 42 +- launcher/tools/BaseExternalTool.cpp | 27 +- launcher/tools/BaseExternalTool.h | 43 +- launcher/tools/BaseProfiler.cpp | 13 +- launcher/tools/BaseProfiler.h | 27 +- launcher/tools/JProfiler.cpp | 53 +- launcher/tools/JProfiler.h | 11 +- launcher/tools/JVisualVM.cpp | 51 +- launcher/tools/JVisualVM.h | 11 +- launcher/tools/MCEditTool.cpp | 26 +- launcher/tools/MCEditTool.h | 12 +- launcher/translations/POTranslator.cpp | 186 +- launcher/translations/POTranslator.h | 14 +- launcher/translations/TranslationsModel.cpp | 391 +- launcher/ui/ColorCache.cpp | 7 +- launcher/ui/ColorCache.h | 49 +- launcher/ui/GuiUtil.cpp | 73 +- launcher/ui/GuiUtil.h | 13 +- launcher/ui/InstanceWindow.cpp | 49 +- launcher/ui/InstanceWindow.h | 30 +- launcher/ui/MainWindow.h | 76 +- launcher/ui/dialogs/AboutDialog.cpp | 61 +- launcher/ui/dialogs/AboutDialog.h | 17 +- launcher/ui/dialogs/BlockedModsDialog.cpp | 2 +- launcher/ui/dialogs/CopyInstanceDialog.cpp | 4 +- launcher/ui/dialogs/CustomMessageBox.cpp | 14 +- launcher/ui/dialogs/CustomMessageBox.h | 7 +- launcher/ui/dialogs/EditAccountDialog.cpp | 11 +- launcher/ui/dialogs/EditAccountDialog.h | 26 +- launcher/ui/dialogs/IconPickerDialog.cpp | 39 +- launcher/ui/dialogs/IconPickerDialog.h | 23 +- launcher/ui/dialogs/ImportResourceDialog.h | 2 +- launcher/ui/dialogs/LoginDialog.cpp | 28 +- launcher/ui/dialogs/LoginDialog.h | 31 +- launcher/ui/dialogs/MSALoginDialog.cpp | 41 +- launcher/ui/dialogs/MSALoginDialog.h | 32 +- launcher/ui/dialogs/ModUpdateDialog.cpp | 14 +- launcher/ui/dialogs/ModUpdateDialog.h | 4 +- launcher/ui/dialogs/NewComponentDialog.cpp | 28 +- launcher/ui/dialogs/NewComponentDialog.h | 16 +- launcher/ui/dialogs/NewInstanceDialog.cpp | 42 +- launcher/ui/dialogs/NewInstanceDialog.h | 40 +- launcher/ui/dialogs/OfflineLoginDialog.cpp | 23 +- launcher/ui/dialogs/OfflineLoginDialog.h | 29 +- launcher/ui/dialogs/ProfileSelectDialog.cpp | 30 +- launcher/ui/dialogs/ProfileSelectDialog.h | 22 +- launcher/ui/dialogs/ProfileSetupDialog.cpp | 95 +- launcher/ui/dialogs/ProfileSetupDialog.h | 56 +- launcher/ui/dialogs/ProgressDialog.cpp | 26 +- launcher/ui/dialogs/ProgressDialog.h | 47 +- launcher/ui/dialogs/ScrollMessageBox.cpp | 9 +- launcher/ui/dialogs/ScrollMessageBox.h | 15 +- launcher/ui/dialogs/SkinUploadDialog.cpp | 82 +- launcher/ui/dialogs/SkinUploadDialog.h | 21 +- launcher/ui/dialogs/VersionSelectDialog.cpp | 13 +- launcher/ui/dialogs/VersionSelectDialog.h | 37 +- .../instanceview/AccessibleInstanceView.cpp | 147 +- .../ui/instanceview/AccessibleInstanceView.h | 4 +- .../instanceview/AccessibleInstanceView_p.h | 68 +- launcher/ui/instanceview/InstanceDelegate.cpp | 140 +- launcher/ui/instanceview/InstanceDelegate.h | 23 +- .../ui/instanceview/InstanceProxyModel.cpp | 33 +- launcher/ui/instanceview/InstanceProxyModel.h | 19 +- launcher/ui/instanceview/InstanceView.cpp | 454 +- launcher/ui/instanceview/InstanceView.h | 116 +- launcher/ui/instanceview/VisualGroup.h | 53 +- launcher/ui/pagedialog/PageDialog.cpp | 14 +- launcher/ui/pagedialog/PageDialog.h | 16 +- launcher/ui/pages/BasePageContainer.h | 5 +- launcher/ui/pages/BasePageProvider.h | 47 +- launcher/ui/pages/global/APIPage.cpp | 45 +- launcher/ui/pages/global/APIPage.h | 36 +- launcher/ui/pages/global/AccountListPage.cpp | 94 +- launcher/ui/pages/global/AccountListPage.h | 44 +- .../ui/pages/global/CustomCommandsPage.cpp | 20 +- launcher/ui/pages/global/CustomCommandsPage.h | 35 +- .../ui/pages/global/ExternalToolsPage.cpp | 103 +- launcher/ui/pages/global/ExternalToolsPage.h | 36 +- launcher/ui/pages/global/JavaPage.cpp | 44 +- launcher/ui/pages/global/JavaPage.h | 47 +- launcher/ui/pages/global/LanguagePage.cpp | 11 +- launcher/ui/pages/global/LanguagePage.h | 37 +- launcher/ui/pages/global/LauncherPage.cpp | 99 +- launcher/ui/pages/global/LauncherPage.h | 49 +- launcher/ui/pages/global/MinecraftPage.cpp | 6 +- launcher/ui/pages/global/MinecraftPage.h | 44 +- launcher/ui/pages/global/ProxyPage.cpp | 21 +- launcher/ui/pages/global/ProxyPage.h | 44 +- .../ui/pages/instance/ExternalResourcesPage.h | 4 +- .../ui/pages/instance/GameOptionsPage.cpp | 11 +- launcher/ui/pages/instance/GameOptionsPage.h | 38 +- .../pages/instance/InstanceSettingsPage.cpp | 127 +- .../ui/pages/instance/InstanceSettingsPage.h | 36 +- launcher/ui/pages/instance/LogPage.cpp | 146 +- launcher/ui/pages/instance/LogPage.h | 44 +- launcher/ui/pages/instance/NotesPage.cpp | 5 +- launcher/ui/pages/instance/NotesPage.h | 35 +- launcher/ui/pages/instance/OtherLogsPage.cpp | 140 +- launcher/ui/pages/instance/OtherLogsPage.h | 42 +- launcher/ui/pages/instance/ResourcePackPage.h | 11 +- .../ui/pages/instance/ScreenshotsPage.cpp | 244 +- launcher/ui/pages/instance/ScreenshotsPage.h | 58 +- launcher/ui/pages/instance/ServersPage.cpp | 382 +- launcher/ui/pages/instance/ServersPage.h | 59 +- launcher/ui/pages/instance/ShaderPackPage.h | 7 +- launcher/ui/pages/instance/TexturePackPage.h | 12 +- launcher/ui/pages/instance/WorldListPage.cpp | 179 +- launcher/ui/pages/instance/WorldListPage.h | 64 +- launcher/ui/pages/modplatform/CustomPage.cpp | 83 +- launcher/ui/pages/modplatform/CustomPage.h | 44 +- launcher/ui/pages/modplatform/ImportPage.cpp | 66 +- launcher/ui/pages/modplatform/ImportPage.h | 43 +- .../ui/pages/modplatform/ResourcePackPage.cpp | 6 +- .../ui/pages/modplatform/ResourcePackPage.h | 2 +- .../ui/pages/modplatform/TexturePackPage.h | 5 +- .../modplatform/atlauncher/AtlFilterModel.cpp | 16 +- .../modplatform/atlauncher/AtlFilterModel.h | 16 +- .../atlauncher/AtlOptionalModDialog.cpp | 130 +- .../atlauncher/AtlOptionalModDialog.h | 37 +- .../pages/modplatform/atlauncher/AtlPage.cpp | 34 +- .../ui/pages/modplatform/atlauncher/AtlPage.h | 46 +- .../AtlUserInteractionSupportImpl.cpp | 16 +- .../ui/pages/modplatform/flame/FlameModel.cpp | 8 +- .../ui/pages/modplatform/flame/FlamePage.cpp | 9 +- .../ui/pages/modplatform/flame/FlamePage.h | 46 +- .../modplatform/flame/FlameResourcePages.cpp | 28 +- .../modplatform/flame/FlameResourcePages.h | 29 +- .../pages/modplatform/legacy_ftb/ListModel.h | 49 +- .../ui/pages/modplatform/legacy_ftb/Page.cpp | 147 +- .../ui/pages/modplatform/legacy_ftb/Page.h | 62 +- .../modplatform/modrinth/ModrinthModel.cpp | 28 +- .../modplatform/modrinth/ModrinthModel.h | 9 +- .../modrinth/ModrinthResourcePages.cpp | 30 +- .../modrinth/ModrinthResourcePages.h | 30 +- .../pages/modplatform/technic/TechnicData.h | 2 +- .../pages/modplatform/technic/TechnicPage.cpp | 98 +- .../pages/modplatform/technic/TechnicPage.h | 44 +- launcher/ui/setupwizard/BaseWizardPage.h | 30 +- launcher/ui/setupwizard/JavaWizardPage.cpp | 40 +- launcher/ui/setupwizard/JavaWizardPage.h | 18 +- .../ui/setupwizard/LanguageWizardPage.cpp | 13 +- launcher/ui/setupwizard/LanguageWizardPage.h | 13 +- launcher/ui/setupwizard/PasteWizardPage.cpp | 11 +- launcher/ui/setupwizard/PasteWizardPage.h | 13 +- launcher/ui/setupwizard/SetupWizard.cpp | 47 +- launcher/ui/setupwizard/SetupWizard.h | 21 +- launcher/ui/themes/BrightTheme.cpp | 23 +- launcher/ui/themes/BrightTheme.h | 6 +- launcher/ui/themes/CustomTheme.cpp | 3 +- launcher/ui/themes/DarkTheme.cpp | 16 +- launcher/ui/themes/DarkTheme.h | 5 +- launcher/ui/themes/FusionTheme.h | 5 +- launcher/ui/themes/ITheme.cpp | 7 +- launcher/ui/themes/SystemTheme.cpp | 2 +- launcher/ui/widgets/CustomCommands.cpp | 13 +- launcher/ui/widgets/CustomCommands.h | 18 +- launcher/ui/widgets/DropLabel.cpp | 17 +- launcher/ui/widgets/DropLabel.h | 19 +- launcher/ui/widgets/ErrorFrame.cpp | 46 +- launcher/ui/widgets/ErrorFrame.h | 22 +- launcher/ui/widgets/FocusLineEdit.cpp | 9 +- launcher/ui/widgets/FocusLineEdit.h | 17 +- launcher/ui/widgets/IconLabel.cpp | 16 +- launcher/ui/widgets/IconLabel.h | 13 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 145 +- launcher/ui/widgets/JavaSettingsWidget.h | 71 +- launcher/ui/widgets/LabeledToolButton.cpp | 46 +- launcher/ui/widgets/LabeledToolButton.h | 16 +- launcher/ui/widgets/LineSeparator.cpp | 14 +- launcher/ui/widgets/LineSeparator.h | 14 +- launcher/ui/widgets/LogView.cpp | 49 +- launcher/ui/widgets/LogView.h | 33 +- launcher/ui/widgets/ModFilterWidget.cpp | 110 +- launcher/ui/widgets/ModFilterWidget.h | 33 +- launcher/ui/widgets/ModListView.cpp | 46 +- launcher/ui/widgets/ModListView.h | 11 +- launcher/ui/widgets/PageContainer.cpp | 103 +- launcher/ui/widgets/PageContainer.h | 54 +- launcher/ui/widgets/PageContainer_p.h | 77 +- launcher/ui/widgets/ProjectItem.cpp | 5 +- launcher/ui/widgets/ProjectItem.h | 7 +- launcher/ui/widgets/SubTaskProgressBar.cpp | 6 +- launcher/ui/widgets/SubTaskProgressBar.h | 10 +- .../ui/widgets/ThemeCustomizationWidget.cpp | 18 +- launcher/ui/widgets/VersionListView.cpp | 52 +- launcher/ui/widgets/VersionListView.h | 31 +- launcher/ui/widgets/VersionSelectWidget.cpp | 52 +- launcher/ui/widgets/VersionSelectWidget.h | 49 +- launcher/ui/widgets/WideBar.cpp | 10 +- launcher/updater/ExternalUpdater.h | 9 +- launcher/updater/MacSparkleUpdater.h | 11 +- launcher/updater/MacSparkleUpdater.mm | 107 +- libraries/LocalPeer/include/LocalPeer.h | 44 +- libraries/LocalPeer/src/LocalPeer.cpp | 65 +- libraries/LocalPeer/src/LockedFile.cpp | 6 +- libraries/LocalPeer/src/LockedFile.h | 10 +- libraries/LocalPeer/src/LockedFile_unix.cpp | 6 +- libraries/LocalPeer/src/LockedFile_win.cpp | 40 +- libraries/gamemode/include/gamemode_client.h | 296 +- libraries/javacheck/JavaCheck.java | 8 +- libraries/katabasis/include/katabasis/Bits.h | 16 +- .../katabasis/include/katabasis/DeviceFlow.h | 64 +- .../katabasis/include/katabasis/Globals.h | 4 +- .../katabasis/include/katabasis/PollServer.h | 25 +- libraries/katabasis/include/katabasis/Reply.h | 40 +- .../include/katabasis/RequestParameter.h | 8 +- libraries/katabasis/src/DeviceFlow.cpp | 184 +- libraries/katabasis/src/JsonResponse.cpp | 5 +- libraries/katabasis/src/JsonResponse.h | 6 +- libraries/katabasis/src/PollServer.cpp | 37 +- libraries/katabasis/src/Reply.cpp | 31 +- .../launcher/net/minecraft/Launcher.java | 8 +- .../org/prismlauncher/EntryPoint.java | 20 +- .../exception/ParameterNotFoundException.java | 2 - .../exception/ParseException.java | 2 - .../org/prismlauncher/launcher/Launcher.java | 2 - .../launcher/impl/AbstractLauncher.java | 8 +- .../launcher/impl/StandardLauncher.java | 6 +- .../launcher/impl/legacy/LegacyFrame.java | 12 +- .../launcher/impl/legacy/LegacyLauncher.java | 15 +- .../org/prismlauncher/utils/Parameters.java | 6 +- .../prismlauncher/utils/ReflectionUtils.java | 9 +- .../prismlauncher/utils/logging/Level.java | 1 - .../org/prismlauncher/utils/logging/Log.java | 4 +- libraries/murmur2/src/MurmurHash2.h | 4 +- libraries/rainbow/include/rainbow.h | 27 +- libraries/rainbow/src/rainbow.cpp | 187 +- libraries/systeminfo/include/distroutils.h | 17 +- libraries/systeminfo/include/sys.h | 32 +- libraries/systeminfo/src/distroutils.cpp | 166 +- libraries/systeminfo/src/sys_apple.cpp | 19 +- libraries/systeminfo/src/sys_test.cpp | 24 +- libraries/systeminfo/src/sys_unix.cpp | 56 +- libraries/systeminfo/src/sys_win32.cpp | 2 +- renovate.json | 20 +- tests/DataPackParse_test.cpp | 8 +- tests/FileSystem_test.cpp | 275 +- tests/GZip_test.cpp | 14 +- tests/GradleSpecifier_test.cpp | 22 +- tests/Index_test.cpp | 22 +- tests/JavaVersion_test.cpp | 69 +- tests/Library_test.cpp | 62 +- tests/MojangVersionFormat_test.cpp | 11 +- tests/Packwiz_test.cpp | 16 +- tests/ParseUtils_test.cpp | 24 +- tests/ResourceFolderModel_test.cpp | 100 +- tests/ResourceModel_test.cpp | 3 +- tests/ResourcePackParse_test.cpp | 14 +- tests/ShaderPackParse_test.cpp | 8 +- tests/Task_test.cpp | 5 +- tests/TexturePackParse_test.cpp | 8 +- tests/Version_test.cpp | 75 +- tests/WorldSaveParse_test.cpp | 18 +- .../MojangVersionFormat/1.9-simple.json | 3 +- tests/testdata/MojangVersionFormat/1.9.json | 54 +- .../MojangVersionFormat/lib-native.json | 12 +- .../PackageManifest/1.8.0_202-x64.json | 4668 ++++++++++++++++- 594 files changed, 16040 insertions(+), 16536 deletions(-) diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index 11773d887..387f494f3 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -36,8 +36,8 @@ */ #pragma once -#include #include +#include /** * \brief The Config class holds all the build-time information passed from the build system. @@ -145,7 +145,7 @@ class Config { QString AUTH_BASE = "https://authserver.mojang.com/"; QString IMGUR_BASE_URL = "https://api.imgur.com/3/"; QString FMLLIBS_BASE_URL = "https://files.prismlauncher.org/fmllibs/"; // FIXME: move into CMakeLists - QString TRANSLATIONS_BASE_URL = "https://i18n.prismlauncher.org/"; // FIXME: move into CMakeLists + QString TRANSLATIONS_BASE_URL = "https://i18n.prismlauncher.org/"; // FIXME: move into CMakeLists QString MODPACKSCH_API_BASE_URL = "https://api.modpacks.ch/"; @@ -162,7 +162,7 @@ class Config { QString MODRINTH_STAGING_URL = "https://staging-api.modrinth.com/v2"; QString MODRINTH_PROD_URL = "https://api.modrinth.com/v2"; - QStringList MODRINTH_MRPACK_HOSTS{"cdn.modrinth.com", "github.com", "raw.githubusercontent.com", "gitlab.com"}; + QStringList MODRINTH_MRPACK_HOSTS{ "cdn.modrinth.com", "github.com", "raw.githubusercontent.com", "gitlab.com" }; QString FLAME_BASE_URL = "https://api.curseforge.com/v1"; diff --git a/flatpak/libdecor.json b/flatpak/libdecor.json index 12afad69f..589310a35 100644 --- a/flatpak/libdecor.json +++ b/flatpak/libdecor.json @@ -1,22 +1,22 @@ { - "name": "libdecor", - "buildsystem": "meson", - "config-opts": [ - "-Ddemo=false" - ], - "sources": [ - { - "type": "git", - "url": "https://gitlab.freedesktop.org/libdecor/libdecor.git", - "commit": "73260393a97291c887e1074ab7f318e031be0ac6" - }, - { - "type": "patch", - "path": "patches/weird_libdecor.patch" - } - ], - "cleanup": [ - "/include", - "/lib/pkgconfig" - ] + "name": "libdecor", + "buildsystem": "meson", + "config-opts": [ + "-Ddemo=false" + ], + "sources": [ + { + "type": "git", + "url": "https://gitlab.freedesktop.org/libdecor/libdecor.git", + "commit": "73260393a97291c887e1074ab7f318e031be0ac6" + }, + { + "type": "patch", + "path": "patches/weird_libdecor.patch" + } + ], + "cleanup": [ + "/include", + "/lib/pkgconfig" + ] } diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c594a2976..14fda9e65 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -49,27 +49,27 @@ #include "pathmatcher/MultiMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h" #include "settings/INIFile.h" -#include "ui/MainWindow.h" #include "ui/InstanceWindow.h" +#include "ui/MainWindow.h" #include "ui/dialogs/ProgressDialog.h" #include "ui/instanceview/AccessibleInstanceView.h" #include "ui/pages/BasePageProvider.h" -#include "ui/pages/global/LauncherPage.h" -#include "ui/pages/global/MinecraftPage.h" +#include "ui/pages/global/APIPage.h" +#include "ui/pages/global/AccountListPage.h" +#include "ui/pages/global/CustomCommandsPage.h" +#include "ui/pages/global/ExternalToolsPage.h" #include "ui/pages/global/JavaPage.h" #include "ui/pages/global/LanguagePage.h" +#include "ui/pages/global/LauncherPage.h" +#include "ui/pages/global/MinecraftPage.h" #include "ui/pages/global/ProxyPage.h" -#include "ui/pages/global/ExternalToolsPage.h" -#include "ui/pages/global/AccountListPage.h" -#include "ui/pages/global/APIPage.h" -#include "ui/pages/global/CustomCommandsPage.h" -#include "ui/setupwizard/SetupWizard.h" -#include "ui/setupwizard/LanguageWizardPage.h" #include "ui/setupwizard/JavaWizardPage.h" +#include "ui/setupwizard/LanguageWizardPage.h" #include "ui/setupwizard/PasteWizardPage.h" +#include "ui/setupwizard/SetupWizard.h" #include "ui/setupwizard/ThemeWizardPage.h" #include "ui/dialogs/CustomMessageBox.h" @@ -83,20 +83,20 @@ #include #include -#include #include #include +#include #include #include -#include -#include +#include +#include #include #include +#include #include -#include #include +#include #include -#include #include "InstanceList.h" #include "MTPixmapCache.h" @@ -116,32 +116,31 @@ #include "settings/INISettingsObject.h" #include "settings/Setting.h" -#include "translations/TranslationsModel.h" #include "meta/Index.h" +#include "translations/TranslationsModel.h" -#include #include +#include #include #include #ifdef Q_OS_LINUX #include -#include "gamemode_client.h" #include "MangoHud.h" +#include "gamemode_client.h" #endif #ifdef Q_OS_MAC #include "updater/MacSparkleUpdater.h" #endif - #if defined Q_OS_WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #include +#include #endif #define STRINGIFY(x) #x @@ -154,10 +153,10 @@ PixmapCache* PixmapCache::s_instance = nullptr; namespace { /** This is used so that we can output to the log file in addition to the CLI. */ -void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +void appDebugOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg) { static std::mutex loggerMutex; - const std::lock_guard lock(loggerMutex); // synchronized, QFile logFile is not thread-safe + const std::lock_guard lock(loggerMutex); // synchronized, QFile logFile is not thread-safe QString out = qFormatLogMessage(type, context, msg); out += QChar::LineFeed; @@ -168,30 +167,26 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QSt fflush(stderr); } -} +} // namespace -Application::Application(int &argc, char **argv) : QApplication(argc, argv) +Application::Application(int& argc, char** argv) : QApplication(argc, argv) { #if defined Q_OS_WIN32 // attach the parent console - if(AttachConsole(ATTACH_PARENT_PROCESS)) - { + if (AttachConsole(ATTACH_PARENT_PROCESS)) { // if attach succeeds, reopen and sync all the i/o - if(freopen("CON", "w", stdout)) - { + if (freopen("CON", "w", stdout)) { std::cout.sync_with_stdio(); } - if(freopen("CON", "w", stderr)) - { + if (freopen("CON", "w", stderr)) { std::cerr.sync_with_stdio(); } - if(freopen("CON", "r", stdin)) - { + if (freopen("CON", "r", stdin)) { std::cin.sync_with_stdio(); } - auto out = GetStdHandle (STD_OUTPUT_HANDLE); + auto out = GetStdHandle(STD_OUTPUT_HANDLE); DWORD written; - const char * endline = "\n"; + const char* endline = "\n"; WriteConsole(out, endline, strlen(endline), &written, NULL); consoleAttached = true; } @@ -211,15 +206,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QCommandLineParser parser; parser.setApplicationDescription(BuildConfig.LAUNCHER_DISPLAYNAME); - parser.addOptions({ - {{"d", "dir"}, "Use a custom path as application root (use '.' for current directory)", "directory"}, - {{"l", "launch"}, "Launch the specified instance (by instance ID)", "instance"}, - {{"s", "server"}, "Join the specified server on launch (only valid in combination with --launch)", "address"}, - {{"a", "profile"}, "Use the account specified by its profile name (only valid in combination with --launch)", "profile"}, - {"alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"}, - {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}, - {"show", "Opens the window for the specified instance (by instance ID)", "show"} - }); + parser.addOptions( + { { { "d", "dir" }, "Use a custom path as application root (use '.' for current directory)", "directory" }, + { { "l", "launch" }, "Launch the specified instance (by instance ID)", "instance" }, + { { "s", "server" }, "Join the specified server on launch (only valid in combination with --launch)", "address" }, + { { "a", "profile" }, "Use the account specified by its profile name (only valid in combination with --launch)", "profile" }, + { "alive", "Write a small '" + liveCheckFile + "' file after the launcher starts" }, + { { "I", "import" }, "Import instance from specified zip (local path or URL)", "file" }, + { "show", "Opens the window for the specified instance (by instance ID)", "show" } }); parser.addHelpOption(); parser.addVersionOption(); @@ -232,7 +226,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_instanceIdToShowWindowOf = parser.value("show"); - for (auto zip_path : parser.values("import")){ + for (auto zip_path : parser.values("import")) { m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath())); } @@ -241,10 +235,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath())); } - // error if --launch is missing with --server or --profile - if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) - { + if ((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) { std::cerr << "--server and --profile can only be used in combination with --launch!" << std::endl; m_status = Application::Failed; return; @@ -256,7 +248,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) { // Root path is used for updates and portable data #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - QDir foo(FS::PathCombine(binPath, "..")); // typically portable-root or /usr + QDir foo(FS::PathCombine(binPath, "..")); // typically portable-root or /usr m_rootPath = foo.absolutePath(); #elif defined(Q_OS_WIN32) m_rootPath = binPath; @@ -272,25 +264,19 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QString dataPath; // change folder QString dirParam = parser.value("dir"); - if (!dirParam.isEmpty()) - { + if (!dirParam.isEmpty()) { // the dir param. it makes multimc data path point to whatever the user specified // on command line adjustedBy = "Command line"; dataPath = dirParam; - } - else - { + } else { QDir foo; - if (DesktopServices::isSnap()) - { + if (DesktopServices::isSnap()) { foo = QDir(getenv("SNAP_USER_COMMON")); - } - else - { + } else { foo = QDir(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); } - + dataPath = foo.absolutePath(); adjustedBy = "Persistent data path"; @@ -303,34 +289,27 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) #endif } - if (!FS::ensureFolderPathExists(dataPath)) - { + if (!FS::ensureFolderPathExists(dataPath)) { showFatalErrorMessage( "The launcher data folder could not be created.", - QString( - "The launcher data folder could not be created.\n" - "\n" - "Make sure you have the right permissions to the launcher data folder and any folder needed to access it.\n" - "(%1)\n" - "\n" - "The launcher cannot continue until you fix this problem." - ).arg(dataPath) - ); + QString("The launcher data folder could not be created.\n" + "\n" + "Make sure you have the right permissions to the launcher data folder and any folder needed to access it.\n" + "(%1)\n" + "\n" + "The launcher cannot continue until you fix this problem.") + .arg(dataPath)); return; } - if (!QDir::setCurrent(dataPath)) - { - showFatalErrorMessage( - "The launcher data folder could not be opened.", - QString( - "The launcher data folder could not be opened.\n" - "\n" - "Make sure you have the right permissions to the launcher data folder.\n" - "(%1)\n" - "\n" - "The launcher cannot continue until you fix this problem." - ).arg(dataPath) - ); + if (!QDir::setCurrent(dataPath)) { + showFatalErrorMessage("The launcher data folder could not be opened.", + QString("The launcher data folder could not be opened.\n" + "\n" + "Make sure you have the right permissions to the launcher data folder.\n" + "(%1)\n" + "\n" + "The launcher cannot continue until you fix this problem.") + .arg(dataPath)); return; } @@ -344,17 +323,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // FIXME: you can run the same binaries with multiple data dirs and they won't clash. This could cause issues for updates. m_peerInstance = new LocalPeer(this, appID); connect(m_peerInstance, &LocalPeer::messageReceived, this, &Application::messageReceived); - if(m_peerInstance->isClient()) { + if (m_peerInstance->isClient()) { int timeout = 2000; - if(m_instanceIdToLaunch.isEmpty()) - { + if (m_instanceIdToLaunch.isEmpty()) { ApplicationMessage activate; activate.command = "activate"; m_peerInstance->sendMessage(activate.serialize(), timeout); - if(!m_zipsToImport.isEmpty()) - { + if (!m_zipsToImport.isEmpty()) { for (auto zip_url : m_zipsToImport) { ApplicationMessage import; import.command = "import"; @@ -362,19 +339,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_peerInstance->sendMessage(import.serialize(), timeout); } } - } - else - { + } else { ApplicationMessage launch; launch.command = "launch"; launch.args["id"] = m_instanceIdToLaunch; - if(!m_serverToJoin.isEmpty()) - { + if (!m_serverToJoin.isEmpty()) { launch.args["server"] = m_serverToJoin; } - if(!m_profileToUse.isEmpty()) - { + if (!m_profileToUse.isEmpty()) { launch.args["profile"] = m_profileToUse; } m_peerInstance->sendMessage(launch.serialize(), timeout); @@ -418,44 +391,51 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) qInstallMessageHandler(appDebugOutput); qSetMessagePattern( - "%{time process}" " " - "%{if-debug}D%{endif}" "%{if-info}I%{endif}" "%{if-warning}W%{endif}" "%{if-critical}C%{endif}" "%{if-fatal}F%{endif}" - " " "|" " " - "%{if-category}[%{category}]: %{endif}" - "%{message}"); - + "%{time process}" + " " + "%{if-debug}D%{endif}" + "%{if-info}I%{endif}" + "%{if-warning}W%{endif}" + "%{if-critical}C%{endif}" + "%{if-fatal}F%{endif}" + " " + "|" + " " + "%{if-category}[%{category}]: %{endif}" + "%{message}"); + bool foundLoggingRules = false; - + auto logRulesFile = QStringLiteral("qtlogging.ini"); auto logRulesPath = FS::PathCombine(dataPath, logRulesFile); - - qDebug() << "Testing" << logRulesPath << "..."; + + qDebug() << "Testing" << logRulesPath << "..."; foundLoggingRules = QFile::exists(logRulesPath); // search the dataPath() // seach app data standard path - if(!foundLoggingRules && !isPortable() && dirParam.isEmpty()) { + if (!foundLoggingRules && !isPortable() && dirParam.isEmpty()) { logRulesPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, FS::PathCombine("..", logRulesFile)); - if(!logRulesPath.isEmpty()) { + if (!logRulesPath.isEmpty()) { qDebug() << "Found" << logRulesPath << "..."; foundLoggingRules = true; } } // seach root path - if(!foundLoggingRules) { + if (!foundLoggingRules) { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - logRulesPath = FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME, logRulesFile); + logRulesPath = FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME, logRulesFile); #else - logRulesPath = FS::PathCombine(m_rootPath, logRulesFile); + logRulesPath = FS::PathCombine(m_rootPath, logRulesFile); #endif qDebug() << "Testing" << logRulesPath << "..."; foundLoggingRules = QFile::exists(logRulesPath); } - - if(foundLoggingRules) { + + if (foundLoggingRules) { // load and set logging rules qDebug() << "Loading logging rules from:" << logRulesPath; - QSettings loggingRules(logRulesPath, QSettings::IniFormat); + QSettings loggingRules(logRulesPath, QSettings::IniFormat); loggingRules.beginGroup("Rules"); QStringList rule_names = loggingRules.childKeys(); QStringList rules; @@ -476,49 +456,44 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) bool migrated = false; if (!migrated) - migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../PolyMC"), "PolyMC", "polymc.cfg"); + migrated = handleDataMigration( + dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../PolyMC"), "PolyMC", + "polymc.cfg"); if (!migrated) - migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../multimc"), "MultiMC", "multimc.cfg"); + migrated = handleDataMigration( + dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../multimc"), "MultiMC", + "multimc.cfg"); } { - qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; qDebug() << "Version : " << BuildConfig.printableVersionString(); qDebug() << "Platform : " << BuildConfig.BUILD_PLATFORM; qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; - if (adjustedBy.size()) - { + if (adjustedBy.size()) { qDebug() << "Work dir before adjustment : " << origcwdPath; qDebug() << "Work dir after adjustment : " << QDir::currentPath(); qDebug() << "Adjusted by : " << adjustedBy; - } - else - { + } else { qDebug() << "Work dir : " << QDir::currentPath(); } qDebug() << "Binary path : " << binPath; qDebug() << "Application root path : " << m_rootPath; - if(!m_instanceIdToLaunch.isEmpty()) - { + if (!m_instanceIdToLaunch.isEmpty()) { qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; } - if(!m_serverToJoin.isEmpty()) - { + if (!m_serverToJoin.isEmpty()) { qDebug() << "Address of server to join :" << m_serverToJoin; } qDebug() << "<> Paths set."; } - if(m_liveCheck) - { + if (m_liveCheck) { QFile check(liveCheckFile); - if(check.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { + if (check.open(QIODevice::WriteOnly | QIODevice::Truncate)) { auto payload = appID.toString().toUtf8(); - if(check.write(payload) == payload.size()) - { + if (check.write(payload) == payload.size()) { check.close(); } else { qWarning() << "Could not write into" << liveCheckFile << "!"; @@ -564,7 +539,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QString resolvedDefaultMonospace = consoleFontInfo.family(); QFont resolvedFont(resolvedDefaultMonospace); qDebug() << "Detected default console font:" << resolvedDefaultMonospace - << ", substitutions:" << resolvedFont.substitutions().join(','); + << ", substitutions:" << resolvedFont.substitutions().join(','); m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace); m_settings->registerSetting("ConsoleFontSize", defaultSize); @@ -573,7 +548,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Folders m_settings->registerSetting("InstanceDir", "instances"); - m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods"); + m_settings->registerSetting({ "CentralModsDir", "ModsDir" }, "mods"); m_settings->registerSetting("IconsDir", "icons"); m_settings->registerSetting("DownloadsDir", QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); m_settings->registerSetting("DownloadsDirWatchRecursive", false); @@ -592,20 +567,20 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("LogPrePostOutput", true); // Window Size - m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false); - m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854); - m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480); + m_settings->registerSetting({ "LaunchMaximized", "MCWindowMaximize" }, false); + m_settings->registerSetting({ "MinecraftWinWidth", "MCWindowWidth" }, 854); + m_settings->registerSetting({ "MinecraftWinHeight", "MCWindowHeight" }, 480); // Proxy Settings m_settings->registerSetting("ProxyType", "None"); - m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1"); + m_settings->registerSetting({ "ProxyAddr", "ProxyHostName" }, "127.0.0.1"); m_settings->registerSetting("ProxyPort", 8080); - m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, ""); - m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, ""); + m_settings->registerSetting({ "ProxyUser", "ProxyUsername" }, ""); + m_settings->registerSetting({ "ProxyPass", "ProxyPassword" }, ""); // Memory - m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); - m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, suitableMaxMem()); + m_settings->registerSetting({ "MinMemAlloc", "MinMemoryAlloc" }, 512); + m_settings->registerSetting({ "MaxMemAlloc", "MaxMemoryAlloc" }, suitableMaxMem()); m_settings->registerSetting("PermGen", 128); // Java Settings @@ -647,8 +622,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("WrapperCommand", ""); // Custom Commands - m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, ""); - m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, ""); + m_settings->registerSetting({ "PreLaunchCommand", "PreLaunchCmd" }, ""); + m_settings->registerSetting({ "PostExitCommand", "PostExitCmd" }, ""); // The cat m_settings->registerSetting("TheCat", false); @@ -687,8 +662,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QString pastebinURL = m_settings->get("PastebinURL").toString(); bool userHadDefaultPastebin = pastebinURL == "https://0x0.st"; - if (!pastebinURL.isEmpty() && !userHadDefaultPastebin) - { + if (!pastebinURL.isEmpty() && !userHadDefaultPastebin) { m_settings->set("PastebinType", PasteUpload::PasteType::NullPointer); m_settings->set("PastebinCustomAPIBase", pastebinURL); m_settings->reset("PastebinURL"); @@ -697,8 +671,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) bool ok; int pasteType = m_settings->get("PastebinType").toInt(&ok); // If PastebinType is invalid then reset the related settings. - if (!ok || !(PasteUpload::PasteType::First <= pasteType && pasteType <= PasteUpload::PasteType::Last)) - { + if (!ok || !(PasteUpload::PasteType::First <= pasteType && pasteType <= PasteUpload::PasteType::Last)) { m_settings->reset("PastebinType"); m_settings->reset("PastebinCustomAPIBase"); } @@ -779,8 +752,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) } // initialize the updater - if(BuildConfig.UPDATER_ENABLED) - { + if (BuildConfig.UPDATER_ENABLED) { qDebug() << "Initializing updater"; #ifdef Q_OS_MAC m_updater.reset(new MacSparkleUpdater()); @@ -791,18 +763,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Instance icons { auto setting = APPLICATION->settings()->getSetting("IconsDir"); - QStringList instFolders = - { - ":/icons/multimc/32x32/instances/", - ":/icons/multimc/50x50/instances/", - ":/icons/multimc/128x128/instances/", - ":/icons/multimc/scalable/instances/" - }; + QStringList instFolders = { ":/icons/multimc/32x32/instances/", ":/icons/multimc/50x50/instances/", + ":/icons/multimc/128x128/instances/", ":/icons/multimc/scalable/instances/" }; m_icons.reset(new IconList(instFolders, setting->get().toString())); - connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) - { - m_icons->directoryChanged(value.toString()); - }); + connect(setting.get(), &Setting::SettingChanged, + [&](const Setting&, QVariant value) { m_icons->directoryChanged(value.toString()); }); qDebug() << "<> Instance icons intialized."; } @@ -816,8 +781,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // and remember that we have to show him a dialog when the gui starts (if it does so) QString instDir = InstDirSetting->get().toString(); qDebug() << "Instance path : " << instDir; - if (FS::checkProblemticPathJava(QDir(instDir))) - { + if (FS::checkProblemticPathJava(QDir(instDir))) { qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!"; } m_instances.reset(new InstanceList(m_settings, instDir, this)); @@ -867,11 +831,10 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // now we have network, download translation updates m_translations->downloadIndex(); - //FIXME: what to do with these? + // FIXME: what to do with these? m_profilers.insert("jprofiler", std::shared_ptr(new JProfilerFactory())); m_profilers.insert("jvisualvm", std::shared_ptr(new JVisualVMFactory())); - for (auto profiler : m_profilers.values()) - { + for (auto profiler : m_profilers.values()) { profiler->registerSettings(m_settings); } @@ -881,19 +844,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) } #ifdef Q_OS_MACOS - connect(this, &Application::clickedOnDock, [this]() { - this->showMainWindow(); - }); + connect(this, &Application::clickedOnDock, [this]() { this->showMainWindow(); }); #endif - connect(this, &Application::aboutToQuit, [this](){ - if(m_instances) - { + connect(this, &Application::aboutToQuit, [this]() { + if (m_instances) { // save any remaining instance state m_instances->saveNow(); } - if(logFile) - { + if (logFile) { logFile->flush(); logFile->close(); } @@ -903,8 +862,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) updateCapabilities(); - if(createSetupWizard()) - { + if (createSetupWizard()) { return; } @@ -913,23 +871,20 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) bool Application::createSetupWizard() { - bool javaRequired = [&]() - { + bool javaRequired = [&]() { bool ignoreJavaWizard = m_settings->get("IgnoreJavaWizard").toBool(); - if(ignoreJavaWizard) { + if (ignoreJavaWizard) { return false; } QString currentHostName = QHostInfo::localHostName(); QString oldHostName = settings()->get("LastHostname").toString(); - if (currentHostName != oldHostName) - { + if (currentHostName != oldHostName) { settings()->set("LastHostname", currentHostName); return true; } QString currentJavaPath = settings()->get("JavaPath").toString(); QString actualPath = FS::ResolveExecutable(currentJavaPath); - if (actualPath.isNull()) - { + if (actualPath.isNull()) { return true; } return false; @@ -939,27 +894,22 @@ bool Application::createSetupWizard() bool themeInterventionRequired = settings()->get("ApplicationTheme") == ""; bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired; - if(wizardRequired) - { + if (wizardRequired) { m_setupWizard = new SetupWizard(nullptr); - if (languageRequired) - { + if (languageRequired) { m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard)); } - if (javaRequired) - { + if (javaRequired) { m_setupWizard->addPage(new JavaWizardPage(m_setupWizard)); } - if (pasteInterventionRequired) - { + if (pasteInterventionRequired) { m_setupWizard->addPage(new PasteWizardPage(m_setupWizard)); } - if (themeInterventionRequired) - { - settings()->set("ApplicationTheme", QString("system")); // set default theme after going into theme wizard + if (themeInterventionRequired) { + settings()->set("ApplicationTheme", QString("system")); // set default theme after going into theme wizard m_setupWizard->addPage(new ThemeWizardPage(m_setupWizard)); } connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished); @@ -999,26 +949,22 @@ void Application::setupWizardFinished(int status) void Application::performMainStartupAction() { m_status = Application::Initialized; - if(!m_instanceIdToLaunch.isEmpty()) - { + if (!m_instanceIdToLaunch.isEmpty()) { auto inst = instances()->getInstanceById(m_instanceIdToLaunch); - if(inst) - { + if (inst) { MinecraftServerTargetPtr serverToJoin = nullptr; MinecraftAccountPtr accountToUse = nullptr; qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; - if(!m_serverToJoin.isEmpty()) - { + if (!m_serverToJoin.isEmpty()) { // FIXME: validate the server string serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); qDebug() << " Launching with server" << m_serverToJoin; } - if(!m_profileToUse.isEmpty()) - { + if (!m_profileToUse.isEmpty()) { accountToUse = accounts()->getAccountByProfileName(m_profileToUse); - if(!accountToUse) { + if (!accountToUse) { return; } qDebug() << " Launching with account" << m_profileToUse; @@ -1028,26 +974,22 @@ void Application::performMainStartupAction() return; } } - if(!m_instanceIdToShowWindowOf.isEmpty()) - { + if (!m_instanceIdToShowWindowOf.isEmpty()) { auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf); - if(inst) - { + if (inst) { qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf; showInstanceWindow(inst); return; } } - if(!m_mainWindow) - { + if (!m_mainWindow) { // normal main window showMainWindow(false); qDebug() << "<> Main window shown."; } - if(!m_zipsToImport.isEmpty()) - { + if (!m_zipsToImport.isEmpty()) { qDebug() << "<> Importing from zip:" << m_zipsToImport; - m_mainWindow->processURLs( m_zipsToImport ); + m_mainWindow->processURLs(m_zipsToImport); } } @@ -1065,8 +1007,7 @@ Application::~Application() #if defined Q_OS_WIN32 // Detach from Windows console - if(consoleAttached) - { + if (consoleAttached) { fclose(stdout); fclose(stdin); fclose(stderr); @@ -1077,8 +1018,7 @@ Application::~Application() void Application::messageReceived(const QByteArray& message) { - if(status() != Initialized) - { + if (status() != Initialized) { qDebug() << "Received message" << message << "while still initializing. It will be ignored."; return; } @@ -1086,66 +1026,51 @@ void Application::messageReceived(const QByteArray& message) ApplicationMessage received; received.parse(message); - auto & command = received.command; + auto& command = received.command; - if(command == "activate") - { + if (command == "activate") { showMainWindow(); - } - else if(command == "import") - { + } else if (command == "import") { QString path = received.args["path"]; - if(path.isEmpty()) - { + if (path.isEmpty()) { qWarning() << "Received" << command << "message without a zip path/URL."; return; } m_mainWindow->processURLs({ QUrl::fromLocalFile(QFileInfo(path).absoluteFilePath()) }); - } - else if(command == "launch") - { + } else if (command == "launch") { QString id = received.args["id"]; QString server = received.args["server"]; QString profile = received.args["profile"]; InstancePtr instance; - if(!id.isEmpty()) { + if (!id.isEmpty()) { instance = instances()->getInstanceById(id); - if(!instance) { + if (!instance) { qWarning() << "Launch command requires an valid instance ID. " << id << "resolves to nothing."; return; } - } - else { + } else { qWarning() << "Launch command called without an instance ID..."; return; } MinecraftServerTargetPtr serverObject = nullptr; - if(!server.isEmpty()) { + if (!server.isEmpty()) { serverObject = std::make_shared(MinecraftServerTarget::parse(server)); } MinecraftAccountPtr accountObject; - if(!profile.isEmpty()) { + if (!profile.isEmpty()) { accountObject = accounts()->getAccountByProfileName(profile); - if(!accountObject) { - qWarning() << "Launch command requires the specified profile to be valid. " << profile << "does not resolve to any account."; + if (!accountObject) { + qWarning() << "Launch command requires the specified profile to be valid. " << profile + << "does not resolve to any account."; return; } } - launch( - instance, - true, - false, - nullptr, - serverObject, - accountObject - ); - } - else - { + launch(instance, true, false, nullptr, serverObject, accountObject); + } else { qWarning() << "Received invalid message" << message; } } @@ -1157,8 +1082,7 @@ std::shared_ptr Application::translations() std::shared_ptr Application::javalist() { - if (!m_javalist) - { + if (!m_javalist) { m_javalist.reset(new JavaInstallList()); } return m_javalist; @@ -1186,7 +1110,7 @@ void Application::setIconTheme(const QString& name) QIcon Application::getThemedIcon(const QString& name) { - if(name == "logo") { + if (name == "logo") { return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME); } return QIcon::fromTheme(name); @@ -1205,41 +1129,32 @@ QString Application::getCatPack(QString catName) bool Application::openJsonEditor(const QString& filename) { const QString file = QDir::current().absoluteFilePath(filename); - if (m_settings->get("JsonEditor").toString().isEmpty()) - { + if (m_settings->get("JsonEditor").toString().isEmpty()) { return DesktopServices::openUrl(QUrl::fromLocalFile(file)); - } - else - { - //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); - return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file}); + } else { + // return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); + return DesktopServices::run(m_settings->get("JsonEditor").toString(), { file }); } } -bool Application::launch( - InstancePtr instance, - bool online, - bool demo, - BaseProfilerFactory *profiler, - MinecraftServerTargetPtr serverToJoin, - MinecraftAccountPtr accountToUse -) { - if(m_updateRunning) - { +bool Application::launch(InstancePtr instance, + bool online, + bool demo, + BaseProfilerFactory* profiler, + MinecraftServerTargetPtr serverToJoin, + MinecraftAccountPtr accountToUse) +{ + if (m_updateRunning) { qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; - } - else if(instance->canLaunch()) - { - auto & extras = m_instanceExtras[instance->id()]; - auto & window = extras.window; - if(window) - { - if(!window->saveAll()) - { + } else if (instance->canLaunch()) { + auto& extras = m_instanceExtras[instance->id()]; + auto& window = extras.window; + if (window) { + if (!window->saveAll()) { return false; } } - auto & controller = extras.controller; + auto& controller = extras.controller; controller.reset(new LaunchController()); controller->setInstance(instance); controller->setOnline(online); @@ -1247,30 +1162,21 @@ bool Application::launch( controller->setProfiler(profiler); controller->setServerToJoin(serverToJoin); controller->setAccountToUse(accountToUse); - if(window) - { + if (window) { controller->setParentWidget(window); - } - else if(m_mainWindow) - { + } else if (m_mainWindow) { controller->setParentWidget(m_mainWindow); } connect(controller.get(), &LaunchController::succeeded, this, &Application::controllerSucceeded); connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed); - connect(controller.get(), &LaunchController::aborted, this, [this] { - controllerFailed(tr("Aborted")); - }); + connect(controller.get(), &LaunchController::aborted, this, [this] { controllerFailed(tr("Aborted")); }); addRunningInstance(); controller->start(); return true; - } - else if (instance->isRunning()) - { + } else if (instance->isRunning()) { showInstanceWindow(instance, "console"); return true; - } - else if (instance->canEdit()) - { + } else if (instance->canEdit()) { showInstanceWindow(instance); return true; } @@ -1279,16 +1185,14 @@ bool Application::launch( bool Application::kill(InstancePtr instance) { - if (!instance->isRunning()) - { + if (!instance->isRunning()) { qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; return false; } - auto & extras = m_instanceExtras[instance->id()]; + auto& extras = m_instanceExtras[instance->id()]; // NOTE: copy of the shared pointer keeps it alive auto controller = extras.controller; - if(controller) - { + if (controller) { return controller->abort(); } return true; @@ -1302,23 +1206,20 @@ void Application::closeCurrentWindow() void Application::addRunningInstance() { - m_runningInstances ++; - if(m_runningInstances == 1) - { + m_runningInstances++; + if (m_runningInstances == 1) { emit updateAllowedChanged(false); } } void Application::subRunningInstance() { - if(m_runningInstances == 0) - { + if (m_runningInstances == 0) { qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF"; return; } - m_runningInstances --; - if(m_runningInstances == 0) - { + m_runningInstances--; + if (m_runningInstances == 0) { emit updateAllowedChanged(true); } } @@ -1338,20 +1239,17 @@ void Application::updateIsRunning(bool running) m_updateRunning = running; } - void Application::controllerSucceeded() { - auto controller = qobject_cast(QObject::sender()); - if(!controller) + auto controller = qobject_cast(QObject::sender()); + if (!controller) return; auto id = controller->id(); - auto & extras = m_instanceExtras[id]; + auto& extras = m_instanceExtras[id]; // on success, do... - if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) - { - if(extras.window) - { + if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) { + if (extras.window) { extras.window->close(); } } @@ -1359,8 +1257,7 @@ void Application::controllerSucceeded() subRunningInstance(); // quit when there are no more windows. - if(shouldExitNow()) - { + if (shouldExitNow()) { m_status = Status::Succeeded; exit(0); } @@ -1369,19 +1266,18 @@ void Application::controllerSucceeded() void Application::controllerFailed(const QString& error) { Q_UNUSED(error); - auto controller = qobject_cast(QObject::sender()); - if(!controller) + auto controller = qobject_cast(QObject::sender()); + if (!controller) return; auto id = controller->id(); - auto & extras = m_instanceExtras[id]; + auto& extras = m_instanceExtras[id]; // on failure, do... nothing extras.controller.reset(); subRunningInstance(); // quit when there are no more windows. - if(shouldExitNow()) - { + if (shouldExitNow()) { m_status = Status::Failed; exit(1); } @@ -1389,7 +1285,7 @@ void Application::controllerFailed(const QString& error) void Application::ShowGlobalSettings(class QWidget* parent, QString open_page) { - if(!m_globalSettingsProvider) { + if (!m_globalSettingsProvider) { return; } emit globalSettingsAboutToOpen(); @@ -1403,24 +1299,18 @@ void Application::ShowGlobalSettings(class QWidget* parent, QString open_page) MainWindow* Application::showMainWindow(bool minimized) { - if(m_mainWindow) - { + if (m_mainWindow) { m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized); m_mainWindow->raise(); m_mainWindow->activateWindow(); - } - else - { + } else { m_mainWindow = new MainWindow(); m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); - if(minimized) - { + if (minimized) { m_mainWindow->showMinimized(); - } - else - { + } else { m_mainWindow->show(); } @@ -1432,31 +1322,26 @@ MainWindow* Application::showMainWindow(bool minimized) return m_mainWindow; } -InstanceWindow *Application::showInstanceWindow(InstancePtr instance, QString page) +InstanceWindow* Application::showInstanceWindow(InstancePtr instance, QString page) { - if(!instance) + if (!instance) return nullptr; auto id = instance->id(); - auto & extras = m_instanceExtras[id]; - auto & window = extras.window; + auto& extras = m_instanceExtras[id]; + auto& window = extras.window; - if(window) - { + if (window) { window->raise(); window->activateWindow(); - } - else - { + } else { window = new InstanceWindow(instance); - m_openWindows ++; + m_openWindows++; connect(window, &InstanceWindow::isClosing, this, &Application::on_windowClose); } - if(!page.isEmpty()) - { + if (!page.isEmpty()) { window->selectPage(page); } - if(extras.controller) - { + if (extras.controller) { extras.controller->setParentWidget(window); } return window; @@ -1465,24 +1350,20 @@ InstanceWindow *Application::showInstanceWindow(InstancePtr instance, QString pa void Application::on_windowClose() { m_openWindows--; - auto instWindow = qobject_cast(QObject::sender()); - if(instWindow) - { - auto & extras = m_instanceExtras[instWindow->instanceId()]; + auto instWindow = qobject_cast(QObject::sender()); + if (instWindow) { + auto& extras = m_instanceExtras[instWindow->instanceId()]; extras.window = nullptr; - if(extras.controller) - { + if (extras.controller) { extras.controller->setParentWidget(m_mainWindow); } } - auto mainWindow = qobject_cast(QObject::sender()); - if(mainWindow) - { + auto mainWindow = qobject_cast(QObject::sender()); + if (mainWindow) { m_mainWindow = nullptr; } // quit when there are no more windows. - if(shouldExitNow()) - { + if (shouldExitNow()) { exit(0); } } @@ -1490,23 +1371,14 @@ void Application::on_windowClose() void Application::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password) { // Set the application proxy settings. - if (proxyTypeStr == "SOCKS5") - { - QNetworkProxy::setApplicationProxy( - QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password)); - } - else if (proxyTypeStr == "HTTP") - { - QNetworkProxy::setApplicationProxy( - QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password)); - } - else if (proxyTypeStr == "None") - { + if (proxyTypeStr == "SOCKS5") { + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password)); + } else if (proxyTypeStr == "HTTP") { + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password)); + } else if (proxyTypeStr == "None") { // If we have no proxy set, set no proxy and return. QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); - } - else - { + } else { // If we have "Default" selected, set Qt to use the system proxy settings. QNetworkProxyFactory::setUseSystemConfiguration(true); } @@ -1516,39 +1388,35 @@ void Application::updateProxySettings(QString proxyTypeStr, QString addr, int po m_network->setProxy(proxy); QString proxyDesc; - if (proxy.type() == QNetworkProxy::NoProxy) - { + if (proxy.type() == QNetworkProxy::NoProxy) { qDebug() << "Using no proxy is an option!"; return; } - switch (proxy.type()) - { - case QNetworkProxy::DefaultProxy: - proxyDesc = "Default proxy: "; - break; - case QNetworkProxy::Socks5Proxy: - proxyDesc = "Socks5 proxy: "; - break; - case QNetworkProxy::HttpProxy: - proxyDesc = "HTTP proxy: "; - break; - case QNetworkProxy::HttpCachingProxy: - proxyDesc = "HTTP caching: "; - break; - case QNetworkProxy::FtpCachingProxy: - proxyDesc = "FTP caching: "; - break; - default: - proxyDesc = "DERP proxy: "; - break; + switch (proxy.type()) { + case QNetworkProxy::DefaultProxy: + proxyDesc = "Default proxy: "; + break; + case QNetworkProxy::Socks5Proxy: + proxyDesc = "Socks5 proxy: "; + break; + case QNetworkProxy::HttpProxy: + proxyDesc = "HTTP proxy: "; + break; + case QNetworkProxy::HttpCachingProxy: + proxyDesc = "HTTP caching: "; + break; + case QNetworkProxy::FtpCachingProxy: + proxyDesc = "FTP caching: "; + break; + default: + proxyDesc = "DERP proxy: "; + break; } - proxyDesc += QString("%1:%2") - .arg(proxy.hostName()) - .arg(proxy.port()); + proxyDesc += QString("%1:%2").arg(proxy.hostName()).arg(proxy.port()); qDebug() << proxyDesc; } -shared_qobject_ptr< HttpMetaCache > Application::metacache() +shared_qobject_ptr Application::metacache() { return m_metacache; } @@ -1560,8 +1428,7 @@ shared_qobject_ptr Application::network() shared_qobject_ptr Application::metadataIndex() { - if (!m_metadataIndex) - { + if (!m_metadataIndex) { m_metadataIndex.reset(new Meta::Index()); } return m_metadataIndex; @@ -1592,10 +1459,9 @@ QString Application::getJarPath(QString jarFile) #endif FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"), - FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging + FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging }; - for(QString p : potentialPaths) - { + for (QString p : potentialPaths) { QString jarPath = FS::PathCombine(p, jarFile); if (QFileInfo(jarPath).isFile()) return jarPath; @@ -1660,7 +1526,7 @@ int Application::suitableMaxMem() // If totalRAM < 6GB, use (totalRAM / 1.5), else 4GB if (totalRAM < (4096 * 1.5)) - maxMemoryAlloc = (int) (totalRAM / 1.5); + maxMemoryAlloc = (int)(totalRAM / 1.5); else maxMemoryAlloc = 4096; diff --git a/launcher/Application.h b/launcher/Application.h index c0a980b2e..cf7967a56 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -38,12 +38,12 @@ #pragma once #include -#include +#include #include #include #include -#include #include +#include #include @@ -73,25 +73,19 @@ class MCEditTool; class ThemeManager; namespace Meta { - class Index; +class Index; } #if defined(APPLICATION) #undef APPLICATION #endif -#define APPLICATION (static_cast(QCoreApplication::instance())) +#define APPLICATION (static_cast(QCoreApplication::instance())) -class Application : public QApplication -{ +class Application : public QApplication { // friends for the purpose of limiting access to deprecated stuff Q_OBJECT -public: - enum Status { - StartingUp, - Failed, - Succeeded, - Initialized - }; + public: + enum Status { StartingUp, Failed, Succeeded, Initialized }; enum Capability { None = 0, @@ -103,19 +97,15 @@ public: }; Q_DECLARE_FLAGS(Capabilities, Capability) -public: - Application(int &argc, char **argv); + public: + Application(int& argc, char** argv); virtual ~Application(); bool event(QEvent* event) override; - std::shared_ptr settings() const { - return m_settings; - } + std::shared_ptr settings() const { return m_settings; } - qint64 timeSinceStart() const { - return startTime.msecsTo(QDateTime::currentDateTime()); - } + qint64 timeSinceStart() const { return startTime.msecsTo(QDateTime::currentDateTime()); } QIcon getThemedIcon(const QString& name); @@ -139,29 +129,17 @@ public: std::shared_ptr javalist(); - std::shared_ptr instances() const { - return m_instances; - } + std::shared_ptr instances() const { return m_instances; } - std::shared_ptr icons() const { - return m_icons; - } + std::shared_ptr icons() const { return m_icons; } - MCEditTool *mcedit() const { - return m_mcedit.get(); - } + MCEditTool* mcedit() const { return m_mcedit.get(); } - shared_qobject_ptr accounts() const { - return m_accounts; - } + shared_qobject_ptr accounts() const { return m_accounts; } - Status status() const { - return m_status; - } + Status status() const { return m_status; } - const QMap> &profilers() const { - return m_profilers; - } + const QMap>& profilers() const { return m_profilers; } void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password); @@ -186,35 +164,29 @@ public: QString getUserAgentUncached(); /// this is the root of the 'installation'. Used for automatic updates - const QString &root() { - return m_rootPath; - } + const QString& root() { return m_rootPath; } - bool isPortable() { - return m_portable; - } + bool isPortable() { return m_portable; } - const Capabilities capabilities() { - return m_capabilities; - } + const Capabilities capabilities() { return m_capabilities; } /*! * Opens a json file using either a system default editor, or, if not empty, the editor * specified in the settings */ - bool openJsonEditor(const QString &filename); + bool openJsonEditor(const QString& filename); - InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString()); - MainWindow *showMainWindow(bool minimized = false); + InstanceWindow* showInstanceWindow(InstancePtr instance, QString page = QString()); + MainWindow* showMainWindow(bool minimized = false); void updateIsRunning(bool running); bool updatesAreAllowed(); - void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); + void ShowGlobalSettings(class QWidget* parent, QString open_page = QString()); int suitableMaxMem(); -signals: + signals: void updateAllowedChanged(bool status); void globalSettingsAboutToOpen(); void globalSettingsClosed(); @@ -224,39 +196,37 @@ signals: void clickedOnDock(); #endif -public slots: - bool launch( - InstancePtr instance, - bool online = true, - bool demo = false, - BaseProfilerFactory *profiler = nullptr, - MinecraftServerTargetPtr serverToJoin = nullptr, - MinecraftAccountPtr accountToUse = nullptr - ); + public slots: + bool launch(InstancePtr instance, + bool online = true, + bool demo = false, + BaseProfilerFactory* profiler = nullptr, + MinecraftServerTargetPtr serverToJoin = nullptr, + MinecraftAccountPtr accountToUse = nullptr); bool kill(InstancePtr instance); void closeCurrentWindow(); -private slots: + private slots: void on_windowClose(); - void messageReceived(const QByteArray & message); + void messageReceived(const QByteArray& message); void controllerSucceeded(); - void controllerFailed(const QString & error); + void controllerFailed(const QString& error); void setupWizardFinished(int status); -private: - bool handleDataMigration(const QString & currentData, const QString & oldData, const QString & name, const QString & configFile) const; + private: + bool handleDataMigration(const QString& currentData, const QString& oldData, const QString& name, const QString& configFile) const; bool createSetupWizard(); void performMainStartupAction(); // sets the fatal error message and m_status to Failed. - void showFatalErrorMessage(const QString & title, const QString & content); + void showFatalErrorMessage(const QString& title, const QString& content); -private: + private: void addRunningInstance(); void subRunningInstance(); bool shouldExitNow() const; -private: + private: QDateTime startTime; shared_qobject_ptr m_network; @@ -282,7 +252,7 @@ private: QString m_rootPath; Status m_status = Application::StartingUp; Capabilities m_capabilities; - bool m_portable = false; + bool m_portable = false; #ifdef Q_OS_MACOS Qt::ApplicationState m_prevAppState = Qt::ApplicationInactive; @@ -295,7 +265,7 @@ private: // FIXME: attach to instances instead. struct InstanceXtras { - InstanceWindow * window = nullptr; + InstanceWindow* window = nullptr; shared_qobject_ptr controller; }; std::map m_instanceExtras; @@ -306,13 +276,14 @@ private: bool m_updateRunning = false; // main window, if any - MainWindow * m_mainWindow = nullptr; + MainWindow* m_mainWindow = nullptr; // peer launcher instance connector - used to implement single instance launcher and signalling - LocalPeer * m_peerInstance = nullptr; + LocalPeer* m_peerInstance = nullptr; - SetupWizard * m_setupWizard = nullptr; -public: + SetupWizard* m_setupWizard = nullptr; + + public: QString m_instanceIdToLaunch; QString m_serverToJoin; QString m_profileToUse; diff --git a/launcher/ApplicationMessage.cpp b/launcher/ApplicationMessage.cpp index 700e43ced..8d75ecc8f 100644 --- a/launcher/ApplicationMessage.cpp +++ b/launcher/ApplicationMessage.cpp @@ -39,7 +39,8 @@ #include #include "Json.h" -void ApplicationMessage::parse(const QByteArray & input) { +void ApplicationMessage::parse(const QByteArray& input) +{ auto doc = Json::requireDocument(input, "ApplicationMessage"); auto root = Json::requireObject(doc, "ApplicationMessage"); @@ -47,12 +48,13 @@ void ApplicationMessage::parse(const QByteArray & input) { args.clear(); auto parsedArgs = root.value("args").toObject(); - for(auto iter = parsedArgs.constBegin(); iter != parsedArgs.constEnd(); iter++) { + for (auto iter = parsedArgs.constBegin(); iter != parsedArgs.constEnd(); iter++) { args.insert(iter.key(), iter.value().toString()); } } -QByteArray ApplicationMessage::serialize() { +QByteArray ApplicationMessage::serialize() +{ QJsonObject root; root.insert("command", command); QJsonObject outArgs; diff --git a/launcher/ApplicationMessage.h b/launcher/ApplicationMessage.h index d66456ebd..7ad674330 100644 --- a/launcher/ApplicationMessage.h +++ b/launcher/ApplicationMessage.h @@ -1,13 +1,13 @@ #pragma once -#include -#include #include +#include +#include struct ApplicationMessage { QString command; QHash args; QByteArray serialize(); - void parse(const QByteArray & input); + void parse(const QByteArray& input); }; diff --git a/launcher/BaseInstaller.cpp b/launcher/BaseInstaller.cpp index d61c3fe90..1ff86ed40 100644 --- a/launcher/BaseInstaller.cpp +++ b/launcher/BaseInstaller.cpp @@ -18,27 +18,21 @@ #include "BaseInstaller.h" #include "minecraft/MinecraftInstance.h" -BaseInstaller::BaseInstaller() -{ +BaseInstaller::BaseInstaller() {} -} - -bool BaseInstaller::isApplied(MinecraftInstance *on) +bool BaseInstaller::isApplied(MinecraftInstance* on) { return QFile::exists(filename(on->instanceRoot())); } -bool BaseInstaller::add(MinecraftInstance *to) +bool BaseInstaller::add(MinecraftInstance* to) { - if (!patchesDir(to->instanceRoot()).exists()) - { + if (!patchesDir(to->instanceRoot()).exists()) { QDir(to->instanceRoot()).mkdir("patches"); } - if (isApplied(to)) - { - if (!remove(to)) - { + if (isApplied(to)) { + if (!remove(to)) { return false; } } @@ -46,16 +40,16 @@ bool BaseInstaller::add(MinecraftInstance *to) return true; } -bool BaseInstaller::remove(MinecraftInstance *from) +bool BaseInstaller::remove(MinecraftInstance* from) { return QFile::remove(filename(from->instanceRoot())); } -QString BaseInstaller::filename(const QString &root) const +QString BaseInstaller::filename(const QString& root) const { return patchesDir(root).absoluteFilePath(id() + ".json"); } -QDir BaseInstaller::patchesDir(const QString &root) const +QDir BaseInstaller::patchesDir(const QString& root) const { return QDir(root + "/patches/"); } diff --git a/launcher/BaseInstaller.h b/launcher/BaseInstaller.h index a1b80e93f..6244ced7d 100644 --- a/launcher/BaseInstaller.h +++ b/launcher/BaseInstaller.h @@ -26,20 +26,19 @@ class QObject; class Task; class BaseVersion; -class BaseInstaller -{ -public: +class BaseInstaller { + public: BaseInstaller(); virtual ~BaseInstaller(){}; - bool isApplied(MinecraftInstance *on); + bool isApplied(MinecraftInstance* on); - virtual bool add(MinecraftInstance *to); - virtual bool remove(MinecraftInstance *from); + virtual bool add(MinecraftInstance* to); + virtual bool remove(MinecraftInstance* from); - virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersion::Ptr version, QObject *parent) = 0; + virtual Task* createInstallTask(MinecraftInstance* instance, BaseVersion::Ptr version, QObject* parent) = 0; -protected: + protected: virtual QString id() const = 0; - QString filename(const QString &root) const; - QDir patchesDir(const QString &root) const; + QString filename(const QString& root) const; + QDir patchesDir(const QString& root) const; }; diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index a8fce879c..67fc150a4 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -36,23 +36,22 @@ #include "BaseInstance.h" -#include -#include #include -#include +#include +#include #include #include +#include #include "settings/INISettingsObject.h" -#include "settings/Setting.h" #include "settings/OverrideSetting.h" +#include "settings/Setting.h" -#include "FileSystem.h" -#include "Commandline.h" #include "BuildConfig.h" +#include "Commandline.h" +#include "FileSystem.h" -BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) - : QObject() +BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) : QObject() { m_settings = settings; m_global_settings = globalSettings; @@ -79,7 +78,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("InstanceType", ""); // Custom Commands - auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); + auto commandSetting = m_settings->registerSetting({ "OverrideCommands", "OverrideLaunchCmd" }, false); m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand"), commandSetting); m_settings->registerOverride(globalSettings->getSetting("WrapperCommand"), commandSetting); m_settings->registerOverride(globalSettings->getSetting("PostExitCommand"), commandSetting); @@ -148,7 +147,11 @@ QString BaseInstance::getManagedPackVersionName() const return m_settings->get("ManagedPackVersionName").toString(); } -void BaseInstance::setManagedPack(const QString& type, const QString& id, const QString& name, const QString& versionId, const QString& version) +void BaseInstance::setManagedPack(const QString& type, + const QString& id, + const QString& name, + const QString& versionId, + const QString& version) { m_settings->set("ManagedPack", true); m_settings->set("ManagedPackType", type); @@ -173,8 +176,7 @@ int BaseInstance::getConsoleMaxLines() const auto lineSetting = m_settings->getSetting("ConsoleMaxLines"); bool conversionOk = false; int maxLines = lineSetting->get().toInt(&conversionOk); - if(!conversionOk) - { + if (!conversionOk) { maxLines = lineSetting->defValue().toInt(); qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines; } @@ -220,8 +222,7 @@ bool BaseInstance::isLinkedToInstanceId(const QString& id) const void BaseInstance::iconUpdated(QString key) { - if(iconKey() == key) - { + if (iconKey() == key) { emit propertiesChanged(this); } } @@ -235,8 +236,7 @@ void BaseInstance::invalidate() void BaseInstance::changeStatus(BaseInstance::Status newStatus) { Status status = currentStatus(); - if(status != newStatus) - { + if (status != newStatus) { m_status = newStatus; emit statusChanged(status, newStatus); } @@ -259,23 +259,19 @@ bool BaseInstance::isRunning() const void BaseInstance::setRunning(bool running) { - if(running == m_isRunning) + if (running == m_isRunning) return; m_isRunning = running; - if(!m_settings->get("RecordGameTime").toBool()) - { + if (!m_settings->get("RecordGameTime").toBool()) { emit runningStatusChanged(running); return; } - if(running) - { + if (running) { m_timeStarted = QDateTime::currentDateTime(); - } - else - { + } else { QDateTime timeEnded = QDateTime::currentDateTime(); qint64 current = settings()->get("totalTimePlayed").toLongLong(); @@ -291,8 +287,7 @@ void BaseInstance::setRunning(bool running) int64_t BaseInstance::totalTimePlayed() const { qint64 current = m_settings->get("totalTimePlayed").toLongLong(); - if(m_isRunning) - { + if (m_isRunning) { QDateTime timeNow = QDateTime::currentDateTime(); return current + m_timeStarted.secsTo(timeNow); } @@ -301,8 +296,7 @@ int64_t BaseInstance::totalTimePlayed() const int64_t BaseInstance::lastTimePlayed() const { - if(m_isRunning) - { + if (m_isRunning) { QDateTime timeNow = QDateTime::currentDateTime(); return m_timeStarted.secsTo(timeNow); } @@ -349,14 +343,14 @@ qint64 BaseInstance::lastLaunch() const void BaseInstance::setLastLaunch(qint64 val) { - //FIXME: if no change, do not set. setting involves saving a file. + // FIXME: if no change, do not set. setting involves saving a file. m_settings->set("lastLaunchTime", val); emit propertiesChanged(this); } void BaseInstance::setNotes(QString val) { - //FIXME: if no change, do not set. setting involves saving a file. + // FIXME: if no change, do not set. setting involves saving a file. m_settings->set("notes", val); } @@ -367,7 +361,7 @@ QString BaseInstance::notes() const void BaseInstance::setIconKey(QString val) { - //FIXME: if no change, do not set. setting involves saving a file. + // FIXME: if no change, do not set. setting involves saving a file. m_settings->set("iconKey", val); emit propertiesChanged(this); } @@ -379,7 +373,7 @@ QString BaseInstance::iconKey() const void BaseInstance::setName(QString val) { - //FIXME: if no change, do not set. setting involves saving a file. + // FIXME: if no change, do not set. setting involves saving a file. m_settings->set("name", val); emit propertiesChanged(this); } diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 83a8064fa..f0686942d 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -37,24 +37,24 @@ #pragma once #include -#include -#include "QObjectPtr.h" #include -#include +#include #include +#include +#include "QObjectPtr.h" #include "settings/SettingsObject.h" -#include "settings/INIFile.h" #include "BaseVersionList.h" -#include "minecraft/auth/MinecraftAccount.h" #include "MessageLevel.h" +#include "minecraft/auth/MinecraftAccount.h" #include "pathmatcher/IPathMatcher.h" +#include "settings/INIFile.h" #include "net/Mode.h" -#include "minecraft/launch/MinecraftServerTarget.h" #include "RuntimeContext.h" +#include "minecraft/launch/MinecraftServerTarget.h" class QDir; class Task; @@ -72,23 +72,21 @@ typedef std::shared_ptr InstancePtr; * To create a new instance type, create a new class inheriting from this class * and implement the pure virtual functions. */ -class BaseInstance : public QObject, public std::enable_shared_from_this -{ +class BaseInstance : public QObject, public std::enable_shared_from_this { Q_OBJECT -protected: + protected: /// no-touchy! - BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir); + BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir); -public: /* types */ - enum class Status - { + public: /* types */ + enum class Status { Present, - Gone // either nuked or invalidated + Gone // either nuked or invalidated }; -public: + public: /// virtual destructor to make sure the destruction is COMPLETE - virtual ~BaseInstance() {}; + virtual ~BaseInstance(){}; virtual void saveNow() = 0; @@ -117,10 +115,7 @@ public: QString instanceRoot() const; /// Path to the instance's game root directory. - virtual QString gameRoot() const - { - return instanceRoot(); - } + virtual QString gameRoot() const { return instanceRoot(); } /// Path to the instance's mods directory. virtual QString modsRoot() const = 0; @@ -151,15 +146,12 @@ public: void copyManagedPack(BaseInstance& other); /// guess log level from a line of game log - virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString &line, MessageLevel::Enum level) - { - return level; - }; + virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString& line, MessageLevel::Enum level) { return level; }; virtual QStringList extraArguments(); /// Traits. Normally inside the version, depends on instance implementation. - virtual QSet traits() const = 0; + virtual QSet traits() const = 0; /** * Gets the time that the instance was last launched. @@ -189,8 +181,7 @@ public: virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0; /// returns a valid launcher (task container) - virtual shared_qobject_ptr createLaunchTask( - AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0; + virtual shared_qobject_ptr createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0; /// returns the current launch task (if any) shared_qobject_ptr getLaunchTask(); @@ -222,45 +213,30 @@ public: virtual QString typeName() const = 0; void updateRuntimeContext(); - RuntimeContext runtimeContext() const - { - return m_runtimeContext; - } + RuntimeContext runtimeContext() const { return m_runtimeContext; } - bool hasVersionBroken() const - { - return m_hasBrokenVersion; - } + bool hasVersionBroken() const { return m_hasBrokenVersion; } void setVersionBroken(bool value) { - if(m_hasBrokenVersion != value) - { + if (m_hasBrokenVersion != value) { m_hasBrokenVersion = value; emit propertiesChanged(this); } } - bool hasUpdateAvailable() const - { - return m_hasUpdate; - } + bool hasUpdateAvailable() const { return m_hasUpdate; } void setUpdateAvailable(bool value) { - if(m_hasUpdate != value) - { + if (m_hasUpdate != value) { m_hasUpdate = value; emit propertiesChanged(this); } } - bool hasCrashed() const - { - return m_crashed; - } + bool hasCrashed() const { return m_crashed; } void setCrashed(bool value) { - if(m_crashed != value) - { + if (m_crashed != value) { m_crashed = value; emit propertiesChanged(this); } @@ -288,7 +264,7 @@ public: bool removeLinkedInstanceId(const QString& id); bool isLinkedToInstanceId(const QString& id) const; -protected: + protected: void changeStatus(Status newStatus); SettingsObjectPtr globalSettings() const { return m_global_settings.lock(); }; @@ -296,11 +272,11 @@ protected: bool isSpecificSettingsLoaded() const { return m_specific_settings_loaded; } void setSpecificSettingsLoaded(bool loaded) { m_specific_settings_loaded = loaded; } -signals: + signals: /*! * \brief Signal emitted when properties relevant to the instance view change */ - void propertiesChanged(BaseInstance *inst); + void propertiesChanged(BaseInstance* inst); void launchTaskChanged(shared_qobject_ptr); @@ -308,10 +284,10 @@ signals: void statusChanged(Status from, Status to); -protected slots: + protected slots: void iconUpdated(QString key); -protected: /* data */ + protected: /* data */ QString m_rootDir; SettingsObjectPtr m_settings; // InstanceFlags m_flags; @@ -320,7 +296,7 @@ protected: /* data */ QDateTime m_timeStarted; RuntimeContext m_runtimeContext; -private: /* data */ + private: /* data */ Status m_status = Status::Present; bool m_crashed = false; bool m_hasUpdate = false; @@ -328,9 +304,8 @@ private: /* data */ SettingsObjectWeakPtr m_global_settings; bool m_specific_settings_loaded = false; - }; Q_DECLARE_METATYPE(shared_qobject_ptr) -//Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) -//Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) +// Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) +// Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index dc95e7ea5..d817926ef 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -36,14 +36,11 @@ #include "BaseVersionList.h" #include "BaseVersion.h" -BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent) -{ -} +BaseVersionList::BaseVersionList(QObject* parent) : QAbstractListModel(parent) {} -BaseVersion::Ptr BaseVersionList::findVersion(const QString &descriptor) +BaseVersion::Ptr BaseVersionList::findVersion(const QString& descriptor) { - for (int i = 0; i < count(); i++) - { + for (int i = 0; i < count(); i++) { if (at(i)->descriptor() == descriptor) return at(i); } @@ -58,7 +55,7 @@ BaseVersion::Ptr BaseVersionList::getRecommended() const return at(0); } -QVariant BaseVersionList::data(const QModelIndex &index, int role) const +QVariant BaseVersionList::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -68,37 +65,36 @@ QVariant BaseVersionList::data(const QModelIndex &index, int role) const BaseVersion::Ptr version = at(index.row()); - switch (role) - { - case VersionPointerRole: - return QVariant::fromValue(version); + switch (role) { + case VersionPointerRole: + return QVariant::fromValue(version); - case VersionRole: - return version->name(); + case VersionRole: + return version->name(); - case VersionIdRole: - return version->descriptor(); + case VersionIdRole: + return version->descriptor(); - case TypeRole: - return version->typeString(); + case TypeRole: + return version->typeString(); - default: - return QVariant(); + default: + return QVariant(); } } BaseVersionList::RoleList BaseVersionList::providesRoles() const { - return {VersionPointerRole, VersionRole, VersionIdRole, TypeRole}; + return { VersionPointerRole, VersionRole, VersionIdRole, TypeRole }; } -int BaseVersionList::rowCount(const QModelIndex &parent) const +int BaseVersionList::rowCount(const QModelIndex& parent) const { // Return count return parent.isValid() ? 0 : count(); } -int BaseVersionList::columnCount(const QModelIndex &parent) const +int BaseVersionList::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : 1; } diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index 31f29022a..fe1550c21 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -15,13 +15,13 @@ #pragma once +#include #include #include -#include #include "BaseVersion.h" -#include "tasks/Task.h" #include "QObjectPtr.h" +#include "tasks/Task.h" /*! * \brief Class that each instance type's version list derives from. @@ -35,12 +35,10 @@ * all have a default implementation, but they can be overridden by plugins to * change the behavior of the list. */ -class BaseVersionList : public QAbstractListModel -{ +class BaseVersionList : public QAbstractListModel { Q_OBJECT -public: - enum ModelRoles - { + public: + enum ModelRoles { VersionPointerRole = Qt::UserRole, VersionRole, VersionIdRole, @@ -55,7 +53,7 @@ public: }; typedef QList RoleList; - explicit BaseVersionList(QObject *parent = 0); + explicit BaseVersionList(QObject* parent = 0); /*! * \brief Gets a task that will reload the version list. @@ -66,7 +64,7 @@ public: virtual Task::Ptr getLoadTask() = 0; //! Checks whether or not the list is loaded. If this returns false, the list should be - //loaded. + // loaded. virtual bool isLoaded() = 0; //! Gets the version at the given index. @@ -76,9 +74,9 @@ public: virtual int count() const = 0; //////// List Model Functions //////// - QVariant data(const QModelIndex &index, int role) const override; - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex& index, int role) const override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; QHash roleNames() const override; //! which roles are provided by this version list? @@ -90,7 +88,7 @@ public: * \return A const pointer to the version with the given descriptor. NULL if * one doesn't exist. */ - virtual BaseVersion::Ptr findVersion(const QString &descriptor); + virtual BaseVersion::Ptr findVersion(const QString& descriptor); /*! * \brief Gets the recommended version from this list @@ -103,8 +101,7 @@ public: */ virtual void sortVersions() = 0; -protected -slots: + protected slots: /*! * Updates this list with the given list of versions. * This is done by copying each version in the given list and inserting it diff --git a/launcher/Commandline.cpp b/launcher/Commandline.cpp index 6d97918de..4fac024ac 100644 --- a/launcher/Commandline.cpp +++ b/launcher/Commandline.cpp @@ -41,8 +41,7 @@ * @file libutil/src/cmdutils.cpp */ -namespace Commandline -{ +namespace Commandline { // commandline splitter QStringList splitArgs(QString args) @@ -51,19 +50,15 @@ QStringList splitArgs(QString args) QString current; bool escape = false; QChar inquotes; - for (int i = 0; i < args.length(); i++) - { + for (int i = 0; i < args.length(); i++) { QChar cchar = args.at(i); // \ escaped - if (escape) - { + if (escape) { current += cchar; escape = false; // in "quotes" - } - else if (!inquotes.isNull()) - { + } else if (!inquotes.isNull()) { if (cchar == '\\') escape = true; else if (cchar == inquotes) @@ -71,18 +66,13 @@ QStringList splitArgs(QString args) else current += cchar; // otherwise - } - else - { - if (cchar == ' ') - { - if (!current.isEmpty()) - { + } else { + if (cchar == ' ') { + if (!current.isEmpty()) { argv << current; current.clear(); } - } - else if (cchar == '"' || cchar == '\'') + } else if (cchar == '"' || cchar == '\'') inquotes = cchar; else current += cchar; @@ -92,4 +82,4 @@ QStringList splitArgs(QString args) argv << current; return argv; } -} +} // namespace Commandline diff --git a/launcher/Commandline.h b/launcher/Commandline.h index 8bd791808..77c557de2 100644 --- a/launcher/Commandline.h +++ b/launcher/Commandline.h @@ -25,8 +25,7 @@ * @brief commandline parsing and processing utilities */ -namespace Commandline -{ +namespace Commandline { /** * @brief split a string into argv items like a shell would do @@ -34,4 +33,4 @@ namespace Commandline * @return a QStringList containing all arguments */ QStringList splitArgs(QString args); -} +} // namespace Commandline diff --git a/launcher/DefaultVariable.h b/launcher/DefaultVariable.h index 5c069bd38..b082091c7 100644 --- a/launcher/DefaultVariable.h +++ b/launcher/DefaultVariable.h @@ -1,33 +1,21 @@ #pragma once template -class DefaultVariable -{ -public: - DefaultVariable(const T & value) - { - defaultValue = value; - } - DefaultVariable & operator =(const T & value) +class DefaultVariable { + public: + DefaultVariable(const T& value) { defaultValue = value; } + DefaultVariable& operator=(const T& value) { currentValue = value; is_default = currentValue == defaultValue; is_explicit = true; return *this; } - operator const T &() const - { - return is_default ? defaultValue : currentValue; - } - bool isDefault() const - { - return is_default; - } - bool isExplicit() const - { - return is_explicit; - } -private: + operator const T&() const { return is_default ? defaultValue : currentValue; } + bool isDefault() const { return is_default; } + bool isExplicit() const { return is_explicit; } + + private: T currentValue; T defaultValue; bool is_default = true; diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp index 81362f099..d7d2833e9 100644 --- a/launcher/DesktopServices.cpp +++ b/launcher/DesktopServices.cpp @@ -33,40 +33,37 @@ * limitations under the License. */ #include "DesktopServices.h" -#include -#include -#include #include +#include +#include +#include /** * This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing. */ #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) -#include #include #include #include +#include template -bool IndirectOpen(T callable, qint64 *pid_forked = nullptr) +bool IndirectOpen(T callable, qint64* pid_forked = nullptr) { auto pid = fork(); - if(pid_forked) - { - if(pid > 0) + if (pid_forked) { + if (pid > 0) *pid_forked = pid; else *pid_forked = 0; } - if(pid == -1) - { + if (pid == -1) { qWarning() << "IndirectOpen failed to fork: " << errno; return false; } // child - do the stuff - if(pid == 0) - { + if (pid == 0) { // unset all this garbage so it doesn't get passed to the child process qunsetenv("LD_PRELOAD"); qunsetenv("LD_LIBRARY_PATH"); @@ -82,19 +79,14 @@ bool IndirectOpen(T callable, qint64 *pid_forked = nullptr) // die. now. do not clean up anything, it would just hang forever. _exit(status ? 0 : 1); - } - else - { - //parent - assume it worked. + } else { + // parent - assume it worked. int status; - while (waitpid(pid, &status, 0)) - { - if(WIFEXITED(status)) - { + while (waitpid(pid, &status, 0)) { + if (WIFEXITED(status)) { return WEXITSTATUS(status) == 0; } - if(WIFSIGNALED(status)) - { + if (WIFSIGNALED(status)) { return false; } } @@ -104,26 +96,19 @@ bool IndirectOpen(T callable, qint64 *pid_forked = nullptr) #endif namespace DesktopServices { -bool openDirectory(const QString &path, bool ensureExists) +bool openDirectory(const QString& path, bool ensureExists) { qDebug() << "Opening directory" << path; QDir parentPath; QDir dir(path); - if (!dir.exists()) - { + if (!dir.exists()) { parentPath.mkpath(dir.absolutePath()); } - auto f = [&]() - { - return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); - }; + auto f = [&]() { return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isSandbox()) - { + if (!isSandbox()) { return IndirectOpen(f); - } - else - { + } else { return f(); } #else @@ -131,20 +116,14 @@ bool openDirectory(const QString &path, bool ensureExists) #endif } -bool openFile(const QString &path) +bool openFile(const QString& path) { qDebug() << "Opening file" << path; - auto f = [&]() - { - return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); - }; + auto f = [&]() { return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isSandbox()) - { + if (!isSandbox()) { return IndirectOpen(f); - } - else - { + } else { return f(); } #else @@ -152,41 +131,29 @@ bool openFile(const QString &path) #endif } -bool openFile(const QString &application, const QString &path, const QString &workingDirectory, qint64 *pid) +bool openFile(const QString& application, const QString& path, const QString& workingDirectory, qint64* pid) { qDebug() << "Opening file" << path << "using" << application; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave - if(!isSandbox()) - { - return IndirectOpen([&]() - { - return QProcess::startDetached(application, QStringList() << path, workingDirectory); - }, pid); - } - else - { - return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid); + if (!isSandbox()) { + return IndirectOpen([&]() { return QProcess::startDetached(application, QStringList() << path, workingDirectory); }, pid); + } else { + return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid); } #else return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid); #endif } -bool run(const QString &application, const QStringList &args, const QString &workingDirectory, qint64 *pid) +bool run(const QString& application, const QStringList& args, const QString& workingDirectory, qint64* pid) { qDebug() << "Running" << application << "with args" << args.join(' '); #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isSandbox()) - { - // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave - return IndirectOpen([&]() - { - return QProcess::startDetached(application, args, workingDirectory); - }, pid); - } - else - { + if (!isSandbox()) { + // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave + return IndirectOpen([&]() { return QProcess::startDetached(application, args, workingDirectory); }, pid); + } else { return QProcess::startDetached(application, args, workingDirectory, pid); } #else @@ -194,20 +161,14 @@ bool run(const QString &application, const QStringList &args, const QString &wor #endif } -bool openUrl(const QUrl &url) +bool openUrl(const QUrl& url) { qDebug() << "Opening URL" << url.toString(); - auto f = [&]() - { - return QDesktopServices::openUrl(url); - }; + auto f = [&]() { return QDesktopServices::openUrl(url); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!isSandbox()) - { + if (!isSandbox()) { return IndirectOpen(f); - } - else - { + } else { return f(); } #else @@ -238,4 +199,4 @@ bool isSandbox() return isSnap() || isFlatpak(); } -} +} // namespace DesktopServices diff --git a/launcher/DesktopServices.h b/launcher/DesktopServices.h index b1948cc2b..151db5557 100644 --- a/launcher/DesktopServices.h +++ b/launcher/DesktopServices.h @@ -1,51 +1,50 @@ #pragma once -#include #include +#include /** * This wraps around QDesktopServices and adds workarounds where needed * Use this instead of QDesktopServices! */ -namespace DesktopServices -{ - /** - * Open a file in whatever application is applicable - */ - bool openFile(const QString &path); +namespace DesktopServices { +/** + * Open a file in whatever application is applicable + */ +bool openFile(const QString& path); - /** - * Open a file in the specified application - */ - bool openFile(const QString &application, const QString &path, const QString & workingDirectory = QString(), qint64 *pid = 0); +/** + * Open a file in the specified application + */ +bool openFile(const QString& application, const QString& path, const QString& workingDirectory = QString(), qint64* pid = 0); - /** - * Run an application - */ - bool run(const QString &application,const QStringList &args, const QString & workingDirectory = QString(), qint64 *pid = 0); +/** + * Run an application + */ +bool run(const QString& application, const QStringList& args, const QString& workingDirectory = QString(), qint64* pid = 0); - /** - * Open a directory - */ - bool openDirectory(const QString &path, bool ensureExists = false); +/** + * Open a directory + */ +bool openDirectory(const QString& path, bool ensureExists = false); - /** - * Open the URL, most likely in a browser. Maybe. - */ - bool openUrl(const QUrl &url); +/** + * Open the URL, most likely in a browser. Maybe. + */ +bool openUrl(const QUrl& url); - /** - * Determine whether the launcher is running in a Flatpak environment - */ - bool isFlatpak(); +/** + * Determine whether the launcher is running in a Flatpak environment + */ +bool isFlatpak(); - /** - * Determine whether the launcher is running in a Snap environment - */ - bool isSnap(); +/** + * Determine whether the launcher is running in a Snap environment + */ +bool isSnap(); - /** - * Determine whether the launcher is running in a sandboxed (Flatpak or Snap) environment - */ - bool isSandbox(); -} +/** + * Determine whether the launcher is running in a sandboxed (Flatpak or Snap) environment + */ +bool isSandbox(); +} // namespace DesktopServices diff --git a/launcher/Exception.h b/launcher/Exception.h index fe0b86b5f..ef1e4e0d8 100644 --- a/launcher/Exception.h +++ b/launcher/Exception.h @@ -2,31 +2,18 @@ #pragma once -#include #include +#include #include -class Exception : public std::exception -{ -public: - Exception(const QString &message) : std::exception(), m_message(message) - { - qCritical() << "Exception:" << message; - } - Exception(const Exception &other) - : std::exception(), m_message(other.cause()) - { - } +class Exception : public std::exception { + public: + Exception(const QString& message) : std::exception(), m_message(message) { qCritical() << "Exception:" << message; } + Exception(const Exception& other) : std::exception(), m_message(other.cause()) {} virtual ~Exception() noexcept {} - const char *what() const noexcept - { - return m_message.toLatin1().constData(); - } - QString cause() const - { - return m_message; - } + const char* what() const noexcept { return m_message.toLatin1().constData(); } + QString cause() const { return m_message; } -private: + private: QString m_message; }; diff --git a/launcher/ExponentialSeries.h b/launcher/ExponentialSeries.h index a9487f0a3..b1fca4359 100644 --- a/launcher/ExponentialSeries.h +++ b/launcher/ExponentialSeries.h @@ -4,31 +4,24 @@ template inline void clamp(T& current, T min, T max) { - if (current < min) - { + if (current < min) { current = min; - } - else if(current > max) - { + } else if (current > max) { current = max; } } // List of numbers from min to max. Next is exponent times bigger than previous. -class ExponentialSeries -{ -public: +class ExponentialSeries { + public: ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2) { m_current = m_min = min; m_max = max; m_exponent = exponent; } - void reset() - { - m_current = m_min; - } + void reset() { m_current = m_min; } unsigned operator()() { unsigned retval = m_current; diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 4538702f2..defb2cb9e 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -779,7 +779,8 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri } #if defined(Q_OS_MACOS) // Create the Application - QDir applicationDirectory = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/"; + QDir applicationDirectory = + QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/"; if (!applicationDirectory.mkpath(".")) { qWarning() << "Couldn't create application directory"; @@ -843,7 +844,9 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri " CFBundleIconFile\n" " Icon.icns\n" " CFBundleName\n" - " " << name << "\n" // Name of the application + " " + << name + << "\n" // Name of the application " CFBundlePackageType\n" " APPL\n" " CFBundleShortVersionString\n" diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index f8a82baef..85e2cbe00 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -43,10 +43,10 @@ #include #include -#include #include #include #include +#include #include namespace FS { @@ -365,25 +365,24 @@ enum class FilesystemType { * QMap is ordered * */ -static const QMap s_filesystem_type_names = { - {FilesystemType::FAT, { "FAT" }}, - {FilesystemType::NTFS, { "NTFS" }}, - {FilesystemType::REFS, { "REFS" }}, - {FilesystemType::EXT_2_OLD, { "EXT_2_OLD", "EXT2_OLD" }}, - {FilesystemType::EXT_2_3_4, { "EXT2/3/4", "EXT_2_3_4", "EXT2", "EXT3", "EXT4" }}, - {FilesystemType::EXT, { "EXT" }}, - {FilesystemType::XFS, { "XFS" }}, - {FilesystemType::BTRFS, { "BTRFS" }}, - {FilesystemType::NFS, { "NFS" }}, - {FilesystemType::ZFS, { "ZFS" }}, - {FilesystemType::APFS, { "APFS" }}, - {FilesystemType::HFS, { "HFS" }}, - {FilesystemType::HFSPLUS, { "HFSPLUS" }}, - {FilesystemType::HFSX, { "HFSX" }}, - {FilesystemType::FUSEBLK, { "FUSEBLK" }}, - {FilesystemType::F2FS, { "F2FS" }}, - {FilesystemType::UNKNOWN, { "UNKNOWN" }} -}; +static const QMap s_filesystem_type_names = { { FilesystemType::FAT, { "FAT" } }, + { FilesystemType::NTFS, { "NTFS" } }, + { FilesystemType::REFS, { "REFS" } }, + { FilesystemType::EXT_2_OLD, { "EXT_2_OLD", "EXT2_OLD" } }, + { FilesystemType::EXT_2_3_4, + { "EXT2/3/4", "EXT_2_3_4", "EXT2", "EXT3", "EXT4" } }, + { FilesystemType::EXT, { "EXT" } }, + { FilesystemType::XFS, { "XFS" } }, + { FilesystemType::BTRFS, { "BTRFS" } }, + { FilesystemType::NFS, { "NFS" } }, + { FilesystemType::ZFS, { "ZFS" } }, + { FilesystemType::APFS, { "APFS" } }, + { FilesystemType::HFS, { "HFS" } }, + { FilesystemType::HFSPLUS, { "HFSPLUS" } }, + { FilesystemType::HFSX, { "HFSX" } }, + { FilesystemType::FUSEBLK, { "FUSEBLK" } }, + { FilesystemType::F2FS, { "F2FS" } }, + { FilesystemType::UNKNOWN, { "UNKNOWN" } } }; /** * @brief Get the string name of Filesystem enum object diff --git a/launcher/Filter.cpp b/launcher/Filter.cpp index c65ca0ceb..9d9044734 100644 --- a/launcher/Filter.cpp +++ b/launcher/Filter.cpp @@ -1,28 +1,27 @@ #include "Filter.h" -Filter::~Filter(){} +Filter::~Filter() {} -ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern){} -ContainsFilter::~ContainsFilter(){} +ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern) {} +ContainsFilter::~ContainsFilter() {} bool ContainsFilter::accepts(const QString& value) { return value.contains(pattern); } -ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern){} -ExactFilter::~ExactFilter(){} +ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern) {} +ExactFilter::~ExactFilter() {} bool ExactFilter::accepts(const QString& value) { return value == pattern; } -RegexpFilter::RegexpFilter(const QString& regexp, bool invert) - :invert(invert) +RegexpFilter::RegexpFilter(const QString& regexp, bool invert) : invert(invert) { pattern.setPattern(regexp); pattern.optimize(); } -RegexpFilter::~RegexpFilter(){} +RegexpFilter::~RegexpFilter() {} bool RegexpFilter::accepts(const QString& value) { auto match = pattern.match(value); diff --git a/launcher/Filter.h b/launcher/Filter.h index b55067acb..f58521cf2 100644 --- a/launcher/Filter.h +++ b/launcher/Filter.h @@ -1,42 +1,41 @@ #pragma once -#include #include +#include -class Filter -{ -public: +class Filter { + public: virtual ~Filter(); - virtual bool accepts(const QString & value) = 0; + virtual bool accepts(const QString& value) = 0; }; -class ContainsFilter: public Filter -{ -public: - ContainsFilter(const QString &pattern); +class ContainsFilter : public Filter { + public: + ContainsFilter(const QString& pattern); virtual ~ContainsFilter(); - bool accepts(const QString & value) override; -private: + bool accepts(const QString& value) override; + + private: QString pattern; }; -class ExactFilter: public Filter -{ -public: - ExactFilter(const QString &pattern); +class ExactFilter : public Filter { + public: + ExactFilter(const QString& pattern); virtual ~ExactFilter(); - bool accepts(const QString & value) override; -private: + bool accepts(const QString& value) override; + + private: QString pattern; }; -class RegexpFilter: public Filter -{ -public: - RegexpFilter(const QString ®exp, bool invert); +class RegexpFilter : public Filter { + public: + RegexpFilter(const QString& regexp, bool invert); virtual ~RegexpFilter(); - bool accepts(const QString & value) override; -private: + bool accepts(const QString& value) override; + + private: QRegularExpression pattern; bool invert = false; }; diff --git a/launcher/GZip.cpp b/launcher/GZip.cpp index e36dc8a49..292fab294 100644 --- a/launcher/GZip.cpp +++ b/launcher/GZip.cpp @@ -37,10 +37,9 @@ #include #include -bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes) +bool GZip::unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes) { - if (compressedBytes.size() == 0) - { + if (compressedBytes.size() == 0) { uncompressedBytes = compressedBytes; return true; } @@ -51,42 +50,37 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte z_stream strm; memset(&strm, 0, sizeof(strm)); - strm.next_in = (Bytef *)compressedBytes.data(); + strm.next_in = (Bytef*)compressedBytes.data(); strm.avail_in = compressedBytes.size(); bool done = false; - if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) - { + if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) { return false; } int err = Z_OK; - while (!done) - { + while (!done) { // If our output buffer is too small - if (strm.total_out >= uncompLength) - { + if (strm.total_out >= uncompLength) { uncompressedBytes.resize(uncompLength * 2); uncompLength *= 2; } - strm.next_out = reinterpret_cast((uncompressedBytes.data() + strm.total_out)); + strm.next_out = reinterpret_cast((uncompressedBytes.data() + strm.total_out)); strm.avail_out = uncompLength - strm.total_out; // Inflate another chunk. err = inflate(&strm, Z_SYNC_FLUSH); if (err == Z_STREAM_END) done = true; - else if (err != Z_OK) - { + else if (err != Z_OK) { break; } } - if (inflateEnd(&strm) != Z_OK || !done) - { + if (inflateEnd(&strm) != Z_OK || !done) { return false; } @@ -94,10 +88,9 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte return true; } -bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) +bool GZip::zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes) { - if (uncompressedBytes.size() == 0) - { + if (uncompressedBytes.size() == 0) { compressedBytes = uncompressedBytes; return true; } @@ -109,8 +102,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) z_stream zs; memset(&zs, 0, sizeof(zs)); - if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) - { + if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) { return false; } @@ -122,11 +114,9 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) unsigned offset = 0; unsigned temp = 0; - do - { + do { auto remaining = compressedBytes.size() - offset; - if(remaining < 1) - { + if (remaining < 1) { compressedBytes.resize(compressedBytes.size() * 2); } zs.next_out = reinterpret_cast((compressedBytes.data() + offset)); @@ -137,13 +127,11 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) compressedBytes.resize(offset); - if (deflateEnd(&zs) != Z_OK) - { + if (deflateEnd(&zs) != Z_OK) { return false; } - if (ret != Z_STREAM_END) - { + if (ret != Z_STREAM_END) { return false; } return true; diff --git a/launcher/GZip.h b/launcher/GZip.h index 7d4b1c332..0bdb70407 100644 --- a/launcher/GZip.h +++ b/launcher/GZip.h @@ -1,10 +1,8 @@ #pragma once #include -class GZip -{ -public: - static bool unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes); - static bool zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes); +class GZip { + public: + static bool unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes); + static bool zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes); }; - diff --git a/launcher/InstanceCopyPrefs.cpp b/launcher/InstanceCopyPrefs.cpp index 0650002b8..63c200cc4 100644 --- a/launcher/InstanceCopyPrefs.cpp +++ b/launcher/InstanceCopyPrefs.cpp @@ -6,17 +6,10 @@ bool InstanceCopyPrefs::allTrue() const { - return copySaves && - keepPlaytime && - copyGameOptions && - copyResourcePacks && - copyShaderPacks && - copyServers && - copyMods && - copyScreenshots; + return copySaves && keepPlaytime && copyGameOptions && copyResourcePacks && copyShaderPacks && copyServers && copyMods && + copyScreenshots; } - // Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat") QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const { @@ -26,25 +19,30 @@ QString InstanceCopyPrefs::getSelectedFiltersAsRegex(const QStringList& addition { QStringList filters; - if(!copySaves) + if (!copySaves) filters << "saves"; - if(!copyGameOptions) + if (!copyGameOptions) filters << "options.txt"; - if(!copyResourcePacks) - filters << "resourcepacks" << "texturepacks"; + if (!copyResourcePacks) + filters << "resourcepacks" + << "texturepacks"; - if(!copyShaderPacks) + if (!copyShaderPacks) filters << "shaderpacks"; - if(!copyServers) - filters << "servers.dat" << "servers.dat_old" << "server-resource-packs"; + if (!copyServers) + filters << "servers.dat" + << "servers.dat_old" + << "server-resource-packs"; - if(!copyMods) - filters << "coremods" << "mods" << "config"; + if (!copyMods) + filters << "coremods" + << "mods" + << "config"; - if(!copyScreenshots) + if (!copyScreenshots) filters << "screenshots"; for (auto filter : additionalFilters) { diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h index c7bde0682..61c51b3b7 100644 --- a/launcher/InstanceCopyPrefs.h +++ b/launcher/InstanceCopyPrefs.h @@ -40,7 +40,7 @@ struct InstanceCopyPrefs { void enableDontLinkSaves(bool b); void enableUseClone(bool b); - protected: // data + protected: // data bool copySaves = true; bool keepPlaytime = true; bool copyGameOptions = true; diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index 57a3143a1..8abf30640 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -156,8 +156,9 @@ void InstanceCopyTask::copyFinished() allowed_symlinks.append(m_origInstance->gameRoot().toUtf8()); allowed_symlinks.append("\n"); if (allowed_symlinks_file.isSymLink()) - FS::deletePath(allowed_symlinks_file - .filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link. + FS::deletePath( + allowed_symlinks_file + .filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link. FS::write(allowed_symlinks_file.filePath(), allowed_symlinks); } diff --git a/launcher/InstanceCopyTask.h b/launcher/InstanceCopyTask.h index aea9d99a1..357c6df0b 100644 --- a/launcher/InstanceCopyTask.h +++ b/launcher/InstanceCopyTask.h @@ -11,19 +11,18 @@ #include "settings/SettingsObject.h" #include "tasks/Task.h" -class InstanceCopyTask : public InstanceTask -{ +class InstanceCopyTask : public InstanceTask { Q_OBJECT -public: + public: explicit InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs); -protected: + protected: //! Entry point for tasks. virtual void executeTask() override; void copyFinished(); void copyAborted(); -private: + private: /* data */ InstancePtr m_origInstance; QFuture m_copyFuture; diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index d6a96deb1..5624454a3 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -45,9 +45,9 @@ #include "icons/IconList.h" #include "icons/IconUtils.h" -#include "modplatform/technic/TechnicPackProcessor.h" -#include "modplatform/modrinth/ModrinthInstanceCreationTask.h" #include "modplatform/flame/FlameInstanceCreationTask.h" +#include "modplatform/modrinth/ModrinthInstanceCreationTask.h" +#include "modplatform/technic/TechnicPackProcessor.h" #include "settings/INISettingsObject.h" @@ -138,8 +138,7 @@ void InstanceImportTask::processZipPack() // open the zip and find relevant files in it m_packZip.reset(new QuaZip(m_archivePath)); - if (!m_packZip->open(QuaZip::mdUnzip)) - { + if (!m_packZip->open(QuaZip::mdUnzip)) { emitFailed(tr("Unable to open supplied modpack zip file.")); return; } @@ -153,44 +152,40 @@ void InstanceImportTask::processZipPack() // NOTE: Prioritize modpack platforms that aren't searched for recursively. // Especially Flame has a very common filename for its manifest, which may appear inside overrides for example - if(modrinthFound) - { + if (modrinthFound) { // process as Modrinth pack qDebug() << "Modrinth:" << modrinthFound; m_modpackType = ModpackType::Modrinth; - } - else if (technicFound) - { + } else if (technicFound) { // process as Technic pack qDebug() << "Technic:" << technicFound; extractDir.mkpath(".minecraft"); extractDir.cd(".minecraft"); m_modpackType = ModpackType::Technic; - } - else - { - QStringList paths_to_ignore { "overrides/" }; + } else { + QStringList paths_to_ignore{ "overrides/" }; if (QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg", paths_to_ignore); !mmcRoot.isNull()) { // process as MultiMC instance/pack qDebug() << "MultiMC:" << mmcRoot; root = mmcRoot; m_modpackType = ModpackType::MultiMC; - } else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore); !flameRoot.isNull()) { + } else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore); + !flameRoot.isNull()) { // process as Flame pack qDebug() << "Flame:" << flameRoot; root = flameRoot; m_modpackType = ModpackType::Flame; } } - if(m_modpackType == ModpackType::Unknown) - { + if (m_modpackType == ModpackType::Unknown) { emitFailed(tr("Archive does not contain a recognized modpack type.")); return; } // make sure we extract just the pack - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath()); + m_extractFuture = + QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath()); connect(&m_extractFutureWatcher, &QFutureWatcher::finished, this, &InstanceImportTask::extractFinished); m_extractFutureWatcher.setFuture(m_extractFuture); } @@ -210,37 +205,28 @@ void InstanceImportTask::extractFinished() qDebug() << "Fixing permissions for extracted pack files..."; QDirIterator it(extractDir, QDirIterator::Subdirectories); - while (it.hasNext()) - { + while (it.hasNext()) { auto filepath = it.next(); QFileInfo file(filepath); auto permissions = QFile::permissions(filepath); auto origPermissions = permissions; - if(file.isDir()) - { + if (file.isDir()) { // Folder +rwx for current user permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser; - } - else - { + } else { // File +rw for current user permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser; } - if(origPermissions != permissions) - { - if(!QFile::setPermissions(filepath, permissions)) - { + if (origPermissions != permissions) { + if (!QFile::setPermissions(filepath, permissions)) { logWarning(tr("Could not fix permissions for %1").arg(filepath)); - } - else - { + } else { qDebug() << "Fixed" << filepath; } } } - switch(m_modpackType) - { + switch (m_modpackType) { case ModpackType::MultiMC: processMultiMC(); return; @@ -276,7 +262,8 @@ void InstanceImportTask::processFlame() if (original_instance_id_it != m_extra_info.constEnd()) original_instance_id = original_instance_id_it.value(); - inst_creation_task = makeShared(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); + inst_creation_task = + makeShared(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); } else { // FIXME: Find a way to get IDs in directly imported ZIPs inst_creation_task = makeShared(m_stagingPath, m_globalSettings, m_parent, QString(), QString()); @@ -286,7 +273,7 @@ void InstanceImportTask::processFlame() inst_creation_task->setIcon(m_instIcon); inst_creation_task->setGroup(m_instGroup); inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); - + connect(inst_creation_task.get(), &Task::succeeded, this, [this, inst_creation_task] { setOverride(inst_creation_task->shouldOverride(), inst_creation_task->originalInstanceID()); emitSucceeded(); @@ -362,7 +349,8 @@ void InstanceImportTask::processModrinth() if (original_instance_id_it != m_extra_info.constEnd()) original_instance_id = original_instance_id_it.value(); - inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); + inst_creation_task = + new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); } else { QString pack_id; if (!m_sourceUrl.isEmpty()) { @@ -378,7 +366,7 @@ void InstanceImportTask::processModrinth() inst_creation_task->setIcon(m_instIcon); inst_creation_task->setGroup(m_instGroup); inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); - + connect(inst_creation_task, &Task::succeeded, this, [this, inst_creation_task] { setOverride(inst_creation_task->shouldOverride(), inst_creation_task->originalInstanceID()); emitSucceeded(); diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index 7fda439fc..582a9ded0 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -35,54 +35,49 @@ #pragma once -#include "InstanceTask.h" -#include "net/NetJob.h" -#include #include #include -#include "settings/SettingsObject.h" +#include +#include "InstanceTask.h" #include "QObjectPtr.h" #include "modplatform/flame/PackManifest.h" +#include "net/NetJob.h" +#include "settings/SettingsObject.h" #include class QuaZip; -namespace Flame -{ - class FileResolvingTask; +namespace Flame { +class FileResolvingTask; } -class InstanceImportTask : public InstanceTask -{ +class InstanceImportTask : public InstanceTask { Q_OBJECT -public: + public: explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr, QMap&& extra_info = {}); bool abort() override; - const QVector &getBlockedFiles() const - { - return m_blockedMods; - } + const QVector& getBlockedFiles() const { return m_blockedMods; } -protected: + protected: //! Entry point for tasks. virtual void executeTask() override; -private: + private: void processZipPack(); void processMultiMC(); void processTechnic(); void processFlame(); void processModrinth(); -private slots: + private slots: void downloadSucceeded(); void downloadFailed(QString reason); void downloadProgressChanged(qint64 current, qint64 total); void downloadAborted(); void extractFinished(); -private: /* data */ + private: /* data */ NetJob::Ptr m_filesNetJob; shared_qobject_ptr m_modIdResolver; QUrl m_sourceUrl; @@ -92,7 +87,7 @@ private: /* data */ QFuture> m_extractFuture; QFutureWatcher> m_extractFutureWatcher; QVector m_blockedMods; - enum class ModpackType{ + enum class ModpackType { Unknown, MultiMC, Technic, @@ -104,6 +99,6 @@ private: /* data */ // the source URL / the resource it points to alone. QMap m_extra_info; - //FIXME: nuke + // FIXME: nuke QWidget* m_parent; }; diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index 0485db19e..d808676c1 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -41,9 +41,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -129,7 +129,7 @@ QMimeData* InstanceList::mimeData(const QModelIndexList& indexes) const return mimeData; } -QStringList InstanceList::getLinkedInstancesById(const QString &id) const +QStringList InstanceList::getLinkedInstancesById(const QString& id) const { QStringList linkedInstances; for (auto inst : m_instances) { @@ -158,42 +158,34 @@ QVariant InstanceList::data(const QModelIndex& index, int role) const if (!index.isValid()) { return QVariant(); } - BaseInstance *pdata = static_cast(index.internalPointer()); - switch (role) - { - case InstancePointerRole: - { - QVariant v = QVariant::fromValue((void *)pdata); - return v; - } - case InstanceIDRole: - { - return pdata->id(); - } - case Qt::EditRole: - case Qt::DisplayRole: - { - return pdata->name(); - } - case Qt::AccessibleTextRole: - { - return tr("%1 Instance").arg(pdata->name()); - } - case Qt::ToolTipRole: - { - return pdata->instanceRoot(); - } - case Qt::DecorationRole: - { - return pdata->iconKey(); - } - // HACK: see InstanceView.h in gui! - case GroupRole: - { - return getInstanceGroup(pdata->id()); - } - default: - break; + BaseInstance* pdata = static_cast(index.internalPointer()); + switch (role) { + case InstancePointerRole: { + QVariant v = QVariant::fromValue((void*)pdata); + return v; + } + case InstanceIDRole: { + return pdata->id(); + } + case Qt::EditRole: + case Qt::DisplayRole: { + return pdata->name(); + } + case Qt::AccessibleTextRole: { + return tr("%1 Instance").arg(pdata->name()); + } + case Qt::ToolTipRole: { + return pdata->instanceRoot(); + } + case Qt::DecorationRole: { + return pdata->iconKey(); + } + // HACK: see InstanceView.h in gui! + case GroupRole: { + return getInstanceGroup(pdata->id()); + } + default: + break; } return QVariant(); } @@ -320,16 +312,18 @@ bool InstanceList::trashInstance(const InstanceId& id) } qDebug() << "Instance" << id << "has been trashed by the launcher."; - m_trashHistory.push({id, inst->instanceRoot(), trashedLoc, cachedGroupId}); - + m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId }); + return true; } -bool InstanceList::trashedSomething() { +bool InstanceList::trashedSomething() +{ return !m_trashHistory.empty(); } -void InstanceList::undoTrashInstance() { +void InstanceList::undoTrashInstance() +{ if (m_trashHistory.empty()) { qWarning() << "Nothing to recover from trash."; return; @@ -558,7 +552,7 @@ InstancePtr InstanceList::getInstanceByManagedName(const QString& managed_name) return {}; } -QModelIndex InstanceList::getInstanceIndexById(const QString &id) const +QModelIndex InstanceList::getInstanceIndexById(const QString& id) const { return index(getInstIndex(getInstanceById(id).get())); } @@ -597,13 +591,11 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) QString inst_type = instanceSettings->get("InstanceType").toString(); - // NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix instance - if (inst_type == "OneSix" || inst_type.isEmpty()) - { + // NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix + // instance + if (inst_type == "OneSix" || inst_type.isEmpty()) { inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot)); - } - else - { + } else { inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot)); } qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot(); @@ -787,9 +779,14 @@ class InstanceStaging : public Task { Q_OBJECT const unsigned minBackoff = 1; const unsigned maxBackoff = 16; + public: InstanceStaging(InstanceList* parent, InstanceTask* child, QString stagingPath, InstanceName const& instanceName, QString groupName) - : m_parent(parent), backoff(minBackoff, maxBackoff), m_stagingPath(std::move(stagingPath)), m_instance_name(std::move(instanceName)), m_groupName(std::move(groupName)) + : m_parent(parent) + , backoff(minBackoff, maxBackoff) + , m_stagingPath(std::move(stagingPath)) + , m_instance_name(std::move(instanceName)) + , m_groupName(std::move(groupName)) { m_child.reset(child); connect(child, &Task::succeeded, this, &InstanceStaging::childSucceded); @@ -815,10 +812,7 @@ class InstanceStaging : public Task { return Task::abort(); } - bool canAbort() const override - { - return (m_child && m_child->canAbort()); - } + bool canAbort() const override { return (m_child && m_child->canAbort()); } protected: virtual void executeTask() override { m_child->start(); } @@ -828,8 +822,7 @@ class InstanceStaging : public Task { void childSucceded() { unsigned sleepTime = backoff(); - if (m_parent->commitStagedInstance(m_stagingPath, m_instance_name, m_groupName, *m_child.get())) - { + if (m_parent->commitStagedInstance(m_stagingPath, m_instance_name, m_groupName, *m_child.get())) { emitSucceeded(); return; } @@ -847,13 +840,10 @@ class InstanceStaging : public Task { emitFailed(reason); } - void childAborted() - { - emitAborted(); - } + void childAborted() { emitAborted(); } -private: - InstanceList * m_parent; + private: + InstanceList* m_parent; /* * WHY: the whole reason why this uses an exponential backoff retry scheme is antivirus on Windows. * Basically, it starts messing things up while the launcher is extracting/creating instances @@ -892,7 +882,10 @@ QString InstanceList::getStagedInstancePath() return path; } -bool InstanceList::commitStagedInstance(const QString& path, InstanceName const& instanceName, const QString& groupName, InstanceTask const& commiting) +bool InstanceList::commitStagedInstance(const QString& path, + InstanceName const& instanceName, + const QString& groupName, + InstanceTask const& commiting) { QDir dir; QString instID; diff --git a/launcher/InstanceList.h b/launcher/InstanceList.h index 48bede07d..ee4578ffd 100644 --- a/launcher/InstanceList.h +++ b/launcher/InstanceList.h @@ -15,12 +15,12 @@ #pragma once -#include #include -#include #include -#include +#include #include +#include +#include #include "BaseInstance.h" @@ -32,21 +32,9 @@ using InstanceId = QString; using GroupId = QString; using InstanceLocator = std::pair; -enum class InstCreateError -{ - NoCreateError = 0, - NoSuchVersion, - UnknownCreateError, - InstExists, - CantCreateDir -}; +enum class InstCreateError { NoCreateError = 0, NoSuchVersion, UnknownCreateError, InstExists, CantCreateDir }; -enum class GroupsState -{ - NotLoaded, - Steady, - Dirty -}; +enum class GroupsState { NotLoaded, Steady, Dirty }; struct TrashHistoryItem { QString id; @@ -55,48 +43,36 @@ struct TrashHistoryItem { QString groupName; }; -class InstanceList : public QAbstractListModel -{ +class InstanceList : public QAbstractListModel { Q_OBJECT -public: - explicit InstanceList(SettingsObjectPtr settings, const QString & instDir, QObject *parent = 0); + public: + explicit InstanceList(SettingsObjectPtr settings, const QString& instDir, QObject* parent = 0); virtual ~InstanceList(); -public: - QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; + public: + QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; - bool setData(const QModelIndex & index, const QVariant & value, int role) override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; - enum AdditionalRoles - { + enum AdditionalRoles { GroupRole = Qt::UserRole, - InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance - InstanceIDRole = 0x34B1CB49 ///< Return id if the instance + InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance + InstanceIDRole = 0x34B1CB49 ///< Return id if the instance }; /*! * \brief Error codes returned by functions in the InstanceList class. * NoError Indicates that no error occurred. * UnknownError indicates that an unspecified error occurred. */ - enum InstListError - { - NoError = 0, - UnknownError - }; + enum InstListError { NoError = 0, UnknownError }; - InstancePtr at(int i) const - { - return m_instances.at(i); - } + InstancePtr at(int i) const { return m_instances.at(i); } - int count() const - { - return m_instances.count(); - } + int count() const { return m_instances.count(); } InstListError loadList(); void saveNow(); @@ -105,21 +81,21 @@ public: InstancePtr getInstanceById(QString id) const; /* O(n) */ InstancePtr getInstanceByManagedName(const QString& managed_name) const; - QModelIndex getInstanceIndexById(const QString &id) const; + QModelIndex getInstanceIndexById(const QString& id) const; QStringList getGroups(); - bool isGroupCollapsed(const QString &groupName); + bool isGroupCollapsed(const QString& groupName); - GroupId getInstanceGroup(const InstanceId & id) const; - void setInstanceGroup(const InstanceId & id, const GroupId& name); + GroupId getInstanceGroup(const InstanceId& id) const; + void setInstanceGroup(const InstanceId& id, const GroupId& name); - void deleteGroup(const GroupId & name); - bool trashInstance(const InstanceId &id); + void deleteGroup(const GroupId& name); + bool trashInstance(const InstanceId& id); bool trashedSomething(); void undoTrashInstance(); - void deleteInstance(const InstanceId & id); + void deleteInstance(const InstanceId& id); // Wrap an instance creation task in some more task machinery and make it ready to be used - Task * wrapInstanceTask(InstanceTask * task); + Task* wrapInstanceTask(InstanceTask* task); /** * Create a new empty staging area for instance creation and @return a path/key top commit it later. @@ -139,7 +115,7 @@ public: * Destroy a previously created staging area given by @keyPath - used when creation fails. * Used by instance manipulation tasks. */ - bool destroyStagingPath(const QString & keyPath); + bool destroyStagingPath(const QString& keyPath); int getTotalPlayTime(); @@ -147,42 +123,42 @@ public: Qt::DropActions supportedDropActions() const override; - bool canDropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) const override; + bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override; - bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override; + bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; QStringList mimeTypes() const override; - QMimeData *mimeData(const QModelIndexList &indexes) const override; + QMimeData* mimeData(const QModelIndexList& indexes) const override; - QStringList getLinkedInstancesById(const QString &id) const; + QStringList getLinkedInstancesById(const QString& id) const; -signals: + signals: void dataIsInvalid(); void instancesChanged(); void instanceSelectRequest(QString instanceId); void groupsChanged(QSet groups); -public slots: - void on_InstFolderChanged(const Setting &setting, QVariant value); - void on_GroupStateChanged(const QString &group, bool collapsed); + public slots: + void on_InstFolderChanged(const Setting& setting, QVariant value); + void on_GroupStateChanged(const QString& group, bool collapsed); -private slots: - void propertiesChanged(BaseInstance *inst); + private slots: + void propertiesChanged(BaseInstance* inst); void providerUpdated(); - void instanceDirContentsChanged(const QString &path); + void instanceDirContentsChanged(const QString& path); -private: - int getInstIndex(BaseInstance *inst) const; + private: + int getInstIndex(BaseInstance* inst) const; void updateTotalPlayTime(); void suspendWatch(); void resumeWatch(); - void add(const QList &list); + void add(const QList& list); void loadGroupList(); void saveGroupList(); QList discoverInstances(); InstancePtr loadInstance(const InstanceId& id); -private: + private: int m_watchLevel = 0; int totalPlayTime = 0; bool m_dirty = false; @@ -191,7 +167,7 @@ private: SettingsObjectPtr m_globalSettings; QString m_instDir; - QFileSystemWatcher * m_watcher; + QFileSystemWatcher* m_watcher; // FIXME: this is so inefficient that looking at it is almost painful. QSet m_collapsedGroups; QMap m_instanceGroupIndex; diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index d25cd330e..66d2b6750 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -1,35 +1,31 @@ #pragma once -#include "minecraft/MinecraftInstance.h" #include +#include "minecraft/MinecraftInstance.h" #include "ui/pages/BasePage.h" #include "ui/pages/BasePageProvider.h" +#include "ui/pages/instance/InstanceSettingsPage.h" #include "ui/pages/instance/LogPage.h" -#include "ui/pages/instance/VersionPage.h" #include "ui/pages/instance/ManagedPackPage.h" #include "ui/pages/instance/ModFolderPage.h" -#include "ui/pages/instance/ResourcePackPage.h" -#include "ui/pages/instance/TexturePackPage.h" -#include "ui/pages/instance/ShaderPackPage.h" #include "ui/pages/instance/NotesPage.h" -#include "ui/pages/instance/ScreenshotsPage.h" -#include "ui/pages/instance/InstanceSettingsPage.h" #include "ui/pages/instance/OtherLogsPage.h" -#include "ui/pages/instance/WorldListPage.h" +#include "ui/pages/instance/ResourcePackPage.h" +#include "ui/pages/instance/ScreenshotsPage.h" #include "ui/pages/instance/ServersPage.h" +#include "ui/pages/instance/ShaderPackPage.h" +#include "ui/pages/instance/TexturePackPage.h" +#include "ui/pages/instance/VersionPage.h" +#include "ui/pages/instance/WorldListPage.h" -class InstancePageProvider : protected QObject, public BasePageProvider -{ +class InstancePageProvider : protected QObject, public BasePageProvider { Q_OBJECT -public: - explicit InstancePageProvider(InstancePtr parent) - { - inst = parent; - } + public: + explicit InstancePageProvider(InstancePtr parent) { inst = parent; } - virtual ~InstancePageProvider() {}; - virtual QList getPages() override + virtual ~InstancePageProvider(){}; + virtual QList getPages() override { - QList values; + QList values; values.append(new LogPage(inst)); std::shared_ptr onesix = std::dynamic_pointer_cast(inst); values.append(new VersionPage(onesix.get())); @@ -49,18 +45,14 @@ public: values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots"))); values.append(new InstanceSettingsPage(onesix.get())); auto logMatcher = inst->getLogFileMatcher(); - if(logMatcher) - { + if (logMatcher) { values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher)); } return values; } - virtual QString dialogTitle() override - { - return tr("Edit Instance (%1)").arg(inst->name()); - } -protected: + virtual QString dialogTitle() override { return tr("Edit Instance (%1)").arg(inst->name()); } + + protected: InstancePtr inst; }; - diff --git a/launcher/InstanceTask.cpp b/launcher/InstanceTask.cpp index b16a40ba6..5b2398268 100644 --- a/launcher/InstanceTask.cpp +++ b/launcher/InstanceTask.cpp @@ -18,13 +18,14 @@ InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& ol return InstanceNameChange::ShouldKeep; } -ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name) +ShouldUpdate askIfShouldUpdate(QWidget* parent, QString original_version_name) { auto info = CustomMessageBox::selectable( parent, QObject::tr("Similar modpack was found!"), - QObject::tr("One or more of your instances are from this same modpack%1. Do you want to create a " - "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " - "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") + QObject::tr( + "One or more of your instances are from this same modpack%1. Do you want to create a " + "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " + "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") .arg(original_version_name), QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort); info->setButtonText(QMessageBox::Ok, QObject::tr("Update existing instance")); @@ -38,7 +39,6 @@ ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name) if (info->clickedButton() == info->button(QMessageBox::Abort)) return ShouldUpdate::SkipUpdating; return ShouldUpdate::Cancel; - } QString InstanceName::name() const diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index 30a7dbacc..73bc96a43 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -39,43 +39,39 @@ #include -bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent) +bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget* parent) { - if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegularExpression("-Xm[sx]")) - || jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize")) - { + if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegularExpression("-Xm[sx]")) || jvmargs.contains("-XX-MaxHeapSize") || + jvmargs.contains("-XX:InitialHeapSize")) { auto warnStr = QObject::tr( - "You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" or \"-Xms\").\n" + "You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" " + "or \"-Xms\").\n" "There are dedicated boxes for these in the settings (Java tab, in the Memory group at the top).\n" "This message will be displayed until you remove them from the JVM arguments."); - CustomMessageBox::selectable( - parent, QObject::tr("JVM arguments warning"), - warnStr, - QMessageBox::Warning)->exec(); + CustomMessageBox::selectable(parent, QObject::tr("JVM arguments warning"), warnStr, QMessageBox::Warning)->exec(); return false; } // block lunacy with passing required version to the JVM if (jvmargs.contains(QRegularExpression("-version:.*"))) { auto warnStr = QObject::tr( - "You tried to pass required Java version argument to the JVM (using \"-version:xxx\"). This is not safe and will not be allowed.\n" + "You tried to pass required Java version argument to the JVM (using \"-version:xxx\"). This is not safe and will not be " + "allowed.\n" "This message will be displayed until you remove this from the JVM arguments."); - CustomMessageBox::selectable( - parent, QObject::tr("JVM arguments warning"), - warnStr, - QMessageBox::Warning)->exec(); + CustomMessageBox::selectable(parent, QObject::tr("JVM arguments warning"), warnStr, QMessageBox::Warning)->exec(); return false; } return true; } -void JavaCommon::javaWasOk(QWidget *parent, const JavaCheckResult &result) +void JavaCommon::javaWasOk(QWidget* parent, const JavaCheckResult& result) { QString text; - text += QObject::tr("Java test succeeded!
    Platform reported: %1
    Java version " - "reported: %2
    Java vendor " - "reported: %3
    ").arg(result.realPlatform, result.javaVersion.toString(), result.javaVendor); - if (result.errorLog.size()) - { + text += QObject::tr( + "Java test succeeded!
    Platform reported: %1
    Java version " + "reported: %2
    Java vendor " + "reported: %3
    ") + .arg(result.realPlatform, result.javaVersion.toString(), result.javaVendor); + if (result.errorLog.size()) { auto htmlError = result.errorLog; htmlError.replace('\n', "
    "); text += QObject::tr("
    Warnings:
    %1").arg(htmlError); @@ -83,7 +79,7 @@ void JavaCommon::javaWasOk(QWidget *parent, const JavaCheckResult &result) CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show(); } -void JavaCommon::javaArgsWereBad(QWidget *parent, const JavaCheckResult &result) +void JavaCommon::javaArgsWereBad(QWidget* parent, const JavaCheckResult& result) { auto htmlError = result.errorLog; QString text; @@ -93,7 +89,7 @@ void JavaCommon::javaArgsWereBad(QWidget *parent, const JavaCheckResult &result) CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); } -void JavaCommon::javaBinaryWasBad(QWidget *parent, const JavaCheckResult &result) +void JavaCommon::javaBinaryWasBad(QWidget* parent, const JavaCheckResult& result) { QString text; text += QObject::tr( @@ -102,7 +98,7 @@ void JavaCommon::javaBinaryWasBad(QWidget *parent, const JavaCheckResult &result CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); } -void JavaCommon::javaCheckNotFound(QWidget *parent) +void JavaCommon::javaCheckNotFound(QWidget* parent) { QString text; text += QObject::tr("Java checker library could not be found. Please check your installation."); @@ -111,8 +107,7 @@ void JavaCommon::javaCheckNotFound(QWidget *parent) void JavaCommon::TestCheck::run() { - if (!JavaCommon::checkJVMArgs(m_args, m_parent)) - { + if (!JavaCommon::checkJVMArgs(m_args, m_parent)) { emit finished(); return; } @@ -129,8 +124,7 @@ void JavaCommon::TestCheck::run() void JavaCommon::TestCheck::checkFinished(JavaCheckResult result) { - if (result.validity != JavaCheckResult::Validity::Valid) - { + if (result.validity != JavaCheckResult::Validity::Valid) { javaBinaryWasBad(m_parent, result); emit finished(); return; @@ -141,8 +135,7 @@ void JavaCommon::TestCheck::checkFinished(JavaCheckResult result) checker->m_args = m_args; checker->m_minMem = m_minMem; checker->m_maxMem = m_maxMem; - if (result.javaVersion.requiresPermGen()) - { + if (result.javaVersion.requiresPermGen()) { checker->m_permGen = m_permGen; } checker->performCheck(); @@ -150,8 +143,7 @@ void JavaCommon::TestCheck::checkFinished(JavaCheckResult result) void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result) { - if (result.validity == JavaCheckResult::Validity::Valid) - { + if (result.validity == JavaCheckResult::Validity::Valid) { javaWasOk(m_parent, result); emit finished(); return; @@ -159,4 +151,3 @@ void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result) javaArgsWereBad(m_parent, result); emit finished(); } - diff --git a/launcher/JavaCommon.h b/launcher/JavaCommon.h index 2ba64c0cd..c96f7a985 100644 --- a/launcher/JavaCommon.h +++ b/launcher/JavaCommon.h @@ -6,45 +6,42 @@ class QWidget; /** * Common UI bits for the java pages to use. */ -namespace JavaCommon -{ - bool checkJVMArgs(QString args, QWidget *parent); +namespace JavaCommon { +bool checkJVMArgs(QString args, QWidget* parent); - // Show a dialog saying that the Java binary was usable - void javaWasOk(QWidget *parent, const JavaCheckResult &result); - // Show a dialog saying that the Java binary was not usable because of bad options - void javaArgsWereBad(QWidget *parent, const JavaCheckResult &result); - // Show a dialog saying that the Java binary was not usable - void javaBinaryWasBad(QWidget *parent, const JavaCheckResult &result); - // Show a dialog if we couldn't find Java Checker - void javaCheckNotFound(QWidget *parent); +// Show a dialog saying that the Java binary was usable +void javaWasOk(QWidget* parent, const JavaCheckResult& result); +// Show a dialog saying that the Java binary was not usable because of bad options +void javaArgsWereBad(QWidget* parent, const JavaCheckResult& result); +// Show a dialog saying that the Java binary was not usable +void javaBinaryWasBad(QWidget* parent, const JavaCheckResult& result); +// Show a dialog if we couldn't find Java Checker +void javaCheckNotFound(QWidget* parent); - class TestCheck : public QObject - { - Q_OBJECT - public: - 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() {}; +class TestCheck : public QObject { + Q_OBJECT + public: + 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(){}; - void run(); + void run(); - signals: - void finished(); + signals: + void finished(); - private slots: - void checkFinished(JavaCheckResult result); - void checkFinishedWithArgs(JavaCheckResult result); + private slots: + void checkFinished(JavaCheckResult result); + void checkFinishedWithArgs(JavaCheckResult result); - private: - std::shared_ptr checker; - QWidget *m_parent = nullptr; - QString m_path; - QString m_args; - int m_minMem = 0; - int m_maxMem = 0; - int m_permGen = 64; - }; -} + private: + std::shared_ptr checker; + QWidget* m_parent = nullptr; + QString m_path; + QString m_args; + int m_minMem = 0; + int m_maxMem = 0; + int m_permGen = 64; +}; +} // namespace JavaCommon diff --git a/launcher/Json.cpp b/launcher/Json.cpp index 06b3d3bd2..8db44f062 100644 --- a/launcher/Json.cpp +++ b/launcher/Json.cpp @@ -37,257 +37,246 @@ #include -#include "FileSystem.h" #include +#include "FileSystem.h" -namespace Json -{ -void write(const QJsonDocument &doc, const QString &filename) +namespace Json { +void write(const QJsonDocument& doc, const QString& filename) { FS::write(filename, doc.toJson()); } -void write(const QJsonObject &object, const QString &filename) +void write(const QJsonObject& object, const QString& filename) { write(QJsonDocument(object), filename); } -void write(const QJsonArray &array, const QString &filename) +void write(const QJsonArray& array, const QString& filename) { write(QJsonDocument(array), filename); } -QByteArray toText(const QJsonObject &obj) +QByteArray toText(const QJsonObject& obj) { return QJsonDocument(obj).toJson(QJsonDocument::Compact); } -QByteArray toText(const QJsonArray &array) +QByteArray toText(const QJsonArray& array) { return QJsonDocument(array).toJson(QJsonDocument::Compact); } -static bool isBinaryJson(const QByteArray &data) +static bool isBinaryJson(const QByteArray& data) { decltype(QJsonDocument::BinaryFormatTag) tag = QJsonDocument::BinaryFormatTag; return memcmp(data.constData(), &tag, sizeof(QJsonDocument::BinaryFormatTag)) == 0; } -QJsonDocument requireDocument(const QByteArray &data, const QString &what) +QJsonDocument requireDocument(const QByteArray& data, const QString& what) { - if (isBinaryJson(data)) - { + if (isBinaryJson(data)) { // FIXME: Is this needed? throw JsonException(what + ": Invalid JSON. Binary JSON unsupported"); - } - else - { + } else { QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(data, &error); - if (error.error != QJsonParseError::NoError) - { + if (error.error != QJsonParseError::NoError) { throw JsonException(what + ": Error parsing JSON: " + error.errorString()); } return doc; } } -QJsonDocument requireDocument(const QString &filename, const QString &what) +QJsonDocument requireDocument(const QString& filename, const QString& what) { return requireDocument(FS::read(filename), what); } -QJsonObject requireObject(const QJsonDocument &doc, const QString &what) +QJsonObject requireObject(const QJsonDocument& doc, const QString& what) { - if (!doc.isObject()) - { + if (!doc.isObject()) { throw JsonException(what + " is not an object"); } return doc.object(); } -QJsonArray requireArray(const QJsonDocument &doc, const QString &what) +QJsonArray requireArray(const QJsonDocument& doc, const QString& what) { - if (!doc.isArray()) - { + if (!doc.isArray()) { throw JsonException(what + " is not an array"); } return doc.array(); } -void writeString(QJsonObject &to, const QString &key, const QString &value) +void writeString(QJsonObject& to, const QString& key, const QString& value) { - if (!value.isEmpty()) - { + if (!value.isEmpty()) { to.insert(key, value); } } -void writeStringList(QJsonObject &to, const QString &key, const QStringList &values) +void writeStringList(QJsonObject& to, const QString& key, const QStringList& values) { - if (!values.isEmpty()) - { + if (!values.isEmpty()) { QJsonArray array; - for(auto value: values) - { + for (auto value : values) { array.append(value); } to.insert(key, array); } } -template<> -QJsonValue toJson(const QUrl &url) +template <> +QJsonValue toJson(const QUrl& url) { return QJsonValue(url.toString(QUrl::FullyEncoded)); } -template<> -QJsonValue toJson(const QByteArray &data) +template <> +QJsonValue toJson(const QByteArray& data) { return QJsonValue(QString::fromLatin1(data.toHex())); } -template<> -QJsonValue toJson(const QDateTime &datetime) +template <> +QJsonValue toJson(const QDateTime& datetime) { return QJsonValue(datetime.toString(Qt::ISODate)); } -template<> -QJsonValue toJson(const QDir &dir) +template <> +QJsonValue toJson(const QDir& dir) { return QDir::current().relativeFilePath(dir.absolutePath()); } -template<> -QJsonValue toJson(const QUuid &uuid) +template <> +QJsonValue toJson(const QUuid& uuid) { return uuid.toString(); } -template<> -QJsonValue toJson(const QVariant &variant) +template <> +QJsonValue toJson(const QVariant& variant) { return QJsonValue::fromVariant(variant); } - -template<> QByteArray requireIsType(const QJsonValue &value, const QString &what) +template <> +QByteArray requireIsType(const QJsonValue& value, const QString& what) { const QString string = ensureIsType(value, what); // ensure that the string can be safely cast to Latin1 - if (string != QString::fromLatin1(string.toLatin1())) - { + if (string != QString::fromLatin1(string.toLatin1())) { throw JsonException(what + " is not encodable as Latin1"); } return QByteArray::fromHex(string.toLatin1()); } -template<> QJsonArray requireIsType(const QJsonValue &value, const QString &what) +template <> +QJsonArray requireIsType(const QJsonValue& value, const QString& what) { - if (!value.isArray()) - { + if (!value.isArray()) { throw JsonException(what + " is not an array"); } return value.toArray(); } - -template<> QString requireIsType(const QJsonValue &value, const QString &what) +template <> +QString requireIsType(const QJsonValue& value, const QString& what) { - if (!value.isString()) - { + if (!value.isString()) { throw JsonException(what + " is not a string"); } return value.toString(); } -template<> bool requireIsType(const QJsonValue &value, const QString &what) +template <> +bool requireIsType(const QJsonValue& value, const QString& what) { - if (!value.isBool()) - { + if (!value.isBool()) { throw JsonException(what + " is not a bool"); } return value.toBool(); } -template<> double requireIsType(const QJsonValue &value, const QString &what) +template <> +double requireIsType(const QJsonValue& value, const QString& what) { - if (!value.isDouble()) - { + if (!value.isDouble()) { throw JsonException(what + " is not a double"); } return value.toDouble(); } -template<> int requireIsType(const QJsonValue &value, const QString &what) +template <> +int requireIsType(const QJsonValue& value, const QString& what) { const double doubl = requireIsType(value, what); - if (fmod(doubl, 1) != 0) - { + if (fmod(doubl, 1) != 0) { throw JsonException(what + " is not an integer"); } return int(doubl); } -template<> QDateTime requireIsType(const QJsonValue &value, const QString &what) +template <> +QDateTime requireIsType(const QJsonValue& value, const QString& what) { const QString string = requireIsType(value, what); const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate); - if (!datetime.isValid()) - { + if (!datetime.isValid()) { throw JsonException(what + " is not a ISO formatted date/time value"); } return datetime; } -template<> QUrl requireIsType(const QJsonValue &value, const QString &what) +template <> +QUrl requireIsType(const QJsonValue& value, const QString& what) { const QString string = ensureIsType(value, what); - if (string.isEmpty()) - { + if (string.isEmpty()) { return QUrl(); } const QUrl url = QUrl(string, QUrl::StrictMode); - if (!url.isValid()) - { + if (!url.isValid()) { throw JsonException(what + " is not a correctly formatted URL"); } return url; } -template<> QDir requireIsType(const QJsonValue &value, const QString &what) +template <> +QDir requireIsType(const QJsonValue& value, const QString& what) { const QString string = requireIsType(value, what); // FIXME: does not handle invalid characters! return QDir::current().absoluteFilePath(string); } -template<> QUuid requireIsType(const QJsonValue &value, const QString &what) +template <> +QUuid requireIsType(const QJsonValue& value, const QString& what) { const QString string = requireIsType(value, what); const QUuid uuid = QUuid(string); - if (uuid.toString() != string) // converts back => valid + if (uuid.toString() != string) // converts back => valid { throw JsonException(what + " is not a valid UUID"); } return uuid; } -template<> QJsonObject requireIsType(const QJsonValue &value, const QString &what) +template <> +QJsonObject requireIsType(const QJsonValue& value, const QString& what) { - if (!value.isObject()) - { + if (!value.isObject()) { throw JsonException(what + " is not an object"); } return value.toObject(); } -template<> QVariant requireIsType(const QJsonValue &value, const QString &what) +template <> +QVariant requireIsType(const QJsonValue& value, const QString& what) { - if (value.isNull() || value.isUndefined()) - { + if (value.isNull() || value.isUndefined()) { throw JsonException(what + " is null or undefined"); } return value.toVariant(); } -template<> QJsonValue requireIsType(const QJsonValue &value, const QString &what) +template <> +QJsonValue requireIsType(const QJsonValue& value, const QString& what) { - if (value.isNull() || value.isUndefined()) - { + if (value.isNull() || value.isUndefined()) { throw JsonException(what + " is null or undefined"); } return value; } -} +} // namespace Json diff --git a/launcher/Json.h b/launcher/Json.h index b11a356cc..5a8504ef9 100644 --- a/launcher/Json.h +++ b/launcher/Json.h @@ -35,74 +35,71 @@ #pragma once -#include -#include -#include #include -#include #include +#include +#include +#include +#include #include #include #include #include "Exception.h" -namespace Json -{ -class JsonException : public ::Exception -{ -public: - JsonException(const QString &message) : Exception(message) {} +namespace Json { +class JsonException : public ::Exception { + public: + JsonException(const QString& message) : Exception(message) {} }; /// @throw FileSystemException -void write(const QJsonDocument &doc, const QString &filename); +void write(const QJsonDocument& doc, const QString& filename); /// @throw FileSystemException -void write(const QJsonObject &object, const QString &filename); +void write(const QJsonObject& object, const QString& filename); /// @throw FileSystemException -void write(const QJsonArray &array, const QString &filename); +void write(const QJsonArray& array, const QString& filename); -QByteArray toText(const QJsonObject &obj); -QByteArray toText(const QJsonArray &array); +QByteArray toText(const QJsonObject& obj); +QByteArray toText(const QJsonArray& array); /// @throw JsonException -QJsonDocument requireDocument(const QByteArray &data, const QString &what = "Document"); +QJsonDocument requireDocument(const QByteArray& data, const QString& what = "Document"); /// @throw JsonException -QJsonDocument requireDocument(const QString &filename, const QString &what = "Document"); +QJsonDocument requireDocument(const QString& filename, const QString& what = "Document"); /// @throw JsonException -QJsonObject requireObject(const QJsonDocument &doc, const QString &what = "Document"); +QJsonObject requireObject(const QJsonDocument& doc, const QString& what = "Document"); /// @throw JsonException -QJsonArray requireArray(const QJsonDocument &doc, const QString &what = "Document"); +QJsonArray requireArray(const QJsonDocument& doc, const QString& what = "Document"); /////////////////// WRITING //////////////////// -void writeString(QJsonObject & to, const QString &key, const QString &value); -void writeStringList(QJsonObject & to, const QString &key, const QStringList &values); +void writeString(QJsonObject& to, const QString& key, const QString& value); +void writeStringList(QJsonObject& to, const QString& key, const QStringList& values); -template -QJsonValue toJson(const T &t) +template +QJsonValue toJson(const T& t) { return QJsonValue(t); } -template<> -QJsonValue toJson(const QUrl &url); -template<> -QJsonValue toJson(const QByteArray &data); -template<> -QJsonValue toJson(const QDateTime &datetime); -template<> -QJsonValue toJson(const QDir &dir); -template<> -QJsonValue toJson(const QUuid &uuid); -template<> -QJsonValue toJson(const QVariant &variant); +template <> +QJsonValue toJson(const QUrl& url); +template <> +QJsonValue toJson(const QByteArray& data); +template <> +QJsonValue toJson(const QDateTime& datetime); +template <> +QJsonValue toJson(const QDir& dir); +template <> +QJsonValue toJson(const QUuid& uuid); +template <> +QJsonValue toJson(const QVariant& variant); -template -QJsonArray toJsonArray(const QList &container) +template +QJsonArray toJsonArray(const QList& container) { QJsonArray array; - for (const T item : container) - { + for (const T item : container) { array.append(toJson(item)); } return array; @@ -112,106 +109,110 @@ QJsonArray toJsonArray(const QList &container) /// @throw JsonException template -T requireIsType(const QJsonValue &value, const QString &what = "Value"); +T requireIsType(const QJsonValue& value, const QString& what = "Value"); /// @throw JsonException -template<> double requireIsType(const QJsonValue &value, const QString &what); +template <> +double requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> bool requireIsType(const QJsonValue &value, const QString &what); +template <> +bool requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> int requireIsType(const QJsonValue &value, const QString &what); +template <> +int requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QJsonObject requireIsType(const QJsonValue &value, const QString &what); +template <> +QJsonObject requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QJsonArray requireIsType(const QJsonValue &value, const QString &what); +template <> +QJsonArray requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QJsonValue requireIsType(const QJsonValue &value, const QString &what); +template <> +QJsonValue requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QByteArray requireIsType(const QJsonValue &value, const QString &what); +template <> +QByteArray requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QDateTime requireIsType(const QJsonValue &value, const QString &what); +template <> +QDateTime requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QVariant requireIsType(const QJsonValue &value, const QString &what); +template <> +QVariant requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QString requireIsType(const QJsonValue &value, const QString &what); +template <> +QString requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QUuid requireIsType(const QJsonValue &value, const QString &what); +template <> +QUuid requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QDir requireIsType(const QJsonValue &value, const QString &what); +template <> +QDir requireIsType(const QJsonValue& value, const QString& what); /// @throw JsonException -template<> QUrl requireIsType(const QJsonValue &value, const QString &what); +template <> +QUrl requireIsType(const QJsonValue& value, const QString& what); // the following functions are higher level functions, that make use of the above functions for // type conversion template -T ensureIsType(const QJsonValue &value, const T default_ = T(), const QString &what = "Value") +T ensureIsType(const QJsonValue& value, const T default_ = T(), const QString& what = "Value") { - if (value.isUndefined() || value.isNull()) - { + if (value.isUndefined() || value.isNull()) { return default_; } - try - { + try { return requireIsType(value, what); - } - catch (const JsonException &) - { + } catch (const JsonException&) { return default_; } } /// @throw JsonException template -T requireIsType(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") +T requireIsType(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); - if (!parent.contains(key)) - { + if (!parent.contains(key)) { throw JsonException(localWhat + "s parent does not contain " + localWhat); } return requireIsType(parent.value(key), localWhat); } template -T ensureIsType(const QJsonObject &parent, const QString &key, const T default_ = T(), const QString &what = "__placeholder__") +T ensureIsType(const QJsonObject& parent, const QString& key, const T default_ = T(), const QString& what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); - if (!parent.contains(key)) - { + if (!parent.contains(key)) { return default_; } return ensureIsType(parent.value(key), default_, localWhat); } template -QVector requireIsArrayOf(const QJsonDocument &doc) +QVector requireIsArrayOf(const QJsonDocument& doc) { const QJsonArray array = requireArray(doc); QVector out; - for (const QJsonValue val : array) - { + for (const QJsonValue val : array) { out.append(requireIsType(val, "Document")); } return out; } template -QVector ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value") +QVector ensureIsArrayOf(const QJsonValue& value, const QString& what = "Value") { const QJsonArray array = ensureIsType(value, QJsonArray(), what); QVector out; - for (const QJsonValue val : array) - { + for (const QJsonValue val : array) { out.append(requireIsType(val, what)); } return out; } template -QVector ensureIsArrayOf(const QJsonValue &value, const QVector default_, const QString &what = "Value") +QVector ensureIsArrayOf(const QJsonValue& value, const QVector default_, const QString& what = "Value") { - if (value.isUndefined()) - { + if (value.isUndefined()) { return default_; } return ensureIsArrayOf(value, what); @@ -219,45 +220,46 @@ QVector ensureIsArrayOf(const QJsonValue &value, const QVector default_, c /// @throw JsonException template -QVector requireIsArrayOf(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") +QVector requireIsArrayOf(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); - if (!parent.contains(key)) - { + if (!parent.contains(key)) { throw JsonException(localWhat + "s parent does not contain " + localWhat); } return ensureIsArrayOf(parent.value(key), localWhat); } template -QVector ensureIsArrayOf(const QJsonObject &parent, const QString &key, - const QVector &default_ = QVector(), const QString &what = "__placeholder__") +QVector ensureIsArrayOf(const QJsonObject& parent, + const QString& key, + const QVector& default_ = QVector(), + const QString& what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); - if (!parent.contains(key)) - { + if (!parent.contains(key)) { return default_; } return ensureIsArrayOf(parent.value(key), default_, localWhat); } // this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers -#define JSON_HELPERFUNCTIONS(NAME, TYPE) \ - inline TYPE require##NAME(const QJsonValue &value, const QString &what = "Value") \ - { \ - return requireIsType(value, what); \ - } \ - inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_ = TYPE(), const QString &what = "Value") \ - { \ - return ensureIsType(value, default_, what); \ - } \ - inline TYPE require##NAME(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") \ - { \ - return requireIsType(parent, key, what); \ - } \ - inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_ = TYPE(), const QString &what = "__placeholder") \ - { \ - return ensureIsType(parent, key, default_, what); \ +#define JSON_HELPERFUNCTIONS(NAME, TYPE) \ + inline TYPE require##NAME(const QJsonValue& value, const QString& what = "Value") \ + { \ + return requireIsType(value, what); \ + } \ + inline TYPE ensure##NAME(const QJsonValue& value, const TYPE default_ = TYPE(), const QString& what = "Value") \ + { \ + return ensureIsType(value, default_, what); \ + } \ + inline TYPE require##NAME(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__") \ + { \ + return requireIsType(parent, key, what); \ + } \ + inline TYPE ensure##NAME(const QJsonObject& parent, const QString& key, const TYPE default_ = TYPE(), \ + const QString& what = "__placeholder") \ + { \ + return ensureIsType(parent, key, default_, what); \ } JSON_HELPERFUNCTIONS(Array, QJsonArray) @@ -276,5 +278,5 @@ JSON_HELPERFUNCTIONS(Variant, QVariant) #undef JSON_HELPERFUNCTIONS -} +} // namespace Json using JSONValidationError = Json::JsonException; diff --git a/launcher/KonamiCode.cpp b/launcher/KonamiCode.cpp index 46a2a0b2e..f9ec3b89d 100644 --- a/launcher/KonamiCode.cpp +++ b/launcher/KonamiCode.cpp @@ -1,42 +1,26 @@ #include "KonamiCode.h" -#include #include +#include namespace { -const std::array konamiCode = -{ - { - Qt::Key_Up, Qt::Key_Up, - Qt::Key_Down, Qt::Key_Down, - Qt::Key_Left, Qt::Key_Right, - Qt::Key_Left, Qt::Key_Right, - Qt::Key_B, Qt::Key_A - } -}; -} - -KonamiCode::KonamiCode(QObject* parent) : QObject(parent) -{ +const std::array konamiCode = { { Qt::Key_Up, Qt::Key_Up, Qt::Key_Down, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, + Qt::Key_Left, Qt::Key_Right, Qt::Key_B, Qt::Key_A } }; } +KonamiCode::KonamiCode(QObject* parent) : QObject(parent) {} void KonamiCode::input(QEvent* event) { - if( event->type() == QEvent::KeyPress ) - { - QKeyEvent *keyEvent = static_cast( event ); + if (event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); auto key = Qt::Key(keyEvent->key()); - if(key == konamiCode[m_progress]) - { - m_progress ++; - } - else - { + if (key == konamiCode[m_progress]) { + m_progress++; + } else { m_progress = 0; } - if(m_progress == static_cast(konamiCode.size())) - { + if (m_progress == static_cast(konamiCode.size())) { m_progress = 0; emit triggered(); } diff --git a/launcher/KonamiCode.h b/launcher/KonamiCode.h index 3d320ae7f..5c21e2ff3 100644 --- a/launcher/KonamiCode.h +++ b/launcher/KonamiCode.h @@ -2,16 +2,15 @@ #include -class KonamiCode : public QObject -{ +class KonamiCode : public QObject { Q_OBJECT -public: - KonamiCode(QObject *parent = 0); - void input(QEvent *event); + public: + KonamiCode(QObject* parent = 0); + void input(QEvent* event); -signals: + signals: void triggered(); -private: + private: int m_progress = 0; }; diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 2b52cac0b..720f8b91b 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -34,44 +34,41 @@ */ #include "LaunchController.h" -#include "minecraft/auth/AccountList.h" #include "Application.h" +#include "minecraft/auth/AccountList.h" -#include "ui/MainWindow.h" #include "ui/InstanceWindow.h" +#include "ui/MainWindow.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/dialogs/ProfileSelectDialog.h" -#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/EditAccountDialog.h" +#include "ui/dialogs/ProfileSelectDialog.h" #include "ui/dialogs/ProfileSetupDialog.h" +#include "ui/dialogs/ProgressDialog.h" -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include +#include #include "BuildConfig.h" #include "JavaCommon.h" -#include "tasks/Task.h" -#include "minecraft/auth/AccountTask.h" #include "launch/steps/TextPrint.h" +#include "minecraft/auth/AccountTask.h" +#include "tasks/Task.h" -LaunchController::LaunchController(QObject *parent) : Task(parent) -{ -} +LaunchController::LaunchController(QObject* parent) : Task(parent) {} void LaunchController::executeTask() { - if (!m_instance) - { + if (!m_instance) { emitFailed(tr("No instance specified!")); return; } - if(!JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget)) { + if (!JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget)) { emitFailed(tr("Invalid Java arguments specified. Please fix this first.")); return; } @@ -81,32 +78,25 @@ void LaunchController::executeTask() void LaunchController::decideAccount() { - if(m_accountToUse) { + if (m_accountToUse) { return; } // Find an account to use. auto accounts = APPLICATION->accounts(); - if (accounts->count() <= 0) - { + if (accounts->count() <= 0) { // Tell the user they need to log in at least one account in order to play. - auto reply = CustomMessageBox::selectable( - m_parentWidget, - tr("No Accounts"), - tr("In order to play Minecraft, you must have at least one Microsoft or Mojang " - "account logged in. Mojang accounts can only be used offline. " - "Would you like to open the account manager to add an account now?"), - QMessageBox::Information, - QMessageBox::Yes | QMessageBox::No - )->exec(); + auto reply = CustomMessageBox::selectable(m_parentWidget, tr("No Accounts"), + tr("In order to play Minecraft, you must have at least one Microsoft or Mojang " + "account logged in. Mojang accounts can only be used offline. " + "Would you like to open the account manager to add an account now?"), + QMessageBox::Information, QMessageBox::Yes | QMessageBox::No) + ->exec(); - if (reply == QMessageBox::Yes) - { + if (reply == QMessageBox::Yes) { // Open the account manager. APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts"); - } - else if (reply == QMessageBox::No) - { + } else if (reply == QMessageBox::No) { // Do not open "profile select" dialog. return; } @@ -121,14 +111,10 @@ void LaunchController::decideAccount() m_accountToUse = accounts->at(instanceAccountIndex); } - if (!m_accountToUse) - { + if (!m_accountToUse) { // If no default account is set, ask the user which one to use. - ProfileSelectDialog selectDialog( - tr("Which account would you like to use?"), - ProfileSelectDialog::GlobalDefaultCheckbox, - m_parentWidget - ); + ProfileSelectDialog selectDialog(tr("Which account would you like to use?"), ProfileSelectDialog::GlobalDefaultCheckbox, + m_parentWidget); selectDialog.exec(); @@ -142,13 +128,12 @@ void LaunchController::decideAccount() } } - -void LaunchController::login() { +void LaunchController::login() +{ decideAccount(); // if no account is selected, we bail - if (!m_accountToUse) - { + if (!m_accountToUse) { emitFailed(tr("No account selected for launch.")); return; } @@ -157,15 +142,11 @@ void LaunchController::login() { bool tryagain = true; unsigned int tries = 0; - while (tryagain) - { + while (tryagain) { if (tries > 0 && tries % 3 == 0) { - auto result = QMessageBox::question( - m_parentWidget, - tr("Continue launch?"), - tr("It looks like we couldn't launch after %1 tries. Do you want to continue trying?") - .arg(tries) - ); + auto result = + QMessageBox::question(m_parentWidget, tr("Continue launch?"), + tr("It looks like we couldn't launch after %1 tries. Do you want to continue trying?").arg(tries)); if (result == QMessageBox::No) { emitAborted(); @@ -179,60 +160,48 @@ void LaunchController::login() { m_accountToUse->fillSession(m_session); // Launch immediately in true offline mode - if(m_accountToUse->isOffline()) { + if (m_accountToUse->isOffline()) { launchInstance(); return; } - switch(m_accountToUse->accountState()) { + switch (m_accountToUse->accountState()) { case AccountState::Offline: { m_session->wants_online = false; } /* fallthrough */ case AccountState::Online: { - if(!m_session->wants_online) { + if (!m_session->wants_online) { // we ask the user for a player name bool ok = false; QString message = tr("Choose your offline mode player name."); - if(m_session->demo) { + if (m_session->demo) { message = tr("Choose your demo mode player name."); } QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString(); QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName; - QString name = QInputDialog::getText( - m_parentWidget, - tr("Player name"), - message, - QLineEdit::Normal, - usedname, - &ok - ); - if (!ok) - { + QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), message, QLineEdit::Normal, usedname, &ok); + if (!ok) { tryagain = false; break; } - if (name.length()) - { + if (name.length()) { usedname = name; APPLICATION->settings()->set("LastOfflinePlayerName", usedname); } m_session->MakeOffline(usedname); // offline flavored game from here :3 } - if(m_accountToUse->ownsMinecraft()) { - if(!m_accountToUse->hasProfile()) { + if (m_accountToUse->ownsMinecraft()) { + if (!m_accountToUse->hasProfile()) { // Now handle setting up a profile name here... ProfileSetupDialog dialog(m_accountToUse, m_parentWidget); - if (dialog.exec() == QDialog::Accepted) - { + if (dialog.exec() == QDialog::Accepted) { tryagain = true; continue; - } - else - { + } else { emitFailed(tr("Received undetermined session status during login.")); return; } @@ -240,24 +209,24 @@ void LaunchController::login() { // we own Minecraft, there is a profile, it's all ready to go! launchInstance(); return; - } - else { + } else { // play demo ? QMessageBox box(m_parentWidget); box.setWindowTitle(tr("Play demo?")); - box.setText(tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play the demo?")); + box.setText( + tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play " + "the demo?")); box.setIcon(QMessageBox::Warning); auto demoButton = box.addButton(tr("Play Demo"), QMessageBox::ButtonRole::YesRole); auto cancelButton = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::NoRole); box.setDefaultButton(cancelButton); box.exec(); - if(box.clickedButton() == demoButton) { + if (box.clickedButton() == demoButton) { // play demo here m_session->MakeDemo(); launchInstance(); - } - else { + } else { emitFailed(tr("Launch cancelled - account does not own Minecraft.")); } } @@ -272,8 +241,7 @@ void LaunchController::login() { case AccountState::Working: { // refresh is in progress, we need to wait for it to finish to proceed. ProgressDialog progDialog(m_parentWidget); - if (m_online) - { + if (m_online) { progDialog.setSkipButton(true, tr("Play Offline")); } auto task = m_accountToUse->currentTask(); @@ -288,37 +256,24 @@ void LaunchController::login() { */ case AccountState::Expired: { auto errorString = tr("The account has expired and needs to be logged into manually again."); - QMessageBox::warning( - m_parentWidget, - tr("Account refresh failed"), - errorString, - QMessageBox::StandardButton::Ok, - QMessageBox::StandardButton::Ok - ); + QMessageBox::warning(m_parentWidget, tr("Account refresh failed"), errorString, QMessageBox::StandardButton::Ok, + QMessageBox::StandardButton::Ok); emitFailed(errorString); return; } case AccountState::Disabled: { auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again."); - QMessageBox::warning( - m_parentWidget, - tr("Client identification changed"), - errorString, - QMessageBox::StandardButton::Ok, - QMessageBox::StandardButton::Ok - ); + QMessageBox::warning(m_parentWidget, tr("Client identification changed"), errorString, QMessageBox::StandardButton::Ok, + QMessageBox::StandardButton::Ok); emitFailed(errorString); return; } case AccountState::Gone: { - auto errorString = tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account you migrated this one to."); - QMessageBox::warning( - m_parentWidget, - tr("Account gone"), - errorString, - QMessageBox::StandardButton::Ok, - QMessageBox::StandardButton::Ok - ); + auto errorString = + tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account " + "you migrated this one to."); + QMessageBox::warning(m_parentWidget, tr("Account gone"), errorString, QMessageBox::StandardButton::Ok, + QMessageBox::StandardButton::Ok); emitFailed(errorString); return; } @@ -332,48 +287,45 @@ void LaunchController::launchInstance() Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL"); Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL"); - if(!m_instance->reloadSettings()) - { + if (!m_instance->reloadSettings()) { QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't load the instance profile.")); emitFailed(tr("Couldn't load the instance profile.")); return; } m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin); - if (!m_launcher) - { + if (!m_launcher) { emitFailed(tr("Couldn't instantiate a launcher.")); return; } - auto console = qobject_cast(m_parentWidget); + auto console = qobject_cast(m_parentWidget); auto showConsole = m_instance->settings()->get("ShowConsole").toBool(); - if(!console && showConsole) - { + if (!console && showConsole) { APPLICATION->showInstanceWindow(m_instance); } connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded); - connect(m_launcher.get(), &LaunchTask::failed, this, &LaunchController::onFailed); + connect(m_launcher.get(), &LaunchTask::failed, this, &LaunchController::onFailed); connect(m_launcher.get(), &LaunchTask::requestProgress, this, &LaunchController::onProgressRequested); // Prepend Online and Auth Status QString online_mode; - if(m_session->wants_online) { + if (m_session->wants_online) { online_mode = "online"; // Prepend Server Status - QStringList servers = {"authserver.mojang.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com"}; + QStringList servers = { "authserver.mojang.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" }; QString resolved_servers = ""; QHostInfo host_info; - for(QString server : servers) { + 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()) { + if (!host_info.addresses().isEmpty()) { + for (QHostAddress address : host_info.addresses()) { resolved_servers = resolved_servers + address.toString(); - if(!host_info.addresses().endsWith(address)) { + if (!host_info.addresses().endsWith(address)) { resolved_servers = resolved_servers + ", "; } } @@ -387,11 +339,13 @@ void LaunchController::launchInstance() online_mode = m_demo ? "demo" : "offline"; } - m_launcher->prependStep(makeShared(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher)); + m_launcher->prependStep( + makeShared(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher)); // Prepend Version { - auto versionString = QString("%1 version: %2 (%3)").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM); + auto versionString = QString("%1 version: %2 (%3)") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM); m_launcher->prependStep(makeShared(m_launcher.get(), versionString + "\n\n", MessageLevel::Launcher)); } m_launcher->start(); @@ -399,28 +353,26 @@ void LaunchController::launchInstance() void LaunchController::readyForLaunch() { - if (!m_profiler) - { + if (!m_profiler) { m_launcher->proceed(); return; } QString error; - if (!m_profiler->check(&error)) - { + if (!m_profiler->check(&error)) { m_launcher->abort(); QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't start profiler: %1").arg(error)); emitFailed("Profiler startup failed!"); return; } - BaseProfiler *profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this); + BaseProfiler* profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this); - connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString & message) - { + connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString& message) { QMessageBox msg; msg.setText(tr("The game launch is delayed until you press the " - "button. This is the right time to setup the profiler, as the " - "profiler server is running now.\n\n%1").arg(message)); + "button. This is the right time to setup the profiler, as the " + "profiler server is running now.\n\n%1") + .arg(message)); msg.setWindowTitle(tr("Waiting.")); msg.setIcon(QMessageBox::Information); msg.addButton(tr("Launch"), QMessageBox::AcceptRole); @@ -428,8 +380,7 @@ void LaunchController::readyForLaunch() msg.exec(); m_launcher->proceed(); }); - connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString & message) - { + connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString& message) { QMessageBox msg; msg.setText(tr("Couldn't start the profiler: %1").arg(message)); msg.setWindowTitle(tr("Error")); @@ -450,8 +401,7 @@ void LaunchController::onSucceeded() void LaunchController::onFailed(QString reason) { - if(m_instance->settings()->get("ShowConsoleOnError").toBool()) - { + if (m_instance->settings()->get("ShowConsoleOnError").toBool()) { APPLICATION->showInstanceWindow(m_instance, "console"); } emitFailed(reason); @@ -467,21 +417,18 @@ void LaunchController::onProgressRequested(Task* task) bool LaunchController::abort() { - if(!m_launcher) - { + if (!m_launcher) { return true; } - if(!m_launcher->canAbort()) - { + if (!m_launcher->canAbort()) { return false; } - auto response = CustomMessageBox::selectable( - m_parentWidget, tr("Kill Minecraft?"), - tr("This can cause the instance to get corrupted and should only be used if Minecraft " - "is frozen for some reason"), - QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec(); - if (response == QMessageBox::Yes) - { + auto response = CustomMessageBox::selectable(m_parentWidget, tr("Kill Minecraft?"), + tr("This can cause the instance to get corrupted and should only be used if Minecraft " + "is frozen for some reason"), + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) + ->exec(); + if (response == QMessageBox::Yes) { return m_launcher->abort(); } return false; diff --git a/launcher/LaunchController.h b/launcher/LaunchController.h index af6c98d18..b4138a062 100644 --- a/launcher/LaunchController.h +++ b/launcher/LaunchController.h @@ -34,81 +34,61 @@ */ #pragma once -#include #include #include +#include -#include "minecraft/launch/MinecraftServerTarget.h" #include "minecraft/auth/MinecraftAccount.h" +#include "minecraft/launch/MinecraftServerTarget.h" class InstanceWindow; -class LaunchController: public Task -{ +class LaunchController : public Task { Q_OBJECT -public: + public: void executeTask() override; - LaunchController(QObject * parent = nullptr); + LaunchController(QObject* parent = nullptr); virtual ~LaunchController(){}; - void setInstance(InstancePtr instance) { - m_instance = instance; - } + void setInstance(InstancePtr instance) { m_instance = instance; } - InstancePtr instance() { - return m_instance; - } + InstancePtr instance() { return m_instance; } - void setOnline(bool online) { - m_online = online; - } + void setOnline(bool online) { m_online = online; } - void setDemo(bool demo) { - m_demo = demo; - } + void setDemo(bool demo) { m_demo = demo; } - void setProfiler(BaseProfilerFactory *profiler) { - m_profiler = profiler; - } + void setProfiler(BaseProfilerFactory* profiler) { m_profiler = profiler; } - void setParentWidget(QWidget * widget) { - m_parentWidget = widget; - } + void setParentWidget(QWidget* widget) { m_parentWidget = widget; } - void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { - m_serverToJoin = std::move(serverToJoin); - } + void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { m_serverToJoin = std::move(serverToJoin); } - void setAccountToUse(MinecraftAccountPtr accountToUse) { - m_accountToUse = std::move(accountToUse); - } + void setAccountToUse(MinecraftAccountPtr accountToUse) { m_accountToUse = std::move(accountToUse); } - QString id() - { - return m_instance->id(); - } + QString id() { return m_instance->id(); } bool abort() override; -private: + private: void login(); void launchInstance(); void decideAccount(); -private slots: + private slots: void readyForLaunch(); void onSucceeded(); void onFailed(QString reason); - void onProgressRequested(Task *task); + void onProgressRequested(Task* task); -private: - BaseProfilerFactory *m_profiler = nullptr; + private: + BaseProfilerFactory* m_profiler = nullptr; bool m_online = true; bool m_demo = false; InstancePtr m_instance; - QWidget * m_parentWidget = nullptr; - InstanceWindow *m_console = nullptr; + QWidget* m_parentWidget = nullptr; + InstanceWindow* m_console = nullptr; MinecraftAccountPtr m_accountToUse = nullptr; AuthSessionPtr m_session; shared_qobject_ptr m_launcher; diff --git a/launcher/LoggedProcess.cpp b/launcher/LoggedProcess.cpp index d70f6d005..6978777e1 100644 --- a/launcher/LoggedProcess.cpp +++ b/launcher/LoggedProcess.cpp @@ -2,7 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022,2023 Sefa Eyeoglu - * Copyright (c) 2023 flowln + * Copyright (c) 2023 flowln * * 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 @@ -39,7 +39,7 @@ #include #include "MessageLevel.h" -LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent) +LoggedProcess::LoggedProcess(QObject* parent) : QProcess(parent) { // QProcess has a strange interface... let's map a lot of those into a few. connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut); @@ -51,8 +51,7 @@ LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent) LoggedProcess::~LoggedProcess() { - if(m_is_detachable) - { + if (m_is_detachable) { setProcessState(QProcess::NotRunning); } } @@ -95,39 +94,31 @@ void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status) m_exit_code = exit_code; // based on state, send signals - if (!m_is_aborting) - { - if (status == QProcess::NormalExit) - { + if (!m_is_aborting) { + if (status == QProcess::NormalExit) { //: Message displayed on instance exit - emit log({tr("Process exited with code %1.").arg(exit_code)}, MessageLevel::Launcher); + emit log({ tr("Process exited with code %1.").arg(exit_code) }, MessageLevel::Launcher); changeState(LoggedProcess::Finished); - } - else - { + } else { //: Message displayed on instance crashed - if(exit_code == -1) - emit log({tr("Process crashed.")}, MessageLevel::Launcher); + if (exit_code == -1) + emit log({ tr("Process crashed.") }, MessageLevel::Launcher); else - emit log({tr("Process crashed with exitcode %1.").arg(exit_code)}, MessageLevel::Launcher); + emit log({ tr("Process crashed with exitcode %1.").arg(exit_code) }, MessageLevel::Launcher); changeState(LoggedProcess::Crashed); } - } - else - { + } else { //: Message displayed after the instance exits due to kill request - emit log({tr("Process was killed by user.")}, MessageLevel::Error); + emit log({ tr("Process was killed by user.") }, MessageLevel::Error); changeState(LoggedProcess::Aborted); } } void LoggedProcess::on_error(QProcess::ProcessError error) { - switch(error) - { - case QProcess::FailedToStart: - { - emit log({tr("The process failed to start.")}, MessageLevel::Fatal); + switch (error) { + case QProcess::FailedToStart: { + emit log({ tr("The process failed to start.") }, MessageLevel::Fatal); changeState(LoggedProcess::FailedToStart); break; } @@ -154,7 +145,7 @@ int LoggedProcess::exitCode() const void LoggedProcess::changeState(LoggedProcess::State state) { - if(state == m_state) + if (state == m_state) return; m_state = state; emit stateChanged(m_state); @@ -167,24 +158,19 @@ LoggedProcess::State LoggedProcess::state() const void LoggedProcess::on_stateChange(QProcess::ProcessState state) { - switch(state) - { + switch (state) { case QProcess::NotRunning: - break; // let's not - there are too many that handle this already. - case QProcess::Starting: - { - if(m_state != LoggedProcess::NotRunning) - { - qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Starting; + break; // let's not - there are too many that handle this already. + case QProcess::Starting: { + if (m_state != LoggedProcess::NotRunning) { + qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Starting; } changeState(LoggedProcess::Starting); return; } - case QProcess::Running: - { - if(m_state != LoggedProcess::Starting) - { - qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Running; + case QProcess::Running: { + if (m_state != LoggedProcess::Starting) { + qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Running; } changeState(LoggedProcess::Running); return; diff --git a/launcher/LoggedProcess.h b/launcher/LoggedProcess.h index af3ed79f4..46bdaa830 100644 --- a/launcher/LoggedProcess.h +++ b/launcher/LoggedProcess.h @@ -43,22 +43,12 @@ * This is a basic process. * It has line-based logging support and hides some of the nasty bits. */ -class LoggedProcess : public QProcess -{ -Q_OBJECT -public: - enum State - { - NotRunning, - Starting, - FailedToStart, - Running, - Finished, - Crashed, - Aborted - }; +class LoggedProcess : public QProcess { + Q_OBJECT + public: + enum State { NotRunning, Starting, FailedToStart, Running, Finished, Crashed, Aborted }; -public: + public: explicit LoggedProcess(QObject* parent = 0); virtual ~LoggedProcess(); @@ -67,30 +57,29 @@ public: void setDetachable(bool detachable); -signals: + signals: void log(QStringList lines, MessageLevel::Enum level); void stateChanged(LoggedProcess::State state); -public slots: + public slots: /** * @brief kill the process - equivalent to kill -9 */ void kill(); - -private slots: + private slots: void on_stdErr(); void on_stdOut(); void on_exit(int exit_code, QProcess::ExitStatus status); void on_error(QProcess::ProcessError error); void on_stateChange(QProcess::ProcessState); -private: + private: void changeState(LoggedProcess::State state); QStringList reprocess(const QByteArray& data, QTextDecoder& decoder); -private: + private: QTextDecoder m_err_decoder = QTextDecoder(QTextCodec::codecForLocale()); QTextDecoder m_out_decoder = QTextDecoder(QTextCodec::codecForLocale()); QString m_leftover_line; diff --git a/launcher/MMCTime.cpp b/launcher/MMCTime.cpp index 1702ec066..3972dbd53 100644 --- a/launcher/MMCTime.cpp +++ b/launcher/MMCTime.cpp @@ -17,30 +17,29 @@ #include -#include #include +#include #include -QString Time::prettifyDuration(int64_t duration) { - int seconds = (int) (duration % 60); +QString Time::prettifyDuration(int64_t duration) +{ + int seconds = (int)(duration % 60); duration /= 60; - int minutes = (int) (duration % 60); + int minutes = (int)(duration % 60); duration /= 60; - int hours = (int) (duration % 24); - int days = (int) (duration / 24); - if((hours == 0)&&(days == 0)) - { + int hours = (int)(duration % 24); + int days = (int)(duration / 24); + if ((hours == 0) && (days == 0)) { return QObject::tr("%1min %2s").arg(minutes).arg(seconds); } - if (days == 0) - { + if (days == 0) { return QObject::tr("%1h %2min").arg(hours).arg(minutes); } return QObject::tr("%1d %2h %3min").arg(days).arg(hours).arg(minutes); } -QString Time::humanReadableDuration(double duration, int precision) { - +QString Time::humanReadableDuration(double duration, int precision) +{ using days = std::chrono::duration>; QString outStr; @@ -48,10 +47,10 @@ QString Time::humanReadableDuration(double duration, int precision) { bool neg = false; if (duration < 0) { - neg = true; // flag - duration *= -1; // invert + neg = true; // flag + duration *= -1; // invert } - + auto std_duration = std::chrono::duration(duration); auto d = std::chrono::duration_cast(std_duration); std_duration -= d; @@ -78,22 +77,22 @@ QString Time::humanReadableDuration(double duration, int precision) { if (hc) { if (dc) os << " "; - os << qSetFieldWidth(2) << hc << QObject::tr("h"); // hours + os << qSetFieldWidth(2) << hc << QObject::tr("h"); // hours } if (mc) { if (dc || hc) os << " "; - os << qSetFieldWidth(2) << mc << QObject::tr("m"); // minutes + os << qSetFieldWidth(2) << mc << QObject::tr("m"); // minutes } if (dc || hc || mc || sc) { if (dc || hc || mc) os << " "; - os << qSetFieldWidth(2) << sc << QObject::tr("s"); // seconds + os << qSetFieldWidth(2) << sc << QObject::tr("s"); // seconds } if ((msc && (precision > 0)) || !(dc || hc || mc || sc)) { if (dc || hc || mc || sc) os << " "; - os << qSetFieldWidth(0) << qSetRealNumberPrecision(precision) << msc << QObject::tr("ms"); // miliseconds + os << qSetFieldWidth(0) << qSetRealNumberPrecision(precision) << msc << QObject::tr("ms"); // miliseconds } os.flush(); diff --git a/launcher/MMCTime.h b/launcher/MMCTime.h index 6a5780b44..b7d34b5d8 100644 --- a/launcher/MMCTime.h +++ b/launcher/MMCTime.h @@ -25,10 +25,10 @@ QString prettifyDuration(int64_t duration); /** * @brief Returns a string with short form time duration ie. `2days 1h3m4s56.0ms`. * miliseconds are only included if `precision` is greater than 0. - * + * * @param duration a number of seconds as floating point * @param precision number of decmial points to display on fractons of a second, defualts to 0. - * @return QString + * @return QString */ QString humanReadableDuration(double duration, int precision = 0); -} +} // namespace Time diff --git a/launcher/MTPixmapCache.h b/launcher/MTPixmapCache.h index 65cbe032a..1a3e52160 100644 --- a/launcher/MTPixmapCache.h +++ b/launcher/MTPixmapCache.h @@ -1,10 +1,10 @@ #pragma once #include +#include #include #include #include -#include #define GET_TYPE() \ Qt::ConnectionType type; \ @@ -94,8 +94,8 @@ class PixmapCache final : public QObject { return true; } - /** - * Mark that a cache miss occurred because of a eviction if too many of these occur too fast the cache size is increased + /** + * Mark that a cache miss occurred because of a eviction if too many of these occur too fast the cache size is increased * @return if the cache size was increased */ bool _markCacheMissByEviciton() diff --git a/launcher/MangoHud.cpp b/launcher/MangoHud.cpp index 90e48e298..5758da3aa 100644 --- a/launcher/MangoHud.cpp +++ b/launcher/MangoHud.cpp @@ -16,15 +16,15 @@ * along with this program. If not, see . */ -#include #include #include +#include #include #include -#include "MangoHud.h" #include "FileSystem.h" #include "Json.h" +#include "MangoHud.h" namespace MangoHud { diff --git a/launcher/Markdown.h b/launcher/Markdown.h index 6b261e60c..f91a016bd 100644 --- a/launcher/Markdown.h +++ b/launcher/Markdown.h @@ -18,7 +18,7 @@ #pragma once -#include #include +#include QString markdownToHTML(const QString& markdown); \ No newline at end of file diff --git a/launcher/MessageLevel.cpp b/launcher/MessageLevel.cpp index 135ef4632..116e70c4b 100644 --- a/launcher/MessageLevel.cpp +++ b/launcher/MessageLevel.cpp @@ -22,12 +22,11 @@ MessageLevel::Enum MessageLevel::getLevel(const QString& levelName) return MessageLevel::Unknown; } -MessageLevel::Enum MessageLevel::fromLine(QString &line) +MessageLevel::Enum MessageLevel::fromLine(QString& line) { // Level prefix int endmark = line.indexOf("]!"); - if (line.startsWith("!![") && endmark != -1) - { + if (line.startsWith("!![") && endmark != -1) { auto level = MessageLevel::getLevel(line.left(endmark).mid(3)); line = line.mid(endmark + 2); return level; diff --git a/launcher/MessageLevel.h b/launcher/MessageLevel.h index 227ad25d8..fd12583f2 100644 --- a/launcher/MessageLevel.h +++ b/launcher/MessageLevel.h @@ -6,23 +6,21 @@ * @brief the MessageLevel Enum * defines what level a log message is */ -namespace MessageLevel -{ -enum Enum -{ - Unknown, /**< No idea what this is or where it came from */ - StdOut, /**< Undetermined stderr messages */ - StdErr, /**< Undetermined stdout messages */ +namespace MessageLevel { +enum Enum { + Unknown, /**< No idea what this is or where it came from */ + StdOut, /**< Undetermined stderr messages */ + StdErr, /**< Undetermined stdout messages */ Launcher, /**< Launcher Messages */ - Debug, /**< Debug Messages */ - Info, /**< Info Messages */ - Message, /**< Standard Messages */ - Warning, /**< Warnings */ - Error, /**< Errors */ - Fatal, /**< Fatal Errors */ + Debug, /**< Debug Messages */ + Info, /**< Info Messages */ + Message, /**< Standard Messages */ + Warning, /**< Warnings */ + Error, /**< Errors */ + Fatal, /**< Fatal Errors */ }; -MessageLevel::Enum getLevel(const QString &levelName); +MessageLevel::Enum getLevel(const QString& levelName); /* Get message level from a line. Line is modified if it was successful. */ -MessageLevel::Enum fromLine(QString &line); -} +MessageLevel::Enum fromLine(QString& line); +} // namespace MessageLevel diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h index 53edfa0b8..85d8e65e7 100644 --- a/launcher/NullInstance.h +++ b/launcher/NullInstance.h @@ -37,88 +37,38 @@ #include "BaseInstance.h" #include "launch/LaunchTask.h" -class NullInstance: public BaseInstance -{ +class NullInstance : public BaseInstance { Q_OBJECT -public: + public: NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) - :BaseInstance(globalSettings, settings, rootDir) + : BaseInstance(globalSettings, settings, rootDir) { setVersionBroken(true); } - virtual ~NullInstance() {}; - void saveNow() override - { - } - void loadSpecificSettings() override - { - setSpecificSettingsLoaded(true); - } - QString getStatusbarDescription() override - { - return tr("Unknown instance type"); - }; - QSet< QString > traits() const override - { - return {}; - }; - QString instanceConfigFolder() const override - { - return instanceRoot(); - }; - shared_qobject_ptr createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override - { - return nullptr; - } - shared_qobject_ptr< Task > createUpdateTask(Net::Mode mode) override - { - return nullptr; - } - QProcessEnvironment createEnvironment() override - { - return QProcessEnvironment(); - } - QProcessEnvironment createLaunchEnvironment() override - { - return QProcessEnvironment(); - } - QMap getVariables() override - { - return QMap(); - } - IPathMatcher::Ptr getLogFileMatcher() override - { - return nullptr; - } - QString getLogFileRoot() override - { - return instanceRoot(); - } - QString typeName() const override - { - return "Null"; - } - bool canExport() const override - { - return false; - } - bool canEdit() const override - { - return false; - } - bool canLaunch() const override - { - return false; - } + virtual ~NullInstance(){}; + void saveNow() override {} + void loadSpecificSettings() override { setSpecificSettingsLoaded(true); } + QString getStatusbarDescription() override { return tr("Unknown instance type"); }; + QSet traits() const override { return {}; }; + QString instanceConfigFolder() const override { return instanceRoot(); }; + shared_qobject_ptr createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override { return nullptr; } + shared_qobject_ptr createUpdateTask(Net::Mode mode) override { return nullptr; } + QProcessEnvironment createEnvironment() override { return QProcessEnvironment(); } + QProcessEnvironment createLaunchEnvironment() override { return QProcessEnvironment(); } + QMap getVariables() override { return QMap(); } + IPathMatcher::Ptr getLogFileMatcher() override { return nullptr; } + QString getLogFileRoot() override { return instanceRoot(); } + QString typeName() const override { return "Null"; } + bool canExport() const override { return false; } + bool canEdit() const override { return false; } + bool canLaunch() const override { return false; } QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override { QStringList out; out << "Null instance - placeholder."; return out; } - QString modsRoot() const override { - return QString(); - } + QString modsRoot() const override { return QString(); } void updateRuntimeContext() { // NOOP diff --git a/launcher/ProblemProvider.h b/launcher/ProblemProvider.h index 2d3b43380..246a8b5c6 100644 --- a/launcher/ProblemProvider.h +++ b/launcher/ProblemProvider.h @@ -3,48 +3,33 @@ #include #include -enum class ProblemSeverity -{ - None, - Warning, - Error -}; +enum class ProblemSeverity { None, Warning, Error }; -struct PatchProblem -{ +struct PatchProblem { ProblemSeverity m_severity; QString m_description; }; -class ProblemProvider -{ -public: - virtual ~ProblemProvider() {}; +class ProblemProvider { + public: + virtual ~ProblemProvider(){}; virtual const QList getProblems() const = 0; virtual ProblemSeverity getProblemSeverity() const = 0; }; -class ProblemContainer : public ProblemProvider -{ -public: - const QList getProblems() const override +class ProblemContainer : public ProblemProvider { + public: + const QList getProblems() const override { return m_problems; } + ProblemSeverity getProblemSeverity() const override { return m_problemSeverity; } + virtual void addProblem(ProblemSeverity severity, const QString& description) { - return m_problems; - } - ProblemSeverity getProblemSeverity() const override - { - return m_problemSeverity; - } - virtual void addProblem(ProblemSeverity severity, const QString &description) - { - if(severity > m_problemSeverity) - { + if (severity > m_problemSeverity) { m_problemSeverity = severity; } - m_problems.append({severity, description}); + m_problems.append({ severity, description }); } -private: + private: QList m_problems; ProblemSeverity m_problemSeverity = ProblemSeverity::None; }; diff --git a/launcher/QVariantUtils.h b/launcher/QVariantUtils.h index 7e422c3e8..91f2ad29c 100644 --- a/launcher/QVariantUtils.h +++ b/launcher/QVariantUtils.h @@ -36,35 +36,34 @@ #pragma once - -#include #include +#include namespace QVariantUtils { -template -inline QList toList(QVariant src) { +template +inline QList toList(QVariant src) +{ QVariantList variantList = src.toList(); QList list_t; list_t.reserve(variantList.size()); - for (const QVariant& v : variantList) - { + for (const QVariant& v : variantList) { list_t.append(v.value()); } - return list_t; + return list_t; } -template -inline QVariant fromList(QList val) { +template +inline QVariant fromList(QList val) +{ QVariantList variantList; variantList.reserve(val.size()); - for (const T& v : val) - { + for (const T& v : val) { variantList.append(v); } return variantList; } -} \ No newline at end of file +} // namespace QVariantUtils \ No newline at end of file diff --git a/launcher/RWStorage.h b/launcher/RWStorage.h index 3028388e2..5764d7958 100644 --- a/launcher/RWStorage.h +++ b/launcher/RWStorage.h @@ -1,13 +1,12 @@ #pragma once -#include -#include #include +#include #include +#include template -class RWStorage -{ -public: +class RWStorage { + public: void add(K key, V value) { QWriteLocker l(&lock); @@ -17,21 +16,19 @@ public: V get(K key) { QReadLocker l(&lock); - if(cache.contains(key)) - { + if (cache.contains(key)) { return cache[key]; - } - else return V(); + } else + return V(); } bool get(K key, V& value) { QReadLocker l(&lock); - if(cache.contains(key)) - { + if (cache.contains(key)) { value = cache[key]; return true; - } - else return false; + } else + return false; } bool has(K key) { @@ -41,15 +38,14 @@ public: bool stale(K key) { QReadLocker l(&lock); - if(!cache.contains(key)) + if (!cache.contains(key)) return true; return stale_entries.contains(key); } void setStale(K key) { QWriteLocker l(&lock); - if(cache.contains(key)) - { + if (cache.contains(key)) { stale_entries.insert(key); } } @@ -59,7 +55,8 @@ public: cache.clear(); stale_entries.clear(); } -private: + + private: QReadWriteLock lock; QMap cache; QSet stale_entries; diff --git a/launcher/RecursiveFileSystemWatcher.cpp b/launcher/RecursiveFileSystemWatcher.cpp index b7417cdfe..f3be1bd8f 100644 --- a/launcher/RecursiveFileSystemWatcher.cpp +++ b/launcher/RecursiveFileSystemWatcher.cpp @@ -1,25 +1,21 @@ #include "RecursiveFileSystemWatcher.h" -#include #include +#include -RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent) - : QObject(parent), m_watcher(new QFileSystemWatcher(this)) +RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject* parent) : QObject(parent), m_watcher(new QFileSystemWatcher(this)) { - connect(m_watcher, &QFileSystemWatcher::fileChanged, this, - &RecursiveFileSystemWatcher::fileChange); - connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, - &RecursiveFileSystemWatcher::directoryChange); + connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &RecursiveFileSystemWatcher::fileChange); + connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &RecursiveFileSystemWatcher::directoryChange); } -void RecursiveFileSystemWatcher::setRootDir(const QDir &root) +void RecursiveFileSystemWatcher::setRootDir(const QDir& root) { bool wasEnabled = m_isEnabled; disable(); m_root = root; setFiles(scanRecursive(m_root)); - if (wasEnabled) - { + if (wasEnabled) { enable(); } } @@ -28,16 +24,14 @@ void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles) bool wasEnabled = m_isEnabled; disable(); m_watchFiles = watchFiles; - if (wasEnabled) - { + if (wasEnabled) { enable(); } } void RecursiveFileSystemWatcher::enable() { - if (m_isEnabled) - { + if (m_isEnabled) { return; } Q_ASSERT(m_root != QDir::root()); @@ -46,8 +40,7 @@ void RecursiveFileSystemWatcher::enable() } void RecursiveFileSystemWatcher::disable() { - if (!m_isEnabled) - { + if (!m_isEnabled) { return; } m_isEnabled = false; @@ -55,57 +48,49 @@ void RecursiveFileSystemWatcher::disable() m_watcher->removePaths(m_watcher->directories()); } -void RecursiveFileSystemWatcher::setFiles(const QStringList &files) +void RecursiveFileSystemWatcher::setFiles(const QStringList& files) { - if (files != m_files) - { + if (files != m_files) { m_files = files; emit filesChanged(); } } -void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir) +void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir& dir) { m_watcher->addPath(dir.absolutePath()); - for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) - { + for (const QString& directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { addFilesToWatcherRecursive(dir.absoluteFilePath(directory)); } - if (m_watchFiles) - { - for (const QFileInfo &info : dir.entryInfoList(QDir::Files)) - { + if (m_watchFiles) { + for (const QFileInfo& info : dir.entryInfoList(QDir::Files)) { m_watcher->addPath(info.absoluteFilePath()); } } } -QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &directory) +QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory) { QStringList ret; - if(!m_matcher) - { + if (!m_matcher) { return {}; } - for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden)) - { + for (const QString& dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden)) { ret.append(scanRecursive(directory.absoluteFilePath(dir))); } - for (const QString &file : directory.entryList(QDir::Files | QDir::Hidden)) - { + for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) { auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file)); - if (m_matcher->matches(relPath)) - { + if (m_matcher->matches(relPath)) { ret.append(relPath); } } return ret; } -void RecursiveFileSystemWatcher::fileChange(const QString &path) +void RecursiveFileSystemWatcher::fileChange(const QString& path) { emit fileChanged(path); } -void RecursiveFileSystemWatcher::directoryChange(const QString &path) +void RecursiveFileSystemWatcher::directoryChange(const QString& path) { setFiles(scanRecursive(m_root)); } diff --git a/launcher/RecursiveFileSystemWatcher.h b/launcher/RecursiveFileSystemWatcher.h index cc837d603..ec3ed804e 100644 --- a/launcher/RecursiveFileSystemWatcher.h +++ b/launcher/RecursiveFileSystemWatcher.h @@ -1,61 +1,48 @@ #pragma once -#include #include +#include #include "pathmatcher/IPathMatcher.h" -class RecursiveFileSystemWatcher : public QObject -{ +class RecursiveFileSystemWatcher : public QObject { Q_OBJECT -public: - RecursiveFileSystemWatcher(QObject *parent); + public: + RecursiveFileSystemWatcher(QObject* parent); - void setRootDir(const QDir &root); - QDir rootDir() const - { - return m_root; - } + void setRootDir(const QDir& root); + QDir rootDir() const { return m_root; } // WARNING: setting this to true may be bad for performance void setWatchFiles(const bool watchFiles); - bool watchFiles() const - { - return m_watchFiles; - } + bool watchFiles() const { return m_watchFiles; } - void setMatcher(IPathMatcher::Ptr matcher) - { - m_matcher = matcher; - } + void setMatcher(IPathMatcher::Ptr matcher) { m_matcher = matcher; } - QStringList files() const - { - return m_files; - } + QStringList files() const { return m_files; } -signals: + signals: void filesChanged(); - void fileChanged(const QString &path); + void fileChanged(const QString& path); -public slots: + public slots: void enable(); void disable(); -private: + private: QDir m_root; bool m_watchFiles = false; bool m_isEnabled = false; IPathMatcher::Ptr m_matcher; - QFileSystemWatcher *m_watcher; + QFileSystemWatcher* m_watcher; QStringList m_files; - void setFiles(const QStringList &files); + void setFiles(const QStringList& files); - void addFilesToWatcherRecursive(const QDir &dir); - QStringList scanRecursive(const QDir &dir); + void addFilesToWatcherRecursive(const QDir& dir); + QStringList scanRecursive(const QDir& dir); -private slots: - void fileChange(const QString &path); - void directoryChange(const QString &path); + private slots: + void fileChange(const QString& path); + void directoryChange(const QString& path); }; diff --git a/launcher/SeparatorPrefixTree.h b/launcher/SeparatorPrefixTree.h index 7a841cb76..df9dfe579 100644 --- a/launcher/SeparatorPrefixTree.h +++ b/launcher/SeparatorPrefixTree.h @@ -1,44 +1,32 @@ #pragma once -#include #include +#include #include template -class SeparatorPrefixTree -{ -public: - SeparatorPrefixTree(QStringList paths) - { - insert(paths); - } +class SeparatorPrefixTree { + public: + SeparatorPrefixTree(QStringList paths) { insert(paths); } - SeparatorPrefixTree(bool contained = false) - { - m_contained = contained; - } + SeparatorPrefixTree(bool contained = false) { m_contained = contained; } void insert(QStringList paths) { - for(auto &path: paths) - { + for (auto& path : paths) { insert(path); } } /// insert an exact path into the tree - SeparatorPrefixTree & insert(QString path) + SeparatorPrefixTree& insert(QString path) { auto sepIndex = path.indexOf(Tseparator); - if(sepIndex == -1) - { + if (sepIndex == -1) { children[path] = SeparatorPrefixTree(true); return children[path]; - } - else - { + } else { auto prefix = path.left(sepIndex); - if(!children.contains(prefix)) - { + if (!children.contains(prefix)) { children[prefix] = SeparatorPrefixTree(false); } return children[prefix].insert(path.mid(sepIndex + 1)); @@ -56,26 +44,20 @@ public: bool covers(QString path) const { // if we found some valid node, it's good enough. the tree covers the path - if(m_contained) - { + if (m_contained) { return true; } auto sepIndex = path.indexOf(Tseparator); - if(sepIndex == -1) - { + if (sepIndex == -1) { auto found = children.find(path); - if(found == children.end()) - { + if (found == children.end()) { return false; } return (*found).covers(QString()); - } - else - { + } else { auto prefix = path.left(sepIndex); auto found = children.find(prefix); - if(found == children.end()) - { + if (found == children.end()) { return false; } return (*found).covers(path.mid(sepIndex + 1)); @@ -86,41 +68,33 @@ public: QString cover(QString path) const { // if we found some valid node, it's good enough. the tree covers the path - if(m_contained) - { + if (m_contained) { return QString(""); } auto sepIndex = path.indexOf(Tseparator); - if(sepIndex == -1) - { + if (sepIndex == -1) { auto found = children.find(path); - if(found == children.end()) - { + if (found == children.end()) { return QString(); } auto nested = (*found).cover(QString()); - if(nested.isNull()) - { + if (nested.isNull()) { return nested; } - if(nested.isEmpty()) + if (nested.isEmpty()) return path; return path + Tseparator + nested; - } - else - { + } else { auto prefix = path.left(sepIndex); auto found = children.find(prefix); - if(found == children.end()) - { + if (found == children.end()) { return QString(); } auto nested = (*found).cover(path.mid(sepIndex + 1)); - if(nested.isNull()) - { + if (nested.isNull()) { return nested; } - if(nested.isEmpty()) + if (nested.isEmpty()) return prefix; return prefix + Tseparator + nested; } @@ -130,21 +104,16 @@ public: bool exists(QString path) const { auto sepIndex = path.indexOf(Tseparator); - if(sepIndex == -1) - { + if (sepIndex == -1) { auto found = children.find(path); - if(found == children.end()) - { + if (found == children.end()) { return false; } return true; - } - else - { + } else { auto prefix = path.left(sepIndex); auto found = children.find(prefix); - if(found == children.end()) - { + if (found == children.end()) { return false; } return (*found).exists(path.mid(sepIndex + 1)); @@ -152,24 +121,19 @@ public: } /// find a node in the tree by name - const SeparatorPrefixTree * find(QString path) const + const SeparatorPrefixTree* find(QString path) const { auto sepIndex = path.indexOf(Tseparator); - if(sepIndex == -1) - { + if (sepIndex == -1) { auto found = children.find(path); - if(found == children.end()) - { + if (found == children.end()) { return nullptr; } return &(*found); - } - else - { + } else { auto prefix = path.left(sepIndex); auto found = children.find(prefix); - if(found == children.end()) - { + if (found == children.end()) { return nullptr; } return (*found).find(path.mid(sepIndex + 1)); @@ -177,70 +141,48 @@ public: } /// is this a leaf node? - bool leaf() const - { - return children.isEmpty(); - } + bool leaf() const { return children.isEmpty(); } /// is this node actually contained in the tree, or is it purely structural? - bool contained() const - { - return m_contained; - } + bool contained() const { return m_contained; } /// Remove a path from the tree - bool remove(QString path) - { - return removeInternal(path) != Failed; - } + bool remove(QString path) { return removeInternal(path) != Failed; } /// Clear all children of this node tree node - void clear() - { - children.clear(); - } + void clear() { children.clear(); } QStringList toStringList() const { QStringList collected; // collecting these is more expensive. auto iter = children.begin(); - while(iter != children.end()) - { + while (iter != children.end()) { QStringList list = iter.value().toStringList(); - for(int i = 0; i < list.size(); i++) - { + for (int i = 0; i < list.size(); i++) { list[i] = iter.key() + Tseparator + list[i]; } collected.append(list); - if((*iter).m_contained) - { + if ((*iter).m_contained) { collected.append(iter.key()); } iter++; } return collected; } -private: - enum Removal - { - Failed, - Succeeded, - HasChildren - }; + + private: + enum Removal { Failed, Succeeded, HasChildren }; Removal removeInternal(QString path = QString()) { - if(path.isEmpty()) - { - if(!m_contained) - { + if (path.isEmpty()) { + if (!m_contained) { // remove all children - we are removing a prefix clear(); return Succeeded; } m_contained = false; - if(children.size()) - { + if (children.size()) { return HasChildren; } return Succeeded; @@ -248,42 +190,32 @@ private: Removal remStatus = Failed; QString childToRemove; auto sepIndex = path.indexOf(Tseparator); - if(sepIndex == -1) - { + if (sepIndex == -1) { childToRemove = path; auto found = children.find(childToRemove); - if(found == children.end()) - { + if (found == children.end()) { return Failed; } remStatus = (*found).removeInternal(); - } - else - { + } else { childToRemove = path.left(sepIndex); auto found = children.find(childToRemove); - if(found == children.end()) - { + if (found == children.end()) { return Failed; } remStatus = (*found).removeInternal(path.mid(sepIndex + 1)); } - switch (remStatus) - { + switch (remStatus) { case Failed: - case HasChildren: - { + case HasChildren: { return remStatus; } - case Succeeded: - { + case Succeeded: { children.remove(childToRemove); - if(m_contained) - { + if (m_contained) { return HasChildren; } - if(children.size()) - { + if (children.size()) { return HasChildren; } return Succeeded; @@ -292,7 +224,7 @@ private: return Failed; } -private: - QMap> children; + private: + QMap> children; bool m_contained = false; }; diff --git a/launcher/SkinUtils.cpp b/launcher/SkinUtils.cpp index 1fe0c896d..20d3b52e7 100644 --- a/launcher/SkinUtils.cpp +++ b/launcher/SkinUtils.cpp @@ -14,17 +14,16 @@ */ #include "SkinUtils.h" -#include "net/HttpMetaCache.h" #include "Application.h" +#include "net/HttpMetaCache.h" #include -#include +#include #include #include -#include +#include -namespace SkinUtils -{ +namespace SkinUtils { /* * Given a username, return a pixmap of the cached skin (if it exists), QPixmap() otherwise */ @@ -32,11 +31,9 @@ QPixmap getFaceFromCache(QString username, int height, int width) { QFile fskin(APPLICATION->metacache()->resolveEntry("skins", username + ".png")->getFullPath()); - if (fskin.exists()) - { + if (fskin.exists()) { QPixmap skinTexture(fskin.fileName()); - if(!skinTexture.isNull()) - { + if (!skinTexture.isNull()) { QPixmap skin = QPixmap(8, 8); QPainter painter(&skin); painter.drawPixmap(0, 0, skinTexture.copy(8, 8, 8, 8)); @@ -47,4 +44,4 @@ QPixmap getFaceFromCache(QString username, int height, int width) return QPixmap(); } -} +} // namespace SkinUtils diff --git a/launcher/SkinUtils.h b/launcher/SkinUtils.h index c1f437ab0..11bc8bc6f 100644 --- a/launcher/SkinUtils.h +++ b/launcher/SkinUtils.h @@ -17,7 +17,6 @@ #include -namespace SkinUtils -{ +namespace SkinUtils { QPixmap getFaceFromCache(QString id, int height = 64, int width = 64); } diff --git a/launcher/StringUtils.h b/launcher/StringUtils.h index f90a6ac75..eac0d5a7d 100644 --- a/launcher/StringUtils.h +++ b/launcher/StringUtils.h @@ -68,15 +68,14 @@ inline QString fromStdString(string s) int naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs); /** - * @brief Truncate a url while keeping its readability py placing the `...` in the middle of the path + * @brief Truncate a url while keeping its readability py placing the `...` in the middle of the path * @param url Url to truncate * @param max_len max lenght of url in charaters * @param hard_limit if truncating the path can't get the url short enough, truncate it normaly. */ -QString truncateUrlHumanFriendly(QUrl &url, int max_len, bool hard_limit = false); +QString truncateUrlHumanFriendly(QUrl& url, int max_len, bool hard_limit = false); QString humanReadableFileSize(double bytes, bool use_si = false, int decimal_points = 1); - QString getRandomAlphaNumeric(); } // namespace StringUtils diff --git a/launcher/Usable.h b/launcher/Usable.h index a3e880f38..a75415aa6 100644 --- a/launcher/Usable.h +++ b/launcher/Usable.h @@ -12,28 +12,18 @@ class Usable; * * @see UseLock */ -class Usable -{ +class Usable { friend class UseLock; -public: - std::size_t useCount() const - { - return m_useCount; - } - bool isInUse() const - { - return m_useCount > 0; - } -protected: - virtual void decrementUses() - { - m_useCount--; - } - virtual void incrementUses() - { - m_useCount++; - } -private: + + public: + std::size_t useCount() const { return m_useCount; } + bool isInUse() const { return m_useCount > 0; } + + protected: + virtual void decrementUses() { m_useCount--; } + virtual void incrementUses() { m_useCount++; } + + private: std::size_t m_useCount = 0; }; @@ -42,19 +32,15 @@ private: * * @see Usable */ -class UseLock -{ -public: - UseLock(shared_qobject_ptr usable) - : m_usable(usable) +class UseLock { + public: + UseLock(shared_qobject_ptr usable) : m_usable(usable) { // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate. m_usable->incrementUses(); } - ~UseLock() - { - m_usable->decrementUses(); - } -private: + ~UseLock() { m_usable->decrementUses(); } + + private: shared_qobject_ptr m_usable; }; diff --git a/launcher/Version.cpp b/launcher/Version.cpp index e4311f314..511aa9c35 100644 --- a/launcher/Version.cpp +++ b/launcher/Version.cpp @@ -117,12 +117,14 @@ QDebug operator<<(QDebug debug, const Version& v) bool first = true; for (auto s : v.m_sections) { - if (!first) debug.nospace() << ", "; + if (!first) + debug.nospace() << ", "; debug.nospace() << s.m_fullString; first = false; } - - debug.nospace() << " ]" << " }"; + + debug.nospace() << " ]" + << " }"; return debug; } diff --git a/launcher/Version.h b/launcher/Version.h index 659f8e54e..51162c073 100644 --- a/launcher/Version.h +++ b/launcher/Version.h @@ -48,12 +48,12 @@ class Version { Version(QString str); Version() = default; - bool operator<(const Version &other) const; - bool operator<=(const Version &other) const; - bool operator>(const Version &other) const; - bool operator>=(const Version &other) const; - bool operator==(const Version &other) const; - bool operator!=(const Version &other) const; + bool operator<(const Version& other) const; + bool operator<=(const Version& other) const; + bool operator>(const Version& other) const; + bool operator>=(const Version& other) const; + bool operator==(const Version& other) const; + bool operator!=(const Version& other) const; QString toString() const { return m_string; } @@ -72,7 +72,7 @@ class Version { } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - auto numPart = QStringView{m_fullString}.left(cutoff); + auto numPart = QStringView{ m_fullString }.left(cutoff); #else auto numPart = m_fullString.leftRef(cutoff); #endif @@ -83,7 +83,7 @@ class Version { } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - auto stringPart = QStringView{m_fullString}.mid(cutoff); + auto stringPart = QStringView{ m_fullString }.mid(cutoff); #else auto stringPart = m_fullString.midRef(cutoff); #endif @@ -103,8 +103,14 @@ class Version { QString m_fullString; - [[nodiscard]] inline bool isAppendix() const { return m_stringPart.startsWith('+'); } - [[nodiscard]] inline bool isPreRelease() const { return m_stringPart.startsWith('-') && m_stringPart.length() > 1; } + [[nodiscard]] inline bool isAppendix() const + { + return m_stringPart.startsWith('+'); + } + [[nodiscard]] inline bool isPreRelease() const + { + return m_stringPart.startsWith('-') && m_stringPart.length() > 1; + } inline bool operator==(const Section& other) const { @@ -121,7 +127,7 @@ class Version { } inline bool operator<(const Section& other) const - { + { static auto unequal_is_less = [](Section const& non_null) -> bool { if (non_null.m_stringPart.isEmpty()) return non_null.m_numPart == 0; @@ -154,7 +160,7 @@ class Version { { return !(*this == other); } - inline bool operator>(const Section &other) const + inline bool operator>(const Section& other) const { return !(*this < other || *this == other); } @@ -166,5 +172,3 @@ class Version { void parse(); }; - - diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 63a43465c..6e0333e46 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -35,53 +35,48 @@ */ #include "VersionProxyModel.h" -#include "Application.h" -#include -#include #include #include +#include +#include +#include "Application.h" -class VersionFilterModel : public QSortFilterProxyModel -{ +class VersionFilterModel : public QSortFilterProxyModel { Q_OBJECT -public: - VersionFilterModel(VersionProxyModel *parent) : QSortFilterProxyModel(parent) + public: + VersionFilterModel(VersionProxyModel* parent) : QSortFilterProxyModel(parent) { m_parent = parent; setSortRole(BaseVersionList::SortRole); sort(0, Qt::DescendingOrder); } - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { - const auto &filters = m_parent->filters(); - const QString &search = m_parent->search(); + const auto& filters = m_parent->filters(); + const QString& search = m_parent->search(); const QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); if (!search.isEmpty() && !sourceModel()->data(idx, BaseVersionList::VersionRole).toString().contains(search, Qt::CaseInsensitive)) return false; - for (auto it = filters.begin(); it != filters.end(); ++it) - { + for (auto it = filters.begin(); it != filters.end(); ++it) { auto data = sourceModel()->data(idx, it.key()); auto match = data.toString(); - if(!it.value()->accepts(match)) - { + if (!it.value()->accepts(match)) { return false; } } return true; } - void filterChanged() - { - invalidateFilter(); - } -private: - VersionProxyModel *m_parent; + void filterChanged() { invalidateFilter(); } + + private: + VersionProxyModel* m_parent; }; -VersionProxyModel::VersionProxyModel(QObject *parent) : QAbstractProxyModel(parent) +VersionProxyModel::VersionProxyModel(QObject* parent) : QAbstractProxyModel(parent) { filterModel = new VersionFilterModel(this); connect(filterModel, &QAbstractItemModel::dataChanged, this, &VersionProxyModel::sourceDataChanged); @@ -104,19 +99,17 @@ VersionProxyModel::VersionProxyModel(QObject *parent) : QAbstractProxyModel(pare QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, int role) const { - if(section < 0 || section >= m_columns.size()) + if (section < 0 || section >= m_columns.size()) return QVariant(); - if(orientation != Qt::Horizontal) + if (orientation != Qt::Horizontal) return QVariant(); auto column = m_columns[section]; - if(role == Qt::DisplayRole) - { - switch(column) - { + if (role == Qt::DisplayRole) { + switch (column) { case Name: return tr("Version"); case ParentVersion: - return tr("Minecraft"); //FIXME: this should come from metadata + return tr("Minecraft"); // FIXME: this should come from metadata case Branch: return tr("Branch"); case Type: @@ -128,15 +121,12 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, case Time: return tr("Released"); } - } - else if(role == Qt::ToolTipRole) - { - switch(column) - { + } else if (role == Qt::ToolTipRole) { + switch (column) { case Name: return tr("The name of the version."); case ParentVersion: - return tr("Minecraft version"); //FIXME: this should come from metadata + return tr("Minecraft version"); // FIXME: this should come from metadata case Branch: return tr("The version's branch"); case Type: @@ -152,25 +142,19 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, return QVariant(); } -QVariant VersionProxyModel::data(const QModelIndex &index, int role) const +QVariant VersionProxyModel::data(const QModelIndex& index, int role) const { - if(!index.isValid()) - { + if (!index.isValid()) { return QVariant(); } auto column = m_columns[index.column()]; auto parentIndex = mapToSource(index); - switch(role) - { - case Qt::DisplayRole: - { - switch(column) - { - case Name: - { + switch (role) { + case Qt::DisplayRole: { + switch (column) { + case Name: { QString version = sourceModel()->data(parentIndex, BaseVersionList::VersionRole).toString(); - if(version == m_currentVersion) - { + if (version == m_currentVersion) { return tr("%1 (installed)").arg(version); } return version; @@ -191,18 +175,14 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return QVariant(); } } - case Qt::ToolTipRole: - { - if(column == Name && hasRecommended) - { + case Qt::ToolTipRole: { + if (column == Name && hasRecommended) { auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { + if (value.toBool()) { return tr("Recommended"); - } else if(hasLatest) { + } else if (hasLatest) { auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { + if (value.toBool()) { return tr("Latest"); } } @@ -210,32 +190,23 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); } } - case Qt::DecorationRole: - { - switch(column) - { - case Name: - { - if(hasRecommended) - { + case Qt::DecorationRole: { + switch (column) { + case Name: { + if (hasRecommended) { auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { + if (value.toBool()) { return APPLICATION->getThemedIcon("star"); - } - else if(hasLatest) - { + } else if (hasLatest) { auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { + if (value.toBool()) { return APPLICATION->getThemedIcon("bug"); } } QPixmap pixmap; QPixmapCache::find("placeholder", &pixmap); - if(!pixmap) - { - QPixmap px(16,16); + if (!pixmap) { + QPixmap px(16, 16); px.fill(Qt::transparent); QPixmapCache::insert("placeholder", px); return px; @@ -243,16 +214,13 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return pixmap; } } - default: - { + default: { return QVariant(); } } } - default: - { - if(roles.contains((BaseVersionList::ModelRoles)role)) - { + default: { + if (roles.contains((BaseVersionList::ModelRoles)role)) { return sourceModel()->data(parentIndex, role); } return QVariant(); @@ -260,61 +228,56 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const } } -QModelIndex VersionProxyModel::parent(const QModelIndex &child) const +QModelIndex VersionProxyModel::parent(const QModelIndex& child) const { return QModelIndex(); } -QModelIndex VersionProxyModel::mapFromSource(const QModelIndex &sourceIndex) const +QModelIndex VersionProxyModel::mapFromSource(const QModelIndex& sourceIndex) const { - if(sourceIndex.isValid()) - { + if (sourceIndex.isValid()) { return index(sourceIndex.row(), 0); } return QModelIndex(); } -QModelIndex VersionProxyModel::mapToSource(const QModelIndex &proxyIndex) const +QModelIndex VersionProxyModel::mapToSource(const QModelIndex& proxyIndex) const { - if(proxyIndex.isValid()) - { + if (proxyIndex.isValid()) { return sourceModel()->index(proxyIndex.row(), 0); } return QModelIndex(); } -QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex &parent) const +QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex& parent) const { // no trees here... shoo - if(parent.isValid()) - { + if (parent.isValid()) { return QModelIndex(); } - if(row < 0 || row >= sourceModel()->rowCount()) + if (row < 0 || row >= sourceModel()->rowCount()) return QModelIndex(); - if(column < 0 || column >= columnCount()) + if (column < 0 || column >= columnCount()) return QModelIndex(); return QAbstractItemModel::createIndex(row, column); } -int VersionProxyModel::columnCount(const QModelIndex &parent) const +int VersionProxyModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : m_columns.size(); } -int VersionProxyModel::rowCount(const QModelIndex &parent) const +int VersionProxyModel::rowCount(const QModelIndex& parent) const { - if(sourceModel()) - { + if (sourceModel()) { return sourceModel()->rowCount(parent); } return 0; } -void VersionProxyModel::sourceDataChanged(const QModelIndex &source_top_left, - const QModelIndex &source_bottom_right) +void VersionProxyModel::sourceDataChanged(const QModelIndex& source_top_left, const QModelIndex& source_bottom_right) { - if(source_top_left.parent() != source_bottom_right.parent()) + if (source_top_left.parent() != source_bottom_right.parent()) return; // whole row is getting changed @@ -323,22 +286,20 @@ void VersionProxyModel::sourceDataChanged(const QModelIndex &source_top_left, emit dataChanged(topLeft, bottomRight); } -void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw) +void VersionProxyModel::setSourceModel(QAbstractItemModel* replacingRaw) { - auto replacing = dynamic_cast(replacingRaw); + auto replacing = dynamic_cast(replacingRaw); beginResetModel(); m_columns.clear(); - if(!replacing) - { + if (!replacing) { roles.clear(); filterModel->setSourceModel(replacing); return; } roles = replacing->providesRoles(); - if(roles.contains(BaseVersionList::VersionRole)) - { + if (roles.contains(BaseVersionList::VersionRole)) { m_columns.push_back(Name); } /* @@ -347,32 +308,25 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw) m_columns.push_back(ParentVersion); } */ - if(roles.contains(BaseVersionList::ArchitectureRole)) - { + if (roles.contains(BaseVersionList::ArchitectureRole)) { m_columns.push_back(Architecture); } - if(roles.contains(BaseVersionList::PathRole)) - { + if (roles.contains(BaseVersionList::PathRole)) { m_columns.push_back(Path); } - if(roles.contains(Meta::VersionList::TimeRole)) - { + if (roles.contains(Meta::VersionList::TimeRole)) { m_columns.push_back(Time); } - if(roles.contains(BaseVersionList::BranchRole)) - { + if (roles.contains(BaseVersionList::BranchRole)) { m_columns.push_back(Branch); } - if(roles.contains(BaseVersionList::TypeRole)) - { + if (roles.contains(BaseVersionList::TypeRole)) { m_columns.push_back(Type); } - if(roles.contains(BaseVersionList::RecommendedRole)) - { + if (roles.contains(BaseVersionList::RecommendedRole)) { hasRecommended = true; } - if(roles.contains(BaseVersionList::LatestRole)) - { + if (roles.contains(BaseVersionList::LatestRole)) { hasLatest = true; } filterModel->setSourceModel(replacing); @@ -382,16 +336,13 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw) QModelIndex VersionProxyModel::getRecommended() const { - if(!roles.contains(BaseVersionList::RecommendedRole)) - { + if (!roles.contains(BaseVersionList::RecommendedRole)) { return index(0, 0); } int recommended = 0; - for (int i = 0; i < rowCount(); i++) - { + for (int i = 0; i < rowCount(); i++) { auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::RecommendedRole); - if (value.toBool()) - { + if (value.toBool()) { recommended = i; } } @@ -401,16 +352,13 @@ QModelIndex VersionProxyModel::getRecommended() const QModelIndex VersionProxyModel::getVersion(const QString& version) const { int found = -1; - for (int i = 0; i < rowCount(); i++) - { + for (int i = 0; i < rowCount(); i++) { auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::VersionRole); - if (value.toString() == version) - { + if (value.toString() == version) { found = i; } } - if(found == -1) - { + if (found == -1) { return QModelIndex(); } return index(found, 0); @@ -423,23 +371,24 @@ void VersionProxyModel::clearFilters() filterModel->filterChanged(); } -void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter * f) +void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter* f) { m_filters[column].reset(f); filterModel->filterChanged(); } -void VersionProxyModel::setSearch(const QString &search) { +void VersionProxyModel::setSearch(const QString& search) +{ m_search = search; filterModel->filterChanged(); } -const VersionProxyModel::FilterMap &VersionProxyModel::filters() const +const VersionProxyModel::FilterMap& VersionProxyModel::filters() const { return m_filters; } -const QString &VersionProxyModel::search() const +const QString& VersionProxyModel::search() const { return m_search; } @@ -474,7 +423,7 @@ void VersionProxyModel::sourceRowsRemoved(const QModelIndex& parent, int first, endRemoveRows(); } -void VersionProxyModel::setCurrentVersion(const QString &version) +void VersionProxyModel::setCurrentVersion(const QString& version) { m_currentVersion = version; } diff --git a/launcher/VersionProxyModel.h b/launcher/VersionProxyModel.h index 6434376c6..c7d5fd94e 100644 --- a/launcher/VersionProxyModel.h +++ b/launcher/VersionProxyModel.h @@ -6,64 +6,53 @@ class VersionFilterModel; -class VersionProxyModel: public QAbstractProxyModel -{ +class VersionProxyModel : public QAbstractProxyModel { Q_OBJECT -public: - - enum Column - { - Name, - ParentVersion, - Branch, - Type, - Architecture, - Path, - Time - }; + public: + enum Column { Name, ParentVersion, Branch, Type, Architecture, Path, Time }; typedef QHash> FilterMap; -public: - VersionProxyModel ( QObject* parent = 0 ); - virtual ~VersionProxyModel() {}; + public: + VersionProxyModel(QObject* parent = 0); + virtual ~VersionProxyModel(){}; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; - virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; - virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override; + virtual QModelIndex mapToSource(const QModelIndex& proxyIndex) const override; + virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - virtual QModelIndex parent(const QModelIndex &child) const override; - virtual void setSourceModel(QAbstractItemModel *sourceModel) override; + virtual QModelIndex parent(const QModelIndex& child) const override; + virtual void setSourceModel(QAbstractItemModel* sourceModel) override; - const FilterMap &filters() const; - const QString &search() const; - void setFilter(const BaseVersionList::ModelRoles column, Filter * filter); - void setSearch(const QString &search); + const FilterMap& filters() const; + const QString& search() const; + void setFilter(const BaseVersionList::ModelRoles column, Filter* filter); + void setSearch(const QString& search); void clearFilters(); QModelIndex getRecommended() const; - QModelIndex getVersion(const QString & version) const; - void setCurrentVersion(const QString &version); -private slots: + QModelIndex getVersion(const QString& version) const; + void setCurrentVersion(const QString& version); + private slots: - void sourceDataChanged(const QModelIndex &source_top_left,const QModelIndex &source_bottom_right); + void sourceDataChanged(const QModelIndex& source_top_left, const QModelIndex& source_bottom_right); void sourceAboutToBeReset(); void sourceReset(); - void sourceRowsAboutToBeInserted(const QModelIndex &parent, int first, int last); - void sourceRowsInserted(const QModelIndex &parent, int first, int last); + void sourceRowsAboutToBeInserted(const QModelIndex& parent, int first, int last); + void sourceRowsInserted(const QModelIndex& parent, int first, int last); - void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last); - void sourceRowsRemoved(const QModelIndex &parent, int first, int last); + void sourceRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last); + void sourceRowsRemoved(const QModelIndex& parent, int first, int last); -private: + private: QList m_columns; FilterMap m_filters; QString m_search; BaseVersionList::RoleList roles; - VersionFilterModel * filterModel; + VersionFilterModel* filterModel; bool hasRecommended = false; bool hasLatest = false; QString m_currentVersion; diff --git a/launcher/WatchLock.h b/launcher/WatchLock.h index 3e08b4137..ad74f251e 100644 --- a/launcher/WatchLock.h +++ b/launcher/WatchLock.h @@ -1,20 +1,15 @@ #pragma once -#include #include +#include -struct WatchLock -{ - WatchLock(QFileSystemWatcher * watcher, const QString& directory) - : m_watcher(watcher), m_directory(directory) +struct WatchLock { + WatchLock(QFileSystemWatcher* watcher, const QString& directory) : m_watcher(watcher), m_directory(directory) { m_watcher->removePath(m_directory); } - ~WatchLock() - { - m_watcher->addPath(m_directory); - } - QFileSystemWatcher * m_watcher; + ~WatchLock() { m_watcher->addPath(m_directory); } + QFileSystemWatcher* m_watcher; QString m_directory; }; diff --git a/launcher/icons/IconList.cpp b/launcher/icons/IconList.cpp index 13174f6e8..2e5e1cadf 100644 --- a/launcher/icons/IconList.cpp +++ b/launcher/icons/IconList.cpp @@ -35,32 +35,29 @@ #include "IconList.h" #include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include #define MAX_SIZE 1024 -IconList::IconList(const QStringList &builtinPaths, QString path, QObject *parent) : QAbstractListModel(parent) +IconList::IconList(const QStringList& builtinPaths, QString path, QObject* parent) : QAbstractListModel(parent) { QSet builtinNames; // add builtin icons - for(auto & builtinPath: builtinPaths) - { + for (auto& builtinPath : builtinPaths) { QDir instance_icons(builtinPath); auto file_info_list = instance_icons.entryInfoList(QDir::Files, QDir::Name); - for (auto file_info : file_info_list) - { + for (auto file_info : file_info_list) { builtinNames.insert(file_info.completeBaseName()); } } - for(auto & builtinName : builtinNames) - { + for (auto& builtinName : builtinNames) { addThemeIcon(builtinName); } @@ -78,31 +75,27 @@ IconList::IconList(const QStringList &builtinPaths, QString path, QObject *paren void IconList::sortIconList() { qDebug() << "Sorting icon list..."; - std::sort(icons.begin(), icons.end(), [](const MMCIcon& a, const MMCIcon& b) { - return a.m_key.localeAwareCompare(b.m_key) < 0; - }); + std::sort(icons.begin(), icons.end(), [](const MMCIcon& a, const MMCIcon& b) { return a.m_key.localeAwareCompare(b.m_key) < 0; }); reindex(); } -void IconList::directoryChanged(const QString &path) +void IconList::directoryChanged(const QString& path) { - QDir new_dir (path); - if(m_dir.absolutePath() != new_dir.absolutePath()) - { + QDir new_dir(path); + if (m_dir.absolutePath() != new_dir.absolutePath()) { m_dir.setPath(path); m_dir.refresh(); - if(is_watching) + if (is_watching) stopWatching(); startWatching(); } - if(!m_dir.exists()) - if(!FS::ensureFolderPathExists(m_dir.absolutePath())) + if (!m_dir.exists()) + if (!FS::ensureFolderPathExists(m_dir.absolutePath())) return; m_dir.refresh(); auto new_list = m_dir.entryList(QDir::Files, QDir::Name); - for (auto it = new_list.begin(); it != new_list.end(); it++) - { - QString &foo = (*it); + for (auto it = new_list.begin(); it != new_list.end(); it++) { + QString& foo = (*it); foo = m_dir.filePath(foo); } #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -111,8 +104,7 @@ void IconList::directoryChanged(const QString &path) auto new_set = new_list.toSet(); #endif QList current_list; - for (auto &it : icons) - { + for (auto& it : icons) { if (!it.has(IconType::FileBased)) continue; current_list.push_back(it.m_images[IconType::FileBased].filename); @@ -129,8 +121,7 @@ void IconList::directoryChanged(const QString &path) QSet to_add = new_set; to_add -= current_set; - for (auto remove : to_remove) - { + for (auto remove : to_remove) { qDebug() << "Removing " << remove; QFileInfo rmfile(remove); QString key = rmfile.completeBaseName(); @@ -144,23 +135,19 @@ void IconList::directoryChanged(const QString &path) if (idx == -1) continue; icons[idx].remove(IconType::FileBased); - if (icons[idx].type() == IconType::ToBeDeleted) - { + if (icons[idx].type() == IconType::ToBeDeleted) { beginRemoveRows(QModelIndex(), idx, idx); icons.remove(idx); reindex(); endRemoveRows(); - } - else - { + } else { dataChanged(index(idx), index(idx)); } m_watcher->removePath(remove); emit iconUpdated(key); } - for (auto add : to_add) - { + for (auto add : to_add) { qDebug() << "Adding " << add; QFileInfo addfile(add); @@ -171,8 +158,7 @@ void IconList::directoryChanged(const QString &path) if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg" && suffix != "gif") key = addfile.fileName(); - if (addIcon(key, QString(), addfile.filePath(), IconType::FileBased)) - { + if (addIcon(key, QString(), addfile.filePath(), IconType::FileBased)) { m_watcher->addPath(add); emit iconUpdated(key); } @@ -181,7 +167,7 @@ void IconList::directoryChanged(const QString &path) sortIconList(); } -void IconList::fileChanged(const QString &path) +void IconList::fileChanged(const QString& path) { qDebug() << "Checking " << path; QFileInfo checkfile(path); @@ -200,9 +186,9 @@ void IconList::fileChanged(const QString &path) emit iconUpdated(key); } -void IconList::SettingChanged(const Setting &setting, QVariant value) +void IconList::SettingChanged(const Setting& setting, QVariant value) { - if(setting.id() != "IconsDir") + if (setting.id() != "IconsDir") return; directoryChanged(value.toString()); @@ -213,12 +199,9 @@ void IconList::startWatching() auto abs_path = m_dir.absolutePath(); FS::ensureFolderPathExists(abs_path); is_watching = m_watcher->addPath(abs_path); - if (is_watching) - { + if (is_watching) { qDebug() << "Started watching " << abs_path; - } - else - { + } else { qDebug() << "Failed to start watching " << abs_path; } } @@ -241,7 +224,11 @@ Qt::DropActions IconList::supportedDropActions() const return Qt::CopyAction; } -bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column, [[maybe_unused]] const QModelIndex &parent) +bool IconList::dropMimeData(const QMimeData* data, + Qt::DropAction action, + [[maybe_unused]] int row, + [[maybe_unused]] int column, + [[maybe_unused]] const QModelIndex& parent) { if (action == Qt::IgnoreAction) return true; @@ -250,12 +237,10 @@ bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[mayb return false; // files dropped from outside? - if (data->hasUrls()) - { + if (data->hasUrls()) { auto urls = data->urls(); QStringList iconFiles; - for (auto url : urls) - { + for (auto url : urls) { // only local files may be dropped... if (!url.isLocalFile()) continue; @@ -267,7 +252,7 @@ bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[mayb return false; } -Qt::ItemFlags IconList::flags(const QModelIndex &index) const +Qt::ItemFlags IconList::flags(const QModelIndex& index) const { Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index); if (index.isValid()) @@ -276,7 +261,7 @@ Qt::ItemFlags IconList::flags(const QModelIndex &index) const return Qt::ItemIsDropEnabled | defaultFlags; } -QVariant IconList::data(const QModelIndex &index, int role) const +QVariant IconList::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -286,28 +271,26 @@ QVariant IconList::data(const QModelIndex &index, int role) const if (row < 0 || row >= icons.size()) return QVariant(); - switch (role) - { - case Qt::DecorationRole: - return icons[row].icon(); - case Qt::DisplayRole: - return icons[row].name(); - case Qt::UserRole: - return icons[row].m_key; - default: - return QVariant(); + switch (role) { + case Qt::DecorationRole: + return icons[row].icon(); + case Qt::DisplayRole: + return icons[row].name(); + case Qt::UserRole: + return icons[row].m_key; + default: + return QVariant(); } } -int IconList::rowCount(const QModelIndex &parent) const +int IconList::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : icons.size(); } -void IconList::installIcons(const QStringList &iconFiles) +void IconList::installIcons(const QStringList& iconFiles) { - for (QString file : iconFiles) - { + for (QString file : iconFiles) { QFileInfo fileinfo(file); if (!fileinfo.isReadable() || !fileinfo.isFile()) continue; @@ -322,10 +305,10 @@ void IconList::installIcons(const QStringList &iconFiles) } } -void IconList::installIcon(const QString &file, const QString &name) +void IconList::installIcon(const QString& file, const QString& name) { QFileInfo fileinfo(file); - if(!fileinfo.isReadable() || !fileinfo.isFile()) + if (!fileinfo.isReadable() || !fileinfo.isFile()) return; QString target = FS::PathCombine(getDirectory(), name); @@ -333,17 +316,16 @@ void IconList::installIcon(const QString &file, const QString &name) QFile::copy(file, target); } -bool IconList::iconFileExists(const QString &key) const +bool IconList::iconFileExists(const QString& key) const { auto iconEntry = icon(key); - if(!iconEntry) - { + if (!iconEntry) { return false; } return iconEntry->has(IconType::FileBased); } -const MMCIcon *IconList::icon(const QString &key) const +const MMCIcon* IconList::icon(const QString& key) const { int iconIdx = getIconIndex(key); if (iconIdx == -1) @@ -351,7 +333,7 @@ const MMCIcon *IconList::icon(const QString &key) const return &icons[iconIdx]; } -bool IconList::deleteIcon(const QString &key) +bool IconList::deleteIcon(const QString& key) { if (!iconFileExists(key)) return false; @@ -359,7 +341,7 @@ bool IconList::deleteIcon(const QString &key) return QFile::remove(icon(key)->getFilePath()); } -bool IconList::trashIcon(const QString &key) +bool IconList::trashIcon(const QString& key) { if (!iconFileExists(key)) return false; @@ -370,15 +352,12 @@ bool IconList::trashIcon(const QString &key) bool IconList::addThemeIcon(const QString& key) { auto iter = name_index.find(key); - if (iter != name_index.end()) - { - auto &oldOne = icons[*iter]; + if (iter != name_index.end()) { + auto& oldOne = icons[*iter]; oldOne.replace(Builtin, key); dataChanged(index(*iter), index(*iter)); return true; - } - else - { + } else { // add a new icon beginInsertRows(QModelIndex(), icons.size(), icons.size()); { @@ -394,22 +373,19 @@ bool IconList::addThemeIcon(const QString& key) } } -bool IconList::addIcon(const QString &key, const QString &name, const QString &path, const IconType type) +bool IconList::addIcon(const QString& key, const QString& name, const QString& path, const IconType type) { // replace the icon even? is the input valid? QIcon icon(path); if (icon.isNull()) return false; auto iter = name_index.find(key); - if (iter != name_index.end()) - { - auto &oldOne = icons[*iter]; + if (iter != name_index.end()) { + auto& oldOne = icons[*iter]; oldOne.replace(type, icon, path); dataChanged(index(*iter), index(*iter)); return true; - } - else - { + } else { // add a new icon beginInsertRows(QModelIndex(), icons.size(), icons.size()); { @@ -425,26 +401,24 @@ bool IconList::addIcon(const QString &key, const QString &name, const QString &p } } -void IconList::saveIcon(const QString &key, const QString &path, const char * format) const +void IconList::saveIcon(const QString& key, const QString& path, const char* format) const { auto icon = getIcon(key); auto pixmap = icon.pixmap(128, 128); pixmap.save(path, format); } - void IconList::reindex() { name_index.clear(); int i = 0; - for (auto &iter : icons) - { + for (auto& iter : icons) { name_index[iter.m_key] = i; i++; } } -QIcon IconList::getIcon(const QString &key) const +QIcon IconList::getIcon(const QString& key) const { int icon_index = getIconIndex(key); @@ -459,7 +433,7 @@ QIcon IconList::getIcon(const QString &key) const return QIcon(); } -int IconList::getIconIndex(const QString &key) const +int IconList::getIconIndex(const QString& key) const { auto iter = name_index.find(key == "default" ? "grass" : key); if (iter != name_index.end()) diff --git a/launcher/icons/IconList.h b/launcher/icons/IconList.h index 97141e4ae..bc1dd3b9b 100644 --- a/launcher/icons/IconList.h +++ b/launcher/icons/IconList.h @@ -15,10 +15,10 @@ #pragma once -#include #include -#include #include +#include +#include #include #include @@ -29,58 +29,58 @@ class QFileSystemWatcher; -class IconList : public QAbstractListModel -{ +class IconList : public QAbstractListModel { Q_OBJECT -public: - explicit IconList(const QStringList &builtinPaths, QString path, QObject *parent = 0); - virtual ~IconList() {}; + public: + explicit IconList(const QStringList& builtinPaths, QString path, QObject* parent = 0); + virtual ~IconList(){}; - QIcon getIcon(const QString &key) const; - int getIconIndex(const QString &key) const; + QIcon getIcon(const QString& key) const; + int getIconIndex(const QString& key) const; QString getDirectory() const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; virtual QStringList mimeTypes() const override; virtual Qt::DropActions supportedDropActions() const override; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - virtual Qt::ItemFlags flags(const QModelIndex &index) const override; + virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; - bool addThemeIcon(const QString &key); - bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type); - void saveIcon(const QString &key, const QString &path, const char * format) const; - bool deleteIcon(const QString &key); - bool trashIcon(const QString &key); - bool iconFileExists(const QString &key) const; + bool addThemeIcon(const QString& key); + bool addIcon(const QString& key, const QString& name, const QString& path, const IconType type); + void saveIcon(const QString& key, const QString& path, const char* format) const; + bool deleteIcon(const QString& key); + bool trashIcon(const QString& key); + bool iconFileExists(const QString& key) const; - void installIcons(const QStringList &iconFiles); - void installIcon(const QString &file, const QString &name); + void installIcons(const QStringList& iconFiles); + void installIcon(const QString& file, const QString& name); - const MMCIcon * icon(const QString &key) const; + const MMCIcon* icon(const QString& key) const; void startWatching(); void stopWatching(); -signals: + signals: void iconUpdated(QString key); -private: + private: // hide copy constructor - IconList(const IconList &) = delete; + IconList(const IconList&) = delete; // hide assign op - IconList &operator=(const IconList &) = delete; + IconList& operator=(const IconList&) = delete; void reindex(); void sortIconList(); -public slots: - void directoryChanged(const QString &path); + public slots: + void directoryChanged(const QString& path); -protected slots: - void fileChanged(const QString &path); - void SettingChanged(const Setting & setting, QVariant value); -private: + protected slots: + void fileChanged(const QString& path); + void SettingChanged(const Setting& setting, QVariant value); + + private: shared_qobject_ptr m_watcher; bool is_watching; QMap name_index; diff --git a/launcher/icons/IconUtils.cpp b/launcher/icons/IconUtils.cpp index bf530c16f..0b06639e7 100644 --- a/launcher/icons/IconUtils.cpp +++ b/launcher/icons/IconUtils.cpp @@ -1,24 +1,18 @@ #include "IconUtils.h" -#include "FileSystem.h" #include +#include "FileSystem.h" #include namespace { -std::array validIconExtensions = {{ - "svg", - "png", - "ico", - "gif", - "jpg", - "jpeg" -}}; +std::array validIconExtensions = { { "svg", "png", "ico", "gif", "jpg", "jpeg" } }; } -namespace IconUtils{ +namespace IconUtils { -QString findBestIconIn(const QString &folder, const QString & iconKey) { +QString findBestIconIn(const QString& folder, const QString& iconKey) +{ int best_found = validIconExtensions.size(); QString best_filename; @@ -27,13 +21,13 @@ QString findBestIconIn(const QString &folder, const QString & iconKey) { it.next(); auto fileInfo = it.fileInfo(); - if(fileInfo.completeBaseName() != iconKey) + if (fileInfo.completeBaseName() != iconKey) continue; auto extension = fileInfo.suffix(); - for(int i = 0; i < best_found; i++) { - if(extension == validIconExtensions[i]) { + for (int i = 0; i < best_found; i++) { + if (extension == validIconExtensions[i]) { best_found = i; qDebug() << i << " : " << fileInfo.fileName(); best_filename = fileInfo.fileName(); @@ -43,12 +37,13 @@ QString findBestIconIn(const QString &folder, const QString & iconKey) { return FS::PathCombine(folder, best_filename); } -QString getIconFilter() { +QString getIconFilter() +{ QString out; QTextStream stream(&out); stream << '('; - for(size_t i = 0; i < validIconExtensions.size() - 1; i++) { - if(i > 0) { + for (size_t i = 0; i < validIconExtensions.size() - 1; i++) { + if (i > 0) { stream << " "; } stream << "*." << validIconExtensions[i]; @@ -58,5 +53,4 @@ QString getIconFilter() { return out; } -} - +} // namespace IconUtils diff --git a/launcher/icons/IconUtils.h b/launcher/icons/IconUtils.h index be93d9143..8c6f677dd 100644 --- a/launcher/icons/IconUtils.h +++ b/launcher/icons/IconUtils.h @@ -5,9 +5,9 @@ namespace IconUtils { // Given a folder and an icon key, find 'best' of the icons with the given key in there and return its path -QString findBestIconIn(const QString &folder, const QString & iconKey); +QString findBestIconIn(const QString& folder, const QString& iconKey); // Get icon file type filter for file browser dialogs QString getIconFilter(); -} +} // namespace IconUtils diff --git a/launcher/icons/MMCIcon.cpp b/launcher/icons/MMCIcon.cpp index 436ef75ff..9c1b366c3 100644 --- a/launcher/icons/MMCIcon.cpp +++ b/launcher/icons/MMCIcon.cpp @@ -37,23 +37,21 @@ #include #include -IconType operator--(IconType &t, int) +IconType operator--(IconType& t, int) { IconType temp = t; - switch (t) - { - case IconType::Builtin: - t = IconType::ToBeDeleted; - break; - case IconType::Transient: - t = IconType::Builtin; - break; - case IconType::FileBased: - t = IconType::Transient; - break; - default: - { - } + switch (t) { + case IconType::Builtin: + t = IconType::ToBeDeleted; + break; + case IconType::Transient: + t = IconType::Builtin; + break; + case IconType::FileBased: + t = IconType::Transient; + break; + default: { + } } return temp; } @@ -79,8 +77,8 @@ QIcon MMCIcon::icon() const { if (m_current_type == IconType::ToBeDeleted) return QIcon(); - auto & icon = m_images[m_current_type].icon; - if(!icon.isNull()) + auto& icon = m_images[m_current_type].icon; + if (!icon.isNull()) return icon; // FIXME: inject this. return QIcon::fromTheme(m_images[m_current_type].key); @@ -90,10 +88,8 @@ void MMCIcon::remove(IconType rm_type) { m_images[rm_type].filename = QString(); m_images[rm_type].icon = QIcon(); - for (auto iter = rm_type; iter != IconType::ToBeDeleted; iter--) - { - if (m_images[iter].present()) - { + for (auto iter = rm_type; iter != IconType::ToBeDeleted; iter--) { + if (m_images[iter].present()) { m_current_type = iter; return; } @@ -103,8 +99,7 @@ void MMCIcon::remove(IconType rm_type) void MMCIcon::replace(IconType new_type, QIcon icon, QString path) { - if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted) - { + if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted) { m_current_type = new_type; } m_images[new_type].icon = icon; @@ -114,8 +109,7 @@ void MMCIcon::replace(IconType new_type, QIcon icon, QString path) void MMCIcon::replace(IconType new_type, const QString& key) { - if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted) - { + if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted) { m_current_type = new_type; } m_images[new_type].icon = QIcon(); @@ -125,13 +119,12 @@ void MMCIcon::replace(IconType new_type, const QString& key) QString MMCIcon::getFilePath() const { - if(m_current_type == IconType::ToBeDeleted){ + if (m_current_type == IconType::ToBeDeleted) { return QString(); } return m_images[m_current_type].filename; } - bool MMCIcon::isBuiltIn() const { return m_current_type == IconType::Builtin; diff --git a/launcher/icons/MMCIcon.h b/launcher/icons/MMCIcon.h index 13d99318a..c968f306a 100644 --- a/launcher/icons/MMCIcon.h +++ b/launcher/icons/MMCIcon.h @@ -14,32 +14,20 @@ */ #pragma once -#include #include #include +#include -enum IconType : unsigned -{ - Builtin, - Transient, - FileBased, - ICONS_TOTAL, - ToBeDeleted -}; +enum IconType : unsigned { Builtin, Transient, FileBased, ICONS_TOTAL, ToBeDeleted }; -struct MMCImage -{ +struct MMCImage { QIcon icon; QString key; QString filename; - bool present() const - { - return !icon.isNull() || !key.isEmpty(); - } + bool present() const { return !icon.isNull() || !key.isEmpty(); } }; -struct MMCIcon -{ +struct MMCIcon { QString m_key; QString m_name; MMCImage m_images[ICONS_TOTAL]; @@ -51,7 +39,7 @@ struct MMCIcon QIcon icon() const; void remove(IconType rm_type); void replace(IconType new_type, QIcon icon, QString path = QString()); - void replace(IconType new_type, const QString &key); + void replace(IconType new_type, const QString& key); bool isBuiltIn() const; QString getFilePath() const; }; diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index e4a686c27..f3207fdcf 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -35,26 +35,23 @@ #include "JavaChecker.h" -#include -#include -#include #include +#include +#include +#include -#include "JavaUtils.h" -#include "FileSystem.h" -#include "Commandline.h" #include "Application.h" +#include "Commandline.h" +#include "FileSystem.h" +#include "JavaUtils.h" -JavaChecker::JavaChecker(QObject *parent) : QObject(parent) -{ -} +JavaChecker::JavaChecker(QObject* parent) : QObject(parent) {} void JavaChecker::performCheck() { QString checkerJar = JavaUtils::getJavaCheckPath(); - if (checkerJar.isEmpty()) - { + if (checkerJar.isEmpty()) { qDebug() << "Java checker library could not be found. Please check your installation."; return; } @@ -62,25 +59,21 @@ void JavaChecker::performCheck() QStringList args; process.reset(new QProcess()); - if(m_args.size()) - { + if (m_args.size()) { auto extraArgs = Commandline::splitArgs(m_args); args.append(extraArgs); } - if(m_minMem != 0) - { + if (m_minMem != 0) { args << QString("-Xms%1m").arg(m_minMem); } - if(m_maxMem != 0) - { + if (m_maxMem != 0) { args << QString("-Xmx%1m").arg(m_maxMem); } - if(m_permGen != 64) - { + if (m_permGen != 64) { args << QString("-XX:PermSize=%1m").arg(m_permGen); } - args.append({"-jar", checkerJar}); + args.append({ "-jar", checkerJar }); process->setArguments(args); process->setProgram(m_path); process->setProcessChannelMode(QProcess::SeparateChannels); @@ -130,8 +123,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) qWarning() << "STDERR" << m_stderr; qDebug() << "Java checker finished with status" << status << "exit code" << exitcode; - if (status == QProcess::CrashExit || exitcode == 1) - { + if (status == QProcess::CrashExit || exitcode == 1) { result.validity = JavaCheckResult::Validity::Errored; emit checkFinished(result); return; @@ -146,8 +138,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) #else QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts); #endif - for(QString line : lines) - { + for (QString line : lines) { line = line.trimmed(); // NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux if (line.contains("/bedrock/strata")) { @@ -159,18 +150,14 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) #else auto parts = line.split('=', QString::SkipEmptyParts); #endif - if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) - { + if (parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) { continue; - } - else - { + } else { results.insert(parts[0], parts[1]); } } - if(!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor") || !success) - { + if (!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor") || !success) { result.validity = JavaCheckResult::Validity::ReturnedInvalidData; emit checkFinished(result); return; @@ -181,7 +168,6 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) auto java_vendor = results["java.vendor"]; bool is_64 = os_arch == "x86_64" || os_arch == "amd64" || os_arch == "aarch64" || os_arch == "arm64"; - result.validity = JavaCheckResult::Validity::Valid; result.is_64bit = is_64; result.mojangPlatform = is_64 ? "64" : "32"; @@ -194,8 +180,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) void JavaChecker::error(QProcess::ProcessError err) { - if(err == QProcess::FailedToStart) - { + if (err == QProcess::FailedToStart) { qDebug() << "Java checker has failed to start."; qDebug() << "Process environment:"; qDebug() << process->environment(); @@ -216,8 +201,7 @@ void JavaChecker::error(QProcess::ProcessError err) void JavaChecker::timeout() { // NO MERCY. NO ABUSE. - if(process) - { + if (process) { qDebug() << "Java checker has been killed by timeout."; process->kill(); } diff --git a/launcher/java/JavaChecker.h b/launcher/java/JavaChecker.h index 122861cf7..743f49417 100644 --- a/launcher/java/JavaChecker.h +++ b/launcher/java/JavaChecker.h @@ -9,8 +9,7 @@ class JavaChecker; -struct JavaCheckResult -{ +struct JavaCheckResult { QString path; QString mojangPlatform; QString realPlatform; @@ -20,21 +19,15 @@ struct JavaCheckResult QString errorLog; bool is_64bit = false; int id; - enum class Validity - { - Errored, - ReturnedInvalidData, - Valid - } validity = Validity::Errored; + enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored; }; typedef shared_qobject_ptr QProcessPtr; typedef shared_qobject_ptr JavaCheckerPtr; -class JavaChecker : public QObject -{ +class JavaChecker : public QObject { Q_OBJECT -public: - explicit JavaChecker(QObject *parent = 0); + public: + explicit JavaChecker(QObject* parent = 0); void performCheck(); QString m_path; @@ -44,15 +37,15 @@ public: int m_maxMem = 0; int m_permGen = 64; -signals: + signals: void checkFinished(JavaCheckResult result); -private: + + private: QProcessPtr process; QTimer killTimer; QString m_stdout; QString m_stderr; -public -slots: + public slots: void timeout(); void finished(int exitcode, QProcess::ExitStatus); void error(QProcess::ProcessError); diff --git a/launcher/java/JavaCheckerJob.cpp b/launcher/java/JavaCheckerJob.cpp index 48274974d..870e2a09a 100644 --- a/launcher/java/JavaCheckerJob.cpp +++ b/launcher/java/JavaCheckerJob.cpp @@ -20,14 +20,12 @@ void JavaCheckerJob::partFinished(JavaCheckResult result) { num_finished++; - qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/" - << javacheckers.size(); + qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/" << javacheckers.size(); setProgress(num_finished, javacheckers.size()); javaresults.replace(result.id, result); - if (num_finished == javacheckers.size()) - { + if (num_finished == javacheckers.size()) { emitSucceeded(); } } @@ -35,8 +33,7 @@ void JavaCheckerJob::partFinished(JavaCheckResult result) void JavaCheckerJob::executeTask() { qDebug() << m_job_name.toLocal8Bit() << " started."; - for (auto iter : javacheckers) - { + for (auto iter : javacheckers) { javaresults.append(JavaCheckResult()); connect(iter.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished); iter->performCheck(); diff --git a/launcher/java/JavaCheckerJob.h b/launcher/java/JavaCheckerJob.h index c09864207..009687917 100644 --- a/launcher/java/JavaCheckerJob.h +++ b/launcher/java/JavaCheckerJob.h @@ -23,37 +23,32 @@ class JavaCheckerJob; typedef shared_qobject_ptr JavaCheckerJobPtr; // FIXME: this just seems horribly redundant -class JavaCheckerJob : public Task -{ +class JavaCheckerJob : public Task { Q_OBJECT -public: - explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name) {}; - virtual ~JavaCheckerJob() {}; + public: + explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name){}; + virtual ~JavaCheckerJob(){}; bool addJavaCheckerAction(JavaCheckerPtr base) { javacheckers.append(base); // if this is already running, the action needs to be started right away! - if (isRunning()) - { + if (isRunning()) { setProgress(num_finished, javacheckers.size()); connect(base.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished); base->performCheck(); } return true; } - QList getResults() - { - return javaresults; - } + QList getResults() { return javaresults; } -private slots: + private slots: void partFinished(JavaCheckResult result); -protected: + protected: virtual void executeTask() override; -private: + private: QString m_job_name; QList javacheckers; QList javaresults; diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 3407fdf72..d8be4963f 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -39,14 +39,12 @@ #include -#include "java/JavaInstallList.h" #include "java/JavaCheckerJob.h" +#include "java/JavaInstallList.h" #include "java/JavaUtils.h" #include "minecraft/VersionFilterData.h" -JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent) -{ -} +JavaInstallList::JavaInstallList(QObject* parent) : BaseVersionList(parent) {} Task::Ptr JavaInstallList::getLoadTask() { @@ -56,8 +54,7 @@ Task::Ptr JavaInstallList::getLoadTask() Task::Ptr JavaInstallList::getCurrentTask() { - if(m_status == Status::InProgress) - { + if (m_status == Status::InProgress) { return m_loadTask; } return nullptr; @@ -65,8 +62,7 @@ Task::Ptr JavaInstallList::getCurrentTask() void JavaInstallList::load() { - if(m_status != Status::InProgress) - { + if (m_status != Status::InProgress) { m_status = Status::InProgress; m_loadTask.reset(new JavaListLoadTask(this)); m_loadTask->start(); @@ -88,7 +84,7 @@ int JavaInstallList::count() const return m_vlist.count(); } -QVariant JavaInstallList::data(const QModelIndex &index, int role) const +QVariant JavaInstallList::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -97,8 +93,7 @@ QVariant JavaInstallList::data(const QModelIndex &index, int role) const return QVariant(); auto version = std::dynamic_pointer_cast(m_vlist[index.row()]); - switch (role) - { + switch (role) { case SortRole: return -index.row(); case VersionPointerRole: @@ -120,17 +115,15 @@ QVariant JavaInstallList::data(const QModelIndex &index, int role) const BaseVersionList::RoleList JavaInstallList::providesRoles() const { - return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole}; + return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole }; } - void JavaInstallList::updateListData(QList versions) { beginResetModel(); m_vlist = versions; sortVersions(); - if(m_vlist.size()) - { + if (m_vlist.size()) { auto best = std::dynamic_pointer_cast(m_vlist[0]); best->recommended = true; } @@ -153,15 +146,13 @@ void JavaInstallList::sortVersions() endResetModel(); } -JavaListLoadTask::JavaListLoadTask(JavaInstallList *vlist) : Task() +JavaListLoadTask::JavaListLoadTask(JavaInstallList* vlist) : Task() { m_list = vlist; m_currentRecommended = NULL; } -JavaListLoadTask::~JavaListLoadTask() -{ -} +JavaListLoadTask::~JavaListLoadTask() {} void JavaListLoadTask::executeTask() { @@ -176,8 +167,7 @@ void JavaListLoadTask::executeTask() qDebug() << "Probing the following Java paths: "; int id = 0; - for(QString candidate : candidate_paths) - { + for (QString candidate : candidate_paths) { qDebug() << " " << candidate; auto candidate_checker = new JavaChecker(); @@ -197,10 +187,8 @@ void JavaListLoadTask::javaCheckerFinished() auto results = m_job->getResults(); qDebug() << "Found the following valid Java installations:"; - for(JavaCheckResult result : results) - { - if(result.validity == JavaCheckResult::Validity::Valid) - { + for (JavaCheckResult result : results) { + if (result.validity == JavaCheckResult::Validity::Valid) { JavaInstallPtr javaVersion(new JavaInstall()); javaVersion->id = result.javaVersion; @@ -213,13 +201,11 @@ void JavaListLoadTask::javaCheckerFinished() } QList javas_bvp; - for (auto java : candidates) - { - //qDebug() << java->id << java->arch << " at " << java->path; + for (auto java : candidates) { + // qDebug() << java->id << java->arch << " at " << java->path; BaseVersion::Ptr bp_java = std::dynamic_pointer_cast(java); - if (bp_java) - { + if (bp_java) { javas_bvp.append(java); } } diff --git a/launcher/java/JavaInstallList.h b/launcher/java/JavaInstallList.h index 733dc7e1c..1eebadf23 100644 --- a/launcher/java/JavaInstallList.h +++ b/launcher/java/JavaInstallList.h @@ -15,8 +15,8 @@ #pragma once -#include #include +#include #include "BaseVersionList.h" #include "tasks/Task.h" @@ -28,17 +28,12 @@ class JavaListLoadTask; -class JavaInstallList : public BaseVersionList -{ +class JavaInstallList : public BaseVersionList { Q_OBJECT - enum class Status - { - NotDone, - InProgress, - Done - }; -public: - explicit JavaInstallList(QObject *parent = 0); + enum class Status { NotDone, InProgress, Done }; + + public: + explicit JavaInstallList(QObject* parent = 0); Task::Ptr getLoadTask() override; bool isLoaded() override; @@ -46,36 +41,35 @@ public: int count() const override; void sortVersions() override; - QVariant data(const QModelIndex &index, int role) const override; + QVariant data(const QModelIndex& index, int role) const override; RoleList providesRoles() const override; -public slots: + public slots: void updateListData(QList versions) override; -protected: + protected: void load(); Task::Ptr getCurrentTask(); -protected: + protected: Status m_status = Status::NotDone; shared_qobject_ptr m_loadTask; QList m_vlist; }; -class JavaListLoadTask : public Task -{ +class JavaListLoadTask : public Task { Q_OBJECT -public: - explicit JavaListLoadTask(JavaInstallList *vlist); + public: + explicit JavaListLoadTask(JavaInstallList* vlist); virtual ~JavaListLoadTask(); void executeTask() override; -public slots: + public slots: void javaCheckerFinished(); -protected: + protected: shared_qobject_ptr m_job; - JavaInstallList *m_list; - JavaInstall *m_currentRecommended; + JavaInstallList* m_list; + JavaInstall* m_currentRecommended; }; diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index e55663aab..a44ebca25 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -33,24 +33,21 @@ * limitations under the License. */ -#include -#include #include +#include #include #include #include -#include "java/JavaUtils.h" -#include "java/JavaInstallList.h" -#include "FileSystem.h" #include "Application.h" +#include "FileSystem.h" +#include "java/JavaInstallList.h" +#include "java/JavaUtils.h" #define IBUS "@im=ibus" -JavaUtils::JavaUtils() -{ -} +JavaUtils::JavaUtils() {} QString stripVariableEntries(QString name, QString target, QString remove) { @@ -65,8 +62,7 @@ QString stripVariableEntries(QString name, QString target, QString remove) for (QString item : toRemove) { bool removed = targetItems.removeOne(item); if (!removed) - qWarning() << "Entry" << item - << "could not be stripped from variable" << name; + qWarning() << "Entry" << item << "could not be stripped from variable" << name; } return targetItems.join(delimiter); } @@ -77,20 +73,10 @@ QProcessEnvironment CleanEnviroment() QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment(); QProcessEnvironment env; - QStringList ignored = - { - "JAVA_ARGS", - "CLASSPATH", - "CONFIGPATH", - "JAVA_HOME", - "JRE_HOME", - "_JAVA_OPTIONS", - "JAVA_OPTIONS", - "JAVA_TOOL_OPTIONS" - }; + QStringList ignored = { "JAVA_ARGS", "CLASSPATH", "CONFIGPATH", "JAVA_HOME", + "JRE_HOME", "_JAVA_OPTIONS", "JAVA_OPTIONS", "JAVA_TOOL_OPTIONS" }; - QStringList stripped = - { + QStringList stripped = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) "LD_LIBRARY_PATH", "LD_PRELOAD", @@ -98,12 +84,10 @@ QProcessEnvironment CleanEnviroment() "QT_PLUGIN_PATH", "QT_FONTPATH" }; - for(auto key: rawenv.keys()) - { + for (auto key : rawenv.keys()) { auto value = rawenv.value(key); // filter out dangerous java crap - if(ignored.contains(key)) - { + if (ignored.contains(key)) { qDebug() << "Env: ignoring" << key << value; continue; } @@ -111,13 +95,11 @@ QProcessEnvironment CleanEnviroment() // These are used to strip the original variables // If there is "LD_LIBRARY_PATH" and "LAUNCHER_LD_LIBRARY_PATH", we want to // remove all values in "LAUNCHER_LD_LIBRARY_PATH" from "LD_LIBRARY_PATH" - if(key.startsWith("LAUNCHER_")) - { + if (key.startsWith("LAUNCHER_")) { qDebug() << "Env: ignoring" << key << value; continue; } - if(stripped.contains(key)) - { + if (stripped.contains(key)) { QString newValue = stripVariableEntries(key, value, rawenv.value("LAUNCHER_" + key)); qDebug() << "Env: stripped" << key << value << "to" << newValue; @@ -125,8 +107,7 @@ QProcessEnvironment CleanEnviroment() #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) // Strip IBus // IBus is a Linux IME framework. For some reason, it breaks MC? - if (key == "XMODIFIERS" && value.contains(IBUS)) - { + if (key == "XMODIFIERS" && value.contains(IBUS)) { QString save = value; value.replace(IBUS, ""); qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value; @@ -137,8 +118,7 @@ QProcessEnvironment CleanEnviroment() } #ifdef Q_OS_LINUX // HACK: Workaround for QTBUG-42500 - if(!env.contains("LD_LIBRARY_PATH")) - { + if (!env.contains("LD_LIBRARY_PATH")) { env.insert("LD_LIBRARY_PATH", ""); } #endif @@ -177,7 +157,7 @@ QStringList addJavasFromEnv(QList javas) auto env = qEnvironmentVariable("PRISMLAUNCHER_JAVA_PATHS"); // FIXME: use launcher name from buildconfig #if defined(Q_OS_WIN32) QList javaPaths = env.replace("\\", "/").split(QLatin1String(";")); - + auto envPath = qEnvironmentVariable("PATH"); QList javaPathsfromPath = envPath.replace("\\", "/").split(QLatin1String(";")); for (QString string : javaPathsfromPath) { @@ -186,8 +166,7 @@ QStringList addJavasFromEnv(QList javas) #else QList javaPaths = env.split(QLatin1String(":")); #endif - for(QString i : javaPaths) - { + for (QString i : javaPaths) { javas.append(i); }; return javas; @@ -205,9 +184,8 @@ QList JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString archType = "32"; HKEY jreKey; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.toStdWString().c_str(), 0, - KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS) - { + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.toStdWString().c_str(), 0, KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == + ERROR_SUCCESS) { // Read the current type version from the registry. // This will be used to find any key that contains the JavaHome value. @@ -215,46 +193,36 @@ QList JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString DWORD subKeyNameSize, numSubKeys, retCode; // Get the number of subkeys - RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, - NULL, NULL); + RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // Iterate until RegEnumKeyEx fails - if (numSubKeys > 0) - { - for (DWORD i = 0; i < numSubKeys; i++) - { + if (numSubKeys > 0) { + for (DWORD i = 0; i < numSubKeys; i++) { subKeyNameSize = 255; - retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, - NULL); + retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, NULL); QString newSubkeyName = QString::fromWCharArray(subKeyName); - if (retCode == ERROR_SUCCESS) - { + if (retCode == ERROR_SUCCESS) { // Now open the registry key for the version that we just got. QString newKeyName = keyName + "\\" + newSubkeyName + subkeySuffix; HKEY newKey; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, newKeyName.toStdWString().c_str(), 0, - KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS) - { + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, newKeyName.toStdWString().c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &newKey) == + ERROR_SUCCESS) { // Read the JavaHome value to find where Java is installed. DWORD valueSz = 0; - if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, - &valueSz) == ERROR_SUCCESS) - { - WCHAR *value = new WCHAR[valueSz]; - RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE *)value, - &valueSz); + if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, &valueSz) == ERROR_SUCCESS) { + WCHAR* value = new WCHAR[valueSz]; + RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE*)value, &valueSz); QString newValue = QString::fromWCharArray(value); - delete [] value; + delete[] value; // Now, we construct the version object and add it to the list. JavaInstallPtr javaVersion(new JavaInstall()); javaVersion->id = newSubkeyName; javaVersion->arch = archType; - javaVersion->path = - QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe"); + javaVersion->path = QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe"); javas.append(javaVersion); } @@ -275,66 +243,56 @@ QList JavaUtils::FindJavaPaths() QList java_candidates; // Oracle - QList JRE64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); - QList JDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); - QList JRE32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); - QList JDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); + QList JRE64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); + QList JDK64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); + QList JRE32s = + this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); + QList JDK32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); // Oracle for Java 9 and newer - QList NEWJRE64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); - QList NEWJDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); - QList NEWJRE32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); - QList NEWJDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); + QList NEWJRE64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); + QList NEWJDK64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); + QList NEWJRE32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); + QList NEWJDK32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); // AdoptOpenJDK - QList ADOPTOPENJRE32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); - QList ADOPTOPENJRE64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); - QList ADOPTOPENJDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); - QList ADOPTOPENJDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); + QList ADOPTOPENJRE32s = + this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); + QList ADOPTOPENJRE64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); + QList ADOPTOPENJDK32s = + this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); + QList ADOPTOPENJDK64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); // Eclipse Foundation - QList FOUNDATIONJDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); - QList FOUNDATIONJDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); + QList FOUNDATIONJDK32s = + this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); + QList FOUNDATIONJDK64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); // Eclipse Adoptium - QList ADOPTIUMJRE32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI"); - QList ADOPTIUMJRE64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI"); - QList ADOPTIUMJDK32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); - QList ADOPTIUMJDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); + QList ADOPTIUMJRE32s = + this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI"); + QList ADOPTIUMJRE64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI"); + QList ADOPTIUMJDK32s = + this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); + QList ADOPTIUMJDK64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); // Microsoft - QList MICROSOFTJDK64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\Microsoft\\JDK", "Path", "\\hotspot\\MSI"); + QList MICROSOFTJDK64s = + this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Microsoft\\JDK", "Path", "\\hotspot\\MSI"); // Azul Zulu - QList ZULU64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); - QList ZULU32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); + QList ZULU64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); + QList ZULU32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); // BellSoft Liberica - QList LIBERICA64s = this->FindJavaFromRegistryKey( - KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); - QList LIBERICA32s = this->FindJavaFromRegistryKey( - KEY_WOW64_32KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); + QList LIBERICA64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); + QList LIBERICA32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); // List x64 before x86 java_candidates.append(JRE64s); @@ -371,10 +329,8 @@ QList JavaUtils::FindJavaPaths() java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path)); QList candidates; - for(JavaInstallPtr java_candidate : java_candidates) - { - if(!candidates.contains(java_candidate->path)) - { + for (JavaInstallPtr java_candidate : java_candidates) { + if (!candidates.contains(java_candidate->path)) { candidates.append(java_candidate->path); } } @@ -394,13 +350,13 @@ QList JavaUtils::FindJavaPaths() javas.append("/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java"); QDir libraryJVMDir("/Library/Java/JavaVirtualMachines/"); QStringList libraryJVMJavas = libraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - foreach (const QString &java, libraryJVMJavas) { + foreach (const QString& java, libraryJVMJavas) { javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/jre/bin/java"); } QDir systemLibraryJVMDir("/System/Library/Java/JavaVirtualMachines/"); QStringList systemLibraryJVMJavas = systemLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - foreach (const QString &java, systemLibraryJVMJavas) { + foreach (const QString& java, systemLibraryJVMJavas) { javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); } @@ -414,14 +370,12 @@ QList JavaUtils::FindJavaPaths() { QList javas; javas.append(this->GetDefaultJava()->path); - auto scanJavaDir = [&](const QString & dirPath) - { + auto scanJavaDir = [&](const QString& dirPath) { QDir dir(dirPath); - if(!dir.exists()) + if (!dir.exists()) return; auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - for(auto & entry: entries) - { + for (auto& entry : entries) { QString prefix; prefix = entry.canonicalFilePath(); javas.append(FS::PathCombine(prefix, "jre/bin/java")); @@ -430,8 +384,7 @@ QList JavaUtils::FindJavaPaths() }; // java installed in a snap is installed in the standard directory, but underneath $SNAP auto snap = qEnvironmentVariable("SNAP"); - auto scanJavaDirs = [&](const QString & dirPath) - { + auto scanJavaDirs = [&](const QString& dirPath) { scanJavaDir(dirPath); if (!snap.isNull()) { scanJavaDir(snap + dirPath); diff --git a/launcher/java/JavaUtils.h b/launcher/java/JavaUtils.h index 9b69b516e..616179706 100644 --- a/launcher/java/JavaUtils.h +++ b/launcher/java/JavaUtils.h @@ -27,10 +27,9 @@ QString stripVariableEntries(QString name, QString target, QString remove); QProcessEnvironment CleanEnviroment(); -class JavaUtils : public QObject -{ +class JavaUtils : public QObject { Q_OBJECT -public: + public: JavaUtils(); JavaInstallPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown"); diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index 7124e22fb..f9ac47824 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -5,27 +5,22 @@ #include #include -JavaVersion & JavaVersion::operator=(const QString & javaVersionString) +JavaVersion& JavaVersion::operator=(const QString& javaVersionString) { m_string = javaVersionString; - auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int - { + auto getCapturedInteger = [](const QRegularExpressionMatch& match, const QString& what) -> int { auto str = match.captured(what); - if(str.isEmpty()) - { + if (str.isEmpty()) { return 0; } return str.toInt(); }; QRegularExpression pattern; - if(javaVersionString.startsWith("1.")) - { - pattern = QRegularExpression ("1[.](?[0-9]+)([.](?[0-9]+))?(_(?[0-9]+)?)?(-(?[a-zA-Z0-9]+))?"); - } - else - { + if (javaVersionString.startsWith("1.")) { + pattern = QRegularExpression("1[.](?[0-9]+)([.](?[0-9]+))?(_(?[0-9]+)?)?(-(?[a-zA-Z0-9]+))?"); + } else { pattern = QRegularExpression("(?[0-9]+)([.](?[0-9]+))?([.](?[0-9]+))?(-(?[a-zA-Z0-9]+))?"); } @@ -38,7 +33,7 @@ JavaVersion & JavaVersion::operator=(const QString & javaVersionString) return *this; } -JavaVersion::JavaVersion(const QString &rhs) +JavaVersion::JavaVersion(const QString& rhs) { operator=(rhs); } @@ -50,73 +45,65 @@ QString JavaVersion::toString() const bool JavaVersion::requiresPermGen() { - if(m_parseable) - { + if (m_parseable) { return m_major < 8; } return true; } -bool JavaVersion::operator<(const JavaVersion &rhs) +bool JavaVersion::operator<(const JavaVersion& rhs) { - if(m_parseable && rhs.m_parseable) - { + if (m_parseable && rhs.m_parseable) { auto major = m_major; auto rmajor = rhs.m_major; // HACK: discourage using java 9 - if(major > 8) + if (major > 8) major = -major; - if(rmajor > 8) + if (rmajor > 8) rmajor = -rmajor; - if(major < rmajor) + if (major < rmajor) return true; - if(major > rmajor) + if (major > rmajor) return false; - if(m_minor < rhs.m_minor) + if (m_minor < rhs.m_minor) return true; - if(m_minor > rhs.m_minor) + if (m_minor > rhs.m_minor) return false; - if(m_security < rhs.m_security) + if (m_security < rhs.m_security) return true; - if(m_security > rhs.m_security) + if (m_security > rhs.m_security) return false; // everything else being equal, consider prerelease status bool thisPre = !m_prerelease.isEmpty(); bool rhsPre = !rhs.m_prerelease.isEmpty(); - if(thisPre && !rhsPre) - { + if (thisPre && !rhsPre) { // this is a prerelease and the other one isn't -> lesser return true; - } - else if(!thisPre && rhsPre) - { + } else if (!thisPre && rhsPre) { // this isn't a prerelease and the other one is -> greater return false; - } - else if(thisPre && rhsPre) - { + } else if (thisPre && rhsPre) { // both are prereleases - use natural compare... return StringUtils::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0; } // neither is prerelease, so they are the same -> this cannot be less than rhs return false; - } - else return StringUtils::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0; + } else + return StringUtils::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0; } -bool JavaVersion::operator==(const JavaVersion &rhs) +bool JavaVersion::operator==(const JavaVersion& rhs) { - if(m_parseable && rhs.m_parseable) - { + if (m_parseable && rhs.m_parseable) { return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease; } return m_string == rhs.m_string; } -bool JavaVersion::operator>(const JavaVersion &rhs) +bool JavaVersion::operator>(const JavaVersion& rhs) { return (!operator<(rhs)) && (!operator==(rhs)); } diff --git a/launcher/java/JavaVersion.h b/launcher/java/JavaVersion.h index c051a794a..694732033 100644 --- a/launcher/java/JavaVersion.h +++ b/launcher/java/JavaVersion.h @@ -4,42 +4,34 @@ // NOTE: apparently the GNU C library pollutes the global namespace with these... undef them. #ifdef major - #undef major +#undef major #endif #ifdef minor - #undef minor +#undef minor #endif -class JavaVersion -{ +class JavaVersion { friend class JavaVersionTest; -public: - JavaVersion() {}; - JavaVersion(const QString & rhs); - JavaVersion & operator=(const QString & rhs); + public: + JavaVersion(){}; + JavaVersion(const QString& rhs); - bool operator<(const JavaVersion & rhs); - bool operator==(const JavaVersion & rhs); - bool operator>(const JavaVersion & rhs); + JavaVersion& operator=(const QString& rhs); + + bool operator<(const JavaVersion& rhs); + bool operator==(const JavaVersion& rhs); + bool operator>(const JavaVersion& rhs); bool requiresPermGen(); QString toString() const; - int major() - { - return m_major; - } - int minor() - { - return m_minor; - } - int security() - { - return m_security; - } -private: + int major() { return m_major; } + int minor() { return m_minor; } + int security() { return m_security; } + + private: QString m_string; int m_major = 0; int m_minor = 0; diff --git a/launcher/launch/LaunchStep.cpp b/launcher/launch/LaunchStep.cpp index d6bb6e885..ebc534617 100644 --- a/launcher/launch/LaunchStep.cpp +++ b/launcher/launch/LaunchStep.cpp @@ -16,7 +16,7 @@ #include "LaunchStep.h" #include "LaunchTask.h" -void LaunchStep::bind(LaunchTask *parent) +void LaunchStep::bind(LaunchTask* parent) { m_parent = parent; connect(this, &LaunchStep::readyForLaunch, parent, &LaunchTask::onReadyForLaunch); diff --git a/launcher/launch/LaunchStep.h b/launcher/launch/LaunchStep.h index 3939f9604..b1bec2b4a 100644 --- a/launcher/launch/LaunchStep.h +++ b/launcher/launch/LaunchStep.h @@ -15,36 +15,32 @@ #pragma once -#include "tasks/Task.h" #include "MessageLevel.h" +#include "tasks/Task.h" #include class LaunchTask; -class LaunchStep: public Task -{ +class LaunchStep : public Task { Q_OBJECT -public: /* methods */ - explicit LaunchStep(LaunchTask *parent):Task(nullptr), m_parent(parent) - { - bind(parent); - }; - virtual ~LaunchStep() {}; + public: /* methods */ + explicit LaunchStep(LaunchTask* parent) : Task(nullptr), m_parent(parent) { bind(parent); }; + virtual ~LaunchStep(){}; -private: /* methods */ - void bind(LaunchTask *parent); + private: /* methods */ + void bind(LaunchTask* parent); -signals: + signals: void logLines(QStringList lines, MessageLevel::Enum level); void logLine(QString line, MessageLevel::Enum level); void readyForLaunch(); void progressReportingRequest(); -public slots: - virtual void proceed() {}; + public slots: + 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; + protected: /* data */ + LaunchTask* m_parent; }; diff --git a/launcher/launch/LaunchTask.cpp b/launcher/launch/LaunchTask.cpp index 9e1794b34..902801a10 100644 --- a/launcher/launch/LaunchTask.cpp +++ b/launcher/launch/LaunchTask.cpp @@ -36,16 +36,16 @@ */ #include "launch/LaunchTask.h" -#include "MessageLevel.h" -#include "java/JavaChecker.h" -#include "tasks/Task.h" +#include +#include #include #include #include #include -#include #include -#include +#include "MessageLevel.h" +#include "java/JavaChecker.h" +#include "tasks/Task.h" void LaunchTask::init() { @@ -59,9 +59,7 @@ shared_qobject_ptr LaunchTask::create(InstancePtr inst) return proc; } -LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance) -{ -} +LaunchTask::LaunchTask(InstancePtr instance) : m_instance(instance) {} void LaunchTask::appendStep(shared_qobject_ptr step) { @@ -76,8 +74,7 @@ void LaunchTask::prependStep(shared_qobject_ptr step) void LaunchTask::executeTask() { m_instance->setCrashed(false); - if(!m_steps.size()) - { + if (!m_steps.size()) { state = LaunchTask::Finished; emitSucceeded(); } @@ -94,46 +91,35 @@ void LaunchTask::onReadyForLaunch() void LaunchTask::onStepFinished() { // initial -> just start the first step - if(currentStep == -1) - { - currentStep ++; + if (currentStep == -1) { + currentStep++; m_steps[currentStep]->start(); return; } auto step = m_steps[currentStep]; - if(step->wasSuccessful()) - { + if (step->wasSuccessful()) { // end? - if(currentStep == m_steps.size() - 1) - { + if (currentStep == m_steps.size() - 1) { finalizeSteps(true, QString()); - } - else - { - currentStep ++; + } else { + currentStep++; step = m_steps[currentStep]; step->start(); } - } - else - { + } else { finalizeSteps(false, step->failReason()); } } void LaunchTask::finalizeSteps(bool successful, const QString& error) { - for(auto step = currentStep; step >= 0; step--) - { + for (auto step = currentStep; step >= 0; step--) { m_steps[step]->finalize(); } - if(successful) - { + if (successful) { emitSucceeded(); - } - else - { + } else { emitFailed(error); } } @@ -152,8 +138,7 @@ void LaunchTask::setCensorFilter(QMap filter) QString LaunchTask::censorPrivateInfo(QString in) { auto iter = m_censorFilter.begin(); - while (iter != m_censorFilter.end()) - { + while (iter != m_censorFilter.end()) { in.replace(iter.key(), iter.value()); iter++; } @@ -162,8 +147,7 @@ QString LaunchTask::censorPrivateInfo(QString in) void LaunchTask::proceed() { - if(state != LaunchTask::Waiting) - { + if (state != LaunchTask::Waiting) { return; } m_steps[currentStep]->proceed(); @@ -171,8 +155,7 @@ void LaunchTask::proceed() bool LaunchTask::canAbort() const { - switch(state) - { + switch (state) { case LaunchTask::Aborted: case LaunchTask::Failed: case LaunchTask::Finished: @@ -180,8 +163,7 @@ bool LaunchTask::canAbort() const case LaunchTask::NotStarted: return true; case LaunchTask::Running: - case LaunchTask::Waiting: - { + case LaunchTask::Waiting: { auto step = m_steps[currentStep]; return step->canAbort(); } @@ -191,28 +173,23 @@ bool LaunchTask::canAbort() const bool LaunchTask::abort() { - switch(state) - { + switch (state) { case LaunchTask::Aborted: case LaunchTask::Failed: case LaunchTask::Finished: return true; - case LaunchTask::NotStarted: - { + case LaunchTask::NotStarted: { state = LaunchTask::Aborted; emitFailed("Aborted"); return true; } case LaunchTask::Running: - case LaunchTask::Waiting: - { + case LaunchTask::Waiting: { auto step = m_steps[currentStep]; - if(!step->canAbort()) - { + if (!step->canAbort()) { return false; } - if(step->abort()) - { + if (step->abort()) { state = LaunchTask::Aborted; return true; } @@ -225,23 +202,22 @@ bool LaunchTask::abort() shared_qobject_ptr LaunchTask::getLogModel() { - if(!m_logModel) - { + if (!m_logModel) { m_logModel.reset(new LogModel()); m_logModel->setMaxLines(m_instance->getConsoleMaxLines()); m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow()); // FIXME: should this really be here? m_logModel->setOverflowMessage(tr("Stopped watching the game log because the log length surpassed %1 lines.\n" - "You may have to fix your mods because the game is still logging to files and" - " likely wasting harddrive space at an alarming rate!").arg(m_logModel->getMaxLines())); + "You may have to fix your mods because the game is still logging to files and" + " likely wasting harddrive space at an alarming rate!") + .arg(m_logModel->getMaxLines())); } return m_logModel; } -void LaunchTask::onLogLines(const QStringList &lines, MessageLevel::Enum defaultLevel) +void LaunchTask::onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel) { - for (auto & line: lines) - { + for (auto& line : lines) { onLogLine(line, defaultLevel); } } @@ -250,21 +226,19 @@ void LaunchTask::onLogLine(QString line, MessageLevel::Enum level) { // if the launcher part set a log level, use it auto innerLevel = MessageLevel::fromLine(line); - if(innerLevel != MessageLevel::Unknown) - { + if (innerLevel != MessageLevel::Unknown) { level = innerLevel; } // If the level is still undetermined, guess level - if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) - { + if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) { level = m_instance->guessLevel(line, level); } // censor private user info line = censorPrivateInfo(line); - auto &model = *getLogModel(); + auto& model = *getLogModel(); model.append(level, line); } @@ -281,22 +255,20 @@ void LaunchTask::emitFailed(QString reason) Task::emitFailed(reason); } -void LaunchTask::substituteVariables(QStringList &args) const +void LaunchTask::substituteVariables(QStringList& args) const { auto env = m_instance->createEnvironment(); - for (auto key : env.keys()) - { + for (auto key : env.keys()) { args.replaceInStrings("$" + key, env.value(key)); } } -void LaunchTask::substituteVariables(QString &cmd) const +void LaunchTask::substituteVariables(QString& cmd) const { auto env = m_instance->createEnvironment(); - for (auto key : env.keys()) - { + for (auto key : env.keys()) { cmd.replace("$" + key, env.value(key)); } } diff --git a/launcher/launch/LaunchTask.h b/launcher/launch/LaunchTask.h index 9c72b23f0..40a3324ba 100644 --- a/launcher/launch/LaunchTask.h +++ b/launcher/launch/LaunchTask.h @@ -36,54 +36,36 @@ */ #pragma once -#include #include -#include "LogModel.h" +#include #include "BaseInstance.h" -#include "MessageLevel.h" -#include "LoggedProcess.h" #include "LaunchStep.h" +#include "LogModel.h" +#include "LoggedProcess.h" +#include "MessageLevel.h" -class LaunchTask: public Task -{ +class LaunchTask : public Task { Q_OBJECT -protected: + protected: explicit LaunchTask(InstancePtr instance); void init(); -public: - enum State - { - NotStarted, - Running, - Waiting, - Failed, - Aborted, - Finished - }; + public: + enum State { NotStarted, Running, Waiting, Failed, Aborted, Finished }; -public: /* methods */ + 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); void setCensorFilter(QMap filter); - InstancePtr instance() - { - return m_instance; - } + InstancePtr instance() { return m_instance; } - void setPid(qint64 pid) - { - m_pid = pid; - } + void setPid(qint64 pid) { m_pid = pid; } - qint64 pid() - { - return m_pid; - } + qint64 pid() { return m_pid; } /** * @brief prepare the process for launch (for multi-stage launch) @@ -104,39 +86,39 @@ public: /* methods */ shared_qobject_ptr getLogModel(); -public: - void substituteVariables(QStringList &args) const; - void substituteVariables(QString &cmd) const; + public: + void substituteVariables(QStringList& args) const; + void substituteVariables(QString& cmd) const; QString censorPrivateInfo(QString in); -protected: /* methods */ + protected: /* methods */ virtual void emitFailed(QString reason) override; virtual void emitSucceeded() override; -signals: + signals: /** * @brief emitted when the launch preparations are done */ void readyForLaunch(); - void requestProgress(Task *task); + void requestProgress(Task* task); void requestLogging(); -public slots: + public slots: void onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel = MessageLevel::Launcher); void onLogLine(QString line, MessageLevel::Enum defaultLevel = MessageLevel::Launcher); void onReadyForLaunch(); void onStepFinished(); void onProgressReportingRequested(); -private: /*methods */ - void finalizeSteps(bool successful, const QString & error); + private: /*methods */ + void finalizeSteps(bool successful, const QString& error); -protected: /* data */ + protected: /* data */ InstancePtr m_instance; shared_qobject_ptr m_logModel; - QList > m_steps; + QList> m_steps; QMap m_censorFilter; int currentStep = -1; State state = NotStarted; diff --git a/launcher/launch/LogModel.cpp b/launcher/launch/LogModel.cpp index 92f9487a9..23a33ae18 100644 --- a/launcher/launch/LogModel.cpp +++ b/launcher/launch/LogModel.cpp @@ -1,11 +1,11 @@ #include "LogModel.h" -LogModel::LogModel(QObject *parent):QAbstractListModel(parent) +LogModel::LogModel(QObject* parent) : QAbstractListModel(parent) { m_content.resize(m_maxLines); } -int LogModel::rowCount(const QModelIndex &parent) const +int LogModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; @@ -13,19 +13,17 @@ int LogModel::rowCount(const QModelIndex &parent) const return m_numLines; } -QVariant LogModel::data(const QModelIndex &index, int role) const +QVariant LogModel::data(const QModelIndex& index, int role) const { if (index.row() < 0 || index.row() >= m_numLines) return QVariant(); auto row = index.row(); auto realRow = (row + m_firstLine) % m_maxLines; - if (role == Qt::DisplayRole || role == Qt::EditRole) - { + if (role == Qt::DisplayRole || role == Qt::EditRole) { return m_content[realRow].line; } - if(role == LevelRole) - { + if (role == LevelRole) { return m_content[realRow].level; } @@ -34,31 +32,26 @@ QVariant LogModel::data(const QModelIndex &index, int role) const void LogModel::append(MessageLevel::Enum level, QString line) { - if(m_suspended) - { + if (m_suspended) { return; } int lineNum = (m_firstLine + m_numLines) % m_maxLines; // overflow - if(m_numLines == m_maxLines) - { - if(m_stopOnOverflow) - { + if (m_numLines == m_maxLines) { + if (m_stopOnOverflow) { // nothing more to do, the buffer is full return; } beginRemoveRows(QModelIndex(), 0, 0); m_firstLine = (m_firstLine + 1) % m_maxLines; - m_numLines --; + m_numLines--; endRemoveRows(); - } - else if (m_numLines == m_maxLines - 1 && m_stopOnOverflow) - { + } else if (m_numLines == m_maxLines - 1 && m_stopOnOverflow) { level = MessageLevel::Fatal; line = m_overflowMessage; } beginInsertRows(QModelIndex(), m_numLines, m_numLines); - m_numLines ++; + m_numLines++; m_content[lineNum].level = level; m_content[lineNum].line = line; endInsertRows(); @@ -86,9 +79,8 @@ QString LogModel::toPlainText() { QString out; out.reserve(m_numLines * 80); - for(int i = 0; i < m_numLines; i++) - { - QString & line = m_content[(m_firstLine + i) % m_maxLines].line; + for (int i = 0; i < m_numLines; i++) { + QString& line = m_content[(m_firstLine + i) % m_maxLines].line; out.append(line + '\n'); } out.squeeze(); @@ -98,13 +90,11 @@ QString LogModel::toPlainText() void LogModel::setMaxLines(int maxLines) { // no-op - if(maxLines == m_maxLines) - { + if (maxLines == m_maxLines) { return; } // if it all still fits in the buffer, just resize it - if(m_firstLine + m_numLines < m_maxLines) - { + if (m_firstLine + m_numLines < m_maxLines) { m_maxLines = maxLines; m_content.resize(maxLines); return; @@ -112,22 +102,17 @@ void LogModel::setMaxLines(int maxLines) // otherwise, we need to reorganize the data because it crosses the wrap boundary QVector newContent; newContent.resize(maxLines); - if(m_numLines <= maxLines) - { + if (m_numLines <= maxLines) { // if it all fits in the new buffer, just copy it over - for(int i = 0; i < m_numLines; i++) - { + for (int i = 0; i < m_numLines; i++) { newContent[i] = m_content[(m_firstLine + i) % m_maxLines]; } m_content.swap(newContent); - } - else - { + } else { // if it doesn't fit, part of the data needs to be thrown away (the oldest log messages) int lead = m_numLines - maxLines; beginRemoveRows(QModelIndex(), 0, lead - 1); - for(int i = 0; i < maxLines; i++) - { + for (int i = 0; i < maxLines; i++) { newContent[i] = m_content[(m_firstLine + lead + i) % m_maxLines]; } m_numLines = m_maxLines; @@ -155,8 +140,7 @@ void LogModel::setOverflowMessage(const QString& overflowMessage) void LogModel::setLineWrap(bool state) { - if(m_lineWrap != state) - { + if (m_lineWrap != state) { m_lineWrap = state; } } diff --git a/launcher/launch/LogModel.h b/launcher/launch/LogModel.h index 6aabc8236..ba2e4054a 100644 --- a/launcher/launch/LogModel.h +++ b/launcher/launch/LogModel.h @@ -4,14 +4,13 @@ #include #include "MessageLevel.h" -class LogModel : public QAbstractListModel -{ +class LogModel : public QAbstractListModel { Q_OBJECT -public: - explicit LogModel(QObject *parent = 0); + public: + explicit LogModel(QObject* parent = 0); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + QVariant data(const QModelIndex& index, int role) const; void append(MessageLevel::Enum, QString line); void clear(); @@ -24,25 +23,21 @@ public: int getMaxLines(); void setMaxLines(int maxLines); void setStopOnOverflow(bool stop); - void setOverflowMessage(const QString & overflowMessage); + void setOverflowMessage(const QString& overflowMessage); void setLineWrap(bool state); bool wrapLines() const; - enum Roles - { - LevelRole = Qt::UserRole - }; + enum Roles { LevelRole = Qt::UserRole }; -private /* types */: - struct entry - { + private /* types */: + struct entry { MessageLevel::Enum level; QString line; }; -private: /* data */ - QVector m_content; + private: /* data */ + QVector m_content; int m_maxLines = 1000; // first line in the circular buffer int m_firstLine = 0; @@ -53,6 +48,6 @@ private: /* data */ bool m_suspended = false; bool m_lineWrap = true; -private: + private: Q_DISABLE_COPY(LogModel) }; diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index 7d697ba96..7fd8fc331 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -34,12 +34,12 @@ */ #include "CheckJava.h" -#include "java/JavaUtils.h" -#include #include -#include -#include +#include #include +#include +#include +#include "java/JavaUtils.h" void CheckJava::executeTask() { @@ -49,32 +49,26 @@ void CheckJava::executeTask() bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool(); auto realJavaPath = QStandardPaths::findExecutable(m_javaPath); - if (realJavaPath.isEmpty()) - { - if (perInstance) - { - emit logLine( - QString("The java binary \"%1\" couldn't be found. Please fix the java path " - "override in the instance's settings or disable it.").arg(m_javaPath), - MessageLevel::Warning); - } - else - { + if (realJavaPath.isEmpty()) { + if (perInstance) { + emit logLine(QString("The java binary \"%1\" couldn't be found. Please fix the java path " + "override in the instance's settings or disable it.") + .arg(m_javaPath), + MessageLevel::Warning); + } else { emit logLine(QString("The java binary \"%1\" couldn't be found. Please set up java in " - "the settings.").arg(m_javaPath), + "the settings.") + .arg(m_javaPath), MessageLevel::Warning); } emitFailed(QString("Java path is not valid.")); return; - } - else - { + } else { emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::Launcher); } - if (JavaUtils::getJavaCheckPath().isEmpty()) - { - const char *reason = QT_TR_NOOP("Java checker library could not be found. Please check your installation."); + if (JavaUtils::getJavaCheckPath().isEmpty()) { + const char* reason = QT_TR_NOOP("Java checker library could not be found. Please check your installation."); emit logLine(tr(reason), MessageLevel::Fatal); emitFailed(tr(reason)); return; @@ -94,19 +88,15 @@ void CheckJava::executeTask() m_javaSignature = hash.result().toHex(); // if timestamps are not the same, or something is missing, check! - if (m_javaSignature != storedSignature || storedVersion.size() == 0 - || storedArchitecture.size() == 0 || storedRealArchitecture.size() == 0 - || storedVendor.size() == 0) - { + if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 || + storedRealArchitecture.size() == 0 || storedVendor.size() == 0) { m_JavaChecker.reset(new JavaChecker); emit logLine(QString("Checking Java version..."), MessageLevel::Launcher); connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished); m_JavaChecker->m_path = realJavaPath; m_JavaChecker->performCheck(); return; - } - else - { + } else { auto verString = instance->settings()->get("JavaVersion").toString(); auto archString = instance->settings()->get("JavaArchitecture").toString(); auto realArchString = settings->get("JavaRealArchitecture").toString(); @@ -118,10 +108,8 @@ void CheckJava::executeTask() void CheckJava::checkJavaFinished(JavaCheckResult result) { - switch (result.validity) - { - case JavaCheckResult::Validity::Errored: - { + switch (result.validity) { + case JavaCheckResult::Validity::Errored: { // Error message displayed if java can't start emit logLine(QString("Could not start java:"), MessageLevel::Error); emit logLines(result.errorLog.split('\n'), MessageLevel::Error); @@ -129,16 +117,14 @@ void CheckJava::checkJavaFinished(JavaCheckResult result) emitFailed(QString("Could not start java!")); return; } - case JavaCheckResult::Validity::ReturnedInvalidData: - { + case JavaCheckResult::Validity::ReturnedInvalidData: { emit logLine(QString("Java checker returned some invalid data we don't understand:"), MessageLevel::Error); emit logLines(result.outLog.split('\n'), MessageLevel::Warning); emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher); emitSucceeded(); return; } - case JavaCheckResult::Validity::Valid: - { + case JavaCheckResult::Validity::Valid: { auto instance = m_parent->instance(); printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, result.realPlatform, result.javaVendor); instance->settings()->set("JavaVersion", result.javaVersion.toString()); @@ -152,8 +138,9 @@ void CheckJava::checkJavaFinished(JavaCheckResult result) } } -void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString & vendor) +void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString& vendor) { - emit logLine(QString("Java is version %1, using %2 (%3) architecture, from %4.\n\n") - .arg(version, architecture, realArchitecture, vendor), MessageLevel::Launcher); + emit logLine( + QString("Java is version %1, using %2 (%3) architecture, from %4.\n\n").arg(version, architecture, realArchitecture, vendor), + MessageLevel::Launcher); } diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h index bbf06b7c7..4436e2a55 100644 --- a/launcher/launch/steps/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h @@ -15,30 +15,26 @@ #pragma once -#include #include #include +#include -class CheckJava: public LaunchStep -{ +class CheckJava : public LaunchStep { Q_OBJECT -public: - explicit CheckJava(LaunchTask *parent) :LaunchStep(parent){}; - virtual ~CheckJava() {}; + public: + explicit CheckJava(LaunchTask* parent) : LaunchStep(parent){}; + virtual ~CheckJava(){}; virtual void executeTask(); - virtual bool canAbort() const - { - return false; - } -private slots: + virtual bool canAbort() const { return false; } + private slots: void checkJavaFinished(JavaCheckResult result); -private: - void printJavaInfo(const QString & version, const QString & architecture, const QString & realArchitecture, const QString & vendor); + private: + void printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString& vendor); void printSystemInfo(bool javaIsKnown, bool javaIs64bit); -private: + private: QString m_javaPath; QString m_javaSignature; JavaCheckerPtr m_JavaChecker; diff --git a/launcher/launch/steps/LookupServerAddress.cpp b/launcher/launch/steps/LookupServerAddress.cpp index c7b8cea47..9bdac203b 100644 --- a/launcher/launch/steps/LookupServerAddress.cpp +++ b/launcher/launch/steps/LookupServerAddress.cpp @@ -13,20 +13,18 @@ * limitations under the License. */ - #include "LookupServerAddress.h" #include -LookupServerAddress::LookupServerAddress(LaunchTask *parent) : - LaunchStep(parent), m_dnsLookup(new QDnsLookup(this)) +LookupServerAddress::LookupServerAddress(LaunchTask* parent) : LaunchStep(parent), m_dnsLookup(new QDnsLookup(this)) { connect(m_dnsLookup, &QDnsLookup::finished, this, &LookupServerAddress::on_dnsLookupFinished); m_dnsLookup->setType(QDnsLookup::SRV); } -void LookupServerAddress::setLookupAddress(const QString &lookupAddress) +void LookupServerAddress::setLookupAddress(const QString& lookupAddress) { m_lookupAddress = lookupAddress; m_dnsLookup->setName(QString("_minecraft._tcp.%1").arg(lookupAddress)); @@ -51,41 +49,40 @@ void LookupServerAddress::executeTask() void LookupServerAddress::on_dnsLookupFinished() { - if (isFinished()) - { + if (isFinished()) { // Aborted return; } - if (m_dnsLookup->error() != QDnsLookup::NoError) - { + if (m_dnsLookup->error() != QDnsLookup::NoError) { emit logLine(QString("Failed to resolve server address (this is NOT an error!) %1: %2\n") - .arg(m_dnsLookup->name(), m_dnsLookup->errorString()), MessageLevel::Launcher); - resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch - // and leave it up to minecraft to fail (or maybe not) when connecting + .arg(m_dnsLookup->name(), m_dnsLookup->errorString()), + MessageLevel::Launcher); + resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch + // and leave it up to minecraft to fail (or maybe not) when connecting return; } const auto records = m_dnsLookup->serviceRecords(); - if (records.empty()) - { - emit logLine( - QString("Failed to resolve server address %1: the DNS lookup succeeded, but no records were returned.\n") - .arg(m_dnsLookup->name()), MessageLevel::Warning); - resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch - // and leave it up to minecraft to fail (or maybe not) when connecting + if (records.empty()) { + emit logLine(QString("Failed to resolve server address %1: the DNS lookup succeeded, but no records were returned.\n") + .arg(m_dnsLookup->name()), + MessageLevel::Warning); + resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch + // and leave it up to minecraft to fail (or maybe not) when connecting return; } - const auto &firstRecord = records.at(0); + const auto& firstRecord = records.at(0); quint16 port = firstRecord.port(); - emit logLine(QString("Resolved server address %1 to %2 with port %3\n").arg( - m_dnsLookup->name(), firstRecord.target(), QString::number(port)),MessageLevel::Launcher); + emit logLine( + QString("Resolved server address %1 to %2 with port %3\n").arg(m_dnsLookup->name(), firstRecord.target(), QString::number(port)), + MessageLevel::Launcher); resolve(firstRecord.target(), port); } -void LookupServerAddress::resolve(const QString &address, quint16 port) +void LookupServerAddress::resolve(const QString& address, quint16 port) { m_output->address = address; m_output->port = port; diff --git a/launcher/launch/steps/LookupServerAddress.h b/launcher/launch/steps/LookupServerAddress.h index 5a5c3de17..abd92a5e8 100644 --- a/launcher/launch/steps/LookupServerAddress.h +++ b/launcher/launch/steps/LookupServerAddress.h @@ -15,35 +15,32 @@ #pragma once -#include #include +#include #include #include "minecraft/launch/MinecraftServerTarget.h" -class LookupServerAddress: public LaunchStep { -Q_OBJECT -public: - explicit LookupServerAddress(LaunchTask *parent); - virtual ~LookupServerAddress() {}; +class LookupServerAddress : public LaunchStep { + Q_OBJECT + public: + explicit LookupServerAddress(LaunchTask* parent); + virtual ~LookupServerAddress(){}; virtual void executeTask(); virtual bool abort(); - virtual bool canAbort() const - { - return true; - } + virtual bool canAbort() const { return true; } - void setLookupAddress(const QString &lookupAddress); + void setLookupAddress(const QString& lookupAddress); void setOutputAddressPtr(MinecraftServerTargetPtr output); -private slots: + private slots: void on_dnsLookupFinished(); -private: - void resolve(const QString &address, quint16 port); + private: + void resolve(const QString& address, quint16 port); - QDnsLookup *m_dnsLookup; + QDnsLookup* m_dnsLookup; QString m_lookupAddress; MinecraftServerTargetPtr m_output; }; diff --git a/launcher/launch/steps/PostLaunchCommand.cpp b/launcher/launch/steps/PostLaunchCommand.cpp index ccf07f220..2e59de630 100644 --- a/launcher/launch/steps/PostLaunchCommand.cpp +++ b/launcher/launch/steps/PostLaunchCommand.cpp @@ -36,7 +36,7 @@ #include "PostLaunchCommand.h" #include -PostLaunchCommand::PostLaunchCommand(LaunchTask *parent) : LaunchStep(parent) +PostLaunchCommand::PostLaunchCommand(LaunchTask* parent) : LaunchStep(parent) { auto instance = m_parent->instance(); m_command = instance->getPostExitCommand(); @@ -47,7 +47,7 @@ PostLaunchCommand::PostLaunchCommand(LaunchTask *parent) : LaunchStep(parent) void PostLaunchCommand::executeTask() { - //FIXME: where to put this? + // FIXME: where to put this? #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) auto args = QProcess::splitCommand(m_command); m_parent->substituteVariables(args); @@ -65,31 +65,22 @@ void PostLaunchCommand::executeTask() void PostLaunchCommand::on_state(LoggedProcess::State state) { - auto getError = [&]() - { - return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode()); - }; - switch(state) - { + auto getError = [&]() { return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode()); }; + switch (state) { case LoggedProcess::Aborted: case LoggedProcess::Crashed: - case LoggedProcess::FailedToStart: - { + case LoggedProcess::FailedToStart: { auto error = getError(); emit logLine(error, MessageLevel::Fatal); emitFailed(error); return; } - case LoggedProcess::Finished: - { - if(m_process.exitCode() != 0) - { + case LoggedProcess::Finished: { + if (m_process.exitCode() != 0) { auto error = getError(); emit logLine(error, MessageLevel::Fatal); emitFailed(error); - } - else - { + } else { emit logLine(tr("Post-Launch command ran successfully.\n\n"), MessageLevel::Launcher); emitSucceeded(); } @@ -99,7 +90,7 @@ void PostLaunchCommand::on_state(LoggedProcess::State state) } } -void PostLaunchCommand::setWorkingDirectory(const QString &wd) +void PostLaunchCommand::setWorkingDirectory(const QString& wd) { m_process.setWorkingDirectory(wd); } @@ -107,8 +98,7 @@ void PostLaunchCommand::setWorkingDirectory(const QString &wd) bool PostLaunchCommand::abort() { auto state = m_process.state(); - if (state == LoggedProcess::Running || state == LoggedProcess::Starting) - { + if (state == LoggedProcess::Running || state == LoggedProcess::Starting) { m_process.kill(); } return true; diff --git a/launcher/launch/steps/PostLaunchCommand.h b/launcher/launch/steps/PostLaunchCommand.h index ab4c494f5..578433b86 100644 --- a/launcher/launch/steps/PostLaunchCommand.h +++ b/launcher/launch/steps/PostLaunchCommand.h @@ -15,27 +15,23 @@ #pragma once -#include #include +#include -class PostLaunchCommand: public LaunchStep -{ +class PostLaunchCommand : public LaunchStep { Q_OBJECT -public: - explicit PostLaunchCommand(LaunchTask *parent); - virtual ~PostLaunchCommand() {}; + public: + explicit PostLaunchCommand(LaunchTask* parent); + virtual ~PostLaunchCommand(){}; virtual void executeTask(); virtual bool abort(); - virtual bool canAbort() const - { - return true; - } - void setWorkingDirectory(const QString &wd); -private slots: + virtual bool canAbort() const { return true; } + void setWorkingDirectory(const QString& wd); + private slots: void on_state(LoggedProcess::State state); -private: + private: LoggedProcess m_process; QString m_command; }; diff --git a/launcher/launch/steps/PreLaunchCommand.cpp b/launcher/launch/steps/PreLaunchCommand.cpp index 0b0392cbb..a7f36086b 100644 --- a/launcher/launch/steps/PreLaunchCommand.cpp +++ b/launcher/launch/steps/PreLaunchCommand.cpp @@ -36,7 +36,7 @@ #include "PreLaunchCommand.h" #include -PreLaunchCommand::PreLaunchCommand(LaunchTask *parent) : LaunchStep(parent) +PreLaunchCommand::PreLaunchCommand(LaunchTask* parent) : LaunchStep(parent) { auto instance = m_parent->instance(); m_command = instance->getPreLaunchCommand(); @@ -47,7 +47,7 @@ PreLaunchCommand::PreLaunchCommand(LaunchTask *parent) : LaunchStep(parent) void PreLaunchCommand::executeTask() { - //FIXME: where to put this? + // FIXME: where to put this? #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) auto args = QProcess::splitCommand(m_command); m_parent->substituteVariables(args); @@ -65,31 +65,22 @@ void PreLaunchCommand::executeTask() void PreLaunchCommand::on_state(LoggedProcess::State state) { - auto getError = [&]() - { - return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode()); - }; - switch(state) - { + auto getError = [&]() { return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode()); }; + switch (state) { case LoggedProcess::Aborted: case LoggedProcess::Crashed: - case LoggedProcess::FailedToStart: - { + case LoggedProcess::FailedToStart: { auto error = getError(); emit logLine(error, MessageLevel::Fatal); emitFailed(error); return; } - case LoggedProcess::Finished: - { - if(m_process.exitCode() != 0) - { + case LoggedProcess::Finished: { + if (m_process.exitCode() != 0) { auto error = getError(); emit logLine(error, MessageLevel::Fatal); emitFailed(error); - } - else - { + } else { emit logLine(tr("Pre-Launch command ran successfully.\n\n"), MessageLevel::Launcher); emitSucceeded(); } @@ -99,7 +90,7 @@ void PreLaunchCommand::on_state(LoggedProcess::State state) } } -void PreLaunchCommand::setWorkingDirectory(const QString &wd) +void PreLaunchCommand::setWorkingDirectory(const QString& wd) { m_process.setWorkingDirectory(wd); } @@ -107,8 +98,7 @@ void PreLaunchCommand::setWorkingDirectory(const QString &wd) bool PreLaunchCommand::abort() { auto state = m_process.state(); - if (state == LoggedProcess::Running || state == LoggedProcess::Starting) - { + if (state == LoggedProcess::Running || state == LoggedProcess::Starting) { m_process.kill(); } return true; diff --git a/launcher/launch/steps/PreLaunchCommand.h b/launcher/launch/steps/PreLaunchCommand.h index dc069f71b..10568ea34 100644 --- a/launcher/launch/steps/PreLaunchCommand.h +++ b/launcher/launch/steps/PreLaunchCommand.h @@ -15,27 +15,23 @@ #pragma once -#include "launch/LaunchStep.h" #include "LoggedProcess.h" +#include "launch/LaunchStep.h" -class PreLaunchCommand: public LaunchStep -{ +class PreLaunchCommand : public LaunchStep { Q_OBJECT -public: - explicit PreLaunchCommand(LaunchTask *parent); - virtual ~PreLaunchCommand() {}; + public: + explicit PreLaunchCommand(LaunchTask* parent); + virtual ~PreLaunchCommand(){}; virtual void executeTask(); virtual bool abort(); - virtual bool canAbort() const - { - return true; - } - void setWorkingDirectory(const QString &wd); -private slots: + virtual bool canAbort() const { return true; } + void setWorkingDirectory(const QString& wd); + private slots: void on_state(LoggedProcess::State state); -private: + private: LoggedProcess m_process; QString m_command; }; diff --git a/launcher/launch/steps/QuitAfterGameStop.h b/launcher/launch/steps/QuitAfterGameStop.h index 1ce14da95..5f5e63048 100644 --- a/launcher/launch/steps/QuitAfterGameStop.h +++ b/launcher/launch/steps/QuitAfterGameStop.h @@ -20,16 +20,12 @@ #include -class QuitAfterGameStop: public LaunchStep -{ +class QuitAfterGameStop : public LaunchStep { Q_OBJECT -public: - explicit QuitAfterGameStop(LaunchTask *parent) :LaunchStep(parent){}; - virtual ~QuitAfterGameStop() {}; + public: + explicit QuitAfterGameStop(LaunchTask* parent) : LaunchStep(parent){}; + virtual ~QuitAfterGameStop(){}; virtual void executeTask(); - virtual bool canAbort() const - { - return false; - } + virtual bool canAbort() const { return false; } }; diff --git a/launcher/launch/steps/TextPrint.cpp b/launcher/launch/steps/TextPrint.cpp index 0c1f320c3..0dec35b79 100644 --- a/launcher/launch/steps/TextPrint.cpp +++ b/launcher/launch/steps/TextPrint.cpp @@ -1,11 +1,11 @@ #include "TextPrint.h" -TextPrint::TextPrint(LaunchTask * parent, const QStringList &lines, MessageLevel::Enum level) : LaunchStep(parent) +TextPrint::TextPrint(LaunchTask* parent, const QStringList& lines, MessageLevel::Enum level) : LaunchStep(parent) { m_lines = lines; m_level = level; } -TextPrint::TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level) : LaunchStep(parent) +TextPrint::TextPrint(LaunchTask* parent, const QString& line, MessageLevel::Enum level) : LaunchStep(parent) { m_lines.append(line); m_level = level; diff --git a/launcher/launch/steps/TextPrint.h b/launcher/launch/steps/TextPrint.h index 36fa7f9a9..bd6c28567 100644 --- a/launcher/launch/steps/TextPrint.h +++ b/launcher/launch/steps/TextPrint.h @@ -15,27 +15,26 @@ #pragma once -#include #include #include +#include /* * FIXME: maybe do not export */ -class TextPrint: public LaunchStep -{ +class TextPrint : public LaunchStep { Q_OBJECT -public: - explicit TextPrint(LaunchTask *parent, const QStringList &lines, MessageLevel::Enum level); - explicit TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level); + public: + explicit TextPrint(LaunchTask* parent, const QStringList& lines, MessageLevel::Enum level); + explicit TextPrint(LaunchTask* parent, const QString& line, MessageLevel::Enum level); virtual ~TextPrint(){}; virtual void executeTask(); virtual bool canAbort() const; virtual bool abort(); -private: + private: QStringList m_lines; MessageLevel::Enum m_level; }; diff --git a/launcher/launch/steps/Update.cpp b/launcher/launch/steps/Update.cpp index 8df2bc67c..f23c0bb4b 100644 --- a/launcher/launch/steps/Update.cpp +++ b/launcher/launch/steps/Update.cpp @@ -18,14 +18,12 @@ void Update::executeTask() { - if(m_aborted) - { + if (m_aborted) { emitFailed(tr("Task aborted.")); return; } m_updateTask.reset(m_parent->instance()->createUpdateTask(m_mode)); - if(m_updateTask) - { + if (m_updateTask) { connect(m_updateTask.get(), &Task::finished, this, &Update::updateFinished); connect(m_updateTask.get(), &Task::progress, this, &Update::setProgress); connect(m_updateTask.get(), &Task::stepProgress, this, &Update::propagateStepProgress); @@ -44,13 +42,10 @@ void Update::proceed() void Update::updateFinished() { - if(m_updateTask->wasSuccessful()) - { + if (m_updateTask->wasSuccessful()) { m_updateTask.reset(); emitSucceeded(); - } - else - { + } else { QString reason = tr("Instance update failed because: %1\n\n").arg(m_updateTask->failReason()); m_updateTask.reset(); emit logLine(reason, MessageLevel::Fatal); @@ -60,21 +55,17 @@ void Update::updateFinished() bool Update::canAbort() const { - if(m_updateTask) - { + if (m_updateTask) { return m_updateTask->canAbort(); } return true; } - bool Update::abort() { m_aborted = true; - if(m_updateTask) - { - if(m_updateTask->canAbort()) - { + if (m_updateTask) { + if (m_updateTask->canAbort()) { return m_updateTask->abort(); } } diff --git a/launcher/launch/steps/Update.h b/launcher/launch/steps/Update.h index ce40611e0..9262cdbe4 100644 --- a/launcher/launch/steps/Update.h +++ b/launcher/launch/steps/Update.h @@ -15,30 +15,29 @@ #pragma once -#include -#include #include +#include #include +#include #include // FIXME: stupid. should be defined by the instance type? or even completely abstracted away... -class Update: public LaunchStep -{ +class Update : public LaunchStep { Q_OBJECT -public: - explicit Update(LaunchTask *parent, Net::Mode mode):LaunchStep(parent), m_mode(mode) {}; - virtual ~Update() {}; + public: + explicit Update(LaunchTask* parent, Net::Mode mode) : LaunchStep(parent), m_mode(mode){}; + virtual ~Update(){}; void executeTask() override; bool canAbort() const override; void proceed() override; -public slots: + public slots: bool abort() override; -private slots: + private slots: void updateFinished(); -private: + private: Task::Ptr m_updateTask; bool m_aborted = false; Net::Mode m_mode = Net::Mode::Offline; diff --git a/launcher/main.cpp b/launcher/main.cpp index b63f8bfd0..31551f998 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -40,15 +40,14 @@ // #define BREAK_RETURN #ifdef BREAK_INFINITE_LOOP -#include #include +#include #endif -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { #ifdef BREAK_INFINITE_LOOP - while(true) - { + while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(250)); } #endif @@ -67,33 +66,31 @@ int main(int argc, char *argv[]) // initialize Qt Application app(argc, argv); - switch (app.status()) - { - case Application::StartingUp: - case Application::Initialized: - { - Q_INIT_RESOURCE(multimc); - Q_INIT_RESOURCE(backgrounds); - Q_INIT_RESOURCE(documents); - Q_INIT_RESOURCE(prismlauncher); + switch (app.status()) { + case Application::StartingUp: + case Application::Initialized: { + Q_INIT_RESOURCE(multimc); + Q_INIT_RESOURCE(backgrounds); + Q_INIT_RESOURCE(documents); + Q_INIT_RESOURCE(prismlauncher); - Q_INIT_RESOURCE(pe_dark); - Q_INIT_RESOURCE(pe_light); - Q_INIT_RESOURCE(pe_blue); - Q_INIT_RESOURCE(pe_colored); - Q_INIT_RESOURCE(breeze_dark); - Q_INIT_RESOURCE(breeze_light); - Q_INIT_RESOURCE(OSX); - Q_INIT_RESOURCE(iOS); - Q_INIT_RESOURCE(flat); - Q_INIT_RESOURCE(flat_white); - return app.exec(); - } - case Application::Failed: - return 1; - case Application::Succeeded: - return 0; - default: - return -1; + Q_INIT_RESOURCE(pe_dark); + Q_INIT_RESOURCE(pe_light); + Q_INIT_RESOURCE(pe_blue); + Q_INIT_RESOURCE(pe_colored); + Q_INIT_RESOURCE(breeze_dark); + Q_INIT_RESOURCE(breeze_light); + Q_INIT_RESOURCE(OSX); + Q_INIT_RESOURCE(iOS); + Q_INIT_RESOURCE(flat); + Q_INIT_RESOURCE(flat_white); + return app.exec(); + } + case Application::Failed: + return 1; + case Application::Succeeded: + return 0; + default: + return -1; } } diff --git a/launcher/meta/BaseEntity.cpp b/launcher/meta/BaseEntity.cpp index 97815eba8..d8003b55a 100644 --- a/launcher/meta/BaseEntity.cpp +++ b/launcher/meta/BaseEntity.cpp @@ -15,74 +15,55 @@ #include "BaseEntity.h" +#include "Json.h" #include "net/Download.h" #include "net/HttpMetaCache.h" #include "net/NetJob.h" -#include "Json.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" -class ParsingValidator : public Net::Validator -{ -public: /* con/des */ - ParsingValidator(Meta::BaseEntity *entity) : m_entity(entity) - { - }; - virtual ~ParsingValidator() - { - }; +class ParsingValidator : public Net::Validator { + public: /* con/des */ + ParsingValidator(Meta::BaseEntity* entity) : m_entity(entity){}; + virtual ~ParsingValidator(){}; -public: /* methods */ - bool init(QNetworkRequest &) override - { - return true; - } - bool write(QByteArray & data) override + public: /* methods */ + bool init(QNetworkRequest&) override { return true; } + bool write(QByteArray& data) override { this->data.append(data); return true; } - bool abort() override - { - return true; - } - bool validate(QNetworkReply &) override + bool abort() override { return true; } + bool validate(QNetworkReply&) override { auto fname = m_entity->localFilename(); - try - { + try { auto doc = Json::requireDocument(data, fname); auto obj = Json::requireObject(doc, fname); m_entity->parse(obj); return true; - } - catch (const Exception &e) - { + } catch (const Exception& e) { qWarning() << "Unable to parse response:" << e.cause(); return false; } } -private: /* data */ + private: /* data */ QByteArray data; - Meta::BaseEntity *m_entity; + Meta::BaseEntity* m_entity; }; -Meta::BaseEntity::~BaseEntity() -{ -} +Meta::BaseEntity::~BaseEntity() {} QUrl Meta::BaseEntity::url() const { auto s = APPLICATION->settings(); QString metaOverride = s->get("MetaURLOverride").toString(); - if(metaOverride.isEmpty()) - { + if (metaOverride.isEmpty()) { return QUrl(BuildConfig.META_URL).resolved(localFilename()); - } - else - { + } else { return QUrl(metaOverride).resolved(localFilename()); } } @@ -90,20 +71,16 @@ QUrl Meta::BaseEntity::url() const bool Meta::BaseEntity::loadLocalFile() { const QString fname = QDir("meta").absoluteFilePath(localFilename()); - if (!QFile::exists(fname)) - { + if (!QFile::exists(fname)) { return false; } // TODO: check if the file has the expected checksum - try - { + try { auto doc = Json::requireDocument(fname, fname); auto obj = Json::requireObject(doc, fname); parse(obj); return true; - } - catch (const Exception &e) - { + } catch (const Exception& e) { qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause()); // just make sure it's gone and we never consider it again. QFile::remove(fname); @@ -114,16 +91,13 @@ bool Meta::BaseEntity::loadLocalFile() void Meta::BaseEntity::load(Net::Mode loadType) { // load local file if nothing is loaded yet - if(!isLoaded()) - { - if(loadLocalFile()) - { + if (!isLoaded()) { + if (loadLocalFile()) { m_loadStatus = LoadStatus::Local; } } // if we need remote update, run the update task - if(loadType == Net::Mode::Offline || !shouldStartRemoteUpdate()) - { + if (loadType == Net::Mode::Offline || !shouldStartRemoteUpdate()) { return; } m_updateTask.reset(new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()), APPLICATION->network())); @@ -138,14 +112,12 @@ void Meta::BaseEntity::load(Net::Mode loadType) dl->addValidator(new ParsingValidator(this)); m_updateTask->addNetAction(dl); m_updateStatus = UpdateStatus::InProgress; - QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]() - { + QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]() { m_loadStatus = LoadStatus::Remote; m_updateStatus = UpdateStatus::Succeeded; m_updateTask.reset(); }); - QObject::connect(m_updateTask.get(), &NetJob::failed, [&]() - { + QObject::connect(m_updateTask.get(), &NetJob::failed, [&]() { m_updateStatus = UpdateStatus::Failed; m_updateTask.reset(); }); @@ -165,8 +137,7 @@ bool Meta::BaseEntity::shouldStartRemoteUpdate() const Task::Ptr Meta::BaseEntity::getCurrentTask() { - if(m_updateStatus == UpdateStatus::InProgress) - { + if (m_updateStatus == UpdateStatus::InProgress) { return m_updateTask; } return nullptr; diff --git a/launcher/meta/BaseEntity.h b/launcher/meta/BaseEntity.h index 75fa384ad..1336a5217 100644 --- a/launcher/meta/BaseEntity.h +++ b/launcher/meta/BaseEntity.h @@ -22,30 +22,17 @@ #include "net/Mode.h" #include "net/NetJob.h" -namespace Meta -{ -class BaseEntity -{ -public: /* types */ +namespace Meta { +class BaseEntity { + public: /* types */ using Ptr = std::shared_ptr; - enum class LoadStatus - { - NotLoaded, - Local, - Remote - }; - enum class UpdateStatus - { - NotDone, - InProgress, - Failed, - Succeeded - }; + enum class LoadStatus { NotLoaded, Local, Remote }; + enum class UpdateStatus { NotDone, InProgress, Failed, Succeeded }; -public: + public: virtual ~BaseEntity(); - virtual void parse(const QJsonObject &obj) = 0; + virtual void parse(const QJsonObject& obj) = 0; virtual QString localFilename() const = 0; virtual QUrl url() const; @@ -56,12 +43,12 @@ public: void load(Net::Mode loadType); Task::Ptr getCurrentTask(); -protected: /* methods */ + protected: /* methods */ bool loadLocalFile(); -private: + private: LoadStatus m_loadStatus = LoadStatus::NotLoaded; UpdateStatus m_updateStatus = UpdateStatus::NotDone; NetJob::Ptr m_updateTask; }; -} +} // namespace Meta diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp index 4dccccca8..657019f8a 100644 --- a/launcher/meta/Index.cpp +++ b/launcher/meta/Index.cpp @@ -15,84 +15,75 @@ #include "Index.h" -#include "VersionList.h" #include "JsonFormat.h" +#include "VersionList.h" -namespace Meta +namespace Meta { +Index::Index(QObject* parent) : QAbstractListModel(parent) {} +Index::Index(const QVector& lists, QObject* parent) : QAbstractListModel(parent), m_lists(lists) { -Index::Index(QObject *parent) - : QAbstractListModel(parent) -{ -} -Index::Index(const QVector &lists, QObject *parent) - : QAbstractListModel(parent), m_lists(lists) -{ - for (int i = 0; i < m_lists.size(); ++i) - { + for (int i = 0; i < m_lists.size(); ++i) { m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i)); connectVersionList(i, m_lists.at(i)); } } -QVariant Index::data(const QModelIndex &index, int role) const +QVariant Index::data(const QModelIndex& index, int role) const { - if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size()) - { + if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size()) { return QVariant(); } VersionList::Ptr list = m_lists.at(index.row()); - switch (role) - { - case Qt::DisplayRole: - if (index.column() == 0) { - return list->humanReadable(); - } else { - break; - } - case UidRole: return list->uid(); - case NameRole: return list->name(); - case ListPtrRole: return QVariant::fromValue(list); + switch (role) { + case Qt::DisplayRole: + if (index.column() == 0) { + return list->humanReadable(); + } else { + break; + } + case UidRole: + return list->uid(); + case NameRole: + return list->name(); + case ListPtrRole: + return QVariant::fromValue(list); } return QVariant(); } -int Index::rowCount(const QModelIndex &parent) const +int Index::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : m_lists.size(); } -int Index::columnCount(const QModelIndex &parent) const +int Index::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : 1; } QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) - { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) { return tr("Name"); - } - else - { + } else { return QVariant(); } } -bool Index::hasUid(const QString &uid) const +bool Index::hasUid(const QString& uid) const { return m_uids.contains(uid); } -VersionList::Ptr Index::get(const QString &uid) +VersionList::Ptr Index::get(const QString& uid) { VersionList::Ptr out = m_uids.value(uid, nullptr); - if(!out) - { + if (!out) { out = std::make_shared(uid); m_uids[uid] = out; } return out; } -Version::Ptr Index::get(const QString &uid, const QString &version) +Version::Ptr Index::get(const QString& uid, const QString& version) { auto list = get(uid); return list->getVersion(version); @@ -103,31 +94,23 @@ void Index::parse(const QJsonObject& obj) parseIndex(obj, this); } -void Index::merge(const std::shared_ptr &other) +void Index::merge(const std::shared_ptr& other) { const QVector lists = std::dynamic_pointer_cast(other)->m_lists; // initial load, no need to merge - if (m_lists.isEmpty()) - { + if (m_lists.isEmpty()) { beginResetModel(); m_lists = lists; - for (int i = 0; i < lists.size(); ++i) - { + for (int i = 0; i < lists.size(); ++i) { m_uids.insert(lists.at(i)->uid(), lists.at(i)); connectVersionList(i, lists.at(i)); } endResetModel(); - } - else - { - for (const VersionList::Ptr &list : lists) - { - if (m_uids.contains(list->uid())) - { + } else { + for (const VersionList::Ptr& list : lists) { + if (m_uids.contains(list->uid())) { m_uids[list->uid()]->mergeFromIndex(list); - } - else - { + } else { beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size()); connectVersionList(m_lists.size(), list); m_lists.append(list); @@ -138,11 +121,9 @@ void Index::merge(const std::shared_ptr &other) } } -void Index::connectVersionList(const int row, const VersionList::Ptr &list) +void Index::connectVersionList(const int row, const VersionList::Ptr& list) { - connect(list.get(), &VersionList::nameChanged, this, [this, row]() - { - emit dataChanged(index(row), index(row), QVector() << Qt::DisplayRole); - }); -} + connect(list.get(), &VersionList::nameChanged, this, + [this, row]() { emit dataChanged(index(row), index(row), QVector() << Qt::DisplayRole); }); } +} // namespace Meta diff --git a/launcher/meta/Index.h b/launcher/meta/Index.h index 06ea09dcf..41fdfcea9 100644 --- a/launcher/meta/Index.h +++ b/launcher/meta/Index.h @@ -23,46 +23,38 @@ class Task; -namespace Meta -{ +namespace Meta { -class Index : public QAbstractListModel, public BaseEntity -{ +class Index : public QAbstractListModel, public BaseEntity { Q_OBJECT -public: - explicit Index(QObject *parent = nullptr); - explicit Index(const QVector &lists, QObject *parent = nullptr); + public: + explicit Index(QObject* parent = nullptr); + explicit Index(const QVector& lists, QObject* parent = nullptr); - enum - { - UidRole = Qt::UserRole, - NameRole, - ListPtrRole - }; + enum { UidRole = Qt::UserRole, NameRole, ListPtrRole }; - QVariant data(const QModelIndex &index, int role) const override; - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex& index, int role) const override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QString localFilename() const override { return "index.json"; } // queries - VersionList::Ptr get(const QString &uid); - Version::Ptr get(const QString &uid, const QString &version); - bool hasUid(const QString &uid) const; + VersionList::Ptr get(const QString& uid); + Version::Ptr get(const QString& uid, const QString& version); + bool hasUid(const QString& uid) const; QVector lists() const { return m_lists; } -public: // for usage by parsers only - void merge(const std::shared_ptr &other); - void parse(const QJsonObject &obj) override; + public: // for usage by parsers only + void merge(const std::shared_ptr& other); + void parse(const QJsonObject& obj) override; -private: + private: QVector m_lists; QHash m_uids; - void connectVersionList(const int row, const VersionList::Ptr &list); + void connectVersionList(const int row, const VersionList::Ptr& list); }; -} - +} // namespace Meta diff --git a/launcher/meta/JsonFormat.cpp b/launcher/meta/JsonFormat.cpp index cb2d06ea0..6c993f720 100644 --- a/launcher/meta/JsonFormat.cpp +++ b/launcher/meta/JsonFormat.cpp @@ -16,8 +16,8 @@ #include "JsonFormat.h" // FIXME: remove this from here... somehow -#include "minecraft/OneSixVersionFormat.h" #include "Json.h" +#include "minecraft/OneSixVersionFormat.h" #include "Index.h" #include "Version.h" @@ -25,8 +25,7 @@ using namespace Json; -namespace Meta -{ +namespace Meta { MetadataVersion currentFormatVersion() { @@ -34,13 +33,12 @@ MetadataVersion currentFormatVersion() } // Index -static std::shared_ptr parseIndexInternal(const QJsonObject &obj) +static std::shared_ptr parseIndexInternal(const QJsonObject& obj) { const QVector objects = requireIsArrayOf(obj, "packages"); QVector lists; lists.reserve(objects.size()); - std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj) - { + std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject& obj) { VersionList::Ptr list = std::make_shared(requireString(obj, "uid")); list->setName(ensureString(obj, "name", QString())); return list; @@ -49,7 +47,7 @@ static std::shared_ptr parseIndexInternal(const QJsonObject &obj) } // Version -static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &obj) +static Version::Ptr parseCommonVersion(const QString& uid, const QJsonObject& obj) { Version::Ptr version = std::make_shared(uid, requireString(obj, "version")); version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000); @@ -63,26 +61,24 @@ static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &ob return version; } -static Version::Ptr parseVersionInternal(const QJsonObject &obj) +static Version::Ptr parseVersionInternal(const QJsonObject& obj) { Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj); - version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj), - QString("%1/%2.json").arg(version->uid(), version->version()), - obj.contains("order"))); + version->setData(OneSixVersionFormat::versionFileFromJson( + QJsonDocument(obj), QString("%1/%2.json").arg(version->uid(), version->version()), obj.contains("order"))); return version; } // Version list / package -static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj) +static VersionList::Ptr parseVersionListInternal(const QJsonObject& obj) { const QString uid = requireString(obj, "uid"); const QVector versionsRaw = requireIsArrayOf(obj, "versions"); QVector versions; versions.reserve(versionsRaw.size()); - std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj) - { + std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject& vObj) { auto version = parseCommonVersion(uid, vObj); version->setProvidesRecommendations(); return version; @@ -94,23 +90,18 @@ static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj) return list; } - -MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required) +MetadataVersion parseFormatVersion(const QJsonObject& obj, bool required) { - if (!obj.contains("formatVersion")) - { - if(required) - { + if (!obj.contains("formatVersion")) { + if (required) { return MetadataVersion::Invalid; } return MetadataVersion::InitialRelease; } - if (!obj.value("formatVersion").isDouble()) - { + if (!obj.value("formatVersion").isDouble()) { return MetadataVersion::Invalid; } - switch(obj.value("formatVersion").toInt()) - { + switch (obj.value("formatVersion").toInt()) { case 0: case 1: return MetadataVersion::InitialRelease; @@ -121,49 +112,45 @@ MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required) void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version) { - if(version == MetadataVersion::Invalid) - { + if (version == MetadataVersion::Invalid) { return; } obj.insert("formatVersion", int(version)); } -void parseIndex(const QJsonObject &obj, Index *ptr) +void parseIndex(const QJsonObject& obj, Index* ptr) { const MetadataVersion version = parseFormatVersion(obj); - switch (version) - { - case MetadataVersion::InitialRelease: - ptr->merge(parseIndexInternal(obj)); - break; - case MetadataVersion::Invalid: - throw ParseException(QObject::tr("Unknown format version!")); + switch (version) { + case MetadataVersion::InitialRelease: + ptr->merge(parseIndexInternal(obj)); + break; + case MetadataVersion::Invalid: + throw ParseException(QObject::tr("Unknown format version!")); } } -void parseVersionList(const QJsonObject &obj, VersionList *ptr) +void parseVersionList(const QJsonObject& obj, VersionList* ptr) { const MetadataVersion version = parseFormatVersion(obj); - switch (version) - { - case MetadataVersion::InitialRelease: - ptr->merge(parseVersionListInternal(obj)); - break; - case MetadataVersion::Invalid: - throw ParseException(QObject::tr("Unknown format version!")); + switch (version) { + case MetadataVersion::InitialRelease: + ptr->merge(parseVersionListInternal(obj)); + break; + case MetadataVersion::Invalid: + throw ParseException(QObject::tr("Unknown format version!")); } } -void parseVersion(const QJsonObject &obj, Version *ptr) +void parseVersion(const QJsonObject& obj, Version* ptr) { const MetadataVersion version = parseFormatVersion(obj); - switch (version) - { - case MetadataVersion::InitialRelease: - ptr->merge(parseVersionInternal(obj)); - break; - case MetadataVersion::Invalid: - throw ParseException(QObject::tr("Unknown format version!")); + switch (version) { + case MetadataVersion::InitialRelease: + ptr->merge(parseVersionInternal(obj)); + break; + case MetadataVersion::Invalid: + throw ParseException(QObject::tr("Unknown format version!")); } } @@ -172,40 +159,34 @@ void parseVersion(const QJsonObject &obj, Version *ptr) {"uid":"foo", "equals":"version"} ] */ -void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char * keyName) +void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName) { - if(obj.contains(keyName)) - { + if (obj.contains(keyName)) { auto reqArray = requireArray(obj, keyName); auto iter = reqArray.begin(); - while(iter != reqArray.end()) - { + while (iter != reqArray.end()) { auto reqObject = requireObject(*iter); auto uid = requireString(reqObject, "uid"); auto equals = ensureString(reqObject, "equals", QString()); auto suggests = ensureString(reqObject, "suggests", QString()); - ptr->insert({uid, equals, suggests}); + ptr->insert({ uid, equals, suggests }); iter++; } } } -void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName) +void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char* keyName) { - if(!ptr || ptr->empty()) - { + if (!ptr || ptr->empty()) { return; } QJsonArray arrOut; - for(auto &iter: *ptr) - { + for (auto& iter : *ptr) { QJsonObject reqOut; reqOut.insert("uid", iter.uid); - if(!iter.equalsVersion.isEmpty()) - { + if (!iter.equalsVersion.isEmpty()) { reqOut.insert("equals", iter.equalsVersion); } - if(!iter.suggests.isEmpty()) - { + if (!iter.suggests.isEmpty()) { reqOut.insert("suggests", iter.suggests); } arrOut.append(reqOut); @@ -213,5 +194,4 @@ void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName) obj.insert(keyName, arrOut); } -} - +} // namespace Meta diff --git a/launcher/meta/JsonFormat.h b/launcher/meta/JsonFormat.h index 63128a4e6..d474bcc39 100644 --- a/launcher/meta/JsonFormat.h +++ b/launcher/meta/JsonFormat.h @@ -18,43 +18,25 @@ #include #include +#include #include "Exception.h" #include "meta/BaseEntity.h" -#include -namespace Meta -{ +namespace Meta { class Index; class Version; class VersionList; -enum class MetadataVersion -{ - Invalid = -1, - InitialRelease = 1 -}; +enum class MetadataVersion { Invalid = -1, InitialRelease = 1 }; -class ParseException : public Exception -{ -public: +class ParseException : public Exception { + public: using Exception::Exception; }; -struct Require -{ - bool operator==(const Require & rhs) const - { - return uid == rhs.uid; - } - bool operator<(const Require & rhs) const - { - return uid < rhs.uid; - } - bool deepEquals(const Require & rhs) const - { - return uid == rhs.uid - && equalsVersion == rhs.equalsVersion - && suggests == rhs.suggests; - } +struct Require { + bool operator==(const Require& rhs) const { return uid == rhs.uid; } + bool operator<(const Require& rhs) const { return uid < rhs.uid; } + bool deepEquals(const Require& rhs) const { return uid == rhs.uid && equalsVersion == rhs.equalsVersion && suggests == rhs.suggests; } QString uid; QString equalsVersion; QString suggests; @@ -62,17 +44,17 @@ struct Require using RequireSet = std::set; -void parseIndex(const QJsonObject &obj, Index *ptr); -void parseVersion(const QJsonObject &obj, Version *ptr); -void parseVersionList(const QJsonObject &obj, VersionList *ptr); +void parseIndex(const QJsonObject& obj, Index* ptr); +void parseVersion(const QJsonObject& obj, Version* ptr); +void parseVersionList(const QJsonObject& obj, VersionList* ptr); -MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required = true); -void serializeFormatVersion(QJsonObject &obj, MetadataVersion version); +MetadataVersion parseFormatVersion(const QJsonObject& obj, bool required = true); +void serializeFormatVersion(QJsonObject& obj, MetadataVersion version); // FIXME: this has a different shape than the others...FIX IT!? -void parseRequires(const QJsonObject &obj, RequireSet * ptr, const char * keyName = "requires"); -void serializeRequires(QJsonObject & objOut, RequireSet* ptr, const char * keyName = "requires"); +void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName = "requires"); +void serializeRequires(QJsonObject& objOut, RequireSet* ptr, const char* keyName = "requires"); MetadataVersion currentFormatVersion(); -} +} // namespace Meta Q_DECLARE_METATYPE(std::set) diff --git a/launcher/meta/Version.cpp b/launcher/meta/Version.cpp index 0718a4204..655a20b93 100644 --- a/launcher/meta/Version.cpp +++ b/launcher/meta/Version.cpp @@ -20,14 +20,9 @@ #include "JsonFormat.h" #include "minecraft/PackProfile.h" -Meta::Version::Version(const QString &uid, const QString &version) - : BaseVersion(), m_uid(uid), m_version(version) -{ -} +Meta::Version::Version(const QString& uid, const QString& version) : BaseVersion(), m_uid(uid), m_version(version) {} -Meta::Version::~Version() -{ -} +Meta::Version::~Version() {} QString Meta::Version::descriptor() { @@ -35,7 +30,7 @@ QString Meta::Version::descriptor() } QString Meta::Version::name() { - if(m_data) + if (m_data) return m_data->name; return m_uid; } @@ -56,40 +51,32 @@ void Meta::Version::parse(const QJsonObject& obj) void Meta::Version::mergeFromList(const Meta::Version::Ptr& other) { - if(other->m_providesRecommendations) - { - if(m_recommended != other->m_recommended) - { + if (other->m_providesRecommendations) { + if (m_recommended != other->m_recommended) { setRecommended(other->m_recommended); } } - if (m_type != other->m_type) - { + if (m_type != other->m_type) { setType(other->m_type); } - if (m_time != other->m_time) - { + if (m_time != other->m_time) { setTime(other->m_time); } - if (m_requires != other->m_requires) - { + if (m_requires != other->m_requires) { m_requires = other->m_requires; } - if (m_conflicts != other->m_conflicts) - { + if (m_conflicts != other->m_conflicts) { m_conflicts = other->m_conflicts; } - if(m_volatile != other->m_volatile) - { + if (m_volatile != other->m_volatile) { setVolatile(other->m_volatile); } } -void Meta::Version::merge(const Version::Ptr &other) +void Meta::Version::merge(const Version::Ptr& other) { mergeFromList(other); - if(other->m_data) - { + if (other->m_data) { setData(other->m_data); } } @@ -104,7 +91,7 @@ QString Meta::Version::localFilename() const return { const_cast(this)->descriptor() }; } -void Meta::Version::setType(const QString &type) +void Meta::Version::setType(const QString& type) { m_type = type; emit typeChanged(); @@ -116,7 +103,7 @@ void Meta::Version::setTime(const qint64 time) emit timeChanged(); } -void Meta::Version::setRequires(const Meta::RequireSet &reqs, const Meta::RequireSet &conflicts) +void Meta::Version::setRequires(const Meta::RequireSet& reqs, const Meta::RequireSet& conflicts) { m_requires = reqs; m_conflicts = conflicts; @@ -128,8 +115,7 @@ void Meta::Version::setVolatile(bool volatile_) m_volatile = volatile_; } - -void Meta::Version::setData(const VersionFilePtr &data) +void Meta::Version::setData(const VersionFilePtr& data) { m_data = data; } diff --git a/launcher/meta/Version.h b/launcher/meta/Version.h index 59a96a68b..07dcafb01 100644 --- a/launcher/meta/Version.h +++ b/launcher/meta/Version.h @@ -15,8 +15,8 @@ #pragma once -#include "BaseVersion.h" #include "../Version.h" +#include "BaseVersion.h" #include #include @@ -29,80 +29,54 @@ #include "JsonFormat.h" -namespace Meta -{ +namespace Meta { -class Version : public QObject, public BaseVersion, public BaseEntity -{ +class Version : public QObject, public BaseVersion, public BaseEntity { Q_OBJECT -public: + public: using Ptr = std::shared_ptr; - explicit Version(const QString &uid, const QString &version); + explicit Version(const QString& uid, const QString& version); virtual ~Version(); QString descriptor() override; QString name() override; QString typeString() const override; - QString uid() const - { - return m_uid; - } - QString version() const - { - return m_version; - } - QString type() const - { - return m_type; - } + QString uid() const { return m_uid; } + QString version() const { return m_version; } + QString type() const { return m_type; } QDateTime time() const; - qint64 rawTime() const - { - return m_time; - } - const Meta::RequireSet &requiredSet() const - { - return m_requires; - } - VersionFilePtr data() const - { - return m_data; - } - bool isRecommended() const - { - return m_recommended; - } - bool isLoaded() const - { - return m_data != nullptr; - } + qint64 rawTime() const { return m_time; } + const Meta::RequireSet& requiredSet() const { return m_requires; } + VersionFilePtr data() const { return m_data; } + bool isRecommended() const { return m_recommended; } + bool isLoaded() const { return m_data != nullptr; } - void merge(const Version::Ptr &other); - void mergeFromList(const Version::Ptr &other); - void parse(const QJsonObject &obj) override; + void merge(const Version::Ptr& other); + void mergeFromList(const Version::Ptr& other); + void parse(const QJsonObject& obj) override; QString localFilename() const override; [[nodiscard]] ::Version toComparableVersion() const; -public: // for usage by format parsers only - void setType(const QString &type); + public: // for usage by format parsers only + void setType(const QString& type); void setTime(const qint64 time); - void setRequires(const Meta::RequireSet &reqs, const Meta::RequireSet &conflicts); + void setRequires(const Meta::RequireSet& reqs, const Meta::RequireSet& conflicts); void setVolatile(bool volatile_); void setRecommended(bool recommended); void setProvidesRecommendations(); - void setData(const VersionFilePtr &data); + void setData(const VersionFilePtr& data); -signals: + signals: void typeChanged(); void timeChanged(); void requiresChanged(); -private: + private: bool m_providesRecommendations = false; bool m_recommended = false; QString m_name; @@ -115,6 +89,6 @@ private: bool m_volatile = false; VersionFilePtr m_data; }; -} +} // namespace Meta Q_DECLARE_METATYPE(Meta::Version::Ptr) diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp index 9f4482784..7b7ae1fa3 100644 --- a/launcher/meta/VersionList.cpp +++ b/launcher/meta/VersionList.cpp @@ -17,14 +17,11 @@ #include -#include "Version.h" #include "JsonFormat.h" #include "Version.h" -namespace Meta -{ -VersionList::VersionList(const QString &uid, QObject *parent) - : BaseVersionList(parent), m_uid(uid) +namespace Meta { +VersionList::VersionList(const QString& uid, QObject* parent) : BaseVersionList(parent), m_uid(uid) { setObjectName("Version list: " + uid); } @@ -52,61 +49,60 @@ int VersionList::count() const void VersionList::sortVersions() { beginResetModel(); - std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b) - { - return *a.get() < *b.get(); - }); + std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr& a, const Version::Ptr& b) { return *a.get() < *b.get(); }); endResetModel(); } -QVariant VersionList::data(const QModelIndex &index, int role) const +QVariant VersionList::data(const QModelIndex& index, int role) const { - if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid()) - { + if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid()) { return QVariant(); } Version::Ptr version = m_versions.at(index.row()); - switch (role) - { - case VersionPointerRole: return QVariant::fromValue(std::dynamic_pointer_cast(version)); - case VersionRole: - case VersionIdRole: - return version->version(); - case ParentVersionRole: - { - // FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent uid'. - auto & reqs = version->requiredSet(); - auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require & req) - { - return req.uid == "net.minecraft"; - }); - if (iter != reqs.end()) - { - return (*iter).equalsVersion; + switch (role) { + case VersionPointerRole: + return QVariant::fromValue(std::dynamic_pointer_cast(version)); + case VersionRole: + case VersionIdRole: + return version->version(); + case ParentVersionRole: { + // FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent + // uid'. + auto& reqs = version->requiredSet(); + auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require& req) { return req.uid == "net.minecraft"; }); + if (iter != reqs.end()) { + return (*iter).equalsVersion; + } + return QVariant(); } - return QVariant(); - } - case TypeRole: return version->type(); + case TypeRole: + return version->type(); - case UidRole: return version->uid(); - case TimeRole: return version->time(); - case RequiresRole: return QVariant::fromValue(version->requiredSet()); - case SortRole: return version->rawTime(); - case VersionPtrRole: return QVariant::fromValue(version); - case RecommendedRole: return version->isRecommended(); - // FIXME: this should be determined in whatever view/proxy is used... - // case LatestRole: return version == getLatestStable(); - default: return QVariant(); + case UidRole: + return version->uid(); + case TimeRole: + return version->time(); + case RequiresRole: + return QVariant::fromValue(version->requiredSet()); + case SortRole: + return version->rawTime(); + case VersionPtrRole: + return QVariant::fromValue(version); + case RecommendedRole: + return version->isRecommended(); + // FIXME: this should be determined in whatever view/proxy is used... + // case LatestRole: return version == getLatestStable(); + default: + return QVariant(); } } BaseVersionList::RoleList VersionList::providesRoles() const { - return {VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole, - TypeRole, UidRole, TimeRole, RequiresRole, SortRole, - RecommendedRole, LatestRole, VersionPtrRole}; + return { VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole, TypeRole, UidRole, + TimeRole, RequiresRole, SortRole, RecommendedRole, LatestRole, VersionPtrRole }; } QHash VersionList::roleNames() const @@ -129,11 +125,10 @@ QString VersionList::humanReadable() const return m_name.isEmpty() ? m_uid : m_name; } -Version::Ptr VersionList::getVersion(const QString &version) +Version::Ptr VersionList::getVersion(const QString& version) { Version::Ptr out = m_lookup.value(version, nullptr); - if(!out) - { + if (!out) { out = std::make_shared(m_uid, version); m_lookup[version] = out; } @@ -142,33 +137,31 @@ Version::Ptr VersionList::getVersion(const QString &version) bool VersionList::hasVersion(QString version) const { - auto ver = std::find_if(m_versions.constBegin(), m_versions.constEnd(), - [&](Meta::Version::Ptr const& a){ return a->version() == version; }); + auto ver = + std::find_if(m_versions.constBegin(), m_versions.constEnd(), [&](Meta::Version::Ptr const& a) { return a->version() == version; }); return (ver != m_versions.constEnd()); } -void VersionList::setName(const QString &name) +void VersionList::setName(const QString& name) { m_name = name; emit nameChanged(name); } -void VersionList::setVersions(const QVector &versions) +void VersionList::setVersions(const QVector& versions) { beginResetModel(); m_versions = versions; - std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b) - { - return a->rawTime() > b->rawTime(); - }); - for (int i = 0; i < m_versions.size(); ++i) - { + std::sort(m_versions.begin(), m_versions.end(), + [](const Version::Ptr& a, const Version::Ptr& b) { return a->rawTime() > b->rawTime(); }); + for (int i = 0; i < m_versions.size(); ++i) { m_lookup.insert(m_versions.at(i)->version(), m_versions.at(i)); setupAddedVersion(i, m_versions.at(i)); } // FIXME: this is dumb, we have 'recommended' as part of the metadata already... - auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr &ptr) { return ptr->type() == "release"; }); + auto recommendedIt = + std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr& ptr) { return ptr->type() == "release"; }); m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt; endResetModel(); } @@ -179,14 +172,13 @@ void VersionList::parse(const QJsonObject& obj) } // FIXME: this is dumb, we have 'recommended' as part of the metadata already... -static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, const Meta::Version::Ptr &b) +static const Meta::Version::Ptr& getBetterVersion(const Meta::Version::Ptr& a, const Meta::Version::Ptr& b) { - if(!a) + if (!a) return b; - if(!b) + if (!b) return a; - if(a->type() == b->type()) - { + if (a->type() == b->type()) { // newer of same type wins return (a->rawTime() > b->rawTime() ? a : b); } @@ -194,37 +186,30 @@ static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, c return (a->type() == "release" ? a : b); } -void VersionList::mergeFromIndex(const VersionList::Ptr &other) +void VersionList::mergeFromIndex(const VersionList::Ptr& other) { - if (m_name != other->m_name) - { + if (m_name != other->m_name) { setName(other->m_name); } } -void VersionList::merge(const VersionList::Ptr &other) +void VersionList::merge(const VersionList::Ptr& other) { - if (m_name != other->m_name) - { + if (m_name != other->m_name) { setName(other->m_name); } // TODO: do not reset the whole model. maybe? beginResetModel(); m_versions.clear(); - if(other->m_versions.isEmpty()) - { + if (other->m_versions.isEmpty()) { qWarning() << "Empty list loaded ..."; } - for (const Version::Ptr &version : other->m_versions) - { + for (const Version::Ptr& version : other->m_versions) { // we already have the version. merge the contents - if (m_lookup.contains(version->version())) - { + if (m_lookup.contains(version->version())) { m_lookup.value(version->version())->mergeFromList(version); - } - else - { + } else { m_lookup.insert(version->uid(), version); } // connect it. @@ -235,13 +220,16 @@ void VersionList::merge(const VersionList::Ptr &other) endResetModel(); } -void VersionList::setupAddedVersion(const int row, const Version::Ptr &version) +void VersionList::setupAddedVersion(const int row, const Version::Ptr& version) { // FIXME: do not disconnect from everythin, disconnect only the lambdas here version->disconnect(); - connect(version.get(), &Version::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << RequiresRole); }); - connect(version.get(), &Version::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << TimeRole << SortRole); }); - connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << TypeRole); }); + connect(version.get(), &Version::requiresChanged, this, + [this, row]() { emit dataChanged(index(row), index(row), QVector() << RequiresRole); }); + connect(version.get(), &Version::timeChanged, this, + [this, row]() { emit dataChanged(index(row), index(row), QVector() << TimeRole << SortRole); }); + connect(version.get(), &Version::typeChanged, this, + [this, row]() { emit dataChanged(index(row), index(row), QVector() << TypeRole); }); } BaseVersion::Ptr VersionList::getRecommended() const @@ -249,4 +237,4 @@ BaseVersion::Ptr VersionList::getRecommended() const return m_recommended; } -} +} // namespace Meta diff --git a/launcher/meta/VersionList.h b/launcher/meta/VersionList.h index a4d5603d9..5e587f204 100644 --- a/launcher/meta/VersionList.h +++ b/launcher/meta/VersionList.h @@ -15,33 +15,25 @@ #pragma once -#include "BaseEntity.h" -#include "BaseVersionList.h" #include #include +#include "BaseEntity.h" +#include "BaseVersionList.h" #include "meta/Version.h" -namespace Meta -{ +namespace Meta { -class VersionList : public BaseVersionList, public BaseEntity -{ +class VersionList : public BaseVersionList, public BaseEntity { Q_OBJECT Q_PROPERTY(QString uid READ uid CONSTANT) Q_PROPERTY(QString name READ name NOTIFY nameChanged) -public: - explicit VersionList(const QString &uid, QObject *parent = nullptr); + public: + explicit VersionList(const QString& uid, QObject* parent = nullptr); using Ptr = std::shared_ptr; - enum Roles - { - UidRole = Qt::UserRole + 100, - TimeRole, - RequiresRole, - VersionPtrRole - }; + enum Roles { UidRole = Qt::UserRole + 100, TimeRole, RequiresRole, VersionPtrRole }; Task::Ptr getLoadTask() override; bool isLoaded() override; @@ -51,46 +43,35 @@ public: BaseVersion::Ptr getRecommended() const override; - QVariant data(const QModelIndex &index, int role) const override; + QVariant data(const QModelIndex& index, int role) const override; RoleList providesRoles() const override; QHash roleNames() const override; QString localFilename() const override; - QString uid() const - { - return m_uid; - } - QString name() const - { - return m_name; - } + QString uid() const { return m_uid; } + QString name() const { return m_name; } QString humanReadable() const; - Version::Ptr getVersion(const QString &version); + Version::Ptr getVersion(const QString& version); bool hasVersion(QString version) const; - QVector versions() const - { - return m_versions; - } + QVector versions() const { return m_versions; } -public: // for usage only by parsers - void setName(const QString &name); - void setVersions(const QVector &versions); - void merge(const VersionList::Ptr &other); - void mergeFromIndex(const VersionList::Ptr &other); - void parse(const QJsonObject &obj) override; + public: // for usage only by parsers + void setName(const QString& name); + void setVersions(const QVector& versions); + void merge(const VersionList::Ptr& other); + void mergeFromIndex(const VersionList::Ptr& other); + void parse(const QJsonObject& obj) override; -signals: - void nameChanged(const QString &name); + signals: + void nameChanged(const QString& name); -protected slots: - void updateListData(QList) override - { - } + protected slots: + void updateListData(QList) override {} -private: + private: QVector m_versions; QHash m_lookup; QString m_uid; @@ -98,7 +79,7 @@ private: Version::Ptr m_recommended; - void setupAddedVersion(const int row, const Version::Ptr &version); + void setupAddedVersion(const int row, const Version::Ptr& version); }; -} +} // namespace Meta Q_DECLARE_METATYPE(Meta::VersionList::Ptr) diff --git a/launcher/minecraft/Agent.h b/launcher/minecraft/Agent.h index 374e6e94e..8958521e5 100644 --- a/launcher/minecraft/Agent.h +++ b/launcher/minecraft/Agent.h @@ -9,28 +9,21 @@ class Agent; typedef std::shared_ptr AgentPtr; class Agent { -public: - Agent(LibraryPtr library, const QString &argument) + public: + Agent(LibraryPtr library, const QString& argument) { m_library = library; m_argument = argument; } -public: /* methods */ - - LibraryPtr library() { - return m_library; - } - QString argument() { - return m_argument; - } - -protected: /* data */ + public: /* methods */ + LibraryPtr library() { return m_library; } + QString argument() { return m_argument; } + protected: /* data */ /// The library pointing to the jar this Java agent is contained within LibraryPtr m_library; /// The argument to the Java agent, passed after an = if present QString m_argument; - }; diff --git a/launcher/minecraft/AssetsUtils.cpp b/launcher/minecraft/AssetsUtils.cpp index 16fdfdb1c..32b48aed8 100644 --- a/launcher/minecraft/AssetsUtils.cpp +++ b/launcher/minecraft/AssetsUtils.cpp @@ -33,21 +33,21 @@ * limitations under the License. */ -#include +#include +#include #include #include -#include -#include +#include #include #include +#include #include -#include #include "AssetsUtils.h" -#include "FileSystem.h" -#include "net/Download.h" -#include "net/ChecksumValidator.h" #include "BuildConfig.h" +#include "FileSystem.h" +#include "net/ChecksumValidator.h" +#include "net/Download.h" #include "Application.h" @@ -56,37 +56,32 @@ QSet collectPathsFromDir(QString dirPath) { QFileInfo dirInfo(dirPath); - if (!dirInfo.exists()) - { + if (!dirInfo.exists()) { return {}; } QSet out; QDirIterator iter(dirPath, QDirIterator::Subdirectories); - while (iter.hasNext()) - { + while (iter.hasNext()) { QString value = iter.next(); QFileInfo info(value); - if(info.isFile()) - { + if (info.isFile()) { out.insert(value); qDebug() << value; } } return out; } -} +} // namespace - -namespace AssetsUtils -{ +namespace AssetsUtils { /* * Returns true on success, with index populated * index is undefined otherwise */ -bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsIndex& index) +bool loadAssetsIndexJson(const QString& assetsId, const QString& path, AssetsIndex& index) { /* { @@ -105,8 +100,7 @@ bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsInd // Try to open the file and fail if we can't. // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::ReadOnly)) - { + if (!file.open(QIODevice::ReadOnly)) { qCritical() << "Failed to read assets index file" << path; return false; } @@ -120,16 +114,14 @@ bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsInd QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); // Fail if the JSON is invalid. - if (parseError.error != QJsonParseError::NoError) - { - qCritical() << "Failed to parse assets index file:" << parseError.errorString() - << "at offset " << QString::number(parseError.offset); + if (parseError.error != QJsonParseError::NoError) { + qCritical() << "Failed to parse assets index file:" << parseError.errorString() << "at offset " + << QString::number(parseError.offset); return false; } // Make sure the root is an object. - if (!jsonDoc.isObject()) - { + if (!jsonDoc.isObject()) { qCritical() << "Invalid assets index JSON: Root should be an array."; return false; } @@ -137,22 +129,19 @@ bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsInd QJsonObject root = jsonDoc.object(); QJsonValue isVirtual = root.value("virtual"); - if (!isVirtual.isUndefined()) - { + if (!isVirtual.isUndefined()) { index.isVirtual = isVirtual.toBool(false); } QJsonValue mapToResources = root.value("map_to_resources"); - if (!mapToResources.isUndefined()) - { + if (!mapToResources.isUndefined()) { index.mapToResources = mapToResources.toBool(false); } QJsonValue objects = root.value("objects"); QVariantMap map = objects.toVariant().toMap(); - for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) - { + for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) { // qDebug() << iter.key(); QVariant variant = iter.value(); @@ -160,19 +149,14 @@ bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsInd AssetObject object; - for (QVariantMap::const_iterator nested_iter = nested_objects.begin(); - nested_iter != nested_objects.end(); ++nested_iter) - { + for (QVariantMap::const_iterator nested_iter = nested_objects.begin(); nested_iter != nested_objects.end(); ++nested_iter) { // qDebug() << nested_iter.key() << nested_iter.value().toString(); QString key = nested_iter.key(); QVariant value = nested_iter.value(); - if (key == "hash") - { + if (key == "hash") { object.hash = value.toString(); - } - else if (key == "size") - { + } else if (key == "size") { object.size = value.toDouble(); } } @@ -184,7 +168,7 @@ bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsInd } // FIXME: ugly code duplication -QDir getAssetsDir(const QString &assetsId, const QString &resourcesFolder) +QDir getAssetsDir(const QString& assetsId, const QString& resourcesFolder) { QDir assetsDir = QDir("assets/"); QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes")); @@ -195,26 +179,21 @@ QDir getAssetsDir(const QString &assetsId, const QString &resourcesFolder) QFile indexFile(indexPath); QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId)); - if (!indexFile.exists()) - { + if (!indexFile.exists()) { qCritical() << "No assets index file" << indexPath << "; can't determine assets path!"; return virtualRoot; } AssetsIndex index; - if(!AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, index)) - { + if (!AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, index)) { qCritical() << "Failed to load asset index file" << indexPath << "; can't determine assets path!"; return virtualRoot; } QString targetPath; - if(index.isVirtual) - { + if (index.isVirtual) { return virtualRoot; - } - else if(index.mapToResources) - { + } else if (index.mapToResources) { return QDir(resourcesFolder); } return virtualRoot; @@ -232,8 +211,7 @@ bool reconstructAssets(QString assetsId, QString resourcesFolder) QFile indexFile(indexPath); QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId)); - if (!indexFile.exists()) - { + if (!indexFile.exists()) { qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets!"; return false; } @@ -241,31 +219,25 @@ bool reconstructAssets(QString assetsId, QString resourcesFolder) qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path() << objectDir.path() << virtualDir.path() << virtualRoot.path(); AssetsIndex index; - if(!AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, index)) - { + if (!AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, index)) { qCritical() << "Failed to load asset index file" << indexPath << "; can't reconstruct assets!"; return false; } QString targetPath; bool removeLeftovers = false; - if(index.isVirtual) - { + if (index.isVirtual) { targetPath = virtualRoot.path(); removeLeftovers = true; qDebug() << "Reconstructing virtual assets folder at" << targetPath; - } - else if(index.mapToResources) - { + } else if (index.mapToResources) { targetPath = resourcesFolder; qDebug() << "Reconstructing resources folder at" << targetPath; } - if (!targetPath.isNull()) - { + if (!targetPath.isNull()) { auto presentFiles = collectPathsFromDir(targetPath); - for (QString map : index.objects.keys()) - { + for (QString map : index.objects.keys()) { AssetObject asset_object = index.objects.value(map); QString target_path = FS::PathCombine(targetPath, map); QFile target(target_path); @@ -279,8 +251,7 @@ bool reconstructAssets(QString assetsId, QString resourcesFolder) presentFiles.remove(target_path); - if (!target.exists()) - { + if (!target.exists()) { QFileInfo info(target_path); QDir target_dir = info.dir(); @@ -293,10 +264,8 @@ bool reconstructAssets(QString assetsId, QString resourcesFolder) } // TODO: Write last used time to virtualRoot/.lastused - if(removeLeftovers) - { - for(auto & file: presentFiles) - { + if (removeLeftovers) { + for (auto& file : presentFiles) { qDebug() << "Would remove" << file; } } @@ -304,16 +273,14 @@ bool reconstructAssets(QString assetsId, QString resourcesFolder) return true; } -} +} // namespace AssetsUtils NetAction::Ptr AssetObject::getDownloadAction() { QFileInfo objectFile(getLocalPath()); - if ((!objectFile.isFile()) || (objectFile.size() != size)) - { + if ((!objectFile.isFile()) || (objectFile.size() != size)) { auto objectDL = Net::Download::makeFile(getUrl(), objectFile.filePath()); - if(hash.size()) - { + if (hash.size()) { auto rawHash = QByteArray::fromHex(hash.toLatin1()); objectDL->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash)); } @@ -341,15 +308,13 @@ QString AssetObject::getRelPath() NetJob::Ptr AssetsIndex::getDownloadJob() { auto job = makeShared(QObject::tr("Assets for %1").arg(id), APPLICATION->network()); - for (auto &object : objects.values()) - { + for (auto& object : objects.values()) { auto dl = object.getDownloadAction(); - if(dl) - { + if (dl) { job->addNetAction(dl); } } - if(job->size()) + if (job->size()) return job; return nullptr; } diff --git a/launcher/minecraft/AssetsUtils.h b/launcher/minecraft/AssetsUtils.h index 3dbf19ed6..87956e57a 100644 --- a/launcher/minecraft/AssetsUtils.h +++ b/launcher/minecraft/AssetsUtils.h @@ -15,13 +15,12 @@ #pragma once -#include #include +#include #include "net/NetAction.h" #include "net/NetJob.h" -struct AssetObject -{ +struct AssetObject { QString getRelPath(); QUrl getUrl(); QString getLocalPath(); @@ -31,8 +30,7 @@ struct AssetObject qint64 size; }; -struct AssetsIndex -{ +struct AssetsIndex { NetJob::Ptr getDownloadJob(); QString id; @@ -42,12 +40,11 @@ struct AssetsIndex }; /// FIXME: this is absolutely horrendous. REDO!!!! -namespace AssetsUtils -{ -bool loadAssetsIndexJson(const QString &id, const QString &file, AssetsIndex& index); +namespace AssetsUtils { +bool loadAssetsIndexJson(const QString& id, const QString& file, AssetsIndex& index); -QDir getAssetsDir(const QString &assetsId, const QString &resourcesFolder); +QDir getAssetsDir(const QString& assetsId, const QString& resourcesFolder); /// Reconstruct a virtual assets folder for the given assets ID and return the folder bool reconstructAssets(QString assetsId, QString resourcesFolder); -} +} // namespace AssetsUtils diff --git a/launcher/minecraft/Component.cpp b/launcher/minecraft/Component.cpp index ff81fcbb8..96d67a057 100644 --- a/launcher/minecraft/Component.cpp +++ b/launcher/minecraft/Component.cpp @@ -33,22 +33,22 @@ * limitations under the License. */ -#include -#include #include "Component.h" +#include +#include #include -#include "meta/Version.h" -#include "VersionFile.h" -#include "minecraft/PackProfile.h" +#include "Application.h" #include "FileSystem.h" #include "OneSixVersionFormat.h" -#include "Application.h" +#include "VersionFile.h" +#include "meta/Version.h" +#include "minecraft/PackProfile.h" #include -Component::Component(PackProfile * parent, const QString& uid) +Component::Component(PackProfile* parent, const QString& uid) { assert(parent); m_parent = parent; @@ -56,7 +56,7 @@ Component::Component(PackProfile * parent, const QString& uid) m_uid = uid; } -Component::Component(PackProfile * parent, std::shared_ptr version) +Component::Component(PackProfile* parent, std::shared_ptr version) { assert(parent); m_parent = parent; @@ -68,7 +68,7 @@ Component::Component(PackProfile * parent, std::shared_ptr versio m_loaded = version->isLoaded(); } -Component::Component(PackProfile * parent, const QString& uid, std::shared_ptr file) +Component::Component(PackProfile* parent, const QString& uid, std::shared_ptr file) { assert(parent); m_parent = parent; @@ -88,33 +88,25 @@ std::shared_ptr Component::getMeta() void Component::applyTo(LaunchProfile* profile) { // do not apply disabled components - if(!isEnabled()) - { + if (!isEnabled()) { return; } auto vfile = getVersionFile(); - if(vfile) - { + if (vfile) { vfile->applyTo(profile, m_parent->runtimeContext()); - } - else - { + } else { profile->applyProblemSeverity(getProblemSeverity()); } } std::shared_ptr Component::getVersionFile() const { - if(m_metaVersion) - { - if(!m_metaVersion->isLoaded()) - { + if (m_metaVersion) { + if (!m_metaVersion->isLoaded()) { m_metaVersion->load(Net::Mode::Online); } return m_metaVersion->data(); - } - else - { + } else { return m_file; } } @@ -122,8 +114,7 @@ std::shared_ptr Component::getVersionFile() const std::shared_ptr Component::getVersionList() const { // FIXME: what if the metadata index isn't loaded yet? - if(APPLICATION->metadataIndex()->hasUid(m_uid)) - { + if (APPLICATION->metadataIndex()->hasUid(m_uid)) { return APPLICATION->metadataIndex()->get(m_uid); } return nullptr; @@ -131,12 +122,11 @@ std::shared_ptr Component::getVersionList() const int Component::getOrder() { - if(m_orderOverride) + if (m_orderOverride) return m_order; auto vfile = getVersionFile(); - if(vfile) - { + if (vfile) { return vfile->order; } return 0; @@ -166,13 +156,11 @@ QString Component::getFilename() } QDateTime Component::getReleaseDateTime() { - if(m_metaVersion) - { + if (m_metaVersion) { return m_metaVersion->time(); } auto vfile = getVersionFile(); - if(vfile) - { + if (vfile) { return vfile->releaseTime; } // FIXME: fake @@ -192,12 +180,10 @@ bool Component::canBeDisabled() bool Component::setEnabled(bool state) { bool intendedDisabled = !state; - if (!canBeDisabled()) - { + if (!canBeDisabled()) { intendedDisabled = false; } - if(intendedDisabled != m_disabled) - { + if (intendedDisabled != m_disabled) { m_disabled = intendedDisabled; emit dataChanged(); return true; @@ -212,10 +198,8 @@ bool Component::isCustom() bool Component::isCustomizable() { - if(m_metaVersion) - { - if(getVersionFile()) - { + if (m_metaVersion) { + if (getVersionFile()) { return true; } } @@ -227,10 +211,8 @@ bool Component::isRemovable() } bool Component::isRevertible() { - if (isCustom()) - { - if(APPLICATION->metadataIndex()->hasUid(m_uid)) - { + if (isCustom()) { + if (APPLICATION->metadataIndex()->hasUid(m_uid)) { return true; } } @@ -244,10 +226,8 @@ bool Component::isMoveable() bool Component::isVersionChangeable() { auto list = getVersionList(); - if(list) - { - if(!list->isLoaded()) - { + if (list) { + if (!list->isLoaded()) { list->load(Net::Mode::Online); } return list->count() != 0; @@ -257,8 +237,7 @@ bool Component::isVersionChangeable() void Component::setImportant(bool state) { - if(m_important != state) - { + if (m_important != state) { m_important = state; emit dataChanged(); } @@ -267,8 +246,7 @@ void Component::setImportant(bool state) ProblemSeverity Component::getProblemSeverity() const { auto file = getVersionFile(); - if(file) - { + if (file) { return file->getProblemSeverity(); } return ProblemSeverity::Error; @@ -277,49 +255,38 @@ ProblemSeverity Component::getProblemSeverity() const const QList Component::getProblems() const { auto file = getVersionFile(); - if(file) - { + if (file) { return file->getProblems(); } - return {{ProblemSeverity::Error, QObject::tr("Patch is not loaded yet.")}}; + return { { ProblemSeverity::Error, QObject::tr("Patch is not loaded yet.") } }; } void Component::setVersion(const QString& version) { - if(version == m_version) - { + if (version == m_version) { return; } m_version = version; - if(m_loaded) - { + if (m_loaded) { // we are loaded and potentially have state to invalidate - if(m_file) - { + if (m_file) { // we have a file... explicit version has been changed and there is nothing else to do. - } - else - { + } else { // we don't have a file, therefore we are loaded with metadata m_cachedVersion = version; // see if the meta version is loaded auto metaVersion = APPLICATION->metadataIndex()->get(m_uid, version); - if(metaVersion->isLoaded()) - { + if (metaVersion->isLoaded()) { // if yes, we can continue with that. m_metaVersion = metaVersion; - } - else - { + } else { // if not, we need loading m_metaVersion.reset(); m_loaded = false; } updateCachedData(); } - } - else - { + } else { // not loaded... assume it will be sorted out later by the update task } emit dataChanged(); @@ -327,41 +294,33 @@ void Component::setVersion(const QString& version) bool Component::customize() { - if(isCustom()) - { + if (isCustom()) { return false; } auto filename = getFilename(); - if(!FS::ensureFilePathExists(filename)) - { + if (!FS::ensureFilePathExists(filename)) { return false; } // FIXME: get rid of this try-catch. - try - { + try { QSaveFile jsonFile(filename); - if(!jsonFile.open(QIODevice::WriteOnly)) - { + if (!jsonFile.open(QIODevice::WriteOnly)) { return false; } auto vfile = getVersionFile(); - if(!vfile) - { + if (!vfile) { return false; } auto document = OneSixVersionFormat::versionFileToJson(vfile); jsonFile.write(document.toJson()); - if(!jsonFile.commit()) - { + if (!jsonFile.commit()) { return false; } m_file = vfile; m_metaVersion.reset(); emit dataChanged(); - } - catch (const Exception &error) - { + } catch (const Exception& error) { qWarning() << "Version could not be loaded:" << error.cause(); } return true; @@ -369,31 +328,25 @@ bool Component::customize() bool Component::revert() { - if(!isCustom()) - { + if (!isCustom()) { // already not custom return true; } auto filename = getFilename(); bool result = true; // just kill the file and reload - if(QFile::exists(filename)) - { + if (QFile::exists(filename)) { result = QFile::remove(filename); } - if(result) - { + if (result) { // file gone... m_file.reset(); // check local cache for metadata... auto version = APPLICATION->metadataIndex()->get(m_uid, m_version); - if(version->isLoaded()) - { + if (version->isLoaded()) { m_metaVersion = version; - } - else - { + } else { m_metaVersion.reset(); m_loaded = false; } @@ -407,23 +360,19 @@ bool Component::revert() * By default, only uids are compared for set operations. * This compares all fields of the Require structs in the sets. */ -static bool deepCompare(const std::set & a, const std::set & b) +static bool deepCompare(const std::set& a, const std::set& b) { // NOTE: this needs to be rewritten if the type of Meta::RequireSet changes - if(a.size() != b.size()) - { + if (a.size() != b.size()) { return false; } - for(const auto & reqA :a) - { - const auto &iter2 = b.find(reqA); - if(iter2 == b.cend()) - { + for (const auto& reqA : a) { + const auto& iter2 = b.find(reqA); + if (iter2 == b.cend()) { return false; } - const auto & reqB = *iter2; - if(!reqA.deepEquals(reqB)) - { + const auto& reqB = *iter2; + if (!reqA.deepEquals(reqB)) { return false; } } @@ -433,41 +382,32 @@ static bool deepCompare(const std::set & a, const std::setname) - { + if (m_cachedName != file->name) { m_cachedName = file->name; changed = true; } - if(m_cachedVersion != file->version) - { + if (m_cachedVersion != file->version) { m_cachedVersion = file->version; changed = true; } - if(m_cachedVolatile != file->m_volatile) - { + if (m_cachedVolatile != file->m_volatile) { m_cachedVolatile = file->m_volatile; changed = true; } - if(!deepCompare(m_cachedRequires, file->m_requires)) - { + if (!deepCompare(m_cachedRequires, file->m_requires)) { m_cachedRequires = file->m_requires; changed = true; } - if(!deepCompare(m_cachedConflicts, file->conflicts)) - { + if (!deepCompare(m_cachedConflicts, file->conflicts)) { m_cachedConflicts = file->conflicts; changed = true; } - if(changed) - { + if (changed) { emit dataChanged(); } - } - else - { + } else { // in case we removed all the metadata m_cachedRequires.clear(); m_cachedConflicts.clear(); diff --git a/launcher/minecraft/Component.h b/launcher/minecraft/Component.h index ef7c99470..00a912d65 100644 --- a/launcher/minecraft/Component.h +++ b/launcher/minecraft/Component.h @@ -1,37 +1,35 @@ #pragma once -#include -#include -#include #include -#include "meta/JsonFormat.h" +#include +#include +#include #include "ProblemProvider.h" #include "QObjectPtr.h" +#include "meta/JsonFormat.h" class PackProfile; class LaunchProfile; -namespace Meta -{ - class Version; - class VersionList; -} +namespace Meta { +class Version; +class VersionList; +} // namespace Meta class VersionFile; -class Component : public QObject, public ProblemProvider -{ -Q_OBJECT -public: - Component(PackProfile * parent, const QString &uid); +class Component : public QObject, public ProblemProvider { + Q_OBJECT + public: + Component(PackProfile* parent, const QString& uid); // DEPRECATED: remove these constructors? - Component(PackProfile * parent, std::shared_ptr version); - Component(PackProfile * parent, const QString & uid, std::shared_ptr file); + Component(PackProfile* parent, std::shared_ptr version); + Component(PackProfile* parent, const QString& uid, std::shared_ptr file); virtual ~Component(){}; - void applyTo(LaunchProfile *profile); + void applyTo(LaunchProfile* profile); bool isEnabled(); - bool setEnabled (bool state); + bool setEnabled(bool state); bool canBeDisabled(); bool isMoveable(); @@ -56,23 +54,22 @@ public: std::shared_ptr getVersionFile() const; std::shared_ptr getVersionList() const; - void setImportant (bool state); - + void setImportant(bool state); const QList getProblems() const override; ProblemSeverity getProblemSeverity() const override; - void setVersion(const QString & version); + void setVersion(const QString& version); bool customize(); bool revert(); void updateCachedData(); -signals: + signals: void dataChanged(); -public: /* data */ - PackProfile * m_parent; + public: /* data */ + PackProfile* m_parent; // BEGIN: persistent component list properties /// ID of the component diff --git a/launcher/minecraft/ComponentUpdateTask.cpp b/launcher/minecraft/ComponentUpdateTask.cpp index d55bc17f2..0b85b81aa 100644 --- a/launcher/minecraft/ComponentUpdateTask.cpp +++ b/launcher/minecraft/ComponentUpdateTask.cpp @@ -1,16 +1,16 @@ #include "ComponentUpdateTask.h" -#include "PackProfile_p.h" -#include "PackProfile.h" #include "Component.h" -#include "meta/Index.h" -#include "meta/VersionList.h" -#include "meta/Version.h" #include "ComponentUpdateTask_p.h" -#include "cassert" -#include "Version.h" -#include "net/Mode.h" #include "OneSixVersionFormat.h" +#include "PackProfile.h" +#include "PackProfile_p.h" +#include "Version.h" +#include "cassert" +#include "meta/Index.h" +#include "meta/Version.h" +#include "meta/VersionList.h" +#include "net/Mode.h" #include "Application.h" @@ -32,8 +32,7 @@ * If the component list changes, start over. */ -ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent) - : Task(parent) +ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent) : Task(parent) { d.reset(new ComponentUpdateTaskData); d->m_list = list; @@ -41,9 +40,7 @@ ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfi d->netmode = netmode; } -ComponentUpdateTask::~ComponentUpdateTask() -{ -} +ComponentUpdateTask::~ComponentUpdateTask() {} void ComponentUpdateTask::executeTask() { @@ -51,19 +48,12 @@ void ComponentUpdateTask::executeTask() loadComponents(); } -namespace -{ -enum class LoadResult -{ - LoadedLocal, - RequiresRemote, - Failed -}; +namespace { +enum class LoadResult { LoadedLocal, RequiresRemote, Failed }; LoadResult composeLoadResult(LoadResult a, LoadResult b) { - if (a < b) - { + if (a < b) { return b; } return a; @@ -71,28 +61,24 @@ LoadResult composeLoadResult(LoadResult a, LoadResult b) static LoadResult loadComponent(ComponentPtr component, Task::Ptr& loadTask, Net::Mode netmode) { - if(component->m_loaded) - { + if (component->m_loaded) { qDebug() << component->getName() << "is already loaded"; return LoadResult::LoadedLocal; } LoadResult result = LoadResult::Failed; auto customPatchFilename = component->getFilename(); - if(QFile::exists(customPatchFilename)) - { + if (QFile::exists(customPatchFilename)) { // if local file exists... // check for uid problems inside... bool fileChanged = false; auto file = ProfileUtils::parseJsonFile(QFileInfo(customPatchFilename), false); - if(file->uid != component->m_uid) - { + if (file->uid != component->m_uid) { file->uid = component->m_uid; fileChanged = true; } - if(fileChanged) - { + if (fileChanged) { // FIXME: @QUALITY do not ignore return value ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), customPatchFilename); } @@ -100,21 +86,16 @@ static LoadResult loadComponent(ComponentPtr component, Task::Ptr& loadTask, Net component->m_file = file; component->m_loaded = true; result = LoadResult::LoadedLocal; - } - else - { + } else { auto metaVersion = APPLICATION->metadataIndex()->get(component->m_uid, component->m_version); component->m_metaVersion = metaVersion; - if(metaVersion->isLoaded()) - { + if (metaVersion->isLoaded()) { component->m_loaded = true; result = LoadResult::LoadedLocal; - } - else - { + } else { metaVersion->load(netmode); loadTask = metaVersion->getCurrentTask(); - if(loadTask) + if (loadTask) result = LoadResult::RequiresRemote; else if (metaVersion->isLoaded()) result = LoadResult::LoadedLocal; @@ -155,21 +136,19 @@ static LoadResult loadPackProfile(ComponentPtr component, Task::Ptr& loadTask, N static LoadResult loadIndex(Task::Ptr& loadTask, Net::Mode netmode) { // FIXME: DECIDE. do we want to run the update task anyway? - if(APPLICATION->metadataIndex()->isLoaded()) - { + if (APPLICATION->metadataIndex()->isLoaded()) { qDebug() << "Index is already loaded"; return LoadResult::LoadedLocal; } APPLICATION->metadataIndex()->load(netmode); loadTask = APPLICATION->metadataIndex()->getCurrentTask(); - if(loadTask) - { + if (loadTask) { return LoadResult::RequiresRemote; } // FIXME: this is assuming the load succeeded... did it really? return LoadResult::LoadedLocal; } -} +} // namespace void ComponentUpdateTask::loadComponents() { @@ -183,34 +162,24 @@ void ComponentUpdateTask::loadComponents() Task::Ptr indexLoadTask; auto singleResult = loadIndex(indexLoadTask, d->netmode); result = composeLoadResult(result, singleResult); - if(indexLoadTask) - { + if (indexLoadTask) { qDebug() << "Remote loading is being run for metadata index"; RemoteLoadStatus status; status.type = RemoteLoadStatus::Type::Index; d->remoteLoadStatusList.append(status); - connect(indexLoadTask.get(), &Task::succeeded, [=]() - { - remoteLoadSucceeded(taskIndex); - }); - connect(indexLoadTask.get(), &Task::failed, [=](const QString & error) - { - remoteLoadFailed(taskIndex, error); - }); - connect(indexLoadTask.get(), &Task::aborted, [=]() - { - remoteLoadFailed(taskIndex, tr("Aborted")); - }); + connect(indexLoadTask.get(), &Task::succeeded, [=]() { remoteLoadSucceeded(taskIndex); }); + connect(indexLoadTask.get(), &Task::failed, [=](const QString& error) { remoteLoadFailed(taskIndex, error); }); + connect(indexLoadTask.get(), &Task::aborted, [=]() { remoteLoadFailed(taskIndex, tr("Aborted")); }); taskIndex++; } } // load all the components OR their lists... - for (auto component: d->m_list->d->components) - { + for (auto component : d->m_list->d->components) { Task::Ptr loadTask; LoadResult singleResult; RemoteLoadStatus::Type loadType; - // FIXME: to do this right, we need to load the lists and decide on which versions to use during dependency resolution. For now, ignore all that... + // FIXME: to do this right, we need to load the lists and decide on which versions to use during dependency resolution. For now, + // ignore all that... #if 0 switch(d->mode) { @@ -231,26 +200,15 @@ void ComponentUpdateTask::loadComponents() singleResult = loadComponent(component, loadTask, d->netmode); loadType = RemoteLoadStatus::Type::Version; #endif - if(singleResult == LoadResult::LoadedLocal) - { + if (singleResult == LoadResult::LoadedLocal) { component->updateCachedData(); } result = composeLoadResult(result, singleResult); - if (loadTask) - { + if (loadTask) { qDebug() << "Remote loading is being run for" << component->getName(); - connect(loadTask.get(), &Task::succeeded, [=]() - { - remoteLoadSucceeded(taskIndex); - }); - connect(loadTask.get(), &Task::failed, [=](const QString & error) - { - remoteLoadFailed(taskIndex, error); - }); - connect(loadTask.get(), &Task::aborted, [=]() - { - remoteLoadFailed(taskIndex, tr("Aborted")); - }); + connect(loadTask.get(), &Task::succeeded, [=]() { remoteLoadSucceeded(taskIndex); }); + connect(loadTask.get(), &Task::failed, [=](const QString& error) { remoteLoadFailed(taskIndex, error); }); + connect(loadTask.get(), &Task::aborted, [=]() { remoteLoadFailed(taskIndex, tr("Aborted")); }); RemoteLoadStatus status; status.type = loadType; status.PackProfileIndex = componentIndex; @@ -260,95 +218,73 @@ void ComponentUpdateTask::loadComponents() componentIndex++; } d->remoteTasksInProgress = taskIndex; - switch(result) - { - case LoadResult::LoadedLocal: - { + switch (result) { + case LoadResult::LoadedLocal: { // Everything got loaded. Advance to dependency resolution. resolveDependencies(d->mode == Mode::Launch || d->netmode == Net::Mode::Offline); break; } - case LoadResult::RequiresRemote: - { + case LoadResult::RequiresRemote: { // we wait for signals. break; } - case LoadResult::Failed: - { + case LoadResult::Failed: { emitFailed(tr("Some component metadata load tasks failed.")); break; } } } -namespace -{ - struct RequireEx : public Meta::Require - { - size_t indexOfFirstDependee = 0; - }; - struct RequireCompositionResult - { - bool ok; - RequireEx outcome; - }; - using RequireExSet = std::set; -} +namespace { +struct RequireEx : public Meta::Require { + size_t indexOfFirstDependee = 0; +}; +struct RequireCompositionResult { + bool ok; + RequireEx outcome; +}; +using RequireExSet = std::set; +} // namespace -static RequireCompositionResult composeRequirement(const RequireEx & a, const RequireEx & b) +static RequireCompositionResult composeRequirement(const RequireEx& a, const RequireEx& b) { assert(a.uid == b.uid); RequireEx out; out.uid = a.uid; out.indexOfFirstDependee = std::min(a.indexOfFirstDependee, b.indexOfFirstDependee); - if(a.equalsVersion.isEmpty()) - { + if (a.equalsVersion.isEmpty()) { out.equalsVersion = b.equalsVersion; - } - else if (b.equalsVersion.isEmpty()) - { + } else if (b.equalsVersion.isEmpty()) { out.equalsVersion = a.equalsVersion; - } - else if (a.equalsVersion == b.equalsVersion) - { + } else if (a.equalsVersion == b.equalsVersion) { out.equalsVersion = a.equalsVersion; - } - else - { + } else { // FIXME: mark error as explicit version conflict - return {false, out}; + return { false, out }; } - if(a.suggests.isEmpty()) - { + if (a.suggests.isEmpty()) { out.suggests = b.suggests; - } - else if (b.suggests.isEmpty()) - { + } else if (b.suggests.isEmpty()) { out.suggests = a.suggests; - } - else - { + } else { Version aVer(a.suggests); Version bVer(b.suggests); out.suggests = (aVer < bVer ? b.suggests : a.suggests); } - return {true, out}; + return { true, out }; } // gather the requirements from all components, finding any obvious conflicts -static bool gatherRequirementsFromComponents(const ComponentContainer & input, RequireExSet & output) +static bool gatherRequirementsFromComponents(const ComponentContainer& input, RequireExSet& output) { bool succeeded = true; size_t componentNum = 0; - for(auto component: input) - { - auto &componentRequires = component->m_cachedRequires; - for(const auto & componentRequire: componentRequires) - { - auto found = std::find_if(output.cbegin(), output.cend(), [componentRequire](const Meta::Require & req){ - return req.uid == componentRequire.uid; - }); + for (auto component : input) { + auto& componentRequires = component->m_cachedRequires; + for (const auto& componentRequire : componentRequires) { + auto found = std::find_if(output.cbegin(), output.cend(), + [componentRequire](const Meta::Require& req) { return req.uid == componentRequire.uid; }); RequireEx componenRequireEx; componenRequireEx.uid = componentRequire.uid; @@ -356,29 +292,18 @@ static bool gatherRequirementsFromComponents(const ComponentContainer & input, R componenRequireEx.equalsVersion = componentRequire.equalsVersion; componenRequireEx.indexOfFirstDependee = componentNum; - if(found != output.cend()) - { + if (found != output.cend()) { // found... process it further auto result = composeRequirement(componenRequireEx, *found); - if(result.ok) - { + if (result.ok) { output.erase(componenRequireEx); output.insert(result.outcome); - } - else - { - qCritical() - << "Conflicting requirements:" - << componentRequire.uid - << "versions:" - << componentRequire.equalsVersion - << ";" - << (*found).equalsVersion; + } else { + qCritical() << "Conflicting requirements:" << componentRequire.uid << "versions:" << componentRequire.equalsVersion + << ";" << (*found).equalsVersion; } succeeded &= result.ok; - } - else - { + } else { // not found, accumulate output.insert(componenRequireEx); } @@ -389,19 +314,17 @@ static bool gatherRequirementsFromComponents(const ComponentContainer & input, R } /// Get list of uids that can be trivially removed because nothing is depending on them anymore (and they are installed as deps) -static void getTrivialRemovals(const ComponentContainer & components, const RequireExSet & reqs, QStringList &toRemove) +static void getTrivialRemovals(const ComponentContainer& components, const RequireExSet& reqs, QStringList& toRemove) { - for(const auto & component: components) - { - if(!component->m_dependencyOnly) + for (const auto& component : components) { + if (!component->m_dependencyOnly) continue; - if(!component->m_cachedVolatile) + if (!component->m_cachedVolatile) continue; RequireEx reqNeedle; reqNeedle.uid = component->m_uid; const auto iter = reqs.find(reqNeedle); - if(iter == reqs.cend()) - { + if (iter == reqs.cend()) { toRemove.append(component->m_uid); } } @@ -415,60 +338,40 @@ static void getTrivialRemovals(const ComponentContainer & components, const Requ * toAdd - set of requirements than mean adding a new component * toChange - set of requirements that mean changing version of an existing component */ -static bool getTrivialComponentChanges(const ComponentIndex & index, const RequireExSet & input, RequireExSet & toAdd, RequireExSet & toChange) +static bool getTrivialComponentChanges(const ComponentIndex& index, const RequireExSet& input, RequireExSet& toAdd, RequireExSet& toChange) { - enum class Decision - { - Undetermined, - Met, - Missing, - VersionNotSame, - LockedVersionNotSame - } decision = Decision::Undetermined; + enum class Decision { Undetermined, Met, Missing, VersionNotSame, LockedVersionNotSame } decision = Decision::Undetermined; QString reqStr; bool succeeded = true; // list the composed requirements and say if they are met or unmet - for(auto & req: input) - { - do - { - if(req.equalsVersion.isEmpty()) - { + for (auto& req : input) { + do { + if (req.equalsVersion.isEmpty()) { reqStr = QString("Req: %1").arg(req.uid); - if(index.contains(req.uid)) - { + if (index.contains(req.uid)) { decision = Decision::Met; - } - else - { + } else { toAdd.insert(req); decision = Decision::Missing; } break; - } - else - { + } else { reqStr = QString("Req: %1 == %2").arg(req.uid, req.equalsVersion); - const auto & compIter = index.find(req.uid); - if(compIter == index.cend()) - { + const auto& compIter = index.find(req.uid); + if (compIter == index.cend()) { toAdd.insert(req); decision = Decision::Missing; break; } - auto & comp = (*compIter); - if(comp->getVersion() != req.equalsVersion) - { - if(comp->isCustom()) { + auto& comp = (*compIter); + if (comp->getVersion() != req.equalsVersion) { + if (comp->isCustom()) { decision = Decision::LockedVersionNotSame; } else { - if(comp->m_dependencyOnly) - { + if (comp->m_dependencyOnly) { decision = Decision::VersionNotSame; - } - else - { + } else { decision = Decision::LockedVersionNotSame; } } @@ -476,9 +379,8 @@ static bool getTrivialComponentChanges(const ComponentIndex & index, const Requi } decision = Decision::Met; } - } while(false); - switch(decision) - { + } while (false); + switch (decision) { case Decision::Undetermined: qCritical() << "No decision for" << reqStr; succeeded = false; @@ -520,26 +422,22 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly) * * NOTE: this is a placeholder and should eventually be replaced with something 'serious' */ - auto & components = d->m_list->d->components; - auto & componentIndex = d->m_list->d->componentIndex; + auto& components = d->m_list->d->components; + auto& componentIndex = d->m_list->d->componentIndex; RequireExSet allRequires; QStringList toRemove; - do - { + do { allRequires.clear(); toRemove.clear(); - if(!gatherRequirementsFromComponents(components, allRequires)) - { + if (!gatherRequirementsFromComponents(components, allRequires)) { emitFailed(tr("Conflicting requirements detected during dependency checking!")); return; } getTrivialRemovals(components, allRequires, toRemove); - if(!toRemove.isEmpty()) - { + if (!toRemove.isEmpty()) { qDebug() << "Removing obsolete components..."; - for(auto & remove : toRemove) - { + for (auto& remove : toRemove) { qDebug() << "Removing" << remove; d->m_list->remove(remove); } @@ -548,69 +446,50 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly) RequireExSet toAdd; RequireExSet toChange; bool succeeded = getTrivialComponentChanges(componentIndex, allRequires, toAdd, toChange); - if(!succeeded) - { + if (!succeeded) { emitFailed(tr("Instance has conflicting dependencies.")); return; } - if(checkOnly) - { - if(toAdd.size() || toChange.size()) - { + if (checkOnly) { + if (toAdd.size() || toChange.size()) { emitFailed(tr("Instance has unresolved dependencies while loading/checking for launch.")); - } - else - { + } else { emitSucceeded(); } return; } bool recursionNeeded = false; - if(toAdd.size()) - { + if (toAdd.size()) { // add stuff... - for(auto &add: toAdd) - { + for (auto& add : toAdd) { auto component = makeShared(d->m_list, add.uid); - if(!add.equalsVersion.isEmpty()) - { + if (!add.equalsVersion.isEmpty()) { // exact version qDebug() << "Adding" << add.uid << "version" << add.equalsVersion << "at position" << add.indexOfFirstDependee; component->m_version = add.equalsVersion; - } - else - { + } else { // version needs to be decided qDebug() << "Adding" << add.uid << "at position" << add.indexOfFirstDependee; -// ############################################################################################################ -// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded. - if(!add.suggests.isEmpty()) - { + // ############################################################################################################ + // HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded. + if (!add.suggests.isEmpty()) { component->m_version = add.suggests; - } - else - { - if(add.uid == "org.lwjgl") - { + } else { + if (add.uid == "org.lwjgl") { component->m_version = "2.9.1"; - } - else if (add.uid == "org.lwjgl3") - { + } else if (add.uid == "org.lwjgl3") { component->m_version = "3.1.2"; - } - else if (add.uid == "net.fabricmc.intermediary" || add.uid == "org.quiltmc.hashed") - { - auto minecraft = std::find_if(components.begin(), components.end(), [](ComponentPtr & cmp){ - return cmp->getID() == "net.minecraft"; - }); - if(minecraft != components.end()) { + } else if (add.uid == "net.fabricmc.intermediary" || add.uid == "org.quiltmc.hashed") { + auto minecraft = std::find_if(components.begin(), components.end(), + [](ComponentPtr& cmp) { return cmp->getID() == "net.minecraft"; }); + if (minecraft != components.end()) { component->m_version = (*minecraft)->getVersion(); } } } -// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded. -// ############################################################################################################ + // HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded. + // ############################################################################################################ } component->m_dependencyOnly = true; // FIXME: this should not work directly with the component list @@ -619,11 +498,9 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly) } recursionNeeded = true; } - if(toChange.size()) - { + if (toChange.size()) { // change a version of something that exists - for(auto &change: toChange) - { + for (auto& change : toChange) { // FIXME: this should not work directly with the component list qDebug() << "Setting version of " << change.uid << "to" << change.equalsVersion; auto component = componentIndex[change.uid]; @@ -632,31 +509,26 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly) recursionNeeded = true; } - if(recursionNeeded) - { + if (recursionNeeded) { loadComponents(); - } - else - { + } else { emitSucceeded(); } } void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex) { - auto &taskSlot = d->remoteLoadStatusList[taskIndex]; - if(taskSlot.finished) - { + auto& taskSlot = d->remoteLoadStatusList[taskIndex]; + if (taskSlot.finished) { qWarning() << "Got multiple results from remote load task" << taskIndex; return; } qDebug() << "Remote task" << taskIndex << "succeeded"; taskSlot.succeeded = false; taskSlot.finished = true; - d->remoteTasksInProgress --; + d->remoteTasksInProgress--; // update the cached data of the component from the downloaded version file. - if (taskSlot.type == RemoteLoadStatus::Type::Version) - { + if (taskSlot.type == RemoteLoadStatus::Type::Version) { auto component = d->m_list->getComponent(taskSlot.PackProfileIndex); component->m_loaded = true; component->updateCachedData(); @@ -664,12 +536,10 @@ void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex) checkIfAllFinished(); } - void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg) { - auto &taskSlot = d->remoteLoadStatusList[taskIndex]; - if(taskSlot.finished) - { + auto& taskSlot = d->remoteLoadStatusList[taskIndex]; + if (taskSlot.finished) { qWarning() << "Got multiple results from remote load task" << taskIndex; return; } @@ -678,31 +548,25 @@ void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg) taskSlot.succeeded = false; taskSlot.finished = true; taskSlot.error = msg; - d->remoteTasksInProgress --; + d->remoteTasksInProgress--; checkIfAllFinished(); } void ComponentUpdateTask::checkIfAllFinished() { - if(d->remoteTasksInProgress) - { + if (d->remoteTasksInProgress) { // not yet... return; } - if(d->remoteLoadSuccessful) - { + if (d->remoteLoadSuccessful) { // nothing bad happened... clear the temp load status and proceed with looking at dependencies d->remoteLoadStatusList.clear(); resolveDependencies(d->mode == Mode::Launch); - } - else - { + } else { // remote load failed... report error and bail QStringList allErrorsList; - for(auto & item: d->remoteLoadStatusList) - { - if(!item.succeeded) - { + for (auto& item : d->remoteLoadStatusList) { + if (!item.succeeded) { allErrorsList.append(item.error); } } diff --git a/launcher/minecraft/ComponentUpdateTask.h b/launcher/minecraft/ComponentUpdateTask.h index 4274cabb5..2f396a049 100644 --- a/launcher/minecraft/ComponentUpdateTask.h +++ b/launcher/minecraft/ComponentUpdateTask.h @@ -1,37 +1,32 @@ #pragma once -#include "tasks/Task.h" #include "net/Mode.h" +#include "tasks/Task.h" #include class PackProfile; struct ComponentUpdateTaskData; -class ComponentUpdateTask : public Task -{ +class ComponentUpdateTask : public Task { Q_OBJECT -public: - enum class Mode - { - Launch, - Resolution - }; + public: + enum class Mode { Launch, Resolution }; -public: - explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile * list, QObject *parent = 0); + public: + explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent = 0); virtual ~ComponentUpdateTask(); -protected: + protected: void executeTask(); -private: + private: void loadComponents(); void resolveDependencies(bool checkOnly); void remoteLoadSucceeded(size_t index); - void remoteLoadFailed(size_t index, const QString &msg); + void remoteLoadFailed(size_t index, const QString& msg); void checkIfAllFinished(); -private: + private: std::unique_ptr d; }; diff --git a/launcher/minecraft/ComponentUpdateTask_p.h b/launcher/minecraft/ComponentUpdateTask_p.h index 5b02431b2..00e8f2fbe 100644 --- a/launcher/minecraft/ComponentUpdateTask_p.h +++ b/launcher/minecraft/ComponentUpdateTask_p.h @@ -1,29 +1,22 @@ #pragma once -#include -#include #include +#include +#include #include "net/Mode.h" class PackProfile; -struct RemoteLoadStatus -{ - enum class Type - { - Index, - List, - Version - } type = Type::Version; +struct RemoteLoadStatus { + enum class Type { Index, List, Version } type = Type::Version; size_t PackProfileIndex = 0; bool finished = false; bool succeeded = false; QString error; }; -struct ComponentUpdateTaskData -{ - PackProfile * m_list = nullptr; +struct ComponentUpdateTaskData { + PackProfile* m_list = nullptr; QList remoteLoadStatusList; bool remoteLoadSuccessful = true; size_t remoteTasksInProgress = 0; diff --git a/launcher/minecraft/GradleSpecifier.h b/launcher/minecraft/GradleSpecifier.h index 27514ab9d..53c31e8e0 100644 --- a/launcher/minecraft/GradleSpecifier.h +++ b/launcher/minecraft/GradleSpecifier.h @@ -35,22 +35,15 @@ #pragma once +#include #include #include -#include #include "DefaultVariable.h" -struct GradleSpecifier -{ - GradleSpecifier() - { - m_valid = false; - } - GradleSpecifier(QString value) - { - operator=(value); - } - GradleSpecifier & operator =(const QString & value) +struct GradleSpecifier { + GradleSpecifier() { m_valid = false; } + GradleSpecifier(QString value) { operator=(value); } + GradleSpecifier& operator=(const QString& value) { /* org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar @@ -61,10 +54,13 @@ struct GradleSpecifier 4 "jdk15" 5 "jar" */ - QRegularExpression matcher(QRegularExpression::anchoredPattern("([^:@]+):([^:@]+):([^:@]+)" "(?::([^:@]+))?" "(?:@([^:@]+))?")); + QRegularExpression matcher( + QRegularExpression::anchoredPattern("([^:@]+):([^:@]+):([^:@]+)" + "(?::([^:@]+))?" + "(?:@([^:@]+))?")); QRegularExpressionMatch match = matcher.match(value); m_valid = match.hasMatch(); - if(!m_valid) { + if (!m_valid) { m_invalidValue = value; return *this; } @@ -73,53 +69,46 @@ struct GradleSpecifier m_artifactId = match.captured(2); m_version = match.captured(3); m_classifier = match.captured(4); - if(match.lastCapturedIndex() >= 5) - { + if (match.lastCapturedIndex() >= 5) { m_extension = match.captured(5); } return *this; } QString serialize() const { - if(!m_valid) { + if (!m_valid) { return m_invalidValue; } QString retval = m_groupId + ":" + m_artifactId + ":" + m_version; - if(!m_classifier.isEmpty()) - { + if (!m_classifier.isEmpty()) { retval += ":" + m_classifier; } - if(m_extension.isExplicit()) - { + if (m_extension.isExplicit()) { retval += "@" + m_extension; } return retval; } QString getFileName() const { - if(!m_valid) { + if (!m_valid) { return QString(); } QString filename = m_artifactId + '-' + m_version; - if(!m_classifier.isEmpty()) - { + if (!m_classifier.isEmpty()) { filename += "-" + m_classifier; } filename += "." + m_extension; return filename; } - QString toPath(const QString & filenameOverride = QString()) const + QString toPath(const QString& filenameOverride = QString()) const { - if(!m_valid) { + if (!m_valid) { return QString(); } QString filename; - if(filenameOverride.isEmpty()) - { + if (filenameOverride.isEmpty()) { filename = getFileName(); - } - else - { + } else { filename = filenameOverride; } QString path = m_groupId; @@ -127,57 +116,34 @@ struct GradleSpecifier path += '/' + m_artifactId + '/' + m_version + '/' + filename; return path; } - inline bool valid() const - { - return m_valid; - } - inline QString version() const - { - return m_version; - } - inline QString groupId() const - { - return m_groupId; - } - inline QString artifactId() const - { - return m_artifactId; - } - inline void setClassifier(const QString & classifier) - { - m_classifier = classifier; - } - inline QString classifier() const - { - return m_classifier; - } - inline QString extension() const - { - return m_extension; - } - inline QString artifactPrefix() const - { - return m_groupId + ":" + m_artifactId; - } - bool matchName(const GradleSpecifier & other) const + inline bool valid() const { return m_valid; } + inline QString version() const { return m_version; } + inline QString groupId() const { return m_groupId; } + inline QString artifactId() const { return m_artifactId; } + inline void setClassifier(const QString& classifier) { m_classifier = classifier; } + inline QString classifier() const { return m_classifier; } + inline QString extension() const { return m_extension; } + inline QString artifactPrefix() const { return m_groupId + ":" + m_artifactId; } + bool matchName(const GradleSpecifier& other) const { return other.artifactId() == artifactId() && other.groupId() == groupId() && other.classifier() == classifier(); } - bool operator==(const GradleSpecifier & other) const + bool operator==(const GradleSpecifier& other) const { - if(m_groupId != other.m_groupId) + if (m_groupId != other.m_groupId) return false; - if(m_artifactId != other.m_artifactId) + if (m_artifactId != other.m_artifactId) return false; - if(m_version != other.m_version) + if (m_version != other.m_version) return false; - if(m_classifier != other.m_classifier) + if (m_classifier != other.m_classifier) return false; - if(m_extension != other.m_extension) + if (m_extension != other.m_extension) return false; return true; } -private: + + private: QString m_invalidValue; QString m_groupId; QString m_artifactId; diff --git a/launcher/minecraft/LaunchProfile.cpp b/launcher/minecraft/LaunchProfile.cpp index 9a6cea11a..013c78ae3 100644 --- a/launcher/minecraft/LaunchProfile.cpp +++ b/launcher/minecraft/LaunchProfile.cpp @@ -55,9 +55,9 @@ void LaunchProfile::clear() m_problemSeverity = ProblemSeverity::None; } -static void applyString(const QString & from, QString & to) +static void applyString(const QString& from, QString& to) { - if(from.isEmpty()) + if (from.isEmpty()) return; to = from; } @@ -94,8 +94,7 @@ void LaunchProfile::applyMinecraftVersionType(const QString& type) void LaunchProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets) { - if(assets) - { + if (assets) { m_minecraftAssets = assets; } } @@ -109,10 +108,8 @@ void LaunchProfile::applyTweakers(const QStringList& tweakers) { // if the applied tweakers override an existing one, skip it. this effectively moves it later in the sequence QStringList newTweakers; - for(auto & tweaker: m_tweakers) - { - if (tweakers.contains(tweaker)) - { + for (auto& tweaker : m_tweakers) { + if (tweakers.contains(tweaker)) { continue; } newTweakers.append(tweaker); @@ -127,13 +124,11 @@ void LaunchProfile::applyJarMods(const QList& jarMods) this->m_jarMods.append(jarMods); } -static int findLibraryByName(QList *haystack, const GradleSpecifier &needle) +static int findLibraryByName(QList* haystack, const GradleSpecifier& needle) { int retval = -1; - for (int i = 0; i < haystack->size(); ++i) - { - if (haystack->at(i)->rawName().matchName(needle)) - { + for (int i = 0; i < haystack->size(); ++i) { + if (haystack->at(i)->rawName().matchName(needle)) { // only one is allowed. if (retval != -1) return -1; @@ -145,24 +140,21 @@ static int findLibraryByName(QList *haystack, const GradleSpecifier void LaunchProfile::applyMods(const QList& mods) { - QList * list = &m_mods; - for(auto & mod: mods) - { + QList* list = &m_mods; + for (auto& mod : mods) { auto modCopy = Library::limitedCopy(mod); // find the mod by name. const int index = findLibraryByName(list, mod->rawName()); // mod not found? just add it. - if (index < 0) - { + if (index < 0) { list->append(modCopy); return; } auto existingLibrary = list->at(index); // if we are higher it means we should update - if (Version(mod->version()) > Version(existingLibrary->version())) - { + if (Version(mod->version()) > Version(existingLibrary->version())) { list->replace(index, modCopy); } } @@ -173,16 +165,14 @@ void LaunchProfile::applyCompatibleJavaMajors(QList& javaMajor) m_compatibleJavaMajors.append(javaMajor); } -void LaunchProfile::applyLibrary(LibraryPtr library, const RuntimeContext & runtimeContext) +void LaunchProfile::applyLibrary(LibraryPtr library, const RuntimeContext& runtimeContext) { - if(!library->isActive(runtimeContext)) - { + if (!library->isActive(runtimeContext)) { return; } - QList * list = &m_libraries; - if(library->isNative()) - { + QList* list = &m_libraries; + if (library->isNative()) { list = &m_nativeLibraries; } @@ -191,29 +181,25 @@ void LaunchProfile::applyLibrary(LibraryPtr library, const RuntimeContext & runt // find the library by name. const int index = findLibraryByName(list, library->rawName()); // library not found? just add it. - if (index < 0) - { + if (index < 0) { list->append(libraryCopy); return; } auto existingLibrary = list->at(index); // if we are higher it means we should update - if (Version(library->version()) > Version(existingLibrary->version())) - { + if (Version(library->version()) > Version(existingLibrary->version())) { list->replace(index, libraryCopy); } } -void LaunchProfile::applyMavenFile(LibraryPtr mavenFile, const RuntimeContext & runtimeContext) +void LaunchProfile::applyMavenFile(LibraryPtr mavenFile, const RuntimeContext& runtimeContext) { - if(!mavenFile->isActive(runtimeContext)) - { + if (!mavenFile->isActive(runtimeContext)) { return; } - if(mavenFile->isNative()) - { + if (mavenFile->isNative()) { return; } @@ -221,16 +207,14 @@ void LaunchProfile::applyMavenFile(LibraryPtr mavenFile, const RuntimeContext & m_mavenFiles.append(Library::limitedCopy(mavenFile)); } -void LaunchProfile::applyAgent(AgentPtr agent, const RuntimeContext & runtimeContext) +void LaunchProfile::applyAgent(AgentPtr agent, const RuntimeContext& runtimeContext) { auto lib = agent->library(); - if(!lib->isActive(runtimeContext)) - { + if (!lib->isActive(runtimeContext)) { return; } - if(lib->isNative()) - { + if (lib->isNative()) { return; } @@ -244,16 +228,14 @@ const LibraryPtr LaunchProfile::getMainJar() const void LaunchProfile::applyMainJar(LibraryPtr jar) { - if(jar) - { + if (jar) { m_mainJar = jar; } } void LaunchProfile::applyProblemSeverity(ProblemSeverity severity) { - if (m_problemSeverity < severity) - { + if (m_problemSeverity < severity) { m_problemSeverity = severity; } } @@ -279,12 +261,12 @@ QString LaunchProfile::getMainClass() const return m_mainClass; } -const QSet &LaunchProfile::getTraits() const +const QSet& LaunchProfile::getTraits() const { return m_traits; } -const QStringList & LaunchProfile::getTweakers() const +const QStringList& LaunchProfile::getTweakers() const { return m_tweakers; } @@ -306,8 +288,7 @@ QString LaunchProfile::getMinecraftVersionType() const std::shared_ptr LaunchProfile::getMinecraftAssets() const { - if(!m_minecraftAssets) - { + if (!m_minecraftAssets) { return std::make_shared("legacy"); } return m_minecraftAssets; @@ -318,80 +299,69 @@ QString LaunchProfile::getMinecraftArguments() const return m_minecraftArguments; } -const QStringList & LaunchProfile::getAddnJvmArguments() const +const QStringList& LaunchProfile::getAddnJvmArguments() const { return m_addnJvmArguments; } -const QList & LaunchProfile::getJarMods() const +const QList& LaunchProfile::getJarMods() const { return m_jarMods; } -const QList & LaunchProfile::getLibraries() const +const QList& LaunchProfile::getLibraries() const { return m_libraries; } -const QList & LaunchProfile::getNativeLibraries() const +const QList& LaunchProfile::getNativeLibraries() const { return m_nativeLibraries; } -const QList & LaunchProfile::getMavenFiles() const +const QList& LaunchProfile::getMavenFiles() const { return m_mavenFiles; } -const QList & LaunchProfile::getAgents() const +const QList& LaunchProfile::getAgents() const { return m_agents; } -const QList & LaunchProfile::getCompatibleJavaMajors() const +const QList& LaunchProfile::getCompatibleJavaMajors() const { return m_compatibleJavaMajors; } -void LaunchProfile::getLibraryFiles( - const RuntimeContext & runtimeContext, - QStringList& jars, - QStringList& nativeJars, - const QString& overridePath, - const QString& tempPath -) const +void LaunchProfile::getLibraryFiles(const RuntimeContext& runtimeContext, + QStringList& jars, + QStringList& nativeJars, + const QString& overridePath, + const QString& tempPath) const { QStringList native32, native64; jars.clear(); nativeJars.clear(); - for (auto lib : getLibraries()) - { + for (auto lib : getLibraries()) { lib->getApplicableFiles(runtimeContext, jars, nativeJars, native32, native64, overridePath); } // NOTE: order is important here, add main jar last to the lists - if(m_mainJar) - { + if (m_mainJar) { // FIXME: HACK!! jar modding is weird and unsystematic! - if(m_jarMods.size()) - { + if (m_jarMods.size()) { QDir tempDir(tempPath); jars.append(tempDir.absoluteFilePath("minecraft.jar")); - } - else - { + } else { m_mainJar->getApplicableFiles(runtimeContext, jars, nativeJars, native32, native64, overridePath); } } - for (auto lib : getNativeLibraries()) - { + for (auto lib : getNativeLibraries()) { lib->getApplicableFiles(runtimeContext, jars, nativeJars, native32, native64, overridePath); } - if(runtimeContext.javaArchitecture == "32") - { + if (runtimeContext.javaArchitecture == "32") { nativeJars.append(native32); - } - else if(runtimeContext.javaArchitecture == "64") - { + } else if (runtimeContext.javaArchitecture == "64") { nativeJars.append(native64); } } diff --git a/launcher/minecraft/LaunchProfile.h b/launcher/minecraft/LaunchProfile.h index 49c1217d3..797631f37 100644 --- a/launcher/minecraft/LaunchProfile.h +++ b/launcher/minecraft/LaunchProfile.h @@ -34,17 +34,16 @@ */ #pragma once -#include -#include "Library.h" -#include "Agent.h" #include +#include +#include "Agent.h" +#include "Library.h" -class LaunchProfile: public ProblemProvider -{ -public: - virtual ~LaunchProfile() {}; +class LaunchProfile : public ProblemProvider { + public: + virtual ~LaunchProfile(){}; -public: /* application of profile variables from patches */ + public: /* application of profile variables from patches */ void applyMinecraftVersion(const QString& id); void applyMainClass(const QString& mainClass); void applyAppletClass(const QString& appletClass); @@ -52,48 +51,46 @@ public: /* application of profile variables from patches */ void applyAddnJvmArguments(const QStringList& minecraftArguments); void applyMinecraftVersionType(const QString& type); void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets); - void applyTraits(const QSet &traits); - void applyTweakers(const QStringList &tweakers); - void applyJarMods(const QList &jarMods); - void applyMods(const QList &jarMods); - void applyLibrary(LibraryPtr library, const RuntimeContext & runtimeContext); - void applyMavenFile(LibraryPtr library, const RuntimeContext & runtimeContext); - void applyAgent(AgentPtr agent, const RuntimeContext & runtimeContext); + void applyTraits(const QSet& traits); + void applyTweakers(const QStringList& tweakers); + void applyJarMods(const QList& jarMods); + void applyMods(const QList& jarMods); + void applyLibrary(LibraryPtr library, const RuntimeContext& runtimeContext); + void applyMavenFile(LibraryPtr library, const RuntimeContext& runtimeContext); + void applyAgent(AgentPtr agent, const RuntimeContext& runtimeContext); void applyCompatibleJavaMajors(QList& javaMajor); void applyMainJar(LibraryPtr jar); void applyProblemSeverity(ProblemSeverity severity); /// clear the profile void clear(); -public: /* getters for profile variables */ + public: /* getters for profile variables */ QString getMinecraftVersion() const; QString getMainClass() const; QString getAppletClass() const; QString getMinecraftVersionType() const; MojangAssetIndexInfo::Ptr getMinecraftAssets() const; QString getMinecraftArguments() const; - const QStringList & getAddnJvmArguments() const; - const QSet & getTraits() const; - const QStringList & getTweakers() const; - const QList & getJarMods() const; - const QList & getLibraries() const; - const QList & getNativeLibraries() const; - const QList & getMavenFiles() const; - const QList & getAgents() const; - const QList & getCompatibleJavaMajors() const; + const QStringList& getAddnJvmArguments() const; + const QSet& getTraits() const; + const QStringList& getTweakers() const; + const QList& getJarMods() const; + const QList& getLibraries() const; + const QList& getNativeLibraries() const; + const QList& getMavenFiles() const; + const QList& getAgents() const; + const QList& getCompatibleJavaMajors() const; const LibraryPtr getMainJar() const; - void getLibraryFiles( - const RuntimeContext & runtimeContext, - QStringList & jars, - QStringList & nativeJars, - const QString & overridePath, - const QString & tempPath - ) const; - bool hasTrait(const QString & trait) const; + void getLibraryFiles(const RuntimeContext& runtimeContext, + QStringList& jars, + QStringList& nativeJars, + const QString& overridePath, + const QString& tempPath) const; + bool hasTrait(const QString& trait) const; ProblemSeverity getProblemSeverity() const override; const QList getProblems() const override; -private: + private: /// the version of Minecraft - jar to use QString m_minecraftVersion; @@ -154,5 +151,4 @@ private: QList m_compatibleJavaMajors; ProblemSeverity m_problemSeverity = ProblemSeverity::None; - }; diff --git a/launcher/minecraft/Library.cpp b/launcher/minecraft/Library.cpp index cb2b5254d..53c285d86 100644 --- a/launcher/minecraft/Library.cpp +++ b/launcher/minecraft/Library.cpp @@ -36,106 +36,90 @@ #include "Library.h" #include "MinecraftInstance.h" -#include -#include -#include #include +#include +#include +#include - -void Library::getApplicableFiles(const RuntimeContext & runtimeContext, QStringList& jar, QStringList& native, QStringList& native32, - QStringList& native64, const QString &overridePath) const +void Library::getApplicableFiles(const RuntimeContext& runtimeContext, + QStringList& jar, + QStringList& native, + QStringList& native32, + QStringList& native64, + const QString& overridePath) const { bool local = isLocal(); - auto actualPath = [&](QString relPath) - { + auto actualPath = [&](QString relPath) { QFileInfo out(FS::PathCombine(storagePrefix(), relPath)); - if(local && !overridePath.isEmpty()) - { + if (local && !overridePath.isEmpty()) { QString fileName = out.fileName(); return QFileInfo(FS::PathCombine(overridePath, fileName)).absoluteFilePath(); } return out.absoluteFilePath(); }; QString raw_storage = storageSuffix(runtimeContext); - if(isNative()) - { - if (raw_storage.contains("${arch}")) - { + if (isNative()) { + if (raw_storage.contains("${arch}")) { auto nat32Storage = raw_storage; nat32Storage.replace("${arch}", "32"); auto nat64Storage = raw_storage; nat64Storage.replace("${arch}", "64"); native32 += actualPath(nat32Storage); native64 += actualPath(nat64Storage); - } - else - { + } else { native += actualPath(raw_storage); } - } - else - { + } else { jar += actualPath(raw_storage); } } -QList Library::getDownloads( - const RuntimeContext & runtimeContext, - class HttpMetaCache* cache, - QStringList& failedLocalFiles, - const QString & overridePath -) const +QList Library::getDownloads(const RuntimeContext& runtimeContext, + class HttpMetaCache* cache, + QStringList& failedLocalFiles, + const QString& overridePath) const { QList out; bool stale = isAlwaysStale(); bool local = isLocal(); - auto check_local_file = [&](QString storage) - { + auto check_local_file = [&](QString storage) { QFileInfo fileinfo(storage); QString fileName = fileinfo.fileName(); auto fullPath = FS::PathCombine(overridePath, fileName); QFileInfo localFileInfo(fullPath); - if(!localFileInfo.exists()) - { + if (!localFileInfo.exists()) { failedLocalFiles.append(localFileInfo.filePath()); return false; } return true; }; - auto add_download = [&](QString storage, QString url, QString sha1) - { - if(local) - { + auto add_download = [&](QString storage, QString url, QString sha1) { + if (local) { return check_local_file(storage); } auto entry = cache->resolveEntry("libraries", storage); - if(stale) - { + if (stale) { entry->setStale(true); } if (!entry->isStale()) return true; Net::Download::Options options; - if(stale) - { + if (stale) { options |= Net::Download::Option::AcceptLocalFiles; } // Don't add a time limit for the libraries cache entry validity options |= Net::Download::Option::MakeEternal; - if(sha1.size()) - { + if (sha1.size()) { auto rawSha1 = QByteArray::fromHex(sha1.toLatin1()); auto dl = Net::Download::makeCached(url, entry, options); dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); qDebug() << "Checksummed Download for:" << rawName().serialize() << "storage:" << storage << "url:" << url; out.append(dl); - } - else - { + } else { out.append(Net::Download::makeCached(url, entry, options)); qDebug() << "Download for:" << rawName().serialize() << "storage:" << storage << "url:" << url; } @@ -143,121 +127,89 @@ QList Library::getDownloads( }; QString raw_storage = storageSuffix(runtimeContext); - if(m_mojangDownloads) - { - if(isNative()) - { + if (m_mojangDownloads) { + if (isNative()) { auto nativeClassifier = getCompatibleNative(runtimeContext); - if(!nativeClassifier.isNull()) - { - if(nativeClassifier.contains("${arch}")) - { + if (!nativeClassifier.isNull()) { + if (nativeClassifier.contains("${arch}")) { auto nat32Classifier = nativeClassifier; nat32Classifier.replace("${arch}", "32"); auto nat64Classifier = nativeClassifier; nat64Classifier.replace("${arch}", "64"); auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier); - if(nat32info) - { + if (nat32info) { auto cooked_storage = raw_storage; cooked_storage.replace("${arch}", "32"); add_download(cooked_storage, nat32info->url, nat32info->sha1); } auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier); - if(nat64info) - { + if (nat64info) { auto cooked_storage = raw_storage; cooked_storage.replace("${arch}", "64"); add_download(cooked_storage, nat64info->url, nat64info->sha1); } - } - else - { + } else { auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier); - if(info) - { + if (info) { add_download(raw_storage, info->url, info->sha1); } } - } - else - { + } else { qDebug() << "Ignoring native library" << m_name.serialize() << "because it has no classifier for current OS"; } - } - else - { - if(m_mojangDownloads->artifact) - { + } else { + if (m_mojangDownloads->artifact) { auto artifact = m_mojangDownloads->artifact; add_download(raw_storage, artifact->url, artifact->sha1); - } - else - { + } else { qDebug() << "Ignoring java library" << m_name.serialize() << "because it has no artifact"; } } - } - else - { - auto raw_dl = [&]() - { - if (!m_absoluteURL.isEmpty()) - { + } else { + auto raw_dl = [&]() { + if (!m_absoluteURL.isEmpty()) { return m_absoluteURL; } - if (m_repositoryURL.isEmpty()) - { + if (m_repositoryURL.isEmpty()) { return BuildConfig.LIBRARY_BASE + raw_storage; } - if(m_repositoryURL.endsWith('/')) - { + if (m_repositoryURL.endsWith('/')) { return m_repositoryURL + raw_storage; - } - else - { + } else { return m_repositoryURL + QChar('/') + raw_storage; } }(); - if (raw_storage.contains("${arch}")) - { + if (raw_storage.contains("${arch}")) { QString cooked_storage = raw_storage; QString cooked_dl = raw_dl; add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"), QString()); cooked_storage = raw_storage; cooked_dl = raw_dl; add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"), QString()); - } - else - { + } else { add_download(raw_storage, raw_dl, QString()); } } return out; } -bool Library::isActive(const RuntimeContext & runtimeContext) const +bool Library::isActive(const RuntimeContext& runtimeContext) const { bool result = true; - if (m_rules.empty()) - { + if (m_rules.empty()) { result = true; - } - else - { + } else { RuleAction ruleResult = Disallow; - for (auto rule : m_rules) - { + for (auto rule : m_rules) { RuleAction temp = rule->apply(this, runtimeContext); if (temp != Defer) ruleResult = temp; } result = result && (ruleResult == Allow); } - if (isNative()) - { + if (isNative()) { result = result && !getCompatibleNative(runtimeContext).isNull(); } return result; @@ -273,7 +225,8 @@ bool Library::isAlwaysStale() const return m_hint == "always-stale"; } -QString Library::getCompatibleNative(const RuntimeContext & runtimeContext) const { +QString Library::getCompatibleNative(const RuntimeContext& runtimeContext) const +{ // try to match precise classifier "[os]-[arch]" auto entry = m_nativeClassifiers.constFind(runtimeContext.getClassifier()); // try to match imprecise classifier on legacy architectures "[os]" @@ -298,63 +251,53 @@ QString Library::defaultStoragePrefix() QString Library::storagePrefix() const { - if(m_storagePrefix.isEmpty()) - { + if (m_storagePrefix.isEmpty()) { return defaultStoragePrefix(); } return m_storagePrefix; } -QString Library::filename(const RuntimeContext & runtimeContext) const +QString Library::filename(const RuntimeContext& runtimeContext) const { - if(!m_filename.isEmpty()) - { + if (!m_filename.isEmpty()) { return m_filename; } // non-native? use only the gradle specifier - if (!isNative()) - { + if (!isNative()) { return m_name.getFileName(); } // otherwise native, override classifiers. Mojang HACK! GradleSpecifier nativeSpec = m_name; QString nativeClassifier = getCompatibleNative(runtimeContext); - if (!nativeClassifier.isNull()) - { + if (!nativeClassifier.isNull()) { nativeSpec.setClassifier(nativeClassifier); - } - else - { + } else { nativeSpec.setClassifier("INVALID"); } return nativeSpec.getFileName(); } -QString Library::displayName(const RuntimeContext & runtimeContext) const +QString Library::displayName(const RuntimeContext& runtimeContext) const { - if(!m_displayname.isEmpty()) + if (!m_displayname.isEmpty()) return m_displayname; return filename(runtimeContext); } -QString Library::storageSuffix(const RuntimeContext & runtimeContext) const +QString Library::storageSuffix(const RuntimeContext& runtimeContext) const { // non-native? use only the gradle specifier - if (!isNative()) - { + if (!isNative()) { return m_name.toPath(m_filename); } // otherwise native, override classifiers. Mojang HACK! GradleSpecifier nativeSpec = m_name; QString nativeClassifier = getCompatibleNative(runtimeContext); - if (!nativeClassifier.isNull()) - { + if (!nativeClassifier.isNull()) { nativeSpec.setClassifier(nativeClassifier); - } - else - { + } else { nativeSpec.setClassifier("INVALID"); } return nativeSpec.toPath(m_filename); diff --git a/launcher/minecraft/Library.h b/launcher/minecraft/Library.h index 26dbf962d..a24c11215 100644 --- a/launcher/minecraft/Library.h +++ b/launcher/minecraft/Library.h @@ -34,20 +34,19 @@ */ #pragma once -#include #include -#include +#include #include +#include +#include #include #include -#include -#include #include #include -#include "Rule.h" #include "GradleSpecifier.h" #include "MojangDownloadInfo.h" +#include "Rule.h" #include "RuntimeContext.h" class Library; @@ -55,19 +54,14 @@ class MinecraftInstance; typedef std::shared_ptr LibraryPtr; -class Library -{ +class Library { friend class OneSixVersionFormat; friend class MojangVersionFormat; friend class LibraryTest; -public: - Library() - { - } - Library(const QString &name) - { - m_name = name; - } + + public: + Library() {} + Library(const QString& name) { m_name = name; } /// limited copy without some data. TODO: why? static LibraryPtr limitedCopy(LibraryPtr base) { @@ -85,98 +79,60 @@ public: return newlib; } -public: /* methods */ + public: /* methods */ /// Returns the raw name field - const GradleSpecifier & rawName() const - { - return m_name; - } + const GradleSpecifier& rawName() const { return m_name; } - void setRawName(const GradleSpecifier & spec) - { - m_name = spec; - } + void setRawName(const GradleSpecifier& spec) { m_name = spec; } - void setClassifier(const QString & spec) - { - m_name.setClassifier(spec); - } + void setClassifier(const QString& spec) { m_name.setClassifier(spec); } /// returns the full group and artifact prefix - QString artifactPrefix() const - { - return m_name.artifactPrefix(); - } + QString artifactPrefix() const { return m_name.artifactPrefix(); } /// get the artifact ID - QString artifactId() const - { - return m_name.artifactId(); - } + QString artifactId() const { return m_name.artifactId(); } /// get the artifact version - QString version() const - { - return m_name.version(); - } + QString version() const { return m_name.version(); } /// Returns true if the library is native - bool isNative() const - { - return m_nativeClassifiers.size() != 0; - } + bool isNative() const { return m_nativeClassifiers.size() != 0; } void setStoragePrefix(QString prefix = QString()); /// Set the url base for downloads - void setRepositoryURL(const QString &base_url) - { - m_repositoryURL = base_url; - } + void setRepositoryURL(const QString& base_url) { m_repositoryURL = base_url; } - void getApplicableFiles(const RuntimeContext & runtimeContext, QStringList & jar, QStringList & native, - QStringList & native32, QStringList & native64, const QString & overridePath) const; + void getApplicableFiles(const RuntimeContext& runtimeContext, + QStringList& jar, + QStringList& native, + QStringList& native32, + QStringList& native64, + const QString& overridePath) const; - void setAbsoluteUrl(const QString &absolute_url) - { - m_absoluteURL = absolute_url; - } + void setAbsoluteUrl(const QString& absolute_url) { m_absoluteURL = absolute_url; } - void setFilename(const QString &filename) - { - m_filename = filename; - } + void setFilename(const QString& filename) { m_filename = filename; } /// Get the file name of the library - QString filename(const RuntimeContext & runtimeContext) const; + QString filename(const RuntimeContext& runtimeContext) const; // DEPRECATED: set a display name, used by jar mods only - void setDisplayName(const QString & displayName) - { - m_displayname = displayName; - } + void setDisplayName(const QString& displayName) { m_displayname = displayName; } /// Get the file name of the library - QString displayName(const RuntimeContext & runtimeContext) const; + QString displayName(const RuntimeContext& runtimeContext) const; - void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info) - { - m_mojangDownloads = info; - } + void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info) { m_mojangDownloads = info; } - void setHint(const QString &hint) - { - m_hint = hint; - } + void setHint(const QString& hint) { m_hint = hint; } /// Set the load rules - void setRules(QList> rules) - { - m_rules = rules; - } + void setRules(QList> rules) { m_rules = rules; } /// Returns true if the library should be loaded (or extracted, in case of natives) - bool isActive(const RuntimeContext & runtimeContext) const; + bool isActive(const RuntimeContext& runtimeContext) const; /// Returns true if the library is contained in an instance and false if it is shared bool isLocal() const; @@ -188,12 +144,14 @@ public: /* methods */ bool isForge() const; // Get a list of downloads for this library - QList getDownloads(const RuntimeContext & runtimeContext, class HttpMetaCache * cache, - QStringList & failedLocalFiles, const QString & overridePath) const; + QList getDownloads(const RuntimeContext& runtimeContext, + class HttpMetaCache* cache, + QStringList& failedLocalFiles, + const QString& overridePath) const; - QString getCompatibleNative(const RuntimeContext & runtimeContext) const; + QString getCompatibleNative(const RuntimeContext& runtimeContext) const; -private: /* methods */ + private: /* methods */ /// the default storage prefix used by Prism Launcher static QString defaultStoragePrefix(); @@ -201,14 +159,11 @@ private: /* methods */ QString storagePrefix() const; /// Get the relative file path where the library should be saved - QString storageSuffix(const RuntimeContext & runtimeContext) const; + QString storageSuffix(const RuntimeContext& runtimeContext) const; - QString hint() const - { - return m_hint; - } + QString hint() const { return m_hint; } -protected: /* data */ + protected: /* data */ /// the basic gradle dependency specifier. GradleSpecifier m_name; @@ -253,4 +208,3 @@ protected: /* data */ /// MOJANG: container with Mojang style download info MojangLibraryDownloadInfo::Ptr m_mojangDownloads; }; - diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 07ed04f96..305bff67b 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -37,32 +37,32 @@ */ #include "MinecraftInstance.h" +#include "Application.h" #include "BuildConfig.h" #include "minecraft/launch/CreateGameFolders.h" #include "minecraft/launch/ExtractNatives.h" #include "minecraft/launch/PrintInstanceInfo.h" #include "settings/Setting.h" #include "settings/SettingsObject.h" -#include "Application.h" -#include "pathmatcher/RegexpMatcher.h" -#include "pathmatcher/MultiMatcher.h" #include "FileSystem.h" -#include "java/JavaVersion.h" #include "MMCTime.h" +#include "java/JavaVersion.h" +#include "pathmatcher/MultiMatcher.h" +#include "pathmatcher/RegexpMatcher.h" #include "launch/LaunchTask.h" +#include "launch/steps/CheckJava.h" #include "launch/steps/LookupServerAddress.h" #include "launch/steps/PostLaunchCommand.h" -#include "launch/steps/Update.h" #include "launch/steps/PreLaunchCommand.h" -#include "launch/steps/TextPrint.h" -#include "launch/steps/CheckJava.h" #include "launch/steps/QuitAfterGameStop.h" +#include "launch/steps/TextPrint.h" +#include "launch/steps/Update.h" +#include "minecraft/launch/ClaimAccount.h" #include "minecraft/launch/LauncherPartLaunch.h" #include "minecraft/launch/ModMinecraftJar.h" -#include "minecraft/launch/ClaimAccount.h" #include "minecraft/launch/ReconstructAssets.h" #include "minecraft/launch/ScanModFolders.h" #include "minecraft/launch/VerifyJavaInstall.h" @@ -81,10 +81,10 @@ #include "WorldList.h" -#include "PackProfile.h" #include "AssetsUtils.h" -#include "MinecraftUpdate.h" #include "MinecraftLoadAndCheck.h" +#include "MinecraftUpdate.h" +#include "PackProfile.h" #include "minecraft/gameoptions/GameOptions.h" #include "minecraft/update/FoldersTask.h" @@ -96,14 +96,10 @@ // all of this because keeping things compatible with deprecated old settings // if either of the settings {a, b} is true, this also resolves to true -class OrSetting : public Setting -{ +class OrSetting : public Setting { Q_OBJECT -public: - OrSetting(QString id, std::shared_ptr a, std::shared_ptr b) - :Setting({id}, false), m_a(a), m_b(b) - { - } + public: + OrSetting(QString id, std::shared_ptr a, std::shared_ptr b) : Setting({ id }, false), m_a(a), m_b(b) {} virtual QVariant get() const { bool a = m_a->get().toBool(); @@ -112,12 +108,13 @@ public: } virtual void reset() {} virtual void set(QVariant value) {} -private: + + private: std::shared_ptr m_a; std::shared_ptr m_b; }; -MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) +MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) : BaseInstance(globalSettings, settings, rootDir) { m_components.reset(new PackProfile(this)); @@ -222,14 +219,12 @@ std::shared_ptr MinecraftInstance::getPackProfile() const QSet MinecraftInstance::traits() const { auto components = getPackProfile(); - if (!components) - { - return {"version-incomplete"}; + if (!components) { + return { "version-incomplete" }; } auto profile = components->getProfile(); - if (!profile) - { - return {"version-incomplete"}; + if (!profile) { + return { "version-incomplete" }; } return profile->getTraits(); } @@ -264,7 +259,7 @@ QString MinecraftInstance::getLocalLibraryPath() const bool MinecraftInstance::supportsDemo() const { - Version instance_ver { getPackProfile()->getComponentVersion("net.minecraft") }; + Version instance_ver{ getPackProfile()->getComponentVersion("net.minecraft") }; // Demo mode was introduced in 1.3.1: https://minecraft.fandom.com/wiki/Demo_mode#History // FIXME: Due to Version constraints atm, this can't handle well non-release versions return instance_ver >= Version("1.3.1"); @@ -375,21 +370,18 @@ QStringList MinecraftInstance::extraArguments() if (!version) return list; auto jarMods = getJarMods(); - if (!jarMods.isEmpty()) - { - list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true", - "-Dfml.ignorePatchDiscrepancies=true"}); + if (!jarMods.isEmpty()) { + list.append({ "-Dfml.ignoreInvalidMinecraftCertificates=true", "-Dfml.ignorePatchDiscrepancies=true" }); } auto addn = m_components->getProfile()->getAddnJvmArguments(); if (!addn.isEmpty()) { list.append(addn); } auto agents = m_components->getProfile()->getAgents(); - for (auto agent : agents) - { + for (auto agent : agents) { QStringList jar, temp1, temp2, temp3; agent->library()->getApplicableFiles(runtimeContext(), jar, temp1, temp2, temp3, getLocalLibraryPath()); - list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument())); + list.append("-javaagent:" + jar[0] + (agent->argument().isEmpty() ? "" : "=" + agent->argument())); } { @@ -416,38 +408,33 @@ QStringList MinecraftInstance::javaArguments() // HACK: fix issues on macOS with 1.13 snapshots // NOTE: Oracle Java option. if there are alternate jvm implementations, this would be the place to customize this for them #ifdef Q_OS_MAC - if(traits_.contains("FirstThreadOnMacOS")) - { + if (traits_.contains("FirstThreadOnMacOS")) { args << QString("-XstartOnFirstThread"); } #endif // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767 #ifdef Q_OS_WIN32 - args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_" - "minecraft.exe.heapdump"); + args << QString( + "-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_" + "minecraft.exe.heapdump"); #endif int min = settings()->get("MinMemAlloc").toInt(); int max = settings()->get("MaxMemAlloc").toInt(); - if(min < max) - { + if (min < max) { args << QString("-Xms%1m").arg(min); args << QString("-Xmx%1m").arg(max); - } - else - { + } else { args << QString("-Xms%1m").arg(max); args << QString("-Xmx%1m").arg(min); } // No PermGen in newer java. JavaVersion javaVersion = getJavaVersion(); - if(javaVersion.requiresPermGen()) - { + if (javaVersion.requiresPermGen()) { auto permgen = settings()->get("PermGen").toInt(); - if (permgen != 64) - { + if (permgen != 64) { args << QString("-XX:PermSize=%1m").arg(permgen); } } @@ -487,8 +474,7 @@ QProcessEnvironment MinecraftInstance::createEnvironment() // export some infos auto variables = getVariables(); - for (auto it = variables.begin(); it != variables.end(); ++it) - { + for (auto it = variables.begin(); it != variables.end(); ++it) { env.insert(it.key(), it.value()); } return env; @@ -500,15 +486,12 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment() QProcessEnvironment env = createEnvironment(); #ifdef Q_OS_LINUX - if (settings()->get("EnableMangoHud").toBool() && APPLICATION->capabilities() & Application::SupportsMangoHud) - { - + if (settings()->get("EnableMangoHud").toBool() && APPLICATION->capabilities() & Application::SupportsMangoHud) { auto preloadList = env.value("LD_PRELOAD").split(QLatin1String(":")); auto libPaths = env.value("LD_LIBRARY_PATH").split(QLatin1String(":")); auto mangoHudLibString = MangoHud::getLibraryString(); - if (!mangoHudLibString.isEmpty()) - { + if (!mangoHudLibString.isEmpty()) { QFileInfo mangoHudLib(mangoHudLibString); // dlsym variant is only needed for OpenGL and not included in the vulkan layer @@ -521,8 +504,7 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment() env.insert("MANGOHUD", "1"); } - if (settings()->get("UseDiscreteGpu").toBool()) - { + if (settings()->get("UseDiscreteGpu").toBool()) { // Open Source Drivers env.insert("DRI_PRIME", "1"); // Proprietary Nvidia Drivers @@ -543,14 +525,12 @@ static QString replaceTokensIn(QString text, QMap with) QStringList list; QRegularExpressionMatchIterator i = token_regexp.globalMatch(text); int lastCapturedEnd = 0; - while (i.hasNext()) - { + while (i.hasNext()) { QRegularExpressionMatch match = i.next(); result.append(text.mid(lastCapturedEnd, match.capturedStart())); QString key = match.captured(1); auto iter = with.find(key); - if (iter != with.end()) - { + if (iter != with.end()) { result.append(*iter); } lastCapturedEnd = match.capturedEnd(); @@ -559,25 +539,22 @@ static QString replaceTokensIn(QString text, QMap with) return result; } -QStringList MinecraftInstance::processMinecraftArgs( - AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) const +QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) const { auto profile = m_components->getProfile(); QString args_pattern = profile->getMinecraftArguments(); - for (auto tweaker : profile->getTweakers()) - { + for (auto tweaker : profile->getTweakers()) { args_pattern += " --tweakClass " + tweaker; } - if (serverToJoin && !serverToJoin->address.isEmpty()) - { + if (serverToJoin && !serverToJoin->address.isEmpty()) { args_pattern += " --server " + serverToJoin->address; args_pattern += " --port " + QString::number(serverToJoin->port); } QMap token_mapping; // yggdrasil! - if(session) { + if (session) { // token_mapping["auth_username"] = session->username; token_mapping["auth_session"] = session->session; token_mapping["auth_access_token"] = session->access_token; @@ -585,7 +562,7 @@ QStringList MinecraftInstance::processMinecraftArgs( token_mapping["auth_uuid"] = session->uuid; token_mapping["user_properties"] = session->serializeUserProperties(); token_mapping["user_type"] = session->user_type; - if(session->demo) { + if (session->demo) { args_pattern += " --demo"; } } @@ -609,8 +586,7 @@ QStringList MinecraftInstance::processMinecraftArgs( #else QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts); #endif - for (int i = 0; i < parts.length(); i++) - { + for (int i = 0; i < parts.length(); i++) { parts[i] = replaceTokensIn(parts[i], token_mapping); } return parts; @@ -623,32 +599,26 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS if (!m_components) return QString(); auto profile = m_components->getProfile(); - if(!profile) + if (!profile) return QString(); auto mainClass = getMainClass(); - if (!mainClass.isEmpty()) - { + if (!mainClass.isEmpty()) { launchScript += "mainClass " + mainClass + "\n"; } auto appletClass = profile->getAppletClass(); - if (!appletClass.isEmpty()) - { + if (!appletClass.isEmpty()) { launchScript += "appletClass " + appletClass + "\n"; } - if (serverToJoin && !serverToJoin->address.isEmpty()) - { + if (serverToJoin && !serverToJoin->address.isEmpty()) { launchScript += "serverAddress " + serverToJoin->address + "\n"; launchScript += "serverPort " + QString::number(serverToJoin->port) + "\n"; } // generic minecraft params - for (auto param : processMinecraftArgs( - session, - nullptr /* When using a launch script, the server parameters are handled by it*/ - )) - { + for (auto param : processMinecraftArgs(session, nullptr /* When using a launch script, the server parameters are handled by it*/ + )) { launchScript += "param " + param + "\n"; } @@ -658,22 +628,19 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS if (settings()->get("LaunchMaximized").toBool()) windowParams = "max"; else - windowParams = QString("%1x%2") - .arg(settings()->get("MinecraftWinWidth").toInt()) - .arg(settings()->get("MinecraftWinHeight").toInt()); + windowParams = + QString("%1x%2").arg(settings()->get("MinecraftWinWidth").toInt()).arg(settings()->get("MinecraftWinHeight").toInt()); launchScript += "windowTitle " + windowTitle() + "\n"; launchScript += "windowParams " + windowParams + "\n"; } // legacy auth - if(session) - { + if (session) { launchScript += "userName " + session->player_name + "\n"; launchScript += "sessionId " + session->session + "\n"; } - for (auto trait : profile->getTraits()) - { + for (auto trait : profile->getTraits()) { launchScript += "traits " + trait + "\n"; } @@ -686,17 +653,17 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) { QStringList out; - out << "Main Class:" << " " + getMainClass() << ""; - out << "Native path:" << " " + getNativePath() << ""; + out << "Main Class:" + << " " + getMainClass() << ""; + out << "Native path:" + << " " + getNativePath() << ""; auto profile = m_components->getProfile(); auto alltraits = traits(); - if(alltraits.size()) - { + if (alltraits.size()) { out << "Traits:"; - for (auto trait : alltraits) - { + for (auto trait : alltraits) { out << "traits " + trait; } out << ""; @@ -705,8 +672,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr auto settings = this->settings(); bool nativeOpenAL = settings->get("UseNativeOpenAL").toBool(); bool nativeGLFW = settings->get("UseNativeGLFW").toBool(); - if (nativeOpenAL || nativeGLFW) - { + if (nativeOpenAL || nativeGLFW) { if (nativeOpenAL) out << "Using system OpenAL."; if (nativeGLFW) @@ -719,34 +685,27 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr out << "Libraries:"; QStringList jars, nativeJars; profile->getLibraryFiles(runtimeContext(), jars, nativeJars, getLocalLibraryPath(), binRoot()); - auto printLibFile = [&](const QString & path) - { + auto printLibFile = [&](const QString& path) { QFileInfo info(path); - if(info.exists()) - { + if (info.exists()) { out << " " + path; - } - else - { + } else { out << " " + path + " (missing)"; } }; - for(auto file: jars) - { + for (auto file : jars) { printLibFile(file); } out << ""; out << "Native libraries:"; - for(auto file: nativeJars) - { + for (auto file : nativeJars) { printLibFile(file); } out << ""; } - auto printModList = [&](const QString & label, ModFolderModel & model) { - if(model.size()) - { + auto printModList = [&](const QString& label, ModFolderModel& model) { + if (model.size()) { out << QString("%1:").arg(label); auto modList = model.allMods(); std::sort(modList.begin(), modList.end(), [](auto a, auto b) { @@ -754,21 +713,17 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr auto bName = b->fileinfo().completeBaseName(); return aName.localeAwareCompare(bName) < 0; }); - for(auto mod: modList) - { - if(mod->type() == ResourceType::FOLDER) - { + for (auto mod : modList) { + if (mod->type() == ResourceType::FOLDER) { out << u8" [🖿] " + mod->fileinfo().completeBaseName() + " (folder)"; continue; } - if(mod->enabled()) { + if (mod->enabled()) { out << u8" [✔] " + mod->fileinfo().completeBaseName(); - } - else { + } else { out << u8" [✘] " + mod->fileinfo().completeBaseName() + " (disabled)"; } - } out << ""; } @@ -777,20 +732,15 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr printModList("Mods", *(loaderModList().get())); printModList("Core Mods", *(coreModList().get())); - auto & jarMods = profile->getJarMods(); - if(jarMods.size()) - { + auto& jarMods = profile->getJarMods(); + if (jarMods.size()) { out << "Jar Mods:"; - for(auto & jarmod: jarMods) - { + for (auto& jarmod : jarMods) { auto displayname = jarmod->displayName(runtimeContext()); auto realname = jarmod->filename(runtimeContext()); - if(displayname != realname) - { + if (displayname != realname) { out << " " + displayname + " (" + realname + ")"; - } - else - { + } else { out << " " + realname; } } @@ -803,12 +753,9 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr out << ""; QString windowParams; - if (settings->get("LaunchMaximized").toBool()) - { + if (settings->get("LaunchMaximized").toBool()) { out << "Window size: max (if available)"; - } - else - { + } else { auto width = settings->get("MinecraftWinWidth").toInt(); auto height = settings->get("MinecraftWinHeight").toInt(); out << "Window size: " + QString::number(width) + " x " + QString::number(height); @@ -821,27 +768,23 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr QMap MinecraftInstance::createCensorFilterFromSession(AuthSessionPtr session) { - if(!session) - { + if (!session) { return QMap(); } - auto & sessionRef = *session.get(); + auto& sessionRef = *session.get(); QMap filter; - auto addToFilter = [&filter](QString key, QString value) - { - if(key.trimmed().size()) - { + auto addToFilter = [&filter](QString key, QString value) { + if (key.trimmed().size()) { filter[key] = value; } }; - if (sessionRef.session != "-") - { + if (sessionRef.session != "-") { addToFilter(sessionRef.session, tr("")); } if (sessionRef.access_token != "0") { addToFilter(sessionRef.access_token, tr("")); } - if(sessionRef.client_token.size()) { + if (sessionRef.client_token.size()) { addToFilter(sessionRef.client_token, tr("")); } addToFilter(sessionRef.uuid, tr("")); @@ -849,31 +792,28 @@ QMap MinecraftInstance::createCensorFilterFromSession(AuthSess return filter; } -MessageLevel::Enum MinecraftInstance::guessLevel(const QString &line, MessageLevel::Enum level) +MessageLevel::Enum MinecraftInstance::guessLevel(const QString& line, MessageLevel::Enum level) { QRegularExpression re("\\[(?[0-9:]+)\\] \\[[^/]+/(?[^\\]]+)\\]"); auto match = re.match(line); - if(match.hasMatch()) - { + if (match.hasMatch()) { // New style logs from log4j QString timestamp = match.captured("timestamp"); QString levelStr = match.captured("level"); - if(levelStr == "INFO") + if (levelStr == "INFO") level = MessageLevel::Message; - if(levelStr == "WARN") + if (levelStr == "WARN") level = MessageLevel::Warning; - if(levelStr == "ERROR") + if (levelStr == "ERROR") level = MessageLevel::Error; - if(levelStr == "FATAL") + if (levelStr == "FATAL") level = MessageLevel::Fatal; - if(levelStr == "TRACE" || levelStr == "DEBUG") + if (levelStr == "TRACE" || levelStr == "DEBUG") level = MessageLevel::Debug; - } - else - { + } else { // Old style forge logs - if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || - line.contains("[FINER]") || line.contains("[FINEST]")) + if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") || + line.contains("[FINEST]")) level = MessageLevel::Message; if (line.contains("[SEVERE]") || line.contains("[STDERR]")) level = MessageLevel::Error; @@ -884,14 +824,12 @@ MessageLevel::Enum MinecraftInstance::guessLevel(const QString &line, MessageLev } if (line.contains("overwriting existing")) return MessageLevel::Fatal; - //NOTE: this diverges from the real regexp. no unicode, the first section is + instead of * + // NOTE: this diverges from the real regexp. no unicode, the first section is + instead of * static const QString javaSymbol = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*"; - if (line.contains("Exception in thread") - || line.contains(QRegularExpression("\\s+at " + javaSymbol)) - || line.contains(QRegularExpression("Caused by: " + javaSymbol)) - || line.contains(QRegularExpression("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)")) - || line.contains(QRegularExpression("... \\d+ more$")) - ) + if (line.contains("Exception in thread") || line.contains(QRegularExpression("\\s+at " + javaSymbol)) || + line.contains(QRegularExpression("Caused by: " + javaSymbol)) || + line.contains(QRegularExpression("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)")) || + line.contains(QRegularExpression("... \\d+ more$"))) return MessageLevel::Error; return level; } @@ -914,14 +852,12 @@ QString MinecraftInstance::getLogFileRoot() QString MinecraftInstance::getStatusbarDescription() { QStringList traits; - if (hasVersionBroken()) - { + if (hasVersionBroken()) { traits.append(tr("broken")); } QString mcVersion = m_components->getComponentVersion("net.minecraft"); - if (mcVersion.isEmpty()) - { + if (mcVersion.isEmpty()) { // Load component info if needed m_components->reload(Net::Mode::Offline); mcVersion = m_components->getComponentVersion("net.minecraft"); @@ -929,8 +865,7 @@ QString MinecraftInstance::getStatusbarDescription() QString description; description.append(tr("Minecraft %1").arg(mcVersion)); - if(m_settings->get("ShowGameTime").toBool()) - { + if (m_settings->get("ShowGameTime").toBool()) { if (lastTimePlayed() > 0) { QDateTime lastLaunchTime = QDateTime::fromMSecsSinceEpoch(lastLaunch()); description.append(tr(", last played on %1 for %2") @@ -942,8 +877,7 @@ QString MinecraftInstance::getStatusbarDescription() description.append(tr(", total played for %1").arg(Time::prettifyDuration(totalTimePlayed()))); } } - if(hasCrashed()) - { + if (hasCrashed()) { description.append(tr(", has crashed.")); } return description; @@ -952,14 +886,11 @@ QString MinecraftInstance::getStatusbarDescription() Task::Ptr MinecraftInstance::createUpdateTask(Net::Mode mode) { updateRuntimeContext(); - switch (mode) - { - case Net::Mode::Offline: - { + switch (mode) { + case Net::Mode::Offline: { return Task::Ptr(new MinecraftLoadAndCheck(this)); } - case Net::Mode::Online: - { + case Net::Mode::Online: { return Task::Ptr(new MinecraftUpdate(this)); } } @@ -990,14 +921,12 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt process->appendStep(makeShared(pptr)); } - if (!serverToJoin && settings()->get("JoinServerOnLaunch").toBool()) - { + if (!serverToJoin && settings()->get("JoinServerOnLaunch").toBool()) { QString fullAddress = settings()->get("JoinServerOnLaunchAddress").toString(); serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(fullAddress))); } - if(serverToJoin && serverToJoin->port == 25565) - { + if (serverToJoin && serverToJoin->port == 25565) { // Resolve server address to join on launch auto step = makeShared(pptr); step->setLookupAddress(serverToJoin->address); @@ -1006,23 +935,19 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt } // run pre-launch command if that's needed - if(getPreLaunchCommand().size()) - { + if (getPreLaunchCommand().size()) { auto step = makeShared(pptr); step->setWorkingDirectory(gameRoot()); process->appendStep(step); } // if we aren't in offline mode,. - if(session->status != AuthSession::PlayableOffline) - { - if(!session->demo) { + if (session->status != AuthSession::PlayableOffline) { + if (!session->demo) { process->appendStep(makeShared(pptr, session)); } process->appendStep(makeShared(pptr, Net::Mode::Online)); - } - else - { + } else { process->appendStep(makeShared(pptr, Net::Mode::Offline)); } @@ -1066,18 +991,15 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt } // run post-exit command if that's needed - if(getPostExitCommand().size()) - { + if (getPostExitCommand().size()) { auto step = makeShared(pptr); step->setWorkingDirectory(gameRoot()); process->appendStep(step); } - if (session) - { + if (session) { process->setCensorFilter(createCensorFilterFromSession(session)); } - if(m_settings->get("QuitAfterGameStop").toBool()) - { + if (m_settings->get("QuitAfterGameStop").toBool()) { process->appendStep(makeShared(pptr)); } m_launchProcess = process; @@ -1119,8 +1041,7 @@ std::shared_ptr MinecraftInstance::nilModList() std::shared_ptr MinecraftInstance::resourcePackList() { - if (!m_resource_pack_list) - { + if (!m_resource_pack_list) { m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir(), this)); } return m_resource_pack_list; @@ -1128,8 +1049,7 @@ std::shared_ptr MinecraftInstance::resourcePackList() std::shared_ptr MinecraftInstance::texturePackList() { - if (!m_texture_pack_list) - { + if (!m_texture_pack_list) { m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir(), this)); } return m_texture_pack_list; @@ -1137,8 +1057,7 @@ std::shared_ptr MinecraftInstance::texturePackList() std::shared_ptr MinecraftInstance::shaderPackList() { - if (!m_shader_pack_list) - { + if (!m_shader_pack_list) { m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir(), this)); } return m_shader_pack_list; @@ -1146,8 +1065,7 @@ std::shared_ptr MinecraftInstance::shaderPackList() std::shared_ptr MinecraftInstance::worldList() { - if (!m_world_list) - { + if (!m_world_list) { m_world_list.reset(new WorldList(worldDir(), this)); } return m_world_list; @@ -1155,8 +1073,7 @@ std::shared_ptr MinecraftInstance::worldList() std::shared_ptr MinecraftInstance::gameOptionsModel() { - if (!m_game_options) - { + if (!m_game_options) { m_game_options.reset(new GameOptions(FS::PathCombine(gameRoot(), "options.txt"))); } return m_game_options; @@ -1166,8 +1083,7 @@ QList MinecraftInstance::getJarMods() const { auto profile = m_components->getProfile(); QList mods; - for (auto jarmod : profile->getJarMods()) - { + for (auto jarmod : profile->getJarMods()) { QStringList jar, temp1, temp2, temp3; jarmod->getApplicableFiles(runtimeContext(), jar, temp1, temp2, temp3, jarmodsPath().absolutePath()); // QString filePath = jarmodsPath().absoluteFilePath(jarmod->filename(currentSystem)); @@ -1176,5 +1092,4 @@ QList MinecraftInstance::getJarMods() const return mods; } - #include "MinecraftInstance.moc" diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 4afcf04b8..c331cc6f5 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -35,12 +35,12 @@ */ #pragma once -#include "BaseInstance.h" #include -#include "minecraft/mod/Mod.h" -#include #include +#include +#include "BaseInstance.h" #include "minecraft/launch/MinecraftServerTarget.h" +#include "minecraft/mod/Mod.h" class ModFolderModel; class ResourceFolderModel; @@ -52,12 +52,11 @@ class GameOptions; class LaunchStep; class PackProfile; -class MinecraftInstance: public BaseInstance -{ +class MinecraftInstance : public BaseInstance { Q_OBJECT -public: - MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir); - virtual ~MinecraftInstance() {}; + public: + MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir); + virtual ~MinecraftInstance(){}; virtual void saveNow() override; void loadSpecificSettings() override; @@ -67,15 +66,9 @@ public: // FIXME: remove QSet traits() const override; - bool canEdit() const override - { - return true; - } + bool canEdit() const override { return true; } - bool canExport() const override - { - return true; - } + bool canExport() const override { return true; } ////// Directories and files ////// QString jarModsDir() const; @@ -143,7 +136,7 @@ public: QProcessEnvironment createLaunchEnvironment() override; /// guess log level from a line of minecraft log - MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level) override; + MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level) override; IPathMatcher::Ptr getLogFileMatcher() override; @@ -163,10 +156,10 @@ public: virtual JavaVersion getJavaVersion(); -protected: + protected: QMap createCensorFilterFromSession(AuthSessionPtr session); -protected: // data + protected: // data std::shared_ptr m_components; mutable std::shared_ptr m_loader_mod_list; mutable std::shared_ptr m_core_mod_list; diff --git a/launcher/minecraft/MinecraftLoadAndCheck.cpp b/launcher/minecraft/MinecraftLoadAndCheck.cpp index 2a3698798..818e90cfc 100644 --- a/launcher/minecraft/MinecraftLoadAndCheck.cpp +++ b/launcher/minecraft/MinecraftLoadAndCheck.cpp @@ -2,9 +2,7 @@ #include "MinecraftInstance.h" #include "PackProfile.h" -MinecraftLoadAndCheck::MinecraftLoadAndCheck(MinecraftInstance *inst, QObject *parent) : Task(parent), m_inst(inst) -{ -} +MinecraftLoadAndCheck::MinecraftLoadAndCheck(MinecraftInstance* inst, QObject* parent) : Task(parent), m_inst(inst) {} void MinecraftLoadAndCheck::executeTask() { @@ -13,14 +11,13 @@ void MinecraftLoadAndCheck::executeTask() components->reload(Net::Mode::Offline); m_task = components->getCurrentTask(); - if(!m_task) - { + if (!m_task) { emitSucceeded(); return; } connect(m_task.get(), &Task::succeeded, this, &MinecraftLoadAndCheck::subtaskSucceeded); connect(m_task.get(), &Task::failed, this, &MinecraftLoadAndCheck::subtaskFailed); - connect(m_task.get(), &Task::aborted, this, [this]{ subtaskFailed(tr("Aborted")); }); + connect(m_task.get(), &Task::aborted, this, [this] { subtaskFailed(tr("Aborted")); }); connect(m_task.get(), &Task::progress, this, &MinecraftLoadAndCheck::progress); connect(m_task.get(), &Task::stepProgress, this, &MinecraftLoadAndCheck::propagateStepProgress); connect(m_task.get(), &Task::status, this, &MinecraftLoadAndCheck::setStatus); @@ -28,8 +25,7 @@ void MinecraftLoadAndCheck::executeTask() void MinecraftLoadAndCheck::subtaskSucceeded() { - if(isFinished()) - { + if (isFinished()) { qCritical() << "MinecraftUpdate: Subtask" << sender() << "succeeded, but work was already done!"; return; } @@ -38,8 +34,7 @@ void MinecraftLoadAndCheck::subtaskSucceeded() void MinecraftLoadAndCheck::subtaskFailed(QString error) { - if(isFinished()) - { + if (isFinished()) { qCritical() << "MinecraftUpdate: Subtask" << sender() << "failed, but work was already done!"; return; } diff --git a/launcher/minecraft/MinecraftLoadAndCheck.h b/launcher/minecraft/MinecraftLoadAndCheck.h index d9af3ace2..9556c1d6a 100644 --- a/launcher/minecraft/MinecraftLoadAndCheck.h +++ b/launcher/minecraft/MinecraftLoadAndCheck.h @@ -15,34 +15,32 @@ #pragma once -#include #include +#include #include -#include "tasks/Task.h" #include +#include "tasks/Task.h" #include "QObjectPtr.h" class MinecraftVersion; class MinecraftInstance; -class MinecraftLoadAndCheck : public Task -{ +class MinecraftLoadAndCheck : public Task { Q_OBJECT -public: - explicit MinecraftLoadAndCheck(MinecraftInstance *inst, QObject *parent = 0); - virtual ~MinecraftLoadAndCheck() {}; + public: + explicit MinecraftLoadAndCheck(MinecraftInstance* inst, QObject* parent = 0); + virtual ~MinecraftLoadAndCheck(){}; void executeTask() override; -private slots: + private slots: void subtaskSucceeded(); void subtaskFailed(QString error); -private: - MinecraftInstance *m_inst = nullptr; + private: + MinecraftInstance* m_inst = nullptr; Task::Ptr m_task; QString m_preFailure; QString m_fail_reason; }; - diff --git a/launcher/minecraft/MinecraftUpdate.cpp b/launcher/minecraft/MinecraftUpdate.cpp index 236d0224b..c009317a6 100644 --- a/launcher/minecraft/MinecraftUpdate.cpp +++ b/launcher/minecraft/MinecraftUpdate.cpp @@ -16,27 +16,25 @@ #include "MinecraftUpdate.h" #include "MinecraftInstance.h" +#include #include #include #include -#include -#include "BaseInstance.h" -#include "minecraft/PackProfile.h" -#include "minecraft/Library.h" #include +#include "BaseInstance.h" +#include "minecraft/Library.h" +#include "minecraft/PackProfile.h" +#include "update/AssetUpdateTask.h" +#include "update/FMLLibrariesTask.h" #include "update/FoldersTask.h" #include "update/LibrariesTask.h" -#include "update/FMLLibrariesTask.h" -#include "update/AssetUpdateTask.h" #include #include -MinecraftUpdate::MinecraftUpdate(MinecraftInstance *inst, QObject *parent) : Task(parent), m_inst(inst) -{ -} +MinecraftUpdate::MinecraftUpdate(MinecraftInstance* inst, QObject* parent) : Task(parent), m_inst(inst) {} void MinecraftUpdate::executeTask() { @@ -51,8 +49,7 @@ void MinecraftUpdate::executeTask() auto components = m_inst->getPackProfile(); components->reload(Net::Mode::Online); auto task = components->getCurrentTask(); - if(task) - { + if (task) { m_tasks.append(task); } } @@ -72,8 +69,7 @@ void MinecraftUpdate::executeTask() m_tasks.append(makeShared(m_inst)); } - if(!m_preFailure.isEmpty()) - { + if (!m_preFailure.isEmpty()) { emitFailed(m_preFailure); return; } @@ -82,19 +78,16 @@ void MinecraftUpdate::executeTask() void MinecraftUpdate::next() { - if(m_abort) - { + if (m_abort) { emitFailed(tr("Aborted by user.")); return; } - if(m_failed_out_of_order) - { + if (m_failed_out_of_order) { emitFailed(m_fail_reason); return; } - m_currentTask ++; - if(m_currentTask > 0) - { + m_currentTask++; + if (m_currentTask > 0) { auto task = m_tasks[m_currentTask - 1]; disconnect(task.get(), &Task::succeeded, this, &MinecraftUpdate::subtaskSucceeded); disconnect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed); @@ -104,15 +97,13 @@ void MinecraftUpdate::next() disconnect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus); disconnect(task.get(), &Task::details, this, &MinecraftUpdate::setDetails); } - if(m_currentTask == m_tasks.size()) - { + if (m_currentTask == m_tasks.size()) { emitSucceeded(); return; } auto task = m_tasks[m_currentTask]; // if the task is already finished by the time we look at it, skip it - if(task->isFinished()) - { + if (task->isFinished()) { qCritical() << "MinecraftUpdate: Skipping finished subtask" << m_currentTask << ":" << task.get(); next(); } @@ -124,23 +115,20 @@ void MinecraftUpdate::next() connect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus); connect(task.get(), &Task::details, this, &MinecraftUpdate::setDetails); // if the task is already running, do not start it again - if(!task->isRunning()) - { + if (!task->isRunning()) { task->start(); } } void MinecraftUpdate::subtaskSucceeded() { - if(isFinished()) - { + if (isFinished()) { qCritical() << "MinecraftUpdate: Subtask" << sender() << "succeeded, but work was already done!"; return; } auto senderTask = QObject::sender(); auto currentTask = m_tasks[m_currentTask].get(); - if(senderTask != currentTask) - { + if (senderTask != currentTask) { qDebug() << "MinecraftUpdate: Subtask" << sender() << "succeeded out of order."; return; } @@ -149,15 +137,13 @@ void MinecraftUpdate::subtaskSucceeded() void MinecraftUpdate::subtaskFailed(QString error) { - if(isFinished()) - { + if (isFinished()) { qCritical() << "MinecraftUpdate: Subtask" << sender() << "failed, but work was already done!"; return; } auto senderTask = QObject::sender(); auto currentTask = m_tasks[m_currentTask].get(); - if(senderTask != currentTask) - { + if (senderTask != currentTask) { qDebug() << "MinecraftUpdate: Subtask" << sender() << "failed out of order."; m_failed_out_of_order = true; m_fail_reason = error; @@ -166,15 +152,12 @@ void MinecraftUpdate::subtaskFailed(QString error) emitFailed(error); } - bool MinecraftUpdate::abort() { - if(!m_abort) - { + if (!m_abort) { m_abort = true; auto task = m_tasks[m_currentTask]; - if(task->canAbort()) - { + if (task->canAbort()) { return task->abort(); } } diff --git a/launcher/minecraft/MinecraftUpdate.h b/launcher/minecraft/MinecraftUpdate.h index c9cf8624b..9c41d7f56 100644 --- a/launcher/minecraft/MinecraftUpdate.h +++ b/launcher/minecraft/MinecraftUpdate.h @@ -15,41 +15,39 @@ #pragma once -#include #include +#include #include +#include +#include "minecraft/VersionFilterData.h" #include "net/NetJob.h" #include "tasks/Task.h" -#include "minecraft/VersionFilterData.h" -#include class MinecraftVersion; class MinecraftInstance; // FIXME: This looks very similar to a SequentialTask. Maybe we can reduce code duplications? :^) -class MinecraftUpdate : public Task -{ +class MinecraftUpdate : public Task { Q_OBJECT -public: - explicit MinecraftUpdate(MinecraftInstance *inst, QObject *parent = 0); - virtual ~MinecraftUpdate() {}; + public: + explicit MinecraftUpdate(MinecraftInstance* inst, QObject* parent = 0); + virtual ~MinecraftUpdate(){}; void executeTask() override; bool canAbort() const override; -private -slots: + private slots: bool abort() override; void subtaskSucceeded(); void subtaskFailed(QString error); -private: + private: void next(); -private: - MinecraftInstance *m_inst = nullptr; + private: + MinecraftInstance* m_inst = nullptr; QList m_tasks; QString m_preFailure; int m_currentTask = -1; diff --git a/launcher/minecraft/MojangDownloadInfo.h b/launcher/minecraft/MojangDownloadInfo.h index 13e27e15e..b98a0168d 100644 --- a/launcher/minecraft/MojangDownloadInfo.h +++ b/launcher/minecraft/MojangDownloadInfo.h @@ -1,10 +1,9 @@ #pragma once -#include #include +#include #include -struct MojangDownloadInfo -{ +struct MojangDownloadInfo { // types typedef std::shared_ptr Ptr; @@ -19,24 +18,20 @@ struct MojangDownloadInfo int size; }; - - -struct MojangLibraryDownloadInfo -{ - MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact): artifact(artifact) {}; - MojangLibraryDownloadInfo() {}; +struct MojangLibraryDownloadInfo { + MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact) : artifact(artifact){}; + MojangLibraryDownloadInfo(){}; // types typedef std::shared_ptr Ptr; // methods - MojangDownloadInfo *getDownloadInfo(QString classifier) + MojangDownloadInfo* getDownloadInfo(QString classifier) { - if (classifier.isNull()) - { + if (classifier.isNull()) { return artifact.get(); } - + return classifiers[classifier].get(); } @@ -45,17 +40,12 @@ struct MojangLibraryDownloadInfo QMap classifiers; }; - - -struct MojangAssetIndexInfo : public MojangDownloadInfo -{ +struct MojangAssetIndexInfo : public MojangDownloadInfo { // types typedef std::shared_ptr Ptr; // methods - MojangAssetIndexInfo() - { - } + MojangAssetIndexInfo() {} MojangAssetIndexInfo(QString id) { @@ -63,13 +53,11 @@ struct MojangAssetIndexInfo : public MojangDownloadInfo // HACK: ignore assets from other version files than Minecraft // workaround for stupid assets issue caused by amazon: // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/ - if(id == "legacy") - { + if (id == "legacy") { url = "https://piston-meta.mojang.com/mc/assets/legacy/c0fd82e8ce9fbc93119e40d96d5a4e62cfa3f729/legacy.json"; } // HACK - else - { + else { url = "https://s3.amazonaws.com/Minecraft.Download/indexes/" + id + ".json"; } known = false; diff --git a/launcher/minecraft/MojangVersionFormat.cpp b/launcher/minecraft/MojangVersionFormat.cpp index 623dcdfa6..d7393cf4a 100644 --- a/launcher/minecraft/MojangVersionFormat.cpp +++ b/launcher/minecraft/MojangVersionFormat.cpp @@ -34,34 +34,32 @@ */ #include "MojangVersionFormat.h" -#include "OneSixVersionFormat.h" #include "MojangDownloadInfo.h" +#include "OneSixVersionFormat.h" #include "Json.h" using namespace Json; -#include "ParseUtils.h" #include +#include "ParseUtils.h" static const int CURRENT_MINIMUM_LAUNCHER_VERSION = 18; -static MojangAssetIndexInfo::Ptr assetIndexFromJson (const QJsonObject &obj); -static MojangDownloadInfo::Ptr downloadInfoFromJson (const QJsonObject &obj); -static MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson (const QJsonObject &libObj); -static QJsonObject assetIndexToJson (MojangAssetIndexInfo::Ptr assetidxinfo); -static QJsonObject libDownloadInfoToJson (MojangLibraryDownloadInfo::Ptr libinfo); -static QJsonObject downloadInfoToJson (MojangDownloadInfo::Ptr info); +static MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject& obj); +static MojangDownloadInfo::Ptr downloadInfoFromJson(const QJsonObject& obj); +static MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject& libObj); +static QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr assetidxinfo); +static QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo); +static QJsonObject downloadInfoToJson(MojangDownloadInfo::Ptr info); -namespace Bits +namespace Bits { +static void readString(const QJsonObject& root, const QString& key, QString& variable) { -static void readString(const QJsonObject &root, const QString &key, QString &variable) -{ - if (root.contains(key)) - { + if (root.contains(key)) { variable = requireString(root.value(key)); } } -static void readDownloadInfo(MojangDownloadInfo::Ptr out, const QJsonObject &obj) +static void readDownloadInfo(MojangDownloadInfo::Ptr out, const QJsonObject& obj) { // optional, not used readString(obj, "path", out->path); @@ -71,22 +69,22 @@ static void readDownloadInfo(MojangDownloadInfo::Ptr out, const QJsonObject &obj out->size = requireInteger(obj, "size"); } -static void readAssetIndex(MojangAssetIndexInfo::Ptr out, const QJsonObject &obj) +static void readAssetIndex(MojangAssetIndexInfo::Ptr out, const QJsonObject& obj) { out->totalSize = requireInteger(obj, "totalSize"); out->id = requireString(obj, "id"); // out->known = true; } -} +} // namespace Bits -MojangDownloadInfo::Ptr downloadInfoFromJson(const QJsonObject &obj) +MojangDownloadInfo::Ptr downloadInfoFromJson(const QJsonObject& obj) { auto out = std::make_shared(); Bits::readDownloadInfo(out, obj); return out; } -MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject &obj) +MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject& obj) { auto out = std::make_shared(); Bits::readDownloadInfo(out, obj); @@ -97,8 +95,7 @@ MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject &obj) QJsonObject downloadInfoToJson(MojangDownloadInfo::Ptr info) { QJsonObject out; - if(!info->path.isNull()) - { + if (!info->path.isNull()) { out.insert("path", info->path); } out.insert("sha1", info->sha1); @@ -107,19 +104,16 @@ QJsonObject downloadInfoToJson(MojangDownloadInfo::Ptr info) return out; } -MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject &libObj) +MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject& libObj) { auto out = std::make_shared(); auto dlObj = requireObject(libObj.value("downloads")); - if(dlObj.contains("artifact")) - { + if (dlObj.contains("artifact")) { out->artifact = downloadInfoFromJson(requireObject(dlObj, "artifact")); } - if(dlObj.contains("classifiers")) - { + if (dlObj.contains("classifiers")) { auto classifiersObj = requireObject(dlObj, "classifiers"); - for(auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++) - { + for (auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++) { auto classifier = iter.key(); auto classifierObj = requireObject(iter.value()); out->classifiers[classifier] = downloadInfoFromJson(classifierObj); @@ -131,15 +125,12 @@ MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject &libObj QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo) { QJsonObject out; - if(libinfo->artifact) - { + if (libinfo->artifact) { out.insert("artifact", downloadInfoToJson(libinfo->artifact)); } - if(!libinfo->classifiers.isEmpty()) - { + if (!libinfo->classifiers.isEmpty()) { QJsonObject classifiersOut; - for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++) - { + for (auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++) { classifiersOut.insert(iter.key(), downloadInfoToJson(iter.value())); } out.insert("classifiers", classifiersOut); @@ -150,8 +141,7 @@ QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo) QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr info) { QJsonObject out; - if(!info->path.isNull()) - { + if (!info->path.isNull()) { out.insert("path", info->path); } out.insert("sha1", info->sha1); @@ -162,76 +152,57 @@ QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr info) return out; } -void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFile *out) +void MojangVersionFormat::readVersionProperties(const QJsonObject& in, VersionFile* out) { Bits::readString(in, "id", out->minecraftVersion); Bits::readString(in, "mainClass", out->mainClass); Bits::readString(in, "minecraftArguments", out->minecraftArguments); - if(out->minecraftArguments.isEmpty()) - { + if (out->minecraftArguments.isEmpty()) { QString processArguments; Bits::readString(in, "processArguments", processArguments); QString toCompare = processArguments.toLower(); - if (toCompare == "legacy") - { + if (toCompare == "legacy") { out->minecraftArguments = " ${auth_player_name} ${auth_session}"; - } - else if (toCompare == "username_session") - { + } else if (toCompare == "username_session") { out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}"; - } - else if (toCompare == "username_session_version") - { + } else if (toCompare == "username_session_version") { out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}"; - } - else if (!toCompare.isEmpty()) - { + } else if (!toCompare.isEmpty()) { out->addProblem(ProblemSeverity::Error, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments)); } } Bits::readString(in, "type", out->type); Bits::readString(in, "assets", out->assets); - if(in.contains("assetIndex")) - { + if (in.contains("assetIndex")) { out->mojangAssetIndex = assetIndexFromJson(requireObject(in, "assetIndex")); - } - else if (!out->assets.isNull()) - { + } else if (!out->assets.isNull()) { out->mojangAssetIndex = std::make_shared(out->assets); } out->releaseTime = timeFromS3Time(in.value("releaseTime").toString("")); out->updateTime = timeFromS3Time(in.value("time").toString("")); - if (in.contains("minimumLauncherVersion")) - { + if (in.contains("minimumLauncherVersion")) { out->minimumLauncherVersion = requireInteger(in.value("minimumLauncherVersion")); - if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION) - { - out->addProblem( - ProblemSeverity::Warning, - QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by %3 (%2). It might not work properly!") - .arg(out->minimumLauncherVersion) - .arg(CURRENT_MINIMUM_LAUNCHER_VERSION) - .arg(BuildConfig.LAUNCHER_DISPLAYNAME) - ); + if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION) { + out->addProblem(ProblemSeverity::Warning, QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than " + "supported by %3 (%2). It might not work properly!") + .arg(out->minimumLauncherVersion) + .arg(CURRENT_MINIMUM_LAUNCHER_VERSION) + .arg(BuildConfig.LAUNCHER_DISPLAYNAME)); } } - if (in.contains("compatibleJavaMajors")) - { - for (auto compatible : requireArray(in.value("compatibleJavaMajors"))) - { + if (in.contains("compatibleJavaMajors")) { + for (auto compatible : requireArray(in.value("compatibleJavaMajors"))) { out->compatibleJavaMajors.append(requireInteger(compatible)); } } - if(in.contains("downloads")) - { + if (in.contains("downloads")) { auto downloadsObj = requireObject(in, "downloads"); - for(auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++) - { + for (auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++) { auto classifier = iter.key(); auto classifierObj = requireObject(iter.value()); out->mojangDownloads[classifier] = downloadInfoFromJson(classifierObj); @@ -239,15 +210,13 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi } } -VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename) +VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument& doc, const QString& filename) { VersionFilePtr out(new VersionFile()); - if (doc.isEmpty() || doc.isNull()) - { + if (doc.isEmpty() || doc.isNull()) { throw JSONValidationError(filename + " is empty or null"); } - if (!doc.isObject()) - { + if (!doc.isObject()) { throw JSONValidationError(filename + " is not an object"); } @@ -260,11 +229,8 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc out->version = out->minecraftVersion; // out->filename = filename; - - if (root.contains("libraries")) - { - for (auto libVal : requireArray(root.value("libraries"))) - { + if (root.contains("libraries")) { + for (auto libVal : requireArray(root.value("libraries"))) { auto libObj = requireObject(libVal); auto lib = MojangVersionFormat::libraryFromJson(*out, libObj, filename); @@ -280,52 +246,42 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj writeString(out, "mainClass", in->mainClass); writeString(out, "minecraftArguments", in->minecraftArguments); writeString(out, "type", in->type); - if(!in->releaseTime.isNull()) - { + if (!in->releaseTime.isNull()) { writeString(out, "releaseTime", timeToS3Time(in->releaseTime)); } - if(!in->updateTime.isNull()) - { + if (!in->updateTime.isNull()) { writeString(out, "time", timeToS3Time(in->updateTime)); } - if(in->minimumLauncherVersion != -1) - { + if (in->minimumLauncherVersion != -1) { out.insert("minimumLauncherVersion", in->minimumLauncherVersion); } writeString(out, "assets", in->assets); - if(in->mojangAssetIndex && in->mojangAssetIndex->known) - { + if (in->mojangAssetIndex && in->mojangAssetIndex->known) { out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex)); } - if(!in->mojangDownloads.isEmpty()) - { + if (!in->mojangDownloads.isEmpty()) { QJsonObject downloadsOut; - for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++) - { + for (auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++) { downloadsOut.insert(iter.key(), downloadInfoToJson(iter.value())); } out.insert("downloads", downloadsOut); } - if(!in->compatibleJavaMajors.isEmpty()) - { + if (!in->compatibleJavaMajors.isEmpty()) { QJsonArray compatibleJavaMajorsOut; - for(auto compatibleJavaMajor : in->compatibleJavaMajors) - { + for (auto compatibleJavaMajor : in->compatibleJavaMajors) { compatibleJavaMajorsOut.append(compatibleJavaMajor); } out.insert("compatibleJavaMajors", compatibleJavaMajorsOut); } } -QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch) +QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr& patch) { QJsonObject root; writeVersionProperties(patch.get(), root); - if (!patch->libraries.isEmpty()) - { + if (!patch->libraries.isEmpty()) { QJsonArray array; - for (auto value: patch->libraries) - { + for (auto value : patch->libraries) { array.append(MojangVersionFormat::libraryToJson(value.get())); } root.insert("libraries", array); @@ -339,96 +295,80 @@ QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch } } -LibraryPtr MojangVersionFormat::libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename) +LibraryPtr MojangVersionFormat::libraryFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename) { LibraryPtr out(new Library()); - if (!libObj.contains("name")) - { + if (!libObj.contains("name")) { throw JSONValidationError(filename + "contains a library that doesn't have a 'name' field"); } auto rawName = libObj.value("name").toString(); out->m_name = rawName; - if(!out->m_name.valid()) { + if (!out->m_name.valid()) { problems.addProblem(ProblemSeverity::Error, QObject::tr("Library %1 name is broken and cannot be processed.").arg(rawName)); } Bits::readString(libObj, "url", out->m_repositoryURL); - if (libObj.contains("extract")) - { + if (libObj.contains("extract")) { out->m_hasExcludes = true; auto extractObj = requireObject(libObj.value("extract")); - for (auto excludeVal : requireArray(extractObj.value("exclude"))) - { + for (auto excludeVal : requireArray(extractObj.value("exclude"))) { out->m_extractExcludes.append(requireString(excludeVal)); } } - if (libObj.contains("natives")) - { + if (libObj.contains("natives")) { QJsonObject nativesObj = requireObject(libObj.value("natives")); - for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) - { - if (!it.value().isString()) - { + for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) { + if (!it.value().isString()) { qWarning() << filename << "contains an invalid native (skipping)"; } // FIXME: Skip unknown platforms out->m_nativeClassifiers[it.key()] = it.value().toString(); } } - if (libObj.contains("rules")) - { + if (libObj.contains("rules")) { out->applyRules = true; out->m_rules = rulesFromJsonV4(libObj); } - if (libObj.contains("downloads")) - { + if (libObj.contains("downloads")) { out->m_mojangDownloads = libDownloadInfoFromJson(libObj); } return out; } -QJsonObject MojangVersionFormat::libraryToJson(Library *library) +QJsonObject MojangVersionFormat::libraryToJson(Library* library) { QJsonObject libRoot; libRoot.insert("name", library->m_name.serialize()); - if (!library->m_repositoryURL.isEmpty()) - { + if (!library->m_repositoryURL.isEmpty()) { libRoot.insert("url", library->m_repositoryURL); } - if (library->isNative()) - { + if (library->isNative()) { QJsonObject nativeList; auto iter = library->m_nativeClassifiers.begin(); - while (iter != library->m_nativeClassifiers.end()) - { + while (iter != library->m_nativeClassifiers.end()) { nativeList.insert(iter.key(), iter.value()); iter++; } libRoot.insert("natives", nativeList); - if (!library->m_extractExcludes.isEmpty()) - { + if (!library->m_extractExcludes.isEmpty()) { QJsonArray excludes; QJsonObject extract; - for (auto exclude : library->m_extractExcludes) - { + for (auto exclude : library->m_extractExcludes) { excludes.append(exclude); } extract.insert("exclude", excludes); libRoot.insert("extract", extract); } } - if (!library->m_rules.isEmpty()) - { + if (!library->m_rules.isEmpty()) { QJsonArray allRules; - for (auto &rule : library->m_rules) - { + for (auto& rule : library->m_rules) { QJsonObject ruleObj = rule->toJson(); allRules.append(ruleObj); } libRoot.insert("rules", allRules); } - if(library->m_mojangDownloads) - { + if (library->m_mojangDownloads) { auto downloadsObj = libDownloadInfoToJson(library->m_mojangDownloads); libRoot.insert("downloads", downloadsObj); } diff --git a/launcher/minecraft/MojangVersionFormat.h b/launcher/minecraft/MojangVersionFormat.h index d38f0a2ff..88d8a206d 100644 --- a/launcher/minecraft/MojangVersionFormat.h +++ b/launcher/minecraft/MojangVersionFormat.h @@ -1,24 +1,25 @@ #pragma once -#include -#include -#include #include +#include +#include +#include -class MojangVersionFormat -{ -friend class OneSixVersionFormat; -protected: +class MojangVersionFormat { + friend class OneSixVersionFormat; + + protected: // does not include libraries static void readVersionProperties(const QJsonObject& in, VersionFile* out); // does not include libraries static void writeVersionProperties(const VersionFile* in, QJsonObject& out); -public: + + public: // version files / profile patches - static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename); - static QJsonDocument versionFileToJson(const VersionFilePtr &patch); + static VersionFilePtr versionFileFromJson(const QJsonDocument& doc, const QString& filename); + static QJsonDocument versionFileToJson(const VersionFilePtr& patch); // libraries - static LibraryPtr libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); - static QJsonObject libraryToJson(Library *library); + static LibraryPtr libraryFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename); + static QJsonObject libraryToJson(Library* library); }; diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index b586198bf..22c2c997c 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -35,23 +35,22 @@ #include "OneSixVersionFormat.h" #include +#include #include "minecraft/Agent.h" #include "minecraft/ParseUtils.h" -#include #include using namespace Json; -static void readString(const QJsonObject &root, const QString &key, QString &variable) +static void readString(const QJsonObject& root, const QString& key, QString& variable) { - if (root.contains(key)) - { + if (root.contains(key)) { variable = requireString(root.value(key)); } } -LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename) +LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename) { LibraryPtr out = MojangVersionFormat::libraryFromJson(problems, libObj, filename); readString(libObj, "MMC-hint", out->m_hint); @@ -62,7 +61,7 @@ LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer & problems, con return out; } -QJsonObject OneSixVersionFormat::libraryToJson(Library *library) +QJsonObject OneSixVersionFormat::libraryToJson(Library* library) { QJsonObject libRoot = MojangVersionFormat::libraryToJson(library); if (!library->m_absoluteURL.isEmpty()) @@ -76,37 +75,30 @@ QJsonObject OneSixVersionFormat::libraryToJson(Library *library) return libRoot; } -VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder) +VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument& doc, const QString& filename, const bool requireOrder) { VersionFilePtr out(new VersionFile()); - if (doc.isEmpty() || doc.isNull()) - { + if (doc.isEmpty() || doc.isNull()) { throw JSONValidationError(filename + " is empty or null"); } - if (!doc.isObject()) - { + if (!doc.isObject()) { throw JSONValidationError(filename + " is not an object"); } QJsonObject root = doc.object(); Meta::MetadataVersion formatVersion = Meta::parseFormatVersion(root, false); - switch(formatVersion) - { + switch (formatVersion) { case Meta::MetadataVersion::InitialRelease: break; case Meta::MetadataVersion::Invalid: throw JSONValidationError(filename + " does not contain a recognizable version of the metadata format."); } - if (requireOrder) - { - if (root.contains("order")) - { + if (requireOrder) { + if (root.contains("order")) { out->order = requireInteger(root.value("order")); - } - else - { + } else { // FIXME: evaluate if we don't want to throw exceptions here instead qCritical() << filename << "doesn't contain an order field"; } @@ -114,22 +106,18 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc out->name = root.value("name").toString(); - if(root.contains("uid")) - { + if (root.contains("uid")) { out->uid = root.value("uid").toString(); - } - else - { + } else { out->uid = root.value("fileId").toString(); } - const QRegularExpression valid_uid_regex{ QRegularExpression::anchoredPattern(QStringLiteral(R"([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)*)")) }; + const QRegularExpression valid_uid_regex{ QRegularExpression::anchoredPattern( + QStringLiteral(R"([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)*)")) }; if (!valid_uid_regex.match(out->uid).hasMatch()) { qCritical() << "The component's 'uid' contains illegal characters! UID:" << out->uid; - out->addProblem( - ProblemSeverity::Error, - QObject::tr("The component's 'uid' contains illegal characters! This can cause security issues.") - ); + out->addProblem(ProblemSeverity::Error, + QObject::tr("The component's 'uid' contains illegal characters! This can cause security issues.")); } out->version = root.value("version").toString(); @@ -139,46 +127,35 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc // added for legacy Minecraft window embedding, TODO: remove readString(root, "appletClass", out->appletClass); - if (root.contains("+tweakers")) - { - for (auto tweakerVal : requireArray(root.value("+tweakers"))) - { + if (root.contains("+tweakers")) { + for (auto tweakerVal : requireArray(root.value("+tweakers"))) { out->addTweakers.append(requireString(tweakerVal)); } } - if (root.contains("+traits")) - { - for (auto tweakerVal : requireArray(root.value("+traits"))) - { + if (root.contains("+traits")) { + for (auto tweakerVal : requireArray(root.value("+traits"))) { out->traits.insert(requireString(tweakerVal)); } } - if (root.contains("+jvmArgs")) - { - for (auto arg : requireArray(root.value("+jvmArgs"))) - { + if (root.contains("+jvmArgs")) { + for (auto arg : requireArray(root.value("+jvmArgs"))) { out->addnJvmArguments.append(requireString(arg)); } } - - if (root.contains("jarMods")) - { - for (auto libVal : requireArray(root.value("jarMods"))) - { + if (root.contains("jarMods")) { + for (auto libVal : requireArray(root.value("jarMods"))) { QJsonObject libObj = requireObject(libVal); // parse the jarmod auto lib = OneSixVersionFormat::jarModFromJson(*out, libObj, filename); // and add to jar mods out->jarMods.append(lib); } - } - else if (root.contains("+jarMods")) // DEPRECATED: old style '+jarMods' are only here for backwards compatibility + } else if (root.contains("+jarMods")) // DEPRECATED: old style '+jarMods' are only here for backwards compatibility { - for (auto libVal : requireArray(root.value("+jarMods"))) - { + for (auto libVal : requireArray(root.value("+jarMods"))) { QJsonObject libObj = requireObject(libVal); // parse the jarmod auto lib = OneSixVersionFormat::plusJarModFromJson(*out, libObj, filename, out->name); @@ -187,10 +164,8 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } } - if (root.contains("mods")) - { - for (auto libVal : requireArray(root.value("mods"))) - { + if (root.contains("mods")) { + for (auto libVal : requireArray(root.value("mods"))) { QJsonObject libObj = requireObject(libVal); // parse the jarmod auto lib = OneSixVersionFormat::modFromJson(*out, libObj, filename); @@ -199,10 +174,8 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } } - auto readLibs = [&](const char * which, QList & outList) - { - for (auto libVal : requireArray(root.value(which))) - { + auto readLibs = [&](const char* which, QList& outList) { + for (auto libVal : requireArray(root.value(which))) { QJsonObject libObj = requireObject(libVal); // parse the library auto lib = libraryFromJson(*out, libObj, filename); @@ -211,29 +184,23 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc }; bool hasPlusLibs = root.contains("+libraries"); bool hasLibs = root.contains("libraries"); - if (hasPlusLibs && hasLibs) - { + if (hasPlusLibs && hasLibs) { out->addProblem(ProblemSeverity::Warning, QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported.")); readLibs("libraries", out->libraries); readLibs("+libraries", out->libraries); - } - else if (hasLibs) - { + } else if (hasLibs) { readLibs("libraries", out->libraries); - } - else if(hasPlusLibs) - { + } else if (hasPlusLibs) { readLibs("+libraries", out->libraries); } - if(root.contains("mavenFiles")) { + if (root.contains("mavenFiles")) { readLibs("mavenFiles", out->mavenFiles); } - if(root.contains("+agents")) { - for (auto agentVal : requireArray(root.value("+agents"))) - { + if (root.contains("+agents")) { + for (auto agentVal : requireArray(root.value("+agents"))) { QJsonObject agentObj = requireObject(agentVal); auto lib = libraryFromJson(*out, agentObj, filename); @@ -246,83 +213,68 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } // if we have mainJar, just use it - if(root.contains("mainJar")) - { + if (root.contains("mainJar")) { QJsonObject libObj = requireObject(root, "mainJar"); out->mainJar = libraryFromJson(*out, libObj, filename); } // else reconstruct it from downloads and id ... if that's available - else if(!out->minecraftVersion.isEmpty()) - { + else if (!out->minecraftVersion.isEmpty()) { auto lib = std::make_shared(); lib->setRawName(GradleSpecifier(QString("com.mojang:minecraft:%1:client").arg(out->minecraftVersion))); // we have a reliable client download, use it. - if(out->mojangDownloads.contains("client")) - { + if (out->mojangDownloads.contains("client")) { auto LibDLInfo = std::make_shared(); LibDLInfo->artifact = out->mojangDownloads["client"]; lib->setMojangDownloadInfo(LibDLInfo); } // we got nothing... - else - { + else { out->addProblem( ProblemSeverity::Error, - QObject::tr("URL for the main jar could not be determined - Mojang removed the server that we used as fallback.") - ); + QObject::tr("URL for the main jar could not be determined - Mojang removed the server that we used as fallback.")); } out->mainJar = lib; } - if (root.contains("requires")) - { + if (root.contains("requires")) { Meta::parseRequires(root, &out->m_requires); } QString dependsOnMinecraftVersion = root.value("mcVersion").toString(); - if(!dependsOnMinecraftVersion.isEmpty()) - { + if (!dependsOnMinecraftVersion.isEmpty()) { Meta::Require mcReq; mcReq.uid = "net.minecraft"; mcReq.equalsVersion = dependsOnMinecraftVersion; - if (out->m_requires.count(mcReq) == 0) - { + if (out->m_requires.count(mcReq) == 0) { out->m_requires.insert(mcReq); } } - if (root.contains("conflicts")) - { + if (root.contains("conflicts")) { Meta::parseRequires(root, &out->conflicts); } - if (root.contains("volatile")) - { + if (root.contains("volatile")) { out->m_volatile = requireBoolean(root, "volatile"); } /* removed features that shouldn't be used */ - if (root.contains("tweakers")) - { + if (root.contains("tweakers")) { out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element 'tweakers'")); } - if (root.contains("-libraries")) - { + if (root.contains("-libraries")) { out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-libraries'")); } - if (root.contains("-tweakers")) - { + if (root.contains("-tweakers")) { out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-tweakers'")); } - if (root.contains("-minecraftArguments")) - { + if (root.contains("-minecraftArguments")) { out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-minecraftArguments'")); } - if (root.contains("+minecraftArguments")) - { + if (root.contains("+minecraftArguments")) { out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '+minecraftArguments'")); } return out; } -QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch) +QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr& patch) { QJsonObject root; writeString(root, "name", patch->name); @@ -335,19 +287,16 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch MojangVersionFormat::writeVersionProperties(patch.get(), root); - if(patch->mainJar) - { + if (patch->mainJar) { root.insert("mainJar", libraryToJson(patch->mainJar.get())); } writeString(root, "appletClass", patch->appletClass); writeStringList(root, "+tweakers", patch->addTweakers); writeStringList(root, "+traits", patch->traits.values()); writeStringList(root, "+jvmArgs", patch->addnJvmArguments); - if (!patch->agents.isEmpty()) - { + if (!patch->agents.isEmpty()) { QJsonArray array; - for (auto value: patch->agents) - { + for (auto value : patch->agents) { QJsonObject agentOut = OneSixVersionFormat::libraryToJson(value->library().get()); if (!value->argument().isEmpty()) agentOut.insert("argument", value->argument()); @@ -356,52 +305,41 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch } root.insert("+agents", array); } - if (!patch->libraries.isEmpty()) - { + if (!patch->libraries.isEmpty()) { QJsonArray array; - for (auto value: patch->libraries) - { + for (auto value : patch->libraries) { array.append(OneSixVersionFormat::libraryToJson(value.get())); } root.insert("libraries", array); } - if (!patch->mavenFiles.isEmpty()) - { + if (!patch->mavenFiles.isEmpty()) { QJsonArray array; - for (auto value: patch->mavenFiles) - { + for (auto value : patch->mavenFiles) { array.append(OneSixVersionFormat::libraryToJson(value.get())); } root.insert("mavenFiles", array); } - if (!patch->jarMods.isEmpty()) - { + if (!patch->jarMods.isEmpty()) { QJsonArray array; - for (auto value: patch->jarMods) - { + for (auto value : patch->jarMods) { array.append(OneSixVersionFormat::jarModtoJson(value.get())); } root.insert("jarMods", array); } - if (!patch->mods.isEmpty()) - { + if (!patch->mods.isEmpty()) { QJsonArray array; - for (auto value: patch->jarMods) - { + for (auto value : patch->jarMods) { array.append(OneSixVersionFormat::modtoJson(value.get())); } root.insert("mods", array); } - if(!patch->m_requires.empty()) - { + if (!patch->m_requires.empty()) { Meta::serializeRequires(root, &patch->m_requires, "requires"); } - if(!patch->conflicts.empty()) - { + if (!patch->conflicts.empty()) { Meta::serializeRequires(root, &patch->conflicts, "conflicts"); } - if(patch->m_volatile) - { + if (patch->m_volatile) { root.insert("volatile", true); } // write the contents to a json document. @@ -412,17 +350,14 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch } } -LibraryPtr OneSixVersionFormat::plusJarModFromJson( - ProblemContainer & problems, - const QJsonObject &libObj, - const QString &filename, - const QString &originalName -) { +LibraryPtr OneSixVersionFormat::plusJarModFromJson(ProblemContainer& problems, + const QJsonObject& libObj, + const QString& filename, + const QString& originalName) +{ LibraryPtr out(new Library()); - if (!libObj.contains("name")) - { - throw JSONValidationError(filename + - "contains a jarmod that doesn't have a 'name' field"); + if (!libObj.contains("name")) { + throw JSONValidationError(filename + "contains a jarmod that doesn't have a 'name' field"); } // just make up something unique on the spot for the library name. @@ -439,36 +374,32 @@ LibraryPtr OneSixVersionFormat::plusJarModFromJson( // read the original name if present - some versions did not set it // it is the original jar mod filename before it got renamed at the point of addition auto displayName = libObj.value("originalName").toString(); - if(displayName.isEmpty()) - { + if (displayName.isEmpty()) { auto fixed = originalName; fixed.remove(" (jar mod)"); out->setDisplayName(fixed); - } - else - { + } else { out->setDisplayName(displayName); } return out; } -LibraryPtr OneSixVersionFormat::jarModFromJson(ProblemContainer & problems, const QJsonObject& libObj, const QString& filename) +LibraryPtr OneSixVersionFormat::jarModFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename) { return libraryFromJson(problems, libObj, filename); } - -QJsonObject OneSixVersionFormat::jarModtoJson(Library *jarmod) +QJsonObject OneSixVersionFormat::jarModtoJson(Library* jarmod) { return libraryToJson(jarmod); } -LibraryPtr OneSixVersionFormat::modFromJson(ProblemContainer & problems, const QJsonObject& libObj, const QString& filename) +LibraryPtr OneSixVersionFormat::modFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename) { - return libraryFromJson(problems, libObj, filename); + return libraryFromJson(problems, libObj, filename); } -QJsonObject OneSixVersionFormat::modtoJson(Library *jarmod) +QJsonObject OneSixVersionFormat::modtoJson(Library* jarmod) { return libraryToJson(jarmod); } diff --git a/launcher/minecraft/OneSixVersionFormat.h b/launcher/minecraft/OneSixVersionFormat.h index 1a091d880..9bdc4a4a3 100644 --- a/launcher/minecraft/OneSixVersionFormat.h +++ b/launcher/minecraft/OneSixVersionFormat.h @@ -1,30 +1,32 @@ #pragma once -#include -#include -#include -#include #include +#include +#include +#include +#include -class OneSixVersionFormat -{ -public: +class OneSixVersionFormat { + public: // version files / profile patches - static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder); - static QJsonDocument versionFileToJson(const VersionFilePtr &patch); + static VersionFilePtr versionFileFromJson(const QJsonDocument& doc, const QString& filename, const bool requireOrder); + static QJsonDocument versionFileToJson(const VersionFilePtr& patch); // libraries - static LibraryPtr libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); - static QJsonObject libraryToJson(Library *library); + static LibraryPtr libraryFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename); + static QJsonObject libraryToJson(Library* library); // DEPRECATED: old 'plus' jar mods generated by the application - static LibraryPtr plusJarModFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename, const QString &originalName); + static LibraryPtr plusJarModFromJson(ProblemContainer& problems, + const QJsonObject& libObj, + const QString& filename, + const QString& originalName); // new jar mods derived from libraries - static LibraryPtr jarModFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); - static QJsonObject jarModtoJson(Library * jarmod); + static LibraryPtr jarModFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename); + static QJsonObject jarModtoJson(Library* jarmod); // mods, also derived from libraries - static LibraryPtr modFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); - static QJsonObject modtoJson(Library * jarmod); + static LibraryPtr modFromJson(ProblemContainer& problems, const QJsonObject& libObj, const QString& filename); + static QJsonObject modtoJson(Library* jarmod); }; diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index 7cdd47ae6..82fc779eb 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -37,40 +37,37 @@ * limitations under the License. */ -#include -#include #include -#include -#include -#include +#include #include +#include +#include +#include +#include #include -#include #include +#include #include "Exception.h" -#include "minecraft/OneSixVersionFormat.h" #include "FileSystem.h" -#include "minecraft/MinecraftInstance.h" -#include "minecraft/ProfileUtils.h" #include "Json.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/OneSixVersionFormat.h" +#include "minecraft/ProfileUtils.h" +#include "ComponentUpdateTask.h" #include "PackProfile.h" #include "PackProfile_p.h" -#include "ComponentUpdateTask.h" #include "Application.h" #include "modplatform/ResourceAPI.h" -static const QMap modloaderMapping{ - {"net.minecraftforge", ResourceAPI::Forge}, - {"net.fabricmc.fabric-loader", ResourceAPI::Fabric}, - {"org.quiltmc.quilt-loader", ResourceAPI::Quilt}, - {"com.mumfrey.liteloader", ResourceAPI::LiteLoader} -}; +static const QMap modloaderMapping{ { "net.minecraftforge", ResourceAPI::Forge }, + { "net.fabricmc.fabric-loader", ResourceAPI::Fabric }, + { "org.quiltmc.quilt-loader", ResourceAPI::Quilt }, + { "com.mumfrey.liteloader", ResourceAPI::LiteLoader } }; -PackProfile::PackProfile(MinecraftInstance * instance) - : QAbstractListModel() +PackProfile::PackProfile(MinecraftInstance* instance) : QAbstractListModel() { d.reset(new PackProfileData); d->m_instance = instance; @@ -95,42 +92,35 @@ static QJsonObject componentToJsonV1(ComponentPtr component) QJsonObject obj; // critical obj.insert("uid", component->m_uid); - if(!component->m_version.isEmpty()) - { + if (!component->m_version.isEmpty()) { obj.insert("version", component->m_version); } - if(component->m_dependencyOnly) - { + if (component->m_dependencyOnly) { obj.insert("dependencyOnly", true); } - if(component->m_important) - { + if (component->m_important) { obj.insert("important", true); } - if(component->m_disabled) - { + if (component->m_disabled) { obj.insert("disabled", true); } // cached - if(!component->m_cachedVersion.isEmpty()) - { + if (!component->m_cachedVersion.isEmpty()) { obj.insert("cachedVersion", component->m_cachedVersion); } - if(!component->m_cachedName.isEmpty()) - { + if (!component->m_cachedName.isEmpty()) { obj.insert("cachedName", component->m_cachedName); } Meta::serializeRequires(obj, &component->m_cachedRequires, "cachedRequires"); Meta::serializeRequires(obj, &component->m_cachedConflicts, "cachedConflicts"); - if(component->m_cachedVolatile) - { + if (component->m_cachedVolatile) { obj.insert("cachedVolatile", true); } return obj; } -static ComponentPtr componentFromJsonV1(PackProfile * parent, const QString & componentJsonPattern, const QJsonObject &obj) +static ComponentPtr componentFromJsonV1(PackProfile* parent, const QString& componentJsonPattern, const QJsonObject& obj) { // critical auto uid = Json::requireString(obj.value("uid")); @@ -153,51 +143,44 @@ static ComponentPtr componentFromJsonV1(PackProfile * parent, const QString & co } // Save the given component container data to a file -static bool savePackProfile(const QString & filename, const ComponentContainer & container) +static bool savePackProfile(const QString& filename, const ComponentContainer& container) { QJsonObject obj; obj.insert("formatVersion", currentComponentsFileVersion); QJsonArray orderArray; - for(auto component: container) - { + for (auto component : container) { orderArray.append(componentToJsonV1(component)); } obj.insert("components", orderArray); QSaveFile outFile(filename); - if (!outFile.open(QFile::WriteOnly)) - { - qCritical() << "Couldn't open" << outFile.fileName() - << "for writing:" << outFile.errorString(); + if (!outFile.open(QFile::WriteOnly)) { + qCritical() << "Couldn't open" << outFile.fileName() << "for writing:" << outFile.errorString(); return false; } auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented); - if(outFile.write(data) != data.size()) - { - qCritical() << "Couldn't write all the data into" << outFile.fileName() - << "because:" << outFile.errorString(); + if (outFile.write(data) != data.size()) { + qCritical() << "Couldn't write all the data into" << outFile.fileName() << "because:" << outFile.errorString(); return false; } - if(!outFile.commit()) - { - qCritical() << "Couldn't save" << outFile.fileName() - << "because:" << outFile.errorString(); + if (!outFile.commit()) { + qCritical() << "Couldn't save" << outFile.fileName() << "because:" << outFile.errorString(); } return true; } // Read the given file into component containers -static bool loadPackProfile(PackProfile * parent, const QString & filename, const QString & componentJsonPattern, ComponentContainer & container) +static bool loadPackProfile(PackProfile* parent, + const QString& filename, + const QString& componentJsonPattern, + ComponentContainer& container) { QFile componentsFile(filename); - if (!componentsFile.exists()) - { + if (!componentsFile.exists()) { qWarning() << "Components file doesn't exist. This should never happen."; return false; } - if (!componentsFile.open(QFile::ReadOnly)) - { - qCritical() << "Couldn't open" << componentsFile.fileName() - << " for reading:" << componentsFile.errorString(); + if (!componentsFile.open(QFile::ReadOnly)) { + qCritical() << "Couldn't open" << componentsFile.fileName() << " for reading:" << componentsFile.errorString(); qWarning() << "Ignoring overriden order"; return false; } @@ -205,33 +188,26 @@ static bool loadPackProfile(PackProfile * parent, const QString & filename, cons // and it's valid JSON QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error); - if (error.error != QJsonParseError::NoError) - { + if (error.error != QJsonParseError::NoError) { qCritical() << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString(); qWarning() << "Ignoring overriden order"; return false; } // and then read it and process it if all above is true. - try - { + try { auto obj = Json::requireObject(doc); // check order file version. auto version = Json::requireInteger(obj.value("formatVersion")); - if (version != currentComponentsFileVersion) - { - throw JSONValidationError(QObject::tr("Invalid component file version, expected %1") - .arg(currentComponentsFileVersion)); + if (version != currentComponentsFileVersion) { + throw JSONValidationError(QObject::tr("Invalid component file version, expected %1").arg(currentComponentsFileVersion)); } auto orderArray = Json::requireArray(obj.value("components")); - for(auto item: orderArray) - { + for (auto item : orderArray) { auto obj = Json::requireObject(item, "Component must be an object."); container.append(componentFromJsonV1(parent, componentJsonPattern, obj)); } - } - catch (const JSONValidationError &err) - { + } catch (const JSONValidationError& err) { qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format"; container.clear(); return false; @@ -245,8 +221,7 @@ static bool loadPackProfile(PackProfile * parent, const QString & filename, cons void PackProfile::saveNow() { - if(saveIsScheduled()) - { + if (saveIsScheduled()) { d->m_saveTimer.stop(); save_internal(); } @@ -265,13 +240,11 @@ void PackProfile::buildingFromScratch() void PackProfile::scheduleSave() { - if(!d->loaded) - { + if (!d->loaded) { qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name(); return; } - if(!d->dirty) - { + if (!d->dirty) { d->dirty = true; qDebug() << "Component list save is scheduled for" << d->m_instance->name(); } @@ -312,26 +285,20 @@ bool PackProfile::load() // load the new component list and swap it with the current one... ComponentContainer newComponents; - if(!loadPackProfile(this, filename, patchesPattern(), newComponents)) - { + if (!loadPackProfile(this, filename, patchesPattern(), newComponents)) { qCritical() << "Failed to load the component config for instance" << d->m_instance->name(); return false; - } - else - { + } else { // FIXME: actually use fine-grained updates, not this... beginResetModel(); // disconnect all the old components - for(auto component: d->components) - { + for (auto component : d->components) { disconnect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged); } d->components.clear(); d->componentIndex.clear(); - for(auto component: newComponents) - { - if(d->componentIndex.contains(component->m_uid)) - { + for (auto component : newComponents) { + if (d->componentIndex.contains(component->m_uid)) { qWarning() << "Ignoring duplicate component entry" << component->m_uid; continue; } @@ -348,8 +315,7 @@ bool PackProfile::load() void PackProfile::reload(Net::Mode netmode) { // Do not reload when the update/resolve task is running. It is in control. - if(d->m_updateTask) - { + if (d->m_updateTask) { return; } @@ -359,8 +325,7 @@ void PackProfile::reload(Net::Mode netmode) // FIXME: differentiate when a reapply is required by propagating state from components invalidateLaunchProfile(); - if(load()) - { + if (load()) { resolve(netmode); } } @@ -376,11 +341,10 @@ void PackProfile::resolve(Net::Mode netmode) d->m_updateTask.reset(updateTask); connect(updateTask, &ComponentUpdateTask::succeeded, this, &PackProfile::updateSucceeded); connect(updateTask, &ComponentUpdateTask::failed, this, &PackProfile::updateFailed); - connect(updateTask, &ComponentUpdateTask::aborted, this, [this]{ updateFailed(tr("Aborted")); }); + connect(updateTask, &ComponentUpdateTask::aborted, this, [this] { updateFailed(tr("Aborted")); }); d->m_updateTask->start(); } - void PackProfile::updateSucceeded() { qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name(); @@ -405,13 +369,11 @@ void PackProfile::appendComponent(ComponentPtr component) void PackProfile::insertComponent(size_t index, ComponentPtr component) { auto id = component->getID(); - if(id.isEmpty()) - { + if (id.isEmpty()) { qWarning() << "Attempt to add a component with empty ID!"; return; } - if(d->componentIndex.contains(id)) - { + if (d->componentIndex.contains(id)) { qWarning() << "Attempt to add a component that is already present!"; return; } @@ -425,21 +387,18 @@ void PackProfile::insertComponent(size_t index, ComponentPtr component) void PackProfile::componentDataChanged() { - auto objPtr = qobject_cast(sender()); - if(!objPtr) - { + auto objPtr = qobject_cast(sender()); + if (!objPtr) { qWarning() << "PackProfile got dataChenged signal from a non-Component!"; return; } - if(objPtr->getID() == "net.minecraft") { + if (objPtr->getID() == "net.minecraft") { emit minecraftChanged(); } // figure out which one is it... in a seriously dumb way. int index = 0; - for (auto component: d->components) - { - if(component.get() == objPtr) - { + for (auto component : d->components) { + if (component.get() == objPtr) { emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1)); scheduleSave(); return; @@ -452,14 +411,12 @@ void PackProfile::componentDataChanged() bool PackProfile::remove(const int index) { auto patch = getComponent(index); - if (!patch->isRemovable()) - { + if (!patch->isRemovable()) { qWarning() << "Patch" << patch->getID() << "is non-removable"; return false; } - if(!removeComponent_internal(patch)) - { + if (!removeComponent_internal(patch)) { qCritical() << "Patch" << patch->getID() << "could not be removed"; return false; } @@ -476,10 +433,8 @@ bool PackProfile::remove(const int index) bool PackProfile::remove(const QString id) { int i = 0; - for (auto patch : d->components) - { - if (patch->getID() == id) - { + for (auto patch : d->components) { + if (patch->getID() == id) { return remove(i); } i++; @@ -490,13 +445,11 @@ bool PackProfile::remove(const QString id) bool PackProfile::customize(int index) { auto patch = getComponent(index); - if (!patch->isCustomizable()) - { + if (!patch->isCustomizable()) { qDebug() << "Patch" << patch->getID() << "is not customizable"; return false; } - if(!patch->customize()) - { + if (!patch->customize()) { qCritical() << "Patch" << patch->getID() << "could not be customized"; return false; } @@ -508,13 +461,11 @@ bool PackProfile::customize(int index) bool PackProfile::revertToBase(int index) { auto patch = getComponent(index); - if (!patch->isRevertible()) - { + if (!patch->isRevertible()) { qDebug() << "Patch" << patch->getID() << "is not revertible"; return false; } - if(!patch->revert()) - { + if (!patch->revert()) { qCritical() << "Patch" << patch->getID() << "could not be reverted"; return false; } @@ -523,11 +474,10 @@ bool PackProfile::revertToBase(int index) return true; } -ComponentPtr PackProfile::getComponent(const QString &id) +ComponentPtr PackProfile::getComponent(const QString& id) { auto iter = d->componentIndex.find(id); - if (iter == d->componentIndex.end()) - { + if (iter == d->componentIndex.end()) { return nullptr; } return (*iter); @@ -535,14 +485,13 @@ ComponentPtr PackProfile::getComponent(const QString &id) ComponentPtr PackProfile::getComponent(int index) { - if(index < 0 || index >= d->components.size()) - { + if (index < 0 || index >= d->components.size()) { return nullptr; } return d->components[index]; } -QVariant PackProfile::data(const QModelIndex &index, int role) const +QVariant PackProfile::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -555,72 +504,58 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const auto patch = d->components.at(row); - switch (role) - { - case Qt::CheckStateRole: - { - switch (column) - { - case NameColumn: { - return patch->isEnabled() ? Qt::Checked : Qt::Unchecked; - } - default: - return QVariant(); - } - } - case Qt::DisplayRole: - { - switch (column) - { - case NameColumn: - return patch->getName(); - case VersionColumn: - { - if(patch->isCustom()) - { - return QString("%1 (Custom)").arg(patch->getVersion()); - } - else - { - return patch->getVersion(); - } - } - default: - return QVariant(); - } - } - case Qt::DecorationRole: - { - if (column == NameColumn) { - auto severity = patch->getProblemSeverity(); - switch (severity) - { - case ProblemSeverity::Warning: - return "warning"; - case ProblemSeverity::Error: - return "error"; + switch (role) { + case Qt::CheckStateRole: { + switch (column) { + case NameColumn: { + return patch->isEnabled() ? Qt::Checked : Qt::Unchecked; + } default: return QVariant(); } } - return QVariant(); - } + case Qt::DisplayRole: { + switch (column) { + case NameColumn: + return patch->getName(); + case VersionColumn: { + if (patch->isCustom()) { + return QString("%1 (Custom)").arg(patch->getVersion()); + } else { + return patch->getVersion(); + } + } + default: + return QVariant(); + } + } + case Qt::DecorationRole: { + if (column == NameColumn) { + auto severity = patch->getProblemSeverity(); + switch (severity) { + case ProblemSeverity::Warning: + return "warning"; + case ProblemSeverity::Error: + return "error"; + default: + return QVariant(); + } + } + return QVariant(); + } } return QVariant(); } bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int role) { - if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent())) - { + if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent())) { return false; } - if (role == Qt::CheckStateRole) - { + if (role == Qt::CheckStateRole) { auto component = d->components[index.row()]; - if (component->setEnabled(!component->isEnabled())) - { + if (component->setEnabled(!component->isEnabled())) { return true; } } @@ -629,18 +564,15 @@ bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int r QVariant PackProfile::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal) - { - if (role == Qt::DisplayRole) - { - switch (section) - { - case NameColumn: - return tr("Name"); - case VersionColumn: - return tr("Version"); - default: - return QVariant(); + if (orientation == Qt::Horizontal) { + if (role == Qt::DisplayRole) { + switch (section) { + case NameColumn: + return tr("Name"); + case VersionColumn: + return tr("Version"); + default: + return QVariant(); } } } @@ -648,7 +580,7 @@ QVariant PackProfile::headerData(int section, Qt::Orientation orientation, int r } // FIXME: zero precision mess -Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const +Qt::ItemFlags PackProfile::flags(const QModelIndex& index) const { if (!index.isValid()) { return Qt::NoItemFlags; @@ -664,19 +596,18 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const auto patch = d->components.at(row); // TODO: this will need fine-tuning later... - if(patch->canBeDisabled() && !d->interactionDisabled) - { + if (patch->canBeDisabled() && !d->interactionDisabled) { outFlags |= Qt::ItemIsUserCheckable; } return outFlags; } -int PackProfile::rowCount(const QModelIndex &parent) const +int PackProfile::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : d->components.size(); } -int PackProfile::columnCount(const QModelIndex &parent) const +int PackProfile::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : NUM_COLUMNS; } @@ -684,12 +615,9 @@ int PackProfile::columnCount(const QModelIndex &parent) const void PackProfile::move(const int index, const MoveDirection direction) { int theirIndex; - if (direction == MoveUp) - { + if (direction == MoveUp) { theirIndex = index - 1; - } - else - { + } else { theirIndex = index + 1; } @@ -706,8 +634,7 @@ void PackProfile::move(const int index, const MoveDirection direction) auto from = getComponent(index); auto to = getComponent(theirIndex); - if (!from || !to || !to->isMoveable() || !from->isMoveable()) - { + if (!from || !to || !to->isMoveable() || !from->isMoveable()) { return; } beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap); @@ -775,8 +702,7 @@ void PackProfile::installAgents(QStringList selectedFiles) bool PackProfile::installEmpty(const QString& uid, const QString& name) { QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches"); - if(!FS::ensureFolderPathExists(patchDir)) - { + if (!FS::ensureFolderPathExists(patchDir)) { return false; } auto f = std::make_shared(); @@ -785,10 +711,8 @@ bool PackProfile::installEmpty(const QString& uid, const QString& name) f->version = "1"; QString patchFileName = FS::PathCombine(patchDir, uid + ".json"); QFile file(patchFileName); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); + if (!file.open(QFile::WriteOnly)) { + qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString(); return false; } file.write(OneSixVersionFormat::versionFileToJson(f).toJson()); @@ -805,31 +729,25 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch) bool ok = true; // first, remove the patch file. this ensures it's not used anymore auto fileName = patch->getFilename(); - if(fileName.size()) - { + if (fileName.size()) { QFile patchFile(fileName); - if(patchFile.exists() && !patchFile.remove()) - { + if (patchFile.exists() && !patchFile.remove()) { qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString(); return false; } } // FIXME: we need a generic way of removing local resources, not just jar mods... - auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool - { - if (!jarMod->isLocal()) - { + auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool { + if (!jarMod->isLocal()) { return true; } QStringList jar, temp1, temp2, temp3; jarMod->getApplicableFiles(d->m_instance->runtimeContext(), jar, temp1, temp2, temp3, d->m_instance->jarmodsPath().absolutePath()); - QFileInfo finfo (jar[0]); - if(finfo.exists()) - { + QFileInfo finfo(jar[0]); + if (finfo.exists()) { QFile jarModFile(jar[0]); - if(!jarModFile.remove()) - { + if (!jarModFile.remove()) { qCritical() << "File" << jar[0] << "could not be removed because:" << jarModFile.errorString(); return false; } @@ -839,11 +757,9 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch) }; auto vFile = patch->getVersionFile(); - if(vFile) - { - auto &jarMods = vFile->jarMods; - for(auto &jarmod: jarMods) - { + if (vFile) { + auto& jarMods = vFile->jarMods; + for (auto& jarmod : jarMods) { ok &= preRemoveJarMod(jarmod); } } @@ -853,18 +769,15 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch) bool PackProfile::installJarMods_internal(QStringList filepaths) { QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches"); - if(!FS::ensureFolderPathExists(patchDir)) - { + if (!FS::ensureFolderPathExists(patchDir)) { return false; } - if (!FS::ensureFolderPathExists(d->m_instance->jarModsDir())) - { + if (!FS::ensureFolderPathExists(d->m_instance->jarModsDir())) { return false; } - for(auto filepath:filepaths) - { + for (auto filepath : filepaths) { QFileInfo sourceInfo(filepath); QString id = QUuid::createUuid().toString(QUuid::WithoutBraces); QString target_filename = id + ".jar"; @@ -875,8 +788,7 @@ bool PackProfile::installJarMods_internal(QStringList filepaths) QFileInfo targetInfo(finalPath); Q_ASSERT(!targetInfo.exists()); - if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath())) - { + if (!QFile::copy(sourceInfo.absoluteFilePath(), QFileInfo(finalPath).absoluteFilePath())) { return false; } @@ -892,10 +804,8 @@ bool PackProfile::installJarMods_internal(QStringList filepaths) QString patchFileName = FS::PathCombine(patchDir, target_id + ".json"); QFile file(patchFileName); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); + if (!file.open(QFile::WriteOnly)) { + qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString(); return false; } file.write(OneSixVersionFormat::versionFileToJson(f).toJson()); @@ -911,14 +821,12 @@ bool PackProfile::installJarMods_internal(QStringList filepaths) bool PackProfile::installCustomJar_internal(QString filepath) { QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches"); - if(!FS::ensureFolderPathExists(patchDir)) - { + if (!FS::ensureFolderPathExists(patchDir)) { return false; } QString libDir = d->m_instance->getLocalLibraryPath(); - if (!FS::ensureFolderPathExists(libDir)) - { + if (!FS::ensureFolderPathExists(libDir)) { return false; } @@ -930,15 +838,12 @@ bool PackProfile::installCustomJar_internal(QString filepath) QString finalPath = FS::PathCombine(libDir, target_filename); QFileInfo jarInfo(finalPath); - if (jarInfo.exists()) - { - if(!QFile::remove(finalPath)) - { + if (jarInfo.exists()) { + if (!QFile::remove(finalPath)) { return false; } } - if (!QFile::copy(filepath, finalPath)) - { + if (!QFile::copy(filepath, finalPath)) { return false; } @@ -953,10 +858,8 @@ bool PackProfile::installCustomJar_internal(QString filepath) QString patchFileName = FS::PathCombine(patchDir, target_id + ".json"); QFile file(patchFileName); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); + if (!file.open(QFile::WriteOnly)) { + qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString(); return false; } file.write(OneSixVersionFormat::versionFileToJson(f).toJson()); @@ -1029,20 +932,15 @@ bool PackProfile::installAgents_internal(QStringList filepaths) std::shared_ptr PackProfile::getProfile() const { - if(!d->m_profile) - { - try - { + if (!d->m_profile) { + try { auto profile = std::make_shared(); - for(auto file: d->components) - { + for (auto file : d->components) { qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD"); file->applyTo(profile.get()); } d->m_profile = profile; - } - catch (const Exception &error) - { + } catch (const Exception& error) { qWarning() << "Couldn't apply profile patches because: " << error.cause(); } } @@ -1052,20 +950,16 @@ std::shared_ptr PackProfile::getProfile() const bool PackProfile::setComponentVersion(const QString& uid, const QString& version, bool important) { auto iter = d->componentIndex.find(uid); - if(iter != d->componentIndex.end()) - { + if (iter != d->componentIndex.end()) { ComponentPtr component = *iter; // set existing - if(component->revert()) - { + if (component->revert()) { component->setVersion(version); component->setImportant(important); return true; } return false; - } - else - { + } else { // add new auto component = makeShared(this, uid); component->m_version = version; @@ -1078,8 +972,7 @@ bool PackProfile::setComponentVersion(const QString& uid, const QString& version QString PackProfile::getComponentVersion(const QString& uid) const { const auto iter = d->componentIndex.find(uid); - if (iter != d->componentIndex.end()) - { + if (iter != d->componentIndex.end()) { return (*iter)->getVersion(); } return QString(); @@ -1087,10 +980,10 @@ QString PackProfile::getComponentVersion(const QString& uid) const void PackProfile::disableInteraction(bool disable) { - if(d->interactionDisabled != disable) { + if (d->interactionDisabled != disable) { d->interactionDisabled = disable; auto size = d->components.size(); - if(size) { + if (size) { emit dataChanged(index(0), index(size - 1)); } } diff --git a/launcher/minecraft/PackProfile.h b/launcher/minecraft/PackProfile.h index d144d875c..a5e5cb1a9 100644 --- a/launcher/minecraft/PackProfile.h +++ b/launcher/minecraft/PackProfile.h @@ -41,44 +41,39 @@ #include -#include #include +#include #include -#include "Library.h" -#include "LaunchProfile.h" -#include "Component.h" -#include "ProfileUtils.h" #include "BaseVersion.h" +#include "Component.h" +#include "LaunchProfile.h" +#include "Library.h" #include "MojangDownloadInfo.h" -#include "net/Mode.h" +#include "ProfileUtils.h" #include "modplatform/ResourceAPI.h" +#include "net/Mode.h" class MinecraftInstance; struct PackProfileData; class ComponentUpdateTask; -class PackProfile : public QAbstractListModel -{ +class PackProfile : public QAbstractListModel { Q_OBJECT friend ComponentUpdateTask; -public: - enum Columns - { - NameColumn = 0, - VersionColumn, - NUM_COLUMNS - }; - explicit PackProfile(MinecraftInstance * instance); + public: + enum Columns { NameColumn = 0, VersionColumn, NUM_COLUMNS }; + + explicit PackProfile(MinecraftInstance* instance); virtual ~PackProfile(); - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; - virtual int columnCount(const QModelIndex &parent) const override; - virtual Qt::ItemFlags flags(const QModelIndex &index) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int columnCount(const QModelIndex& parent) const override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; /// call this to explicitly mark the component list as loaded - this is used to build a new component list from scratch. void buildingFromScratch(); @@ -121,15 +116,15 @@ public: std::shared_ptr getProfile() const; // NOTE: used ONLY by MinecraftInstance to provide legacy version mappings from instance config - void setOldConfigVersion(const QString &uid, const QString &version); + void setOldConfigVersion(const QString& uid, const QString& version); - QString getComponentVersion(const QString &uid) const; + QString getComponentVersion(const QString& uid) const; - bool setComponentVersion(const QString &uid, const QString &version, bool important = false); + bool setComponentVersion(const QString& uid, const QString& version, bool important = false); - bool installEmpty(const QString &uid, const QString &name); + bool installEmpty(const QString& uid, const QString& name); - QString patchFilePathForUid(const QString &uid) const; + QString patchFilePathForUid(const QString& uid) const; /// if there is a save scheduled, do it now. void saveNow(); @@ -137,12 +132,12 @@ public: /// helper method, returns RuntimeContext of instance RuntimeContext runtimeContext(); -signals: + signals: void minecraftChanged(); -public: + public: /// get the profile component by id - ComponentPtr getComponent(const QString &id); + ComponentPtr getComponent(const QString& id); /// get the profile component by index ComponentPtr getComponent(int index); @@ -153,7 +148,7 @@ public: std::optional getModLoaders(); -private: + private: void scheduleSave(); bool saveIsScheduled() const; @@ -166,21 +161,20 @@ private: QString componentsFilePath() const; QString patchesPattern() const; -private slots: + private slots: void save_internal(); void updateSucceeded(); - void updateFailed(const QString & error); + void updateFailed(const QString& error); void componentDataChanged(); void disableInteraction(bool disable); -private: + private: bool load(); bool installJarMods_internal(QStringList filepaths); bool installCustomJar_internal(QString filepath); bool installAgents_internal(QStringList filepaths); bool removeComponent_internal(ComponentPtr patch); -private: /* data */ - + private: /* data */ std::unique_ptr d; }; diff --git a/launcher/minecraft/PackProfile_p.h b/launcher/minecraft/PackProfile_p.h index 715e04606..0cd4fb839 100644 --- a/launcher/minecraft/PackProfile_p.h +++ b/launcher/minecraft/PackProfile_p.h @@ -1,19 +1,18 @@ #pragma once -#include "Component.h" -#include -#include #include #include +#include +#include +#include "Component.h" class MinecraftInstance; using ComponentContainer = QList; using ComponentIndex = QMap; -struct PackProfileData -{ +struct PackProfileData { // the instance this belongs to - MinecraftInstance *m_instance; + MinecraftInstance* m_instance; // the launch profile (volatile, temporary thing created on demand) std::shared_ptr m_profile; @@ -27,4 +26,3 @@ struct PackProfileData bool loaded = false; bool interactionDisabled = true; }; - diff --git a/launcher/minecraft/ParseUtils.cpp b/launcher/minecraft/ParseUtils.cpp index c9640e776..fabc57a65 100644 --- a/launcher/minecraft/ParseUtils.cpp +++ b/launcher/minecraft/ParseUtils.cpp @@ -1,7 +1,7 @@ -#include -#include #include "ParseUtils.h" +#include #include +#include #include QDateTime timeFromS3Time(QString str) @@ -22,7 +22,7 @@ QString timeToS3Time(QDateTime time) int offsetMinutes = offsetAbs % 3600; offsetAbs -= offsetMinutes; offsetMinutes /= 60; - + int offsetHours = offsetAbs / 3600; QString raw = time.toString("yyyy-MM-ddTHH:mm:ss"); diff --git a/launcher/minecraft/ParseUtils.h b/launcher/minecraft/ParseUtils.h index aad82748d..c81d8f8bb 100644 --- a/launcher/minecraft/ParseUtils.h +++ b/launcher/minecraft/ParseUtils.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include /// take the timestamp used by S3 and turn it into QDateTime QDateTime timeFromS3Time(QString str); diff --git a/launcher/minecraft/ProfileUtils.cpp b/launcher/minecraft/ProfileUtils.cpp index 03f8c1989..666ebcfc1 100644 --- a/launcher/minecraft/ProfileUtils.cpp +++ b/launcher/minecraft/ProfileUtils.cpp @@ -34,33 +34,29 @@ */ #include "ProfileUtils.h" -#include "minecraft/VersionFilterData.h" -#include "minecraft/OneSixVersionFormat.h" -#include "Json.h" #include +#include "Json.h" +#include "minecraft/OneSixVersionFormat.h" +#include "minecraft/VersionFilterData.h" -#include #include +#include #include #include -namespace ProfileUtils -{ +namespace ProfileUtils { static const int currentOrderFileVersion = 1; -bool readOverrideOrders(QString path, PatchOrder &order) +bool readOverrideOrders(QString path, PatchOrder& order) { QFile orderFile(path); - if (!orderFile.exists()) - { + if (!orderFile.exists()) { qWarning() << "Order file doesn't exist. Ignoring."; return false; } - if (!orderFile.open(QFile::ReadOnly)) - { - qCritical() << "Couldn't open" << orderFile.fileName() - << " for reading:" << orderFile.errorString(); + if (!orderFile.open(QFile::ReadOnly)) { + qCritical() << "Couldn't open" << orderFile.fileName() << " for reading:" << orderFile.errorString(); qWarning() << "Ignoring overriden order"; return false; } @@ -68,32 +64,25 @@ bool readOverrideOrders(QString path, PatchOrder &order) // and it's valid JSON QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error); - if (error.error != QJsonParseError::NoError) - { + if (error.error != QJsonParseError::NoError) { qCritical() << "Couldn't parse" << orderFile.fileName() << ":" << error.errorString(); qWarning() << "Ignoring overriden order"; return false; } // and then read it and process it if all above is true. - try - { + try { auto obj = Json::requireObject(doc); // check order file version. auto version = Json::requireInteger(obj.value("version")); - if (version != currentOrderFileVersion) - { - throw JSONValidationError(QObject::tr("Invalid order file version, expected %1") - .arg(currentOrderFileVersion)); + if (version != currentOrderFileVersion) { + throw JSONValidationError(QObject::tr("Invalid order file version, expected %1").arg(currentOrderFileVersion)); } auto orderArray = Json::requireArray(obj.value("order")); - for(auto item: orderArray) - { + for (auto item : orderArray) { order.append(Json::requireString(item)); } - } - catch (const JSONValidationError &err) - { + } catch (const JSONValidationError& err) { qCritical() << "Couldn't parse" << orderFile.fileName() << ": bad file format"; qWarning() << "Ignoring overriden order"; order.clear(); @@ -111,23 +100,19 @@ static VersionFilePtr createErrorVersionFile(QString fileId, QString filepath, Q return outError; } -static VersionFilePtr guardedParseJson(const QJsonDocument & doc,const QString &fileId,const QString &filepath,const bool &requireOrder) +static VersionFilePtr guardedParseJson(const QJsonDocument& doc, const QString& fileId, const QString& filepath, const bool& requireOrder) { - try - { + try { return OneSixVersionFormat::versionFileFromJson(doc, filepath, requireOrder); - } - catch (const Exception &e) - { + } catch (const Exception& e) { return createErrorVersionFile(fileId, filepath, e.cause()); } } -VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder) +VersionFilePtr parseJsonFile(const QFileInfo& fileInfo, const bool requireOrder) { QFile file(fileInfo.absoluteFilePath()); - if (!file.open(QFile::ReadOnly)) - { + if (!file.open(QFile::ReadOnly)) { auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString()); return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr); } @@ -135,14 +120,11 @@ VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder) auto data = file.readAll(); QJsonDocument doc = QJsonDocument::fromJson(data, &error); file.close(); - if (error.error != QJsonParseError::NoError) - { + if (error.error != QJsonParseError::NoError) { int line = 1; int column = 0; - for(int i = 0; i < error.offset; i++) - { - if(data[i] == '\n') - { + for (int i = 0; i < error.offset; i++) { + if (data[i] == '\n') { line++; column = 0; continue; @@ -150,26 +132,25 @@ VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder) column++; } auto errorStr = QObject::tr("Unable to process the version file %1: %2 at line %3 column %4.") - .arg(fileInfo.fileName(), error.errorString()) - .arg(line).arg(column); + .arg(fileInfo.fileName(), error.errorString()) + .arg(line) + .arg(column); return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr); } return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), requireOrder); } -bool saveJsonFile(const QJsonDocument doc, const QString & filename) +bool saveJsonFile(const QJsonDocument doc, const QString& filename) { auto data = doc.toJson(); QSaveFile jsonFile(filename); - if(!jsonFile.open(QIODevice::WriteOnly)) - { + if (!jsonFile.open(QIODevice::WriteOnly)) { jsonFile.cancelWriting(); qWarning() << "Couldn't open" << filename << "for writing"; return false; } jsonFile.write(data); - if(!jsonFile.commit()) - { + if (!jsonFile.commit()) { qWarning() << "Couldn't save" << filename; return false; } @@ -178,13 +159,10 @@ bool saveJsonFile(const QJsonDocument doc, const QString & filename) void removeLwjglFromPatch(VersionFilePtr patch) { - auto filter = [](QList& libs) - { + auto filter = [](QList& libs) { QList filteredLibs; - for (auto lib : libs) - { - if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix())) - { + for (auto lib : libs) { + if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix())) { filteredLibs.append(lib); } } @@ -192,4 +170,4 @@ void removeLwjglFromPatch(VersionFilePtr patch) }; filter(patch->libraries); } -} +} // namespace ProfileUtils diff --git a/launcher/minecraft/ProfileUtils.h b/launcher/minecraft/ProfileUtils.h index 5b938784c..93cc3da07 100644 --- a/launcher/minecraft/ProfileUtils.h +++ b/launcher/minecraft/ProfileUtils.h @@ -37,24 +37,22 @@ #include "Library.h" #include "VersionFile.h" -namespace ProfileUtils -{ +namespace ProfileUtils { typedef QStringList PatchOrder; /// Read and parse a OneSix format order file -bool readOverrideOrders(QString path, PatchOrder &order); +bool readOverrideOrders(QString path, PatchOrder& order); /// Write a OneSix format order file -bool writeOverrideOrders(QString path, const PatchOrder &order); - +bool writeOverrideOrders(QString path, const PatchOrder& order); /// Parse a version file in JSON format -VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder); +VersionFilePtr parseJsonFile(const QFileInfo& fileInfo, const bool requireOrder); /// Save a JSON file (in any format) -bool saveJsonFile(const QJsonDocument doc, const QString & filename); +bool saveJsonFile(const QJsonDocument doc, const QString& filename); /// Remove LWJGL from a patch file. This is applied to all Mojang-like profile files. void removeLwjglFromPatch(VersionFilePtr patch); -} +} // namespace ProfileUtils diff --git a/launcher/minecraft/Rule.cpp b/launcher/minecraft/Rule.cpp index ff3d75f2e..74c12a0d2 100644 --- a/launcher/minecraft/Rule.cpp +++ b/launcher/minecraft/Rule.cpp @@ -33,8 +33,8 @@ * limitations under the License. */ -#include #include +#include #include "Rule.h" @@ -47,7 +47,7 @@ RuleAction RuleAction_fromString(QString name) return Defer; } -QList> rulesFromJsonV4(const QJsonObject &objectWithRules) +QList> rulesFromJsonV4(const QJsonObject& objectWithRules) { QList> rules; auto rulesVal = objectWithRules.value("rules"); @@ -55,8 +55,7 @@ QList> rulesFromJsonV4(const QJsonObject &objectWithRules) return rules; QJsonArray ruleList = rulesVal.toArray(); - for (auto ruleVal : ruleList) - { + for (auto ruleVal : ruleList) { std::shared_ptr rule; if (!ruleVal.isObject()) continue; @@ -69,8 +68,7 @@ QList> rulesFromJsonV4(const QJsonObject &objectWithRules) continue; auto osVal = ruleObj.value("os"); - if (!osVal.isObject()) - { + if (!osVal.isObject()) { // add a new implicit action rule rules.append(ImplicitRule::create(action)); continue; @@ -102,12 +100,10 @@ QJsonObject OsRule::toJson() QJsonObject osObj; { osObj.insert("name", m_system); - if(!m_version_regexp.isEmpty()) - { + if (!m_version_regexp.isEmpty()) { osObj.insert("version", m_version_regexp); } } ruleObj.insert("os", osObj); return ruleObj; } - diff --git a/launcher/minecraft/Rule.h b/launcher/minecraft/Rule.h index 846e8e428..0ece6ae22 100644 --- a/launcher/minecraft/Rule.h +++ b/launcher/minecraft/Rule.h @@ -35,37 +35,29 @@ #pragma once -#include -#include #include +#include +#include #include #include "RuntimeContext.h" class Library; class Rule; -enum RuleAction -{ - Allow, - Disallow, - Defer -}; +enum RuleAction { Allow, Disallow, Defer }; -QList> rulesFromJsonV4(const QJsonObject &objectWithRules); +QList> rulesFromJsonV4(const QJsonObject& objectWithRules); -class Rule -{ -protected: +class Rule { + protected: RuleAction m_result; - virtual bool applies(const Library *parent, const RuntimeContext & runtimeContext) = 0; + virtual bool applies(const Library* parent, const RuntimeContext& runtimeContext) = 0; -public: - Rule(RuleAction result) : m_result(result) - { - } - virtual ~Rule() {}; + public: + Rule(RuleAction result) : m_result(result) {} + virtual ~Rule(){}; virtual QJsonObject toJson() = 0; - RuleAction apply(const Library *parent, const RuntimeContext & runtimeContext) + RuleAction apply(const Library* parent, const RuntimeContext& runtimeContext) { if (applies(parent, runtimeContext)) return m_result; @@ -74,48 +66,31 @@ public: } }; -class OsRule : public Rule -{ -private: +class OsRule : public Rule { + private: // the OS QString m_system; // the OS version regexp QString m_version_regexp; -protected: - virtual bool applies(const Library *, const RuntimeContext & runtimeContext) - { - return runtimeContext.classifierMatches(m_system); - } - OsRule(RuleAction result, QString system, QString version_regexp) - : Rule(result), m_system(system), m_version_regexp(version_regexp) - { - } + protected: + virtual bool applies(const Library*, const RuntimeContext& runtimeContext) { return runtimeContext.classifierMatches(m_system); } + OsRule(RuleAction result, QString system, QString version_regexp) : Rule(result), m_system(system), m_version_regexp(version_regexp) {} -public: + public: virtual QJsonObject toJson(); - static std::shared_ptr create(RuleAction result, QString system, - QString version_regexp) + static std::shared_ptr create(RuleAction result, QString system, QString version_regexp) { return std::shared_ptr(new OsRule(result, system, version_regexp)); } }; -class ImplicitRule : public Rule -{ -protected: - virtual bool applies(const Library *, [[maybe_unused]] const RuntimeContext & runtimeContext) - { - return true; - } - ImplicitRule(RuleAction result) : Rule(result) - { - } +class ImplicitRule : public Rule { + protected: + virtual bool applies(const Library*, [[maybe_unused]] const RuntimeContext& runtimeContext) { return true; } + ImplicitRule(RuleAction result) : Rule(result) {} -public: + public: virtual QJsonObject toJson(); - static std::shared_ptr create(RuleAction result) - { - return std::shared_ptr(new ImplicitRule(result)); - } + static std::shared_ptr create(RuleAction result) { return std::shared_ptr(new ImplicitRule(result)); } }; diff --git a/launcher/minecraft/VanillaInstanceCreationTask.cpp b/launcher/minecraft/VanillaInstanceCreationTask.cpp index 0bb92e876..ccbd8c677 100644 --- a/launcher/minecraft/VanillaInstanceCreationTask.cpp +++ b/launcher/minecraft/VanillaInstanceCreationTask.cpp @@ -8,7 +8,11 @@ #include "settings/INISettingsObject.h" VanillaCreationTask::VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version) - : InstanceCreationTask(), m_version(std::move(version)), m_using_loader(true), m_loader(std::move(loader)), m_loader_version(std::move(loader_version)) + : InstanceCreationTask() + , m_version(std::move(version)) + , m_using_loader(true) + , m_loader(std::move(loader)) + , m_loader_version(std::move(loader_version)) {} bool VanillaCreationTask::createInstance() @@ -22,7 +26,7 @@ bool VanillaCreationTask::createInstance() auto components = inst.getPackProfile(); components->buildingFromScratch(); components->setComponentVersion("net.minecraft", m_version->descriptor(), true); - if(m_using_loader) + if (m_using_loader) components->setComponentVersion(m_loader, m_loader_version->descriptor()); inst.setName(name()); diff --git a/launcher/minecraft/VersionFile.cpp b/launcher/minecraft/VersionFile.cpp index 76f41600f..b8aaee90f 100644 --- a/launcher/minecraft/VersionFile.cpp +++ b/launcher/minecraft/VersionFile.cpp @@ -39,23 +39,22 @@ #include -#include "minecraft/VersionFile.h" +#include "ParseUtils.h" #include "minecraft/Library.h" #include "minecraft/PackProfile.h" -#include "ParseUtils.h" +#include "minecraft/VersionFile.h" #include -static bool isMinecraftVersion(const QString &uid) +static bool isMinecraftVersion(const QString& uid) { return uid == "net.minecraft"; } -void VersionFile::applyTo(LaunchProfile *profile, const RuntimeContext & runtimeContext) +void VersionFile::applyTo(LaunchProfile* profile, const RuntimeContext& runtimeContext) { // Only real Minecraft can set those. Don't let anything override them. - if (isMinecraftVersion(uid)) - { + if (isMinecraftVersion(uid)) { profile->applyMinecraftVersion(version); profile->applyMinecraftVersionType(type); // HACK: ignore assets from other version files than Minecraft @@ -75,16 +74,13 @@ void VersionFile::applyTo(LaunchProfile *profile, const RuntimeContext & runtime profile->applyTraits(traits); profile->applyCompatibleJavaMajors(compatibleJavaMajors); - for (auto library : libraries) - { + for (auto library : libraries) { profile->applyLibrary(library, runtimeContext); } - for (auto mavenFile : mavenFiles) - { + for (auto mavenFile : mavenFiles) { profile->applyMavenFile(mavenFile, runtimeContext); } - for (auto agent : agents) - { + for (auto agent : agents) { profile->applyAgent(agent, runtimeContext); } profile->applyProblemSeverity(getProblemSeverity()); diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index 8e9dd1670..d8984a29e 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -35,17 +35,17 @@ #pragma once -#include -#include #include #include +#include +#include -#include -#include "minecraft/Rule.h" -#include "ProblemProvider.h" -#include "Library.h" -#include "Agent.h" #include +#include +#include "Agent.h" +#include "Library.h" +#include "ProblemProvider.h" +#include "minecraft/Rule.h" class PackProfile; class VersionFile; @@ -54,14 +54,14 @@ struct MojangDownloadInfo; struct MojangAssetIndexInfo; using VersionFilePtr = std::shared_ptr; -class VersionFile : public ProblemContainer -{ +class VersionFile : public ProblemContainer { friend class MojangVersionFormat; friend class OneSixVersionFormat; -public: /* methods */ - void applyTo(LaunchProfile* profile, const RuntimeContext & runtimeContext); -public: /* data */ + public: /* methods */ + void applyTo(LaunchProfile* profile, const RuntimeContext& runtimeContext); + + public: /* data */ /// Prism Launcher: order hint for this version file if no explicit order is set int order = 0; @@ -149,11 +149,10 @@ public: /* data */ /// is volatile -- may be removed as soon as it is no longer needed by something else bool m_volatile = false; -public: + public: // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more. - QMap > mojangDownloads; + QMap> mojangDownloads; // Mojang: extended asset index download information std::shared_ptr mojangAssetIndex; }; - diff --git a/launcher/minecraft/VersionFilterData.cpp b/launcher/minecraft/VersionFilterData.cpp index c286d2662..3924e598f 100644 --- a/launcher/minecraft/VersionFilterData.cpp +++ b/launcher/minecraft/VersionFilterData.cpp @@ -6,19 +6,17 @@ VersionFilterData g_VersionFilterData = VersionFilterData(); VersionFilterData::VersionFilterData() { // 1.3.* - auto libs13 = - QList{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b"}, - {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f"}, - {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82"}}; + auto libs13 = QList{ { "argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b" }, + { "guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f" }, + { "asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82" } }; fmlLibsMapping["1.3.2"] = libs13; // 1.4.* - auto libs14 = QList{ - {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b"}, - {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f"}, - {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82"}, - {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb"}}; + auto libs14 = QList{ { "argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b" }, + { "guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f" }, + { "asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82" }, + { "bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb" } }; fmlLibsMapping["1.4"] = libs14; fmlLibsMapping["1.4.1"] = libs14; @@ -30,43 +28,38 @@ VersionFilterData::VersionFilterData() fmlLibsMapping["1.4.7"] = libs14; // 1.5 - fmlLibsMapping["1.5"] = QList{ - {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"}, - {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"}, - {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"}, - {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"}, - {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8"}, - {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85"}}; + fmlLibsMapping["1.5"] = QList{ { "argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51" }, + { "guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a" }, + { "asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58" }, + { "bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65" }, + { "deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8" }, + { "scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85" } }; // 1.5.1 - fmlLibsMapping["1.5.1"] = QList{ - {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"}, - {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"}, - {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"}, - {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"}, - {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6"}, - {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85"}}; + fmlLibsMapping["1.5.1"] = QList{ { "argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51" }, + { "guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a" }, + { "asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58" }, + { "bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65" }, + { "deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6" }, + { "scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85" } }; // 1.5.2 - fmlLibsMapping["1.5.2"] = QList{ - {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"}, - {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"}, - {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"}, - {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"}, - {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9"}, - {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85"}}; + fmlLibsMapping["1.5.2"] = QList{ { "argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51" }, + { "guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a" }, + { "asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58" }, + { "bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65" }, + { "deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9" }, + { "scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85" } }; // don't use installers for those. - forgeInstallerBlacklist = QSet({"1.5.2"}); + forgeInstallerBlacklist = QSet({ "1.5.2" }); // FIXME: remove, used for deciding when core mods should display legacyCutoffDate = timeFromS3Time("2013-06-25T15:08:56+02:00"); - lwjglWhitelist = - QSet{"net.java.jinput:jinput", "net.java.jinput:jinput-platform", - "net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl", - "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"}; + lwjglWhitelist = QSet{ "net.java.jinput:jinput", "net.java.jinput:jinput-platform", "net.java.jutils:jutils", + "org.lwjgl.lwjgl:lwjgl", "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform" }; - java8BeginsDate = timeFromS3Time("2017-03-30T09:32:19+00:00"); + java8BeginsDate = timeFromS3Time("2017-03-30T09:32:19+00:00"); java16BeginsDate = timeFromS3Time("2021-05-12T11:19:15+00:00"); java17BeginsDate = timeFromS3Time("2021-11-16T17:04:48+00:00"); } diff --git a/launcher/minecraft/VersionFilterData.h b/launcher/minecraft/VersionFilterData.h index 13445a517..bcd329b6c 100644 --- a/launcher/minecraft/VersionFilterData.h +++ b/launcher/minecraft/VersionFilterData.h @@ -1,17 +1,15 @@ #pragma once -#include -#include -#include #include +#include +#include +#include -struct FMLlib -{ +struct FMLlib { QString filename; QString checksum; }; -struct VersionFilterData -{ +struct VersionFilterData { VersionFilterData(); // mapping between minecraft versions and FML libraries required QMap> fmlLibsMapping; diff --git a/launcher/minecraft/World.cpp b/launcher/minecraft/World.cpp index 54fb94346..62e0279a1 100644 --- a/launcher/minecraft/World.cpp +++ b/launcher/minecraft/World.cpp @@ -34,23 +34,23 @@ * limitations under the License. */ -#include -#include -#include -#include -#include #include "World.h" +#include +#include +#include +#include +#include -#include "GZip.h" -#include #include -#include +#include #include -#include -#include #include -#include #include +#include +#include +#include +#include +#include "GZip.h" #include @@ -58,16 +58,15 @@ #include "FileSystem.h" -using std::optional; using std::nullopt; +using std::optional; -GameType::GameType(std::optional original): - original(original) +GameType::GameType(std::optional original) : original(original) { - if(!original) { + if (!original) { return; } - switch(*original) { + switch (*original) { case 0: type = GameType::Survival; break; @@ -87,8 +86,7 @@ GameType::GameType(std::optional original): QString GameType::toTranslatedString() const { - switch (type) - { + switch (type) { case GameType::Survival: return QCoreApplication::translate("GameType", "Survival"); case GameType::Creative: @@ -100,7 +98,7 @@ QString GameType::toTranslatedString() const default: break; } - if(original) { + if (original) { return QCoreApplication::translate("GameType", "Unknown (%1)").arg(*original); } return QCoreApplication::translate("GameType", "Undefined"); @@ -108,8 +106,7 @@ QString GameType::toTranslatedString() const QString GameType::toLogString() const { - switch (type) - { + switch (type) { case GameType::Survival: return "Survival"; case GameType::Creative: @@ -121,108 +118,94 @@ QString GameType::toLogString() const default: break; } - if(original) { + if (original) { return QString("Unknown (%1)").arg(*original); } return "Undefined"; } -std::unique_ptr parseLevelDat(QByteArray data) +std::unique_ptr parseLevelDat(QByteArray data) { QByteArray output; - if(!GZip::unzip(data, output)) - { + if (!GZip::unzip(data, output)) { return nullptr; } std::istringstream foo(std::string(output.constData(), output.size())); try { auto pair = nbt::io::read_compound(foo); - if(pair.first != "") + if (pair.first != "") return nullptr; - if(pair.second == nullptr) + if (pair.second == nullptr) return nullptr; return std::move(pair.second); - } - catch (const nbt::io::input_error &e) - { + } catch (const nbt::io::input_error& e) { qWarning() << "Unable to parse level.dat:" << e.what(); return nullptr; } } -QByteArray serializeLevelDat(nbt::tag_compound * levelInfo) +QByteArray serializeLevelDat(nbt::tag_compound* levelInfo) { std::ostringstream s; nbt::io::write_tag("", *levelInfo, s); - QByteArray val( s.str().data(), (int) s.str().size() ); + QByteArray val(s.str().data(), (int)s.str().size()); return val; } -QString getLevelDatFromFS(const QFileInfo &file) +QString getLevelDatFromFS(const QFileInfo& file) { QDir worldDir(file.filePath()); - if(!file.isDir() || !worldDir.exists("level.dat")) - { + if (!file.isDir() || !worldDir.exists("level.dat")) { return QString(); } return worldDir.absoluteFilePath("level.dat"); } -QByteArray getLevelDatDataFromFS(const QFileInfo &file) +QByteArray getLevelDatDataFromFS(const QFileInfo& file) { auto fullFilePath = getLevelDatFromFS(file); - if(fullFilePath.isNull()) - { + if (fullFilePath.isNull()) { return QByteArray(); } QFile f(fullFilePath); - if(!f.open(QIODevice::ReadOnly)) - { + if (!f.open(QIODevice::ReadOnly)) { return QByteArray(); } return f.readAll(); } -bool putLevelDatDataToFS(const QFileInfo &file, QByteArray & data) +bool putLevelDatDataToFS(const QFileInfo& file, QByteArray& data) { - auto fullFilePath = getLevelDatFromFS(file); - if(fullFilePath.isNull()) - { + auto fullFilePath = getLevelDatFromFS(file); + if (fullFilePath.isNull()) { return false; } QSaveFile f(fullFilePath); - if(!f.open(QIODevice::WriteOnly)) - { + if (!f.open(QIODevice::WriteOnly)) { return false; } QByteArray compressed; - if(!GZip::zip(data, compressed)) - { + if (!GZip::zip(data, compressed)) { return false; } - if(f.write(compressed) != compressed.size()) - { + if (f.write(compressed) != compressed.size()) { f.cancelWriting(); return false; } return f.commit(); } -int64_t calculateWorldSize(const QFileInfo &file) +int64_t calculateWorldSize(const QFileInfo& file) { - if (file.isFile() && file.suffix() == "zip") - { + if (file.isFile() && file.suffix() == "zip") { return file.size(); - } - else if(file.isDir()) - { + } else if (file.isDir()) { QDirIterator it(file.absoluteFilePath(), QDir::Files, QDirIterator::Subdirectories); int64_t total = 0; - while (it.hasNext()) - { + while (it.hasNext()) { total += it.fileInfo().size(); it.next(); } @@ -231,25 +214,22 @@ int64_t calculateWorldSize(const QFileInfo &file) return -1; } -World::World(const QFileInfo &file) +World::World(const QFileInfo& file) { repath(file); } -void World::repath(const QFileInfo &file) +void World::repath(const QFileInfo& file) { m_containerFile = file; m_folderName = file.fileName(); m_size = calculateWorldSize(file); - if(file.isFile() && file.suffix() == "zip") - { + if (file.isFile() && file.suffix() == "zip") { m_iconFile = QString(); readFromZip(file); - } - else if(file.isDir()) - { + } else if (file.isDir()) { QFileInfo assumedIconPath(file.absoluteFilePath() + "/icon.png"); - if(assumedIconPath.exists()) { + if (assumedIconPath.exists()) { m_iconFile = assumedIconPath.absoluteFilePath(); } readFromFS(file); @@ -258,21 +238,20 @@ void World::repath(const QFileInfo &file) bool World::resetIcon() { - if(m_iconFile.isNull()) { + if (m_iconFile.isNull()) { return false; } - if(QFile(m_iconFile).remove()) { + if (QFile(m_iconFile).remove()) { m_iconFile = QString(); return true; } return false; } -void World::readFromFS(const QFileInfo &file) +void World::readFromFS(const QFileInfo& file) { auto bytes = getLevelDatDataFromFS(file); - if(bytes.isEmpty()) - { + if (bytes.isEmpty()) { is_valid = false; return; } @@ -280,104 +259,88 @@ void World::readFromFS(const QFileInfo &file) levelDatTime = file.lastModified(); } -void World::readFromZip(const QFileInfo &file) +void World::readFromZip(const QFileInfo& file) { QuaZip zip(file.absoluteFilePath()); is_valid = zip.open(QuaZip::mdUnzip); - if (!is_valid) - { + if (!is_valid) { return; } auto location = MMCZip::findFolderOfFileInZip(&zip, "level.dat"); is_valid = !location.isEmpty(); - if (!is_valid) - { + if (!is_valid) { return; } m_containerOffsetPath = location; QuaZipFile zippedFile(&zip); // read the install profile is_valid = zip.setCurrentFile(location + "level.dat"); - if (!is_valid) - { + if (!is_valid) { return; } is_valid = zippedFile.open(QIODevice::ReadOnly); QuaZipFileInfo64 levelDatInfo; zippedFile.getFileInfo(&levelDatInfo); auto modTime = levelDatInfo.getNTFSmTime(); - if(!modTime.isValid()) - { + if (!modTime.isValid()) { modTime = levelDatInfo.dateTime; } levelDatTime = modTime; - if (!is_valid) - { + if (!is_valid) { return; } loadFromLevelDat(zippedFile.readAll()); zippedFile.close(); } -bool World::install(const QString &to, const QString &name) +bool World::install(const QString& to, const QString& name) { auto finalPath = FS::PathCombine(to, FS::DirNameFromString(m_actualName, to)); - if(!FS::ensureFolderPathExists(finalPath)) - { + if (!FS::ensureFolderPathExists(finalPath)) { return false; } bool ok = false; - if(m_containerFile.isFile()) - { + if (m_containerFile.isFile()) { QuaZip zip(m_containerFile.absoluteFilePath()); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { return false; } ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath); - } - else if(m_containerFile.isDir()) - { + } else if (m_containerFile.isDir()) { QString from = m_containerFile.filePath(); ok = FS::copy(from, finalPath)(); } - if(ok && !name.isEmpty() && m_actualName != name) - { + if (ok && !name.isEmpty() && m_actualName != name) { QFileInfo finalPathInfo(finalPath); World newWorld(finalPathInfo); - if(newWorld.isValid()) - { + if (newWorld.isValid()) { newWorld.rename(name); } } return ok; } -bool World::rename(const QString &newName) +bool World::rename(const QString& newName) { - if(m_containerFile.isFile()) - { + if (m_containerFile.isFile()) { return false; } auto data = getLevelDatDataFromFS(m_containerFile); - if(data.isEmpty()) - { + if (data.isEmpty()) { return false; } auto worldData = parseLevelDat(data); - if(!worldData) - { + if (!worldData) { return false; } - auto &val = worldData->at("Data"); - if(val.get_type() != nbt::tag_type::Compound) - { + auto& val = worldData->at("Data"); + if (val.get_type() != nbt::tag_type::Compound) { return false; } - auto &dataCompound = val.as(); + auto& dataCompound = val.as(); dataCompound.put("LevelName", nbt::value_initializer(newName.toUtf8().data())); data = serializeLevelDat(worldData.get()); @@ -396,112 +359,93 @@ bool World::rename(const QString &newName) namespace { -optional read_string (nbt::value& parent, const char * name) +optional read_string(nbt::value& parent, const char* name) { - try - { - auto &namedValue = parent.at(name); - if(namedValue.get_type() != nbt::tag_type::String) - { + try { + auto& namedValue = parent.at(name); + if (namedValue.get_type() != nbt::tag_type::String) { return nullopt; } - auto & tag_str = namedValue.as(); + auto& tag_str = namedValue.as(); return QString::fromStdString(tag_str.get()); - } - catch (const std::out_of_range &e) - { + } catch (const std::out_of_range& e) { // fallback for old world formats qWarning() << "String NBT tag" << name << "could not be found."; return nullopt; - } - catch (const std::bad_cast &e) - { + } catch (const std::bad_cast& e) { // type mismatch qWarning() << "NBT tag" << name << "could not be converted to string."; return nullopt; } } -optional read_long (nbt::value& parent, const char * name) +optional read_long(nbt::value& parent, const char* name) { - try - { - auto &namedValue = parent.at(name); - if(namedValue.get_type() != nbt::tag_type::Long) - { + try { + auto& namedValue = parent.at(name); + if (namedValue.get_type() != nbt::tag_type::Long) { return nullopt; } - auto & tag_str = namedValue.as(); + auto& tag_str = namedValue.as(); return tag_str.get(); - } - catch (const std::out_of_range &e) - { + } catch (const std::out_of_range& e) { // fallback for old world formats qWarning() << "Long NBT tag" << name << "could not be found."; return nullopt; - } - catch (const std::bad_cast &e) - { + } catch (const std::bad_cast& e) { // type mismatch qWarning() << "NBT tag" << name << "could not be converted to long."; return nullopt; } } -optional read_int (nbt::value& parent, const char * name) +optional read_int(nbt::value& parent, const char* name) { - try - { - auto &namedValue = parent.at(name); - if(namedValue.get_type() != nbt::tag_type::Int) - { + try { + auto& namedValue = parent.at(name); + if (namedValue.get_type() != nbt::tag_type::Int) { return nullopt; } - auto & tag_str = namedValue.as(); + auto& tag_str = namedValue.as(); return tag_str.get(); - } - catch (const std::out_of_range &e) - { + } catch (const std::out_of_range& e) { // fallback for old world formats qWarning() << "Int NBT tag" << name << "could not be found."; return nullopt; - } - catch (const std::bad_cast &e) - { + } catch (const std::bad_cast& e) { // type mismatch qWarning() << "NBT tag" << name << "could not be converted to int."; return nullopt; } } -GameType read_gametype(nbt::value& parent, const char * name) { +GameType read_gametype(nbt::value& parent, const char* name) +{ return GameType(read_int(parent, name)); } -} +} // namespace void World::loadFromLevelDat(QByteArray data) { auto levelData = parseLevelDat(data); - if(!levelData) - { + if (!levelData) { is_valid = false; return; } - nbt::value * valPtr = nullptr; + nbt::value* valPtr = nullptr; try { valPtr = &levelData->at("Data"); - } - catch (const std::out_of_range &e) { + } catch (const std::out_of_range& e) { qWarning() << "Unable to read NBT tags from " << m_folderName << ":" << e.what(); is_valid = false; return; } - nbt::value &val = *valPtr; + nbt::value& val = *valPtr; is_valid = val.get_type() == nbt::tag_type::Compound; - if(!is_valid) + if (!is_valid) return; auto name = read_string(val, "LevelName"); @@ -514,31 +458,30 @@ void World::loadFromLevelDat(QByteArray data) optional randomSeed; try { - auto &WorldGen_val = val.at("WorldGenSettings"); + auto& WorldGen_val = val.at("WorldGenSettings"); randomSeed = read_long(WorldGen_val, "seed"); + } catch (const std::out_of_range&) { } - catch (const std::out_of_range &) {} - if(!randomSeed) { + if (!randomSeed) { randomSeed = read_long(val, "RandomSeed"); } m_randomSeed = randomSeed ? *randomSeed : 0; qDebug() << "World Name:" << m_actualName; qDebug() << "Last Played:" << m_lastPlayed.toString(); - if(randomSeed) { + if (randomSeed) { qDebug() << "Seed:" << *randomSeed; } qDebug() << "Size:" << m_size; qDebug() << "GameType:" << m_gameType.toLogString(); } -bool World::replace(World &with) +bool World::replace(World& with) { if (!destroy()) return false; bool success = FS::copy(with.m_containerFile.filePath(), m_containerFile.path())(); - if (success) - { + if (success) { m_folderName = with.m_folderName; m_containerFile.refresh(); } @@ -547,25 +490,23 @@ bool World::replace(World &with) bool World::destroy() { - if(!is_valid) return false; + if (!is_valid) + return false; if (FS::trash(m_containerFile.filePath())) return true; - if (m_containerFile.isDir()) - { + if (m_containerFile.isDir()) { QDir d(m_containerFile.filePath()); return d.removeRecursively(); - } - else if(m_containerFile.isFile()) - { + } else if (m_containerFile.isFile()) { QFile file(m_containerFile.absoluteFilePath()); return file.remove(); } return true; } -bool World::operator==(const World &other) const +bool World::operator==(const World& other) const { return is_valid == other.is_valid && folderName() == other.folderName(); } @@ -585,8 +526,7 @@ bool World::isSymLinkUnder(const QString& instPath) const bool World::isMoreThanOneHardLink() const { - if (m_containerFile.isDir()) - { + if (m_containerFile.isDir()) { return FS::hardLinkCount(QDir(m_containerFile.absoluteFilePath()).filePath("level.dat")) > 1; } return FS::hardLinkCount(m_containerFile.absoluteFilePath()) > 1; diff --git a/launcher/minecraft/World.h b/launcher/minecraft/World.h index dc3733d5f..4303dc553 100644 --- a/launcher/minecraft/World.h +++ b/launcher/minecraft/World.h @@ -14,95 +14,57 @@ */ #pragma once -#include #include +#include #include struct GameType { GameType() = default; - GameType (std::optional original); + GameType(std::optional original); QString toTranslatedString() const; QString toLogString() const; - enum - { - Unknown = -1, - Survival, - Creative, - Adventure, - Spectator - } type = Unknown; + enum { Unknown = -1, Survival, Creative, Adventure, Spectator } type = Unknown; std::optional original; }; -class World -{ -public: - World(const QFileInfo &file); - QString folderName() const - { - return m_folderName; - } - QString name() const - { - return m_actualName; - } - QString iconFile() const - { - return m_iconFile; - } - int64_t bytes() const - { - return m_size; - } - QDateTime lastPlayed() const - { - return m_lastPlayed; - } - GameType gameType() const - { - return m_gameType; - } - int64_t seed() const - { - return m_randomSeed; - } - bool isValid() const - { - return is_valid; - } - bool isOnFS() const - { - return m_containerFile.isDir(); - } - QFileInfo container() const - { - return m_containerFile; - } +class World { + public: + World(const QFileInfo& file); + QString folderName() const { return m_folderName; } + QString name() const { return m_actualName; } + QString iconFile() const { return m_iconFile; } + int64_t bytes() const { return m_size; } + QDateTime lastPlayed() const { return m_lastPlayed; } + GameType gameType() const { return m_gameType; } + int64_t seed() const { return m_randomSeed; } + bool isValid() const { return is_valid; } + bool isOnFS() const { return m_containerFile.isDir(); } + QFileInfo container() const { return m_containerFile; } // delete all the files of this world bool destroy(); // replace this world with a copy of the other - bool replace(World &with); + bool replace(World& with); // change the world's filesystem path (used by world lists for *MAGIC* purposes) - void repath(const QFileInfo &file); + void repath(const QFileInfo& file); // remove the icon file, if any bool resetIcon(); - bool rename(const QString &to); - bool install(const QString &to, const QString &name= QString()); + bool rename(const QString& to); + bool install(const QString& to, const QString& name = QString()); // WEAK compare operator - used for replacing worlds - bool operator==(const World &other) const; + bool operator==(const World& other) const; - [[nodiscard]] auto isSymLink() const -> bool{ return m_containerFile.isSymLink(); } + [[nodiscard]] auto isSymLink() const -> bool { return m_containerFile.isSymLink(); } /** * @brief Take a instance path, checks if the file pointed to by the resource is a symlink or under a symlink in that instance - * + * * @param instPath path to an instance directory - * @return true - * @return false + * @return true + * @return false */ [[nodiscard]] bool isSymLinkUnder(const QString& instPath) const; @@ -110,13 +72,12 @@ public: QString canonicalFilePath() const { return m_containerFile.canonicalFilePath(); } -private: - void readFromZip(const QFileInfo &file); - void readFromFS(const QFileInfo &file); + private: + void readFromZip(const QFileInfo& file); + void readFromFS(const QFileInfo& file); void loadFromLevelDat(QByteArray data); -protected: - + protected: QFileInfo m_containerFile; QString m_containerOffsetPath; QString m_folderName; diff --git a/launcher/minecraft/WorldList.cpp b/launcher/minecraft/WorldList.cpp index 0feee2999..c55742eb7 100644 --- a/launcher/minecraft/WorldList.cpp +++ b/launcher/minecraft/WorldList.cpp @@ -35,18 +35,17 @@ #include "WorldList.h" -#include "Application.h" #include -#include +#include +#include #include +#include #include #include -#include -#include -#include +#include +#include "Application.h" -WorldList::WorldList(const QString &dir, BaseInstance* instance) - : QAbstractListModel(), m_instance(instance), m_dir(dir) +WorldList::WorldList(const QString& dir, BaseInstance* instance) : QAbstractListModel(), m_instance(instance), m_dir(dir) { FS::ensureFolderPathExists(m_dir.absolutePath()); m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); @@ -58,35 +57,27 @@ WorldList::WorldList(const QString &dir, BaseInstance* instance) void WorldList::startWatching() { - if(is_watching) - { + if (is_watching) { return; } update(); is_watching = m_watcher->addPath(m_dir.absolutePath()); - if (is_watching) - { + if (is_watching) { qDebug() << "Started watching " << m_dir.absolutePath(); - } - else - { + } else { qDebug() << "Failed to start watching " << m_dir.absolutePath(); } } void WorldList::stopWatching() { - if(!is_watching) - { + if (!is_watching) { return; } is_watching = !m_watcher->removePath(m_dir.absolutePath()); - if (!is_watching) - { + if (!is_watching) { qDebug() << "Stopped watching " << m_dir.absolutePath(); - } - else - { + } else { qDebug() << "Failed to stop watching " << m_dir.absolutePath(); } } @@ -100,14 +91,12 @@ bool WorldList::update() m_dir.refresh(); auto folderContents = m_dir.entryInfoList(); // if there are any untracked files... - for (QFileInfo entry : folderContents) - { - if(!entry.isDir()) + for (QFileInfo entry : folderContents) { + if (!entry.isDir()) continue; World w(entry); - if(w.isValid()) - { + if (w.isValid()) { newWorlds.append(w); } } @@ -127,7 +116,8 @@ bool WorldList::isValid() return m_dir.exists() && m_dir.isReadable(); } -QString WorldList::instDirPath() const { +QString WorldList::instDirPath() const +{ return QFileInfo(m_instance->instanceRoot()).absoluteFilePath(); } @@ -135,9 +125,8 @@ bool WorldList::deleteWorld(int index) { if (index >= worlds.size() || index < 0) return false; - World &m = worlds[index]; - if (m.destroy()) - { + World& m = worlds[index]; + if (m.destroy()) { beginRemoveRows(QModelIndex(), index, index); worlds.removeAt(index); endRemoveRows(); @@ -149,9 +138,8 @@ bool WorldList::deleteWorld(int index) bool WorldList::deleteWorlds(int first, int last) { - for (int i = first; i <= last; i++) - { - World &m = worlds[i]; + for (int i = first; i <= last; i++) { + World& m = worlds[i]; m.destroy(); } beginRemoveRows(QModelIndex(), first, last); @@ -165,21 +153,20 @@ bool WorldList::resetIcon(int row) { if (row >= worlds.size() || row < 0) return false; - World &m = worlds[row]; - if(m.resetIcon()) { - emit dataChanged(index(row), index(row), {WorldList::IconFileRole}); + World& m = worlds[row]; + if (m.resetIcon()) { + emit dataChanged(index(row), index(row), { WorldList::IconFileRole }); return true; } return false; } - -int WorldList::columnCount(const QModelIndex &parent) const +int WorldList::columnCount(const QModelIndex& parent) const { - return parent.isValid()? 0 : 5; + return parent.isValid() ? 0 : 5; } -QVariant WorldList::data(const QModelIndex &index, int role) const +QVariant WorldList::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -192,133 +179,120 @@ QVariant WorldList::data(const QModelIndex &index, int role) const QLocale locale; - auto & world = worlds[row]; - switch (role) - { - case Qt::DisplayRole: - switch (column) - { - case NameColumn: + auto& world = worlds[row]; + switch (role) { + case Qt::DisplayRole: + switch (column) { + case NameColumn: + return world.name(); + + case GameModeColumn: + return world.gameType().toTranslatedString(); + + case LastPlayedColumn: + return world.lastPlayed(); + + case SizeColumn: + return locale.formattedDataSize(world.bytes()); + + case InfoColumn: + if (world.isSymLinkUnder(instDirPath())) { + return tr("This world is symbolically linked from elsewhere."); + } + if (world.isMoreThanOneHardLink()) { + return tr("\nThis world is hard linked elsewhere."); + } + return ""; + default: + return QVariant(); + } + + case Qt::UserRole: + switch (column) { + case SizeColumn: + return QVariant::fromValue(world.bytes()); + + default: + return data(index, Qt::DisplayRole); + } + + case Qt::ToolTipRole: { + if (column == InfoColumn) { + if (world.isSymLinkUnder(instDirPath())) { + return tr("Warning: This world is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(world.canonicalFilePath()); + } + if (world.isMoreThanOneHardLink()) { + return tr("Warning: This world is hard linked elsewhere. Editing it will also change the original."); + } + } + return world.folderName(); + } + case ObjectRole: { + return QVariant::fromValue((void*)&world); + } + case FolderRole: { + return QDir::toNativeSeparators(dir().absoluteFilePath(world.folderName())); + } + case SeedRole: { + return QVariant::fromValue(world.seed()); + } + case NameRole: { return world.name(); - - case GameModeColumn: - return world.gameType().toTranslatedString(); - - case LastPlayedColumn: + } + case LastPlayedRole: { return world.lastPlayed(); - - case SizeColumn: - return locale.formattedDataSize(world.bytes()); - - case InfoColumn: - if (world.isSymLinkUnder(instDirPath())) { - return tr("This world is symbolically linked from elsewhere."); - } - if (world.isMoreThanOneHardLink()) { - return tr("\nThis world is hard linked elsewhere."); - } - return ""; + } + case SizeRole: { + return QVariant::fromValue(world.bytes()); + } + case IconFileRole: { + return world.iconFile(); + } default: return QVariant(); - } - - case Qt::UserRole: - switch (column) - { - case SizeColumn: - return QVariant::fromValue(world.bytes()); - - default: - return data(index, Qt::DisplayRole); - } - - case Qt::ToolTipRole: - { - if (column == InfoColumn) { - if (world.isSymLinkUnder(instDirPath())) { - return tr("Warning: This world is symbolically linked from elsewhere. Editing it will also change the original." - "\nCanonical Path: %1").arg(world.canonicalFilePath()); - } - if (world.isMoreThanOneHardLink()) { - return tr("Warning: This world is hard linked elsewhere. Editing it will also change the original."); - } - } - return world.folderName(); - } - case ObjectRole: - { - return QVariant::fromValue((void *)&world); - } - case FolderRole: - { - return QDir::toNativeSeparators(dir().absoluteFilePath(world.folderName())); - } - case SeedRole: - { - return QVariant::fromValue(world.seed()); - } - case NameRole: - { - return world.name(); - } - case LastPlayedRole: - { - return world.lastPlayed(); - } - case SizeRole: - { - return QVariant::fromValue(world.bytes()); - } - case IconFileRole: - { - return world.iconFile(); - } - default: - return QVariant(); } } QVariant WorldList::headerData(int section, Qt::Orientation orientation, int role) const { - switch (role) - { - case Qt::DisplayRole: - switch (section) - { - case NameColumn: - return tr("Name"); - case GameModeColumn: - return tr("Game Mode"); - case LastPlayedColumn: - return tr("Last Played"); - case SizeColumn: - //: World size on disk - return tr("Size"); - case InfoColumn: - //: special warnings? - return tr("Info"); - default: - return QVariant(); - } + switch (role) { + case Qt::DisplayRole: + switch (section) { + case NameColumn: + return tr("Name"); + case GameModeColumn: + return tr("Game Mode"); + case LastPlayedColumn: + return tr("Last Played"); + case SizeColumn: + //: World size on disk + return tr("Size"); + case InfoColumn: + //: special warnings? + return tr("Info"); + default: + return QVariant(); + } - case Qt::ToolTipRole: - switch (section) - { - case NameColumn: - return tr("The name of the world."); - case GameModeColumn: - return tr("Game mode of the world."); - case LastPlayedColumn: - return tr("Date and time the world was last played."); - case SizeColumn: - return tr("Size of the world on disk."); - case InfoColumn: - return tr("Information and warnings about the world."); + case Qt::ToolTipRole: + switch (section) { + case NameColumn: + return tr("The name of the world."); + case GameModeColumn: + return tr("Game mode of the world."); + case LastPlayedColumn: + return tr("Date and time the world was last played."); + case SizeColumn: + return tr("Size of the world on disk."); + case InfoColumn: + return tr("Information and warnings about the world."); + default: + return QVariant(); + } default: return QVariant(); - } - default: - return QVariant(); } return QVariant(); } @@ -330,32 +304,23 @@ QStringList WorldList::mimeTypes() const return types; } -class WorldMimeData : public QMimeData -{ -Q_OBJECT +class WorldMimeData : public QMimeData { + Q_OBJECT -public: - WorldMimeData(QList worlds) - { - m_worlds = worlds; + public: + WorldMimeData(QList worlds) { m_worlds = worlds; } + QStringList formats() const { return QMimeData::formats() << "text/uri-list"; } - } - QStringList formats() const - { - return QMimeData::formats() << "text/uri-list"; - } - -protected: + protected: #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - QVariant retrieveData(const QString &mimetype, QMetaType type) const + QVariant retrieveData(const QString& mimetype, QMetaType type) const #else - QVariant retrieveData(const QString &mimetype, QVariant::Type type) const + QVariant retrieveData(const QString& mimetype, QVariant::Type type) const #endif { QList urls; - for(auto &world: m_worlds) - { - if(!world.isValid() || !world.isOnFS()) + for (auto& world : m_worlds) { + if (!world.isValid() || !world.isOnFS()) continue; QString worldPath = world.container().absoluteFilePath(); qDebug() << worldPath; @@ -364,38 +329,36 @@ protected: const_cast(this)->setUrls(urls); return QMimeData::retrieveData(mimetype, type); } -private: + + private: QList m_worlds; }; -QMimeData *WorldList::mimeData(const QModelIndexList &indexes) const +QMimeData* WorldList::mimeData(const QModelIndexList& indexes) const { if (indexes.size() == 0) return new QMimeData(); QList worlds; - for(auto idx : indexes) - { - if(idx.column() != 0) + for (auto idx : indexes) { + if (idx.column() != 0) continue; int row = idx.row(); if (row < 0 || row >= this->worlds.size()) continue; worlds.append(this->worlds[row]); } - if(!worlds.size()) - { + if (!worlds.size()) { return new QMimeData(); } return new WorldMimeData(worlds); } -Qt::ItemFlags WorldList::flags(const QModelIndex &index) const +Qt::ItemFlags WorldList::flags(const QModelIndex& index) const { Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index); if (index.isValid()) - return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | - defaultFlags; + return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; else return Qt::ItemIsDropEnabled | defaultFlags; } @@ -416,15 +379,17 @@ void WorldList::installWorld(QFileInfo filename) { qDebug() << "installing: " << filename.absoluteFilePath(); World w(filename); - if(!w.isValid()) - { + if (!w.isValid()) { return; } w.install(m_dir.absolutePath()); } -bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column, - [[maybe_unused]] const QModelIndex &parent) +bool WorldList::dropMimeData(const QMimeData* data, + Qt::DropAction action, + [[maybe_unused]] int row, + [[maybe_unused]] int column, + [[maybe_unused]] const QModelIndex& parent) { if (action == Qt::IgnoreAction) return true; @@ -432,14 +397,12 @@ bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[may if (!data || !(action & supportedDropActions())) return false; // files dropped from outside? - if (data->hasUrls()) - { + if (data->hasUrls()) { bool was_watching = is_watching; if (was_watching) stopWatching(); auto urls = data->urls(); - for (auto url : urls) - { + for (auto url : urls) { // only local files may be dropped... if (!url.isLocalFile()) continue; @@ -447,8 +410,7 @@ bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[may QFileInfo worldInfo(filename); - if(!m_dir.entryInfoList().contains(worldInfo)) - { + if (!m_dir.entryInfoList().contains(worldInfo)) { installWorld(worldInfo); } } diff --git a/launcher/minecraft/WorldList.h b/launcher/minecraft/WorldList.h index 96b64193f..bea24bb9a 100644 --- a/launcher/minecraft/WorldList.h +++ b/launcher/minecraft/WorldList.h @@ -15,65 +15,34 @@ #pragma once -#include -#include -#include #include +#include +#include #include -#include "minecraft/World.h" +#include #include "BaseInstance.h" +#include "minecraft/World.h" class QFileSystemWatcher; -class WorldList : public QAbstractListModel -{ +class WorldList : public QAbstractListModel { Q_OBJECT -public: - enum Columns - { - NameColumn, - GameModeColumn, - LastPlayedColumn, - SizeColumn, - InfoColumn - }; + public: + enum Columns { NameColumn, GameModeColumn, LastPlayedColumn, SizeColumn, InfoColumn }; - enum Roles - { - ObjectRole = Qt::UserRole + 1, - FolderRole, - SeedRole, - NameRole, - GameModeRole, - LastPlayedRole, - SizeRole, - IconFileRole - }; + enum Roles { ObjectRole = Qt::UserRole + 1, FolderRole, SeedRole, NameRole, GameModeRole, LastPlayedRole, SizeRole, IconFileRole }; - WorldList(const QString &dir, BaseInstance* instance); + WorldList(const QString& dir, BaseInstance* instance); - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const - { - return parent.isValid() ? 0 : static_cast(size()); - }; - virtual QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &parent) const; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const { return parent.isValid() ? 0 : static_cast(size()); }; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex& parent) const; - size_t size() const - { - return worlds.size(); - }; - bool empty() const - { - return size() == 0; - } - World &operator[](size_t index) - { - return worlds[index]; - } + size_t size() const { return worlds.size(); }; + bool empty() const { return size() == 0; } + World& operator[](size_t index) { return worlds[index]; } /// Reloads the mod list and returns true if the list changed. virtual bool update(); @@ -91,13 +60,13 @@ public: virtual bool deleteWorlds(int first, int last); /// flags, mostly to support drag&drop - virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual Qt::ItemFlags flags(const QModelIndex& index) const; /// get data for drag action - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; + virtual QMimeData* mimeData(const QModelIndexList& indexes) const; /// get the supported mime types virtual QStringList mimeTypes() const; /// process data from drop action - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); /// what drag actions do we support? virtual Qt::DropActions supportedDragActions() const; @@ -109,27 +78,21 @@ public: virtual bool isValid(); - QDir dir() const - { - return m_dir; - } + QDir dir() const { return m_dir; } QString instDirPath() const; - const QList &allWorlds() const - { - return worlds; - } + const QList& allWorlds() const { return worlds; } -private slots: + private slots: void directoryChanged(QString path); -signals: + signals: void changed(); -protected: + protected: BaseInstance* m_instance; - QFileSystemWatcher *m_watcher; + QFileSystemWatcher* m_watcher; bool is_watching; QDir m_dir; QList worlds; diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp index 0b78cb0c1..b621a68c8 100644 --- a/launcher/minecraft/auth/AccountData.cpp +++ b/launcher/minecraft/auth/AccountData.cpp @@ -34,87 +34,90 @@ */ #include "AccountData.h" +#include +#include #include #include -#include -#include -#include #include +#include namespace { -void tokenToJSONV3(QJsonObject &parent, Katabasis::Token t, const char * tokenName) { - if(!t.persistent) { +void tokenToJSONV3(QJsonObject& parent, Katabasis::Token t, const char* tokenName) +{ + if (!t.persistent) { return; } QJsonObject out; - if(t.issueInstant.isValid()) { + if (t.issueInstant.isValid()) { out["iat"] = QJsonValue(t.issueInstant.toMSecsSinceEpoch() / 1000); } - if(t.notAfter.isValid()) { + if (t.notAfter.isValid()) { out["exp"] = QJsonValue(t.notAfter.toMSecsSinceEpoch() / 1000); } bool save = false; - if(!t.token.isEmpty()) { + if (!t.token.isEmpty()) { out["token"] = QJsonValue(t.token); save = true; } - if(!t.refresh_token.isEmpty()) { + if (!t.refresh_token.isEmpty()) { out["refresh_token"] = QJsonValue(t.refresh_token); save = true; } - if(t.extra.size()) { + if (t.extra.size()) { out["extra"] = QJsonObject::fromVariantMap(t.extra); save = true; } - if(save) { + if (save) { parent[tokenName] = out; } } -Katabasis::Token tokenFromJSONV3(const QJsonObject &parent, const char * tokenName) { +Katabasis::Token tokenFromJSONV3(const QJsonObject& parent, const char* tokenName) +{ Katabasis::Token out; auto tokenObject = parent.value(tokenName).toObject(); - if(tokenObject.isEmpty()) { + if (tokenObject.isEmpty()) { return out; } auto issueInstant = tokenObject.value("iat"); - if(issueInstant.isDouble()) { - out.issueInstant = QDateTime::fromMSecsSinceEpoch(((int64_t) issueInstant.toDouble()) * 1000); + if (issueInstant.isDouble()) { + out.issueInstant = QDateTime::fromMSecsSinceEpoch(((int64_t)issueInstant.toDouble()) * 1000); } auto notAfter = tokenObject.value("exp"); - if(notAfter.isDouble()) { - out.notAfter = QDateTime::fromMSecsSinceEpoch(((int64_t) notAfter.toDouble()) * 1000); + if (notAfter.isDouble()) { + out.notAfter = QDateTime::fromMSecsSinceEpoch(((int64_t)notAfter.toDouble()) * 1000); } auto token = tokenObject.value("token"); - if(token.isString()) { + if (token.isString()) { out.token = token.toString(); out.validity = Katabasis::Validity::Assumed; } auto refresh_token = tokenObject.value("refresh_token"); - if(refresh_token.isString()) { + if (refresh_token.isString()) { out.refresh_token = refresh_token.toString(); } auto extra = tokenObject.value("extra"); - if(extra.isObject()) { + if (extra.isObject()) { out.extra = extra.toObject().toVariantMap(); } return out; } -void profileToJSONV3(QJsonObject &parent, MinecraftProfile p, const char * tokenName) { - if(p.id.isEmpty()) { +void profileToJSONV3(QJsonObject& parent, MinecraftProfile p, const char* tokenName) +{ + if (p.id.isEmpty()) { return; } QJsonObject out; out["id"] = QJsonValue(p.id); out["name"] = QJsonValue(p.name); - if(!p.currentCape.isEmpty()) { + if (!p.currentCape.isEmpty()) { out["cape"] = p.currentCape; } @@ -123,19 +126,19 @@ void profileToJSONV3(QJsonObject &parent, MinecraftProfile p, const char * token skinObj["id"] = p.skin.id; skinObj["url"] = p.skin.url; skinObj["variant"] = p.skin.variant; - if(p.skin.data.size()) { + if (p.skin.data.size()) { skinObj["data"] = QString::fromLatin1(p.skin.data.toBase64()); } out["skin"] = skinObj; } QJsonArray capesArray; - for(auto & cape: p.capes) { + for (auto& cape : p.capes) { QJsonObject capeObj; capeObj["id"] = cape.id; capeObj["url"] = cape.url; capeObj["alias"] = cape.alias; - if(cape.data.size()) { + if (cape.data.size()) { capeObj["data"] = QString::fromLatin1(cape.data.toBase64()); } capesArray.push_back(capeObj); @@ -144,16 +147,17 @@ void profileToJSONV3(QJsonObject &parent, MinecraftProfile p, const char * token parent[tokenName] = out; } -MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * tokenName) { +MinecraftProfile profileFromJSONV3(const QJsonObject& parent, const char* tokenName) +{ MinecraftProfile out; auto tokenObject = parent.value(tokenName).toObject(); - if(tokenObject.isEmpty()) { + if (tokenObject.isEmpty()) { return out; } { auto idV = tokenObject.value("id"); auto nameV = tokenObject.value("name"); - if(!idV.isString() || !nameV.isString()) { + if (!idV.isString() || !nameV.isString()) { qWarning() << "mandatory profile attributes are missing or of unexpected type"; return MinecraftProfile(); } @@ -163,7 +167,7 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token { auto skinV = tokenObject.value("skin"); - if(!skinV.isObject()) { + if (!skinV.isObject()) { qWarning() << "skin is missing"; return MinecraftProfile(); } @@ -171,7 +175,7 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token auto idV = skinObj.value("id"); auto urlV = skinObj.value("url"); auto variantV = skinObj.value("variant"); - if(!idV.isString() || !urlV.isString() || !variantV.isString()) { + if (!idV.isString() || !urlV.isString() || !variantV.isString()) { qWarning() << "mandatory skin attributes are missing or of unexpected type"; return MinecraftProfile(); } @@ -181,11 +185,10 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token // data for skin is optional auto dataV = skinObj.value("data"); - if(dataV.isString()) { + if (dataV.isString()) { // TODO: validate base64 out.skin.data = QByteArray::fromBase64(dataV.toString().toLatin1()); - } - else if (!dataV.isUndefined()) { + } else if (!dataV.isUndefined()) { qWarning() << "skin data is something unexpected"; return MinecraftProfile(); } @@ -193,13 +196,13 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token { auto capesV = tokenObject.value("capes"); - if(!capesV.isArray()) { + if (!capesV.isArray()) { qWarning() << "capes is not an array!"; return MinecraftProfile(); } auto capesArray = capesV.toArray(); - for(auto capeV: capesArray) { - if(!capeV.isObject()) { + for (auto capeV : capesArray) { + if (!capeV.isObject()) { qWarning() << "cape is not an object!"; return MinecraftProfile(); } @@ -207,7 +210,7 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token auto idV = capeObj.value("id"); auto urlV = capeObj.value("url"); auto aliasV = capeObj.value("alias"); - if(!idV.isString() || !urlV.isString() || !aliasV.isString()) { + if (!idV.isString() || !urlV.isString() || !aliasV.isString()) { qWarning() << "mandatory skin attributes are missing or of unexpected type"; return MinecraftProfile(); } @@ -218,11 +221,10 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token // data for cape is optional. auto dataV = capeObj.value("data"); - if(dataV.isString()) { + if (dataV.isString()) { // TODO: validate base64 cape.data = QByteArray::fromBase64(dataV.toString().toLatin1()); - } - else if (!dataV.isUndefined()) { + } else if (!dataV.isUndefined()) { qWarning() << "cape data is something unexpected"; return MinecraftProfile(); } @@ -232,9 +234,9 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token // current cape { auto capeV = tokenObject.value("cape"); - if(capeV.isString()) { + if (capeV.isString()) { auto currentCape = capeV.toString(); - if(out.capes.contains(currentCape)) { + if (out.capes.contains(currentCape)) { out.currentCape = currentCape; } } @@ -243,8 +245,9 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token return out; } -void entitlementToJSONV3(QJsonObject &parent, MinecraftEntitlement p) { - if(p.validity == Katabasis::Validity::None) { +void entitlementToJSONV3(QJsonObject& parent, MinecraftEntitlement p) +{ + if (p.validity == Katabasis::Validity::None) { return; } QJsonObject out; @@ -253,15 +256,16 @@ void entitlementToJSONV3(QJsonObject &parent, MinecraftEntitlement p) { parent["entitlement"] = out; } -bool entitlementFromJSONV3(const QJsonObject &parent, MinecraftEntitlement & out) { +bool entitlementFromJSONV3(const QJsonObject& parent, MinecraftEntitlement& out) +{ auto entitlementObject = parent.value("entitlement").toObject(); - if(entitlementObject.isEmpty()) { + if (entitlementObject.isEmpty()) { return false; } { auto ownsMinecraftV = entitlementObject.value("ownsMinecraft"); auto canPlayMinecraftV = entitlementObject.value("canPlayMinecraft"); - if(!ownsMinecraftV.isBool() || !canPlayMinecraftV.isBool()) { + if (!ownsMinecraftV.isBool() || !canPlayMinecraftV.isBool()) { qWarning() << "mandatory attributes are missing or of unexpected type"; return false; } @@ -272,12 +276,12 @@ bool entitlementFromJSONV3(const QJsonObject &parent, MinecraftEntitlement & out return true; } -} +} // namespace -bool AccountData::resumeStateFromV2(QJsonObject data) { +bool AccountData::resumeStateFromV2(QJsonObject data) +{ // The JSON object must at least have a username for it to be valid. - if (!data.value("username").isString()) - { + if (!data.value("username").isString()) { qCritical() << "Can't load Mojang account info from JSON object. Username field is missing or of the wrong type."; return false; } @@ -287,14 +291,12 @@ bool AccountData::resumeStateFromV2(QJsonObject data) { QString accessToken = data.value("accessToken").toString(""); QJsonArray profileArray = data.value("profiles").toArray(); - if (profileArray.size() < 1) - { + if (profileArray.size() < 1) { qCritical() << "Can't load Mojang account with username \"" << userName << "\". No profiles found."; return false; } - struct AccountProfile - { + struct AccountProfile { QString id; QString name; bool legacy; @@ -304,24 +306,22 @@ bool AccountData::resumeStateFromV2(QJsonObject data) { int currentProfileIndex = 0; int index = -1; QString currentProfile = data.value("activeProfile").toString(""); - for (QJsonValue profileVal : profileArray) - { + for (QJsonValue profileVal : profileArray) { index++; QJsonObject profileObject = profileVal.toObject(); QString id = profileObject.value("id").toString(""); QString name = profileObject.value("name").toString(""); bool legacy = profileObject.value("legacy").toBool(false); - if (id.isEmpty() || name.isEmpty()) - { + if (id.isEmpty() || name.isEmpty()) { qWarning() << "Unable to load a profile" << name << "because it was missing an ID or a name."; continue; } - if(id == currentProfile) { + if (id == currentProfile) { currentProfileIndex = index; } - profiles.append({id, name, legacy}); + profiles.append({ id, name, legacy }); } - auto & profile = profiles[currentProfileIndex]; + auto& profile = profiles[currentProfileIndex]; type = AccountType::Mojang; legacy = profile.legacy; @@ -339,14 +339,15 @@ bool AccountData::resumeStateFromV2(QJsonObject data) { return true; } -bool AccountData::resumeStateFromV3(QJsonObject data) { +bool AccountData::resumeStateFromV3(QJsonObject data) +{ auto typeV = data.value("type"); - if(!typeV.isString()) { + if (!typeV.isString()) { qWarning() << "Failed to parse account data: type is missing."; return false; } auto typeS = typeV.toString(); - if(typeS == "MSA") { + if (typeS == "MSA") { type = AccountType::MSA; } else if (typeS == "Mojang") { type = AccountType::Mojang; @@ -357,16 +358,16 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { return false; } - if(type == AccountType::Mojang) { + if (type == AccountType::Mojang) { legacy = data.value("legacy").toBool(false); canMigrateToMSA = data.value("canMigrateToMSA").toBool(false); } - if(type == AccountType::MSA) { + if (type == AccountType::MSA) { auto clientIDV = data.value("msa-client-id"); if (clientIDV.isString()) { msaClientID = clientIDV.toString(); - } // leave msaClientID empty if it doesn't exist or isn't a string + } // leave msaClientID empty if it doesn't exist or isn't a string msaToken = tokenFromJSONV3(data, "msa"); userToken = tokenFromJSONV3(data, "utoken"); xboxApiToken = tokenFromJSONV3(data, "xrp-main"); @@ -379,8 +380,8 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { yggdrasilToken.token = "0"; minecraftProfile = profileFromJSONV3(data, "profile"); - if(!entitlementFromJSONV3(data, minecraftEntitlement)) { - if(minecraftProfile.validity != Katabasis::Validity::None) { + if (!entitlementFromJSONV3(data, minecraftEntitlement)) { + if (minecraftProfile.validity != Katabasis::Validity::None) { minecraftEntitlement.canPlayMinecraft = true; minecraftEntitlement.ownsMinecraft = true; minecraftEntitlement.validity = Katabasis::Validity::Assumed; @@ -391,26 +392,25 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { return true; } -QJsonObject AccountData::saveState() const { +QJsonObject AccountData::saveState() const +{ QJsonObject output; - if(type == AccountType::Mojang) { + if (type == AccountType::Mojang) { output["type"] = "Mojang"; - if(legacy) { + if (legacy) { output["legacy"] = true; } - if(canMigrateToMSA) { + if (canMigrateToMSA) { output["canMigrateToMSA"] = true; } - } - else if (type == AccountType::MSA) { + } else if (type == AccountType::MSA) { output["type"] = "MSA"; output["msa-client-id"] = msaClientID; tokenToJSONV3(output, msaToken, "msa"); tokenToJSONV3(output, userToken, "utoken"); tokenToJSONV3(output, xboxApiToken, "xrp-main"); tokenToJSONV3(output, mojangservicesToken, "xrp-mc"); - } - else if (type == AccountType::Offline) { + } else if (type == AccountType::Offline) { output["type"] = "Offline"; } @@ -420,60 +420,68 @@ QJsonObject AccountData::saveState() const { return output; } -QString AccountData::userName() const { - if(type == AccountType::MSA) { +QString AccountData::userName() const +{ + if (type == AccountType::MSA) { return QString(); } return yggdrasilToken.extra["userName"].toString(); } -QString AccountData::accessToken() const { +QString AccountData::accessToken() const +{ return yggdrasilToken.token; } -QString AccountData::clientToken() const { - if(type != AccountType::Mojang) { +QString AccountData::clientToken() const +{ + if (type != AccountType::Mojang) { return QString(); } return yggdrasilToken.extra["clientToken"].toString(); } -void AccountData::setClientToken(QString clientToken) { - if(type != AccountType::Mojang) { +void AccountData::setClientToken(QString clientToken) +{ + if (type != AccountType::Mojang) { return; } yggdrasilToken.extra["clientToken"] = clientToken; } -void AccountData::generateClientTokenIfMissing() { - if(yggdrasilToken.extra.contains("clientToken")) { +void AccountData::generateClientTokenIfMissing() +{ + if (yggdrasilToken.extra.contains("clientToken")) { return; } invalidateClientToken(); } -void AccountData::invalidateClientToken() { - if(type != AccountType::Mojang) { +void AccountData::invalidateClientToken() +{ + if (type != AccountType::Mojang) { return; } yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegularExpression("[{-}]")); } -QString AccountData::profileId() const { +QString AccountData::profileId() const +{ return minecraftProfile.id; } -QString AccountData::profileName() const { - if(minecraftProfile.name.size() == 0) { +QString AccountData::profileName() const +{ + if (minecraftProfile.name.size() == 0) { return QObject::tr("No profile (%1)").arg(accountDisplayString()); - } - else { + } else { return minecraftProfile.name; } } -QString AccountData::accountDisplayString() const { - switch(type) { +QString AccountData::accountDisplayString() const +{ + switch (type) { case AccountType::Mojang: { return userName(); } @@ -481,7 +489,7 @@ QString AccountData::accountDisplayString() const { return QObject::tr(""); } case AccountType::MSA: { - if(xboxApiToken.extra.contains("gtg")) { + if (xboxApiToken.extra.contains("gtg")) { return xboxApiToken.extra["gtg"].toString(); } return "Xbox profile missing"; @@ -492,6 +500,7 @@ QString AccountData::accountDisplayString() const { } } -QString AccountData::lastError() const { +QString AccountData::lastError() const +{ return errorString; } diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h index 092e1691d..38e3c3c90 100644 --- a/launcher/minecraft/auth/AccountData.h +++ b/launcher/minecraft/auth/AccountData.h @@ -34,11 +34,11 @@ */ #pragma once -#include -#include -#include #include +#include #include +#include +#include struct Skin { QString id; @@ -71,22 +71,9 @@ struct MinecraftProfile { Katabasis::Validity validity = Katabasis::Validity::None; }; -enum class AccountType { - MSA, - Mojang, - Offline -}; +enum class AccountType { MSA, Mojang, Offline }; -enum class AccountState { - Unchecked, - Offline, - Working, - Online, - Disabled, - Errored, - Expired, - Gone -}; +enum class AccountState { Unchecked, Offline, Working, Online, Disabled, Errored, Expired, Gone }; struct AccountData { QJsonObject saveState() const; diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index d6f42b75c..609eaa550 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -37,14 +37,14 @@ #include "AccountData.h" #include "AccountTask.h" -#include +#include #include -#include -#include +#include #include +#include #include #include -#include +#include #include #include @@ -54,12 +54,10 @@ #include -enum AccountListVersion { - MojangOnly = 2, - MojangMSA = 3 -}; +enum AccountListVersion { MojangOnly = 2, MojangMSA = 3 }; -AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) { +AccountList::AccountList(QObject* parent) : QAbstractListModel(parent) +{ m_refreshTimer = new QTimer(this); m_refreshTimer->setSingleShot(true); connect(m_refreshTimer, &QTimer::timeout, this, &AccountList::fillQueue); @@ -70,7 +68,8 @@ AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) { AccountList::~AccountList() noexcept {} -int AccountList::findAccountByProfileId(const QString& profileId) const { +int AccountList::findAccountByProfileId(const QString& profileId) const +{ for (int i = 0; i < count(); i++) { MinecraftAccountPtr account = at(i); if (account->profileId() == profileId) { @@ -80,7 +79,8 @@ int AccountList::findAccountByProfileId(const QString& profileId) const { return -1; } -MinecraftAccountPtr AccountList::getAccountByProfileName(const QString& profileName) const { +MinecraftAccountPtr AccountList::getAccountByProfileName(const QString& profileName) const +{ for (int i = 0; i < count(); i++) { MinecraftAccountPtr account = at(i); if (account->profileName() == profileName) { @@ -95,11 +95,12 @@ const MinecraftAccountPtr AccountList::at(int i) const return MinecraftAccountPtr(m_accounts.at(i)); } -QStringList AccountList::profileNames() const { +QStringList AccountList::profileNames() const +{ QStringList out; - for(auto & account: m_accounts) { - auto profileName = account->profileName(); - if(profileName.isEmpty()) { + for (auto& account : m_accounts) { + auto profileName = account->profileName(); + if (profileName.isEmpty()) { continue; } out.append(profileName); @@ -122,14 +123,14 @@ void AccountList::addAccount(const MinecraftAccountPtr account) // override/replace existing account with the same profileId auto profileId = account->profileId(); - if(profileId.size()) { + if (profileId.size()) { auto existingAccount = findAccountByProfileId(profileId); - if(existingAccount != -1) { + if (existingAccount != -1) { qDebug() << "Replacing old account with a new one with the same profile ID!"; MinecraftAccountPtr existingAccountPtr = m_accounts[existingAccount]; m_accounts[existingAccount] = account; - if(m_defaultAccount == existingAccountPtr) { + if (m_defaultAccount == existingAccountPtr) { m_defaultAccount = account; } // disconnect notifications for changes in the account being replaced @@ -154,11 +155,9 @@ void AccountList::addAccount(const MinecraftAccountPtr account) void AccountList::removeAccount(QModelIndex index) { int row = index.row(); - if(index.isValid() && row >= 0 && row < m_accounts.size()) - { - auto & account = m_accounts[row]; - if(account == m_defaultAccount) - { + if (index.isValid() && row >= 0 && row < m_accounts.size()) { + auto& account = m_accounts[row]; + if (account == m_defaultAccount) { m_defaultAccount = nullptr; onDefaultAccountChanged(); } @@ -178,43 +177,34 @@ MinecraftAccountPtr AccountList::defaultAccount() const void AccountList::setDefaultAccount(MinecraftAccountPtr newAccount) { - if (!newAccount && m_defaultAccount) - { + if (!newAccount && m_defaultAccount) { int idx = 0; auto previousDefaultAccount = m_defaultAccount; m_defaultAccount = nullptr; - for (MinecraftAccountPtr account : m_accounts) - { - if (account == previousDefaultAccount) - { + for (MinecraftAccountPtr account : m_accounts) { + if (account == previousDefaultAccount) { emit dataChanged(index(idx), index(idx, columnCount(QModelIndex()) - 1)); } - idx ++; + idx++; } onDefaultAccountChanged(); - } - else - { + } else { auto currentDefaultAccount = m_defaultAccount; int currentDefaultAccountIdx = -1; auto newDefaultAccount = m_defaultAccount; int newDefaultAccountIdx = -1; int idx = 0; - for (MinecraftAccountPtr account : m_accounts) - { - if (account == newAccount) - { + for (MinecraftAccountPtr account : m_accounts) { + if (account == newAccount) { newDefaultAccount = account; newDefaultAccountIdx = idx; } - if(currentDefaultAccount == account) - { + if (currentDefaultAccount == account) { currentDefaultAccountIdx = idx; } idx++; } - if(currentDefaultAccount != newDefaultAccount) - { + if (currentDefaultAccount != newDefaultAccount) { emit dataChanged(index(currentDefaultAccountIdx), index(currentDefaultAccountIdx, columnCount(QModelIndex()) - 1)); emit dataChanged(index(newDefaultAccountIdx), index(newDefaultAccountIdx, columnCount(QModelIndex()) - 1)); m_defaultAccount = newDefaultAccount; @@ -231,27 +221,25 @@ void AccountList::accountChanged() void AccountList::accountActivityChanged(bool active) { - MinecraftAccount *account = qobject_cast(sender()); + MinecraftAccount* account = qobject_cast(sender()); bool found = false; for (int i = 0; i < count(); i++) { if (at(i).get() == account) { - emit dataChanged(index(i), index(i, columnCount(QModelIndex()) - 1)); + emit dataChanged(index(i), index(i, columnCount(QModelIndex()) - 1)); found = true; break; } } - if(found) { + if (found) { emit listActivityChanged(); - if(active) { + if (active) { beginActivity(); - } - else { + } else { endActivity(); } } } - void AccountList::onListChanged() { if (m_autosave) @@ -274,7 +262,7 @@ int AccountList::count() const return m_accounts.count(); } -QVariant AccountList::data(const QModelIndex &index, int role) const +QVariant AccountList::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -284,70 +272,67 @@ QVariant AccountList::data(const QModelIndex &index, int role) const MinecraftAccountPtr account = at(index.row()); - switch (role) - { + switch (role) { case Qt::DisplayRole: - switch (index.column()) - { - case ProfileNameColumn: { - return account->profileName(); - } + switch (index.column()) { + case ProfileNameColumn: { + return account->profileName(); + } - case NameColumn: - return account->accountDisplayString(); + case NameColumn: + return account->accountDisplayString(); - case TypeColumn: { - auto typeStr = account->typeString(); - typeStr[0] = typeStr[0].toUpper(); - return typeStr; - } + case TypeColumn: { + auto typeStr = account->typeString(); + typeStr[0] = typeStr[0].toUpper(); + return typeStr; + } - case StatusColumn: { - switch(account->accountState()) { - case AccountState::Unchecked: { - return tr("Unchecked", "Account status"); - } - case AccountState::Offline: { - return tr("Offline", "Account status"); - } - case AccountState::Online: { - return tr("Ready", "Account status"); - } - case AccountState::Working: { - return tr("Working", "Account status"); - } - case AccountState::Errored: { - return tr("Errored", "Account status"); - } - case AccountState::Expired: { - return tr("Expired", "Account status"); - } - case AccountState::Disabled: { - return tr("Disabled", "Account status"); - } - case AccountState::Gone: { - return tr("Gone", "Account status"); - } - default: { - return tr("Unknown", "Account status"); + case StatusColumn: { + switch (account->accountState()) { + case AccountState::Unchecked: { + return tr("Unchecked", "Account status"); + } + case AccountState::Offline: { + return tr("Offline", "Account status"); + } + case AccountState::Online: { + return tr("Ready", "Account status"); + } + case AccountState::Working: { + return tr("Working", "Account status"); + } + case AccountState::Errored: { + return tr("Errored", "Account status"); + } + case AccountState::Expired: { + return tr("Expired", "Account status"); + } + case AccountState::Disabled: { + return tr("Disabled", "Account status"); + } + case AccountState::Gone: { + return tr("Gone", "Account status"); + } + default: { + return tr("Unknown", "Account status"); + } } } - } - case MigrationColumn: { - if(account->isMSA() || account->isOffline()) { - return tr("N/A", "Can Migrate"); + case MigrationColumn: { + if (account->isMSA() || account->isOffline()) { + return tr("N/A", "Can Migrate"); + } + if (account->canMigrate()) { + return tr("Yes", "Can Migrate"); + } else { + return tr("No", "Can Migrate"); + } } - if (account->canMigrate()) { - return tr("Yes", "Can Migrate"); - } - else { - return tr("No", "Can Migrate"); - } - } - default: - return QVariant(); + default: + return QVariant(); } case Qt::ToolTipRole: @@ -362,7 +347,6 @@ QVariant AccountList::data(const QModelIndex &index, int role) const } else { return QVariant(); } - default: return QVariant(); @@ -371,79 +355,72 @@ QVariant AccountList::data(const QModelIndex &index, int role) const QVariant AccountList::headerData(int section, Qt::Orientation orientation, int role) const { - switch (role) - { - case Qt::DisplayRole: - switch (section) - { - case ProfileNameColumn: - return tr("Username"); - case NameColumn: - return tr("Account"); - case TypeColumn: - return tr("Type"); - case StatusColumn: - return tr("Status"); - case MigrationColumn: - return tr("Can Migrate?"); + switch (role) { + case Qt::DisplayRole: + switch (section) { + case ProfileNameColumn: + return tr("Username"); + case NameColumn: + return tr("Account"); + case TypeColumn: + return tr("Type"); + case StatusColumn: + return tr("Status"); + case MigrationColumn: + return tr("Can Migrate?"); + default: + return QVariant(); + } + + case Qt::ToolTipRole: + switch (section) { + case ProfileNameColumn: + return tr("Minecraft username associated with the account."); + case NameColumn: + return tr("User name of the account."); + case TypeColumn: + return tr("Type of the account - Mojang or MSA."); + case StatusColumn: + return tr("Current status of the account."); + case MigrationColumn: + return tr("Can this account migrate to a Microsoft account?"); + default: + return QVariant(); + } + default: return QVariant(); - } - - case Qt::ToolTipRole: - switch (section) - { - case ProfileNameColumn: - return tr("Minecraft username associated with the account."); - case NameColumn: - return tr("User name of the account."); - case TypeColumn: - return tr("Type of the account - Mojang or MSA."); - case StatusColumn: - return tr("Current status of the account."); - case MigrationColumn: - return tr("Can this account migrate to a Microsoft account?"); - default: - return QVariant(); - } - - default: - return QVariant(); } } -int AccountList::rowCount(const QModelIndex &parent) const +int AccountList::rowCount(const QModelIndex& parent) const { // Return count return parent.isValid() ? 0 : count(); } -int AccountList::columnCount(const QModelIndex &parent) const +int AccountList::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : NUM_COLUMNS; } -Qt::ItemFlags AccountList::flags(const QModelIndex &index) const +Qt::ItemFlags AccountList::flags(const QModelIndex& index) const { - if (index.row() < 0 || index.row() >= rowCount(index.parent()) || !index.isValid()) - { + if (index.row() < 0 || index.row() >= rowCount(index.parent()) || !index.isValid()) { return Qt::NoItemFlags; } return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -bool AccountList::setData(const QModelIndex &idx, const QVariant &value, int role) +bool AccountList::setData(const QModelIndex& idx, const QVariant& value, int role) { - if (idx.row() < 0 || idx.row() >= rowCount(idx) || !idx.isValid()) - { + if (idx.row() < 0 || idx.row() >= rowCount(idx) || !idx.isValid()) { return false; } - if(role == Qt::CheckStateRole) - { - if(value == Qt::Checked) - { + if (role == Qt::CheckStateRole) { + if (value == Qt::Checked) { MinecraftAccountPtr account = at(idx.row()); setDefaultAccount(account); } @@ -455,8 +432,7 @@ bool AccountList::setData(const QModelIndex &idx, const QVariant &value, int rol bool AccountList::loadList() { - if (m_listFilePath.isEmpty()) - { + if (m_listFilePath.isEmpty()) { qCritical() << "Can't load Mojang account list. No file path given and no default set."; return false; } @@ -465,8 +441,7 @@ bool AccountList::loadList() // Try to open the file and fail if we can't. // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::ReadOnly)) - { + if (!file.open(QIODevice::ReadOnly)) { qCritical() << QString("Failed to read the account list file (%1).").arg(m_listFilePath).toUtf8(); return false; } @@ -479,17 +454,15 @@ bool AccountList::loadList() QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); // Fail if the JSON is invalid. - if (parseError.error != QJsonParseError::NoError) - { + if (parseError.error != QJsonParseError::NoError) { qCritical() << QString("Failed to parse account list file: %1 at offset %2") - .arg(parseError.errorString(), QString::number(parseError.offset)) - .toUtf8(); + .arg(parseError.errorString(), QString::number(parseError.offset)) + .toUtf8(); return false; } // Make sure the root is an object. - if (!jsonDoc.isObject()) - { + if (!jsonDoc.isObject()) { qCritical() << "Invalid account list JSON: Root should be an array."; return false; } @@ -498,15 +471,13 @@ bool AccountList::loadList() // Make sure the format version matches. auto listVersion = root.value("formatVersion").toVariant().toInt(); - switch(listVersion) { + switch (listVersion) { case AccountListVersion::MojangOnly: { return loadV2(root); - } - break; + } break; case AccountListVersion::MojangMSA: { return loadV3(root); - } - break; + } break; default: { QString newName = "accounts-old.json"; qWarning() << "Unknown format version when loading account list. Existing one will be renamed to" << newName; @@ -517,21 +488,20 @@ bool AccountList::loadList() } } -bool AccountList::loadV2(QJsonObject& root) { +bool AccountList::loadV2(QJsonObject& root) +{ beginResetModel(); auto defaultUserName = root.value("activeAccount").toString(""); QJsonArray accounts = root.value("accounts").toArray(); - for (QJsonValue accountVal : accounts) - { + for (QJsonValue accountVal : accounts) { QJsonObject accountObj = accountVal.toObject(); MinecraftAccountPtr account = MinecraftAccount::loadFromJsonV2(accountObj); - if (account.get() != nullptr) - { + if (account.get() != nullptr) { auto profileId = account->profileId(); - if(!profileId.size()) { + if (!profileId.size()) { continue; } - if(findAccountByProfileId(profileId) != -1) { + if (findAccountByProfileId(profileId) != -1) { continue; } connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); @@ -540,9 +510,7 @@ bool AccountList::loadV2(QJsonObject& root) { if (defaultUserName.size() && account->mojangUserName() == defaultUserName) { m_defaultAccount = account; } - } - else - { + } else { qWarning() << "Failed to load an account."; } } @@ -550,30 +518,27 @@ bool AccountList::loadV2(QJsonObject& root) { return true; } -bool AccountList::loadV3(QJsonObject& root) { +bool AccountList::loadV3(QJsonObject& root) +{ beginResetModel(); QJsonArray accounts = root.value("accounts").toArray(); - for (QJsonValue accountVal : accounts) - { + for (QJsonValue accountVal : accounts) { QJsonObject accountObj = accountVal.toObject(); MinecraftAccountPtr account = MinecraftAccount::loadFromJsonV3(accountObj); - if (account.get() != nullptr) - { + if (account.get() != nullptr) { auto profileId = account->profileId(); - if(profileId.size()) { - if(findAccountByProfileId(profileId) != -1) { + if (profileId.size()) { + if (findAccountByProfileId(profileId) != -1) { continue; } } connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); - if(accountObj.value("active").toBool(false)) { + if (accountObj.value("active").toBool(false)) { m_defaultAccount = account; } - } - else - { + } else { qWarning() << "Failed to load an account."; } } @@ -581,23 +546,20 @@ bool AccountList::loadV3(QJsonObject& root) { return true; } - bool AccountList::saveList() { - if (m_listFilePath.isEmpty()) - { + if (m_listFilePath.isEmpty()) { qCritical() << "Can't save Mojang account list. No file path given and no default set."; return false; } // make sure the parent folder exists - if(!FS::ensureFilePathExists(m_listFilePath)) + if (!FS::ensureFilePathExists(m_listFilePath)) return false; // make sure the file wasn't overwritten with a folder before (fixes a bug) QFileInfo finfo(m_listFilePath); - if(finfo.isDir()) - { + if (finfo.isDir()) { QDir badDir(m_listFilePath); badDir.removeRecursively(); } @@ -613,10 +575,9 @@ bool AccountList::saveList() // Build a list of accounts. qDebug() << "Building account array."; QJsonArray accounts; - for (MinecraftAccountPtr account : m_accounts) - { + for (MinecraftAccountPtr account : m_accounts) { QJsonObject accountObj = account->saveToJson(); - if(m_defaultAccount == account) { + if (m_defaultAccount == account) { accountObj["active"] = true; } accounts.append(accountObj); @@ -634,20 +595,18 @@ bool AccountList::saveList() // Try to open the file and fail if we can't. // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::WriteOnly)) - { + if (!file.open(QIODevice::WriteOnly)) { qCritical() << QString("Failed to read the account list file (%1).").arg(m_listFilePath).toUtf8(); return false; } // Write the JSON to the file. file.write(doc.toJson()); - file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser); - if(file.commit()) { + file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser); + if (file.commit()) { qDebug() << "Saved account list to" << m_listFilePath; return true; - } - else { + } else { qDebug() << "Failed to save accounts to" << m_listFilePath; return false; } @@ -661,30 +620,29 @@ void AccountList::setListFilePath(QString path, bool autosave) bool AccountList::anyAccountIsValid() { - for(auto account: m_accounts) - { - if(account->ownsMinecraft()) { + for (auto account : m_accounts) { + if (account->ownsMinecraft()) { return true; } } return false; } -void AccountList::fillQueue() { - - if(m_defaultAccount && m_defaultAccount->shouldRefresh()) { +void AccountList::fillQueue() +{ + if (m_defaultAccount && m_defaultAccount->shouldRefresh()) { auto idToRefresh = m_defaultAccount->internalId(); m_refreshQueue.push_back(idToRefresh); qDebug() << "AccountList: Queued default account with internal ID " << idToRefresh << " to refresh first"; } - for(int i = 0; i < count(); i++) { + for (int i = 0; i < count(); i++) { auto account = at(i); - if(account == m_defaultAccount) { + if (account == m_defaultAccount) { continue; } - if(account->shouldRefresh()) { + if (account->shouldRefresh()) { auto idToRefresh = account->internalId(); queueRefresh(idToRefresh); } @@ -692,40 +650,43 @@ void AccountList::fillQueue() { tryNext(); } -void AccountList::requestRefresh(QString accountId) { +void AccountList::requestRefresh(QString accountId) +{ auto index = m_refreshQueue.indexOf(accountId); - if(index != -1) { + if (index != -1) { m_refreshQueue.removeAt(index); } m_refreshQueue.push_front(accountId); qDebug() << "AccountList: Pushed account with internal ID " << accountId << " to the front of the queue"; - if(!isActive()) { + if (!isActive()) { tryNext(); } } -void AccountList::queueRefresh(QString accountId) { - if(m_refreshQueue.indexOf(accountId) != -1) { +void AccountList::queueRefresh(QString accountId) +{ + if (m_refreshQueue.indexOf(accountId) != -1) { return; } m_refreshQueue.push_back(accountId); qDebug() << "AccountList: Queued account with internal ID " << accountId << " to refresh"; } - -void AccountList::tryNext() { +void AccountList::tryNext() +{ while (m_refreshQueue.length()) { auto accountId = m_refreshQueue.front(); m_refreshQueue.pop_front(); - for(int i = 0; i < count(); i++) { + for (int i = 0; i < count(); i++) { auto account = at(i); - if(account->internalId() == accountId) { + if (account->internalId() == accountId) { m_currentTask = account->refresh(); - if(m_currentTask) { + if (m_currentTask) { connect(m_currentTask.get(), &AccountTask::succeeded, this, &AccountList::authSucceeded); connect(m_currentTask.get(), &AccountTask::failed, this, &AccountList::authFailed); m_currentTask->start(); - qDebug() << "RefreshSchedule: Processing account " << account->accountDisplayString() << " with internal ID " << accountId; + qDebug() << "RefreshSchedule: Processing account " << account->accountDisplayString() << " with internal ID " + << accountId; return; } } @@ -736,38 +697,43 @@ void AccountList::tryNext() { m_refreshTimer->start(1000 * 3600); } -void AccountList::authSucceeded() { +void AccountList::authSucceeded() +{ qDebug() << "RefreshSchedule: Background account refresh succeeded"; m_currentTask.reset(); m_nextTimer->start(1000 * 20); } -void AccountList::authFailed(QString reason) { +void AccountList::authFailed(QString reason) +{ qDebug() << "RefreshSchedule: Background account refresh failed: " << reason; m_currentTask.reset(); m_nextTimer->start(1000 * 20); } -bool AccountList::isActive() const { +bool AccountList::isActive() const +{ return m_activityCount != 0; } -void AccountList::beginActivity() { +void AccountList::beginActivity() +{ bool activating = m_activityCount == 0; m_activityCount++; - if(activating) { + if (activating) { emit activityChanged(true); } } -void AccountList::endActivity() { - if(m_activityCount == 0) { +void AccountList::endActivity() +{ + if (m_activityCount == 0) { qWarning() << m_name << " - Activity count would become below zero"; return; } bool deactivating = m_activityCount == 1; m_activityCount--; - if(deactivating) { + if (deactivating) { emit activityChanged(false); } } diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h index a8c3529ac..30926d13f 100644 --- a/launcher/minecraft/auth/AccountList.h +++ b/launcher/minecraft/auth/AccountList.h @@ -37,26 +37,21 @@ #include "MinecraftAccount.h" -#include -#include #include +#include #include +#include /*! * List of available Mojang accounts. * This should be loaded in the background by Prism Launcher on startup. */ -class AccountList : public QAbstractListModel -{ +class AccountList : public QAbstractListModel { Q_OBJECT -public: - enum ModelRoles - { - PointerRole = 0x34B1CB48 - }; + public: + enum ModelRoles { PointerRole = 0x34B1CB48 }; - enum VListColumns - { + enum VListColumns { // TODO: Add icon column. ProfileNameColumn = 0, NameColumn, @@ -67,24 +62,24 @@ public: NUM_COLUMNS }; - explicit AccountList(QObject *parent = 0); + explicit AccountList(QObject* parent = 0); virtual ~AccountList() noexcept; const MinecraftAccountPtr at(int i) const; int count() const; //////// List Model Functions //////// - QVariant data(const QModelIndex &index, int role) const override; + QVariant data(const QModelIndex& index, int role) const override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - virtual int rowCount(const QModelIndex &parent) const override; - virtual int columnCount(const QModelIndex &parent) const override; - virtual Qt::ItemFlags flags(const QModelIndex &index) const override; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override; + virtual int rowCount(const QModelIndex& parent) const override; + virtual int columnCount(const QModelIndex& parent) const override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; + virtual bool setData(const QModelIndex& index, const QVariant& value, int role) override; void addAccount(const MinecraftAccountPtr account); void removeAccount(QModelIndex index); - int findAccountByProfileId(const QString &profileId) const; - MinecraftAccountPtr getAccountByProfileName(const QString &profileName) const; + int findAccountByProfileId(const QString& profileId) const; + MinecraftAccountPtr getAccountByProfileName(const QString& profileName) const; QStringList profileNames() const; // requesting a refresh pushes it to the front of the queue @@ -102,8 +97,8 @@ public: void setListFilePath(QString path, bool autosave = false); bool loadList(); - bool loadV2(QJsonObject &root); - bool loadV3(QJsonObject &root); + bool loadV2(QJsonObject& root); + bool loadV3(QJsonObject& root); bool saveList(); MinecraftAccountPtr defaultAccount() const; @@ -112,20 +107,20 @@ public: bool isActive() const; -protected: + protected: void beginActivity(); void endActivity(); -private: + private: const char* m_name; uint32_t m_activityCount = 0; -signals: + signals: void listChanged(); void listActivityChanged(); void defaultAccountChanged(); void activityChanged(bool active); -public slots: + public slots: /** * This is called when one of the accounts changes and the list needs to be updated */ @@ -141,16 +136,16 @@ public slots: */ void fillQueue(); -private slots: + private slots: void tryNext(); void authSucceeded(); void authFailed(QString reason); -protected: + protected: QList m_refreshQueue; - QTimer *m_refreshTimer; - QTimer *m_nextTimer; + QTimer* m_refreshTimer; + QTimer* m_nextTimer; shared_qobject_ptr m_currentTask; /*! @@ -178,4 +173,3 @@ protected: */ bool m_autosave = false; }; - diff --git a/launcher/minecraft/auth/AccountTask.cpp b/launcher/minecraft/auth/AccountTask.cpp index 4118c3c5d..896607197 100644 --- a/launcher/minecraft/auth/AccountTask.cpp +++ b/launcher/minecraft/auth/AccountTask.cpp @@ -36,43 +36,41 @@ #include "AccountTask.h" #include "MinecraftAccount.h" +#include +#include +#include +#include #include #include -#include -#include -#include -#include #include -AccountTask::AccountTask(AccountData *data, QObject *parent) - : Task(parent), m_data(data) +AccountTask::AccountTask(AccountData* data, QObject* parent) : Task(parent), m_data(data) { changeState(AccountTaskState::STATE_CREATED); } QString AccountTask::getStateMessage() const { - switch (m_taskState) - { - case AccountTaskState::STATE_CREATED: - return "Waiting..."; - case AccountTaskState::STATE_WORKING: - return tr("Sending request to auth servers..."); - case AccountTaskState::STATE_SUCCEEDED: - return tr("Authentication task succeeded."); - case AccountTaskState::STATE_OFFLINE: - return tr("Failed to contact the authentication server."); - case AccountTaskState::STATE_DISABLED: - return tr("Client ID has changed. New session needs to be created."); - case AccountTaskState::STATE_FAILED_SOFT: - return tr("Encountered an error during authentication."); - case AccountTaskState::STATE_FAILED_HARD: - return tr("Failed to authenticate. The session has expired."); - case AccountTaskState::STATE_FAILED_GONE: - return tr("Failed to authenticate. The account no longer exists."); - default: - return tr("..."); + switch (m_taskState) { + case AccountTaskState::STATE_CREATED: + return "Waiting..."; + case AccountTaskState::STATE_WORKING: + return tr("Sending request to auth servers..."); + case AccountTaskState::STATE_SUCCEEDED: + return tr("Authentication task succeeded."); + case AccountTaskState::STATE_OFFLINE: + return tr("Failed to contact the authentication server."); + case AccountTaskState::STATE_DISABLED: + return tr("Client ID has changed. New session needs to be created."); + case AccountTaskState::STATE_FAILED_SOFT: + return tr("Encountered an error during authentication."); + case AccountTaskState::STATE_FAILED_HARD: + return tr("Failed to authenticate. The session has expired."); + case AccountTaskState::STATE_FAILED_GONE: + return tr("Failed to authenticate. The account no longer exists."); + default: + return tr("..."); } } @@ -82,7 +80,7 @@ bool AccountTask::changeState(AccountTaskState newState, QString reason) // FIXME: virtual method invoked in constructor. // We want that behavior, but maybe make it less weird? setStatus(getStateMessage()); - switch(newState) { + switch (newState) { case AccountTaskState::STATE_CREATED: { m_data->errorString.clear(); return true; diff --git a/launcher/minecraft/auth/AccountTask.h b/launcher/minecraft/auth/AccountTask.h index 1bd6c59f3..68bbfe5fa 100644 --- a/launcher/minecraft/auth/AccountTask.h +++ b/launcher/minecraft/auth/AccountTask.h @@ -37,10 +37,10 @@ #include -#include -#include -#include #include +#include +#include +#include #include "MinecraftAccount.h" @@ -50,37 +50,32 @@ class QNetworkReply; * Enum for describing the state of the current task. * Used by the getStateMessage function to determine what the status message should be. */ -enum class AccountTaskState -{ +enum class AccountTaskState { STATE_CREATED, STATE_WORKING, STATE_SUCCEEDED, - STATE_DISABLED, //!< MSA Client ID has changed. Tell user to reloginn - STATE_FAILED_SOFT, //!< soft failure. authentication went through partially - STATE_FAILED_HARD, //!< hard failure. main tokens are invalid - STATE_FAILED_GONE, //!< hard failure. main tokens are invalid, and the account no longer exists - STATE_OFFLINE //!< soft failure. authentication failed in the first step in a 'soft' way + STATE_DISABLED, //!< MSA Client ID has changed. Tell user to reloginn + STATE_FAILED_SOFT, //!< soft failure. authentication went through partially + STATE_FAILED_HARD, //!< hard failure. main tokens are invalid + STATE_FAILED_GONE, //!< hard failure. main tokens are invalid, and the account no longer exists + STATE_OFFLINE //!< soft failure. authentication failed in the first step in a 'soft' way }; -class AccountTask : public Task -{ +class AccountTask : public Task { Q_OBJECT -public: - explicit AccountTask(AccountData * data, QObject *parent = 0); - virtual ~AccountTask() {}; + public: + explicit AccountTask(AccountData* data, QObject* parent = 0); + virtual ~AccountTask(){}; AccountTaskState m_taskState = AccountTaskState::STATE_CREATED; - AccountTaskState taskState() { - return m_taskState; - } + AccountTaskState taskState() { return m_taskState; } -signals: - void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); + signals: + void showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn); void hideVerificationUriAndCode(); -protected: - + protected: /** * Returns the state message for the given state. * Used to set the status message for the task. @@ -88,10 +83,10 @@ protected: */ virtual QString getStateMessage() const; -protected slots: + protected slots: // NOTE: true -> non-terminal state, false -> terminal state bool changeState(AccountTaskState newState, QString reason = QString()); -protected: - AccountData *m_data = nullptr; + protected: + AccountData* m_data = nullptr; }; diff --git a/launcher/minecraft/auth/AuthRequest.cpp b/launcher/minecraft/auth/AuthRequest.cpp index a21634b7a..bd48a059d 100644 --- a/launcher/minecraft/auth/AuthRequest.cpp +++ b/launcher/minecraft/auth/AuthRequest.cpp @@ -35,44 +35,44 @@ #include +#include #include #include -#include #include #include "Application.h" #include "AuthRequest.h" #include "katabasis/Globals.h" -AuthRequest::AuthRequest(QObject *parent): QObject(parent) { -} +AuthRequest::AuthRequest(QObject* parent) : QObject(parent) {} -AuthRequest::~AuthRequest() { -} +AuthRequest::~AuthRequest() {} -void AuthRequest::get(const QNetworkRequest &req, int timeout/* = 60*1000*/) { +void AuthRequest::get(const QNetworkRequest& req, int timeout /* = 60*1000*/) +{ setup(req, QNetworkAccessManager::GetOperation); reply_ = APPLICATION->network()->get(request_); status_ = Requesting; timedReplies_.add(new Katabasis::Reply(reply_, timeout)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(reply_, &QNetworkReply::errorOccurred, this, &AuthRequest::onRequestError); -#else // &QNetworkReply::error SIGNAL depricated +#else // &QNetworkReply::error SIGNAL depricated connect(reply_, QOverload::of(&QNetworkReply::error), this, &AuthRequest::onRequestError); #endif connect(reply_, &QNetworkReply::finished, this, &AuthRequest::onRequestFinished); connect(reply_, &QNetworkReply::sslErrors, this, &AuthRequest::onSslErrors); } -void AuthRequest::post(const QNetworkRequest &req, const QByteArray &data, int timeout/* = 60*1000*/) { +void AuthRequest::post(const QNetworkRequest& req, const QByteArray& data, int timeout /* = 60*1000*/) +{ setup(req, QNetworkAccessManager::PostOperation); data_ = data; status_ = Requesting; reply_ = APPLICATION->network()->post(request_, data_); timedReplies_.add(new Katabasis::Reply(reply_, timeout)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(reply_, &QNetworkReply::errorOccurred, this, &AuthRequest::onRequestError); -#else // &QNetworkReply::error SIGNAL depricated +#else // &QNetworkReply::error SIGNAL depricated connect(reply_, QOverload::of(&QNetworkReply::error), this, &AuthRequest::onRequestError); #endif connect(reply_, &QNetworkReply::finished, this, &AuthRequest::onRequestFinished); @@ -80,35 +80,39 @@ void AuthRequest::post(const QNetworkRequest &req, const QByteArray &data, int t connect(reply_, &QNetworkReply::uploadProgress, this, &AuthRequest::onUploadProgress); } -void AuthRequest::onRequestFinished() { +void AuthRequest::onRequestFinished() +{ if (status_ == Idle) { return; } - if (reply_ != qobject_cast(sender())) { + if (reply_ != qobject_cast(sender())) { return; } httpStatus_ = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); finish(); } -void AuthRequest::onRequestError(QNetworkReply::NetworkError error) { +void AuthRequest::onRequestError(QNetworkReply::NetworkError error) +{ qWarning() << "AuthRequest::onRequestError: Error" << (int)error; if (status_ == Idle) { return; } - if (reply_ != qobject_cast(sender())) { + if (reply_ != qobject_cast(sender())) { return; } errorString_ = reply_->errorString(); httpStatus_ = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); error_ = error; qWarning() << "AuthRequest::onRequestError: Error string: " << errorString_; - qWarning() << "AuthRequest::onRequestError: HTTP status" << httpStatus_ << reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); + qWarning() << "AuthRequest::onRequestError: HTTP status" << httpStatus_ + << reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); // QTimer::singleShot(10, this, SLOT(finish())); } -void AuthRequest::onSslErrors(QList errors) { +void AuthRequest::onSslErrors(QList errors) +{ int i = 1; for (auto error : errors) { qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString(); @@ -118,23 +122,25 @@ void AuthRequest::onSslErrors(QList errors) { } } -void AuthRequest::onUploadProgress(qint64 uploaded, qint64 total) { +void AuthRequest::onUploadProgress(qint64 uploaded, qint64 total) +{ if (status_ == Idle) { qWarning() << "AuthRequest::onUploadProgress: No pending request"; return; } - if (reply_ != qobject_cast(sender())) { + if (reply_ != qobject_cast(sender())) { return; } // Restart timeout because request in progress - Katabasis::Reply *o2Reply = timedReplies_.find(reply_); - if(o2Reply) { + Katabasis::Reply* o2Reply = timedReplies_.find(reply_); + if (o2Reply) { o2Reply->start(); } emit uploadProgress(uploaded, total); } -void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Operation operation, const QByteArray &verb) { +void AuthRequest::setup(const QNetworkRequest& req, QNetworkAccessManager::Operation operation, const QByteArray& verb) +{ request_ = req; operation_ = operation; url_ = req.url(); @@ -152,7 +158,8 @@ void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Opera httpStatus_ = 0; } -void AuthRequest::finish() { +void AuthRequest::finish() +{ QByteArray data; if (status_ == Idle) { qWarning() << "AuthRequest::finish: No pending request"; diff --git a/launcher/minecraft/auth/AuthRequest.h b/launcher/minecraft/auth/AuthRequest.h index 89f7a123e..84d2a7d68 100644 --- a/launcher/minecraft/auth/AuthRequest.h +++ b/launcher/minecraft/auth/AuthRequest.h @@ -1,27 +1,26 @@ #pragma once -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include "katabasis/Reply.h" /// Makes authentication requests. -class AuthRequest: public QObject { +class AuthRequest : public QObject { Q_OBJECT -public: - explicit AuthRequest(QObject *parent = 0); + public: + explicit AuthRequest(QObject* parent = 0); ~AuthRequest(); -public slots: - void get(const QNetworkRequest &req, int timeout = 60*1000); - void post(const QNetworkRequest &req, const QByteArray &data, int timeout = 60*1000); + public slots: + void get(const QNetworkRequest& req, int timeout = 60 * 1000); + void post(const QNetworkRequest& req, const QByteArray& data, int timeout = 60 * 1000); - -signals: + signals: /// Emitted when a request has been completed or failed. void finished(QNetworkReply::NetworkError error, QByteArray data, QList headers); @@ -29,7 +28,7 @@ signals: /// Emitted when an upload has progressed. void uploadProgress(qint64 bytesSent, qint64 bytesTotal); -protected slots: + protected slots: /// Handle request finished. void onRequestFinished(); @@ -46,25 +45,23 @@ protected slots: /// Handle upload progress. void onUploadProgress(qint64 uploaded, qint64 total); -public: + public: QNetworkReply::NetworkError error_; int httpStatus_ = 0; QString errorString_; -protected: - void setup(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &verb = QByteArray()); + protected: + void setup(const QNetworkRequest& request, QNetworkAccessManager::Operation operation, const QByteArray& verb = QByteArray()); - enum Status { - Idle, Requesting, ReRequesting - }; + enum Status { Idle, Requesting, ReRequesting }; QNetworkRequest request_; QByteArray data_; - QNetworkReply *reply_; + QNetworkReply* reply_; Status status_; QNetworkAccessManager::Operation operation_; QUrl url_; Katabasis::ReplyList timedReplies_; - QTimer *timer_; + QTimer* timer_; }; diff --git a/launcher/minecraft/auth/AuthSession.cpp b/launcher/minecraft/auth/AuthSession.cpp index 2c06beaa2..37534f983 100644 --- a/launcher/minecraft/auth/AuthSession.cpp +++ b/launcher/minecraft/auth/AuthSession.cpp @@ -1,7 +1,7 @@ #include "AuthSession.h" -#include #include #include +#include #include QString AuthSession::serializeUserProperties() @@ -16,13 +16,11 @@ QString AuthSession::serializeUserProperties() */ QJsonDocument value(userAttrs); return value.toJson(QJsonDocument::Compact); - } bool AuthSession::MakeOffline(QString offline_playername) { - if (status != PlayableOffline && status != PlayableOnline) - { + if (status != PlayableOffline && status != PlayableOnline) { return false; } session = "-"; @@ -32,7 +30,8 @@ bool AuthSession::MakeOffline(QString offline_playername) return true; } -void AuthSession::MakeDemo() { +void AuthSession::MakeDemo() +{ player_name = "Player"; demo = true; } diff --git a/launcher/minecraft/auth/AuthSession.h b/launcher/minecraft/auth/AuthSession.h index a75df506b..40519476d 100644 --- a/launcher/minecraft/auth/AuthSession.h +++ b/launcher/minecraft/auth/AuthSession.h @@ -1,22 +1,20 @@ #pragma once -#include #include +#include #include #include "QObjectPtr.h" class MinecraftAccount; class QNetworkAccessManager; -struct AuthSession -{ +struct AuthSession { bool MakeOffline(QString offline_playername); void MakeDemo(); QString serializeUserProperties(); - enum Status - { + enum Status { Undetermined, RequiresOAuth, RequiresPassword, @@ -45,7 +43,7 @@ struct AuthSession // Did the user request online mode? bool wants_online = true; - //Is this a demo session? + // Is this a demo session? bool demo = false; }; diff --git a/launcher/minecraft/auth/AuthStep.cpp b/launcher/minecraft/auth/AuthStep.cpp index ffa2581b6..6240cc549 100644 --- a/launcher/minecraft/auth/AuthStep.cpp +++ b/launcher/minecraft/auth/AuthStep.cpp @@ -1,7 +1,5 @@ #include "AuthStep.h" -AuthStep::AuthStep(AccountData *data) : QObject(nullptr), m_data(data) { -} +AuthStep::AuthStep(AccountData* data) : QObject(nullptr), m_data(data) {} AuthStep::~AuthStep() noexcept = default; - diff --git a/launcher/minecraft/auth/AuthStep.h b/launcher/minecraft/auth/AuthStep.h index 2a8dc2cac..becd9b0c5 100644 --- a/launcher/minecraft/auth/AuthStep.h +++ b/launcher/minecraft/auth/AuthStep.h @@ -1,33 +1,33 @@ #pragma once -#include #include #include +#include +#include "AccountTask.h" #include "QObjectPtr.h" #include "minecraft/auth/AccountData.h" -#include "AccountTask.h" class AuthStep : public QObject { Q_OBJECT -public: + public: using Ptr = shared_qobject_ptr; -public: - explicit AuthStep(AccountData *data); + public: + explicit AuthStep(AccountData* data); virtual ~AuthStep() noexcept; virtual QString describe() = 0; -public slots: + public slots: virtual void perform() = 0; virtual void rehydrate() = 0; -signals: + signals: void finished(AccountTaskState resultingState, QString message); - void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); + void showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn); void hideVerificationUriAndCode(); -protected: - AccountData *m_data; + protected: + AccountData* m_data; }; diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index 5d279af1c..e8422a6f3 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -38,12 +38,12 @@ #include "MinecraftAccount.h" #include -#include -#include #include +#include +#include #include #include -#include +#include #include @@ -53,28 +53,30 @@ #include "flows/Mojang.h" #include "flows/Offline.h" -MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) { +MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) +{ data.internalId = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]")); } - -MinecraftAccountPtr MinecraftAccount::loadFromJsonV2(const QJsonObject& json) { +MinecraftAccountPtr MinecraftAccount::loadFromJsonV2(const QJsonObject& json) +{ MinecraftAccountPtr account(new MinecraftAccount()); - if(account->data.resumeStateFromV2(json)) { + if (account->data.resumeStateFromV2(json)) { return account; } return nullptr; } -MinecraftAccountPtr MinecraftAccount::loadFromJsonV3(const QJsonObject& json) { +MinecraftAccountPtr MinecraftAccount::loadFromJsonV3(const QJsonObject& json) +{ MinecraftAccountPtr account(new MinecraftAccount()); - if(account->data.resumeStateFromV3(json)) { + if (account->data.resumeStateFromV3(json)) { return account; } return nullptr; } -MinecraftAccountPtr MinecraftAccount::createFromUsername(const QString &username) +MinecraftAccountPtr MinecraftAccount::createFromUsername(const QString& username) { auto account = makeShared(); account->data.type = AccountType::Mojang; @@ -90,7 +92,7 @@ MinecraftAccountPtr MinecraftAccount::createBlankMSA() return account; } -MinecraftAccountPtr MinecraftAccount::createOffline(const QString &username) +MinecraftAccountPtr MinecraftAccount::createOffline(const QString& username) { auto account = makeShared(); account->data.type = AccountType::Offline; @@ -107,19 +109,20 @@ MinecraftAccountPtr MinecraftAccount::createOffline(const QString &username) return account; } - QJsonObject MinecraftAccount::saveToJson() const { return data.saveState(); } -AccountState MinecraftAccount::accountState() const { +AccountState MinecraftAccount::accountState() const +{ return data.accountState; } -QPixmap MinecraftAccount::getFace() const { +QPixmap MinecraftAccount::getFace() const +{ QPixmap skinTexture; - if(!skinTexture.loadFromData(data.minecraftProfile.skin.data, "PNG")) { + if (!skinTexture.loadFromData(data.minecraftProfile.skin.data, "PNG")) { return QPixmap(); } QPixmap skin = QPixmap(8, 8); @@ -129,67 +132,68 @@ QPixmap MinecraftAccount::getFace() const { return skin.scaled(64, 64, Qt::KeepAspectRatio); } - -shared_qobject_ptr MinecraftAccount::login(QString password) { +shared_qobject_ptr MinecraftAccount::login(QString password) +{ Q_ASSERT(m_currentTask.get() == nullptr); m_currentTask.reset(new MojangLogin(&data, password)); connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded); connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed); - connect(m_currentTask.get(), &Task::aborted, this, [this]{ authFailed(tr("Aborted")); }); + connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); }); emit activityChanged(true); return m_currentTask; } -shared_qobject_ptr MinecraftAccount::loginMSA() { +shared_qobject_ptr MinecraftAccount::loginMSA() +{ Q_ASSERT(m_currentTask.get() == nullptr); m_currentTask.reset(new MSAInteractive(&data)); connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded); connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed); - connect(m_currentTask.get(), &Task::aborted, this, [this]{ authFailed(tr("Aborted")); }); + connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); }); emit activityChanged(true); return m_currentTask; } -shared_qobject_ptr MinecraftAccount::loginOffline() { +shared_qobject_ptr MinecraftAccount::loginOffline() +{ Q_ASSERT(m_currentTask.get() == nullptr); m_currentTask.reset(new OfflineLogin(&data)); connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded); connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed); - connect(m_currentTask.get(), &Task::aborted, this, [this]{ authFailed(tr("Aborted")); }); + connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); }); emit activityChanged(true); return m_currentTask; } -shared_qobject_ptr MinecraftAccount::refresh() { - if(m_currentTask) { +shared_qobject_ptr MinecraftAccount::refresh() +{ + if (m_currentTask) { return m_currentTask; } - if(data.type == AccountType::MSA) { + if (data.type == AccountType::MSA) { m_currentTask.reset(new MSASilent(&data)); - } - else if(data.type == AccountType::Offline) { + } else if (data.type == AccountType::Offline) { m_currentTask.reset(new OfflineRefresh(&data)); - } - else { + } else { m_currentTask.reset(new MojangRefresh(&data)); } connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded); connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed); - connect(m_currentTask.get(), &Task::aborted, this, [this]{ authFailed(tr("Aborted")); }); + connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); }); emit activityChanged(true); return m_currentTask; } -shared_qobject_ptr MinecraftAccount::currentTask() { +shared_qobject_ptr MinecraftAccount::currentTask() +{ return m_currentTask; } - void MinecraftAccount::authSucceeded() { m_currentTask.reset(); @@ -206,28 +210,24 @@ void MinecraftAccount::authFailed(QString reason) } case AccountTaskState::STATE_FAILED_SOFT: { // NOTE: this doesn't do much. There was an error of some sort. - } - break; + } break; case AccountTaskState::STATE_FAILED_HARD: { - if(isMSA()) { + if (isMSA()) { data.msaToken.token = QString(); data.msaToken.refresh_token = QString(); data.msaToken.validity = Katabasis::Validity::None; data.validity_ = Katabasis::Validity::None; - } - else { + } else { data.yggdrasilToken.token = QString(); data.yggdrasilToken.validity = Katabasis::Validity::None; data.validity_ = Katabasis::Validity::None; } emit changed(); - } - break; + } break; case AccountTaskState::STATE_FAILED_GONE: { data.validity_ = Katabasis::Validity::None; emit changed(); - } - break; + } break; case AccountTaskState::STATE_CREATED: case AccountTaskState::STATE_WORKING: case AccountTaskState::STATE_SUCCEEDED: { @@ -238,21 +238,23 @@ void MinecraftAccount::authFailed(QString reason) emit activityChanged(false); } -bool MinecraftAccount::isActive() const { +bool MinecraftAccount::isActive() const +{ return !m_currentTask.isNull(); } -bool MinecraftAccount::shouldRefresh() const { +bool MinecraftAccount::shouldRefresh() const +{ /* * Never refresh accounts that are being used by the game, it breaks the game session. * Always refresh accounts that have not been refreshed yet during this session. * Don't refresh broken accounts. * Refresh accounts that would expire in the next 12 hours (fresh token validity is 24 hours). */ - if(isInUse()) { + if (isInUse()) { return false; } - switch(data.validity_) { + switch (data.validity_) { case Katabasis::Validity::Certain: { break; } @@ -267,7 +269,7 @@ bool MinecraftAccount::shouldRefresh() const { auto issuedTimestamp = data.yggdrasilToken.issueInstant; auto expiresTimestamp = data.yggdrasilToken.notAfter; - if(!expiresTimestamp.isValid()) { + if (!expiresTimestamp.isValid()) { expiresTimestamp = issuedTimestamp.addSecs(24 * 3600); } if (now.secsTo(expiresTimestamp) < (12 * 3600)) { @@ -278,14 +280,12 @@ bool MinecraftAccount::shouldRefresh() const { void MinecraftAccount::fillSession(AuthSessionPtr session) { - if(ownsMinecraft() && !hasProfile()) { + if (ownsMinecraft() && !hasProfile()) { session->status = AuthSession::RequiresProfileSetup; - } - else { - if(session->wants_online) { + } else { + if (session->wants_online) { session->status = AuthSession::PlayableOnline; - } - else { + } else { session->status = AuthSession::PlayableOffline; } } @@ -303,12 +303,9 @@ void MinecraftAccount::fillSession(AuthSessionPtr session) session->uuid = data.profileId(); // 'legacy' or 'mojang', depending on account type session->user_type = typeString(); - if (!session->access_token.isEmpty()) - { + if (!session->access_token.isEmpty()) { session->session = "token:" + data.accessToken() + ":" + data.profileId(); - } - else - { + } else { session->session = "-"; } } @@ -316,8 +313,7 @@ void MinecraftAccount::fillSession(AuthSessionPtr session) void MinecraftAccount::decrementUses() { Usable::decrementUses(); - if(!isInUse()) - { + if (!isInUse()) { emit changed(); // FIXME: we now need a better way to identify accounts... qWarning() << "Profile" << data.profileId() << "is no longer in use."; @@ -328,39 +324,31 @@ void MinecraftAccount::incrementUses() { bool wasInUse = isInUse(); Usable::incrementUses(); - if(!wasInUse) - { + if (!wasInUse) { emit changed(); // FIXME: we now need a better way to identify accounts... qWarning() << "Profile" << data.profileId() << "is now in use."; } } -QUuid MinecraftAccount::uuidFromUsername(QString username) { +QUuid MinecraftAccount::uuidFromUsername(QString username) +{ auto input = QString("OfflinePlayer:%1").arg(username).toUtf8(); // basically a reimplementation of Java's UUID#nameUUIDFromBytes QByteArray digest = QCryptographicHash::hash(input, QCryptographicHash::Md5); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - auto bOr = [](QByteArray& array, int index, char value) { - array[index] = array.at(index) | value; - }; - auto bAnd = [](QByteArray& array, int index, char value) { - array[index] = array.at(index) & value; - }; + auto bOr = [](QByteArray& array, int index, char value) { array[index] = array.at(index) | value; }; + auto bAnd = [](QByteArray& array, int index, char value) { array[index] = array.at(index) & value; }; #else - auto bOr = [](QByteArray& array, qsizetype index, char value) { - array[index] |= value; - }; - auto bAnd = [](QByteArray& array, qsizetype index, char value) { - array[index] &= value; - }; + auto bOr = [](QByteArray& array, qsizetype index, char value) { array[index] |= value; }; + auto bAnd = [](QByteArray& array, qsizetype index, char value) { array[index] &= value; }; #endif - bAnd(digest, 6, (char) 0x0f); // clear version - bOr(digest, 6, (char) 0x30); // set to version 3 - bAnd(digest, 8, (char) 0x3f); // clear variant - bOr(digest, 8, (char) 0x80); // set to IETF variant + bAnd(digest, 6, (char)0x0f); // clear version + bOr(digest, 6, (char)0x30); // set to version 3 + bAnd(digest, 8, (char)0x3f); // clear variant + bOr(digest, 8, (char)0x80); // set to IETF variant return QUuid::fromRfc4122(digest); } diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h index 67623a5ab..395ca5498 100644 --- a/launcher/minecraft/auth/MinecraftAccount.h +++ b/launcher/minecraft/auth/MinecraftAccount.h @@ -35,20 +35,20 @@ #pragma once -#include -#include -#include #include -#include +#include #include +#include +#include #include +#include #include -#include "AuthSession.h" -#include "Usable.h" #include "AccountData.h" +#include "AuthSession.h" #include "QObjectPtr.h" +#include "Usable.h" class Task; class AccountTask; @@ -64,8 +64,7 @@ Q_DECLARE_METATYPE(MinecraftAccountPtr) * but we might as well add some things for it in Prism Launcher right now so * we don't have to rip the code to pieces to add it later. */ -struct AccountProfile -{ +struct AccountProfile { QString id; QString name; bool legacy; @@ -77,34 +76,30 @@ struct AccountProfile * Said information may include things such as that account's username, client token, and access * token if the user chose to stay logged in. */ -class MinecraftAccount : - public QObject, - public Usable -{ +class MinecraftAccount : public QObject, public Usable { Q_OBJECT -public: /* construction */ + public: /* construction */ //! Do not copy accounts. ever. - explicit MinecraftAccount(const MinecraftAccount &other, QObject *parent) = delete; + explicit MinecraftAccount(const MinecraftAccount& other, QObject* parent) = delete; //! Default constructor - explicit MinecraftAccount(QObject *parent = 0); + explicit MinecraftAccount(QObject* parent = 0); - static MinecraftAccountPtr createFromUsername(const QString &username); + static MinecraftAccountPtr createFromUsername(const QString& username); static MinecraftAccountPtr createBlankMSA(); - static MinecraftAccountPtr createOffline(const QString &username); + static MinecraftAccountPtr createOffline(const QString& username); - static MinecraftAccountPtr loadFromJsonV2(const QJsonObject &json); - static MinecraftAccountPtr loadFromJsonV3(const QJsonObject &json); + static MinecraftAccountPtr loadFromJsonV2(const QJsonObject& json); + static MinecraftAccountPtr loadFromJsonV3(const QJsonObject& json); static QUuid uuidFromUsername(QString username); //! Saves a MinecraftAccount to a JSON object and returns it. QJsonObject saveToJson() const; -public: /* manipulation */ - + public: /* manipulation */ /** * Attempt to login. Empty password means we use the token. * If the attempt fails because we already are performing some task, it returns false. @@ -119,70 +114,46 @@ public: /* manipulation */ shared_qobject_ptr currentTask(); -public: /* queries */ - QString internalId() const { - return data.internalId; - } + public: /* queries */ + QString internalId() const { return data.internalId; } - QString accountDisplayString() const { - return data.accountDisplayString(); - } + QString accountDisplayString() const { return data.accountDisplayString(); } - QString mojangUserName() const { - return data.userName(); - } + QString mojangUserName() const { return data.userName(); } - QString accessToken() const { - return data.accessToken(); - } + QString accessToken() const { return data.accessToken(); } - QString profileId() const { - return data.profileId(); - } + QString profileId() const { return data.profileId(); } - QString profileName() const { - return data.profileName(); - } + QString profileName() const { return data.profileName(); } bool isActive() const; - bool canMigrate() const { - return data.canMigrateToMSA; - } + bool canMigrate() const { return data.canMigrateToMSA; } - bool isMSA() const { - return data.type == AccountType::MSA; - } + bool isMSA() const { return data.type == AccountType::MSA; } - bool isOffline() const { - return data.type == AccountType::Offline; - } + bool isOffline() const { return data.type == AccountType::Offline; } - bool ownsMinecraft() const { - return data.minecraftEntitlement.ownsMinecraft; - } + bool ownsMinecraft() const { return data.minecraftEntitlement.ownsMinecraft; } - bool hasProfile() const { - return data.profileId().size() != 0; - } + bool hasProfile() const { return data.profileId().size() != 0; } - QString typeString() const { - switch(data.type) { + QString typeString() const + { + switch (data.type) { case AccountType::Mojang: { - if(data.legacy) { + if (data.legacy) { return "legacy"; } return "mojang"; - } - break; + } break; case AccountType::MSA: { return "msa"; - } - break; + } break; case AccountType::Offline: { return "offline"; - } - break; + } break; default: { return "unknown"; } @@ -194,19 +165,15 @@ public: /* queries */ //! Returns the current state of the account AccountState accountState() const; - AccountData * accountData() { - return &data; - } + AccountData* accountData() { return &data; } bool shouldRefresh() const; void fillSession(AuthSessionPtr session); - QString lastError() const { - return data.lastError(); - } + QString lastError() const { return data.lastError(); } -signals: + signals: /** * This signal is emitted when the account changes */ @@ -216,20 +183,17 @@ signals: // TODO: better signalling for the various possible state changes - especially errors -protected: /* variables */ + protected: /* variables */ AccountData data; // current task we are executing here shared_qobject_ptr m_currentTask; -protected: /* methods */ - + protected: /* methods */ void incrementUses() override; void decrementUses() override; -private -slots: + private slots: void authSucceeded(); void authFailed(QString reason); }; - diff --git a/launcher/minecraft/auth/Parsers.cpp b/launcher/minecraft/auth/Parsers.cpp index f3d9ad56b..8dbe446ab 100644 --- a/launcher/minecraft/auth/Parsers.cpp +++ b/launcher/minecraft/auth/Parsers.cpp @@ -2,46 +2,51 @@ #include "Json.h" #include "Logging.h" -#include -#include #include +#include +#include namespace Parsers { -bool getDateTime(QJsonValue value, QDateTime & out) { - if(!value.isString()) { +bool getDateTime(QJsonValue value, QDateTime& out) +{ + if (!value.isString()) { return false; } out = QDateTime::fromString(value.toString(), Qt::ISODate); return out.isValid(); } -bool getString(QJsonValue value, QString & out) { - if(!value.isString()) { +bool getString(QJsonValue value, QString& out) +{ + if (!value.isString()) { return false; } out = value.toString(); return true; } -bool getNumber(QJsonValue value, double & out) { - if(!value.isDouble()) { +bool getNumber(QJsonValue value, double& out) +{ + if (!value.isDouble()) { return false; } out = value.toDouble(); return true; } -bool getNumber(QJsonValue value, int64_t & out) { - if(!value.isDouble()) { +bool getNumber(QJsonValue value, int64_t& out) +{ + if (!value.isDouble()) { return false; } - out = (int64_t) value.toDouble(); + out = (int64_t)value.toDouble(); return true; } -bool getBool(QJsonValue value, bool & out) { - if(!value.isBool()) { +bool getBool(QJsonValue value, bool& out) +{ + if (!value.isBool()) { return false; } out = value.toBool(); @@ -74,49 +79,50 @@ bool getBool(QJsonValue value, bool & out) { // 2148916238 = child account not linked to a family */ -bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString name) { - qDebug() << "Parsing" << name <<":"; +bool parseXTokenResponse(QByteArray& data, Katabasis::Token& output, QString name) +{ + qDebug() << "Parsing" << name << ":"; qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); return false; } auto obj = doc.object(); - if(!getDateTime(obj.value("IssueInstant"), output.issueInstant)) { + if (!getDateTime(obj.value("IssueInstant"), output.issueInstant)) { qWarning() << "User IssueInstant is not a timestamp"; return false; } - if(!getDateTime(obj.value("NotAfter"), output.notAfter)) { + if (!getDateTime(obj.value("NotAfter"), output.notAfter)) { qWarning() << "User NotAfter is not a timestamp"; return false; } - if(!getString(obj.value("Token"), output.token)) { + if (!getString(obj.value("Token"), output.token)) { qWarning() << "User Token is not a string"; return false; } auto arrayVal = obj.value("DisplayClaims").toObject().value("xui"); - if(!arrayVal.isArray()) { + if (!arrayVal.isArray()) { qWarning() << "Missing xui claims array"; return false; } bool foundUHS = false; - for(auto item: arrayVal.toArray()) { - if(!item.isObject()) { + for (auto item : arrayVal.toArray()) { + if (!item.isObject()) { continue; } auto obj = item.toObject(); - if(obj.contains("uhs")) { + if (obj.contains("uhs")) { foundUHS = true; } else { continue; } // consume all 'display claims' ... whatever that means - for(auto iter = obj.begin(); iter != obj.end(); iter++) { + for (auto iter = obj.begin(); iter != obj.end(); iter++) { QString claim; - if(!getString(obj.value(iter.key()), claim)) { + if (!getString(obj.value(iter.key()), claim)) { qWarning() << "display claim " << iter.key() << " is not a string..."; return false; } @@ -125,7 +131,7 @@ bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString na break; } - if(!foundUHS) { + if (!foundUHS) { qWarning() << "Missing uhs"; return false; } @@ -134,46 +140,47 @@ bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString na return true; } -bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { +bool parseMinecraftProfile(QByteArray& data, MinecraftProfile& output) +{ qDebug() << "Parsing Minecraft profile..."; qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); return false; } auto obj = doc.object(); - if(!getString(obj.value("id"), output.id)) { + if (!getString(obj.value("id"), output.id)) { qWarning() << "Minecraft profile id is not a string"; return false; } - if(!getString(obj.value("name"), output.name)) { + if (!getString(obj.value("name"), output.name)) { qWarning() << "Minecraft profile name is not a string"; return false; } auto skinsArray = obj.value("skins").toArray(); - for(auto skin: skinsArray) { + for (auto skin : skinsArray) { auto skinObj = skin.toObject(); Skin skinOut; - if(!getString(skinObj.value("id"), skinOut.id)) { + if (!getString(skinObj.value("id"), skinOut.id)) { continue; } QString state; - if(!getString(skinObj.value("state"), state)) { + if (!getString(skinObj.value("state"), state)) { continue; } - if(state != "ACTIVE") { + if (state != "ACTIVE") { continue; } - if(!getString(skinObj.value("url"), skinOut.url)) { + if (!getString(skinObj.value("url"), skinOut.url)) { continue; } - if(!getString(skinObj.value("variant"), skinOut.variant)) { + if (!getString(skinObj.value("variant"), skinOut.variant)) { continue; } // we deal with only the active skin @@ -183,23 +190,23 @@ bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { auto capesArray = obj.value("capes").toArray(); QString currentCape; - for(auto cape: capesArray) { + for (auto cape : capesArray) { auto capeObj = cape.toObject(); Cape capeOut; - if(!getString(capeObj.value("id"), capeOut.id)) { + if (!getString(capeObj.value("id"), capeOut.id)) { continue; } QString state; - if(!getString(capeObj.value("state"), state)) { + if (!getString(capeObj.value("state"), state)) { continue; } - if(state == "ACTIVE") { + if (state == "ACTIVE") { currentCape = capeOut.id; } - if(!getString(capeObj.value("url"), capeOut.url)) { + if (!getString(capeObj.value("url"), capeOut.url)) { continue; } - if(!getString(capeObj.value("alias"), capeOut.alias)) { + if (!getString(capeObj.value("alias"), capeOut.alias)) { continue; } @@ -211,30 +218,33 @@ bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { } namespace { - // these skin URLs are for the MHF_Steve and MHF_Alex accounts (made by a Mojang employee) - // they are needed because the session server doesn't return skin urls for default skins - static const QString SKIN_URL_STEVE = "http://textures.minecraft.net/texture/1a4af718455d4aab528e7a61f86fa25e6a369d1768dcb13f7df319a713eb810b"; - static const QString SKIN_URL_ALEX = "http://textures.minecraft.net/texture/83cee5ca6afcdb171285aa00e8049c297b2dbeba0efb8ff970a5677a1b644032"; +// these skin URLs are for the MHF_Steve and MHF_Alex accounts (made by a Mojang employee) +// they are needed because the session server doesn't return skin urls for default skins +static const QString SKIN_URL_STEVE = + "http://textures.minecraft.net/texture/1a4af718455d4aab528e7a61f86fa25e6a369d1768dcb13f7df319a713eb810b"; +static const QString SKIN_URL_ALEX = + "http://textures.minecraft.net/texture/83cee5ca6afcdb171285aa00e8049c297b2dbeba0efb8ff970a5677a1b644032"; - bool isDefaultModelSteve(QString uuid) { - // need to calculate *Java* hashCode of UUID - // if number is even, skin/model is steve, otherwise it is alex +bool isDefaultModelSteve(QString uuid) +{ + // need to calculate *Java* hashCode of UUID + // if number is even, skin/model is steve, otherwise it is alex - // just in case dashes are in the id - uuid.remove('-'); + // just in case dashes are in the id + uuid.remove('-'); - if (uuid.size() != 32) { - return true; - } - - // qulonglong is guaranteed to be 64 bits - // we need to use unsigned numbers to guarantee truncation below - qulonglong most = uuid.left(16).toULongLong(nullptr, 16); - qulonglong least = uuid.right(16).toULongLong(nullptr, 16); - qulonglong xored = most ^ least; - return ((static_cast(xored >> 32)) ^ static_cast(xored)) % 2 == 0; + if (uuid.size() != 32) { + return true; } + + // qulonglong is guaranteed to be 64 bits + // we need to use unsigned numbers to guarantee truncation below + qulonglong most = uuid.left(16).toULongLong(nullptr, 16); + qulonglong least = uuid.right(16).toULongLong(nullptr, 16); + qulonglong xored = most ^ least; + return ((static_cast(xored >> 32)) ^ static_cast(xored)) % 2 == 0; } +} // namespace /** Uses session server for skin/cape lookup instead of profile, @@ -270,31 +280,32 @@ decoded base64 "value": } */ -bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { +bool parseMinecraftProfileMojang(QByteArray& data, MinecraftProfile& output) +{ qDebug() << "Parsing Minecraft profile..."; qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Failed to parse response as JSON: " << jsonError.errorString(); return false; } auto obj = Json::requireObject(doc, "mojang minecraft profile"); - if(!getString(obj.value("id"), output.id)) { + if (!getString(obj.value("id"), output.id)) { qWarning() << "Minecraft profile id is not a string"; return false; } - if(!getString(obj.value("name"), output.name)) { + if (!getString(obj.value("name"), output.name)) { qWarning() << "Minecraft profile name is not a string"; return false; } auto propsArray = obj.value("properties").toArray(); QByteArray texturePayload; - for( auto p : propsArray) { + for (auto p : propsArray) { auto pObj = p.toObject(); auto name = pObj.value("name"); if (!name.isString() || name.toString() != "textures") { @@ -321,7 +332,7 @@ bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { } doc = QJsonDocument::fromJson(texturePayload, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Failed to parse response as JSON: " << jsonError.errorString(); return false; } @@ -357,8 +368,7 @@ bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { // might not be present getString(meta.value("model"), skinOut.variant); } - } - else if (idx.key() == "CAPE") { + } else if (idx.key() == "CAPE") { auto cape = idx->toObject(); if (!getString(cape.value("url"), capeOut.url)) { qWarning() << "Cape url is not a string"; @@ -374,7 +384,7 @@ bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { output.skin = skinOut; if (capeOut.alias == "cape") { - output.capes = QMap({{capeOut.alias, capeOut}}); + output.capes = QMap({ { capeOut.alias, capeOut } }); output.currentCape = capeOut.alias; } @@ -382,13 +392,14 @@ bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { return true; } -bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) { +bool parseMinecraftEntitlements(QByteArray& data, MinecraftEntitlement& output) +{ qDebug() << "Parsing Minecraft entitlements..."; qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); return false; } @@ -398,16 +409,16 @@ bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) output.ownsMinecraft = false; auto itemsArray = obj.value("items").toArray(); - for(auto item: itemsArray) { + for (auto item : itemsArray) { auto itemObj = item.toObject(); QString name; - if(!getString(itemObj.value("name"), name)) { + if (!getString(itemObj.value("name"), name)) { continue; } - if(name == "game_minecraft") { + if (name == "game_minecraft") { output.canPlayMinecraft = true; } - if(name == "product_minecraft") { + if (name == "product_minecraft") { output.ownsMinecraft = true; } } @@ -415,47 +426,50 @@ bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) return true; } -bool parseRolloutResponse(QByteArray & data, bool& result) { +bool parseRolloutResponse(QByteArray& data, bool& result) +{ qDebug() << "Parsing Rollout response..."; qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { - qWarning() << "Failed to parse response from https://api.minecraftservices.com/rollout/v1/msamigration as JSON: " << jsonError.errorString(); + if (jsonError.error) { + qWarning() << "Failed to parse response from https://api.minecraftservices.com/rollout/v1/msamigration as JSON: " + << jsonError.errorString(); return false; } auto obj = doc.object(); QString feature; - if(!getString(obj.value("feature"), feature)) { + if (!getString(obj.value("feature"), feature)) { qWarning() << "Rollout feature is not a string"; return false; } - if(feature != "msamigration") { + if (feature != "msamigration") { qWarning() << "Rollout feature is not what we expected (msamigration), but is instead \"" << feature << "\""; return false; } - if(!getBool(obj.value("rollout"), result)) { + if (!getBool(obj.value("rollout"), result)) { qWarning() << "Rollout feature is not a string"; return false; } return true; } -bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) { +bool parseMojangResponse(QByteArray& data, Katabasis::Token& output) +{ QJsonParseError jsonError; qDebug() << "Parsing Mojang response..."; qCDebug(authCredentials()) << data; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Failed to parse response from api.minecraftservices.com/launcher/login as JSON: " << jsonError.errorString(); return false; } auto obj = doc.object(); double expires_in = 0; - if(!getNumber(obj.value("expires_in"), expires_in)) { + if (!getNumber(obj.value("expires_in"), expires_in)) { qWarning() << "expires_in is not a valid number"; return false; } @@ -464,13 +478,13 @@ bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) { output.notAfter = currentTime.addSecs(expires_in); QString username; - if(!getString(obj.value("username"), username)) { + if (!getString(obj.value("username"), username)) { qWarning() << "username is not valid"; return false; } // TODO: it's a JWT... validate it? - if(!getString(obj.value("access_token"), output.token)) { + if (!getString(obj.value("access_token"), output.token)) { qWarning() << "access_token is not valid"; return false; } @@ -479,4 +493,4 @@ bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) { return true; } -} +} // namespace Parsers diff --git a/launcher/minecraft/auth/Parsers.h b/launcher/minecraft/auth/Parsers.h index 2666d890c..d073f9994 100644 --- a/launcher/minecraft/auth/Parsers.h +++ b/launcher/minecraft/auth/Parsers.h @@ -2,19 +2,18 @@ #include "AccountData.h" -namespace Parsers -{ - bool getDateTime(QJsonValue value, QDateTime & out); - bool getString(QJsonValue value, QString & out); - bool getNumber(QJsonValue value, double & out); - bool getNumber(QJsonValue value, int64_t & out); - bool getBool(QJsonValue value, bool & out); +namespace Parsers { +bool getDateTime(QJsonValue value, QDateTime& out); +bool getString(QJsonValue value, QString& out); +bool getNumber(QJsonValue value, double& out); +bool getNumber(QJsonValue value, int64_t& out); +bool getBool(QJsonValue value, bool& out); - bool parseXTokenResponse(QByteArray &data, Katabasis::Token &output, QString name); - bool parseMojangResponse(QByteArray &data, Katabasis::Token &output); +bool parseXTokenResponse(QByteArray& data, Katabasis::Token& output, QString name); +bool parseMojangResponse(QByteArray& data, Katabasis::Token& output); - bool parseMinecraftProfile(QByteArray &data, MinecraftProfile &output); - bool parseMinecraftProfileMojang(QByteArray &data, MinecraftProfile &output); - bool parseMinecraftEntitlements(QByteArray &data, MinecraftEntitlement &output); - bool parseRolloutResponse(QByteArray &data, bool& result); -} +bool parseMinecraftProfile(QByteArray& data, MinecraftProfile& output); +bool parseMinecraftProfileMojang(QByteArray& data, MinecraftProfile& output); +bool parseMinecraftEntitlements(QByteArray& data, MinecraftEntitlement& output); +bool parseRolloutResponse(QByteArray& data, bool& result); +} // namespace Parsers diff --git a/launcher/minecraft/auth/Yggdrasil.cpp b/launcher/minecraft/auth/Yggdrasil.cpp index d3e7ccddb..97f2a78d4 100644 --- a/launcher/minecraft/auth/Yggdrasil.cpp +++ b/launcher/minecraft/auth/Yggdrasil.cpp @@ -16,24 +16,24 @@ #include "Yggdrasil.h" #include "AccountData.h" +#include +#include +#include +#include #include #include -#include -#include -#include -#include #include #include "Application.h" -Yggdrasil::Yggdrasil(AccountData *data, QObject *parent) - : AccountTask(data, parent) +Yggdrasil::Yggdrasil(AccountData* data, QObject* parent) : AccountTask(data, parent) { changeState(AccountTaskState::STATE_CREATED); } -void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) { +void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) +{ changeState(AccountTaskState::STATE_WORKING); QNetworkRequest netRequest(endpoint); @@ -52,10 +52,10 @@ void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) { connect(&counter, &QTimer::timeout, this, &Yggdrasil::heartbeat); } -void Yggdrasil::executeTask() { -} +void Yggdrasil::executeTask() {} -void Yggdrasil::refresh() { +void Yggdrasil::refresh() +{ start(); /* * { @@ -90,7 +90,8 @@ void Yggdrasil::refresh() { sendRequest(reqUrl, requestData); } -void Yggdrasil::login(QString password) { +void Yggdrasil::login(QString password) +{ start(); /* * { @@ -136,20 +137,21 @@ void Yggdrasil::login(QString password) { sendRequest(reqUrl, requestData); } - - -void Yggdrasil::refreshTimers(qint64, qint64) { +void Yggdrasil::refreshTimers(qint64, qint64) +{ timeout_keeper.stop(); timeout_keeper.start(timeout_max); progress(count = 0, timeout_max); } -void Yggdrasil::heartbeat() { +void Yggdrasil::heartbeat() +{ count += time_step; progress(count, timeout_max); } -bool Yggdrasil::abort() { +bool Yggdrasil::abort() +{ progress(timeout_max, timeout_max); // TODO: actually use this in a meaningful way m_aborted = Yggdrasil::BY_USER; @@ -157,14 +159,16 @@ bool Yggdrasil::abort() { return true; } -void Yggdrasil::abortByTimeout() { +void Yggdrasil::abortByTimeout() +{ progress(timeout_max, timeout_max); // TODO: actually use this in a meaningful way m_aborted = Yggdrasil::BY_TIMEOUT; m_netReply->abort(); } -void Yggdrasil::sslErrors(QList errors) { +void Yggdrasil::sslErrors(QList errors) +{ int i = 1; for (auto error : errors) { qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString(); @@ -174,7 +178,8 @@ void Yggdrasil::sslErrors(QList errors) { } } -void Yggdrasil::processResponse(QJsonObject responseData) { +void Yggdrasil::processResponse(QJsonObject responseData) +{ // Read the response data. We need to get the client token, access token, and the selected // profile. qDebug() << "Processing authentication response."; @@ -188,11 +193,11 @@ void Yggdrasil::processResponse(QJsonObject responseData) { changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send a client token.")); return; } - if(m_data->clientToken().isEmpty()) { + if (m_data->clientToken().isEmpty()) { m_data->setClientToken(clientToken); - } - else if(clientToken != m_data->clientToken()) { - changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported.")); + } else if (clientToken != m_data->clientToken()) { + changeState(AccountTaskState::STATE_FAILED_HARD, + tr("Authentication server attempted to change the client token. This isn't supported.")); return; } @@ -220,8 +225,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) { for (auto i = profileObj.constBegin(); i != profileObj.constEnd(); ++i) { if (i.key() == "name" && i.value().isString()) { m_data->minecraftProfile.name = i->toString(); - } - else if (i.key() == "id" && i.value().isString()) { + } else if (i.key() == "id" && i.value().isString()) { m_data->minecraftProfile.id = i->toString(); } } @@ -237,50 +241,43 @@ void Yggdrasil::processResponse(QJsonObject responseData) { changeState(AccountTaskState::STATE_SUCCEEDED); } -void Yggdrasil::processReply() { +void Yggdrasil::processReply() +{ changeState(AccountTaskState::STATE_WORKING); - switch (m_netReply->error()) - { - case QNetworkReply::NoError: - break; - case QNetworkReply::TimeoutError: - changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation timed out.")); - return; - case QNetworkReply::OperationCanceledError: - changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation cancelled.")); - return; - case QNetworkReply::SslHandshakeFailedError: - changeState( - AccountTaskState::STATE_FAILED_SOFT, - tr( - "SSL Handshake failed.
    There might be a few causes for it:
    " - "
      " - "
    • You use Windows and need to update your root certificates, please install any outstanding updates.
    • " - "
    • Some device on your network is interfering with SSL traffic. In that case, " - "you have bigger worries than Minecraft not starting.
    • " - "
    • Possibly something else. Check the log file for details
    • " - "
    " - ) - ); - return; - // used for invalid credentials and similar errors. Fall through. - case QNetworkReply::ContentAccessDenied: - case QNetworkReply::ContentOperationNotPermittedError: - break; - case QNetworkReply::ContentGoneError: { - changeState( - AccountTaskState::STATE_FAILED_GONE, - tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account.") - ); - return; - } - default: - changeState( - AccountTaskState::STATE_FAILED_SOFT, - tr("Authentication operation failed due to a network error: %1 (%2)").arg(m_netReply->errorString()).arg(m_netReply->error()) - ); - return; + switch (m_netReply->error()) { + case QNetworkReply::NoError: + break; + case QNetworkReply::TimeoutError: + changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation timed out.")); + return; + case QNetworkReply::OperationCanceledError: + changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation cancelled.")); + return; + case QNetworkReply::SslHandshakeFailedError: + changeState(AccountTaskState::STATE_FAILED_SOFT, + tr("SSL Handshake failed.
    There might be a few causes for it:
    " + "
      " + "
    • You use Windows and need to update your root certificates, please install any outstanding updates.
    • " + "
    • Some device on your network is interfering with SSL traffic. In that case, " + "you have bigger worries than Minecraft not starting.
    • " + "
    • Possibly something else. Check the log file for details
    • " + "
    ")); + return; + // used for invalid credentials and similar errors. Fall through. + case QNetworkReply::ContentAccessDenied: + case QNetworkReply::ContentOperationNotPermittedError: + break; + case QNetworkReply::ContentGoneError: { + changeState(AccountTaskState::STATE_FAILED_GONE, + tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account.")); + return; + } + default: + changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation failed due to a network error: %1 (%2)") + .arg(m_netReply->errorString()) + .arg(m_netReply->error())); + return; } // Try to parse the response regardless of the response code. @@ -299,12 +296,11 @@ void Yggdrasil::processReply() { if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0) { processResponse(replyData.size() > 0 ? doc.object() : QJsonObject()); return; - } - else { - changeState( - AccountTaskState::STATE_FAILED_SOFT, - tr("Failed to parse authentication server response JSON response: %1 at offset %2.").arg(jsonError.errorString()).arg(jsonError.offset) - ); + } else { + changeState(AccountTaskState::STATE_FAILED_SOFT, + tr("Failed to parse authentication server response JSON response: %1 at offset %2.") + .arg(jsonError.errorString()) + .arg(jsonError.offset)); qCritical() << replyData; } return; @@ -320,34 +316,26 @@ void Yggdrasil::processReply() { // stuff there. qDebug() << "The request failed, but the server gave us an error message. Processing error."; processError(doc.object()); - } - else { + } else { // The server didn't say anything regarding the error. Give the user an unknown // error. qDebug() << "The request failed and the server gave no error message. Unknown error."; changeState( AccountTaskState::STATE_FAILED_SOFT, - tr("An unknown error occurred when trying to communicate with the authentication server: %1").arg(m_netReply->errorString()) - ); + tr("An unknown error occurred when trying to communicate with the authentication server: %1").arg(m_netReply->errorString())); } } -void Yggdrasil::processError(QJsonObject responseData) { +void Yggdrasil::processError(QJsonObject responseData) +{ QJsonValue errorVal = responseData.value("error"); QJsonValue errorMessageValue = responseData.value("errorMessage"); QJsonValue causeVal = responseData.value("cause"); if (errorVal.isString() && errorMessageValue.isString()) { - m_error = std::shared_ptr( - new Error { - errorVal.toString(""), - errorMessageValue.toString(""), - causeVal.toString("") - } - ); + m_error = std::shared_ptr(new Error{ errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("") }); changeState(AccountTaskState::STATE_FAILED_HARD, m_error->m_errorMessageVerbose); - } - else { + } else { // Error is not in standard format. Don't set m_error and return unknown error. changeState(AccountTaskState::STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred.")); } diff --git a/launcher/minecraft/auth/Yggdrasil.h b/launcher/minecraft/auth/Yggdrasil.h index 4f52a04c2..560d7fb81 100644 --- a/launcher/minecraft/auth/Yggdrasil.h +++ b/launcher/minecraft/auth/Yggdrasil.h @@ -17,10 +17,10 @@ #include "AccountTask.h" -#include -#include -#include #include +#include +#include +#include #include "MinecraftAccount.h" @@ -30,35 +30,25 @@ class QNetworkReply; /** * A Yggdrasil task is a task that performs an operation on a given mojang account. */ -class Yggdrasil : public AccountTask -{ +class Yggdrasil : public AccountTask { Q_OBJECT -public: - explicit Yggdrasil( - AccountData *data, - QObject *parent = 0 - ); + public: + explicit Yggdrasil(AccountData* data, QObject* parent = 0); virtual ~Yggdrasil() = default; void refresh(); void login(QString password); - struct Error - { + struct Error { QString m_errorMessageShort; QString m_errorMessageVerbose; QString m_cause; }; std::shared_ptr m_error; - enum AbortedBy - { - BY_NOTHING, - BY_USER, - BY_TIMEOUT - } m_aborted = BY_NOTHING; + enum AbortedBy { BY_NOTHING, BY_USER, BY_TIMEOUT } m_aborted = BY_NOTHING; -protected: + protected: void executeTask() override; /** @@ -78,24 +68,24 @@ protected: */ virtual void processError(QJsonObject responseData); -protected slots: + protected slots: void processReply(); void refreshTimers(qint64, qint64); void heartbeat(); void sslErrors(QList); void abortByTimeout(); -public slots: + public slots: virtual bool abort() override; -private: + private: void sendRequest(QUrl endpoint, QByteArray content); -protected: - QNetworkReply *m_netReply = nullptr; + protected: + QNetworkReply* m_netReply = nullptr; QTimer timeout_keeper; QTimer counter; - int count = 0; // num msec since time reset + int count = 0; // num msec since time reset const int timeout_max = 30000; const int time_step = 50; diff --git a/launcher/minecraft/auth/flows/AuthFlow.cpp b/launcher/minecraft/auth/flows/AuthFlow.cpp index 4f78e8c31..c51839a8c 100644 --- a/launcher/minecraft/auth/flows/AuthFlow.cpp +++ b/launcher/minecraft/auth/flows/AuthFlow.cpp @@ -1,36 +1,33 @@ -#include -#include -#include #include +#include +#include +#include #include "AuthFlow.h" #include "katabasis/Globals.h" #include -AuthFlow::AuthFlow(AccountData * data, QObject *parent) : - AccountTask(data, parent) +AuthFlow::AuthFlow(AccountData* data, QObject* parent) : AccountTask(data, parent) {} + +void AuthFlow::succeed() { -} - -void AuthFlow::succeed() { m_data->validity_ = Katabasis::Validity::Certain; - changeState( - AccountTaskState::STATE_SUCCEEDED, - tr("Finished all authentication steps") - ); + changeState(AccountTaskState::STATE_SUCCEEDED, tr("Finished all authentication steps")); } -void AuthFlow::executeTask() { - if(m_currentStep) { +void AuthFlow::executeTask() +{ + if (m_currentStep) { return; } changeState(AccountTaskState::STATE_WORKING, tr("Initializing")); nextStep(); } -void AuthFlow::nextStep() { - if(m_steps.size() == 0) { +void AuthFlow::nextStep() +{ + if (m_steps.size() == 0) { // we got to the end without an incident... assume this is all. m_currentStep.reset(); succeed(); @@ -46,15 +43,13 @@ void AuthFlow::nextStep() { m_currentStep->perform(); } - -QString AuthFlow::getStateMessage() const { - switch (m_taskState) - { +QString AuthFlow::getStateMessage() const +{ + switch (m_taskState) { case AccountTaskState::STATE_WORKING: { - if(m_currentStep) { + if (m_currentStep) { return m_currentStep->describe(); - } - else { + } else { return tr("Working..."); } } @@ -64,8 +59,9 @@ QString AuthFlow::getStateMessage() const { } } -void AuthFlow::stepFinished(AccountTaskState resultingState, QString message) { - if(changeState(resultingState, message)) { +void AuthFlow::stepFinished(AccountTaskState resultingState, QString message) +{ + if (changeState(resultingState, message)) { nextStep(); } } diff --git a/launcher/minecraft/auth/flows/AuthFlow.h b/launcher/minecraft/auth/flows/AuthFlow.h index e067cc99f..c2c412abc 100644 --- a/launcher/minecraft/auth/flows/AuthFlow.h +++ b/launcher/minecraft/auth/flows/AuthFlow.h @@ -1,45 +1,42 @@ #pragma once -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include -#include "minecraft/auth/Yggdrasil.h" #include "minecraft/auth/AccountData.h" #include "minecraft/auth/AccountTask.h" #include "minecraft/auth/AuthStep.h" +#include "minecraft/auth/Yggdrasil.h" -class AuthFlow : public AccountTask -{ +class AuthFlow : public AccountTask { Q_OBJECT -public: - explicit AuthFlow(AccountData * data, QObject *parent = 0); + public: + explicit AuthFlow(AccountData* data, QObject* parent = 0); - Katabasis::Validity validity() { - return m_data->validity_; - }; + Katabasis::Validity validity() { return m_data->validity_; }; QString getStateMessage() const override; void executeTask() override; -signals: + signals: void activityChanged(Katabasis::Activity activity); -private slots: + private slots: void stepFinished(AccountTaskState resultingState, QString message); -protected: + protected: void succeed(); void nextStep(); -protected: + protected: QList m_steps; AuthStep::Ptr m_currentStep; }; diff --git a/launcher/minecraft/auth/flows/MSA.cpp b/launcher/minecraft/auth/flows/MSA.cpp index f1987e0c1..f0399342e 100644 --- a/launcher/minecraft/auth/flows/MSA.cpp +++ b/launcher/minecraft/auth/flows/MSA.cpp @@ -1,15 +1,16 @@ #include "MSA.h" -#include "minecraft/auth/steps/MSAStep.h" -#include "minecraft/auth/steps/XboxUserStep.h" -#include "minecraft/auth/steps/XboxAuthorizationStep.h" -#include "minecraft/auth/steps/LauncherLoginStep.h" -#include "minecraft/auth/steps/XboxProfileStep.h" #include "minecraft/auth/steps/EntitlementsStep.h" -#include "minecraft/auth/steps/MinecraftProfileStep.h" #include "minecraft/auth/steps/GetSkinStep.h" +#include "minecraft/auth/steps/LauncherLoginStep.h" +#include "minecraft/auth/steps/MSAStep.h" +#include "minecraft/auth/steps/MinecraftProfileStep.h" +#include "minecraft/auth/steps/XboxAuthorizationStep.h" +#include "minecraft/auth/steps/XboxProfileStep.h" +#include "minecraft/auth/steps/XboxUserStep.h" -MSASilent::MSASilent(AccountData* data, QObject* parent) : AuthFlow(data, parent) { +MSASilent::MSASilent(AccountData* data, QObject* parent) : AuthFlow(data, parent) +{ m_steps.append(makeShared(m_data, MSAStep::Action::Refresh)); m_steps.append(makeShared(m_data)); m_steps.append(makeShared(m_data, &m_data->xboxApiToken, "http://xboxlive.com", "Xbox")); @@ -21,10 +22,8 @@ MSASilent::MSASilent(AccountData* data, QObject* parent) : AuthFlow(data, parent m_steps.append(makeShared(m_data)); } -MSAInteractive::MSAInteractive( - AccountData* data, - QObject* parent -) : AuthFlow(data, parent) { +MSAInteractive::MSAInteractive(AccountData* data, QObject* parent) : AuthFlow(data, parent) +{ m_steps.append(makeShared(m_data, MSAStep::Action::Login)); m_steps.append(makeShared(m_data)); m_steps.append(makeShared(m_data, &m_data->xboxApiToken, "http://xboxlive.com", "Xbox")); diff --git a/launcher/minecraft/auth/flows/MSA.h b/launcher/minecraft/auth/flows/MSA.h index 14a4ff430..e403d530f 100644 --- a/launcher/minecraft/auth/flows/MSA.h +++ b/launcher/minecraft/auth/flows/MSA.h @@ -1,22 +1,14 @@ #pragma once #include "AuthFlow.h" -class MSAInteractive : public AuthFlow -{ +class MSAInteractive : public AuthFlow { Q_OBJECT -public: - explicit MSAInteractive( - AccountData *data, - QObject *parent = 0 - ); + public: + explicit MSAInteractive(AccountData* data, QObject* parent = 0); }; -class MSASilent : public AuthFlow -{ +class MSASilent : public AuthFlow { Q_OBJECT -public: - explicit MSASilent( - AccountData * data, - QObject *parent = 0 - ); + public: + explicit MSASilent(AccountData* data, QObject* parent = 0); }; diff --git a/launcher/minecraft/auth/flows/Mojang.cpp b/launcher/minecraft/auth/flows/Mojang.cpp index 5900ea988..7e2db16fa 100644 --- a/launcher/minecraft/auth/flows/Mojang.cpp +++ b/launcher/minecraft/auth/flows/Mojang.cpp @@ -1,25 +1,20 @@ #include "Mojang.h" -#include "minecraft/auth/steps/YggdrasilStep.h" -#include "minecraft/auth/steps/MinecraftProfileStepMojang.h" -#include "minecraft/auth/steps/MigrationEligibilityStep.h" #include "minecraft/auth/steps/GetSkinStep.h" +#include "minecraft/auth/steps/MigrationEligibilityStep.h" +#include "minecraft/auth/steps/MinecraftProfileStepMojang.h" +#include "minecraft/auth/steps/YggdrasilStep.h" -MojangRefresh::MojangRefresh( - AccountData *data, - QObject *parent -) : AuthFlow(data, parent) { +MojangRefresh::MojangRefresh(AccountData* data, QObject* parent) : AuthFlow(data, parent) +{ m_steps.append(makeShared(m_data, QString())); m_steps.append(makeShared(m_data)); m_steps.append(makeShared(m_data)); m_steps.append(makeShared(m_data)); } -MojangLogin::MojangLogin( - AccountData *data, - QString password, - QObject *parent -): AuthFlow(data, parent), m_password(password) { +MojangLogin::MojangLogin(AccountData* data, QString password, QObject* parent) : AuthFlow(data, parent), m_password(password) +{ m_steps.append(makeShared(m_data, m_password)); m_steps.append(makeShared(m_data)); m_steps.append(makeShared(m_data)); diff --git a/launcher/minecraft/auth/flows/Mojang.h b/launcher/minecraft/auth/flows/Mojang.h index c09c81a80..779ca7e34 100644 --- a/launcher/minecraft/auth/flows/Mojang.h +++ b/launcher/minecraft/auth/flows/Mojang.h @@ -1,26 +1,17 @@ #pragma once #include "AuthFlow.h" -class MojangRefresh : public AuthFlow -{ +class MojangRefresh : public AuthFlow { Q_OBJECT -public: - explicit MojangRefresh( - AccountData *data, - QObject *parent = 0 - ); + public: + explicit MojangRefresh(AccountData* data, QObject* parent = 0); }; -class MojangLogin : public AuthFlow -{ +class MojangLogin : public AuthFlow { Q_OBJECT -public: - explicit MojangLogin( - AccountData *data, - QString password, - QObject *parent = 0 - ); + public: + explicit MojangLogin(AccountData* data, QString password, QObject* parent = 0); -private: + private: QString m_password; }; diff --git a/launcher/minecraft/auth/flows/Offline.cpp b/launcher/minecraft/auth/flows/Offline.cpp index d5c632715..3770b869a 100644 --- a/launcher/minecraft/auth/flows/Offline.cpp +++ b/launcher/minecraft/auth/flows/Offline.cpp @@ -2,16 +2,12 @@ #include "minecraft/auth/steps/OfflineStep.h" -OfflineRefresh::OfflineRefresh( - AccountData *data, - QObject *parent -) : AuthFlow(data, parent) { +OfflineRefresh::OfflineRefresh(AccountData* data, QObject* parent) : AuthFlow(data, parent) +{ m_steps.append(makeShared(m_data)); } -OfflineLogin::OfflineLogin( - AccountData *data, - QObject *parent -) : AuthFlow(data, parent) { +OfflineLogin::OfflineLogin(AccountData* data, QObject* parent) : AuthFlow(data, parent) +{ m_steps.append(makeShared(m_data)); } diff --git a/launcher/minecraft/auth/flows/Offline.h b/launcher/minecraft/auth/flows/Offline.h index 5d1f83a46..2bc9c7612 100644 --- a/launcher/minecraft/auth/flows/Offline.h +++ b/launcher/minecraft/auth/flows/Offline.h @@ -1,22 +1,14 @@ #pragma once #include "AuthFlow.h" -class OfflineRefresh : public AuthFlow -{ +class OfflineRefresh : public AuthFlow { Q_OBJECT -public: - explicit OfflineRefresh( - AccountData *data, - QObject *parent = 0 - ); + public: + explicit OfflineRefresh(AccountData* data, QObject* parent = 0); }; -class OfflineLogin : public AuthFlow -{ +class OfflineLogin : public AuthFlow { Q_OBJECT -public: - explicit OfflineLogin( - AccountData *data, - QObject *parent = 0 - ); + public: + explicit OfflineLogin(AccountData* data, QObject* parent = 0); }; diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.cpp b/launcher/minecraft/auth/steps/EntitlementsStep.cpp index bd6042926..e942db526 100644 --- a/launcher/minecraft/auth/steps/EntitlementsStep.cpp +++ b/launcher/minecraft/auth/steps/EntitlementsStep.cpp @@ -11,12 +11,13 @@ EntitlementsStep::EntitlementsStep(AccountData* data) : AuthStep(data) {} EntitlementsStep::~EntitlementsStep() noexcept = default; -QString EntitlementsStep::describe() { +QString EntitlementsStep::describe() +{ return tr("Determining game ownership."); } - -void EntitlementsStep::perform() { +void EntitlementsStep::perform() +{ auto uuid = QUuid::createUuid(); m_entitlementsRequestId = uuid.toString().remove('{').remove('}'); auto url = "https://api.minecraftservices.com/entitlements/license?requestId=" + m_entitlementsRequestId; @@ -24,22 +25,20 @@ void EntitlementsStep::perform() { request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &EntitlementsStep::onRequestDone); requestor->get(request); qDebug() << "Getting entitlements..."; } -void EntitlementsStep::rehydrate() { +void EntitlementsStep::rehydrate() +{ // NOOP, for now. We only save bools and there's nothing to check. } -void EntitlementsStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void EntitlementsStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); qCDebug(authCredentials()) << data; diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.h b/launcher/minecraft/auth/steps/EntitlementsStep.h index 9412ae79d..be16bda13 100644 --- a/launcher/minecraft/auth/steps/EntitlementsStep.h +++ b/launcher/minecraft/auth/steps/EntitlementsStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class EntitlementsStep : public AuthStep { Q_OBJECT -public: - explicit EntitlementsStep(AccountData *data); + public: + explicit EntitlementsStep(AccountData* data); virtual ~EntitlementsStep() noexcept; void perform() override; @@ -17,9 +16,9 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); -private: + private: QString m_entitlementsRequestId; }; diff --git a/launcher/minecraft/auth/steps/GetSkinStep.cpp b/launcher/minecraft/auth/steps/GetSkinStep.cpp index 3521f8dc5..520877020 100644 --- a/launcher/minecraft/auth/steps/GetSkinStep.cpp +++ b/launcher/minecraft/auth/steps/GetSkinStep.cpp @@ -6,34 +6,32 @@ #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" -GetSkinStep::GetSkinStep(AccountData* data) : AuthStep(data) { - -} +GetSkinStep::GetSkinStep(AccountData* data) : AuthStep(data) {} GetSkinStep::~GetSkinStep() noexcept = default; -QString GetSkinStep::describe() { +QString GetSkinStep::describe() +{ return tr("Getting skin."); } -void GetSkinStep::perform() { +void GetSkinStep::perform() +{ auto url = QUrl(m_data->minecraftProfile.skin.url); QNetworkRequest request = QNetworkRequest(url); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &GetSkinStep::onRequestDone); requestor->get(request); } -void GetSkinStep::rehydrate() { +void GetSkinStep::rehydrate() +{ // NOOP, for now. } -void GetSkinStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void GetSkinStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); if (error == QNetworkReply::NoError) { diff --git a/launcher/minecraft/auth/steps/GetSkinStep.h b/launcher/minecraft/auth/steps/GetSkinStep.h index 6b97371e5..105e497d1 100644 --- a/launcher/minecraft/auth/steps/GetSkinStep.h +++ b/launcher/minecraft/auth/steps/GetSkinStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class GetSkinStep : public AuthStep { Q_OBJECT -public: - explicit GetSkinStep(AccountData *data); + public: + explicit GetSkinStep(AccountData* data); virtual ~GetSkinStep() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp index 8a26cbe77..c57f51113 100644 --- a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp +++ b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp @@ -8,17 +8,17 @@ #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" -LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) { - -} +LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) {} LauncherLoginStep::~LauncherLoginStep() noexcept = default; -QString LauncherLoginStep::describe() { +QString LauncherLoginStep::describe() +{ return tr("Accessing Mojang services."); } -void LauncherLoginStep::perform() { +void LauncherLoginStep::perform() +{ auto requestURL = "https://api.minecraftservices.com/launcher/login"; auto uhs = m_data->mojangservicesToken.extra["uhs"].toString(); auto xToken = m_data->mojangservicesToken.token; @@ -34,22 +34,20 @@ void LauncherLoginStep::perform() { QNetworkRequest request = QNetworkRequest(QUrl(requestURL)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &LauncherLoginStep::onRequestDone); requestor->post(request, requestBody.toUtf8()); qDebug() << "Getting Minecraft access token..."; } -void LauncherLoginStep::rehydrate() { +void LauncherLoginStep::rehydrate() +{ // TODO: check the token validity } -void LauncherLoginStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void LauncherLoginStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); qCDebug(authCredentials()) << data; @@ -57,27 +55,17 @@ void LauncherLoginStep::onRequestDone( qWarning() << "Reply error:" << error; qCDebug(authCredentials()) << data; if (Net::isApplicationError(error)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_) - ); - } - else { - emit finished( - AccountTaskState::STATE_OFFLINE, - tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_)); + } else { + emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_)); } return; } - if(!Parsers::parseMojangResponse(data, m_data->yggdrasilToken)) { + if (!Parsers::parseMojangResponse(data, m_data->yggdrasilToken)) { qWarning() << "Could not parse login_with_xbox response..."; qCDebug(authCredentials()) << data; - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Failed to parse the Minecraft access token response.") - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to parse the Minecraft access token response.")); return; } emit finished(AccountTaskState::STATE_WORKING, tr("")); diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.h b/launcher/minecraft/auth/steps/LauncherLoginStep.h index e06a306f9..30c18e675 100644 --- a/launcher/minecraft/auth/steps/LauncherLoginStep.h +++ b/launcher/minecraft/auth/steps/LauncherLoginStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class LauncherLoginStep : public AuthStep { Q_OBJECT -public: - explicit LauncherLoginStep(AccountData *data); + public: + explicit LauncherLoginStep(AccountData* data); virtual ~LauncherLoginStep() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp index 6fc8d468e..66a9a0e80 100644 --- a/launcher/minecraft/auth/steps/MSAStep.cpp +++ b/launcher/minecraft/auth/steps/MSAStep.cpp @@ -47,7 +47,8 @@ using OAuth2 = Katabasis::DeviceFlow; using Activity = Katabasis::Activity; -MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(action) { +MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(action) +{ m_clientId = APPLICATION->getMSAClientID(); OAuth2::Options opts; opts.scope = "XboxLive.signin offline_access"; @@ -64,13 +65,14 @@ MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(ac MSAStep::~MSAStep() noexcept = default; -QString MSAStep::describe() { +QString MSAStep::describe() +{ return tr("Logging in with Microsoft account."); } - -void MSAStep::rehydrate() { - switch(m_action) { +void MSAStep::rehydrate() +{ + switch (m_action) { case Refresh: { // TODO: check the tokens and see if they are old (older than a day) return; @@ -82,12 +84,14 @@ void MSAStep::rehydrate() { } } -void MSAStep::perform() { - switch(m_action) { +void MSAStep::perform() +{ + switch (m_action) { case Refresh: { if (m_data->msaClientID != m_clientId) { emit hideVerificationUriAndCode(); - emit finished(AccountTaskState::STATE_DISABLED, tr("Microsoft user authentication failed - client identification has changed.")); + emit finished(AccountTaskState::STATE_DISABLED, + tr("Microsoft user authentication failed - client identification has changed.")); } m_oauth2->refresh(); return; @@ -105,8 +109,9 @@ void MSAStep::perform() { } } -void MSAStep::onOAuthActivityChanged(Katabasis::Activity activity) { - switch(activity) { +void MSAStep::onOAuthActivityChanged(Katabasis::Activity activity) +{ + switch (activity) { case Katabasis::Activity::Idle: case Katabasis::Activity::LoggingIn: case Katabasis::Activity::Refreshing: diff --git a/launcher/minecraft/auth/steps/MSAStep.h b/launcher/minecraft/auth/steps/MSAStep.h index e9a1524e8..fc070ff6a 100644 --- a/launcher/minecraft/auth/steps/MSAStep.h +++ b/launcher/minecraft/auth/steps/MSAStep.h @@ -43,13 +43,11 @@ class MSAStep : public AuthStep { Q_OBJECT -public: - enum Action { - Refresh, - Login - }; -public: - explicit MSAStep(AccountData *data, Action action); + public: + enum Action { Refresh, Login }; + + public: + explicit MSAStep(AccountData* data, Action action); virtual ~MSAStep() noexcept; void perform() override; @@ -57,11 +55,11 @@ public: QString describe() override; -private slots: + private slots: void onOAuthActivityChanged(Katabasis::Activity activity); -private: - Katabasis::DeviceFlow *m_oauth2 = nullptr; + private: + Katabasis::DeviceFlow* m_oauth2 = nullptr; Action m_action; QString m_clientId; }; diff --git a/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp b/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp index f5b5637a4..5ce953dfb 100644 --- a/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp +++ b/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp @@ -5,37 +5,37 @@ #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" -MigrationEligibilityStep::MigrationEligibilityStep(AccountData* data) : AuthStep(data) { - -} +MigrationEligibilityStep::MigrationEligibilityStep(AccountData* data) : AuthStep(data) {} MigrationEligibilityStep::~MigrationEligibilityStep() noexcept = default; -QString MigrationEligibilityStep::describe() { +QString MigrationEligibilityStep::describe() +{ return tr("Checking for migration eligibility."); } -void MigrationEligibilityStep::perform() { +void MigrationEligibilityStep::perform() +{ auto url = QUrl("https://api.minecraftservices.com/rollout/v1/msamigration"); QNetworkRequest request = QNetworkRequest(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &MigrationEligibilityStep::onRequestDone); requestor->get(request); } -void MigrationEligibilityStep::rehydrate() { +void MigrationEligibilityStep::rehydrate() +{ // NOOP, for now. We only save bools and there's nothing to check. } -void MigrationEligibilityStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void MigrationEligibilityStep::onRequestDone(QNetworkReply::NetworkError error, + QByteArray data, + QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); if (error == QNetworkReply::NoError) { diff --git a/launcher/minecraft/auth/steps/MigrationEligibilityStep.h b/launcher/minecraft/auth/steps/MigrationEligibilityStep.h index b1bf9cbf4..8638975d8 100644 --- a/launcher/minecraft/auth/steps/MigrationEligibilityStep.h +++ b/launcher/minecraft/auth/steps/MigrationEligibilityStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class MigrationEligibilityStep : public AuthStep { Q_OBJECT -public: - explicit MigrationEligibilityStep(AccountData *data); + public: + explicit MigrationEligibilityStep(AccountData* data); virtual ~MigrationEligibilityStep() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp index 6cfa7c1cf..7cdce23f0 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp +++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp @@ -7,52 +7,46 @@ #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" -MinecraftProfileStep::MinecraftProfileStep(AccountData* data) : AuthStep(data) { - -} +MinecraftProfileStep::MinecraftProfileStep(AccountData* data) : AuthStep(data) {} MinecraftProfileStep::~MinecraftProfileStep() noexcept = default; -QString MinecraftProfileStep::describe() { +QString MinecraftProfileStep::describe() +{ return tr("Fetching the Minecraft profile."); } - -void MinecraftProfileStep::perform() { +void MinecraftProfileStep::perform() +{ auto url = QUrl("https://api.minecraftservices.com/minecraft/profile"); QNetworkRequest request = QNetworkRequest(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &MinecraftProfileStep::onRequestDone); requestor->get(request); } -void MinecraftProfileStep::rehydrate() { +void MinecraftProfileStep::rehydrate() +{ // NOOP, for now. We only save bools and there's nothing to check. } -void MinecraftProfileStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void MinecraftProfileStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); qCDebug(authCredentials()) << data; if (error == QNetworkReply::ContentNotFoundError) { // NOTE: Succeed even if we do not have a profile. This is a valid account state. - if(m_data->type == AccountType::Mojang) { + if (m_data->type == AccountType::Mojang) { m_data->minecraftEntitlement.canPlayMinecraft = false; m_data->minecraftEntitlement.ownsMinecraft = false; } m_data->minecraftProfile = MinecraftProfile(); - emit finished( - AccountTaskState::STATE_SUCCEEDED, - tr("Account has no Minecraft profile.") - ); + emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Account has no Minecraft profile.")); return; } if (error != QNetworkReply::NoError) { @@ -65,35 +59,24 @@ void MinecraftProfileStep::onRequestDone( qWarning() << QString::fromUtf8(data); if (Net::isApplicationError(error)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_) - ); - } - else { - emit finished( - AccountTaskState::STATE_OFFLINE, - tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)); + } else { + emit finished(AccountTaskState::STATE_OFFLINE, + tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)); } return; } - if(!Parsers::parseMinecraftProfile(data, m_data->minecraftProfile)) { + if (!Parsers::parseMinecraftProfile(data, m_data->minecraftProfile)) { m_data->minecraftProfile = MinecraftProfile(); - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Minecraft Java profile response could not be parsed") - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Minecraft Java profile response could not be parsed")); return; } - if(m_data->type == AccountType::Mojang) { + if (m_data->type == AccountType::Mojang) { auto validProfile = m_data->minecraftProfile.validity == Katabasis::Validity::Certain; m_data->minecraftEntitlement.canPlayMinecraft = validProfile; m_data->minecraftEntitlement.ownsMinecraft = validProfile; } - emit finished( - AccountTaskState::STATE_WORKING, - tr("Minecraft Java profile acquisition succeeded.") - ); + emit finished(AccountTaskState::STATE_WORKING, tr("Minecraft Java profile acquisition succeeded.")); } diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.h b/launcher/minecraft/auth/steps/MinecraftProfileStep.h index 8ef3395c6..cb30dab21 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStep.h +++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class MinecraftProfileStep : public AuthStep { Q_OBJECT -public: - explicit MinecraftProfileStep(AccountData *data); + public: + explicit MinecraftProfileStep(AccountData* data); virtual ~MinecraftProfileStep() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp index 8c3785882..d035e39a0 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp +++ b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp @@ -7,18 +7,17 @@ #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" -MinecraftProfileStepMojang::MinecraftProfileStepMojang(AccountData* data) : AuthStep(data) { - -} +MinecraftProfileStepMojang::MinecraftProfileStepMojang(AccountData* data) : AuthStep(data) {} MinecraftProfileStepMojang::~MinecraftProfileStepMojang() noexcept = default; -QString MinecraftProfileStepMojang::describe() { +QString MinecraftProfileStepMojang::describe() +{ return tr("Fetching the Minecraft profile."); } - -void MinecraftProfileStepMojang::perform() { +void MinecraftProfileStepMojang::perform() +{ if (m_data->minecraftProfile.id.isEmpty()) { emit finished(AccountTaskState::STATE_FAILED_HARD, tr("A UUID is required to get the profile.")); return; @@ -27,35 +26,32 @@ void MinecraftProfileStepMojang::perform() { // use session server instead of profile due to profile endpoint being locked for locked Mojang accounts QUrl url = QUrl("https://sessionserver.mojang.com/session/minecraft/profile/" + m_data->minecraftProfile.id); QNetworkRequest req = QNetworkRequest(url); - AuthRequest *request = new AuthRequest(this); + AuthRequest* request = new AuthRequest(this); connect(request, &AuthRequest::finished, this, &MinecraftProfileStepMojang::onRequestDone); request->get(req); } -void MinecraftProfileStepMojang::rehydrate() { +void MinecraftProfileStepMojang::rehydrate() +{ // NOOP, for now. We only save bools and there's nothing to check. } -void MinecraftProfileStepMojang::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void MinecraftProfileStepMojang::onRequestDone(QNetworkReply::NetworkError error, + QByteArray data, + QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); qCDebug(authCredentials()) << data; if (error == QNetworkReply::ContentNotFoundError) { // NOTE: Succeed even if we do not have a profile. This is a valid account state. - if(m_data->type == AccountType::Mojang) { + if (m_data->type == AccountType::Mojang) { m_data->minecraftEntitlement.canPlayMinecraft = false; m_data->minecraftEntitlement.ownsMinecraft = false; } m_data->minecraftProfile = MinecraftProfile(); - emit finished( - AccountTaskState::STATE_SUCCEEDED, - tr("Account has no Minecraft profile.") - ); + emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Account has no Minecraft profile.")); return; } if (error != QNetworkReply::NoError) { @@ -68,35 +64,24 @@ void MinecraftProfileStepMojang::onRequestDone( qWarning() << QString::fromUtf8(data); if (Net::isApplicationError(error)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_) - ); - } - else { - emit finished( - AccountTaskState::STATE_OFFLINE, - tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)); + } else { + emit finished(AccountTaskState::STATE_OFFLINE, + tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_)); } return; } - if(!Parsers::parseMinecraftProfileMojang(data, m_data->minecraftProfile)) { + if (!Parsers::parseMinecraftProfileMojang(data, m_data->minecraftProfile)) { m_data->minecraftProfile = MinecraftProfile(); - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Minecraft Java profile response could not be parsed") - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Minecraft Java profile response could not be parsed")); return; } - if(m_data->type == AccountType::Mojang) { + if (m_data->type == AccountType::Mojang) { auto validProfile = m_data->minecraftProfile.validity == Katabasis::Validity::Certain; m_data->minecraftEntitlement.canPlayMinecraft = validProfile; m_data->minecraftEntitlement.ownsMinecraft = validProfile; } - emit finished( - AccountTaskState::STATE_WORKING, - tr("Minecraft Java profile acquisition succeeded.") - ); + emit finished(AccountTaskState::STATE_WORKING, tr("Minecraft Java profile acquisition succeeded.")); } diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h index e06b30ab0..730ec3f68 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h +++ b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class MinecraftProfileStepMojang : public AuthStep { Q_OBJECT -public: - explicit MinecraftProfileStepMojang(AccountData *data); + public: + explicit MinecraftProfileStepMojang(AccountData* data); virtual ~MinecraftProfileStepMojang() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/OfflineStep.cpp b/launcher/minecraft/auth/steps/OfflineStep.cpp index dc092bfd4..bf111abe8 100644 --- a/launcher/minecraft/auth/steps/OfflineStep.cpp +++ b/launcher/minecraft/auth/steps/OfflineStep.cpp @@ -5,14 +5,17 @@ OfflineStep::OfflineStep(AccountData* data) : AuthStep(data) {} OfflineStep::~OfflineStep() noexcept = default; -QString OfflineStep::describe() { +QString OfflineStep::describe() +{ return tr("Creating offline account."); } -void OfflineStep::rehydrate() { +void OfflineStep::rehydrate() +{ // NOOP } -void OfflineStep::perform() { +void OfflineStep::perform() +{ emit finished(AccountTaskState::STATE_WORKING, tr("Created offline account.")); } diff --git a/launcher/minecraft/auth/steps/OfflineStep.h b/launcher/minecraft/auth/steps/OfflineStep.h index 436597cd8..3bf123d6a 100644 --- a/launcher/minecraft/auth/steps/OfflineStep.h +++ b/launcher/minecraft/auth/steps/OfflineStep.h @@ -8,8 +8,8 @@ class OfflineStep : public AuthStep { Q_OBJECT -public: - explicit OfflineStep(AccountData *data); + public: + explicit OfflineStep(AccountData* data); virtual ~OfflineStep() noexcept; void perform() override; diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp index b397b7349..c33d7e629 100644 --- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp +++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp @@ -1,33 +1,32 @@ #include "XboxAuthorizationStep.h" -#include -#include #include +#include +#include #include "Logging.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" -XboxAuthorizationStep::XboxAuthorizationStep(AccountData* data, Katabasis::Token *token, QString relyingParty, QString authorizationKind): - AuthStep(data), - m_token(token), - m_relyingParty(relyingParty), - m_authorizationKind(authorizationKind) -{ -} +XboxAuthorizationStep::XboxAuthorizationStep(AccountData* data, Katabasis::Token* token, QString relyingParty, QString authorizationKind) + : AuthStep(data), m_token(token), m_relyingParty(relyingParty), m_authorizationKind(authorizationKind) +{} XboxAuthorizationStep::~XboxAuthorizationStep() noexcept = default; -QString XboxAuthorizationStep::describe() { +QString XboxAuthorizationStep::describe() +{ return tr("Getting authorization to access %1 services.").arg(m_authorizationKind); } -void XboxAuthorizationStep::rehydrate() { +void XboxAuthorizationStep::rehydrate() +{ // FIXME: check if the tokens are good? } -void XboxAuthorizationStep::perform() { +void XboxAuthorizationStep::perform() +{ QString xbox_auth_template = R"XXX( { "Properties": { @@ -41,129 +40,98 @@ void XboxAuthorizationStep::perform() { } )XXX"; auto xbox_auth_data = xbox_auth_template.arg(m_data->userToken.token, m_relyingParty); -// http://xboxlive.com + // http://xboxlive.com QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &XboxAuthorizationStep::onRequestDone); requestor->post(request, xbox_auth_data.toUtf8()); qDebug() << "Getting authorization token for " << m_relyingParty; } -void XboxAuthorizationStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void XboxAuthorizationStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); qCDebug(authCredentials()) << data; if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; if (Net::isApplicationError(error)) { - if(!processSTSError(error, data, headers)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, error) - ); + if (!processSTSError(error, data, headers)) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, error)); + } else { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, requestor->errorString_)); } - else { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, requestor->errorString_) - ); - } - } - else { - emit finished( - AccountTaskState::STATE_OFFLINE, - tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, requestor->errorString_) - ); + } else { + emit finished(AccountTaskState::STATE_OFFLINE, + tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, requestor->errorString_)); } return; } Katabasis::Token temp; - if(!Parsers::parseXTokenResponse(data, temp, m_authorizationKind)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Could not parse authorization response for access to %1 services.").arg(m_authorizationKind) - ); + if (!Parsers::parseXTokenResponse(data, temp, m_authorizationKind)) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Could not parse authorization response for access to %1 services.").arg(m_authorizationKind)); return; } - if(temp.extra["uhs"] != m_data->userToken.extra["uhs"]) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Server has changed %1 authorization user hash in the reply. Something is wrong.").arg(m_authorizationKind) - ); + if (temp.extra["uhs"] != m_data->userToken.extra["uhs"]) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Server has changed %1 authorization user hash in the reply. Something is wrong.").arg(m_authorizationKind)); return; } - auto & token = *m_token; + auto& token = *m_token; token = temp; emit finished(AccountTaskState::STATE_WORKING, tr("Got authorization to access %1").arg(m_relyingParty)); } - -bool XboxAuthorizationStep::processSTSError( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - if(error == QNetworkReply::AuthenticationRequiredError) { +bool XboxAuthorizationStep::processSTSError(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + if (error == QNetworkReply::AuthenticationRequiredError) { QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { + if (jsonError.error) { qWarning() << "Cannot parse error XSTS response as JSON: " << jsonError.errorString(); - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Cannot parse %1 authorization error response as JSON: %2").arg(m_authorizationKind, jsonError.errorString()) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Cannot parse %1 authorization error response as JSON: %2").arg(m_authorizationKind, jsonError.errorString())); return true; } int64_t errorCode = -1; auto obj = doc.object(); - if(!Parsers::getNumber(obj.value("XErr"), errorCode)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("XErr element is missing from %1 authorization error response.").arg(m_authorizationKind) - ); + if (!Parsers::getNumber(obj.value("XErr"), errorCode)) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("XErr element is missing from %1 authorization error response.").arg(m_authorizationKind)); return true; } - switch(errorCode) { - case 2148916233:{ - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("This Microsoft account does not have an XBox Live profile. Buy the game on %1 first.") - .arg("minecraft.net") - ); + switch (errorCode) { + case 2148916233: { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("This Microsoft account does not have an XBox Live profile. Buy the game on %1 first.") + .arg("minecraft.net")); return true; } case 2148916235: { // NOTE: this is the Grulovia error - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("XBox Live is not available in your country. You've been blocked.") - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox Live is not available in your country. You've been blocked.")); return true; } case 2148916238: { emit finished( AccountTaskState::STATE_FAILED_SOFT, tr("This Microsoft account is underaged and is not linked to a family.\n\nPlease set up your account according to %1.") - .arg("help.minecraft.net") - ); + .arg("help.minecraft.net")); return true; } default: { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("XSTS authentication ended with unrecognized error(s):\n\n%1").arg(errorCode) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("XSTS authentication ended with unrecognized error(s):\n\n%1").arg(errorCode)); return true; } } diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.h b/launcher/minecraft/auth/steps/XboxAuthorizationStep.h index 31e43bf05..dee24c954 100644 --- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.h +++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class XboxAuthorizationStep : public AuthStep { Q_OBJECT -public: - explicit XboxAuthorizationStep(AccountData *data, Katabasis::Token *token, QString relyingParty, QString authorizationKind); + public: + explicit XboxAuthorizationStep(AccountData* data, Katabasis::Token* token, QString relyingParty, QString authorizationKind); virtual ~XboxAuthorizationStep() noexcept; void perform() override; @@ -17,18 +16,14 @@ public: QString describe() override; -private: - bool processSTSError( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers - ); + private: + bool processSTSError(QNetworkReply::NetworkError error, QByteArray data, QList headers); -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); -private: - Katabasis::Token *m_token; + private: + Katabasis::Token* m_token; QString m_relyingParty; QString m_authorizationKind; }; diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.cpp b/launcher/minecraft/auth/steps/XboxProfileStep.cpp index 644c419b1..fd2b32cce 100644 --- a/launcher/minecraft/auth/steps/XboxProfileStep.cpp +++ b/launcher/minecraft/auth/steps/XboxProfileStep.cpp @@ -8,66 +8,56 @@ #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" -XboxProfileStep::XboxProfileStep(AccountData* data) : AuthStep(data) { - -} +XboxProfileStep::XboxProfileStep(AccountData* data) : AuthStep(data) {} XboxProfileStep::~XboxProfileStep() noexcept = default; -QString XboxProfileStep::describe() { +QString XboxProfileStep::describe() +{ return tr("Fetching Xbox profile."); } -void XboxProfileStep::rehydrate() { +void XboxProfileStep::rehydrate() +{ // NOOP, for now. We only save bools and there's nothing to check. } -void XboxProfileStep::perform() { +void XboxProfileStep::perform() +{ auto url = QUrl("https://profile.xboxlive.com/users/me/profile/settings"); QUrlQuery q; - q.addQueryItem( - "settings", - "GameDisplayName,AppDisplayName,AppDisplayPicRaw,GameDisplayPicRaw," - "PublicGamerpic,ShowUserAsAvatar,Gamerscore,Gamertag,ModernGamertag,ModernGamertagSuffix," - "UniqueModernGamertag,AccountTier,TenureLevel,XboxOneRep," - "PreferredColor,Location,Bio,Watermarks," - "RealName,RealNameOverride,IsQuarantined" - ); + q.addQueryItem("settings", + "GameDisplayName,AppDisplayName,AppDisplayPicRaw,GameDisplayPicRaw," + "PublicGamerpic,ShowUserAsAvatar,Gamerscore,Gamertag,ModernGamertag,ModernGamertagSuffix," + "UniqueModernGamertag,AccountTier,TenureLevel,XboxOneRep," + "PreferredColor,Location,Bio,Watermarks," + "RealName,RealNameOverride,IsQuarantined"); url.setQuery(q); QNetworkRequest request = QNetworkRequest(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); request.setRawHeader("x-xbl-contract-version", "3"); - request.setRawHeader("Authorization", QString("XBL3.0 x=%1;%2").arg(m_data->userToken.extra["uhs"].toString(), m_data->xboxApiToken.token).toUtf8()); - AuthRequest *requestor = new AuthRequest(this); + request.setRawHeader("Authorization", + QString("XBL3.0 x=%1;%2").arg(m_data->userToken.extra["uhs"].toString(), m_data->xboxApiToken.token).toUtf8()); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &XboxProfileStep::onRequestDone); requestor->get(request); qDebug() << "Getting Xbox profile..."; } -void XboxProfileStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void XboxProfileStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; qCDebug(authCredentials()) << data; if (Net::isApplicationError(error)) { - emit finished( - AccountTaskState::STATE_FAILED_SOFT, - tr("Failed to retrieve the Xbox profile: %1").arg(requestor->errorString_) - ); - } - else { - emit finished( - AccountTaskState::STATE_OFFLINE, - tr("Failed to retrieve the Xbox profile: %1").arg(requestor->errorString_) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to retrieve the Xbox profile: %1").arg(requestor->errorString_)); + } else { + emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to retrieve the Xbox profile: %1").arg(requestor->errorString_)); } return; } diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.h b/launcher/minecraft/auth/steps/XboxProfileStep.h index 7a0c5873d..b8494b6e5 100644 --- a/launcher/minecraft/auth/steps/XboxProfileStep.h +++ b/launcher/minecraft/auth/steps/XboxProfileStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class XboxProfileStep : public AuthStep { Q_OBJECT -public: - explicit XboxProfileStep(AccountData *data); + public: + explicit XboxProfileStep(AccountData* data); virtual ~XboxProfileStep() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/XboxUserStep.cpp b/launcher/minecraft/auth/steps/XboxUserStep.cpp index 842eb60ff..61c33a18d 100644 --- a/launcher/minecraft/auth/steps/XboxUserStep.cpp +++ b/launcher/minecraft/auth/steps/XboxUserStep.cpp @@ -6,22 +6,22 @@ #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" -XboxUserStep::XboxUserStep(AccountData* data) : AuthStep(data) { - -} +XboxUserStep::XboxUserStep(AccountData* data) : AuthStep(data) {} XboxUserStep::~XboxUserStep() noexcept = default; -QString XboxUserStep::describe() { +QString XboxUserStep::describe() +{ return tr("Logging in as an Xbox user."); } - -void XboxUserStep::rehydrate() { +void XboxUserStep::rehydrate() +{ // NOOP, for now. We only save bools and there's nothing to check. } -void XboxUserStep::perform() { +void XboxUserStep::perform() +{ QString xbox_auth_template = R"XXX( { "Properties": { @@ -40,40 +40,31 @@ void XboxUserStep::perform() { request.setRawHeader("Accept", "application/json"); // set contract-verison header (prevent err 400 bad-request?) // https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/reference/live/rest/additional/httpstandardheaders - request.setRawHeader("x-xbl-contract-version", "1"); + request.setRawHeader("x-xbl-contract-version", "1"); - auto *requestor = new AuthRequest(this); + auto* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &XboxUserStep::onRequestDone); requestor->post(request, xbox_auth_data.toUtf8()); qDebug() << "First layer of XBox auth ... commencing."; } -void XboxUserStep::onRequestDone( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void XboxUserStep::onRequestDone(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; if (Net::isApplicationError(error)) { - emit finished(AccountTaskState::STATE_FAILED_SOFT, - tr("XBox user authentication failed: %1").arg(requestor->errorString_) - ); - } - else { - emit finished( - AccountTaskState::STATE_OFFLINE, - tr("XBox user authentication failed: %1").arg(requestor->errorString_) - ); + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed: %1").arg(requestor->errorString_)); + } else { + emit finished(AccountTaskState::STATE_OFFLINE, tr("XBox user authentication failed: %1").arg(requestor->errorString_)); } return; } Katabasis::Token temp; - if(!Parsers::parseXTokenResponse(data, temp, "UToken")) { + if (!Parsers::parseXTokenResponse(data, temp, "UToken")) { qWarning() << "Could not parse user authentication response..."; emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication response could not be understood.")); return; diff --git a/launcher/minecraft/auth/steps/XboxUserStep.h b/launcher/minecraft/auth/steps/XboxUserStep.h index 83e9405f4..e92727a4d 100644 --- a/launcher/minecraft/auth/steps/XboxUserStep.h +++ b/launcher/minecraft/auth/steps/XboxUserStep.h @@ -4,12 +4,11 @@ #include "QObjectPtr.h" #include "minecraft/auth/AuthStep.h" - class XboxUserStep : public AuthStep { Q_OBJECT -public: - explicit XboxUserStep(AccountData *data); + public: + explicit XboxUserStep(AccountData* data); virtual ~XboxUserStep() noexcept; void perform() override; @@ -17,6 +16,6 @@ public: QString describe() override; -private slots: + private slots: void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); }; diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.cpp b/launcher/minecraft/auth/steps/YggdrasilStep.cpp index e1d331726..fdcaa0d67 100644 --- a/launcher/minecraft/auth/steps/YggdrasilStep.cpp +++ b/launcher/minecraft/auth/steps/YggdrasilStep.cpp @@ -4,7 +4,8 @@ #include "minecraft/auth/Parsers.h" #include "minecraft/auth/Yggdrasil.h" -YggdrasilStep::YggdrasilStep(AccountData* data, QString password) : AuthStep(data), m_password(password) { +YggdrasilStep::YggdrasilStep(AccountData* data, QString password) : AuthStep(data), m_password(password) +{ m_yggdrasil = new Yggdrasil(m_data, this); connect(m_yggdrasil, &Task::failed, this, &YggdrasilStep::onAuthFailed); @@ -14,28 +15,32 @@ YggdrasilStep::YggdrasilStep(AccountData* data, QString password) : AuthStep(dat YggdrasilStep::~YggdrasilStep() noexcept = default; -QString YggdrasilStep::describe() { +QString YggdrasilStep::describe() +{ return tr("Logging in with Mojang account."); } -void YggdrasilStep::rehydrate() { +void YggdrasilStep::rehydrate() +{ // NOOP, for now. } -void YggdrasilStep::perform() { - if(m_password.size()) { +void YggdrasilStep::perform() +{ + if (m_password.size()) { m_yggdrasil->login(m_password); - } - else { + } else { m_yggdrasil->refresh(); } } -void YggdrasilStep::onAuthSucceeded() { +void YggdrasilStep::onAuthSucceeded() +{ emit finished(AccountTaskState::STATE_WORKING, tr("Logged in with Mojang")); } -void YggdrasilStep::onAuthFailed() { +void YggdrasilStep::onAuthFailed() +{ // TODO: hook these in again, expand to MSA // m_error = m_yggdrasil->m_error; // m_aborted = m_yggdrasil->m_aborted; @@ -44,7 +49,7 @@ void YggdrasilStep::onAuthFailed() { QString errorMessage = tr("Mojang user authentication failed."); // NOTE: soft error in the first step means 'offline' - if(state == AccountTaskState::STATE_FAILED_SOFT) { + if (state == AccountTaskState::STATE_FAILED_SOFT) { state = AccountTaskState::STATE_OFFLINE; errorMessage = tr("Mojang user authentication ended with a network error."); } diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.h b/launcher/minecraft/auth/steps/YggdrasilStep.h index ebafb8e5b..ef31f34d5 100644 --- a/launcher/minecraft/auth/steps/YggdrasilStep.h +++ b/launcher/minecraft/auth/steps/YggdrasilStep.h @@ -9,8 +9,8 @@ class Yggdrasil; class YggdrasilStep : public AuthStep { Q_OBJECT -public: - explicit YggdrasilStep(AccountData *data, QString password); + public: + explicit YggdrasilStep(AccountData* data, QString password); virtual ~YggdrasilStep() noexcept; void perform() override; @@ -18,11 +18,11 @@ public: QString describe() override; -private slots: + private slots: void onAuthSucceeded(); void onAuthFailed(); -private: - Yggdrasil *m_yggdrasil = nullptr; + private: + Yggdrasil* m_yggdrasil = nullptr; QString m_password; }; diff --git a/launcher/minecraft/gameoptions/GameOptions.cpp b/launcher/minecraft/gameoptions/GameOptions.cpp index e547b32a3..443525ae4 100644 --- a/launcher/minecraft/gameoptions/GameOptions.cpp +++ b/launcher/minecraft/gameoptions/GameOptions.cpp @@ -1,59 +1,51 @@ #include "GameOptions.h" -#include "FileSystem.h" #include #include +#include "FileSystem.h" namespace { -bool load(const QString& path, std::vector &contents, int & version) +bool load(const QString& path, std::vector& contents, int& version) { contents.clear(); QFile file(path); - if (!file.open(QFile::ReadOnly)) - { + if (!file.open(QFile::ReadOnly)) { qWarning() << "Failed to read options file."; return false; } version = 0; - while(!file.atEnd()) - { + while (!file.atEnd()) { auto line = file.readLine(); - if(line.endsWith('\n')) - { + if (line.endsWith('\n')) { line.chop(1); } auto separatorIndex = line.indexOf(':'); - if(separatorIndex == -1) - { + if (separatorIndex == -1) { continue; } auto key = QString::fromUtf8(line.data(), separatorIndex); auto value = QString::fromUtf8(line.data() + separatorIndex + 1, line.size() - 1 - separatorIndex); qDebug() << "!!" << key << "!!"; - if(key == "version") - { + if (key == "version") { version = value.toInt(); continue; } - contents.emplace_back(GameOptionItem{key, value}); + contents.emplace_back(GameOptionItem{ key, value }); } qDebug() << "Loaded" << path << "with version:" << version; return true; } -bool save(const QString& path, std::vector &mapping, int version) +bool save(const QString& path, std::vector& mapping, int version) { QSaveFile out(path); - if(!out.open(QIODevice::WriteOnly)) - { + if (!out.open(QIODevice::WriteOnly)) { return false; } - if(version != 0) - { + if (version != 0) { QString versionLine = QString("version:%1\n").arg(version); out.write(versionLine.toUtf8()); } auto iter = mapping.begin(); - while (iter != mapping.end()) - { + while (iter != mapping.end()) { out.write(iter->key.toUtf8()); out.write(":"); out.write(iter->value.toUtf8()); @@ -62,22 +54,19 @@ bool save(const QString& path, std::vector &mapping, int version } return out.commit(); } -} +} // namespace -GameOptions::GameOptions(const QString& path): - path(path) +GameOptions::GameOptions(const QString& path) : path(path) { reload(); } QVariant GameOptions::headerData(int section, Qt::Orientation orientation, int role) const { - if(role != Qt::DisplayRole) - { + if (role != Qt::DisplayRole) { return QAbstractListModel::headerData(section, orientation, role); } - switch(section) - { + switch (section) { case 0: return tr("Key"); case 1: @@ -98,19 +87,15 @@ QVariant GameOptions::data(const QModelIndex& index, int role) const if (row < 0 || row >= int(contents.size())) return QVariant(); - switch (role) - { - case Qt::DisplayRole: - if(column == 0) - { - return contents[row].key; - } - else - { - return contents[row].value; - } - default: - return QVariant(); + switch (role) { + case Qt::DisplayRole: + if (column == 0) { + return contents[row].key; + } else { + return contents[row].value; + } + default: + return QVariant(); } return QVariant(); } diff --git a/launcher/minecraft/gameoptions/GameOptions.h b/launcher/minecraft/gameoptions/GameOptions.h index c6d254928..ae031efb2 100644 --- a/launcher/minecraft/gameoptions/GameOptions.h +++ b/launcher/minecraft/gameoptions/GameOptions.h @@ -1,32 +1,30 @@ #pragma once -#include -#include #include +#include +#include -struct GameOptionItem -{ +struct GameOptionItem { QString key; QString value; }; -class GameOptions : public QAbstractListModel -{ +class GameOptions : public QAbstractListModel { Q_OBJECT -public: + public: explicit GameOptions(const QString& path); virtual ~GameOptions() = default; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex & parent) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; bool isLoaded() const; bool reload(); bool save(); -private: + private: std::vector contents; bool loaded = false; QString path; diff --git a/launcher/minecraft/launch/ClaimAccount.cpp b/launcher/minecraft/launch/ClaimAccount.cpp index 1cd7c0da7..a3de1516a 100644 --- a/launcher/minecraft/launch/ClaimAccount.cpp +++ b/launcher/minecraft/launch/ClaimAccount.cpp @@ -4,10 +4,9 @@ #include "Application.h" #include "minecraft/auth/AccountList.h" -ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session): LaunchStep(parent) +ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session) : LaunchStep(parent) { - if(session->status == AuthSession::Status::PlayableOnline && !session->demo) - { + if (session->status == AuthSession::Status::PlayableOnline && !session->demo) { auto accounts = APPLICATION->accounts(); m_account = accounts->getAccountByProfileName(session->player_name); } @@ -15,8 +14,7 @@ ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session): LaunchSt void ClaimAccount::executeTask() { - if(m_account) - { + if (m_account) { lock.reset(new UseLock(m_account)); emitSucceeded(); } diff --git a/launcher/minecraft/launch/ClaimAccount.h b/launcher/minecraft/launch/ClaimAccount.h index cb4de23f5..3d47539ac 100644 --- a/launcher/minecraft/launch/ClaimAccount.h +++ b/launcher/minecraft/launch/ClaimAccount.h @@ -18,20 +18,17 @@ #include #include -class ClaimAccount: public LaunchStep -{ +class ClaimAccount : public LaunchStep { Q_OBJECT -public: - explicit ClaimAccount(LaunchTask *parent, AuthSessionPtr session); - virtual ~ClaimAccount() {}; + public: + explicit ClaimAccount(LaunchTask* parent, AuthSessionPtr session); + virtual ~ClaimAccount(){}; void executeTask() override; void finalize() override; - bool canAbort() const override - { - return false; - } -private: + bool canAbort() const override { return false; } + + private: std::unique_ptr lock; MinecraftAccountPtr m_account; }; diff --git a/launcher/minecraft/launch/CreateGameFolders.cpp b/launcher/minecraft/launch/CreateGameFolders.cpp index 4081e72ed..36f5e6407 100644 --- a/launcher/minecraft/launch/CreateGameFolders.cpp +++ b/launcher/minecraft/launch/CreateGameFolders.cpp @@ -1,27 +1,23 @@ #include "CreateGameFolders.h" -#include "minecraft/MinecraftInstance.h" -#include "launch/LaunchTask.h" #include "FileSystem.h" +#include "launch/LaunchTask.h" +#include "minecraft/MinecraftInstance.h" -CreateGameFolders::CreateGameFolders(LaunchTask* parent): LaunchStep(parent) -{ -} +CreateGameFolders::CreateGameFolders(LaunchTask* parent) : LaunchStep(parent) {} void CreateGameFolders::executeTask() { auto instance = m_parent->instance(); std::shared_ptr minecraftInstance = std::dynamic_pointer_cast(instance); - if(!FS::ensureFolderPathExists(minecraftInstance->gameRoot())) - { + if (!FS::ensureFolderPathExists(minecraftInstance->gameRoot())) { emit logLine("Couldn't create the main game folder", MessageLevel::Error); emitFailed(tr("Couldn't create the main game folder")); return; } // HACK: this is a workaround for MCL-3732 - 'server-resource-packs' folder is created. - if(!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->gameRoot(), "server-resource-packs"))) - { + if (!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->gameRoot(), "server-resource-packs"))) { emit logLine("Couldn't create the 'server-resource-packs' folder", MessageLevel::Error); } emitSucceeded(); diff --git a/launcher/minecraft/launch/CreateGameFolders.h b/launcher/minecraft/launch/CreateGameFolders.h index 9c7d3c940..44524ded5 100644 --- a/launcher/minecraft/launch/CreateGameFolders.h +++ b/launcher/minecraft/launch/CreateGameFolders.h @@ -15,23 +15,17 @@ #pragma once -#include #include +#include #include // Create the main .minecraft for the instance and any other necessary folders -class CreateGameFolders: public LaunchStep -{ +class CreateGameFolders : public LaunchStep { Q_OBJECT -public: - explicit CreateGameFolders(LaunchTask *parent); - virtual ~CreateGameFolders() {}; + public: + explicit CreateGameFolders(LaunchTask* parent); + virtual ~CreateGameFolders(){}; virtual void executeTask(); - virtual bool canAbort() const - { - return false; - } + virtual bool canAbort() const { return false; } }; - - diff --git a/launcher/minecraft/launch/ExtractNatives.cpp b/launcher/minecraft/launch/ExtractNatives.cpp index 7d5f41791..cebeaedd4 100644 --- a/launcher/minecraft/launch/ExtractNatives.cpp +++ b/launcher/minecraft/launch/ExtractNatives.cpp @@ -14,26 +14,25 @@ */ #include "ExtractNatives.h" -#include #include +#include #include #include -#include "MMCZip.h" -#include "FileSystem.h" #include +#include "FileSystem.h" +#include "MMCZip.h" #ifdef major - #undef major +#undef major #endif #ifdef minor - #undef minor +#undef minor #endif -static QString replaceSuffix (QString target, const QString &suffix, const QString &replacement) +static QString replaceSuffix(QString target, const QString& suffix, const QString& replacement) { - if (!target.endsWith(suffix)) - { + if (!target.endsWith(suffix)) { return target; } target.resize(target.length() - suffix.length()); @@ -43,17 +42,14 @@ static QString replaceSuffix (QString target, const QString &suffix, const QStri static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibHack, bool nativeOpenAL, bool nativeGLFW) { QuaZip zip(source); - if(!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { return false; } QDir directory(targetFolder); - if (!zip.goToFirstFile()) - { + if (!zip.goToFirstFile()) { return false; } - do - { + do { QString name = zip.getCurrentFileName(); auto lowercase = name.toLower(); if (nativeGLFW && name.contains("glfw")) { @@ -62,19 +58,16 @@ static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibH if (nativeOpenAL && name.contains("openal")) { continue; } - if(applyJnilibHack) - { + if (applyJnilibHack) { name = replaceSuffix(name, ".jnilib", ".dylib"); } QString absFilePath = directory.absoluteFilePath(name); - if (!JlCompress::extractFile(&zip, "", absFilePath)) - { + if (!JlCompress::extractFile(&zip, "", absFilePath)) { return false; } } while (zip.goToNextFile()); zip.close(); - if(zip.getZipError()!=0) - { + if (zip.getZipError() != 0) { return false; } return true; @@ -85,8 +78,7 @@ void ExtractNatives::executeTask() auto instance = m_parent->instance(); std::shared_ptr minecraftInstance = std::dynamic_pointer_cast(instance); auto toExtract = minecraftInstance->getNativeJars(); - if(toExtract.isEmpty()) - { + if (toExtract.isEmpty()) { emitSucceeded(); return; } @@ -94,14 +86,12 @@ void ExtractNatives::executeTask() bool nativeOpenAL = settings->get("UseNativeOpenAL").toBool(); bool nativeGLFW = settings->get("UseNativeGLFW").toBool(); - auto outputPath = minecraftInstance->getNativePath(); + auto outputPath = minecraftInstance->getNativePath(); auto javaVersion = minecraftInstance->getJavaVersion(); bool jniHackEnabled = javaVersion.major() >= 8; - for(const auto &source: toExtract) - { - if(!unzipNatives(source, outputPath, jniHackEnabled, nativeOpenAL, nativeGLFW)) - { - const char *reason = QT_TR_NOOP("Couldn't extract native jar '%1' to destination '%2'"); + for (const auto& source : toExtract) { + if (!unzipNatives(source, outputPath, jniHackEnabled, nativeOpenAL, nativeGLFW)) { + const char* reason = QT_TR_NOOP("Couldn't extract native jar '%1' to destination '%2'"); emit logLine(QString(reason).arg(source, outputPath), MessageLevel::Fatal); emitFailed(tr(reason).arg(source, outputPath)); } diff --git a/launcher/minecraft/launch/ExtractNatives.h b/launcher/minecraft/launch/ExtractNatives.h index 094fcd6bb..2ab8816bd 100644 --- a/launcher/minecraft/launch/ExtractNatives.h +++ b/launcher/minecraft/launch/ExtractNatives.h @@ -20,19 +20,13 @@ #include "minecraft/auth/AuthSession.h" // FIXME: temporary wrapper for existing task. -class ExtractNatives: public LaunchStep -{ +class ExtractNatives : public LaunchStep { Q_OBJECT -public: - explicit ExtractNatives(LaunchTask *parent) : LaunchStep(parent){}; + public: + explicit ExtractNatives(LaunchTask* parent) : LaunchStep(parent){}; virtual ~ExtractNatives(){}; void executeTask() override; - bool canAbort() const override - { - return false; - } + bool canAbort() const override { return false; } void finalize() override; }; - - diff --git a/launcher/minecraft/launch/LauncherPartLaunch.cpp b/launcher/minecraft/launch/LauncherPartLaunch.cpp index 8ecf715db..e5f919d79 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.cpp +++ b/launcher/minecraft/launch/LauncherPartLaunch.cpp @@ -35,29 +35,27 @@ #include "LauncherPartLaunch.h" -#include #include +#include +#include "Application.h" +#include "Commandline.h" +#include "FileSystem.h" #include "launch/LaunchTask.h" #include "minecraft/MinecraftInstance.h" -#include "FileSystem.h" -#include "Commandline.h" -#include "Application.h" #ifdef Q_OS_LINUX #include "gamemode_client.h" #endif -LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent) +LauncherPartLaunch::LauncherPartLaunch(LaunchTask* parent) : LaunchStep(parent) { auto instance = parent->instance(); - if (instance->settings()->get("CloseAfterLaunch").toBool()) - { - std::shared_ptr connection{new QMetaObject::Connection}; + if (instance->settings()->get("CloseAfterLaunch").toBool()) { + std::shared_ptr connection{ new QMetaObject::Connection }; *connection = connect(&m_process, &LoggedProcess::log, this, [=](QStringList lines, MessageLevel::Enum level) { qDebug() << lines; - if (lines.filter(QRegularExpression(".*Setting user.+", QRegularExpression::CaseInsensitiveOption)).length() != 0) - { + if (lines.filter(QRegularExpression(".*Setting user.+", QRegularExpression::CaseInsensitiveOption)).length() != 0) { APPLICATION->closeAllWindows(); disconnect(*connection); } @@ -71,7 +69,7 @@ LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent) #ifdef Q_OS_WIN // returns 8.3 file format from long path #include -QString shortPathName(const QString & file) +QString shortPathName(const QString& file) { auto input = file.toStdWString(); std::wstring output; @@ -81,15 +79,15 @@ QString shortPathName(const QString & file) // when it succeeds, it returns length excluding null character // See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989(v=vs.85).aspx output.resize(length); - GetShortPathNameW(input.c_str(),(LPWSTR)output.c_str(),length); - output.resize(length-1); + GetShortPathNameW(input.c_str(), (LPWSTR)output.c_str(), length); + output.resize(length - 1); QString ret = QString::fromStdWString(output); return ret; } #endif // if the string survives roundtrip through local 8bit encoding... -bool fitsInLocal8bit(const QString & string) +bool fitsInLocal8bit(const QString& string) { return string == QString::fromLocal8Bit(string.toLocal8Bit()); } @@ -97,9 +95,8 @@ bool fitsInLocal8bit(const QString & string) void LauncherPartLaunch::executeTask() { QString jarPath = APPLICATION->getJarPath("NewLaunch.jar"); - if (jarPath.isEmpty()) - { - const char *reason = QT_TR_NOOP("Launcher library could not be found. Please check your installation."); + if (jarPath.isEmpty()) { + const char* reason = QT_TR_NOOP("Launcher library could not be found. Please check your installation."); emit logLine(tr(reason), MessageLevel::Fatal); emitFailed(tr(reason)); return; @@ -125,12 +122,9 @@ void LauncherPartLaunch::executeTask() auto natPath = minecraftInstance->getNativePath(); #ifdef Q_OS_WIN - if (!fitsInLocal8bit(natPath)) - { + if (!fitsInLocal8bit(natPath)) { args << "-Djava.library.path=" + shortPathName(natPath); - } - else - { + } else { args << "-Djava.library.path=" + natPath; } #else @@ -140,14 +134,10 @@ void LauncherPartLaunch::executeTask() args << "-cp"; #ifdef Q_OS_WIN QStringList processed; - for(auto & item: classPath) - { - if (!fitsInLocal8bit(item)) - { + for (auto& item : classPath) { + if (!fitsInLocal8bit(item)) { processed << shortPathName(item); - } - else - { + } else { processed << item; } } @@ -160,14 +150,12 @@ void LauncherPartLaunch::executeTask() qDebug() << args.join(' '); QString wrapperCommandStr = instance->getWrapperCommand().trimmed(); - if(!wrapperCommandStr.isEmpty()) - { + if (!wrapperCommandStr.isEmpty()) { auto wrapperArgs = Commandline::splitArgs(wrapperCommandStr); auto wrapperCommand = wrapperArgs.takeFirst(); auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand); - if (realWrapperCommand.isEmpty()) - { - const char *reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); + if (realWrapperCommand.isEmpty()) { + const char* reason = QT_TR_NOOP("The wrapper command \"%1\" couldn't be found."); emit logLine(QString(reason).arg(wrapperCommand), MessageLevel::Fatal); emitFailed(tr(reason).arg(wrapperCommand)); return; @@ -175,18 +163,14 @@ void LauncherPartLaunch::executeTask() emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::Launcher); args.prepend(javaPath); m_process.start(wrapperCommand, wrapperArgs + args); - } - else - { + } else { m_process.start(javaPath, args); } #ifdef Q_OS_LINUX - if (instance->settings()->get("EnableFeralGamemode").toBool() && APPLICATION->capabilities() & Application::SupportsGameMode) - { + if (instance->settings()->get("EnableFeralGamemode").toBool() && APPLICATION->capabilities() & Application::SupportsGameMode) { auto pid = m_process.processId(); - if (pid) - { + if (pid) { gamemode_request_start_for(pid); } } @@ -195,25 +179,21 @@ void LauncherPartLaunch::executeTask() void LauncherPartLaunch::on_state(LoggedProcess::State state) { - switch(state) - { - case LoggedProcess::FailedToStart: - { + switch (state) { + case LoggedProcess::FailedToStart: { //: Error message displayed if instace can't start - const char *reason = QT_TR_NOOP("Could not launch Minecraft!"); + const char* reason = QT_TR_NOOP("Could not launch Minecraft!"); emit logLine(reason, MessageLevel::Fatal); emitFailed(tr(reason)); return; } case LoggedProcess::Aborted: - case LoggedProcess::Crashed: - { + case LoggedProcess::Crashed: { m_parent->setPid(-1); emitFailed(tr("Game crashed.")); return; } - case LoggedProcess::Finished: - { + case LoggedProcess::Finished: { auto instance = m_parent->instance(); if (instance->settings()->get("CloseAfterLaunch").toBool()) APPLICATION->showMainWindow(); @@ -221,14 +201,13 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) m_parent->setPid(-1); // if the exit code wasn't 0, report this as a crash auto exitCode = m_process.exitCode(); - if(exitCode != 0) - { + if (exitCode != 0) { emitFailed(tr("Game crashed.")); return; } - //FIXME: make this work again - // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode)); - // run post-exit + // FIXME: make this work again + // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode)); + // run post-exit emitSucceeded(); break; } @@ -247,15 +226,14 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) } } -void LauncherPartLaunch::setWorkingDirectory(const QString &wd) +void LauncherPartLaunch::setWorkingDirectory(const QString& wd) { m_process.setWorkingDirectory(wd); } void LauncherPartLaunch::proceed() { - if(mayProceed) - { + if (mayProceed) { QString launchString("launch\n"); m_process.write(launchString.toUtf8()); mayProceed = false; @@ -264,17 +242,13 @@ void LauncherPartLaunch::proceed() bool LauncherPartLaunch::abort() { - if(mayProceed) - { + if (mayProceed) { mayProceed = false; QString launchString("abort\n"); m_process.write(launchString.toUtf8()); - } - else - { + } else { auto state = m_process.state(); - if (state == LoggedProcess::Running || state == LoggedProcess::Starting) - { + if (state == LoggedProcess::Running || state == LoggedProcess::Starting) { m_process.kill(); } } diff --git a/launcher/minecraft/launch/LauncherPartLaunch.h b/launcher/minecraft/launch/LauncherPartLaunch.h index 6a7ee0e5f..9f6ca1e7b 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.h +++ b/launcher/minecraft/launch/LauncherPartLaunch.h @@ -15,41 +15,31 @@ #pragma once -#include #include +#include #include #include "MinecraftServerTarget.h" -class LauncherPartLaunch: public LaunchStep -{ +class LauncherPartLaunch : public LaunchStep { Q_OBJECT -public: - explicit LauncherPartLaunch(LaunchTask *parent); - virtual ~LauncherPartLaunch() {}; + public: + explicit LauncherPartLaunch(LaunchTask* parent); + virtual ~LauncherPartLaunch(){}; virtual void executeTask(); virtual bool abort(); virtual void proceed(); - virtual bool canAbort() const - { - return true; - } - void setWorkingDirectory(const QString &wd); - void setAuthSession(AuthSessionPtr session) - { - m_session = session; - } + virtual bool canAbort() const { return true; } + void setWorkingDirectory(const QString& wd); + void setAuthSession(AuthSessionPtr session) { m_session = session; } - void setServerToJoin(MinecraftServerTargetPtr serverToJoin) - { - m_serverToJoin = std::move(serverToJoin); - } + void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { m_serverToJoin = std::move(serverToJoin); } -private slots: + private slots: void on_state(LoggedProcess::State state); -private: + private: LoggedProcess m_process; QString m_command; AuthSessionPtr m_session; diff --git a/launcher/minecraft/launch/MinecraftServerTarget.cpp b/launcher/minecraft/launch/MinecraftServerTarget.cpp index a3383ec08..e201efab1 100644 --- a/launcher/minecraft/launch/MinecraftServerTarget.cpp +++ b/launcher/minecraft/launch/MinecraftServerTarget.cpp @@ -18,50 +18,43 @@ #include // FIXME: the way this is written, it can't ever do any sort of validation and can accept total junk -MinecraftServerTarget MinecraftServerTarget::parse(const QString &fullAddress) { +MinecraftServerTarget MinecraftServerTarget::parse(const QString& fullAddress) +{ QStringList split = fullAddress.split(":"); // The logic below replicates the exact logic minecraft uses for parsing server addresses. // While the conversion is not lossless and eats errors, it ensures the same behavior // within Minecraft and Prism Launcher when entering server addresses. - if (fullAddress.startsWith("[")) - { + if (fullAddress.startsWith("[")) { int bracket = fullAddress.indexOf("]"); - if (bracket > 0) - { + if (bracket > 0) { QString ipv6 = fullAddress.mid(1, bracket - 1); QString port = fullAddress.mid(bracket + 1).trimmed(); - if (port.startsWith(":") && !ipv6.isEmpty()) - { + if (port.startsWith(":") && !ipv6.isEmpty()) { port = port.mid(1); split = QStringList({ ipv6, port }); - } - else - { - split = QStringList({ipv6}); + } else { + split = QStringList({ ipv6 }); } } } - if (split.size() > 2) - { - split = QStringList({fullAddress}); + if (split.size() > 2) { + split = QStringList({ fullAddress }); } QString realAddress = split[0]; quint16 realPort = 25565; - if (split.size() > 1) - { + if (split.size() > 1) { bool ok; realPort = split[1].toUInt(&ok); - if (!ok) - { + if (!ok) { realPort = 25565; } } - return MinecraftServerTarget { realAddress, realPort }; + return MinecraftServerTarget{ realAddress, realPort }; } diff --git a/launcher/minecraft/launch/MinecraftServerTarget.h b/launcher/minecraft/launch/MinecraftServerTarget.h index a402421af..af8d6550b 100644 --- a/launcher/minecraft/launch/MinecraftServerTarget.h +++ b/launcher/minecraft/launch/MinecraftServerTarget.h @@ -23,7 +23,7 @@ struct MinecraftServerTarget { QString address; quint16 port; - static MinecraftServerTarget parse(const QString &fullAddress); + static MinecraftServerTarget parse(const QString& fullAddress); }; typedef std::shared_ptr MinecraftServerTargetPtr; diff --git a/launcher/minecraft/launch/ModMinecraftJar.cpp b/launcher/minecraft/launch/ModMinecraftJar.cpp index 1d6eecf2d..f858dd740 100644 --- a/launcher/minecraft/launch/ModMinecraftJar.cpp +++ b/launcher/minecraft/launch/ModMinecraftJar.cpp @@ -34,9 +34,9 @@ */ #include "ModMinecraftJar.h" -#include "launch/LaunchTask.h" -#include "MMCZip.h" #include "FileSystem.h" +#include "MMCZip.h" +#include "launch/LaunchTask.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" @@ -44,20 +44,17 @@ void ModMinecraftJar::executeTask() { auto m_inst = std::dynamic_pointer_cast(m_parent->instance()); - if(!m_inst->getJarMods().size()) - { + if (!m_inst->getJarMods().size()) { emitSucceeded(); return; } // nuke obsolete stripped jar(s) if needed - if(!FS::ensureFolderPathExists(m_inst->binRoot())) - { + if (!FS::ensureFolderPathExists(m_inst->binRoot())) { emitFailed(tr("Couldn't create the bin folder for Minecraft.jar")); } auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar"); - if(!removeJar()) - { + if (!removeJar()) { emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath)); } @@ -65,14 +62,12 @@ void ModMinecraftJar::executeTask() auto components = m_inst->getPackProfile(); auto profile = components->getProfile(); auto jarMods = m_inst->getJarMods(); - if(jarMods.size()) - { + if (jarMods.size()) { auto mainJar = profile->getMainJar(); QStringList jars, temp1, temp2, temp3, temp4; mainJar->getApplicableFiles(m_inst->runtimeContext(), jars, temp1, temp2, temp3, m_inst->getLocalLibraryPath()); auto sourceJarPath = jars[0]; - if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods)) - { + if (!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods)) { emitFailed(tr("Failed to create the custom Minecraft jar file.")); return; } @@ -90,10 +85,8 @@ bool ModMinecraftJar::removeJar() auto m_inst = std::dynamic_pointer_cast(m_parent->instance()); auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar"); QFile finalJar(finalJarPath); - if(finalJar.exists()) - { - if(!finalJar.remove()) - { + if (finalJar.exists()) { + if (!finalJar.remove()) { return false; } } diff --git a/launcher/minecraft/launch/ModMinecraftJar.h b/launcher/minecraft/launch/ModMinecraftJar.h index 081c6a914..12e73b5f8 100644 --- a/launcher/minecraft/launch/ModMinecraftJar.h +++ b/launcher/minecraft/launch/ModMinecraftJar.h @@ -18,19 +18,16 @@ #include #include -class ModMinecraftJar: public LaunchStep -{ +class ModMinecraftJar : public LaunchStep { Q_OBJECT -public: - explicit ModMinecraftJar(LaunchTask *parent) : LaunchStep(parent) {}; + public: + explicit ModMinecraftJar(LaunchTask* parent) : LaunchStep(parent){}; virtual ~ModMinecraftJar(){}; virtual void executeTask() override; - virtual bool canAbort() const override - { - return false; - } + virtual bool canAbort() const override { return false; } void finalize() override; -private: + + private: bool removeJar(); }; diff --git a/launcher/minecraft/launch/PrintInstanceInfo.cpp b/launcher/minecraft/launch/PrintInstanceInfo.cpp index e8fbcb9b7..e3a45b030 100644 --- a/launcher/minecraft/launch/PrintInstanceInfo.cpp +++ b/launcher/minecraft/launch/PrintInstanceInfo.cpp @@ -16,50 +16,44 @@ #include #include -#include "PrintInstanceInfo.h" #include +#include "PrintInstanceInfo.h" #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) namespace { #if defined(Q_OS_LINUX) -void probeProcCpuinfo(QStringList &log) +void probeProcCpuinfo(QStringList& log) { std::ifstream cpuin("/proc/cpuinfo"); - for (std::string line; std::getline(cpuin, line);) - { - if (strncmp(line.c_str(), "model name", 10) == 0) - { + for (std::string line; std::getline(cpuin, line);) { + if (strncmp(line.c_str(), "model name", 10) == 0) { log << QString::fromStdString(line.substr(13, std::string::npos)); break; } } } -void runLspci(QStringList &log) +void runLspci(QStringList& log) { // FIXME: fixed size buffers... char buff[512]; int gpuline = -1; int cline = 0; - FILE * lspci = popen("lspci -k", "r"); + FILE* lspci = popen("lspci -k", "r"); if (!lspci) return; - while (fgets(buff, 512, lspci) != NULL) - { + while (fgets(buff, 512, lspci) != NULL) { std::string str(buff); if (str.length() < 9) continue; - if (str.substr(8, 3) == "VGA") - { + if (str.substr(8, 3) == "VGA") { gpuline = cline; log << QString::fromStdString(str.substr(35, std::string::npos)); } - if (gpuline > -1 && gpuline != cline) - { - if (cline - gpuline < 3) - { + if (gpuline > -1 && gpuline != cline) { + if (cline - gpuline < 3) { log << QString::fromStdString(str.substr(1, std::string::npos)); } } @@ -68,54 +62,47 @@ void runLspci(QStringList &log) pclose(lspci); } #elif defined(Q_OS_FREEBSD) -void runSysctlHwModel(QStringList &log) +void runSysctlHwModel(QStringList& log) { char buff[512]; - FILE *hwmodel = popen("sysctl hw.model", "r"); - while (fgets(buff, 512, hwmodel) != NULL) - { - log << QString::fromUtf8(buff); - break; + FILE* hwmodel = popen("sysctl hw.model", "r"); + while (fgets(buff, 512, hwmodel) != NULL) { + log << QString::fromUtf8(buff); + break; } pclose(hwmodel); } -void runPciconf(QStringList &log) +void runPciconf(QStringList& log) { char buff[512]; std::string strcard; - FILE *pciconf = popen("pciconf -lv -a vgapci0", "r"); - while (fgets(buff, 512, pciconf) != NULL) - { - if (strncmp(buff, " vendor", 10) == 0) - { - std::string str(buff); - strcard.append(str.substr(str.find_first_of("'") + 1, str.find_last_not_of("'") - (str.find_first_of("'") + 2))); - strcard.append(" "); - } - else if (strncmp(buff, " device", 10) == 0) - { - std::string str2(buff); - strcard.append(str2.substr(str2.find_first_of("'") + 1, str2.find_last_not_of("'") - (str2.find_first_of("'") + 2))); - } - log << QString::fromStdString(strcard); - break; + FILE* pciconf = popen("pciconf -lv -a vgapci0", "r"); + while (fgets(buff, 512, pciconf) != NULL) { + if (strncmp(buff, " vendor", 10) == 0) { + std::string str(buff); + strcard.append(str.substr(str.find_first_of("'") + 1, str.find_last_not_of("'") - (str.find_first_of("'") + 2))); + strcard.append(" "); + } else if (strncmp(buff, " device", 10) == 0) { + std::string str2(buff); + strcard.append(str2.substr(str2.find_first_of("'") + 1, str2.find_last_not_of("'") - (str2.find_first_of("'") + 2))); + } + log << QString::fromStdString(strcard); + break; } pclose(pciconf); } #endif -void runGlxinfo(QStringList & log) +void runGlxinfo(QStringList& log) { // FIXME: fixed size buffers... char buff[512]; - FILE *glxinfo = popen("glxinfo", "r"); + FILE* glxinfo = popen("glxinfo", "r"); if (!glxinfo) return; - while (fgets(buff, 512, glxinfo) != NULL) - { - if (strncmp(buff, "OpenGL version string:", 22) == 0) - { + while (fgets(buff, 512, glxinfo) != NULL) { + if (strncmp(buff, "OpenGL version string:", 22) == 0) { log << QString::fromUtf8(buff); break; } @@ -123,7 +110,7 @@ void runGlxinfo(QStringList & log) pclose(glxinfo); } -} +} // namespace #endif void PrintInstanceInfo::executeTask() diff --git a/launcher/minecraft/launch/PrintInstanceInfo.h b/launcher/minecraft/launch/PrintInstanceInfo.h index fdc30f316..8e1c41b62 100644 --- a/launcher/minecraft/launch/PrintInstanceInfo.h +++ b/launcher/minecraft/launch/PrintInstanceInfo.h @@ -21,21 +21,17 @@ #include "minecraft/launch/MinecraftServerTarget.h" // FIXME: temporary wrapper for existing task. -class PrintInstanceInfo: public LaunchStep -{ +class PrintInstanceInfo : public LaunchStep { Q_OBJECT -public: - explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) : - LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin) {}; + public: + explicit PrintInstanceInfo(LaunchTask* parent, AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) + : LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin){}; virtual ~PrintInstanceInfo(){}; virtual void executeTask(); - virtual bool canAbort() const - { - return false; - } -private: + virtual bool canAbort() const { return false; } + + private: AuthSessionPtr m_session; MinecraftServerTargetPtr m_serverToJoin; }; - diff --git a/launcher/minecraft/launch/ReconstructAssets.cpp b/launcher/minecraft/launch/ReconstructAssets.cpp index 4d206665f..843ccc554 100644 --- a/launcher/minecraft/launch/ReconstructAssets.cpp +++ b/launcher/minecraft/launch/ReconstructAssets.cpp @@ -14,10 +14,10 @@ */ #include "ReconstructAssets.h" +#include "launch/LaunchTask.h" +#include "minecraft/AssetsUtils.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "minecraft/AssetsUtils.h" -#include "launch/LaunchTask.h" void ReconstructAssets::executeTask() { @@ -27,8 +27,7 @@ void ReconstructAssets::executeTask() auto profile = components->getProfile(); auto assets = profile->getMinecraftAssets(); - if(!AssetsUtils::reconstructAssets(assets->id, minecraftInstance->resourcesDir())) - { + if (!AssetsUtils::reconstructAssets(assets->id, minecraftInstance->resourcesDir())) { emit logLine("Failed to reconstruct Minecraft assets.", MessageLevel::Error); } diff --git a/launcher/minecraft/launch/ReconstructAssets.h b/launcher/minecraft/launch/ReconstructAssets.h index 58d7febd1..bd867c8d4 100644 --- a/launcher/minecraft/launch/ReconstructAssets.h +++ b/launcher/minecraft/launch/ReconstructAssets.h @@ -18,16 +18,12 @@ #include #include -class ReconstructAssets: public LaunchStep -{ +class ReconstructAssets : public LaunchStep { Q_OBJECT -public: - explicit ReconstructAssets(LaunchTask *parent) : LaunchStep(parent){}; + public: + explicit ReconstructAssets(LaunchTask* parent) : LaunchStep(parent){}; virtual ~ReconstructAssets(){}; void executeTask() override; - bool canAbort() const override - { - return false; - } + bool canAbort() const override { return false; } }; diff --git a/launcher/minecraft/launch/ScanModFolders.cpp b/launcher/minecraft/launch/ScanModFolders.cpp index 71e7638cd..04d820668 100644 --- a/launcher/minecraft/launch/ScanModFolders.cpp +++ b/launcher/minecraft/launch/ScanModFolders.cpp @@ -34,9 +34,9 @@ */ #include "ScanModFolders.h" -#include "launch/LaunchTask.h" -#include "MMCZip.h" #include "FileSystem.h" +#include "MMCZip.h" +#include "launch/LaunchTask.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/mod/ModFolderModel.h" @@ -46,19 +46,19 @@ void ScanModFolders::executeTask() auto loaders = m_inst->loaderModList(); connect(loaders.get(), &ModFolderModel::updateFinished, this, &ScanModFolders::modsDone); - if(!loaders->update()) { + if (!loaders->update()) { m_modsDone = true; } auto cores = m_inst->coreModList(); connect(cores.get(), &ModFolderModel::updateFinished, this, &ScanModFolders::coreModsDone); - if(!cores->update()) { + if (!cores->update()) { m_coreModsDone = true; } auto nils = m_inst->nilModList(); connect(nils.get(), &ModFolderModel::updateFinished, this, &ScanModFolders::nilModsDone); - if(!nils->update()) { + if (!nils->update()) { m_nilModsDone = true; } checkDone(); @@ -84,7 +84,7 @@ void ScanModFolders::nilModsDone() void ScanModFolders::checkDone() { - if(m_modsDone && m_coreModsDone && m_nilModsDone) { + if (m_modsDone && m_coreModsDone && m_nilModsDone) { emitSucceeded(); } } diff --git a/launcher/minecraft/launch/ScanModFolders.h b/launcher/minecraft/launch/ScanModFolders.h index 111a5850b..a5b75825b 100644 --- a/launcher/minecraft/launch/ScanModFolders.h +++ b/launcher/minecraft/launch/ScanModFolders.h @@ -18,26 +18,23 @@ #include #include -class ScanModFolders: public LaunchStep -{ +class ScanModFolders : public LaunchStep { Q_OBJECT -public: - explicit ScanModFolders(LaunchTask *parent) : LaunchStep(parent) {}; + public: + explicit ScanModFolders(LaunchTask* parent) : LaunchStep(parent){}; virtual ~ScanModFolders(){}; virtual void executeTask() override; - virtual bool canAbort() const override - { - return false; - } -private slots: + virtual bool canAbort() const override { return false; } + private slots: void coreModsDone(); void modsDone(); void nilModsDone(); -private: + + private: void checkDone(); -private: // DATA + private: // DATA bool m_modsDone = false; bool m_nilModsDone = false; bool m_coreModsDone = false; diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 6ae666b47..03831d175 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -36,10 +36,11 @@ #include "VerifyJavaInstall.h" #include "java/JavaVersion.h" -#include "minecraft/PackProfile.h" #include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" -void VerifyJavaInstall::executeTask() { +void VerifyJavaInstall::executeTask() +{ auto instance = std::dynamic_pointer_cast(m_parent->instance()); auto packProfile = instance->getPackProfile(); auto settings = instance->settings(); @@ -50,28 +51,27 @@ void VerifyJavaInstall::executeTask() { JavaVersion javaVersion(storedVersion); - if (compatibleMajors.isEmpty() || compatibleMajors.contains(javaVersion.major())) - { + if (compatibleMajors.isEmpty() || compatibleMajors.contains(javaVersion.major())) { emitSucceeded(); return; } - - if (ignoreCompatibility) - { + if (ignoreCompatibility) { emit logLine(tr("Java major version is incompatible. Things might break."), MessageLevel::Warning); emitSucceeded(); return; } emit logLine(tr("This instance is not compatible with Java version %1.\n" - "Please switch to one of the following Java versions for this instance:").arg(javaVersion.major()), + "Please switch to one of the following Java versions for this instance:") + .arg(javaVersion.major()), MessageLevel::Error); - for (auto major : compatibleMajors) - { + for (auto major : compatibleMajors) { emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); } - emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error); + emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what " + "you're doing."), + MessageLevel::Error); emitFailed(QString("Incompatible Java major version")); } diff --git a/launcher/minecraft/launch/VerifyJavaInstall.h b/launcher/minecraft/launch/VerifyJavaInstall.h index 9139c0faf..edf6015a3 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.h +++ b/launcher/minecraft/launch/VerifyJavaInstall.h @@ -41,13 +41,10 @@ class VerifyJavaInstall : public LaunchStep { Q_OBJECT -public: - explicit VerifyJavaInstall(LaunchTask *parent) : LaunchStep(parent) { - }; + public: + explicit VerifyJavaInstall(LaunchTask* parent) : LaunchStep(parent){}; ~VerifyJavaInstall() override = default; void executeTask() override; - bool canAbort() const override { - return false; - } + bool canAbort() const override { return false; } }; diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp index c5754638a..7bf5a3112 100644 --- a/launcher/minecraft/mod/DataPack.cpp +++ b/launcher/minecraft/mod/DataPack.cpp @@ -30,10 +30,10 @@ // Values taken from: // https://minecraft.fandom.com/wiki/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") } }, + { 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") } }, }; diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 39723b49c..ea9078e04 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -42,28 +42,13 @@ class Metadata { return Packwiz::V1::createModFormat(index_dir, internal_mod, mod_slug); } - static void update(QDir& index_dir, ModStruct& mod) - { - Packwiz::V1::updateModIndex(index_dir, mod); - } + static void update(QDir& index_dir, ModStruct& mod) { Packwiz::V1::updateModIndex(index_dir, mod); } - static void remove(QDir& index_dir, QString mod_slug) - { - Packwiz::V1::deleteModIndex(index_dir, mod_slug); - } + static void remove(QDir& index_dir, QString mod_slug) { Packwiz::V1::deleteModIndex(index_dir, mod_slug); } - static void remove(QDir& index_dir, QVariant& mod_id) - { - Packwiz::V1::deleteModIndex(index_dir, mod_id); - } + static void remove(QDir& index_dir, QVariant& mod_id) { Packwiz::V1::deleteModIndex(index_dir, mod_id); } - static auto get(QDir& index_dir, QString mod_slug) -> ModStruct - { - return Packwiz::V1::getIndexForMod(index_dir, mod_slug); - } + 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 get(QDir& index_dir, QVariant& mod_id) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_id); } }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 880dacb15..46509cde6 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -1,45 +1,45 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "Mod.h" #include #include -#include #include +#include #include "MTPixmapCache.h" #include "MetadataHandler.h" @@ -54,8 +54,7 @@ Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details() m_enabled = (file.suffix() != "disabled"); } -Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata) - : Mod(mods_dir.absoluteFilePath(metadata.filename)) +Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata) : Mod(mods_dir.absoluteFilePath(metadata.filename)) { m_name = metadata.name; m_local_details.metadata = std::make_shared(std::move(metadata)); @@ -73,7 +72,8 @@ void Mod::setMetadata(std::shared_ptr&& metadata) m_local_details.metadata = metadata; } -void Mod::setDetails(const ModDetails& details) { +void Mod::setDetails(const ModDetails& details) +{ m_local_details = details; } @@ -103,7 +103,8 @@ std::pair Mod::compare(const Resource& other, SortType type) const break; } case SortType::PROVIDER: { - auto compare_result = QString::compare(provider().value_or("Unknown"), cast_other->provider().value_or("Unknown"), Qt::CaseInsensitive); + auto compare_result = + QString::compare(provider().value_or("Unknown"), cast_other->provider().value_or("Unknown"), Qt::CaseInsensitive); if (compare_result != 0) return { compare_result, type == SortType::PROVIDER }; break; @@ -230,7 +231,7 @@ auto Mod::licenses() const -> const QList& return details().licenses; } - auto Mod::issueTracker() const -> QString +auto Mod::issueTracker() const -> QString { return details().issue_tracker; } @@ -245,7 +246,7 @@ void Mod::setIcon(QImage new_image) const PixmapCache::remove(m_pack_image_cache_key.key); // scale the image to avoid flooding the pixmapcache - auto pixmap = QPixmap::fromImage(new_image.scaled({64, 64}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + auto pixmap = QPixmap::fromImage(new_image.scaled({ 64, 64 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); m_pack_image_cache_key.key = PixmapCache::insert(pixmap); m_pack_image_cache_key.was_ever_used = true; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index b67bd4659..51c42028c 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -1,76 +1,75 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 #include -#include #include +#include #include #include #include #include -#include "Resource.h" #include "ModDetails.h" +#include "Resource.h" -class Mod : public Resource -{ +class Mod : public Resource { Q_OBJECT -public: + public: using Ptr = shared_qobject_ptr; using WeakPtr = QPointer; Mod() = default; - Mod(const QFileInfo &file); + Mod(const QFileInfo& file); Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata); Mod(QString file_path) : Mod(QFileInfo(file_path)) {} - auto details() const -> const ModDetails&; - auto name() const -> QString override; - auto version() const -> QString; - auto homeurl() const -> QString; + auto details() const -> const ModDetails&; + auto name() const -> QString override; + auto version() const -> QString; + auto homeurl() const -> QString; auto description() const -> QString; - auto authors() const -> QStringList; - auto status() const -> ModStatus; - auto provider() const -> std::optional; - auto licenses() const -> const QList&; + auto authors() const -> QStringList; + auto status() const -> ModStatus; + auto provider() const -> std::optional; + auto licenses() const -> const QList&; auto issueTracker() const -> QString; - auto metaurl() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; @@ -97,7 +96,7 @@ public: void finishResolvingWithDetails(ModDetails&& details); -protected: + protected: ModDetails m_local_details; mutable QMutex m_data_lock; @@ -107,5 +106,4 @@ protected: bool was_ever_used = false; bool was_read_attempt = false; } mutable m_pack_image_cache_key; - }; diff --git a/launcher/minecraft/mod/ModDetails.h b/launcher/minecraft/mod/ModDetails.h index b4e59d52d..60099496c 100644 --- a/launcher/minecraft/mod/ModDetails.h +++ b/launcher/minecraft/mod/ModDetails.h @@ -1,37 +1,37 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -44,10 +44,10 @@ #include "minecraft/mod/MetadataHandler.h" enum class ModStatus { - Installed, // Both JAR and Metadata are present - NotInstalled, // Only the Metadata is present - NoMetadata, // Only the JAR is present - Unknown, // Default status + Installed, // Both JAR and Metadata are present + NotInstalled, // Only the Metadata is present + NoMetadata, // Only the JAR is present + Unknown, // Default status }; struct ModLicense { @@ -58,11 +58,12 @@ struct ModLicense { ModLicense() {} - ModLicense(const QString license) { - // FIXME: come up with a better license parseing. + ModLicense(const QString license) + { + // FIXME: come up with a better license parseing. // handle SPDX identifiers? https://spdx.org/licenses/ auto parts = license.split(' '); - QStringList notNameParts = {}; + QStringList notNameParts = {}; for (auto part : parts) { auto url = QUrl(part); if (part.startsWith("(") && part.endsWith(")")) @@ -78,7 +79,7 @@ struct ModLicense { for (auto part : notNameParts) { parts.removeOne(part); } - + auto licensePart = parts.join(' '); this->name = licensePart; this->description = licensePart; @@ -86,22 +87,17 @@ struct ModLicense { if (parts.size() == 1) { this->id = parts.first(); } - } - ModLicense(const QString name, const QString id, const QString url, const QString description) { + ModLicense(const QString name, const QString id, const QString url, const QString description) + { this->name = name; this->id = id; this->url = url; this->description = description; } - ModLicense(const ModLicense& other) - : name(other.name) - , id(other.id) - , url(other.url) - , description(other.description) - {} + ModLicense(const ModLicense& other) : name(other.name), id(other.id), url(other.url), description(other.description) {} ModLicense& operator=(const ModLicense& other) { @@ -123,28 +119,25 @@ struct ModLicense { return *this; } - bool isEmpty() { - return this->name.isEmpty() && this->id.isEmpty() && this->url.isEmpty() && this->description.isEmpty(); - } + bool isEmpty() { return this->name.isEmpty() && this->id.isEmpty() && this->url.isEmpty() && this->description.isEmpty(); } }; -struct ModDetails -{ +struct ModDetails { /* Mod ID as defined in the ModLoader-specific metadata */ QString mod_id = {}; - + /* Human-readable name */ QString name = {}; - + /* Human-readable mod version */ QString version = {}; - + /* Human-readable minecraft version */ QString mcversion = {}; - + /* URL for mod's home page */ QString homeurl = {}; - + /* Human-readable description */ QString description = {}; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 51383edf0..69028199a 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -1,38 +1,38 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "ModFolderModel.h" @@ -59,11 +59,12 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool { 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_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents}; + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, + QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; } -QVariant ModFolderModel::data(const QModelIndex &index, int role) const +QVariant ModFolderModel::data(const QModelIndex& index, int role) const { if (!validateIndex(index)) return {}; @@ -71,115 +72,109 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const int row = index.row(); int column = index.column(); - switch (role) - { - case Qt::DisplayRole: - switch (column) - { - case NameColumn: - return m_resources[row]->name(); - case VersionColumn: { - switch(m_resources[row]->type()) { - case ResourceType::FOLDER: - return tr("Folder"); - case ResourceType::SINGLEFILE: - return tr("File"); + switch (role) { + case Qt::DisplayRole: + switch (column) { + case NameColumn: + return m_resources[row]->name(); + case VersionColumn: { + switch (m_resources[row]->type()) { + case ResourceType::FOLDER: + return tr("Folder"); + case ResourceType::SINGLEFILE: + return tr("File"); + default: + break; + } + return at(row)->version(); + } + case DateColumn: + return m_resources[row]->dateTimeChanged(); + case ProviderColumn: { + auto provider = at(row)->provider(); + if (!provider.has_value()) { + //: Unknown mod provider (i.e. not Modrinth, CurseForge, etc...) + return tr("Unknown"); + } + + return provider.value(); + } default: - break; - } - return at(row)->version(); - } - case DateColumn: - return m_resources[row]->dateTimeChanged(); - case ProviderColumn: { - auto provider = at(row)->provider(); - if (!provider.has_value()) { - //: Unknown mod provider (i.e. not Modrinth, CurseForge, etc...) - return tr("Unknown"); + return QVariant(); } - return provider.value(); + case Qt::ToolTipRole: + if (column == NAME_COLUMN) { + if (at(row)->isSymLinkUnder(instDirPath())) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(at(row)->fileinfo().canonicalFilePath()); + } + if (at(row)->isMoreThanOneHardLink()) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); + } + } + return m_resources[row]->internal_id(); + case Qt::DecorationRole: { + if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) + return APPLICATION->getThemedIcon("status-yellow"); + if (column == ImageColumn) { + return at(row)->icon({ 32, 32 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding); + } + return {}; } + case Qt::CheckStateRole: + switch (column) { + case ActiveColumn: + return at(row)->enabled() ? Qt::Checked : Qt::Unchecked; + default: + return QVariant(); + } default: return QVariant(); - } - - case Qt::ToolTipRole: - if (column == NAME_COLUMN) { - if (at(row)->isSymLinkUnder(instDirPath())) { - return m_resources[row]->internal_id() + - tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." - "\nCanonical Path: %1") - .arg(at(row)->fileinfo().canonicalFilePath()); - } - if (at(row)->isMoreThanOneHardLink()) { - return m_resources[row]->internal_id() + - tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); - } - } - return m_resources[row]->internal_id(); - case Qt::DecorationRole: { - if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) - return APPLICATION->getThemedIcon("status-yellow"); - if (column == ImageColumn) { - return at(row)->icon({32, 32}, Qt::AspectRatioMode::KeepAspectRatioByExpanding); - } - return {}; - } - case Qt::CheckStateRole: - switch (column) - { - case ActiveColumn: - return at(row)->enabled() ? Qt::Checked : Qt::Unchecked; - default: - return QVariant(); - } - default: - return QVariant(); } } QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, int role) const { - switch (role) - { - case Qt::DisplayRole: - switch (section) - { - case ActiveColumn: - case NameColumn: - case VersionColumn: - case DateColumn: - case ProviderColumn: - case ImageColumn: - return columnNames().at(section); - default: - return QVariant(); - } + switch (role) { + case Qt::DisplayRole: + switch (section) { + case ActiveColumn: + case NameColumn: + case VersionColumn: + case DateColumn: + case ProviderColumn: + case ImageColumn: + return columnNames().at(section); + default: + return QVariant(); + } - case Qt::ToolTipRole: - switch (section) - { - case ActiveColumn: - return tr("Is the mod enabled?"); - case NameColumn: - return tr("The name of the mod."); - case VersionColumn: - return tr("The version of the mod."); - case DateColumn: - return tr("The date and time this mod was last changed (or added)."); - case ProviderColumn: - return tr("Where the mod was downloaded from."); + case Qt::ToolTipRole: + switch (section) { + case ActiveColumn: + return tr("Is the mod enabled?"); + case NameColumn: + return tr("The name of the mod."); + case VersionColumn: + return tr("The version of the mod."); + case DateColumn: + return tr("The date and time this mod was last changed (or added)."); + case ProviderColumn: + return tr("Where the mod was downloaded from."); + default: + return QVariant(); + } default: return QVariant(); - } - default: - return QVariant(); } return QVariant(); } -int ModFolderModel::columnCount(const QModelIndex &parent) const +int ModFolderModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : NUM_COLUMNS; } @@ -199,8 +194,8 @@ Task* ModFolderModel::createParseTask(Resource& resource) bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadata) { - for(auto mod : allMods()) { - if(mod->fileinfo().fileName() == filename) { + for (auto mod : allMods()) { + if (mod->fileinfo().fileName() == filename) { auto index_dir = indexDir(); mod->destroy(index_dir, preserve_metadata, false); @@ -253,7 +248,7 @@ auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> QList { QList selected_resources; for (auto i : indexes) { - if(i.column() != 0) + if (i.column() != 0) continue; selected_resources.push_back(at(i.row())); diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 6ccaba235..f1f40a817 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -1,53 +1,53 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 +#include #include #include #include #include -#include -#include #include "Mod.h" #include "ResourceFolderModel.h" -#include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h" +#include "minecraft/mod/tasks/ModFolderLoadTask.h" class LegacyInstance; class BaseInstance; @@ -57,33 +57,19 @@ class QFileSystemWatcher; * A legacy mod list. * Backed by a folder. */ -class ModFolderModel : public ResourceFolderModel -{ +class ModFolderModel : public ResourceFolderModel { Q_OBJECT -public: - enum Columns - { - ActiveColumn = 0, - ImageColumn, - NameColumn, - VersionColumn, - DateColumn, - ProviderColumn, - NUM_COLUMNS - }; - enum ModStatusAction { - Disable, - Enable, - Toggle - }; - ModFolderModel(const QString &dir, BaseInstance* instance, bool is_indexed = false, bool create_dir = true); + public: + enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, VersionColumn, DateColumn, ProviderColumn, NUM_COLUMNS }; + enum ModStatusAction { Disable, Enable, Toggle }; + ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed = false, bool create_dir = true); virtual QString id() const override { return "mods"; } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - int columnCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex& parent) const override; [[nodiscard]] Task* createUpdateTask() override; [[nodiscard]] Task* createParseTask(Resource&) override; @@ -92,7 +78,7 @@ public: bool uninstallMod(const QString& filename, bool preserve_metadata = false); /// Deletes all the selected mods - bool deleteMods(const QModelIndexList &indexes); + bool deleteMods(const QModelIndexList& indexes); bool isValid(); @@ -106,12 +92,11 @@ public: RESOURCE_HELPERS(Mod) -private -slots: + private slots: void onUpdateSucceeded() override; void onParseSucceeded(int ticket, QString resource_id) override; -protected: + protected: bool m_is_indexed; bool m_first_folder_load = true; }; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 098a617f8..da806f0f4 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -1,8 +1,7 @@ #include "Resource.h" - -#include #include +#include #include "FileSystem.h" @@ -105,7 +104,6 @@ bool Resource::enable(EnableAction action) if (m_type == ResourceType::UNKNOWN || m_type == ResourceType::FOLDER) return false; - QString path = m_file_info.absoluteFilePath(); QFile file(path); @@ -154,7 +152,7 @@ bool Resource::destroy(bool attemptTrash) return (attemptTrash && FS::trash(m_file_info.filePath())) || FS::deletePath(m_file_info.filePath()); } -bool Resource::isSymLinkUnder(const QString& instPath) const +bool Resource::isSymLinkUnder(const QString& instPath) const { if (isSymLink()) return true; @@ -167,7 +165,7 @@ bool Resource::isSymLinkUnder(const QString& instPath) const return relAbsPath != relCanonPath; } -bool Resource::isMoreThanOneHardLink() const +bool Resource::isMoreThanOneHardLink() const { return FS::hardLinkCount(m_file_info.absoluteFilePath()) > 1; } diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index 94f3160c3..c1ed49461 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -15,20 +15,9 @@ 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 }; -enum class EnableAction { - ENABLE, - DISABLE, - TOGGLE -}; +enum class EnableAction { ENABLE, DISABLE, TOGGLE }; /** General class for managed resources. It mirrors a file in disk, with some more info * for display and house-keeping purposes. @@ -98,10 +87,10 @@ class Resource : public QObject { /** * @brief Take a instance path, checks if the file pointed to by the resource is a symlink or under a symlink in that instance - * + * * @param instPath path to an instance directory - * @return true - * @return false + * @return true + * @return false */ [[nodiscard]] bool isSymLinkUnder(const QString& instPath) const; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 39a61067e..0106d5c9b 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -515,25 +515,25 @@ void ResourceFolderModel::setupHeaderAction(QAction* act, int column) void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) { auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); - auto setting = (m_instance->settings()->contains(setting_name)) ? - m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); + auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name) + : m_instance->settings()->registerSetting(setting_name); auto hiddenColumns = setting->get().toStringList(); auto name = columnNames(false).at(column); auto index = hiddenColumns.indexOf(name); if (index >= 0 && !hidden) { hiddenColumns.removeAt(index); - } else if ( index < 0 && hidden) { + } else if (index < 0 && hidden) { hiddenColumns.append(name); } setting->set(hiddenColumns); } -void ResourceFolderModel::loadHiddenColumns(QTreeView *tree) +void ResourceFolderModel::loadHiddenColumns(QTreeView* tree) { auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); - auto setting = (m_instance->settings()->contains(setting_name)) ? - m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); + auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name) + : m_instance->settings()->registerSetting(setting_name); auto hiddenColumns = setting->get().toStringList(); auto col_names = columnNames(false); @@ -542,7 +542,6 @@ void ResourceFolderModel::loadHiddenColumns(QTreeView *tree) if (index >= 0) tree->setColumnHidden(index, true); } - } QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) @@ -558,9 +557,9 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) act->setCheckable(true); act->setChecked(!tree->isColumnHidden(col)); - connect(act, &QAction::toggled, tree, [this, col, tree](bool toggled){ + connect(act, &QAction::toggled, tree, [this, col, tree](bool toggled) { tree->setColumnHidden(col, !toggled); - for(int c = 0; c < columnCount(); ++c) { + for (int c = 0; c < columnCount(); ++c) { if (m_column_resize_modes.at(c) == QHeaderView::ResizeToContents) tree->resizeColumnToContents(c); } @@ -568,7 +567,6 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) }); menu->addAction(act); - } return menu; diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 454b84c36..595b9762e 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -1,14 +1,14 @@ #pragma once -#include -#include -#include #include +#include #include #include +#include #include #include #include +#include #include "Resource.h" @@ -120,7 +120,7 @@ class ResourceFolderModel : public QAbstractListModel { void saveHiddenColumn(int column, bool hidden); void loadHiddenColumns(QTreeView* tree); QMenu* createHeaderContextMenu(QTreeView* tree); - + /** This creates a proxy model to filter / sort the model for a UI. * * The actual comparisons and filtering are done directly by the Resource, so to modify behavior go there instead! @@ -199,9 +199,10 @@ class ResourceFolderModel : public QAbstractListModel { // Represents the relationship between a column's index (represented by the list index), and it's sorting key. // As such, the order in with they appear is very important! QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; - QStringList m_column_names = {"Enable", "Name", "Last Modified"}; - QStringList m_column_names_translated = {tr("Enable"), tr("Name"), tr("Last Modified")}; - QList m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents }; + QStringList m_column_names = { "Enable", "Name", "Last Modified" }; + QStringList m_column_names_translated = { tr("Enable"), tr("Name"), tr("Last Modified") }; + QList m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch, + QHeaderView::ResizeToContents }; QDir m_dir; BaseInstance* m_instance; diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 6d5978d4d..dab0f6d67 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -50,7 +50,7 @@ void ResourcePack::setImage(QImage new_image) const PixmapCache::instance().remove(m_pack_image_cache_key.key); // scale the image to avoid flooding the pixmapcache - auto pixmap = QPixmap::fromImage(new_image.scaled({64, 64}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + auto pixmap = QPixmap::fromImage(new_image.scaled({ 64, 64 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); m_pack_image_cache_key.key = PixmapCache::instance().insert(pixmap); m_pack_image_cache_key.was_ever_used = true; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 41455599b..0e2981eff 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -47,14 +47,13 @@ #include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalResourcePackParseTask.h" -ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstance* instance) - : ResourceFolderModel(QDir(dir), instance) +ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) { m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") }); - m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE}; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; - + m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE }; + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, + QHeaderView::ResizeToContents }; } QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const @@ -93,7 +92,7 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); if (column == ImageColumn) { - return at(row)->image({32, 32}, Qt::AspectRatioMode::KeepAspectRatioByExpanding); + return at(row)->image({ 32, 32 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding); } return {}; } @@ -105,13 +104,14 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const if (column == NameColumn) { if (at(row)->isSymLinkUnder(instDirPath())) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." - "\nCanonical Path: %1") - .arg(at(row)->fileinfo().canonicalFilePath());; + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(at(row)->fileinfo().canonicalFilePath()); + ; } if (at(row)->isMoreThanOneHardLink()) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); } } return m_resources[row]->internal_id(); @@ -159,7 +159,7 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient } case Qt::SizeHintRole: if (section == ImageColumn) { - return QSize(64,0); + return QSize(64, 0); } return {}; default: diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h index 531d81928..29c2c5995 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.h +++ b/launcher/minecraft/mod/ResourcePackFolderModel.h @@ -4,28 +4,19 @@ #include "ResourcePack.h" -class ResourcePackFolderModel : public ResourceFolderModel -{ +class ResourcePackFolderModel : public ResourceFolderModel { Q_OBJECT -public: - enum Columns - { - ActiveColumn = 0, - ImageColumn, - NameColumn, - PackFormatColumn, - DateColumn, - NUM_COLUMNS - }; + public: + enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, PackFormatColumn, DateColumn, NUM_COLUMNS }; - explicit ResourcePackFolderModel(const QString &dir, BaseInstance* instance); + explicit ResourcePackFolderModel(const QString& dir, BaseInstance* instance); virtual QString id() const override { return "resourcepacks"; } - [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + [[nodiscard]] QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - [[nodiscard]] int columnCount(const QModelIndex &parent) const override; + [[nodiscard]] int columnCount(const QModelIndex& parent) const override; [[nodiscard]] Task* createUpdateTask() override; [[nodiscard]] Task* createParseTask(Resource&) override; diff --git a/launcher/minecraft/mod/ShaderPackFolderModel.h b/launcher/minecraft/mod/ShaderPackFolderModel.h index f8249962f..44ed37a47 100644 --- a/launcher/minecraft/mod/ShaderPackFolderModel.h +++ b/launcher/minecraft/mod/ShaderPackFolderModel.h @@ -6,9 +6,7 @@ class ShaderPackFolderModel : public ResourceFolderModel { Q_OBJECT public: - explicit ShaderPackFolderModel(const QString& dir, BaseInstance* instance) - : ResourceFolderModel(QDir(dir), instance) - {} - + explicit ShaderPackFolderModel(const QString& dir, BaseInstance* instance) : ResourceFolderModel(QDir(dir), instance) {} + virtual QString id() const override { return "shaderpacks"; } }; diff --git a/launcher/minecraft/mod/TexturePack.cpp b/launcher/minecraft/mod/TexturePack.cpp index c7a50a97a..fbc716c42 100644 --- a/launcher/minecraft/mod/TexturePack.cpp +++ b/launcher/minecraft/mod/TexturePack.cpp @@ -44,7 +44,7 @@ void TexturePack::setImage(QImage new_image) const PixmapCache::remove(m_pack_image_cache_key.key); // scale the image to avoid flooding the pixmapcache - auto pixmap = QPixmap::fromImage(new_image.scaled({64, 64}, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); + auto pixmap = QPixmap::fromImage(new_image.scaled({ 64, 64 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding)); m_pack_image_cache_key.key = PixmapCache::insert(pixmap); m_pack_image_cache_key.was_ever_used = true; diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 531a70232..869fbe2e5 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -42,14 +42,13 @@ #include "minecraft/mod/tasks/BasicFolderLoadTask.h" #include "minecraft/mod/tasks/LocalTexturePackParseTask.h" -TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* instance) - : ResourceFolderModel(QDir(dir), instance) +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_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents}; - + m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, + QHeaderView::ResizeToContents }; } Task* TexturePackFolderModel::createUpdateTask() @@ -62,7 +61,6 @@ Task* TexturePackFolderModel::createParseTask(Resource& resource) return new LocalTexturePackParseTask(m_next_resolution_ticket, static_cast(resource)); } - QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const { if (!validateIndex(index)) @@ -85,28 +83,29 @@ QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const if (column == NameColumn) { if (at(row)->isSymLinkUnder(instDirPath())) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." - "\nCanonical Path: %1") - .arg(at(row)->fileinfo().canonicalFilePath());; + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(at(row)->fileinfo().canonicalFilePath()); + ; } if (at(row)->isMoreThanOneHardLink()) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); } } - + return m_resources[row]->internal_id(); case Qt::DecorationRole: { if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) return APPLICATION->getThemedIcon("status-yellow"); if (column == ImageColumn) { - return at(row)->image({32, 32}, Qt::AspectRatioMode::KeepAspectRatioByExpanding); + return at(row)->image({ 32, 32 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding); } return {}; } case Qt::CheckStateRole: if (column == ActiveColumn) { - return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked; + return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked; } return {}; default: @@ -153,4 +152,3 @@ int TexturePackFolderModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : NUM_COLUMNS; } - diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index 71a8bdd16..ccc634da7 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -40,31 +40,22 @@ #include "TexturePack.h" -class TexturePackFolderModel : public ResourceFolderModel -{ +class TexturePackFolderModel : public ResourceFolderModel { Q_OBJECT -public: + public: + enum Columns { ActiveColumn = 0, ImageColumn, NameColumn, DateColumn, NUM_COLUMNS }; - enum Columns - { - ActiveColumn = 0, - ImageColumn, - NameColumn, - DateColumn, - NUM_COLUMNS - }; - - explicit TexturePackFolderModel(const QString &dir, std::shared_ptr instance); + explicit TexturePackFolderModel(const QString& dir, std::shared_ptr instance); virtual QString id() const override { return "texturepacks"; } - [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + [[nodiscard]] QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - [[nodiscard]] int columnCount(const QModelIndex &parent) const override; + [[nodiscard]] int columnCount(const QModelIndex& parent) const override; - explicit TexturePackFolderModel(const QString &dir, BaseInstance* instance); + explicit TexturePackFolderModel(const QString& dir, BaseInstance* instance); [[nodiscard]] Task* createUpdateTask() override; [[nodiscard]] Task* createParseTask(Resource&) override; diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h index 3ee7e2e0f..23a2b649a 100644 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h @@ -26,12 +26,14 @@ class BasicFolderLoadTask : public Task { public: BasicFolderLoadTask(QDir dir) : Task(nullptr, false), m_dir(dir), m_result(new Result), m_thread_to_spawn_into(thread()) { - m_create_func = [](QFileInfo const& entry) -> Resource::Ptr { - return makeShared(entry); - }; + m_create_func = [](QFileInfo const& entry) -> Resource::Ptr { return makeShared(entry); }; } BasicFolderLoadTask(QDir dir, std::function create_function) - : Task(nullptr, false), m_dir(dir), m_result(new Result), m_create_func(std::move(create_function)), m_thread_to_spawn_into(thread()) + : Task(nullptr, false) + , m_dir(dir) + , m_result(new Result) + , m_create_func(std::move(create_function)) + , m_thread_to_spawn_into(thread()) {} [[nodiscard]] bool canAbort() const override { return true; } @@ -59,7 +61,7 @@ class BasicFolderLoadTask : public Task { emitSucceeded(); } -private: + private: QDir m_dir; ResultPtr m_result; diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 60389753e..75bb6d25c 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -181,7 +181,7 @@ ModDetails ReadMCModTOML(QByteArray contents) QString license = ""; if (auto licenseDatum = tomlData["license"].as_string()) { license = QString::fromStdString(licenseDatum->get()); - } else if (auto licenseDatum =(*modsTable)["license"].as_string()) { + } else if (auto licenseDatum = (*modsTable)["license"].as_string()) { license = QString::fromStdString(licenseDatum->get()); } if (!license.isEmpty()) @@ -190,7 +190,7 @@ ModDetails ReadMCModTOML(QByteArray contents) QString logoFile = ""; if (auto logoFileDatum = tomlData["logoFile"].as_string()) { logoFile = QString::fromStdString(logoFileDatum->get()); - } else if (auto logoFileDatum =(*modsTable)["logoFile"].as_string()) { + } else if (auto logoFileDatum = (*modsTable)["logoFile"].as_string()) { logoFile = QString::fromStdString(logoFileDatum->get()); } details.icon_file = logoFile; @@ -271,7 +271,7 @@ ModDetails ReadFabricModInfo(QByteArray contents) if (largest > 0) { auto key = QString::number(largest) + "x" + QString::number(largest); details.icon_file = obj.value(key).toString(); - } else { // parsing the sizes failed + } else { // parsing the sizes failed // take the first for (auto i : obj) { details.icon_file = i.toString(); @@ -358,7 +358,7 @@ ModDetails ReadQuiltModInfo(QByteArray contents) if (largest > 0) { auto key = QString::number(largest) + "x" + QString::number(largest); details.icon_file = obj.value(key).toString(); - } else { // parsing the sizes failed + } else { // parsing the sizes failed // take the first for (auto i : obj) { details.icon_file = i.toString(); @@ -658,7 +658,8 @@ bool processIconPNG(const Mod& mod, QByteArray&& raw_data) return true; } -bool loadIconFile(const Mod& mod) { +bool loadIconFile(const Mod& mod) +{ if (mod.iconPath().isEmpty()) { qWarning() << "No Iconfile set, be sure to parse the mod first"; return false; @@ -670,15 +671,14 @@ bool loadIconFile(const Mod& mod) { }; switch (mod.type()) { - case ResourceType::FOLDER: - { + case ResourceType::FOLDER: { QFileInfo icon_info(FS::PathCombine(mod.fileinfo().filePath(), mod.iconPath())); if (icon_info.exists() && icon_info.isFile()) { QFile icon(icon_info.filePath()); if (!icon.open(QIODevice::ReadOnly)) return false; auto data = icon.readAll(); - + bool icon_result = ModUtils::processIconPNG(mod, std::move(data)); icon.close(); @@ -688,8 +688,7 @@ bool loadIconFile(const Mod& mod) { } } } - case ResourceType::ZIPFILE: - { + case ResourceType::ZIPFILE: { QuaZip zip(mod.fileinfo().filePath()); if (!zip.open(QuaZip::mdUnzip)) return false; @@ -715,9 +714,8 @@ bool loadIconFile(const Mod& mod) { return png_invalid(); // could not set icon as current file. } } - case ResourceType::LITEMOD: - { - return false; // can lightmods even have icons? + case ResourceType::LITEMOD: { + return false; // can lightmods even have icons? } default: qWarning() << "Invalid type for mod, can not load icon."; diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h index 1d2f06a6f..31f919b84 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp index a67c56a8f..7440e6aa3 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp @@ -207,15 +207,14 @@ bool processPackPNG(const ResourcePack& pack, QByteArray&& raw_data) } bool processPackPNG(const ResourcePack& pack) -{ +{ auto png_invalid = [&pack]() { qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png"; return false; }; switch (pack.type()) { - case ResourceType::FOLDER: - { + case ResourceType::FOLDER: { QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png")); if (image_file_info.exists() && image_file_info.isFile()) { QFile pack_png_file(image_file_info.filePath()); @@ -234,8 +233,7 @@ bool processPackPNG(const ResourcePack& pack) return png_invalid(); // pack.png does not exists or is not a valid file. } } - case ResourceType::ZIPFILE: - { + case ResourceType::ZIPFILE: { Q_ASSERT(pack.type() == ResourceType::ZIPFILE); QuaZip zip(pack.fileinfo().filePath()); diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index 0894049cd..d5a090832 100644 --- a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#include +#include #include "LocalResourceParse.h" @@ -30,19 +30,17 @@ #include "LocalTexturePackParseTask.h" #include "LocalWorldSaveParseTask.h" - -static const QMap s_packed_type_names = { - {PackedResourceType::ResourcePack, QObject::tr("resource pack")}, - {PackedResourceType::TexturePack, QObject::tr("texture pack")}, - {PackedResourceType::DataPack, QObject::tr("data pack")}, - {PackedResourceType::ShaderPack, QObject::tr("shader pack")}, - {PackedResourceType::WorldSave, QObject::tr("world save")}, - {PackedResourceType::Mod , QObject::tr("mod")}, - {PackedResourceType::UNKNOWN, QObject::tr("unknown")} -}; +static const QMap s_packed_type_names = { { PackedResourceType::ResourcePack, QObject::tr("resource pack") }, + { PackedResourceType::TexturePack, QObject::tr("texture pack") }, + { PackedResourceType::DataPack, QObject::tr("data pack") }, + { PackedResourceType::ShaderPack, QObject::tr("shader pack") }, + { PackedResourceType::WorldSave, QObject::tr("world save") }, + { PackedResourceType::Mod, QObject::tr("mod") }, + { PackedResourceType::UNKNOWN, QObject::tr("unknown") } }; namespace ResourceUtils { -PackedResourceType identify(QFileInfo file){ +PackedResourceType identify(QFileInfo file) +{ if (file.exists() && file.isFile()) { if (ModUtils::validate(file)) { // mods can contain resource and data packs so they must be tested first @@ -64,7 +62,7 @@ PackedResourceType identify(QFileInfo file){ qDebug() << file.fileName() << "is a shader pack"; return PackedResourceType::ShaderPack; } else { - qDebug() << "Can't Identify" << file.fileName() ; + qDebug() << "Can't Identify" << file.fileName(); } } else { qDebug() << "Can't find" << file.absolutePath(); @@ -72,8 +70,9 @@ PackedResourceType identify(QFileInfo file){ return PackedResourceType::UNKNOWN; } -QString getPackedTypeName(PackedResourceType type) { +QString getPackedTypeName(PackedResourceType type) +{ return s_packed_type_names.constFind(type).value(); } -} +} // namespace ResourceUtils diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp index a72e81150..817b0ea9c 100644 --- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp @@ -161,15 +161,14 @@ bool processPackPNG(const TexturePack& pack, QByteArray&& raw_data) } bool processPackPNG(const TexturePack& pack) -{ +{ auto png_invalid = [&pack]() { qWarning() << "Texture pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png"; return false; }; switch (pack.type()) { - case ResourceType::FOLDER: - { + case ResourceType::FOLDER: { QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png")); if (image_file_info.exists() && image_file_info.isFile()) { QFile pack_png_file(image_file_info.filePath()); @@ -188,8 +187,7 @@ bool processPackPNG(const TexturePack& pack) return png_invalid(); // pack.png does not exists or is not a valid file. } } - case ResourceType::ZIPFILE: - { + case ResourceType::ZIPFILE: { Q_ASSERT(pack.type() == ResourceType::ZIPFILE); QuaZip zip(pack.fileinfo().filePath()); @@ -232,8 +230,7 @@ bool validate(QFileInfo file) } // namespace TexturePackUtils -LocalTexturePackParseTask::LocalTexturePackParseTask(int token, TexturePack& rp) - : Task(nullptr, false), m_token(token), m_texture_pack(rp) +LocalTexturePackParseTask::LocalTexturePackParseTask(int token, TexturePack& rp) : Task(nullptr, false), m_token(token), m_texture_pack(rp) {} bool LocalTexturePackParseTask::abort() diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp index cbc8f8cee..9d564ddb3 100644 --- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp @@ -50,8 +50,8 @@ bool process(WorldSave& pack, ProcessingLevel level) /// @param dir the path to check /// @param saves used in recursive call if a "saves" dir was found /// @return std::tuple of ( -/// bool , -/// QString , +/// bool , +/// QString , /// bool /// ) static std::tuple contains_level_dat(QDir dir, bool saves = false) @@ -101,8 +101,8 @@ bool processFolder(WorldSave& save, ProcessingLevel level) /// @brief checks a folder structure to see if it contains a level.dat /// @param zip the zip file to check /// @return std::tuple of ( -/// bool , -/// QString , +/// bool , +/// QString , /// bool /// ) static std::tuple contains_level_dat(QuaZip& zip) diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h index 9dcdca2b9..12f677b02 100644 --- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h @@ -39,7 +39,7 @@ bool processFolder(WorldSave& pack, ProcessingLevel level = ProcessingLevel::Ful bool validate(QFileInfo file); -} // namespace WorldSaveUtils +} // namespace WorldSaveUtils class LocalWorldSaveParseTask : public Task { Q_OBJECT diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index ef353c701..4a19a8eb4 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -1,38 +1,38 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 "ModFolderLoadTask.h" @@ -70,13 +70,11 @@ void ModFolderLoadTask::executeTask() m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); // Delete the object we just created, since a valid one is already in the mods list. delete mod; - } - else { + } else { m_result->mods[mod->internal_id()].reset(std::move(mod)); m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata); } - } - else { + } else { QString chopped_id = mod->internal_id().chopped(9); if (m_result->mods.contains(chopped_id)) { m_result->mods[mod->internal_id()].reset(std::move(mod)); @@ -88,8 +86,7 @@ void ModFolderLoadTask::executeTask() m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); m_result->mods.remove(chopped_id); } - } - else { + } else { m_result->mods[mod->internal_id()].reset(std::move(mod)); m_result->mods[mod->internal_id()]->setStatus(ModStatus::NoMetadata); } @@ -124,7 +121,7 @@ void ModFolderLoadTask::getFromMetadata() for (auto entry : m_index_dir.entryList(QDir::Files)) { auto metadata = Metadata::get(m_index_dir, entry); - if(!metadata.isValid()){ + if (!metadata.isValid()) { return; } diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h index af5f58a5e..7ce13cfaf 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h @@ -1,38 +1,38 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 @@ -44,19 +44,16 @@ #include "minecraft/mod/Mod.h" #include "tasks/Task.h" -class ModFolderLoadTask : public Task -{ +class ModFolderLoadTask : public Task { Q_OBJECT -public: + public: struct Result { QMap mods; }; using ResultPtr = std::shared_ptr; - ResultPtr result() const { - return m_result; - } + ResultPtr result() const { return m_result; } -public: + public: ModFolderLoadTask(QDir mods_dir, QDir index_dir, bool is_indexed, bool clean_orphan = false); [[nodiscard]] bool canAbort() const override { return true; } @@ -66,13 +63,12 @@ public: return true; } - void executeTask() override; -private: + private: void getFromMetadata(); -private: + private: QDir m_mods_dir, m_index_dir; bool m_is_indexed; bool m_clean_orphan; diff --git a/launcher/minecraft/services/CapeChange.cpp b/launcher/minecraft/services/CapeChange.cpp index 1d5ea36da..cb6ed1a41 100644 --- a/launcher/minecraft/services/CapeChange.cpp +++ b/launcher/minecraft/services/CapeChange.cpp @@ -35,27 +35,25 @@ #include "CapeChange.h" -#include #include +#include #include "Application.h" -CapeChange::CapeChange(QObject *parent, QString token, QString cape) - : Task(parent), m_capeId(cape), m_token(token) -{ -} +CapeChange::CapeChange(QObject* parent, QString token, QString cape) : Task(parent), m_capeId(cape), m_token(token) {} -void CapeChange::setCape(QString& cape) { +void CapeChange::setCape(QString& cape) +{ QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active")); auto requestString = QString("{\"capeId\":\"%1\"}").arg(m_capeId); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit()); - QNetworkReply *rep = APPLICATION->network()->put(request, requestString.toUtf8()); + QNetworkReply* rep = APPLICATION->network()->put(request, requestString.toUtf8()); setStatus(tr("Equipping cape")); m_reply = shared_qobject_ptr(rep); connect(rep, &QNetworkReply::uploadProgress, this, &CapeChange::setProgress); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &CapeChange::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &CapeChange::downloadError); @@ -64,17 +62,18 @@ void CapeChange::setCape(QString& cape) { connect(rep, &QNetworkReply::finished, this, &CapeChange::downloadFinished); } -void CapeChange::clearCape() { +void CapeChange::clearCape() +{ QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active")); auto requestString = QString("{\"capeId\":\"%1\"}").arg(m_capeId); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit()); - QNetworkReply *rep = APPLICATION->network()->deleteResource(request); + QNetworkReply* rep = APPLICATION->network()->deleteResource(request); setStatus(tr("Removing cape")); m_reply = shared_qobject_ptr(rep); connect(rep, &QNetworkReply::uploadProgress, this, &CapeChange::setProgress); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &CapeChange::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &CapeChange::downloadError); @@ -83,13 +82,11 @@ void CapeChange::clearCape() { connect(rep, &QNetworkReply::finished, this, &CapeChange::downloadFinished); } - void CapeChange::executeTask() { - if(m_capeId.isEmpty()) { + if (m_capeId.isEmpty()) { clearCape(); - } - else { + } else { setCape(m_capeId); } } @@ -115,8 +112,7 @@ void CapeChange::sslErrors(const QList& errors) void CapeChange::downloadFinished() { // if the download failed - if (m_reply->error() != QNetworkReply::NetworkError::NoError) - { + if (m_reply->error() != QNetworkReply::NetworkError::NoError) { emitFailed(QString("Network error: %1").arg(m_reply->errorString())); m_reply.reset(); return; diff --git a/launcher/minecraft/services/CapeChange.h b/launcher/minecraft/services/CapeChange.h index 38069f90a..d0c893c44 100644 --- a/launcher/minecraft/services/CapeChange.h +++ b/launcher/minecraft/services/CapeChange.h @@ -3,31 +3,29 @@ #include #include #include -#include "tasks/Task.h" #include "QObjectPtr.h" +#include "tasks/Task.h" -class CapeChange : public Task -{ +class CapeChange : public Task { Q_OBJECT -public: - CapeChange(QObject *parent, QString token, QString capeId); + public: + CapeChange(QObject* parent, QString token, QString capeId); virtual ~CapeChange() {} -private: - void setCape(QString & cape); + private: + void setCape(QString& cape); void clearCape(); -private: + private: QString m_capeId; QString m_token; shared_qobject_ptr m_reply; -protected: + protected: virtual void executeTask(); -public slots: + public slots: void downloadError(QNetworkReply::NetworkError); void sslErrors(const QList& errors); void downloadFinished(); }; - diff --git a/launcher/minecraft/services/SkinDelete.cpp b/launcher/minecraft/services/SkinDelete.cpp index fbaaeacb6..3737a5af8 100644 --- a/launcher/minecraft/services/SkinDelete.cpp +++ b/launcher/minecraft/services/SkinDelete.cpp @@ -35,26 +35,23 @@ #include "SkinDelete.h" -#include #include +#include #include "Application.h" -SkinDelete::SkinDelete(QObject *parent, QString token) - : Task(parent), m_token(token) -{ -} +SkinDelete::SkinDelete(QObject* parent, QString token) : Task(parent), m_token(token) {} void SkinDelete::executeTask() { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/skins/active")); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit()); - QNetworkReply *rep = APPLICATION->network()->deleteResource(request); + QNetworkReply* rep = APPLICATION->network()->deleteResource(request); m_reply = shared_qobject_ptr(rep); setStatus(tr("Deleting skin")); connect(rep, &QNetworkReply::uploadProgress, this, &SkinDelete::setProgress); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &SkinDelete::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &SkinDelete::downloadError); @@ -84,12 +81,10 @@ void SkinDelete::sslErrors(const QList& errors) void SkinDelete::downloadFinished() { // if the download failed - if (m_reply->error() != QNetworkReply::NetworkError::NoError) - { + if (m_reply->error() != QNetworkReply::NetworkError::NoError) { emitFailed(QString("Network error: %1").arg(m_reply->errorString())); m_reply.reset(); return; } emitSucceeded(); } - diff --git a/launcher/minecraft/services/SkinDelete.h b/launcher/minecraft/services/SkinDelete.h index b9a1c9d3f..d5b2e63db 100644 --- a/launcher/minecraft/services/SkinDelete.h +++ b/launcher/minecraft/services/SkinDelete.h @@ -6,21 +6,20 @@ typedef shared_qobject_ptr SkinDeletePtr; -class SkinDelete : public Task -{ +class SkinDelete : public Task { Q_OBJECT -public: - SkinDelete(QObject *parent, QString token); + public: + SkinDelete(QObject* parent, QString token); virtual ~SkinDelete() = default; -private: + private: QString m_token; shared_qobject_ptr m_reply; -protected: + protected: virtual void executeTask(); -public slots: + public slots: void downloadError(QNetworkReply::NetworkError); void sslErrors(const QList& errors); void downloadFinished(); diff --git a/launcher/minecraft/services/SkinUpload.cpp b/launcher/minecraft/services/SkinUpload.cpp index 711f87392..299608815 100644 --- a/launcher/minecraft/services/SkinUpload.cpp +++ b/launcher/minecraft/services/SkinUpload.cpp @@ -35,12 +35,13 @@ #include "SkinUpload.h" -#include #include +#include #include "Application.h" -QByteArray getVariant(SkinUpload::Model model) { +QByteArray getVariant(SkinUpload::Model model) +{ switch (model) { default: qDebug() << "Unknown skin type!"; @@ -51,16 +52,15 @@ QByteArray getVariant(SkinUpload::Model model) { } } -SkinUpload::SkinUpload(QObject *parent, QString token, QByteArray skin, SkinUpload::Model model) +SkinUpload::SkinUpload(QObject* parent, QString token, QByteArray skin, SkinUpload::Model model) : Task(parent), m_model(model), m_skin(skin), m_token(token) -{ -} +{} void SkinUpload::executeTask() { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/skins")); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit()); - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart skin; skin.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png")); @@ -74,12 +74,12 @@ void SkinUpload::executeTask() multiPart->append(skin); multiPart->append(model); - QNetworkReply *rep = APPLICATION->network()->post(request, multiPart); + QNetworkReply* rep = APPLICATION->network()->post(request, multiPart); m_reply = shared_qobject_ptr(rep); setStatus(tr("Uploading skin")); connect(rep, &QNetworkReply::uploadProgress, this, &SkinUpload::setProgress); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &SkinUpload::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &SkinUpload::downloadError); @@ -109,8 +109,7 @@ void SkinUpload::sslErrors(const QList& errors) void SkinUpload::downloadFinished() { // if the download failed - if (m_reply->error() != QNetworkReply::NetworkError::NoError) - { + if (m_reply->error() != QNetworkReply::NetworkError::NoError) { emitFailed(QString("Network error: %1").arg(m_reply->errorString())); m_reply.reset(); return; diff --git a/launcher/minecraft/services/SkinUpload.h b/launcher/minecraft/services/SkinUpload.h index ac8c5b361..5716aa996 100644 --- a/launcher/minecraft/services/SkinUpload.h +++ b/launcher/minecraft/services/SkinUpload.h @@ -7,29 +7,25 @@ typedef shared_qobject_ptr SkinUploadPtr; -class SkinUpload : public Task -{ +class SkinUpload : public Task { Q_OBJECT -public: - enum Model - { - STEVE, - ALEX - }; + public: + enum Model { STEVE, ALEX }; // Note this class takes ownership of the file. - SkinUpload(QObject *parent, QString token, QByteArray skin, Model model = STEVE); + SkinUpload(QObject* parent, QString token, QByteArray skin, Model model = STEVE); virtual ~SkinUpload() {} -private: + private: Model m_model; QByteArray m_skin; QString m_token; shared_qobject_ptr m_reply; -protected: + + protected: virtual void executeTask(); -public slots: + public slots: void downloadError(QNetworkReply::NetworkError); void sslErrors(const QList& errors); diff --git a/launcher/minecraft/update/AssetUpdateTask.cpp b/launcher/minecraft/update/AssetUpdateTask.cpp index fda85ba8a..7043d9878 100644 --- a/launcher/minecraft/update/AssetUpdateTask.cpp +++ b/launcher/minecraft/update/AssetUpdateTask.cpp @@ -1,20 +1,18 @@ #include "AssetUpdateTask.h" +#include "minecraft/AssetsUtils.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" #include "net/ChecksumValidator.h" -#include "minecraft/AssetsUtils.h" #include "Application.h" -AssetUpdateTask::AssetUpdateTask(MinecraftInstance * inst) +AssetUpdateTask::AssetUpdateTask(MinecraftInstance* inst) { m_inst = inst; } -AssetUpdateTask::~AssetUpdateTask() -{ -} +AssetUpdateTask::~AssetUpdateTask() {} void AssetUpdateTask::executeTask() { @@ -24,10 +22,7 @@ void AssetUpdateTask::executeTask() auto assets = profile->getMinecraftAssets(); QUrl indexUrl = assets->url; QString localPath = assets->id + ".json"; - auto job = makeShared( - tr("Asset index for %1").arg(m_inst->name()), - APPLICATION->network() - ); + auto job = makeShared(tr("Asset index for %1").arg(m_inst->name()), APPLICATION->network()); auto metacache = APPLICATION->metacache(); auto entry = metacache->resolveEntry("asset_indexes", localPath); @@ -43,7 +38,7 @@ void AssetUpdateTask::executeTask() connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::assetIndexFinished); connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetIndexFailed); - connect(downloadJob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); + connect(downloadJob.get(), &NetJob::aborted, this, [this] { emitFailed(tr("Aborted")); }); connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress); connect(downloadJob.get(), &NetJob::stepProgress, this, &AssetUpdateTask::propagateStepProgress); @@ -67,8 +62,7 @@ void AssetUpdateTask::assetIndexFinished() QString asset_fname = "assets/indexes/" + assets->id + ".json"; // FIXME: this looks like a job for a generic validator based on json schema? - if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, index)) - { + if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, index)) { auto metacache = APPLICATION->metacache(); auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json"); metacache->evictEntry(entry); @@ -76,13 +70,12 @@ void AssetUpdateTask::assetIndexFinished() } auto job = index.getDownloadJob(); - if(job) - { + if (job) { setStatus(tr("Getting the assets files from Mojang...")); downloadJob = job; connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded); connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed); - connect(downloadJob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); + connect(downloadJob.get(), &NetJob::aborted, this, [this] { emitFailed(tr("Aborted")); }); connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress); connect(downloadJob.get(), &NetJob::stepProgress, this, &AssetUpdateTask::propagateStepProgress); downloadJob->start(); @@ -104,12 +97,9 @@ void AssetUpdateTask::assetsFailed(QString reason) bool AssetUpdateTask::abort() { - if(downloadJob) - { + if (downloadJob) { return downloadJob->abort(); - } - else - { + } else { qWarning() << "Prematurely aborted AssetUpdateTask"; } return true; diff --git a/launcher/minecraft/update/AssetUpdateTask.h b/launcher/minecraft/update/AssetUpdateTask.h index 6d7356f38..6f053a54a 100644 --- a/launcher/minecraft/update/AssetUpdateTask.h +++ b/launcher/minecraft/update/AssetUpdateTask.h @@ -1,28 +1,27 @@ #pragma once -#include "tasks/Task.h" #include "net/NetJob.h" +#include "tasks/Task.h" class MinecraftInstance; -class AssetUpdateTask : public Task -{ +class AssetUpdateTask : public Task { Q_OBJECT -public: - AssetUpdateTask(MinecraftInstance * inst); + public: + AssetUpdateTask(MinecraftInstance* inst); virtual ~AssetUpdateTask(); void executeTask() override; bool canAbort() const override; -private slots: + private slots: void assetIndexFinished(); void assetIndexFailed(QString reason); void assetsFailed(QString reason); -public slots: + public slots: bool abort() override; -private: - MinecraftInstance *m_inst; + private: + MinecraftInstance* m_inst; NetJob::Ptr downloadJob; }; diff --git a/launcher/minecraft/update/FMLLibrariesTask.cpp b/launcher/minecraft/update/FMLLibrariesTask.cpp index d9fa0595d..a6ca21021 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.cpp +++ b/launcher/minecraft/update/FMLLibrariesTask.cpp @@ -1,51 +1,47 @@ #include "FMLLibrariesTask.h" #include "FileSystem.h" -#include "minecraft/VersionFilterData.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "minecraft/VersionFilterData.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" -FMLLibrariesTask::FMLLibrariesTask(MinecraftInstance * inst) +FMLLibrariesTask::FMLLibrariesTask(MinecraftInstance* inst) { m_inst = inst; } void FMLLibrariesTask::executeTask() { // Get the mod list - MinecraftInstance *inst = (MinecraftInstance *)m_inst; + MinecraftInstance* inst = (MinecraftInstance*)m_inst; auto components = inst->getPackProfile(); auto profile = components->getProfile(); - if (!profile->hasTrait("legacyFML")) - { + if (!profile->hasTrait("legacyFML")) { emitSucceeded(); return; } QString version = components->getComponentVersion("net.minecraft"); - auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping; - if (!fmlLibsMapping.contains(version)) - { + auto& fmlLibsMapping = g_VersionFilterData.fmlLibsMapping; + if (!fmlLibsMapping.contains(version)) { emitSucceeded(); return; } - auto &libList = fmlLibsMapping[version]; + auto& libList = fmlLibsMapping[version]; // determine if we need some libs for FML or forge setStatus(tr("Checking for FML libraries...")); - if(!components->getComponent("net.minecraftforge")) - { + if (!components->getComponent("net.minecraftforge")) { emitSucceeded(); return; } // now check the lib folder inside the instance for files. - for (auto &lib : libList) - { + for (auto& lib : libList) { QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename)); if (libInfo.exists()) continue; @@ -53,8 +49,7 @@ void FMLLibrariesTask::executeTask() } // if everything is in place, there's nothing to do here... - if (fmlLibsToProcess.isEmpty()) - { + if (fmlLibsToProcess.isEmpty()) { emitSucceeded(); return; } @@ -64,8 +59,7 @@ void FMLLibrariesTask::executeTask() NetJob::Ptr dljob{ new NetJob("FML libraries", APPLICATION->network()) }; auto metacache = APPLICATION->metacache(); Net::Download::Options options = Net::Download::Option::MakeEternal; - for (auto &lib : fmlLibsToProcess) - { + for (auto& lib : fmlLibsToProcess) { auto entry = metacache->resolveEntry("fmllibs", lib.filename); QString urlString = BuildConfig.FMLLIBS_BASE_URL + lib.filename; dljob->addNetAction(Net::Download::makeCached(QUrl(urlString), entry, options)); @@ -73,7 +67,7 @@ void FMLLibrariesTask::executeTask() connect(dljob.get(), &NetJob::succeeded, this, &FMLLibrariesTask::fmllibsFinished); connect(dljob.get(), &NetJob::failed, this, &FMLLibrariesTask::fmllibsFailed); - connect(dljob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); + connect(dljob.get(), &NetJob::aborted, this, [this] { emitFailed(tr("Aborted")); }); connect(dljob.get(), &NetJob::progress, this, &FMLLibrariesTask::progress); connect(dljob.get(), &NetJob::stepProgress, this, &FMLLibrariesTask::propagateStepProgress); downloadJob.reset(dljob); @@ -88,24 +82,20 @@ bool FMLLibrariesTask::canAbort() const void FMLLibrariesTask::fmllibsFinished() { downloadJob.reset(); - if (!fmlLibsToProcess.isEmpty()) - { + if (!fmlLibsToProcess.isEmpty()) { setStatus(tr("Copying FML libraries into the instance...")); - MinecraftInstance *inst = (MinecraftInstance *)m_inst; + MinecraftInstance* inst = (MinecraftInstance*)m_inst; auto metacache = APPLICATION->metacache(); int index = 0; - for (auto &lib : fmlLibsToProcess) - { + for (auto& lib : fmlLibsToProcess) { progress(index, fmlLibsToProcess.size()); auto entry = metacache->resolveEntry("fmllibs", lib.filename); auto path = FS::PathCombine(inst->libDir(), lib.filename); - if (!FS::ensureFilePathExists(path)) - { + if (!FS::ensureFilePathExists(path)) { emitFailed(tr("Failed creating FML library folder inside the instance.")); return; } - if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename))) - { + if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename))) { emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename)); return; } @@ -124,12 +114,9 @@ void FMLLibrariesTask::fmllibsFailed(QString reason) bool FMLLibrariesTask::abort() { - if(downloadJob) - { + if (downloadJob) { return downloadJob->abort(); - } - else - { + } else { qWarning() << "Prematurely aborted FMLLibrariesTask"; } return true; diff --git a/launcher/minecraft/update/FMLLibrariesTask.h b/launcher/minecraft/update/FMLLibrariesTask.h index 2e5ad83a2..9d0102be7 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.h +++ b/launcher/minecraft/update/FMLLibrariesTask.h @@ -1,31 +1,29 @@ #pragma once -#include "tasks/Task.h" -#include "net/NetJob.h" #include "minecraft/VersionFilterData.h" +#include "net/NetJob.h" +#include "tasks/Task.h" class MinecraftInstance; -class FMLLibrariesTask : public Task -{ +class FMLLibrariesTask : public Task { Q_OBJECT -public: - FMLLibrariesTask(MinecraftInstance * inst); - virtual ~FMLLibrariesTask() {}; + public: + FMLLibrariesTask(MinecraftInstance* inst); + virtual ~FMLLibrariesTask(){}; void executeTask() override; bool canAbort() const override; -private slots: + private slots: void fmllibsFinished(); void fmllibsFailed(QString reason); -public slots: + public slots: bool abort() override; -private: - MinecraftInstance *m_inst; + private: + MinecraftInstance* m_inst; NetJob::Ptr downloadJob; QList fmlLibsToProcess; }; - diff --git a/launcher/minecraft/update/FoldersTask.cpp b/launcher/minecraft/update/FoldersTask.cpp index b9ee9d980..3cbc309d0 100644 --- a/launcher/minecraft/update/FoldersTask.cpp +++ b/launcher/minecraft/update/FoldersTask.cpp @@ -34,11 +34,10 @@ */ #include "FoldersTask.h" -#include "minecraft/MinecraftInstance.h" #include +#include "minecraft/MinecraftInstance.h" -FoldersTask::FoldersTask(MinecraftInstance * inst) - :Task() +FoldersTask::FoldersTask(MinecraftInstance* inst) : Task() { m_inst = inst; } @@ -47,8 +46,7 @@ void FoldersTask::executeTask() { // Make directories QDir mcDir(m_inst->gameRoot()); - if (!mcDir.exists() && !mcDir.mkpath(".")) - { + if (!mcDir.exists() && !mcDir.mkpath(".")) { emitFailed(tr("Failed to create folder for Minecraft binaries.")); return; } diff --git a/launcher/minecraft/update/FoldersTask.h b/launcher/minecraft/update/FoldersTask.h index f6ed5e6db..2d2954b2a 100644 --- a/launcher/minecraft/update/FoldersTask.h +++ b/launcher/minecraft/update/FoldersTask.h @@ -3,15 +3,14 @@ #include "tasks/Task.h" class MinecraftInstance; -class FoldersTask : public Task -{ +class FoldersTask : public Task { Q_OBJECT -public: - FoldersTask(MinecraftInstance * inst); - virtual ~FoldersTask() {}; + public: + FoldersTask(MinecraftInstance* inst); + virtual ~FoldersTask(){}; void executeTask() override; -private: - MinecraftInstance *m_inst; -}; + private: + MinecraftInstance* m_inst; +}; diff --git a/launcher/minecraft/update/LibrariesTask.cpp b/launcher/minecraft/update/LibrariesTask.cpp index 9d1c02957..1581b32ee 100644 --- a/launcher/minecraft/update/LibrariesTask.cpp +++ b/launcher/minecraft/update/LibrariesTask.cpp @@ -5,7 +5,7 @@ #include "Application.h" -LibrariesTask::LibrariesTask(MinecraftInstance * inst) +LibrariesTask::LibrariesTask(MinecraftInstance* inst) { m_inst = inst; } @@ -14,7 +14,7 @@ void LibrariesTask::executeTask() { setStatus(tr("Downloading required library files...")); qDebug() << m_inst->name() << ": downloading libraries"; - MinecraftInstance *inst = (MinecraftInstance *)m_inst; + MinecraftInstance* inst = (MinecraftInstance*)m_inst; // Build a list of URLs that will need to be downloaded. auto components = inst->getPackProfile(); @@ -25,18 +25,14 @@ void LibrariesTask::executeTask() auto metacache = APPLICATION->metacache(); - auto processArtifactPool = [&](const QList & pool, QStringList & errors, const QString & localPath) - { - for (auto lib : pool) - { - if(!lib) - { + auto processArtifactPool = [&](const QList& pool, QStringList& errors, const QString& localPath) { + for (auto lib : pool) { + if (!lib) { emitFailed(tr("Null jar is specified in the metadata, aborting.")); return false; } auto dls = lib->getDownloads(inst->runtimeContext(), metacache.get(), errors, localPath); - for(auto dl : dls) - { + for (auto dl : dls) { downloadJob->addNetAction(dl); } } @@ -48,8 +44,7 @@ void LibrariesTask::executeTask() libArtifactPool.append(profile->getLibraries()); libArtifactPool.append(profile->getNativeLibraries()); libArtifactPool.append(profile->getMavenFiles()); - for (auto agent : profile->getAgents()) - { + for (auto agent : profile->getAgents()) { libArtifactPool.append(agent->library()); } libArtifactPool.append(profile->getMainJar()); @@ -58,17 +53,18 @@ void LibrariesTask::executeTask() QStringList failedLocalJarMods; processArtifactPool(profile->getJarMods(), failedLocalJarMods, inst->jarModsDir()); - if (!failedLocalJarMods.empty() || !failedLocalLibraries.empty()) - { + if (!failedLocalJarMods.empty() || !failedLocalLibraries.empty()) { downloadJob.reset(); QString failed_all = (failedLocalLibraries + failedLocalJarMods).join("\n"); - emitFailed(tr("Some artifacts marked as 'local' are missing their files:\n%1\n\nYou need to either add the files, or removed the packages that require them.\nYou'll have to correct this problem manually.").arg(failed_all)); + emitFailed(tr("Some artifacts marked as 'local' are missing their files:\n%1\n\nYou need to either add the files, or removed the " + "packages that require them.\nYou'll have to correct this problem manually.") + .arg(failed_all)); return; } connect(downloadJob.get(), &NetJob::succeeded, this, &LibrariesTask::emitSucceeded); connect(downloadJob.get(), &NetJob::failed, this, &LibrariesTask::jarlibFailed); - connect(downloadJob.get(), &NetJob::aborted, this, [this]{ emitFailed(tr("Aborted")); }); + connect(downloadJob.get(), &NetJob::aborted, this, [this] { emitFailed(tr("Aborted")); }); connect(downloadJob.get(), &NetJob::progress, this, &LibrariesTask::progress); connect(downloadJob.get(), &NetJob::stepProgress, this, &LibrariesTask::propagateStepProgress); @@ -87,12 +83,9 @@ void LibrariesTask::jarlibFailed(QString reason) bool LibrariesTask::abort() { - if(downloadJob) - { + if (downloadJob) { return downloadJob->abort(); - } - else - { + } else { qWarning() << "Prematurely aborted LibrariesTask"; } return true; diff --git a/launcher/minecraft/update/LibrariesTask.h b/launcher/minecraft/update/LibrariesTask.h index b966ad6cb..c969e74df 100644 --- a/launcher/minecraft/update/LibrariesTask.h +++ b/launcher/minecraft/update/LibrariesTask.h @@ -1,26 +1,25 @@ #pragma once -#include "tasks/Task.h" #include "net/NetJob.h" +#include "tasks/Task.h" class MinecraftInstance; -class LibrariesTask : public Task -{ +class LibrariesTask : public Task { Q_OBJECT -public: - LibrariesTask(MinecraftInstance * inst); - virtual ~LibrariesTask() {}; + public: + LibrariesTask(MinecraftInstance* inst); + virtual ~LibrariesTask(){}; void executeTask() override; bool canAbort() const override; -private slots: + private slots: void jarlibFailed(QString reason); -public slots: + public slots: bool abort() override; -private: - MinecraftInstance *m_inst; + private: + MinecraftInstance* m_inst; NetJob::Ptr downloadJob; }; diff --git a/launcher/modplatform/CheckUpdateTask.h b/launcher/modplatform/CheckUpdateTask.h index f7582b8f1..6d968ea48 100644 --- a/launcher/modplatform/CheckUpdateTask.h +++ b/launcher/modplatform/CheckUpdateTask.h @@ -1,8 +1,8 @@ #pragma once #include "minecraft/mod/Mod.h" -#include "modplatform/ResourceAPI.h" #include "modplatform/ModIndex.h" +#include "modplatform/ResourceAPI.h" #include "tasks/Task.h" class ResourceDownloadTask; @@ -12,8 +12,11 @@ class CheckUpdateTask : public Task { Q_OBJECT public: - CheckUpdateTask(QList& mods, 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) {}; + CheckUpdateTask(QList& mods, + 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){}; struct UpdatableMod { QString name; @@ -25,7 +28,13 @@ class CheckUpdateTask : public Task { shared_qobject_ptr download; public: - UpdatableMod(QString name, QString old_h, QString old_v, QString new_v, QString changelog, ModPlatform::ResourceProvider p, shared_qobject_ptr t) + UpdatableMod(QString name, + QString old_h, + QString old_v, + QString new_v, + QString changelog, + ModPlatform::ResourceProvider p, + shared_qobject_ptr t) : name(name), old_hash(old_h), old_version(old_v), new_version(new_v), changelog(changelog), provider(p), download(t) {} }; diff --git a/launcher/modplatform/EnsureMetadataTask.h b/launcher/modplatform/EnsureMetadataTask.h index 03cae4e4a..2f276e5a0 100644 --- a/launcher/modplatform/EnsureMetadataTask.h +++ b/launcher/modplatform/EnsureMetadataTask.h @@ -35,10 +35,7 @@ class EnsureMetadataTask : public Task { auto flameProjectsTask() -> Task::Ptr; // Helpers - enum class RemoveFromList { - Yes, - No - }; + enum class RemoveFromList { Yes, No }; void emitReady(Mod*, QString key = {}, RemoveFromList = RemoveFromList::Yes); void emitFail(Mod*, QString key = {}, RemoveFromList = RemoveFromList::Yes); diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index a1c4d8917..ecea0d8ce 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 "modplatform/ModIndex.h" diff --git a/launcher/modplatform/atlauncher/ATLPackIndex.cpp b/launcher/modplatform/atlauncher/ATLPackIndex.cpp index e649c43a6..3be169739 100644 --- a/launcher/modplatform/atlauncher/ATLPackIndex.cpp +++ b/launcher/modplatform/atlauncher/ATLPackIndex.cpp @@ -21,23 +21,20 @@ #include "Json.h" -static void loadIndexedVersion(ATLauncher::IndexedVersion & v, QJsonObject & obj) +static void loadIndexedVersion(ATLauncher::IndexedVersion& v, QJsonObject& obj) { v.version = Json::requireString(obj, "version"); v.minecraft = Json::requireString(obj, "minecraft"); } -void ATLauncher::loadIndexedPack(ATLauncher::IndexedPack & m, QJsonObject & obj) +void ATLauncher::loadIndexedPack(ATLauncher::IndexedPack& m, QJsonObject& obj) { m.id = Json::requireInteger(obj, "id"); m.position = Json::requireInteger(obj, "position"); m.name = Json::requireString(obj, "name"); - m.type = Json::requireString(obj, "type") == "private" ? - ATLauncher::PackType::Private : - ATLauncher::PackType::Public; + m.type = Json::requireString(obj, "type") == "private" ? ATLauncher::PackType::Private : ATLauncher::PackType::Public; auto versionsArr = Json::requireArray(obj, "versions"); - for (const auto versionRaw : versionsArr) - { + for (const auto versionRaw : versionsArr) { auto versionObj = Json::requireObject(versionRaw); ATLauncher::IndexedVersion version; loadIndexedVersion(version, versionObj); diff --git a/launcher/modplatform/atlauncher/ATLPackIndex.h b/launcher/modplatform/atlauncher/ATLPackIndex.h index 337b80b88..8d18c671d 100644 --- a/launcher/modplatform/atlauncher/ATLPackIndex.h +++ b/launcher/modplatform/atlauncher/ATLPackIndex.h @@ -18,21 +18,18 @@ #include "ATLPackManifest.h" +#include #include #include -#include -namespace ATLauncher -{ +namespace ATLauncher { -struct IndexedVersion -{ +struct IndexedVersion { QString version; QString minecraft; }; -struct IndexedPack -{ +struct IndexedPack { int id; int position; QString name; @@ -44,7 +41,7 @@ struct IndexedPack QString safeName; }; -void loadIndexedPack(IndexedPack & m, QJsonObject & obj); -} +void loadIndexedPack(IndexedPack& m, QJsonObject& obj); +} // namespace ATLauncher Q_DECLARE_METATYPE(ATLauncher::IndexedPack) diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 82a51c274..1ac527bc9 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -40,27 +40,27 @@ #include -#include "MMCZip.h" -#include "minecraft/OneSixVersionFormat.h" -#include "Version.h" -#include "net/ChecksumValidator.h" #include "FileSystem.h" #include "Json.h" -#include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" -#include "settings/INISettingsObject.h" +#include "MMCZip.h" +#include "Version.h" #include "meta/Index.h" #include "meta/Version.h" #include "meta/VersionList.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/OneSixVersionFormat.h" +#include "minecraft/PackProfile.h" +#include "net/ChecksumValidator.h" +#include "settings/INISettingsObject.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" namespace ATLauncher { static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version); -PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode) +PackInstallTask::PackInstallTask(UserInteractionSupport* support, QString packName, QString version, InstallMode installMode) { m_support = support; m_pack_name = packName; @@ -71,8 +71,7 @@ PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString packNa bool PackInstallTask::abort() { - if(abortable) - { + if (abortable) { return jobPtr->abort(); } return false; @@ -110,12 +109,9 @@ void PackInstallTask::onDownloadSucceeded() auto obj = doc.object(); ATLauncher::PackVersion version; - try - { + try { ATLauncher::loadVersion(version, obj); - } - catch (const JSONValidationError &e) - { + } catch (const JSONValidationError& e) { emitFailed(tr("Could not understand pack manifest:\n") + e.cause()); return; } @@ -126,20 +122,20 @@ void PackInstallTask::onDownloadSucceeded() bool resetDirectory; switch (m_install_mode) { - case InstallMode::Reinstall: - case InstallMode::Update: - message = m_version.messages.update; - resetDirectory = true; - break; + case InstallMode::Reinstall: + case InstallMode::Update: + message = m_version.messages.update; + resetDirectory = true; + break; - case InstallMode::Install: - message = m_version.messages.install; - resetDirectory = false; - break; + case InstallMode::Install: + message = m_version.messages.install; + resetDirectory = false; + break; - default: - emitFailed(tr("Unsupported installation mode")); - return; + default: + emitFailed(tr("Unsupported installation mode")); + return; } // Display message if one exists @@ -157,10 +153,9 @@ void PackInstallTask::onDownloadSucceeded() deleteExistingFiles(); } - if(m_version.noConfigs) { + if (m_version.noConfigs) { downloadMods(); - } - else { + } else { installConfigs(); } } @@ -212,11 +207,9 @@ void PackInstallTask::deleteExistingFiles() if (base == "root") { return minecraftPath; - } - else if (base == "config") { + } else if (base == "config") { return FS::PathCombine(minecraftPath, "config"); - } - else { + } else { qWarning() << "Unrecognised base path" << base; return minecraftPath; } @@ -338,19 +331,18 @@ QString PackInstallTask::getDirForModType(ModType type, QString raw) QString PackInstallTask::getVersionForLoader(QString uid) { - if(m_version.loader.recommended || m_version.loader.latest || m_version.loader.choose) { + if (m_version.loader.recommended || m_version.loader.latest || m_version.loader.choose) { auto vlist = APPLICATION->metadataIndex()->get(uid); - if(!vlist) - { + if (!vlist) { emitFailed(tr("Failed to get local metadata index for %1").arg(uid)); return Q_NULLPTR; } - if(!vlist->isLoaded()) { + if (!vlist->isLoaded()) { vlist->load(Net::Mode::Online); } - if(m_version.loader.recommended || m_version.loader.latest) { + if (m_version.loader.recommended || m_version.loader.latest) { for (int i = 0; i < vlist->versions().size(); i++) { auto version = vlist->versions().at(i); auto reqs = version->requiredSet(); @@ -359,16 +351,17 @@ QString PackInstallTask::getVersionForLoader(QString uid) // not all mod loaders depend on a given Minecraft version, so we won't do this // filtering for those loaders. if (m_version.loader.type != "fabric") { - auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require &req) { - return req.uid == "net.minecraft"; - }); - if (iter == reqs.end()) continue; - if (iter->equalsVersion != m_version.minecraft) continue; + auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require& req) { return req.uid == "net.minecraft"; }); + if (iter == reqs.end()) + continue; + if (iter->equalsVersion != m_version.minecraft) + continue; } if (m_version.loader.recommended) { // first recommended build we find, we use. - if (!version->isRecommended()) continue; + if (!version->isRecommended()) + continue; } return version->descriptor(); @@ -376,8 +369,7 @@ QString PackInstallTask::getVersionForLoader(QString uid) emitFailed(tr("Failed to find version for %1 loader").arg(m_version.loader.type)); return Q_NULLPTR; - } - else if(m_version.loader.choose) { + } else if (m_version.loader.choose) { // Fabric Loader doesn't depend on a given Minecraft version. if (m_version.loader.type == "fabric") { return m_support->chooseVersion(vlist, Q_NULLPTR); @@ -414,15 +406,14 @@ QString PackInstallTask::detectLibrary(VersionLibrary library) return group + ":" + artefact + ":" + version; } - if(library.file.contains("-")) { + if (library.file.contains("-")) { auto lastSlash = library.file.lastIndexOf("-"); auto name = library.file.mid(0, lastSlash); auto version = library.file.mid(lastSlash + 1).remove(".jar"); - if(name == QString("guava")) { + if (name == QString("guava")) { return "com.google.guava:guava:" + version; - } - else if(name == QString("commons-lang3")) { + } else if (name == QString("commons-lang3")) { return "org.apache.commons:commons-lang3:" + version; } } @@ -432,22 +423,22 @@ QString PackInstallTask::detectLibrary(VersionLibrary library) bool PackInstallTask::createLibrariesComponent(QString instanceRoot, std::shared_ptr profile) { - if(m_version.libraries.isEmpty()) { + if (m_version.libraries.isEmpty()) { return true; } QList exempt; - for(const auto & componentUid : componentsToInstall.keys()) { + for (const auto& componentUid : componentsToInstall.keys()) { auto componentVersion = componentsToInstall.value(componentUid); - for(const auto & library : componentVersion->data()->libraries) { + for (const auto& library : componentVersion->data()->libraries) { GradleSpecifier lib(library->rawName()); exempt.append(lib); } } { - for(const auto & library : minecraftVersion->data()->libraries) { + for (const auto& library : minecraftVersion->data()->libraries) { GradleSpecifier lib(library->rawName()); exempt.append(lib); } @@ -458,8 +449,7 @@ bool PackInstallTask::createLibrariesComponent(QString instanceRoot, std::shared auto target_id = "org.multimc.atlauncher." + id; auto patchDir = FS::PathCombine(instanceRoot, "patches"); - if(!FS::ensureFolderPathExists(patchDir)) - { + if (!FS::ensureFolderPathExists(patchDir)) { return false; } auto patchFileName = FS::PathCombine(patchDir, target_id + ".json"); @@ -468,38 +458,24 @@ bool PackInstallTask::createLibrariesComponent(QString instanceRoot, std::shared f->name = m_pack_name + " " + m_version_name + " (libraries)"; const static QMap liteLoaderMap = { - { "61179803bcd5fb7790789b790908663d", "1.12-SNAPSHOT" }, - { "1420785ecbfed5aff4a586c5c9dd97eb", "1.12.2-SNAPSHOT" }, - { "073f68e2fcb518b91fd0d99462441714", "1.6.2_03" }, - { "10a15b52fc59b1bfb9c05b56de1097d6", "1.6.2_02" }, - { "b52f90f08303edd3d4c374e268a5acf1", "1.6.2_04" }, - { "ea747e24e03e24b7cad5bc8a246e0319", "1.6.2_01" }, - { "55785ccc82c07ff0ba038fe24be63ea2", "1.7.10_01" }, - { "63ada46e033d0cb6782bada09ad5ca4e", "1.7.10_04" }, - { "7983e4b28217c9ae8569074388409c86", "1.7.10_03" }, - { "c09882458d74fe0697c7681b8993097e", "1.7.10_02" }, - { "db7235aefd407ac1fde09a7baba50839", "1.7.10_00" }, - { "6e9028816027f53957bd8fcdfabae064", "1.8" }, - { "5e732dc446f9fe2abe5f9decaec40cde", "1.10-SNAPSHOT" }, - { "3a98b5ed95810bf164e71c1a53be568d", "1.11.2-SNAPSHOT" }, - { "ba8e6285966d7d988a96496f48cbddaa", "1.8.9-SNAPSHOT" }, - { "8524af3ac3325a82444cc75ae6e9112f", "1.11-SNAPSHOT" }, - { "53639d52340479ccf206a04f5e16606f", "1.5.2_01" }, - { "1fcdcf66ce0a0806b7ad8686afdce3f7", "1.6.4_00" }, - { "531c116f71ae2b11033f9a11a0f8e668", "1.6.4_01" }, - { "4009eeb99c9068f608d3483a6439af88", "1.7.2_03" }, - { "66f343354b8417abce1a10d557d2c6e9", "1.7.2_04" }, - { "ab554c21f28fbc4ae9b098bcb5f4cceb", "1.7.2_05" }, - { "e1d76a05a3723920e2f80a5e66c45f16", "1.7.2_02" }, - { "00318cb0c787934d523f63cdfe8ddde4", "1.9-SNAPSHOT" }, - { "986fd1ee9525cb0dcab7609401cef754", "1.9.4-SNAPSHOT" }, - { "571ad5e6edd5ff40259570c9be588bb5", "1.9.4" }, - { "1cdd72f7232e45551f16cc8ffd27ccf3", "1.10.2-SNAPSHOT" }, - { "8a7c21f32d77ee08b393dd3921ced8eb", "1.10.2" }, - { "b9bef8abc8dc309069aeba6fbbe58980", "1.12.1-SNAPSHOT" } + { "61179803bcd5fb7790789b790908663d", "1.12-SNAPSHOT" }, { "1420785ecbfed5aff4a586c5c9dd97eb", "1.12.2-SNAPSHOT" }, + { "073f68e2fcb518b91fd0d99462441714", "1.6.2_03" }, { "10a15b52fc59b1bfb9c05b56de1097d6", "1.6.2_02" }, + { "b52f90f08303edd3d4c374e268a5acf1", "1.6.2_04" }, { "ea747e24e03e24b7cad5bc8a246e0319", "1.6.2_01" }, + { "55785ccc82c07ff0ba038fe24be63ea2", "1.7.10_01" }, { "63ada46e033d0cb6782bada09ad5ca4e", "1.7.10_04" }, + { "7983e4b28217c9ae8569074388409c86", "1.7.10_03" }, { "c09882458d74fe0697c7681b8993097e", "1.7.10_02" }, + { "db7235aefd407ac1fde09a7baba50839", "1.7.10_00" }, { "6e9028816027f53957bd8fcdfabae064", "1.8" }, + { "5e732dc446f9fe2abe5f9decaec40cde", "1.10-SNAPSHOT" }, { "3a98b5ed95810bf164e71c1a53be568d", "1.11.2-SNAPSHOT" }, + { "ba8e6285966d7d988a96496f48cbddaa", "1.8.9-SNAPSHOT" }, { "8524af3ac3325a82444cc75ae6e9112f", "1.11-SNAPSHOT" }, + { "53639d52340479ccf206a04f5e16606f", "1.5.2_01" }, { "1fcdcf66ce0a0806b7ad8686afdce3f7", "1.6.4_00" }, + { "531c116f71ae2b11033f9a11a0f8e668", "1.6.4_01" }, { "4009eeb99c9068f608d3483a6439af88", "1.7.2_03" }, + { "66f343354b8417abce1a10d557d2c6e9", "1.7.2_04" }, { "ab554c21f28fbc4ae9b098bcb5f4cceb", "1.7.2_05" }, + { "e1d76a05a3723920e2f80a5e66c45f16", "1.7.2_02" }, { "00318cb0c787934d523f63cdfe8ddde4", "1.9-SNAPSHOT" }, + { "986fd1ee9525cb0dcab7609401cef754", "1.9.4-SNAPSHOT" }, { "571ad5e6edd5ff40259570c9be588bb5", "1.9.4" }, + { "1cdd72f7232e45551f16cc8ffd27ccf3", "1.10.2-SNAPSHOT" }, { "8a7c21f32d77ee08b393dd3921ced8eb", "1.10.2" }, + { "b9bef8abc8dc309069aeba6fbbe58980", "1.12.1-SNAPSHOT" } }; - for(const auto & lib : m_version.libraries) { + for (const auto& lib : m_version.libraries) { // If the library is LiteLoader, we need to ignore it and handle it separately. if (liteLoaderMap.contains(lib.md5)) { auto ver = getComponentVersion("com.mumfrey.liteloader", liteLoaderMap.value(lib.md5)); @@ -513,18 +489,19 @@ bool PackInstallTask::createLibrariesComponent(QString instanceRoot, std::shared GradleSpecifier libSpecifier(libName); bool libExempt = false; - for(const auto & existingLib : exempt) { - if(libSpecifier.matchName(existingLib)) { + for (const auto& existingLib : exempt) { + if (libSpecifier.matchName(existingLib)) { // If the pack specifies a newer version of the lib, use that! libExempt = Version(libSpecifier.version()) >= Version(existingLib.version()); } } - if(libExempt) continue; + if (libExempt) + continue; auto library = std::make_shared(); library->setRawName(libName); - switch(lib.download) { + switch (lib.download) { case DownloadType::Server: library->setAbsoluteUrl(BuildConfig.ATL_DOWNLOAD_SERVER_URL + lib.url); break; @@ -540,15 +517,13 @@ bool PackInstallTask::createLibrariesComponent(QString instanceRoot, std::shared f->libraries.append(library); } - if(f->libraries.isEmpty()) { + if (f->libraries.isEmpty()) { return true; } QFile file(patchFileName); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); + if (!file.open(QFile::WriteOnly)) { + qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString(); return false; } file.write(OneSixVersionFormat::versionFileToJson(f).toJson()); @@ -593,18 +568,17 @@ bool PackInstallTask::createPackComponent(QString instanceRoot, std::shared_ptr< auto target_id = "org.multimc.atlauncher." + id; auto patchDir = FS::PathCombine(instanceRoot, "patches"); - if(!FS::ensureFolderPathExists(patchDir)) - { + if (!FS::ensureFolderPathExists(patchDir)) { return false; } auto patchFileName = FS::PathCombine(patchDir, target_id + ".json"); QStringList mainClasses; QStringList tweakers; - for(const auto & componentUid : componentsToInstall.keys()) { + for (const auto& componentUid : componentsToInstall.keys()) { auto componentVersion = componentsToInstall.value(componentUid); - if(componentVersion->data()->mainClass != QString("")) { + if (componentVersion->data()->mainClass != QString("")) { mainClasses.append(componentVersion->data()->mainClass); } tweakers.append(componentVersion->data()->addTweakers); @@ -619,25 +593,24 @@ bool PackInstallTask::createPackComponent(QString instanceRoot, std::shared_ptr< // Parse out tweakers auto args = extraArguments.split(" "); QString previous; - for(auto arg : args) { - if(arg.startsWith("--tweakClass=") || previous == "--tweakClass") { + for (auto arg : args) { + if (arg.startsWith("--tweakClass=") || previous == "--tweakClass") { auto tweakClass = arg.remove("--tweakClass="); - if(tweakers.contains(tweakClass)) continue; + if (tweakers.contains(tweakClass)) + continue; f->addTweakers.append(tweakClass); } previous = arg; } - if(f->mainClass == QString() && f->addTweakers.isEmpty()) { + if (f->mainClass == QString() && f->addTweakers.isEmpty()) { return true; } QFile file(patchFileName); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); + if (!file.open(QFile::WriteOnly)) { + qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString(); return false; } file.write(OneSixVersionFormat::versionFileToJson(f).toJson()); @@ -654,8 +627,7 @@ void PackInstallTask::installConfigs() jobPtr.reset(new NetJob(tr("Config download"), APPLICATION->network())); auto path = QString("Configs/%1/%2.zip").arg(m_pack_safe_name).arg(m_version_name); - auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.zip") - .arg(m_pack_safe_name).arg(m_version_name); + auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.zip").arg(m_pack_safe_name).arg(m_version_name); auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", path); entry->setStale(true); @@ -667,25 +639,22 @@ void PackInstallTask::installConfigs() jobPtr->addNetAction(dl); archivePath = entry->getFullPath(); - connect(jobPtr.get(), &NetJob::succeeded, this, [&]() - { + connect(jobPtr.get(), &NetJob::succeeded, this, [&]() { abortable = false; jobPtr.reset(); extractConfigs(); }); - connect(jobPtr.get(), &NetJob::failed, [&](QString reason) - { + connect(jobPtr.get(), &NetJob::failed, [&](QString reason) { abortable = false; jobPtr.reset(); emitFailed(reason); }); - connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) - { + connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) { abortable = true; setProgress(current, total); }); connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); - connect(jobPtr.get(), &NetJob::aborted, [&]{ + connect(jobPtr.get(), &NetJob::aborted, [&] { abortable = false; jobPtr.reset(); emitAborted(); @@ -702,25 +671,20 @@ void PackInstallTask::extractConfigs() QDir extractDir(m_stagingPath); QuaZip packZip(archivePath); - if(!packZip.open(QuaZip::mdUnzip)) - { + if (!packZip.open(QuaZip::mdUnzip)) { emitFailed(tr("Failed to open pack configs %1!").arg(archivePath)); return; } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload::of(MMCZip::extractDir), archivePath, extractDir.absolutePath() + "/minecraft"); + m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload::of(MMCZip::extractDir), archivePath, + extractDir.absolutePath() + "/minecraft"); #else - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft"); + m_extractFuture = + QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft"); #endif - connect(&m_extractFutureWatcher, &QFutureWatcher::finished, this, [&]() - { - downloadMods(); - }); - connect(&m_extractFutureWatcher, &QFutureWatcher::canceled, this, [&]() - { - emitAborted(); - }); + connect(&m_extractFutureWatcher, &QFutureWatcher::finished, this, [&]() { downloadMods(); }); + connect(&m_extractFutureWatcher, &QFutureWatcher::canceled, this, [&]() { emitAborted(); }); m_extractFutureWatcher.setFuture(m_extractFuture); } @@ -751,15 +715,17 @@ void PackInstallTask::downloadMods() jarmods.clear(); jobPtr.reset(new NetJob(tr("Mod download"), APPLICATION->network())); - for(const auto& mod : m_version.mods) { + for (const auto& mod : m_version.mods) { // skip non-client mods - if(!mod.client) continue; + if (!mod.client) + continue; // skip optional mods that were not selected - if(mod.optional && !selectedMods.contains(mod.name)) continue; + if (mod.optional && !selectedMods.contains(mod.name)) + continue; QString url; - switch(mod.download) { + switch (mod.download) { case DownloadType::Server: url = BuildConfig.ATL_DOWNLOAD_SERVER_URL + mod.url; break; @@ -788,8 +754,7 @@ void PackInstallTask::downloadMods() dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); } jobPtr->addNetAction(dl); - } - else if(mod.type == ModType::Decomp) { + } else if (mod.type == ModType::Decomp) { auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); modsToDecomp.insert(entry->getFullPath(), mod); @@ -800,10 +765,10 @@ void PackInstallTask::downloadMods() dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5)); } jobPtr->addNetAction(dl); - } - else { + } else { auto relpath = getDirForModType(mod.type, mod.type_raw); - if(relpath == Q_NULLPTR) continue; + if (relpath == Q_NULLPTR) + continue; auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); @@ -817,7 +782,7 @@ void PackInstallTask::downloadMods() auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file); - if(mod.type == ModType::Forge) { + if (mod.type == ModType::Forge) { auto ver = getComponentVersion("net.minecraftforge", mod.version); if (ver) { componentsToInstall.insert("net.minecraftforge", ver); @@ -828,7 +793,7 @@ void PackInstallTask::downloadMods() jarmods.push_back(path); } - if(mod.type == ModType::Jar) { + if (mod.type == ModType::Jar) { qDebug() << "Jarmod: " + path; jarmods.push_back(path); } @@ -840,21 +805,18 @@ void PackInstallTask::downloadMods() } connect(jobPtr.get(), &NetJob::succeeded, this, &PackInstallTask::onModsDownloaded); - connect(jobPtr.get(), &NetJob::failed, [&](QString reason) - { + connect(jobPtr.get(), &NetJob::failed, [&](QString reason) { abortable = false; jobPtr.reset(); emitFailed(reason); }); - connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) - { + connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total) { setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); abortable = true; setProgress(current, total); }); connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); - connect(jobPtr.get(), &NetJob::aborted, [&] - { + connect(jobPtr.get(), &NetJob::aborted, [&] { abortable = false; jobPtr.reset(); emitAborted(); @@ -863,60 +825,56 @@ void PackInstallTask::downloadMods() jobPtr->start(); } -void PackInstallTask::onModsDownloaded() { +void PackInstallTask::onModsDownloaded() +{ abortable = false; qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId(); jobPtr.reset(); - if(!modsToExtract.empty() || !modsToDecomp.empty() || !modsToCopy.empty()) { + if (!modsToExtract.empty() || !modsToDecomp.empty() || !modsToCopy.empty()) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - m_modExtractFuture = QtConcurrent::run(QThreadPool::globalInstance(), &PackInstallTask::extractMods, this, modsToExtract, modsToDecomp, modsToCopy); + m_modExtractFuture = + QtConcurrent::run(QThreadPool::globalInstance(), &PackInstallTask::extractMods, this, modsToExtract, modsToDecomp, modsToCopy); #else - m_modExtractFuture = QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy); + m_modExtractFuture = + QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy); #endif connect(&m_modExtractFutureWatcher, &QFutureWatcher::finished, this, &PackInstallTask::onModsExtracted); - connect(&m_modExtractFutureWatcher, &QFutureWatcher::canceled, this, [&]() - { - emitAborted(); - }); + connect(&m_modExtractFutureWatcher, &QFutureWatcher::canceled, this, [&]() { emitAborted(); }); m_modExtractFutureWatcher.setFuture(m_modExtractFuture); - } - else { + } else { install(); } } -void PackInstallTask::onModsExtracted() { +void PackInstallTask::onModsExtracted() +{ qDebug() << "PackInstallTask::onModsExtracted: " << QThread::currentThreadId(); - if(m_modExtractFuture.result()) { + if (m_modExtractFuture.result()) { install(); - } - else { + } else { emitFailed(tr("Failed to extract mods...")); } } -bool PackInstallTask::extractMods( - const QMap &toExtract, - const QMap &toDecomp, - const QMap &toCopy -) { +bool PackInstallTask::extractMods(const QMap& toExtract, + const QMap& toDecomp, + const QMap& toCopy) +{ qDebug() << "PackInstallTask::extractMods: " << QThread::currentThreadId(); setStatus(tr("Extracting mods...")); for (auto iter = toExtract.begin(); iter != toExtract.end(); iter++) { - auto &modPath = iter.key(); - auto &mod = iter.value(); + auto& modPath = iter.key(); + auto& mod = iter.value(); QString extractToDir; - if(mod.type == ModType::Extract) { + if (mod.type == ModType::Extract) { extractToDir = getDirForModType(mod.extractTo, mod.extractTo_raw); - } - else if(mod.type == ModType::TexturePackExtract) { + } else if (mod.type == ModType::TexturePackExtract) { extractToDir = FS::PathCombine("texturepacks", "extracted"); - } - else if(mod.type == ModType::ResourcePackExtract) { + } else if (mod.type == ModType::ResourcePackExtract) { extractToDir = FS::PathCombine("resourcepacks", "extracted"); } @@ -924,36 +882,36 @@ bool PackInstallTask::extractMods( auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir); QString folderToExtract = ""; - if(mod.type == ModType::Extract) { + if (mod.type == ModType::Extract) { folderToExtract = mod.extractFolder; folderToExtract.remove(QRegularExpression("^/")); } qDebug() << "Extracting " + mod.file + " to " + extractToDir; - if(!MMCZip::extractDir(modPath, folderToExtract, extractToPath)) { + if (!MMCZip::extractDir(modPath, folderToExtract, extractToPath)) { // assume error return false; } } for (auto iter = toDecomp.begin(); iter != toDecomp.end(); iter++) { - auto &modPath = iter.key(); - auto &mod = iter.value(); + auto& modPath = iter.key(); + auto& mod = iter.value(); auto extractToDir = getDirForModType(mod.decompType, mod.decompType_raw); QDir extractDir(m_stagingPath); auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir, mod.decompFile); qDebug() << "Extracting " + mod.decompFile + " to " + extractToDir; - if(!MMCZip::extractFile(modPath, mod.decompFile, extractToPath)) { + if (!MMCZip::extractFile(modPath, mod.decompFile, extractToPath)) { qWarning() << "Failed to extract" << mod.decompFile; return false; } } for (auto iter = toCopy.begin(); iter != toCopy.end(); iter++) { - auto &from = iter.key(); - auto &to = iter.value(); + auto& from = iter.key(); + auto& to = iter.value(); // If the file already exists, assume the mod is the correct copy - and remove // the copy from the Configs.zip @@ -966,7 +924,7 @@ bool PackInstallTask::extractMods( } FS::copy fileCopyOperation(from, to); - if(!fileCopyOperation()) { + if (!fileCopyOperation()) { qWarning() << "Failed to copy" << from << "to" << to; return false; } @@ -988,7 +946,7 @@ void PackInstallTask::install() components->buildingFromScratch(); // Use a component to add libraries BEFORE Minecraft - if(!createLibrariesComponent(instance.instanceRoot(), components)) { + if (!createLibrariesComponent(instance.instanceRoot(), components)) { emitFailed(tr("Failed to create libraries component")); return; } @@ -997,27 +955,24 @@ void PackInstallTask::install() components->setComponentVersion("net.minecraft", m_version.minecraft, true); // Loader - if(m_version.loader.type == QString("forge")) - { + if (m_version.loader.type == QString("forge")) { auto version = getVersionForLoader("net.minecraftforge"); - if(version == Q_NULLPTR) return; + if (version == Q_NULLPTR) + return; components->setComponentVersion("net.minecraftforge", version); - } - else if(m_version.loader.type == QString("fabric")) - { + } else if (m_version.loader.type == QString("fabric")) { auto version = getVersionForLoader("net.fabricmc.fabric-loader"); - if(version == Q_NULLPTR) return; + if (version == Q_NULLPTR) + return; components->setComponentVersion("net.fabricmc.fabric-loader", version); - } - else if(m_version.loader.type != QString()) - { + } else if (m_version.loader.type != QString()) { emitFailed(tr("Unknown loader type: ") + m_version.loader.type); return; } - for(const auto & componentUid : componentsToInstall.keys()) { + for (const auto& componentUid : componentsToInstall.keys()) { auto version = componentsToInstall.value(componentUid); components->setComponentVersion(componentUid, version->version()); } @@ -1026,7 +981,7 @@ void PackInstallTask::install() // Use a component to fill in the rest of the data // todo: use more detection - if(!createPackComponent(instance.instanceRoot(), components)) { + if (!createPackComponent(instance.instanceRoot(), components)) { emitFailed(tr("Failed to create pack component")); return; } @@ -1061,4 +1016,4 @@ static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& return ver; } -} +} // namespace ATLauncher diff --git a/launcher/modplatform/atlauncher/ATLPackManifest.cpp b/launcher/modplatform/atlauncher/ATLPackManifest.cpp index 5a458f4e2..88d728c22 100644 --- a/launcher/modplatform/atlauncher/ATLPackManifest.cpp +++ b/launcher/modplatform/atlauncher/ATLPackManifest.cpp @@ -38,84 +38,67 @@ #include "Json.h" -static ATLauncher::DownloadType parseDownloadType(QString rawType) { - if(rawType == QString("server")) { +static ATLauncher::DownloadType parseDownloadType(QString rawType) +{ + if (rawType == QString("server")) { return ATLauncher::DownloadType::Server; - } - else if(rawType == QString("browser")) { + } else if (rawType == QString("browser")) { return ATLauncher::DownloadType::Browser; - } - else if(rawType == QString("direct")) { + } else if (rawType == QString("direct")) { return ATLauncher::DownloadType::Direct; } return ATLauncher::DownloadType::Unknown; } -static ATLauncher::ModType parseModType(QString rawType) { +static ATLauncher::ModType parseModType(QString rawType) +{ // See https://wiki.atlauncher.com/mod_types - if(rawType == QString("root")) { + if (rawType == QString("root")) { return ATLauncher::ModType::Root; - } - else if(rawType == QString("forge")) { + } else if (rawType == QString("forge")) { return ATLauncher::ModType::Forge; - } - else if(rawType == QString("jar")) { + } else if (rawType == QString("jar")) { return ATLauncher::ModType::Jar; - } - else if(rawType == QString("mods")) { + } else if (rawType == QString("mods")) { return ATLauncher::ModType::Mods; - } - else if(rawType == QString("flan")) { + } else if (rawType == QString("flan")) { return ATLauncher::ModType::Flan; - } - else if(rawType == QString("dependency") || rawType == QString("depandency")) { + } else if (rawType == QString("dependency") || rawType == QString("depandency")) { return ATLauncher::ModType::Dependency; - } - else if(rawType == QString("ic2lib")) { + } else if (rawType == QString("ic2lib")) { return ATLauncher::ModType::Ic2Lib; - } - else if(rawType == QString("denlib")) { + } else if (rawType == QString("denlib")) { return ATLauncher::ModType::DenLib; - } - else if(rawType == QString("coremods")) { + } else if (rawType == QString("coremods")) { return ATLauncher::ModType::Coremods; - } - else if(rawType == QString("mcpc")) { + } else if (rawType == QString("mcpc")) { return ATLauncher::ModType::MCPC; - } - else if(rawType == QString("plugins")) { + } else if (rawType == QString("plugins")) { return ATLauncher::ModType::Plugins; - } - else if(rawType == QString("extract")) { + } else if (rawType == QString("extract")) { return ATLauncher::ModType::Extract; - } - else if(rawType == QString("decomp")) { + } else if (rawType == QString("decomp")) { return ATLauncher::ModType::Decomp; - } - else if(rawType == QString("texturepack")) { + } else if (rawType == QString("texturepack")) { return ATLauncher::ModType::TexturePack; - } - else if(rawType == QString("resourcepack")) { + } else if (rawType == QString("resourcepack")) { return ATLauncher::ModType::ResourcePack; - } - else if(rawType == QString("shaderpack")) { + } else if (rawType == QString("shaderpack")) { return ATLauncher::ModType::ShaderPack; - } - else if(rawType == QString("texturepackextract")) { + } else if (rawType == QString("texturepackextract")) { return ATLauncher::ModType::TexturePackExtract; - } - else if(rawType == QString("resourcepackextract")) { + } else if (rawType == QString("resourcepackextract")) { return ATLauncher::ModType::ResourcePackExtract; - } - else if(rawType == QString("millenaire")) { + } else if (rawType == QString("millenaire")) { return ATLauncher::ModType::Millenaire; } return ATLauncher::ModType::Unknown; } -static void loadVersionLoader(ATLauncher::VersionLoader & p, QJsonObject & obj) { +static void loadVersionLoader(ATLauncher::VersionLoader& p, QJsonObject& obj) +{ p.type = Json::requireString(obj, "type"); p.choose = Json::ensureBoolean(obj, QString("choose"), false); @@ -134,7 +117,8 @@ static void loadVersionLoader(ATLauncher::VersionLoader & p, QJsonObject & obj) } } -static void loadVersionLibrary(ATLauncher::VersionLibrary & p, QJsonObject & obj) { +static void loadVersionLibrary(ATLauncher::VersionLibrary& p, QJsonObject& obj) +{ p.url = Json::requireString(obj, "url"); p.file = Json::requireString(obj, "file"); p.md5 = Json::requireString(obj, "md5"); @@ -145,12 +129,14 @@ static void loadVersionLibrary(ATLauncher::VersionLibrary & p, QJsonObject & obj p.server = Json::ensureString(obj, "server", ""); } -static void loadVersionConfigs(ATLauncher::VersionConfigs & p, QJsonObject & obj) { +static void loadVersionConfigs(ATLauncher::VersionConfigs& p, QJsonObject& obj) +{ p.filesize = Json::requireInteger(obj, "filesize"); p.sha1 = Json::requireString(obj, "sha1"); } -static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { +static void loadVersionMod(ATLauncher::VersionMod& p, QJsonObject& obj) +{ p.name = Json::requireString(obj, "name"); p.version = Json::requireString(obj, "version"); p.url = Json::requireString(obj, "url"); @@ -167,18 +153,18 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { // when the mod represents Forge. As there is little difference between "Jar" and "Forge, some // packs regretfully use "Jar". This will correct the type to "Forge" in these cases (as best // it can). - if(p.name == QString("Minecraft Forge") && p.type == ATLauncher::ModType::Jar) { + if (p.name == QString("Minecraft Forge") && p.type == ATLauncher::ModType::Jar) { p.type_raw = "forge"; p.type = ATLauncher::ModType::Forge; } - if(obj.contains("extractTo")) { + if (obj.contains("extractTo")) { p.extractTo_raw = Json::requireString(obj, "extractTo"); p.extractTo = parseModType(p.extractTo_raw); p.extractFolder = Json::ensureString(obj, "extractFolder", "").replace("%s%", "/"); } - if(obj.contains("decompType")) { + if (obj.contains("decompType")) { p.decompType_raw = Json::requireString(obj, "decompType"); p.decompType = parseModType(p.decompType_raw); p.decompFile = Json::requireString(obj, "decompFile"); @@ -191,7 +177,7 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { p.hidden = Json::ensureBoolean(obj, QString("hidden"), false); p.library = Json::ensureBoolean(obj, QString("library"), false); p.group = Json::ensureString(obj, QString("group"), ""); - if(obj.contains("depends")) { + if (obj.contains("depends")) { auto dependsArr = Json::requireArray(obj, "depends"); for (const auto depends : dependsArr) { p.depends.append(Json::requireString(depends)); @@ -282,31 +268,30 @@ static void loadVersionDeletes(ATLauncher::VersionDeletes& d, QJsonObject& obj) } } -void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) +void ATLauncher::loadVersion(PackVersion& v, QJsonObject& obj) { v.version = Json::requireString(obj, "version"); v.minecraft = Json::requireString(obj, "minecraft"); v.noConfigs = Json::ensureBoolean(obj, QString("noConfigs"), false); - if(obj.contains("mainClass")) { + if (obj.contains("mainClass")) { auto main = Json::requireObject(obj, "mainClass"); loadVersionMainClass(v.mainClass, main); } - if(obj.contains("extraArguments")) { + if (obj.contains("extraArguments")) { auto arguments = Json::requireObject(obj, "extraArguments"); loadVersionExtraArguments(v.extraArguments, arguments); } - if(obj.contains("loader")) { + if (obj.contains("loader")) { auto loader = Json::requireObject(obj, "loader"); loadVersionLoader(v.loader, loader); } - if(obj.contains("libraries")) { + if (obj.contains("libraries")) { auto libraries = Json::requireArray(obj, "libraries"); - for (const auto libraryRaw : libraries) - { + for (const auto libraryRaw : libraries) { auto libraryObj = Json::requireObject(libraryRaw); ATLauncher::VersionLibrary target; loadVersionLibrary(target, libraryObj); @@ -314,10 +299,9 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) } } - if(obj.contains("mods")) { + if (obj.contains("mods")) { auto mods = Json::requireArray(obj, "mods"); - for (const auto modRaw : mods) - { + for (const auto modRaw : mods) { auto modObj = Json::requireObject(modRaw); ATLauncher::VersionMod mod; loadVersionMod(mod, modObj); @@ -325,18 +309,18 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) } } - if(obj.contains("configs")) { + if (obj.contains("configs")) { auto configsObj = Json::requireObject(obj, "configs"); loadVersionConfigs(v.configs, configsObj); } auto colourObj = Json::ensureObject(obj, "colours"); - for (const auto &key : colourObj.keys()) { + for (const auto& key : colourObj.keys()) { v.colours[key] = Json::requireString(colourObj.value(key), "colour"); } auto warningsObj = Json::ensureObject(obj, "warnings"); - for (const auto &key : warningsObj.keys()) { + for (const auto& key : warningsObj.keys()) { v.warnings[key] = Json::requireString(warningsObj.value(key), "warning"); } diff --git a/launcher/modplatform/atlauncher/ATLPackManifest.h b/launcher/modplatform/atlauncher/ATLPackManifest.h index 571c976da..fec4bb576 100644 --- a/launcher/modplatform/atlauncher/ATLPackManifest.h +++ b/launcher/modplatform/atlauncher/ATLPackManifest.h @@ -40,17 +40,11 @@ #include #include -namespace ATLauncher -{ +namespace ATLauncher { -enum class PackType -{ - Public, - Private -}; +enum class PackType { Public, Private }; -enum class ModType -{ +enum class ModType { Root, Forge, Jar, @@ -73,16 +67,9 @@ enum class ModType Unknown }; -enum class DownloadType -{ - Server, - Browser, - Direct, - Unknown -}; +enum class DownloadType { Server, Browser, Direct, Unknown }; -struct VersionLoader -{ +struct VersionLoader { QString type; bool latest; bool recommended; @@ -91,8 +78,7 @@ struct VersionLoader QString version; }; -struct VersionLibrary -{ +struct VersionLibrary { QString url; QString file; QString server; @@ -101,8 +87,7 @@ struct VersionLibrary QString download_raw; }; -struct VersionMod -{ +struct VersionMod { QString name; QString version; QString url; @@ -138,14 +123,12 @@ struct VersionMod bool effectively_hidden; }; -struct VersionConfigs -{ +struct VersionConfigs { int filesize; QString sha1; }; -struct VersionMessages -{ +struct VersionMessages { QString install; QString update; }; @@ -170,20 +153,17 @@ struct VersionDeletes { QVector folders; }; -struct PackVersionMainClass -{ +struct PackVersionMainClass { QString mainClass; QString depends; }; -struct PackVersionExtraArguments -{ +struct PackVersionExtraArguments { QString arguments; QString depends; }; -struct PackVersion -{ +struct PackVersion { QString version; QString minecraft; bool noConfigs; @@ -203,6 +183,6 @@ struct PackVersion VersionDeletes deletes; }; -void loadVersion(PackVersion & v, QJsonObject & obj); +void loadVersion(PackVersion& v, QJsonObject& obj); -} +} // namespace ATLauncher diff --git a/launcher/modplatform/atlauncher/ATLShareCode.cpp b/launcher/modplatform/atlauncher/ATLShareCode.cpp index 59030c873..b49631024 100644 --- a/launcher/modplatform/atlauncher/ATLShareCode.cpp +++ b/launcher/modplatform/atlauncher/ATLShareCode.cpp @@ -57,4 +57,4 @@ void loadShareCodeResponse(ShareCodeResponse& r, QJsonObject& obj) } } -} +} // namespace ATLauncher diff --git a/launcher/modplatform/atlauncher/ATLShareCode.h b/launcher/modplatform/atlauncher/ATLShareCode.h index 88c30c98e..69a493f85 100644 --- a/launcher/modplatform/atlauncher/ATLShareCode.h +++ b/launcher/modplatform/atlauncher/ATLShareCode.h @@ -18,9 +18,9 @@ #pragma once +#include #include #include -#include namespace ATLauncher { @@ -44,4 +44,4 @@ struct ShareCodeResponse { void loadShareCodeResponse(ShareCodeResponse& r, QJsonObject& obj); -} +} // namespace ATLauncher diff --git a/launcher/modplatform/flame/FlameCheckUpdate.h b/launcher/modplatform/flame/FlameCheckUpdate.h index 4a98d684f..e3465d7e2 100644 --- a/launcher/modplatform/flame/FlameCheckUpdate.h +++ b/launcher/modplatform/flame/FlameCheckUpdate.h @@ -8,7 +8,10 @@ class FlameCheckUpdate : public CheckUpdateTask { Q_OBJECT public: - FlameCheckUpdate(QList& mods, std::list& mcVersions, std::optional loaders, std::shared_ptr mods_folder) + FlameCheckUpdate(QList& mods, + std::list& mcVersions, + std::optional loaders, + std::shared_ptr mods_folder) : CheckUpdateTask(mods, mcVersions, loaders, mods_folder) {} diff --git a/launcher/modplatform/flame/FlamePackIndex.cpp b/launcher/modplatform/flame/FlamePackIndex.cpp index ad48b7b6a..21835a543 100644 --- a/launcher/modplatform/flame/FlamePackIndex.cpp +++ b/launcher/modplatform/flame/FlamePackIndex.cpp @@ -54,23 +54,22 @@ void Flame::loadIndexedInfo(IndexedPack& pack, QJsonObject& obj) auto links_obj = Json::ensureObject(obj, "links"); pack.extra.websiteUrl = Json::ensureString(links_obj, "websiteUrl"); - if(pack.extra.websiteUrl.endsWith('/')) + if (pack.extra.websiteUrl.endsWith('/')) pack.extra.websiteUrl.chop(1); pack.extra.issuesUrl = Json::ensureString(links_obj, "issuesUrl"); - if(pack.extra.issuesUrl.endsWith('/')) + if (pack.extra.issuesUrl.endsWith('/')) pack.extra.issuesUrl.chop(1); pack.extra.sourceUrl = Json::ensureString(links_obj, "sourceUrl"); - if(pack.extra.sourceUrl.endsWith('/')) + if (pack.extra.sourceUrl.endsWith('/')) pack.extra.sourceUrl.chop(1); pack.extra.wikiUrl = Json::ensureString(links_obj, "wikiUrl"); - if(pack.extra.wikiUrl.endsWith('/')) + if (pack.extra.wikiUrl.endsWith('/')) pack.extra.wikiUrl.chop(1); pack.extraInfoLoaded = true; - } void Flame::loadIndexedPackVersions(Flame::IndexedPack& pack, QJsonArray& arr) diff --git a/launcher/modplatform/flame/PackManifest.cpp b/launcher/modplatform/flame/PackManifest.cpp index ee4d07662..40a523d31 100644 --- a/launcher/modplatform/flame/PackManifest.cpp +++ b/launcher/modplatform/flame/PackManifest.cpp @@ -46,7 +46,7 @@ static void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest) Flame::File file; loadFileV1(file, obj); - pack.files.insert(file.fileId,file); + pack.files.insert(file.fileId, file); } pack.overrides = Json::ensureString(manifest, "overrides", "overrides"); @@ -69,7 +69,7 @@ void Flame::loadManifest(Flame::Manifest& m, const QString& filepath) loadManifestV1(m, obj); } -bool Flame::File::parseFromObject(const QJsonObject& obj, bool throw_on_blocked) +bool Flame::File::parseFromObject(const QJsonObject& obj, bool throw_on_blocked) { fileName = Json::requireString(obj, "fileName"); // This is a piece of a Flame project JSON pulled out into the file metadata (here) for convenience @@ -81,7 +81,7 @@ bool Flame::File::parseFromObject(const QJsonObject& obj, bool throw_on_blocked // get the hash hash = QString(); auto hashes = Json::ensureArray(obj, "hashes"); - for(QJsonValueRef item : hashes) { + for (QJsonValueRef item : hashes) { auto hobj = Json::requireObject(item); auto algo = Json::requireInteger(hobj, "algo"); auto value = Json::requireString(hobj, "value"); @@ -90,7 +90,6 @@ bool Flame::File::parseFromObject(const QJsonObject& obj, bool throw_on_blocked } } - // may throw, if the project is blocked QString rawUrl = Json::ensureString(obj, "downloadUrl"); url = QUrl(rawUrl, QUrl::TolerantMode); diff --git a/launcher/modplatform/flame/PackManifest.h b/launcher/modplatform/flame/PackManifest.h index 0b7461d84..a608263c6 100644 --- a/launcher/modplatform/flame/PackManifest.h +++ b/launcher/modplatform/flame/PackManifest.h @@ -41,10 +41,8 @@ #include #include -namespace Flame -{ -struct File -{ +namespace Flame { +struct File { // NOTE: throws JSONValidationError bool parseFromObject(const QJsonObject& object, bool throw_on_blocked = true); @@ -61,45 +59,33 @@ struct File QString fileName; QUrl url; QString targetFolder = QStringLiteral("mods"); - enum class Type - { - Unknown, - Folder, - Ctoc, - SingleFile, - Cmod2, - Modpack, - Mod - } type = Type::Mod; + enum class Type { Unknown, Folder, Ctoc, SingleFile, Cmod2, Modpack, Mod } type = Type::Mod; }; -struct Modloader -{ +struct Modloader { QString id; bool primary = false; }; -struct Minecraft -{ +struct Minecraft { QString version; QString libraries; QVector modLoaders; }; -struct Manifest -{ +struct Manifest { QString manifestType; int manifestVersion = 0; Flame::Minecraft minecraft; QString name; QString version; QString author; - //File id -> File - QMap files; + // File id -> File + QMap files; QString overrides; bool is_loaded = false; }; -void loadManifest(Flame::Manifest & m, const QString &filepath); -} +void loadManifest(Flame::Manifest& m, const QString& filepath); +} // namespace Flame diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp index a8a0fc2c2..c7db4906e 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp @@ -37,8 +37,8 @@ #include "PrivatePackManager.h" #include -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" namespace LegacyFTB { diff --git a/launcher/modplatform/legacy_ftb/PackHelpers.h b/launcher/modplatform/legacy_ftb/PackHelpers.h index 566210d05..4fb535530 100644 --- a/launcher/modplatform/legacy_ftb/PackHelpers.h +++ b/launcher/modplatform/legacy_ftb/PackHelpers.h @@ -1,22 +1,16 @@ #pragma once #include +#include #include #include -#include namespace LegacyFTB { -//Header for structs etc... -enum class PackType -{ - Public, - ThirdParty, - Private -}; +// Header for structs etc... +enum class PackType { Public, ThirdParty, Private }; -struct Modpack -{ +struct Modpack { QString name; QString description; QString author; @@ -26,9 +20,9 @@ struct Modpack QString mods; QString logo; - //Technical data + // Technical data QString dir; - QString file; //<- Url in the xml, but doesn't make much sense + QString file; //<- Url in the xml, but doesn't make much sense bool bugged = false; bool broken = false; @@ -39,7 +33,7 @@ struct Modpack typedef QList ModpackList; -} +} // namespace LegacyFTB -//We need it for the proxy model +// We need it for the proxy model Q_DECLARE_METATYPE(LegacyFTB::Modpack) diff --git a/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp b/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp index 1a81f0265..7ab5e9d6b 100644 --- a/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp +++ b/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp @@ -43,8 +43,7 @@ namespace LegacyFTB { void PrivatePackManager::load() { - try - { + try { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto foo = QString::fromUtf8(FS::read(m_filename)).split('\n', Qt::SkipEmptyParts); currentPacks = QSet(foo.begin(), foo.end()); @@ -53,9 +52,7 @@ void PrivatePackManager::load() #endif dirty = false; - } - catch(...) - { + } catch (...) { currentPacks = {}; qWarning() << "Failed to read third party FTB pack codes from" << m_filename; } @@ -63,20 +60,16 @@ void PrivatePackManager::load() void PrivatePackManager::save() const { - if(!dirty) - { + if (!dirty) { return; } - try - { + try { QStringList list = currentPacks.values(); FS::write(m_filename, list.join('\n').toUtf8()); dirty = false; - } - catch(...) - { + } catch (...) { qWarning() << "Failed to write third party FTB pack codes to" << m_filename; } } -} +} // namespace LegacyFTB diff --git a/launcher/modplatform/legacy_ftb/PrivatePackManager.h b/launcher/modplatform/legacy_ftb/PrivatePackManager.h index 0e8146462..be811f832 100644 --- a/launcher/modplatform/legacy_ftb/PrivatePackManager.h +++ b/launcher/modplatform/legacy_ftb/PrivatePackManager.h @@ -1,43 +1,33 @@ #pragma once +#include #include #include -#include namespace LegacyFTB { -class PrivatePackManager -{ -public: - ~PrivatePackManager() - { - save(); - } +class PrivatePackManager { + public: + ~PrivatePackManager() { save(); } void load(); void save() const; - bool empty() const - { - return currentPacks.empty(); - } - const QSet &getCurrentPackCodes() const - { - return currentPacks; - } - void add(const QString &code) + bool empty() const { return currentPacks.empty(); } + const QSet& getCurrentPackCodes() const { return currentPacks; } + void add(const QString& code) { currentPacks.insert(code); dirty = true; } - void remove(const QString &code) + void remove(const QString& code) { currentPacks.remove(code); dirty = true; } -private: + private: QSet currentPacks; QString m_filename = "private_packs.txt"; mutable bool dirty = false; }; -} +} // namespace LegacyFTB diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h index 88e1a6751..4583dd6ce 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h @@ -8,7 +8,10 @@ class ModrinthCheckUpdate : public CheckUpdateTask { Q_OBJECT public: - ModrinthCheckUpdate(QList& mods, std::list& mcVersions, std::optional loaders, std::shared_ptr mods_folder) + ModrinthCheckUpdate(QList& mods, + std::list& mcVersions, + std::optional loaders, + std::shared_ptr mods_folder) : CheckUpdateTask(mods, mcVersions, loaders, mods_folder) {} diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index bd0b828c6..16e375cde 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -133,10 +133,10 @@ bool ModrinthCreationTask::updateInstance() } } else { // We don't have an old index file, so we may duplicate stuff! - auto dialog = CustomMessageBox::selectable(m_parent, - tr("No index file."), - tr("We couldn't find a suitable index file for the older version. This may cause some of the files to be duplicated. Do you want to continue?"), - QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); + auto dialog = CustomMessageBox::selectable(m_parent, tr("No index file."), + tr("We couldn't find a suitable index file for the older version. This may cause some " + "of the files to be duplicated. Do you want to continue?"), + QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); if (dialog->exec() == QDialog::DialogCode::Rejected) { m_abort = true; @@ -144,7 +144,6 @@ bool ModrinthCreationTask::updateInstance() } } - setOverride(true, inst->id()); qDebug() << "Will override instance!"; @@ -233,7 +232,8 @@ bool ModrinthCreationTask::createInstance() auto file_path = FS::PathCombine(root_modpack_path, file.path); if (!root_modpack_url.isParentOf(QUrl::fromLocalFile(file_path))) { // This means we somehow got out of the root folder, so abort here to prevent exploits - setError(tr("One of the files has a path that leads to an arbitrary location (%1). This is a security risk and isn't allowed.").arg(file.path)); + setError(tr("One of the files has a path that leads to an arbitrary location (%1). This is a security risk and isn't allowed.") + .arg(file.path)); return false; } @@ -250,7 +250,8 @@ bool ModrinthCreationTask::createInstance() auto ndl = Net::Download::makeFile(file.downloads.dequeue(), file_path); ndl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash)); m_files_job->addNetAction(ndl); - if (auto shared = param.lock()) shared->succeeded(); + if (auto shared = param.lock()) + shared->succeeded(); }); } } @@ -263,9 +264,9 @@ bool ModrinthCreationTask::createInstance() setError(reason); }); connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); - connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { + connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); - setProgress(current, total); + setProgress(current, total); }); connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propagateStepProgress); @@ -293,7 +294,10 @@ bool ModrinthCreationTask::createInstance() return ended_well; } -bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector& files, bool set_internal_data, bool show_optional_dialog) +bool ModrinthCreationTask::parseManifest(const QString& index_path, + std::vector& files, + bool set_internal_data, + bool show_optional_dialog) { try { auto doc = Json::requireDocument(index_path); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h index 6de24fd40..07e417be5 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h @@ -20,10 +20,7 @@ class ModrinthCreationTask final : public InstanceCreationTask { QString id, QString version_id = {}, QString original_instance_id = {}) - : InstanceCreationTask() - , m_parent(parent) - , m_managed_id(std::move(id)) - , m_managed_version_id(std::move(version_id)) + : InstanceCreationTask(), m_parent(parent), m_managed_id(std::move(id)), m_managed_version_id(std::move(version_id)) { setStagingPath(staging_path); setParentSettings(global_settings); diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 4dca786f0..d4565191a 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -66,23 +66,23 @@ void loadIndexedInfo(Modpack& pack, QJsonObject& obj) pack.extra.projectUrl = QString("https://modrinth.com/modpack/%1").arg(Json::ensureString(obj, "slug")); pack.extra.issuesUrl = Json::ensureString(obj, "issues_url"); - if(pack.extra.issuesUrl.endsWith('/')) + if (pack.extra.issuesUrl.endsWith('/')) pack.extra.issuesUrl.chop(1); pack.extra.sourceUrl = Json::ensureString(obj, "source_url"); - if(pack.extra.sourceUrl.endsWith('/')) + if (pack.extra.sourceUrl.endsWith('/')) pack.extra.sourceUrl.chop(1); pack.extra.wikiUrl = Json::ensureString(obj, "wiki_url"); - if(pack.extra.wikiUrl.endsWith('/')) + if (pack.extra.wikiUrl.endsWith('/')) pack.extra.wikiUrl.chop(1); pack.extra.discordUrl = Json::ensureString(obj, "discord_url"); - if(pack.extra.discordUrl.endsWith('/')) + if (pack.extra.discordUrl.endsWith('/')) pack.extra.discordUrl.chop(1); auto donate_arr = Json::ensureArray(obj, "donation_urls"); - for(auto d : donate_arr){ + for (auto d : donate_arr) { auto d_obj = Json::requireObject(d); DonationData donate; @@ -107,7 +107,7 @@ void loadIndexedVersions(Modpack& pack, QJsonDocument& doc) auto obj = Json::requireObject(versionIter); auto file = loadIndexedVersion(obj); - if(!file.id.isEmpty()) // Heuristic to check if the returned value is valid + if (!file.id.isEmpty()) // Heuristic to check if the returned value is valid unsortedVersions.append(file); } auto orderSortPredicate = [](const ModpackVersion& a, const ModpackVersion& b) -> bool { @@ -122,7 +122,7 @@ void loadIndexedVersions(Modpack& pack, QJsonDocument& doc) pack.versionsLoaded = true; } -auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion +auto loadIndexedVersion(QJsonObject& obj) -> ModpackVersion { ModpackVersion file; @@ -132,12 +132,11 @@ auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion file.id = Json::requireString(obj, "id"); file.project_id = Json::requireString(obj, "project_id"); - + file.date = Json::requireString(obj, "date_published"); auto files = Json::requireArray(obj, "files"); - for (auto file_iter : files) { File indexed_file; auto parent = Json::requireObject(file_iter); @@ -146,21 +145,21 @@ auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion auto filename = Json::ensureString(parent, "filename"); // Checking suffix here is fine because it's the response from Modrinth, // so one would assume it will always be in English. - if(!filename.endsWith("mrpack") && !filename.endsWith("zip")) + if (!filename.endsWith("mrpack") && !filename.endsWith("zip")) continue; } auto url = Json::requireString(parent, "url"); file.download_url = url; - if(is_primary) + if (is_primary) break; } - if(file.download_url.isEmpty()) + if (file.download_url.isEmpty()) return {}; return file; -} +} } // namespace Modrinth diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.h b/launcher/modplatform/modrinth/ModrinthPackManifest.h index 2973dfba2..1af47cbc0 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.h +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.h @@ -74,7 +74,6 @@ struct ModpackExtra { QString discordUrl; QList donate; - }; struct ModpackVersion { @@ -97,10 +96,10 @@ struct Modpack { QString description; std::tuple author; QString iconName; - QUrl iconUrl; + QUrl iconUrl; - bool versionsLoaded = false; - bool extraInfoLoaded = false; + bool versionsLoaded = false; + bool extraInfoLoaded = false; ModpackExtra extra; QVector versions; @@ -113,7 +112,7 @@ auto loadIndexedVersion(QJsonObject&) -> ModpackVersion; auto validateDownloadUrl(QUrl) -> bool; -} +} // namespace Modrinth Q_DECLARE_METATYPE(Modrinth::Modpack) Q_DECLARE_METATYPE(Modrinth::ModpackVersion) diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 4b096eec7..6b13f74a9 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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 @@ -36,22 +36,22 @@ auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool shoul class V1 { public: struct Mod { - QString slug {}; - QString name {}; - QString filename {}; + QString slug{}; + QString name{}; + QString filename{}; // FIXME: make side an enum - QString side {"both"}; + QString side{ "both" }; // [download] - QString mode {}; - QUrl url {}; - QString hash_format {}; - QString hash {}; + QString mode{}; + QUrl url{}; + QString hash_format{}; + QString hash{}; // [update] - ModPlatform::ResourceProvider provider {}; - QVariant file_id {}; - QVariant project_id {}; + ModPlatform::ResourceProvider provider{}; + QVariant file_id{}; + QVariant project_id{}; public: // This is a totally heuristic, but should work for now. @@ -95,4 +95,4 @@ class V1 { static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod; }; -} // namespace Packwiz +} // namespace Packwiz diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp index ab91c4668..dd59e652c 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp @@ -17,21 +17,21 @@ #include +#include "FileSystem.h" #include "MMCZip.h" #include "TechnicPackProcessor.h" -#include "FileSystem.h" #include "Application.h" -Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion) +Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl& sourceUrl, const QString& minecraftVersion) { m_sourceUrl = sourceUrl; m_minecraftVersion = minecraftVersion; } -bool Technic::SingleZipPackInstallTask::abort() { - if(m_abortable) - { +bool Technic::SingleZipPackInstallTask::abort() +{ + if (m_abortable) { return m_filesNetJob->abort(); } return false; @@ -65,12 +65,12 @@ void Technic::SingleZipPackInstallTask::downloadSucceeded() // open the zip and find relevant files in it m_packZip.reset(new QuaZip(m_archivePath)); - if (!m_packZip->open(QuaZip::mdUnzip)) - { + if (!m_packZip->open(QuaZip::mdUnzip)) { emitFailed(tr("Unable to open supplied modpack zip file.")); return; } - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString(""), extractDir.absolutePath()); + m_extractFuture = + QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString(""), extractDir.absolutePath()); connect(&m_extractFutureWatcher, &QFutureWatcher::finished, this, &Technic::SingleZipPackInstallTask::extractFinished); connect(&m_extractFutureWatcher, &QFutureWatcher::canceled, this, &Technic::SingleZipPackInstallTask::extractAborted); m_extractFutureWatcher.setFuture(m_extractFuture); @@ -93,8 +93,7 @@ void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current, void Technic::SingleZipPackInstallTask::extractFinished() { m_packZip.reset(); - if (!m_extractFuture.result()) - { + if (!m_extractFuture.result()) { emitFailed(tr("Failed to extract modpack")); return; } @@ -102,30 +101,22 @@ void Technic::SingleZipPackInstallTask::extractFinished() qDebug() << "Fixing permissions for extracted pack files..."; QDirIterator it(extractDir, QDirIterator::Subdirectories); - while (it.hasNext()) - { + while (it.hasNext()) { auto filepath = it.next(); QFileInfo file(filepath); auto permissions = QFile::permissions(filepath); auto origPermissions = permissions; - if (file.isDir()) - { + if (file.isDir()) { // Folder +rwx for current user permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser; - } - else - { + } else { // File +rw for current user permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser; } - if (origPermissions != permissions) - { - if (!QFile::setPermissions(filepath, permissions)) - { + if (origPermissions != permissions) { + if (!QFile::setPermissions(filepath, permissions)) { logWarning(tr("Could not fix permissions for %1").arg(filepath)); - } - else - { + } else { qDebug() << "Fixed" << filepath; } } diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.h b/launcher/modplatform/technic/SingleZipPackInstallTask.h index 981ccf8a7..d49d008b9 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.h +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.h @@ -28,28 +28,26 @@ namespace Technic { -class SingleZipPackInstallTask : public InstanceTask -{ +class SingleZipPackInstallTask : public InstanceTask { Q_OBJECT -public: - SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion); + public: + SingleZipPackInstallTask(const QUrl& sourceUrl, const QString& minecraftVersion); bool canAbort() const override { return true; } bool abort() override; -protected: + protected: void executeTask() override; - -private slots: + private slots: void downloadSucceeded(); void downloadFailed(QString reason); void downloadProgressChanged(qint64 current, qint64 total); void extractFinished(); void extractAborted(); -private: + private: bool m_abortable = false; QUrl m_sourceUrl; @@ -61,4 +59,4 @@ private: QFutureWatcher> m_extractFutureWatcher; }; -} // namespace Technic +} // namespace Technic diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index cc1d261e2..1e2716e90 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -96,8 +96,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded() TechnicSolder::PackBuild build; try { TechnicSolder::loadPackBuild(build, obj); - } - catch (const JSONValidationError& e) { + } catch (const JSONValidationError& e) { emitFailed(tr("Could not understand pack manifest:\n") + e.cause()); m_filesNetJob.reset(); return; @@ -138,17 +137,14 @@ void Technic::SolderPackInstallTask::downloadSucceeded() setStatus(tr("Extracting modpack")); m_filesNetJob.reset(); - m_extractFuture = QtConcurrent::run([this]() - { + m_extractFuture = QtConcurrent::run([this]() { int i = 0; QString extractDir = FS::PathCombine(m_stagingPath, ".minecraft"); FS::ensureFolderPathExists(extractDir); - while (m_modCount > i) - { + while (m_modCount > i) { auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i)); - if (!MMCZip::extractDir(path, extractDir)) - { + if (!MMCZip::extractDir(path, extractDir)) { return false; } i++; @@ -181,8 +177,7 @@ void Technic::SolderPackInstallTask::downloadAborted() void Technic::SolderPackInstallTask::extractFinished() { - if (!m_extractFuture.result()) - { + if (!m_extractFuture.result()) { emitFailed(tr("Failed to extract modpack")); return; } @@ -190,30 +185,22 @@ void Technic::SolderPackInstallTask::extractFinished() qDebug() << "Fixing permissions for extracted pack files..."; QDirIterator it(extractDir, QDirIterator::Subdirectories); - while (it.hasNext()) - { + while (it.hasNext()) { auto filepath = it.next(); QFileInfo file(filepath); auto permissions = QFile::permissions(filepath); auto origPermissions = permissions; - if(file.isDir()) - { + if (file.isDir()) { // Folder +rwx for current user permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser; - } - else - { + } else { // File +rw for current user permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser; } - if(origPermissions != permissions) - { - if(!QFile::setPermissions(filepath, permissions)) - { + if (origPermissions != permissions) { + if (!QFile::setPermissions(filepath, permissions)) { logWarning(tr("Could not fix permissions for %1").arg(filepath)); - } - else - { + } else { qDebug() << "Fixed" << filepath; } } @@ -229,4 +216,3 @@ void Technic::SolderPackInstallTask::extractAborted() { emitFailed(tr("Instance import has been aborted.")); } - diff --git a/launcher/modplatform/technic/SolderPackManifest.cpp b/launcher/modplatform/technic/SolderPackManifest.cpp index e52a7ec07..3d9a2ea11 100644 --- a/launcher/modplatform/technic/SolderPackManifest.cpp +++ b/launcher/modplatform/technic/SolderPackManifest.cpp @@ -55,4 +55,4 @@ void loadPackBuild(PackBuild& v, QJsonObject& obj) } } -} +} // namespace TechnicSolder diff --git a/launcher/modplatform/technic/SolderPackManifest.h b/launcher/modplatform/technic/SolderPackManifest.h index 09f18df02..917b4eefa 100644 --- a/launcher/modplatform/technic/SolderPackManifest.h +++ b/launcher/modplatform/technic/SolderPackManifest.h @@ -18,9 +18,9 @@ #pragma once +#include #include #include -#include namespace TechnicSolder { @@ -46,4 +46,4 @@ struct PackBuild { void loadPackBuild(PackBuild& v, QJsonObject& obj); -} +} // namespace TechnicSolder diff --git a/launcher/modplatform/technic/TechnicPackProcessor.cpp b/launcher/modplatform/technic/TechnicPackProcessor.cpp index df713a725..778a6531e 100644 --- a/launcher/modplatform/technic/TechnicPackProcessor.cpp +++ b/launcher/modplatform/technic/TechnicPackProcessor.cpp @@ -26,7 +26,12 @@ #include -void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const QString &instName, const QString &instIcon, const QString &stagingPath, const QString &minecraftVersion, const bool isSolder) +void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, + const QString& instName, + const QString& instIcon, + const QString& stagingPath, + const QString& minecraftVersion, + const bool isSolder) { QString minecraftPath = FS::PathCombine(stagingPath, ".minecraft"); QString configPath = FS::PathCombine(stagingPath, "instance.cfg"); @@ -35,8 +40,7 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const instance.setName(instName); - if (instIcon != "default") - { + if (instIcon != "default") { instance.setIconKey(instIcon); } @@ -48,23 +52,18 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const QString modpackJar = FS::PathCombine(minecraftPath, "bin", "modpack.jar"); QString versionJson = FS::PathCombine(minecraftPath, "bin", "version.json"); QString fmlMinecraftVersion; - if (QFile::exists(modpackJar)) - { + if (QFile::exists(modpackJar)) { QuaZip zipFile(modpackJar); - if (!zipFile.open(QuaZip::mdUnzip)) - { + if (!zipFile.open(QuaZip::mdUnzip)) { emit failed(tr("Unable to open \"bin/modpack.jar\" file!")); return; } QuaZipDir zipFileRoot(&zipFile, "/"); - if (zipFileRoot.exists("/version.json")) - { - if (zipFileRoot.exists("/fmlversion.properties")) - { + if (zipFileRoot.exists("/version.json")) { + if (zipFileRoot.exists("/fmlversion.properties")) { zipFile.setCurrentFile("fmlversion.properties"); QuaZipFile file(&zipFile); - if (!file.open(QIODevice::ReadOnly)) - { + if (!file.open(QIODevice::ReadOnly)) { emit failed(tr("Unable to open \"fmlversion.properties\"!")); return; } @@ -77,30 +76,25 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const } zipFile.setCurrentFile("version.json", QuaZip::csSensitive); QuaZipFile file(&zipFile); - if (!file.open(QIODevice::ReadOnly)) - { + if (!file.open(QIODevice::ReadOnly)) { emit failed(tr("Unable to open \"version.json\"!")); return; } data = file.readAll(); file.close(); - } - else - { + } else { if (minecraftVersion.isEmpty()) emit failed(tr("Could not find \"version.json\" inside \"bin/modpack.jar\", but Minecraft version is unknown")); components->setComponentVersion("net.minecraft", minecraftVersion, true); - components->installJarMods({modpackJar}); + components->installJarMods({ modpackJar }); // Forge for 1.4.7 and for 1.5.2 require extra libraries. // Figure out the forge version and add it as a component // (the code still comes from the jar mod installed above) - if (zipFileRoot.exists("/forgeversion.properties")) - { + if (zipFileRoot.exists("/forgeversion.properties")) { zipFile.setCurrentFile("forgeversion.properties", QuaZip::csSensitive); QuaZipFile file(&zipFile); - if (!file.open(QIODevice::ReadOnly)) - { + if (!file.open(QIODevice::ReadOnly)) { // Really shouldn't happen, but error handling shall not be forgotten emit failed(tr("Unable to open \"forgeversion.properties\"")); return; @@ -115,8 +109,7 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const revision = iniFile["forge.revision.number"].toString(); build = iniFile["forge.build.number"].toString(); - if (major.isEmpty() || minor.isEmpty() || revision.isEmpty() || build.isEmpty()) - { + if (major.isEmpty() || minor.isEmpty() || revision.isEmpty() || build.isEmpty()) { emit failed(tr("Invalid \"forgeversion.properties\"!")); return; } @@ -128,84 +121,63 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const emit succeeded(); return; } - } - else if (QFile::exists(versionJson)) - { + } else if (QFile::exists(versionJson)) { QFile file(versionJson); - if (!file.open(QIODevice::ReadOnly)) - { + if (!file.open(QIODevice::ReadOnly)) { emit failed(tr("Unable to open \"version.json\"!")); return; } data = file.readAll(); file.close(); - } - else - { + } else { // This is the "Vanilla" modpack, excluded by the search code emit failed(tr("Unable to find a \"version.json\"!")); return; } - try - { + try { QJsonDocument doc = Json::requireDocument(data); QJsonObject root = Json::requireObject(doc, "version.json"); QString minecraftVersion = Json::ensureString(root, "inheritsFrom", QString(), ""); - if (minecraftVersion.isEmpty()) - { - if (fmlMinecraftVersion.isEmpty()) - { + if (minecraftVersion.isEmpty()) { + if (fmlMinecraftVersion.isEmpty()) { emit failed(tr("Could not understand \"version.json\":\ninheritsFrom is missing")); return; } minecraftVersion = fmlMinecraftVersion; } components->setComponentVersion("net.minecraft", minecraftVersion, true); - for (auto library: Json::ensureArray(root, "libraries", {})) - { - if (!library.isObject()) - { + for (auto library : Json::ensureArray(root, "libraries", {})) { + if (!library.isObject()) { continue; } auto libraryObject = Json::ensureObject(library, {}, ""); auto libraryName = Json::ensureString(libraryObject, "name", "", ""); - if ((libraryName.startsWith("net.minecraftforge:forge:") || libraryName.startsWith("net.minecraftforge:fmlloader:")) && libraryName.contains('-')) - { + if ((libraryName.startsWith("net.minecraftforge:forge:") || libraryName.startsWith("net.minecraftforge:fmlloader:")) && + libraryName.contains('-')) { QString libraryVersion = libraryName.section(':', 2); - if (!libraryVersion.startsWith("1.7.10-")) - { + if (!libraryVersion.startsWith("1.7.10-")) { components->setComponentVersion("net.minecraftforge", libraryName.section('-', 1)); - } - else - { + } else { // 1.7.10 versions sometimes look like 1.7.10-10.13.4.1614-1.7.10, this filters out the 10.13.4.1614 part components->setComponentVersion("net.minecraftforge", libraryName.section('-', 1, 1)); } - } - else - { + } else { // -> - static QMap loaderMap { - {"net.minecraftforge:minecraftforge:", "net.minecraftforge"}, - {"net.fabricmc:fabric-loader:", "net.fabricmc.fabric-loader"}, - {"org.quiltmc:quilt-loader:", "org.quiltmc.quilt-loader"} - }; - for (const auto& loader : loaderMap.keys()) - { - if (libraryName.startsWith(loader)) - { + static QMap loaderMap{ { "net.minecraftforge:minecraftforge:", "net.minecraftforge" }, + { "net.fabricmc:fabric-loader:", "net.fabricmc.fabric-loader" }, + { "org.quiltmc:quilt-loader:", "org.quiltmc.quilt-loader" } }; + for (const auto& loader : loaderMap.keys()) { + if (libraryName.startsWith(loader)) { components->setComponentVersion(loaderMap.value(loader), libraryName.section(':', 2)); break; } } } } - } - catch (const JSONValidationError &e) - { + } catch (const JSONValidationError& e) { emit failed(tr("Could not understand \"version.json\":\n") + e.cause()); return; } diff --git a/launcher/modplatform/technic/TechnicPackProcessor.h b/launcher/modplatform/technic/TechnicPackProcessor.h index 2ad803b34..466bce596 100644 --- a/launcher/modplatform/technic/TechnicPackProcessor.h +++ b/launcher/modplatform/technic/TechnicPackProcessor.h @@ -18,18 +18,21 @@ #include #include "settings/SettingsObject.h" -namespace Technic -{ - // not exporting it, only used in SingleZipPackInstallTask, InstanceImportTask and SolderPackInstallTask - class TechnicPackProcessor : public QObject - { - Q_OBJECT +namespace Technic { +// not exporting it, only used in SingleZipPackInstallTask, InstanceImportTask and SolderPackInstallTask +class TechnicPackProcessor : public QObject { + Q_OBJECT - signals: - void succeeded(); - void failed(QString reason); + signals: + void succeeded(); + void failed(QString reason); - public: - void run(SettingsObjectPtr globalSettings, const QString &instName, const QString &instIcon, const QString &stagingPath, const QString &minecraftVersion=QString(), const bool isSolder = false); - }; -} + public: + void run(SettingsObjectPtr globalSettings, + const QString& instName, + const QString& instIcon, + const QString& stagingPath, + const QString& minecraftVersion = QString(), + const bool isSolder = false); +}; +} // namespace Technic diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp index 4ea45c635..9ad49ded3 100644 --- a/launcher/net/Download.cpp +++ b/launcher/net/Download.cpp @@ -146,7 +146,7 @@ void Download::executeTask() m_reply.reset(rep); connect(rep, &QNetworkReply::downloadProgress, this, &Download::downloadProgress); connect(rep, &QNetworkReply::finished, this, &Download::downloadFinished); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &Download::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &Download::downloadError); @@ -174,8 +174,7 @@ void Download::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) if (elapsed_ms.count() > 0) { auto str_eta = bytesTotal > 0 ? Time::humanReadableDuration(remaing_time_s) : tr("unknown"); //: Download speed, in bytes per second (remaining download time in parenthesis) - dl_speed_str = - tr("%1 /s (%2)").arg(StringUtils::humanReadableFileSize(dl_speed_bps)).arg(str_eta); + dl_speed_str = tr("%1 /s (%2)").arg(StringUtils::humanReadableFileSize(dl_speed_bps)).arg(str_eta); } else { //: Download speed at 0 bytes per second dl_speed_str = tr("0 B/s"); diff --git a/launcher/net/HttpMetaCache.cpp b/launcher/net/HttpMetaCache.cpp index 689dbac96..7809d40fc 100644 --- a/launcher/net/HttpMetaCache.cpp +++ b/launcher/net/HttpMetaCache.cpp @@ -125,8 +125,9 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex // Get rid of old entries, to prevent cache problems auto current_time = QDateTime::currentSecsSinceEpoch(); - if (entry->isExpired(current_time - ( file_last_changed / 1000 ))) { - qCWarning(taskNetLogC) << "[HttpMetaCache]" << "Removing cache entry because of old age!"; + if (entry->isExpired(current_time - (file_last_changed / 1000))) { + qCWarning(taskNetLogC) << "[HttpMetaCache]" + << "Removing cache entry because of old age!"; selected_base.entry_list.remove(resource_path); return staleEntry(base, resource_path); } diff --git a/launcher/net/Logging.h b/launcher/net/Logging.h index b692e7075..4deed2b49 100644 --- a/launcher/net/Logging.h +++ b/launcher/net/Logging.h @@ -16,8 +16,8 @@ * along with this program. If not, see . * */ - -#pragma once + +#pragma once #include diff --git a/launcher/net/MetaCacheSink.cpp b/launcher/net/MetaCacheSink.cpp index e203bc06d..889588a11 100644 --- a/launcher/net/MetaCacheSink.cpp +++ b/launcher/net/MetaCacheSink.cpp @@ -46,32 +46,27 @@ namespace Net { /** Maximum time to hold a cache entry * = 1 week in seconds */ -#define MAX_TIME_TO_EXPIRE 1*7*24*60*60 +#define MAX_TIME_TO_EXPIRE 1 * 7 * 24 * 60 * 60 - -MetaCacheSink::MetaCacheSink(MetaEntryPtr entry, ChecksumValidator * md5sum, bool is_eternal) - :Net::FileSink(entry->getFullPath()), m_entry(entry), m_md5Node(md5sum), m_is_eternal(is_eternal) +MetaCacheSink::MetaCacheSink(MetaEntryPtr entry, ChecksumValidator* md5sum, bool is_eternal) + : Net::FileSink(entry->getFullPath()), m_entry(entry), m_md5Node(md5sum), m_is_eternal(is_eternal) { addValidator(md5sum); } Task::State MetaCacheSink::initCache(QNetworkRequest& request) { - if (!m_entry->isStale()) - { + if (!m_entry->isStale()) { return Task::State::Succeeded; } // check if file exists, if it does, use its information for the request QFile current(m_filename); - if(current.exists() && current.size() != 0) - { - if (m_entry->getRemoteChangedTimestamp().size()) - { + if (current.exists() && current.size() != 0) { + if (m_entry->getRemoteChangedTimestamp().size()) { request.setRawHeader(QString("If-Modified-Since").toLatin1(), m_entry->getRemoteChangedTimestamp().toLatin1()); } - if (m_entry->getETag().size()) - { + if (m_entry->getETag().size()) { request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1()); } } @@ -79,25 +74,23 @@ Task::State MetaCacheSink::initCache(QNetworkRequest& request) return Task::State::Running; } -Task::State MetaCacheSink::finalizeCache(QNetworkReply & reply) +Task::State MetaCacheSink::finalizeCache(QNetworkReply& reply) { QFileInfo output_file_info(m_filename); - if(wroteAnyData) - { + if (wroteAnyData) { m_entry->setMD5Sum(m_md5Node->hash().toHex().constData()); } m_entry->setETag(reply.rawHeader("ETag").constData()); - if (reply.hasRawHeader("Last-Modified")) - { + if (reply.hasRawHeader("Last-Modified")) { m_entry->setRemoteChangedTimestamp(reply.rawHeader("Last-Modified").constData()); } m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); - { // Cache lifetime + { // Cache lifetime if (m_is_eternal) { qCDebug(taskMetaCacheLogC) << "Adding eternal cache entry:" << m_entry->getFullPath(); m_entry->makeEternal(true); @@ -141,4 +134,4 @@ bool MetaCacheSink::hasLocalData() QFileInfo info(m_filename); return info.exists() && info.size() != 0; } -} +} // namespace Net diff --git a/launcher/net/NetAction.h b/launcher/net/NetAction.h index ab9322c26..54eddc72b 100644 --- a/launcher/net/NetAction.h +++ b/launcher/net/NetAction.h @@ -62,7 +62,8 @@ class NetAction : public Task { virtual void downloadFinished() = 0; virtual void downloadReadyRead() = 0; - virtual void sslErrors(const QList& errors) { + virtual void sslErrors(const QList& errors) + { int i = 1; for (auto error : errors) { qCritical() << "Network SSL Error #" << i << " : " << error.errorString(); @@ -70,7 +71,6 @@ class NetAction : public Task { qCritical() << "Certificate in question:\n" << cert.toText(); i++; } - }; public slots: diff --git a/launcher/net/NetJob.h b/launcher/net/NetJob.h index 764cec18b..cc63f4497 100644 --- a/launcher/net/NetJob.h +++ b/launcher/net/NetJob.h @@ -52,7 +52,9 @@ class NetJob : public ConcurrentTask { public: using Ptr = shared_qobject_ptr; - explicit NetJob(QString job_name, shared_qobject_ptr network) : ConcurrentTask(nullptr, job_name), m_network(network) {} + explicit NetJob(QString job_name, shared_qobject_ptr network) + : ConcurrentTask(nullptr, job_name), m_network(network) + {} ~NetJob() override = default; void startNext() override; diff --git a/launcher/net/NetUtils.h b/launcher/net/NetUtils.h index fa3bd8c03..afaf7b5f3 100644 --- a/launcher/net/NetUtils.h +++ b/launcher/net/NetUtils.h @@ -22,23 +22,22 @@ #include namespace Net { - inline bool isApplicationError(QNetworkReply::NetworkError x) { - // Mainly taken from https://github.com/qt/qtbase/blob/dev/src/network/access/qhttpthreaddelegate.cpp - static QSet errors = { - QNetworkReply::ProtocolInvalidOperationError, - QNetworkReply::AuthenticationRequiredError, - QNetworkReply::ContentAccessDenied, - QNetworkReply::ContentNotFoundError, - QNetworkReply::ContentOperationNotPermittedError, - QNetworkReply::ProxyAuthenticationRequiredError, - QNetworkReply::ContentConflictError, - QNetworkReply::ContentGoneError, - QNetworkReply::InternalServerError, - QNetworkReply::OperationNotImplementedError, - QNetworkReply::ServiceUnavailableError, - QNetworkReply::UnknownServerError, - QNetworkReply::UnknownContentError - }; - return errors.contains(x); - } +inline bool isApplicationError(QNetworkReply::NetworkError x) +{ + // Mainly taken from https://github.com/qt/qtbase/blob/dev/src/network/access/qhttpthreaddelegate.cpp + static QSet errors = { QNetworkReply::ProtocolInvalidOperationError, + QNetworkReply::AuthenticationRequiredError, + QNetworkReply::ContentAccessDenied, + QNetworkReply::ContentNotFoundError, + QNetworkReply::ContentOperationNotPermittedError, + QNetworkReply::ProxyAuthenticationRequiredError, + QNetworkReply::ContentConflictError, + QNetworkReply::ContentGoneError, + QNetworkReply::InternalServerError, + QNetworkReply::OperationNotImplementedError, + QNetworkReply::ServiceUnavailableError, + QNetworkReply::UnknownServerError, + QNetworkReply::UnknownContentError }; + return errors.contains(x); +} } // namespace Net diff --git a/launcher/net/PasteUpload.cpp b/launcher/net/PasteUpload.cpp index 595279a3a..c67d3b23c 100644 --- a/launcher/net/PasteUpload.cpp +++ b/launcher/net/PasteUpload.cpp @@ -36,26 +36,26 @@ */ #include "PasteUpload.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" #include -#include +#include #include #include #include -#include +#include #include #include "net/Logging.h" -std::array PasteUpload::PasteTypes = { - {{"0x0.st", "https://0x0.st", ""}, - {"hastebin", "https://hst.sh", "/documents"}, - {"paste.gg", "https://paste.gg", "/api/v1/pastes"}, - {"mclo.gs", "https://api.mclo.gs", "/1/log"}}}; +std::array PasteUpload::PasteTypes = { { { "0x0.st", "https://0x0.st", "" }, + { "hastebin", "https://hst.sh", "/documents" }, + { "paste.gg", "https://paste.gg", "/api/v1/pastes" }, + { "mclo.gs", "https://api.mclo.gs", "/1/log" } } }; -PasteUpload::PasteUpload(QWidget *window, QString text, QString baseUrl, PasteType pasteType) : m_window(window), m_baseUrl(baseUrl), m_pasteType(pasteType), m_text(text.toUtf8()) +PasteUpload::PasteUpload(QWidget* window, QString text, QString baseUrl, PasteType pasteType) + : m_window(window), m_baseUrl(baseUrl), m_pasteType(pasteType), m_text(text.toUtf8()) { if (m_baseUrl == "") m_baseUrl = PasteTypes.at(pasteType).defaultBase; @@ -67,68 +67,64 @@ PasteUpload::PasteUpload(QWidget *window, QString text, QString baseUrl, PasteTy m_uploadUrl = m_baseUrl + PasteTypes.at(pasteType).endpointPath; } -PasteUpload::~PasteUpload() -{ -} +PasteUpload::~PasteUpload() {} void PasteUpload::executeTask() { - QNetworkRequest request{QUrl(m_uploadUrl)}; - QNetworkReply *rep{}; + QNetworkRequest request{ QUrl(m_uploadUrl) }; + QNetworkReply* rep{}; request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); switch (m_pasteType) { - case NullPointer: { - QHttpMultiPart *multiPart = - new QHttpMultiPart{QHttpMultiPart::FormDataType}; + case NullPointer: { + QHttpMultiPart* multiPart = new QHttpMultiPart{ QHttpMultiPart::FormDataType }; - QHttpPart filePart; - filePart.setBody(m_text); - filePart.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); - filePart.setHeader(QNetworkRequest::ContentDispositionHeader, - "form-data; name=\"file\"; filename=\"log.txt\""); - multiPart->append(filePart); + QHttpPart filePart; + filePart.setBody(m_text); + filePart.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); + filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"file\"; filename=\"log.txt\""); + multiPart->append(filePart); - rep = APPLICATION->network()->post(request, multiPart); - multiPart->setParent(rep); + rep = APPLICATION->network()->post(request, multiPart); + multiPart->setParent(rep); - break; - } - case Hastebin: { - request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); - rep = APPLICATION->network()->post(request, m_text); - break; - } - case Mclogs: { - QUrlQuery postData; - postData.addQueryItem("content", m_text); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - rep = APPLICATION->network()->post(request, postData.toString().toUtf8()); - break; - } - case PasteGG: { - QJsonObject obj; - QJsonDocument doc; - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + break; + } + case Hastebin: { + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); + rep = APPLICATION->network()->post(request, m_text); + break; + } + case Mclogs: { + QUrlQuery postData; + postData.addQueryItem("content", m_text); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + rep = APPLICATION->network()->post(request, postData.toString().toUtf8()); + break; + } + case PasteGG: { + QJsonObject obj; + QJsonDocument doc; + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - obj.insert("expires", QDateTime::currentDateTimeUtc().addDays(100).toString(Qt::DateFormat::ISODate)); + obj.insert("expires", QDateTime::currentDateTimeUtc().addDays(100).toString(Qt::DateFormat::ISODate)); - QJsonArray files; - QJsonObject logFileInfo; - QJsonObject logFileContentInfo; - logFileContentInfo.insert("format", "text"); - logFileContentInfo.insert("value", QString::fromUtf8(m_text)); - logFileInfo.insert("name", "log.txt"); - logFileInfo.insert("content", logFileContentInfo); - files.append(logFileInfo); + QJsonArray files; + QJsonObject logFileInfo; + QJsonObject logFileContentInfo; + logFileContentInfo.insert("format", "text"); + logFileContentInfo.insert("value", QString::fromUtf8(m_text)); + logFileInfo.insert("name", "log.txt"); + logFileInfo.insert("content", logFileContentInfo); + files.append(logFileInfo); - obj.insert("files", files); + obj.insert("files", files); - doc.setObject(obj); - rep = APPLICATION->network()->post(request, doc.toJson()); - break; - } + doc.setObject(obj); + rep = APPLICATION->network()->post(request, doc.toJson()); + break; + } } connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress); @@ -140,7 +136,6 @@ void PasteUpload::executeTask() connect(rep, QOverload::of(&QNetworkReply::error), this, &PasteUpload::downloadError); #endif - m_reply = std::shared_ptr(rep); setStatus(tr("Uploading to %1").arg(m_uploadUrl)); @@ -158,97 +153,81 @@ void PasteUpload::downloadFinished() QByteArray data = m_reply->readAll(); int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (m_reply->error() != QNetworkReply::NetworkError::NoError) - { + if (m_reply->error() != QNetworkReply::NetworkError::NoError) { emitFailed(tr("Network error: %1").arg(m_reply->errorString())); m_reply.reset(); return; - } - else if (statusCode != 200 && statusCode != 201) - { + } else if (statusCode != 200 && statusCode != 201) { QString reasonPhrase = m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); emitFailed(tr("Error: %1 returned unexpected status code %2 %3").arg(m_uploadUrl).arg(statusCode).arg(reasonPhrase)); - qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned unexpected status code " << statusCode << " with body: " << data; + qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned unexpected status code " << statusCode + << " with body: " << data; m_reply.reset(); return; } - switch (m_pasteType) - { - case NullPointer: - m_pasteLink = QString::fromUtf8(data).trimmed(); - break; - case Hastebin: { - QJsonDocument jsonDoc{QJsonDocument::fromJson(data)}; - QJsonObject jsonObj{jsonDoc.object()}; - if (jsonObj.contains("key") && jsonObj["key"].isString()) - { - QString key = jsonDoc.object()["key"].toString(); - m_pasteLink = m_baseUrl + "/" + key; - } - else - { - emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl)); - qCCritical(taskUploadLogC) << getUid().toString() << getUid().toString() << m_uploadUrl << " returned malformed response body: " << data; - return; - } - break; - } - case Mclogs: { - QJsonDocument jsonDoc{QJsonDocument::fromJson(data)}; - QJsonObject jsonObj{jsonDoc.object()}; - if (jsonObj.contains("success") && jsonObj["success"].isBool()) - { - bool success = jsonObj["success"].toBool(); - if (success) - { - m_pasteLink = jsonObj["url"].toString(); - } - else - { - QString error = jsonObj["error"].toString(); - emitFailed(tr("Error: %1 returned an error: %2").arg(m_uploadUrl, error)); - qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned error: " << error; - qCCritical(taskUploadLogC) << getUid().toString() << "Response body: " << data; + switch (m_pasteType) { + case NullPointer: + m_pasteLink = QString::fromUtf8(data).trimmed(); + break; + case Hastebin: { + QJsonDocument jsonDoc{ QJsonDocument::fromJson(data) }; + QJsonObject jsonObj{ jsonDoc.object() }; + if (jsonObj.contains("key") && jsonObj["key"].isString()) { + QString key = jsonDoc.object()["key"].toString(); + m_pasteLink = m_baseUrl + "/" + key; + } else { + emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl)); + qCCritical(taskUploadLogC) << getUid().toString() << getUid().toString() << m_uploadUrl + << " returned malformed response body: " << data; return; } + break; } - else - { - emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl)); - qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned malformed response body: " << data; - return; - } - break; - } - case PasteGG: - QJsonDocument jsonDoc{QJsonDocument::fromJson(data)}; - QJsonObject jsonObj{jsonDoc.object()}; - if (jsonObj.contains("status") && jsonObj["status"].isString()) - { - QString status = jsonObj["status"].toString(); - if (status == "success") - { - m_pasteLink = m_baseUrl + "/p/anonymous/" + jsonObj["result"].toObject()["id"].toString(); - } - else - { - QString error = jsonObj["error"].toString(); - QString message = (jsonObj.contains("message") && jsonObj["message"].isString()) ? jsonObj["message"].toString() : "none"; - emitFailed(tr("Error: %1 returned an error code: %2\nError message: %3").arg(m_uploadUrl, error, message)); - qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned error: " << error; - qCCritical(taskUploadLogC) << getUid().toString() << "Error message: " << message; - qCCritical(taskUploadLogC) << getUid().toString() << "Response body: " << data; + case Mclogs: { + QJsonDocument jsonDoc{ QJsonDocument::fromJson(data) }; + QJsonObject jsonObj{ jsonDoc.object() }; + if (jsonObj.contains("success") && jsonObj["success"].isBool()) { + bool success = jsonObj["success"].toBool(); + if (success) { + m_pasteLink = jsonObj["url"].toString(); + } else { + QString error = jsonObj["error"].toString(); + emitFailed(tr("Error: %1 returned an error: %2").arg(m_uploadUrl, error)); + qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned error: " << error; + qCCritical(taskUploadLogC) << getUid().toString() << "Response body: " << data; + return; + } + } else { + emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl)); + qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned malformed response body: " << data; return; } + break; } - else - { - emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl)); - qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned malformed response body: " << data; - return; - } - break; + case PasteGG: + QJsonDocument jsonDoc{ QJsonDocument::fromJson(data) }; + QJsonObject jsonObj{ jsonDoc.object() }; + if (jsonObj.contains("status") && jsonObj["status"].isString()) { + QString status = jsonObj["status"].toString(); + if (status == "success") { + m_pasteLink = m_baseUrl + "/p/anonymous/" + jsonObj["result"].toObject()["id"].toString(); + } else { + QString error = jsonObj["error"].toString(); + QString message = + (jsonObj.contains("message") && jsonObj["message"].isString()) ? jsonObj["message"].toString() : "none"; + emitFailed(tr("Error: %1 returned an error code: %2\nError message: %3").arg(m_uploadUrl, error, message)); + qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned error: " << error; + qCCritical(taskUploadLogC) << getUid().toString() << "Error message: " << message; + qCCritical(taskUploadLogC) << getUid().toString() << "Response body: " << data; + return; + } + } else { + emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl)); + qCCritical(taskUploadLogC) << getUid().toString() << m_uploadUrl << " returned malformed response body: " << data; + return; + } + break; } emitSucceeded(); } diff --git a/launcher/net/PasteUpload.h b/launcher/net/PasteUpload.h index b72ab5b00..2ba6067c3 100644 --- a/launcher/net/PasteUpload.h +++ b/launcher/net/PasteUpload.h @@ -35,17 +35,16 @@ #pragma once -#include "tasks/Task.h" +#include #include #include -#include -#include #include +#include +#include "tasks/Task.h" -class PasteUpload : public Task -{ +class PasteUpload : public Task { Q_OBJECT -public: + public: enum PasteType : int { // 0x0.st NullPointer, @@ -68,26 +67,23 @@ public: static std::array PasteTypes; - PasteUpload(QWidget *window, QString text, QString url, PasteType pasteType); + PasteUpload(QWidget* window, QString text, QString url, PasteType pasteType); virtual ~PasteUpload(); - QString pasteLink() - { - return m_pasteLink; - } -protected: + QString pasteLink() { return m_pasteLink; } + + protected: virtual void executeTask(); -private: - QWidget *m_window; + private: + QWidget* m_window; QString m_pasteLink; QString m_baseUrl; QString m_uploadUrl; PasteType m_pasteType; QByteArray m_text; std::shared_ptr m_reply; -public -slots: + public slots: void downloadError(QNetworkReply::NetworkError); void downloadFinished(); }; diff --git a/launcher/net/Validator.h b/launcher/net/Validator.h index 6b3d46352..105a233c8 100644 --- a/launcher/net/Validator.h +++ b/launcher/net/Validator.h @@ -37,16 +37,15 @@ #include "net/NetAction.h" namespace Net { -class Validator -{ -public: /* con/des */ - Validator() {}; - virtual ~Validator() {}; +class Validator { + public: /* con/des */ + Validator(){}; + virtual ~Validator(){}; -public: /* methods */ - virtual bool init(QNetworkRequest & request) = 0; - virtual bool write(QByteArray & data) = 0; + public: /* methods */ + virtual bool init(QNetworkRequest& request) = 0; + virtual bool write(QByteArray& data) = 0; virtual bool abort() = 0; - virtual bool validate(QNetworkReply & reply) = 0; + virtual bool validate(QNetworkReply& reply) = 0; }; -} +} // namespace Net diff --git a/launcher/news/NewsChecker.cpp b/launcher/news/NewsChecker.cpp index 4f02bf5e0..11ba5311b 100644 --- a/launcher/news/NewsChecker.cpp +++ b/launcher/news/NewsChecker.cpp @@ -49,8 +49,7 @@ NewsChecker::NewsChecker(shared_qobject_ptr network, cons void NewsChecker::reloadNews() { // Start a netjob to download the RSS feed and call rssDownloadFinished() when it's done. - if (isLoadingNews()) - { + if (isLoadingNews()) { qDebug() << "Ignored request to reload news. Currently reloading already."; return; } @@ -113,7 +112,6 @@ void NewsChecker::rssDownloadFailed(QString reason) fail(tr("Failed to load news RSS feed:\n%1").arg(reason)); } - QList NewsChecker::getNewsEntries() const { return m_newsEntries; @@ -144,4 +142,3 @@ void NewsChecker::fail(const QString& errorMsg) m_newsNetJob.reset(); emit newsLoadingFailed(errorMsg); } - diff --git a/launcher/news/NewsChecker.h b/launcher/news/NewsChecker.h index 41babfff7..cdd621a20 100644 --- a/launcher/news/NewsChecker.h +++ b/launcher/news/NewsChecker.h @@ -15,18 +15,17 @@ #pragma once +#include #include #include -#include #include #include "NewsEntry.h" -class NewsChecker : public QObject -{ +class NewsChecker : public QObject { Q_OBJECT -public: + public: /*! * Constructs a news reader to read from the given RSS feed URL. */ @@ -57,7 +56,7 @@ public: */ void Q_SLOT reloadNews(); -signals: + signals: /*! * Signal fired after the news has finished loading. */ @@ -68,11 +67,11 @@ signals: */ void newsLoadingFailed(QString errorMsg); -protected slots: + protected slots: void rssDownloadFinished(); void rssDownloadFailed(QString reason); -protected: /* data */ + protected: /* data */ //! The URL for the RSS feed to fetch. QString m_feedUrl; @@ -95,11 +94,10 @@ protected: /* data */ shared_qobject_ptr m_network; -protected slots: + protected slots: /// Emits newsLoaded() and sets m_lastLoadError to empty string. void succeed(); /// Emits newsLoadingFailed() and sets m_lastLoadError to the given message. void fail(const QString& errorMsg); }; - diff --git a/launcher/news/NewsEntry.cpp b/launcher/news/NewsEntry.cpp index cfe07e864..cf6d3e46b 100644 --- a/launcher/news/NewsEntry.cpp +++ b/launcher/news/NewsEntry.cpp @@ -18,16 +18,14 @@ #include #include -NewsEntry::NewsEntry(QObject* parent) : - QObject(parent) +NewsEntry::NewsEntry(QObject* parent) : QObject(parent) { this->title = tr("Untitled"); this->content = tr("No content."); this->link = ""; } -NewsEntry::NewsEntry(const QString& title, const QString& content, const QString& link, QObject* parent) : - QObject(parent) +NewsEntry::NewsEntry(const QString& title, const QString& content, const QString& link, QObject* parent) : QObject(parent) { this->title = title; this->content = content; @@ -37,16 +35,13 @@ NewsEntry::NewsEntry(const QString& title, const QString& content, const QString /*! * Gets the text content of the given child element as a QVariant. */ -inline QString childValue(const QDomElement& element, const QString& childName, QString defaultVal="") +inline QString childValue(const QDomElement& element, const QString& childName, QString defaultVal = "") { QDomNodeList nodes = element.elementsByTagName(childName); - if (nodes.count() > 0) - { + if (nodes.count() > 0) { QDomElement element = nodes.at(0).toElement(); return element.text(); - } - else - { + } else { return defaultVal; } } @@ -62,4 +57,3 @@ bool NewsEntry::fromXmlElement(const QDomElement& element, NewsEntry* entry, QSt entry->link = link; return true; } - diff --git a/launcher/news/NewsEntry.h b/launcher/news/NewsEntry.h index 1fe95623d..2d409a9fb 100644 --- a/launcher/news/NewsEntry.h +++ b/launcher/news/NewsEntry.h @@ -15,33 +15,31 @@ #pragma once +#include #include #include -#include #include -class NewsEntry : public QObject -{ +class NewsEntry : public QObject { Q_OBJECT -public: + public: /*! * Constructs an empty news entry. */ - explicit NewsEntry(QObject* parent=0); + explicit NewsEntry(QObject* parent = 0); /*! * Constructs a new news entry. * Note that content may contain HTML. */ - NewsEntry(const QString& title, const QString& content, const QString& link, QObject* parent=0); + NewsEntry(const QString& title, const QString& content, const QString& link, QObject* parent = 0); /*! * Attempts to load information from the given XML element into the given news entry pointer. * If this fails, the function will return false and store an error message in the errorMsg pointer. */ - static bool fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg=0); - + static bool fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg = 0); //! The post title. QString title; @@ -54,4 +52,3 @@ public: }; typedef std::shared_ptr NewsEntryPtr; - diff --git a/launcher/pathmatcher/FSTreeMatcher.h b/launcher/pathmatcher/FSTreeMatcher.h index b84af2945..52f1404df 100644 --- a/launcher/pathmatcher/FSTreeMatcher.h +++ b/launcher/pathmatcher/FSTreeMatcher.h @@ -1,21 +1,15 @@ #pragma once -#include "IPathMatcher.h" #include #include +#include "IPathMatcher.h" -class FSTreeMatcher : public IPathMatcher -{ -public: - virtual ~FSTreeMatcher() {}; - FSTreeMatcher(SeparatorPrefixTree<'/'> & tree) : m_fsTree(tree) - { - } +class FSTreeMatcher : public IPathMatcher { + public: + virtual ~FSTreeMatcher(){}; + FSTreeMatcher(SeparatorPrefixTree<'/'>& tree) : m_fsTree(tree) {} - bool matches(const QString &string) const override - { - return m_fsTree.covers(string); - } + bool matches(const QString& string) const override { return m_fsTree.covers(string); } - SeparatorPrefixTree<'/'> & m_fsTree; + SeparatorPrefixTree<'/'>& m_fsTree; }; diff --git a/launcher/pathmatcher/IPathMatcher.h b/launcher/pathmatcher/IPathMatcher.h index 192782d7c..8121de5cb 100644 --- a/launcher/pathmatcher/IPathMatcher.h +++ b/launcher/pathmatcher/IPathMatcher.h @@ -1,13 +1,12 @@ #pragma once -#include #include +#include -class IPathMatcher -{ -public: +class IPathMatcher { + public: typedef std::shared_ptr Ptr; -public: + public: virtual ~IPathMatcher(){}; - virtual bool matches(const QString &string) const = 0; + virtual bool matches(const QString& string) const = 0; }; diff --git a/launcher/pathmatcher/MultiMatcher.h b/launcher/pathmatcher/MultiMatcher.h index 8bc1b6eed..101595809 100644 --- a/launcher/pathmatcher/MultiMatcher.h +++ b/launcher/pathmatcher/MultiMatcher.h @@ -1,26 +1,21 @@ -#include "IPathMatcher.h" #include #include +#include "IPathMatcher.h" -class MultiMatcher : public IPathMatcher -{ -public: - virtual ~MultiMatcher() {}; - MultiMatcher() - { - } - MultiMatcher &add(Ptr add) +class MultiMatcher : public IPathMatcher { + public: + virtual ~MultiMatcher(){}; + MultiMatcher() {} + MultiMatcher& add(Ptr add) { m_matchers.append(add); return *this; } - virtual bool matches(const QString &string) const override + virtual bool matches(const QString& string) const override { - for(auto iter: m_matchers) - { - if(iter->matches(string)) - { + for (auto iter : m_matchers) { + if (iter->matches(string)) { return true; } } diff --git a/launcher/pathmatcher/RegexpMatcher.h b/launcher/pathmatcher/RegexpMatcher.h index 825d488c3..fe4aee6a7 100644 --- a/launcher/pathmatcher/RegexpMatcher.h +++ b/launcher/pathmatcher/RegexpMatcher.h @@ -1,36 +1,30 @@ -#include "IPathMatcher.h" #include +#include "IPathMatcher.h" -class RegexpMatcher : public IPathMatcher -{ -public: - virtual ~RegexpMatcher() {}; - RegexpMatcher(const QString ®exp) +class RegexpMatcher : public IPathMatcher { + public: + virtual ~RegexpMatcher(){}; + RegexpMatcher(const QString& regexp) { m_regexp.setPattern(regexp); m_onlyFilenamePart = !regexp.contains('/'); } - RegexpMatcher &caseSensitive(bool cs = true) + RegexpMatcher& caseSensitive(bool cs = true) { - if(cs) - { + if (cs) { m_regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption); - } - else - { + } else { m_regexp.setPatternOptions(QRegularExpression::NoPatternOption); } return *this; } - virtual bool matches(const QString &string) const override + virtual bool matches(const QString& string) const override { - if(m_onlyFilenamePart) - { + if (m_onlyFilenamePart) { auto slash = string.lastIndexOf('/'); - if(slash != -1) - { + if (slash != -1) { auto part = string.mid(slash + 1); return m_regexp.match(part).hasMatch(); } diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp index ab425f1a0..68eb02ac4 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -36,15 +36,15 @@ #include "ImgurAlbumCreation.h" -#include +#include #include #include -#include +#include #include -#include +#include -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" ImgurAlbumCreation::ImgurAlbumCreation(QList screenshots) : NetAction(), m_screenshots(screenshots) { @@ -62,19 +62,18 @@ void ImgurAlbumCreation::executeTask() request.setRawHeader("Accept", "application/json"); QStringList hashes; - for (auto shot : m_screenshots) - { + for (auto shot : m_screenshots) { hashes.append(shot->m_imgurDeleteHash); } const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; - QNetworkReply *rep = APPLICATION->network()->post(request, data); + QNetworkReply* rep = APPLICATION->network()->post(request, data); m_reply.reset(rep); connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress); connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &ImgurAlbumCreation::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &ImgurAlbumCreation::downloadError); @@ -90,21 +89,18 @@ void ImgurAlbumCreation::downloadError(QNetworkReply::NetworkError error) void ImgurAlbumCreation::downloadFinished() { - if (m_state != State::Failed) - { + if (m_state != State::Failed) { QByteArray data = m_reply->readAll(); m_reply.reset(); QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if (jsonError.error != QJsonParseError::NoError) - { + if (jsonError.error != QJsonParseError::NoError) { qDebug() << jsonError.errorString(); emitFailed(); return; } auto object = doc.object(); - if (!object.value("success").toBool()) - { + if (!object.value("success").toBool()) { qDebug() << doc.toJson(); emitFailed(); return; @@ -114,9 +110,7 @@ void ImgurAlbumCreation::downloadFinished() m_state = State::Succeeded; emit succeeded(); return; - } - else - { + } else { qDebug() << m_reply->readAll(); m_reply.reset(); emitFailed(); diff --git a/launcher/screenshots/ImgurAlbumCreation.h b/launcher/screenshots/ImgurAlbumCreation.h index 0228b6e4a..9efaed4fe 100644 --- a/launcher/screenshots/ImgurAlbumCreation.h +++ b/launcher/screenshots/ImgurAlbumCreation.h @@ -35,40 +35,31 @@ #pragma once -#include "net/NetAction.h" #include "Screenshot.h" +#include "net/NetAction.h" typedef shared_qobject_ptr ImgurAlbumCreationPtr; -class ImgurAlbumCreation : public NetAction -{ -public: +class ImgurAlbumCreation : public NetAction { + public: explicit ImgurAlbumCreation(QList screenshots); static ImgurAlbumCreationPtr make(QList screenshots) { return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots)); } - QString deleteHash() const - { - return m_deleteHash; - } - QString id() const - { - return m_id; - } + QString deleteHash() const { return m_deleteHash; } + QString id() const { return m_id; } -protected -slots: + protected slots: void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; void downloadError(QNetworkReply::NetworkError error) override; void downloadFinished() override; void downloadReadyRead() override {} -public -slots: + public slots: void executeTask() override; -private: + private: QList m_screenshots; QString m_deleteHash; diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp index a50f9afae..81aa1f749 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -35,17 +35,17 @@ */ #include "ImgurUpload.h" -#include "BuildConfig.h" #include "Application.h" +#include "BuildConfig.h" -#include +#include +#include #include +#include #include #include -#include -#include +#include #include -#include ImgurUpload::ImgurUpload(ScreenShot::Ptr shot) : NetAction(), m_shot(shot) { @@ -63,13 +63,12 @@ void ImgurUpload::executeTask() request.setRawHeader("Accept", "application/json"); QFile f(m_shot->m_file.absoluteFilePath()); - if (!f.open(QFile::ReadOnly)) - { + if (!f.open(QFile::ReadOnly)) { emitFailed(); return; } - QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart filePart; filePart.setBody(f.readAll().toBase64()); filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png"); @@ -84,12 +83,12 @@ void ImgurUpload::executeTask() namePart.setBody(m_shot->m_file.baseName().toUtf8()); multipart->append(namePart); - QNetworkReply *rep = m_network->post(request, multipart); + QNetworkReply* rep = m_network->post(request, multipart); m_reply.reset(rep); connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress); connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 connect(rep, &QNetworkReply::errorOccurred, this, &ImgurUpload::downloadError); #else connect(rep, QOverload::of(&QNetworkReply::error), this, &ImgurUpload::downloadError); @@ -100,8 +99,7 @@ void ImgurUpload::executeTask() void ImgurUpload::downloadError(QNetworkReply::NetworkError error) { qCritical() << "ImgurUpload failed with error" << m_reply->errorString() << "Server reply:\n" << m_reply->readAll(); - if(finished) - { + if (finished) { qCritical() << "Double finished ImgurUpload!"; return; } @@ -113,8 +111,7 @@ void ImgurUpload::downloadError(QNetworkReply::NetworkError error) void ImgurUpload::downloadFinished() { - if(finished) - { + if (finished) { qCritical() << "Double finished ImgurUpload!"; return; } @@ -122,8 +119,7 @@ void ImgurUpload::downloadFinished() m_reply.reset(); QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if (jsonError.error != QJsonParseError::NoError) - { + if (jsonError.error != QJsonParseError::NoError) { qDebug() << "imgur server did not reply with JSON" << jsonError.errorString(); finished = true; m_reply.reset(); @@ -131,8 +127,7 @@ void ImgurUpload::downloadFinished() return; } auto object = doc.object(); - if (!object.value("success").toBool()) - { + if (!object.value("success").toBool()) { qDebug() << "Screenshot upload not successful:" << doc.toJson(); finished = true; m_reply.reset(); diff --git a/launcher/screenshots/ImgurUpload.h b/launcher/screenshots/ImgurUpload.h index 404dc8765..084349b22 100644 --- a/launcher/screenshots/ImgurUpload.h +++ b/launcher/screenshots/ImgurUpload.h @@ -35,30 +35,26 @@ #pragma once -#include "net/NetAction.h" #include "Screenshot.h" +#include "net/NetAction.h" class ImgurUpload : public NetAction { -public: + public: using Ptr = shared_qobject_ptr; explicit ImgurUpload(ScreenShot::Ptr shot); - static Ptr make(ScreenShot::Ptr shot) { - return Ptr(new ImgurUpload(shot)); - } + static Ptr make(ScreenShot::Ptr shot) { return Ptr(new ImgurUpload(shot)); } -protected -slots: + protected slots: void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; void downloadError(QNetworkReply::NetworkError error) override; void downloadFinished() override; void downloadReadyRead() override {} -public -slots: + public slots: void executeTask() override; -private: + private: ScreenShot::Ptr m_shot; bool finished = true; }; diff --git a/launcher/screenshots/Screenshot.h b/launcher/screenshots/Screenshot.h index ca45aabff..767f39061 100644 --- a/launcher/screenshots/Screenshot.h +++ b/launcher/screenshots/Screenshot.h @@ -1,16 +1,14 @@ #pragma once #include -#include #include +#include #include struct ScreenShot { using Ptr = std::shared_ptr; - ScreenShot(QFileInfo file) { - m_file = file; - } + ScreenShot(QFileInfo file) { m_file = file; } QFileInfo m_file; QString m_url; QString m_imgurId; diff --git a/launcher/settings/INIFile.h b/launcher/settings/INIFile.h index 4ee543cf1..c15578f6d 100644 --- a/launcher/settings/INIFile.h +++ b/launcher/settings/INIFile.h @@ -36,17 +36,16 @@ #pragma once +#include #include #include -#include -#include #include +#include // Sectionless INI parser (for instance config files) -class INIFile : public QMap -{ -public: +class INIFile : public QMap { + public: explicit INIFile(); bool loadFile(QString fileName); diff --git a/launcher/settings/INISettingsObject.cpp b/launcher/settings/INISettingsObject.cpp index da962ee97..519b8193e 100644 --- a/launcher/settings/INISettingsObject.cpp +++ b/launcher/settings/INISettingsObject.cpp @@ -19,8 +19,7 @@ #include #include -INISettingsObject::INISettingsObject(QStringList paths, QObject *parent) - : SettingsObject(parent) +INISettingsObject::INISettingsObject(QStringList paths, QObject* parent) : SettingsObject(parent) { auto first_path = paths.constFirst(); for (auto path : paths) { @@ -39,14 +38,13 @@ INISettingsObject::INISettingsObject(QStringList paths, QObject *parent) m_ini.loadFile(first_path); } -INISettingsObject::INISettingsObject(QString path, QObject* parent) - : SettingsObject(parent) +INISettingsObject::INISettingsObject(QString path, QObject* parent) : SettingsObject(parent) { m_filePath = path; m_ini.loadFile(path); } -void INISettingsObject::setFilePath(const QString &filePath) +void INISettingsObject::setFilePath(const QString& filePath) { m_filePath = filePath; } @@ -64,28 +62,24 @@ void INISettingsObject::suspendSave() void INISettingsObject::resumeSave() { m_suspendSave = false; - if(m_doSave) - { + if (m_doSave) { m_ini.saveFile(m_filePath); } } -void INISettingsObject::changeSetting(const Setting &setting, QVariant value) +void INISettingsObject::changeSetting(const Setting& setting, QVariant value) { - if (contains(setting.id())) - { + if (contains(setting.id())) { // valid value -> set the main config, remove all the sysnonyms - if (value.isValid()) - { + if (value.isValid()) { auto list = setting.configKeys(); m_ini.set(list.takeFirst(), value); - for(auto iter: list) + for (auto iter : list) m_ini.remove(iter); } // invalid -> remove all (just like resetSetting) - else - { - for(auto iter: setting.configKeys()) + else { + for (auto iter : setting.configKeys()) m_ini.remove(iter); } doSave(); @@ -94,35 +88,29 @@ void INISettingsObject::changeSetting(const Setting &setting, QVariant value) void INISettingsObject::doSave() { - if(m_suspendSave) - { + if (m_suspendSave) { m_doSave = true; - } - else - { + } else { m_ini.saveFile(m_filePath); } } -void INISettingsObject::resetSetting(const Setting &setting) +void INISettingsObject::resetSetting(const Setting& setting) { // if we have the setting, remove all the synonyms. ALL OF THEM - if (contains(setting.id())) - { - for(auto iter: setting.configKeys()) + if (contains(setting.id())) { + for (auto iter : setting.configKeys()) m_ini.remove(iter); doSave(); } } -QVariant INISettingsObject::retrieveValue(const Setting &setting) +QVariant INISettingsObject::retrieveValue(const Setting& setting) { // if we have the setting, return value of the first matching synonym - if (contains(setting.id())) - { - for(auto iter: setting.configKeys()) - { - if(m_ini.contains(iter)) + if (contains(setting.id())) { + for (auto iter : setting.configKeys()) { + if (m_ini.contains(iter)) return m_ini[iter]; } } diff --git a/launcher/settings/INISettingsObject.h b/launcher/settings/INISettingsObject.h index d2f448a9c..4cc808580 100644 --- a/launcher/settings/INISettingsObject.h +++ b/launcher/settings/INISettingsObject.h @@ -24,44 +24,40 @@ /*! * \brief A settings object that stores its settings in an INIFile. */ -class INISettingsObject : public SettingsObject -{ +class INISettingsObject : public SettingsObject { Q_OBJECT -public: + public: /** 'paths' is a list of INI files to try, in order, for fallback support. */ explicit INISettingsObject(QStringList paths, QObject* parent = nullptr); - explicit INISettingsObject(QString path, QObject* parent = nullptr); + explicit INISettingsObject(QString path, QObject* parent = nullptr); /*! * \brief Gets the path to the INI file. * \return The path to the INI file. */ - virtual QString filePath() const - { - return m_filePath; - } + virtual QString filePath() const { return m_filePath; } /*! * \brief Sets the path to the INI file and reloads it. * \param filePath The INI file's new path. */ - virtual void setFilePath(const QString &filePath); + virtual void setFilePath(const QString& filePath); bool reload() override; void suspendSave() override; void resumeSave() override; -protected slots: - virtual void changeSetting(const Setting &setting, QVariant value) override; - virtual void resetSetting(const Setting &setting) override; + protected slots: + virtual void changeSetting(const Setting& setting, QVariant value) override; + virtual void resetSetting(const Setting& setting) override; -protected: - virtual QVariant retrieveValue(const Setting &setting) override; + protected: + virtual QVariant retrieveValue(const Setting& setting) override; void doSave(); -protected: + protected: INIFile m_ini; QString m_filePath; }; diff --git a/launcher/settings/OverrideSetting.cpp b/launcher/settings/OverrideSetting.cpp index 4396a3817..fee65b8db 100644 --- a/launcher/settings/OverrideSetting.cpp +++ b/launcher/settings/OverrideSetting.cpp @@ -15,8 +15,7 @@ #include "OverrideSetting.h" -OverrideSetting::OverrideSetting(std::shared_ptr other, std::shared_ptr gate) - : Setting(other->configKeys(), QVariant()) +OverrideSetting::OverrideSetting(std::shared_ptr other, std::shared_ptr gate) : Setting(other->configKeys(), QVariant()) { Q_ASSERT(other); Q_ASSERT(gate); @@ -36,8 +35,7 @@ QVariant OverrideSetting::defValue() const QVariant OverrideSetting::get() const { - if(isOverriding()) - { + if (isOverriding()) { return Setting::get(); } return m_other->get(); diff --git a/launcher/settings/OverrideSetting.h b/launcher/settings/OverrideSetting.h index 9f0c98b52..faa3e7948 100644 --- a/launcher/settings/OverrideSetting.h +++ b/launcher/settings/OverrideSetting.h @@ -26,21 +26,20 @@ * The other setting can be (and usually is) a part of a different SettingsObject * than this one. */ -class OverrideSetting : public Setting -{ +class OverrideSetting : public Setting { Q_OBJECT -public: + public: explicit OverrideSetting(std::shared_ptr overriden, std::shared_ptr gate); virtual QVariant defValue() const; virtual QVariant get() const; - virtual void set (QVariant value); + virtual void set(QVariant value); virtual void reset(); -private: + private: bool isOverriding() const; -protected: + protected: std::shared_ptr m_other; std::shared_ptr m_gate; }; diff --git a/launcher/settings/PassthroughSetting.cpp b/launcher/settings/PassthroughSetting.cpp index 8f93b2519..86bb861e4 100644 --- a/launcher/settings/PassthroughSetting.cpp +++ b/launcher/settings/PassthroughSetting.cpp @@ -25,8 +25,7 @@ PassthroughSetting::PassthroughSetting(std::shared_ptr other, std::shar bool PassthroughSetting::isOverriding() const { - if(!m_gate) - { + if (!m_gate) { return false; } return m_gate->get().toBool(); @@ -34,8 +33,7 @@ bool PassthroughSetting::isOverriding() const QVariant PassthroughSetting::defValue() const { - if(isOverriding()) - { + if (isOverriding()) { return m_other->get(); } return m_other->defValue(); @@ -43,8 +41,7 @@ QVariant PassthroughSetting::defValue() const QVariant PassthroughSetting::get() const { - if(isOverriding()) - { + if (isOverriding()) { return Setting::get(); } return m_other->get(); @@ -52,8 +49,7 @@ QVariant PassthroughSetting::get() const void PassthroughSetting::reset() { - if(isOverriding()) - { + if (isOverriding()) { Setting::reset(); } m_other->reset(); @@ -61,8 +57,7 @@ void PassthroughSetting::reset() void PassthroughSetting::set(QVariant value) { - if(isOverriding()) - { + if (isOverriding()) { Setting::set(value); } m_other->set(value); diff --git a/launcher/settings/PassthroughSetting.h b/launcher/settings/PassthroughSetting.h index 22008f83d..c776ca951 100644 --- a/launcher/settings/PassthroughSetting.h +++ b/launcher/settings/PassthroughSetting.h @@ -25,21 +25,20 @@ * If 'gate' evaluates to true, the override stores and returns data * If 'gate' evaluates to false, the original does, */ -class PassthroughSetting : public Setting -{ +class PassthroughSetting : public Setting { Q_OBJECT -public: + public: explicit PassthroughSetting(std::shared_ptr overriden, std::shared_ptr gate); virtual QVariant defValue() const; virtual QVariant get() const; - virtual void set (QVariant value); + virtual void set(QVariant value); virtual void reset(); -private: + private: bool isOverriding() const; -protected: + protected: std::shared_ptr m_other; std::shared_ptr m_gate; }; diff --git a/launcher/settings/Setting.cpp b/launcher/settings/Setting.cpp index cfe5a7f92..1e861e36b 100644 --- a/launcher/settings/Setting.cpp +++ b/launcher/settings/Setting.cpp @@ -16,20 +16,14 @@ #include "Setting.h" #include "settings/SettingsObject.h" -Setting::Setting(QStringList synonyms, QVariant defVal) - : QObject(), m_synonyms(synonyms), m_defVal(defVal) -{ -} +Setting::Setting(QStringList synonyms, QVariant defVal) : QObject(), m_synonyms(synonyms), m_defVal(defVal) {} QVariant Setting::get() const { - SettingsObject *sbase = m_storage; - if (!sbase) - { + SettingsObject* sbase = m_storage; + if (!sbase) { return defValue(); - } - else - { + } else { QVariant test = sbase->retrieveValue(*this); if (!test.isValid()) return defValue(); diff --git a/launcher/settings/Setting.h b/launcher/settings/Setting.h index 86007c13d..44b350379 100644 --- a/launcher/settings/Setting.h +++ b/launcher/settings/Setting.h @@ -16,8 +16,8 @@ #pragma once #include -#include #include +#include #include class SettingsObject; @@ -25,10 +25,9 @@ class SettingsObject; /*! * */ -class Setting : public QObject -{ +class Setting : public QObject { Q_OBJECT -public: + public: /** * Construct a Setting * @@ -47,10 +46,7 @@ public: * undefined behavior. * \return The ID of the setting. */ - virtual QString id() const - { - return m_synonyms.first(); - } + virtual QString id() const { return m_synonyms.first(); } /*! * \brief Gets this setting's config file key. @@ -58,10 +54,7 @@ public: * the same as the setting's ID, but it can be different. * \return The setting's config file key. */ - virtual QStringList configKeys() const - { - return m_synonyms; - } + virtual QStringList configKeys() const { return m_synonyms; } /*! * \brief Gets this setting's value as a QVariant. @@ -78,22 +71,21 @@ public: */ virtual QVariant defValue() const; -signals: + signals: /*! * \brief Signal emitted when this Setting object's value changes. * \param setting A reference to the Setting that changed. * \param value This Setting object's new value. */ - void SettingChanged(const Setting &setting, QVariant value); + void SettingChanged(const Setting& setting, QVariant value); /*! * \brief Signal emitted when this Setting object's value resets to default. * \param setting A reference to the Setting that changed. */ - void settingReset(const Setting &setting); + void settingReset(const Setting& setting); -public -slots: + public slots: /*! * \brief Changes the setting's value. * This is done by emitting the SettingChanged() signal which will then be @@ -109,10 +101,9 @@ slots: */ virtual void reset(); -protected: + protected: friend class SettingsObject; - SettingsObject * m_storage; + SettingsObject* m_storage; QStringList m_synonyms; QVariant m_defVal; }; - diff --git a/launcher/settings/SettingsObject.cpp b/launcher/settings/SettingsObject.cpp index 634acd341..1e5dce251 100644 --- a/launcher/settings/SettingsObject.cpp +++ b/launcher/settings/SettingsObject.cpp @@ -14,30 +14,25 @@ */ #include "settings/SettingsObject.h" -#include "settings/Setting.h" -#include "settings/OverrideSetting.h" -#include "PassthroughSetting.h" #include +#include "PassthroughSetting.h" +#include "settings/OverrideSetting.h" +#include "settings/Setting.h" #include -SettingsObject::SettingsObject(QObject *parent) : QObject(parent) -{ -} +SettingsObject::SettingsObject(QObject* parent) : QObject(parent) {} SettingsObject::~SettingsObject() { m_settings.clear(); } -std::shared_ptr SettingsObject::registerOverride(std::shared_ptr original, - std::shared_ptr gate) +std::shared_ptr SettingsObject::registerOverride(std::shared_ptr original, std::shared_ptr gate) { - if (contains(original->id())) - { - qCritical() << QString("Failed to register setting %1. ID already exists.") - .arg(original->id()); - return nullptr; // Fail + if (contains(original->id())) { + qCritical() << QString("Failed to register setting %1. ID already exists.").arg(original->id()); + return nullptr; // Fail } auto override = std::make_shared(original, gate); override->m_storage = this; @@ -46,14 +41,11 @@ std::shared_ptr SettingsObject::registerOverride(std::shared_ptr SettingsObject::registerPassthrough(std::shared_ptr original, - std::shared_ptr gate) +std::shared_ptr SettingsObject::registerPassthrough(std::shared_ptr original, std::shared_ptr gate) { - if (contains(original->id())) - { - qCritical() << QString("Failed to register setting %1. ID already exists.") - .arg(original->id()); - return nullptr; // Fail + if (contains(original->id())) { + qCritical() << QString("Failed to register setting %1. ID already exists.").arg(original->id()); + return nullptr; // Fail } auto passthrough = std::make_shared(original, gate); passthrough->m_storage = this; @@ -66,11 +58,9 @@ std::shared_ptr SettingsObject::registerSetting(QStringList synonyms, Q { if (synonyms.empty()) return nullptr; - if (contains(synonyms.first())) - { - qCritical() << QString("Failed to register setting %1. ID already exists.") - .arg(synonyms.first()); - return nullptr; // Fail + if (contains(synonyms.first())) { + qCritical() << QString("Failed to register setting %1. ID already exists.").arg(synonyms.first()); + return nullptr; // Fail } auto setting = std::make_shared(synonyms, defVal); setting->m_storage = this; @@ -79,7 +69,7 @@ std::shared_ptr SettingsObject::registerSetting(QStringList synonyms, Q return setting; } -std::shared_ptr SettingsObject::getSetting(const QString &id) const +std::shared_ptr SettingsObject::getSetting(const QString& id) const { // Make sure there is a setting with the given ID. if (!m_settings.contains(id)) @@ -88,54 +78,49 @@ std::shared_ptr SettingsObject::getSetting(const QString &id) const return m_settings[id]; } -QVariant SettingsObject::get(const QString &id) const +QVariant SettingsObject::get(const QString& id) const { auto setting = getSetting(id); return (setting ? setting->get() : QVariant()); } -bool SettingsObject::set(const QString &id, QVariant value) +bool SettingsObject::set(const QString& id, QVariant value) { auto setting = getSetting(id); - if (!setting) - { + if (!setting) { qCritical() << QString("Error changing setting %1. Setting doesn't exist.").arg(id); return false; - } - else - { + } else { setting->set(value); return true; } } -void SettingsObject::reset(const QString &id) const +void SettingsObject::reset(const QString& id) const { auto setting = getSetting(id); if (setting) setting->reset(); } -bool SettingsObject::contains(const QString &id) +bool SettingsObject::contains(const QString& id) { return m_settings.contains(id); } bool SettingsObject::reload() { - for (auto setting : m_settings.values()) - { + for (auto setting : m_settings.values()) { setting->set(setting->get()); } return true; } -void SettingsObject::connectSignals(const Setting &setting) +void SettingsObject::connectSignals(const Setting& setting) { connect(&setting, &Setting::SettingChanged, this, &SettingsObject::changeSetting); - connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)), this, - SIGNAL(SettingChanged(const Setting &, QVariant))); + connect(&setting, SIGNAL(SettingChanged(const Setting&, QVariant)), this, SIGNAL(SettingChanged(const Setting&, QVariant))); connect(&setting, &Setting::settingReset, this, &SettingsObject::resetSetting); - connect(&setting, SIGNAL(settingReset(Setting)), this, SIGNAL(settingReset(const Setting &))); + connect(&setting, SIGNAL(settingReset(Setting)), this, SIGNAL(settingReset(const Setting&))); } diff --git a/launcher/settings/SettingsObject.h b/launcher/settings/SettingsObject.h index 4d735511c..75631f247 100644 --- a/launcher/settings/SettingsObject.h +++ b/launcher/settings/SettingsObject.h @@ -15,12 +15,12 @@ #pragma once -#include +#include +#include #include +#include #include #include -#include -#include #include class Setting; @@ -41,27 +41,20 @@ typedef std::weak_ptr SettingsObjectWeakPtr; * * \sa Setting */ -class SettingsObject : public QObject -{ +class SettingsObject : public QObject { Q_OBJECT -public: - class Lock - { - public: - Lock(SettingsObjectPtr locked) - :m_locked(locked) - { - m_locked->suspendSave(); - } - ~Lock() - { - m_locked->resumeSave(); - } - private: + public: + class Lock { + public: + Lock(SettingsObjectPtr locked) : m_locked(locked) { m_locked->suspendSave(); } + ~Lock() { m_locked->resumeSave(); } + + private: SettingsObjectPtr m_locked; }; -public: - explicit SettingsObject(QObject *parent = 0); + + public: + explicit SettingsObject(QObject* parent = 0); virtual ~SettingsObject(); /*! * Registers an override setting for the given original setting in this settings object @@ -90,8 +83,7 @@ public: * the one that is being registered. * \return A valid Setting shared pointer if successful. */ - std::shared_ptr registerSetting(QStringList synonyms, - QVariant defVal = QVariant()); + std::shared_ptr registerSetting(QStringList synonyms, QVariant defVal = QVariant()); /*! * Registers the given setting with this SettingsObject and connects the necessary signals. @@ -100,10 +92,7 @@ public: * the one that is being registered. * \return A valid Setting shared pointer if successful. */ - std::shared_ptr registerSetting(QString id, QVariant defVal = QVariant()) - { - return registerSetting(QStringList(id), defVal); - } + std::shared_ptr registerSetting(QString id, QVariant defVal = QVariant()) { return registerSetting(QStringList(id), defVal); } /*! * \brief Gets the setting with the given ID. @@ -112,7 +101,7 @@ public: * Returns null if there is no setting with the given ID. * \sa operator []() */ - std::shared_ptr getSetting(const QString &id) const; + std::shared_ptr getSetting(const QString& id) const; /*! * \brief Gets the value of the setting with the given ID. @@ -120,7 +109,7 @@ public: * \return The setting's value as a QVariant. * If no setting with the given ID exists, returns an invalid QVariant. */ - QVariant get(const QString &id) const; + QVariant get(const QString& id) const; /*! * \brief Sets the value of the setting with the given ID. @@ -129,20 +118,20 @@ public: * \param value The new value of the setting. * \return True if successful, false if it failed. */ - bool set(const QString &id, QVariant value); + bool set(const QString& id, QVariant value); /*! * \brief Reverts the setting with the given ID to default. * \param id The ID of the setting to reset. */ - void reset(const QString &id) const; + void reset(const QString& id) const; /*! * \brief Checks if this SettingsObject contains a setting with the given ID. * \param id The ID to check for. * \return True if the SettingsObject has a setting with the given ID. */ - bool contains(const QString &id); + bool contains(const QString& id); /*! * \brief Reloads the settings and emit signals for changed settings @@ -152,7 +141,7 @@ public: virtual void suspendSave() = 0; virtual void resumeSave() = 0; -signals: + signals: /*! * \brief Signal emitted when one of this SettingsObject object's settings changes. * This is usually just connected directly to each Setting object's @@ -160,7 +149,7 @@ signals: * \param setting A reference to the Setting object that changed. * \param value The Setting object's new value. */ - void SettingChanged(const Setting &setting, QVariant value); + void SettingChanged(const Setting& setting, QVariant value); /*! * \brief Signal emitted when one of this SettingsObject object's settings resets. @@ -168,10 +157,9 @@ signals: * settingReset() signals. * \param setting A reference to the Setting object that changed. */ - void settingReset(const Setting &setting); + void settingReset(const Setting& setting); -protected -slots: + protected slots: /*! * \brief Changes a setting. * This slot is usually connected to each Setting object's @@ -180,7 +168,7 @@ slots: * \param setting A reference to the Setting object that changed. * \param value The setting's new value. */ - virtual void changeSetting(const Setting &setting, QVariant value) = 0; + virtual void changeSetting(const Setting& setting, QVariant value) = 0; /*! * \brief Resets a setting. @@ -189,27 +177,28 @@ slots: * to update the setting's value in the config file. * \param setting A reference to the Setting object that changed. */ - virtual void resetSetting(const Setting &setting) = 0; + virtual void resetSetting(const Setting& setting) = 0; -protected: + protected: /*! * \brief Connects the necessary signals to the given Setting. * \param setting The setting to connect. */ - void connectSignals(const Setting &setting); + void connectSignals(const Setting& setting); /*! * \brief Function used by Setting objects to get their values from the SettingsObject. * \param setting The * \return */ - virtual QVariant retrieveValue(const Setting &setting) = 0; + virtual QVariant retrieveValue(const Setting& setting) = 0; friend class Setting; -private: + private: QMap> m_settings; -protected: + + protected: bool m_suspendSave = false; bool m_doSave = false; }; diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp index 9aada5e69..884923466 100644 --- a/launcher/tasks/ConcurrentTask.cpp +++ b/launcher/tasks/ConcurrentTask.cpp @@ -194,7 +194,7 @@ void ConcurrentTask::subTaskStatus(Task::Ptr task, const QString& msg) auto task_progress = m_task_progress.value(task->getUid()); task_progress->status = msg; task_progress->state = TaskStepState::Running; - + emit stepProgress(*task_progress); if (totalSize() == 1) { @@ -207,7 +207,7 @@ void ConcurrentTask::subTaskDetails(Task::Ptr task, const QString& msg) auto task_progress = m_task_progress.value(task->getUid()); task_progress->details = msg; task_progress->state = TaskStepState::Running; - + emit stepProgress(*task_progress); if (totalSize() == 1) { @@ -220,7 +220,7 @@ void ConcurrentTask::subTaskProgress(Task::Ptr task, qint64 current, qint64 tota auto task_progress = m_task_progress.value(task->getUid()); task_progress->update(current, total); - + emit stepProgress(*task_progress); updateStepProgress(*task_progress, Operation::CHANGED); updateState(); @@ -233,7 +233,7 @@ void ConcurrentTask::subTaskProgress(Task::Ptr task, qint64 current, qint64 tota void ConcurrentTask::subTaskStepProgress(Task::Ptr task, TaskStepProgress const& task_progress) { Operation op = Operation::ADDED; - + if (!m_task_progress.contains(task_progress.uid)) { m_task_progress.insert(task_progress.uid, std::make_shared(task_progress)); op = Operation::ADDED; @@ -254,12 +254,10 @@ void ConcurrentTask::subTaskStepProgress(Task::Ptr task, TaskStepProgress const& emit stepProgress(*tp.get()); updateStepProgress(*tp.get(), op); } - } void ConcurrentTask::updateStepProgress(TaskStepProgress const& changed_progress, Operation op) { - switch (op) { case Operation::ADDED: m_stepProgress += changed_progress.current; @@ -274,9 +272,8 @@ void ConcurrentTask::updateStepProgress(TaskStepProgress const& changed_progress m_stepTotalProgress -= changed_progress.old_total; m_stepProgress += changed_progress.current; m_stepTotalProgress += changed_progress.total; - break; + break; } - } void ConcurrentTask::updateState() diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index fd82ec001..a8097ffd6 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -40,16 +40,15 @@ Q_LOGGING_CATEGORY(taskLogC, "launcher.task") -Task::Task(QObject *parent, bool show_debug) : QObject(parent), m_show_debug(show_debug) +Task::Task(QObject* parent, bool show_debug) : QObject(parent), m_show_debug(show_debug) { m_uid = QUuid::createUuid(); setAutoDelete(false); } -void Task::setStatus(const QString &new_status) +void Task::setStatus(const QString& new_status) { - if(m_status != new_status) - { + if (m_status != new_status) { m_status = new_status; emit status(m_status); } @@ -57,8 +56,7 @@ void Task::setStatus(const QString &new_status) void Task::setDetails(const QString& new_details) { - if (m_details != new_details) - { + if (m_details != new_details) { m_details = new_details; emit details(m_details); } @@ -69,41 +67,35 @@ void Task::setProgress(qint64 current, qint64 total) if ((m_progress != current) || (m_progressTotal != total)) { m_progress = current; m_progressTotal = total; - + emit progress(m_progress, m_progressTotal); - } + } } void Task::start() { - switch(m_state) - { - case State::Inactive: - { + switch (m_state) { + case State::Inactive: { if (m_show_debug) qCDebug(taskLogC) << "Task" << describe() << "starting for the first time"; break; } - case State::AbortedByUser: - { + case State::AbortedByUser: { if (m_show_debug) qCDebug(taskLogC) << "Task" << describe() << "restarting for after being aborted by user"; break; } - case State::Failed: - { + case State::Failed: { if (m_show_debug) qCDebug(taskLogC) << "Task" << describe() << "restarting for after failing at first"; break; } - case State::Succeeded: - { + case State::Succeeded: { if (m_show_debug) qCDebug(taskLogC) << "Task" << describe() << "restarting for after succeeding at first"; break; } - case State::Running: - { + case State::Running: { if (m_show_debug) qCWarning(taskLogC) << "The launcher tried to start task" << describe() << "while it was already running!"; return; @@ -118,8 +110,7 @@ void Task::start() void Task::emitFailed(QString reason) { // Don't fail twice. - if (!isRunning()) - { + if (!isRunning()) { qCCritical(taskLogC) << "Task" << describe() << "failed while not running!!!!: " << reason; return; } @@ -133,8 +124,7 @@ void Task::emitFailed(QString reason) void Task::emitAborted() { // Don't abort twice. - if (!isRunning()) - { + if (!isRunning()) { qCCritical(taskLogC) << "Task" << describe() << "aborted while not running!!!!"; return; } @@ -149,8 +139,7 @@ void Task::emitAborted() void Task::emitSucceeded() { // Don't succeed twice. - if (!isRunning()) - { + if (!isRunning()) { qCCritical(taskLogC) << "Task" << describe() << "succeeded while not running!!!!"; return; } @@ -172,12 +161,9 @@ QString Task::describe() QTextStream out(&outStr); out << metaObject()->className() << QChar('('); auto name = objectName(); - if(name.isEmpty()) - { + if (name.isEmpty()) { out << QString("0x%1").arg(reinterpret_cast(this), 0, 16); - } - else - { + } else { out << name; } out << " ID: " << m_uid.toString(QUuid::WithoutBraces); diff --git a/launcher/tasks/Task.h b/launcher/tasks/Task.h index 57177697e..7e1defd80 100644 --- a/launcher/tasks/Task.h +++ b/launcher/tasks/Task.h @@ -36,25 +36,20 @@ #pragma once +#include #include #include -#include #include "QObjectPtr.h" Q_DECLARE_LOGGING_CATEGORY(taskLogC) -enum class TaskStepState { - Waiting, - Running, - Failed, - Succeeded -}; +enum class TaskStepState { Waiting, Running, Failed, Succeeded }; Q_DECLARE_METATYPE(TaskStepState) struct TaskStepProgress { - QUuid uid; + QUuid uid; qint64 current = 0; qint64 total = -1; @@ -64,14 +59,11 @@ struct TaskStepProgress { QString status = ""; QString details = ""; TaskStepState state = TaskStepState::Waiting; - TaskStepProgress() { - this->uid = QUuid::createUuid(); - } - TaskStepProgress(QUuid uid) { - this->uid = uid; - } + TaskStepProgress() { this->uid = QUuid::createUuid(); } + TaskStepProgress(QUuid uid) { this->uid = uid; } bool isDone() const { return (state == TaskStepState::Failed) || (state == TaskStepState::Succeeded); } - void update(qint64 current, qint64 total) { + void update(qint64 current, qint64 total) + { this->old_current = this->current; this->old_total = this->total; @@ -100,8 +92,8 @@ class Task : public QObject, public QRunnable { bool isFinished() const; bool wasSuccessful() const; - /*! - * MultiStep tasks are combinations of multiple tasks into a single logical task. + /*! + * MultiStep tasks are combinations of multiple tasks into a single logical task. * The main usage of this is in SequencialTask. */ virtual auto isMultiStep() const -> bool { return false; } @@ -125,8 +117,6 @@ class Task : public QObject, public QRunnable { qint64 getTotalProgress() { return m_progressTotal; } virtual auto getStepProgress() const -> TaskStepProgressList { return {}; } - - QUuid getUid() { return m_uid; } protected: @@ -155,9 +145,18 @@ class Task : public QObject, public QRunnable { void run() override { start(); } virtual void start(); - virtual bool abort() { if(canAbort()) emitAborted(); return canAbort(); }; + virtual bool abort() + { + if (canAbort()) + emitAborted(); + return canAbort(); + }; - void setAbortable(bool can_abort) { m_can_abort = can_abort; emit abortStatusChanged(can_abort); } + void setAbortable(bool can_abort) + { + m_can_abort = can_abort; + emit abortStatusChanged(can_abort); + } protected: virtual void executeTask() = 0; @@ -190,5 +189,4 @@ class Task : public QObject, public QRunnable { // Change using setAbortStatus bool m_can_abort = false; QUuid m_uid; - }; diff --git a/launcher/tools/BaseExternalTool.cpp b/launcher/tools/BaseExternalTool.cpp index 38d817887..9e4b91cd8 100644 --- a/launcher/tools/BaseExternalTool.cpp +++ b/launcher/tools/BaseExternalTool.cpp @@ -1,7 +1,7 @@ #include "BaseExternalTool.h" -#include #include +#include #ifdef Q_OS_WIN #include @@ -9,33 +9,24 @@ #include "BaseInstance.h" -BaseExternalTool::BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent) +BaseExternalTool::BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject* parent) : QObject(parent), m_instance(instance), globalSettings(settings) -{ -} +{} -BaseExternalTool::~BaseExternalTool() -{ -} +BaseExternalTool::~BaseExternalTool() {} -BaseDetachedTool::BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent) +BaseDetachedTool::BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject* parent) : BaseExternalTool(settings, instance, parent) -{ - -} +{} void BaseDetachedTool::run() { runImpl(); } +BaseExternalToolFactory::~BaseExternalToolFactory() {} -BaseExternalToolFactory::~BaseExternalToolFactory() +BaseDetachedTool* BaseDetachedToolFactory::createDetachedTool(InstancePtr instance, QObject* parent) { -} - -BaseDetachedTool *BaseDetachedToolFactory::createDetachedTool(InstancePtr instance, - QObject *parent) -{ - return qobject_cast(createTool(instance, parent)); + return qobject_cast(createTool(instance, parent)); } diff --git a/launcher/tools/BaseExternalTool.h b/launcher/tools/BaseExternalTool.h index 1ebed6ae2..eb2d07e1e 100644 --- a/launcher/tools/BaseExternalTool.h +++ b/launcher/tools/BaseExternalTool.h @@ -1,58 +1,53 @@ #pragma once -#include #include +#include class BaseInstance; class SettingsObject; class QProcess; -class BaseExternalTool : public QObject -{ +class BaseExternalTool : public QObject { Q_OBJECT -public: - explicit BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0); + public: + explicit BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject* parent = 0); virtual ~BaseExternalTool(); -protected: + protected: InstancePtr m_instance; SettingsObjectPtr globalSettings; }; -class BaseDetachedTool : public BaseExternalTool -{ +class BaseDetachedTool : public BaseExternalTool { Q_OBJECT -public: - explicit BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0); + public: + explicit BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject* parent = 0); -public -slots: + public slots: void run(); -protected: + protected: virtual void runImpl() = 0; }; -class BaseExternalToolFactory -{ -public: +class BaseExternalToolFactory { + public: virtual ~BaseExternalToolFactory(); virtual QString name() const = 0; virtual void registerSettings(SettingsObjectPtr settings) = 0; - virtual BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) = 0; + virtual BaseExternalTool* createTool(InstancePtr instance, QObject* parent = 0) = 0; - virtual bool check(QString *error) = 0; - virtual bool check(const QString &path, QString *error) = 0; + virtual bool check(QString* error) = 0; + virtual bool check(const QString& path, QString* error) = 0; -protected: + protected: SettingsObjectPtr globalSettings; }; -class BaseDetachedToolFactory : public BaseExternalToolFactory -{ -public: - virtual BaseDetachedTool *createDetachedTool(InstancePtr instance, QObject *parent = 0); +class BaseDetachedToolFactory : public BaseExternalToolFactory { + public: + virtual BaseDetachedTool* createDetachedTool(InstancePtr instance, QObject* parent = 0); }; diff --git a/launcher/tools/BaseProfiler.cpp b/launcher/tools/BaseProfiler.cpp index 300d1a736..2ab1254e9 100644 --- a/launcher/tools/BaseProfiler.cpp +++ b/launcher/tools/BaseProfiler.cpp @@ -3,10 +3,8 @@ #include -BaseProfiler::BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent) - : BaseExternalTool(settings, instance, parent) -{ -} +BaseProfiler::BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject* parent) : BaseExternalTool(settings, instance, parent) +{} void BaseProfiler::beginProfiling(shared_qobject_ptr process) { @@ -20,8 +18,7 @@ void BaseProfiler::abortProfiling() void BaseProfiler::abortProfilingImpl() { - if (!m_profilerProcess) - { + if (!m_profilerProcess) { return; } m_profilerProcess->terminate(); @@ -30,7 +27,7 @@ void BaseProfiler::abortProfilingImpl() emit abortLaunch(tr("Profiler aborted")); } -BaseProfiler *BaseProfilerFactory::createProfiler(InstancePtr instance, QObject *parent) +BaseProfiler* BaseProfilerFactory::createProfiler(InstancePtr instance, QObject* parent) { - return qobject_cast(createTool(instance, parent)); + return qobject_cast(createTool(instance, parent)); } diff --git a/launcher/tools/BaseProfiler.h b/launcher/tools/BaseProfiler.h index 1c934aa35..ac0f3a786 100644 --- a/launcher/tools/BaseProfiler.h +++ b/launcher/tools/BaseProfiler.h @@ -8,30 +8,27 @@ class SettingsObject; class LaunchTask; class QProcess; -class BaseProfiler : public BaseExternalTool -{ +class BaseProfiler : public BaseExternalTool { Q_OBJECT -public: - explicit BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0); + public: + explicit BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject* parent = 0); -public -slots: + public slots: void beginProfiling(shared_qobject_ptr process); void abortProfiling(); -protected: - QProcess *m_profilerProcess; + protected: + QProcess* m_profilerProcess; virtual void beginProfilingImpl(shared_qobject_ptr process) = 0; virtual void abortProfilingImpl(); -signals: - void readyToLaunch(const QString &message); - void abortLaunch(const QString &message); + signals: + void readyToLaunch(const QString& message); + void abortLaunch(const QString& message); }; -class BaseProfilerFactory : public BaseExternalToolFactory -{ -public: - virtual BaseProfiler *createProfiler(InstancePtr instance, QObject *parent = 0); +class BaseProfilerFactory : public BaseExternalToolFactory { + public: + virtual BaseProfiler* createProfiler(InstancePtr instance, QObject* parent = 0); }; diff --git a/launcher/tools/JProfiler.cpp b/launcher/tools/JProfiler.cpp index 15c0cab6d..3fa9e94e4 100644 --- a/launcher/tools/JProfiler.cpp +++ b/launcher/tools/JProfiler.cpp @@ -2,32 +2,27 @@ #include -#include "settings/SettingsObject.h" -#include "launch/LaunchTask.h" #include "BaseInstance.h" +#include "launch/LaunchTask.h" +#include "settings/SettingsObject.h" -class JProfiler : public BaseProfiler -{ +class JProfiler : public BaseProfiler { Q_OBJECT -public: - JProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0); + public: + JProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject* parent = 0); -private slots: + private slots: void profilerStarted(); void profilerFinished(int exit, QProcess::ExitStatus status); -protected: + protected: void beginProfilingImpl(shared_qobject_ptr process); -private: + private: int listeningPort = 0; }; -JProfiler::JProfiler(SettingsObjectPtr settings, InstancePtr instance, - QObject *parent) - : BaseProfiler(settings, instance, parent) -{ -} +JProfiler::JProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject* parent) : BaseProfiler(settings, instance, parent) {} void JProfiler::profilerStarted() { @@ -36,12 +31,10 @@ void JProfiler::profilerStarted() void JProfiler::profilerFinished(int exit, QProcess::ExitStatus status) { - if (status == QProcess::CrashExit) - { + if (status == QProcess::CrashExit) { emit abortLaunch(tr("Profiler aborted")); } - if (m_profilerProcess) - { + if (m_profilerProcess) { m_profilerProcess->deleteLater(); m_profilerProcess = 0; } @@ -50,13 +43,8 @@ void JProfiler::profilerFinished(int exit, QProcess::ExitStatus status) void JProfiler::beginProfilingImpl(shared_qobject_ptr process) { listeningPort = globalSettings->get("JProfilerPort").toInt(); - QProcess *profiler = new QProcess(this); - QStringList profilerArgs = - { - "-d", QString::number(process->pid()), - "--gui", - "-p", QString::number(listeningPort) - }; + QProcess* profiler = new QProcess(this); + QStringList profilerArgs = { "-d", QString::number(process->pid()), "--gui", "-p", QString::number(listeningPort) }; auto basePath = globalSettings->get("JProfilerPath").toString(); #ifdef Q_OS_WIN @@ -82,31 +70,28 @@ void JProfilerFactory::registerSettings(SettingsObjectPtr settings) globalSettings = settings; } -BaseExternalTool *JProfilerFactory::createTool(InstancePtr instance, QObject *parent) +BaseExternalTool* JProfilerFactory::createTool(InstancePtr instance, QObject* parent) { return new JProfiler(globalSettings, instance, parent); } -bool JProfilerFactory::check(QString *error) +bool JProfilerFactory::check(QString* error) { return check(globalSettings->get("JProfilerPath").toString(), error); } -bool JProfilerFactory::check(const QString &path, QString *error) +bool JProfilerFactory::check(const QString& path, QString* error) { - if (path.isEmpty()) - { + if (path.isEmpty()) { *error = QObject::tr("Empty path"); return false; } QDir dir(path); - if (!dir.exists()) - { + if (!dir.exists()) { *error = QObject::tr("Path does not exist"); return false; } - if (!dir.exists("bin") || !(dir.exists("bin/jprofiler") || dir.exists("bin/jprofiler.exe")) || !dir.exists("bin/agent.jar")) - { + if (!dir.exists("bin") || !(dir.exists("bin/jprofiler") || dir.exists("bin/jprofiler.exe")) || !dir.exists("bin/agent.jar")) { *error = QObject::tr("Invalid JProfiler install"); return false; } diff --git a/launcher/tools/JProfiler.h b/launcher/tools/JProfiler.h index 0e9a3a85a..55715df32 100644 --- a/launcher/tools/JProfiler.h +++ b/launcher/tools/JProfiler.h @@ -2,12 +2,11 @@ #include "BaseProfiler.h" -class JProfilerFactory : public BaseProfilerFactory -{ -public: +class JProfilerFactory : public BaseProfilerFactory { + public: QString name() const override { return "JProfiler"; } void registerSettings(SettingsObjectPtr settings) override; - BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override; - bool check(QString *error) override; - bool check(const QString &path, QString *error) override; + BaseExternalTool* createTool(InstancePtr instance, QObject* parent = 0) override; + bool check(QString* error) override; + bool check(const QString& path, QString* error) override; }; diff --git a/launcher/tools/JVisualVM.cpp b/launcher/tools/JVisualVM.cpp index 28ffb9cdc..5f2762ebd 100644 --- a/launcher/tools/JVisualVM.cpp +++ b/launcher/tools/JVisualVM.cpp @@ -3,29 +3,24 @@ #include #include -#include "settings/SettingsObject.h" -#include "launch/LaunchTask.h" #include "BaseInstance.h" +#include "launch/LaunchTask.h" +#include "settings/SettingsObject.h" -class JVisualVM : public BaseProfiler -{ +class JVisualVM : public BaseProfiler { Q_OBJECT -public: - JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0); + public: + JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject* parent = 0); -private slots: + private slots: void profilerStarted(); void profilerFinished(int exit, QProcess::ExitStatus status); -protected: + protected: void beginProfilingImpl(shared_qobject_ptr process); }; - -JVisualVM::JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent) - : BaseProfiler(settings, instance, parent) -{ -} +JVisualVM::JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject* parent) : BaseProfiler(settings, instance, parent) {} void JVisualVM::profilerStarted() { @@ -34,12 +29,10 @@ void JVisualVM::profilerStarted() void JVisualVM::profilerFinished(int exit, QProcess::ExitStatus status) { - if (status == QProcess::CrashExit) - { + if (status == QProcess::CrashExit) { emit abortLaunch(tr("Profiler aborted")); } - if (m_profilerProcess) - { + if (m_profilerProcess) { m_profilerProcess->deleteLater(); m_profilerProcess = 0; } @@ -47,18 +40,15 @@ void JVisualVM::profilerFinished(int exit, QProcess::ExitStatus status) void JVisualVM::beginProfilingImpl(shared_qobject_ptr process) { - QProcess *profiler = new QProcess(this); - QStringList profilerArgs = - { - "--openpid", QString::number(process->pid()) - }; + QProcess* profiler = new QProcess(this); + QStringList profilerArgs = { "--openpid", QString::number(process->pid()) }; auto programPath = globalSettings->get("JVisualVMPath").toString(); profiler->setArguments(profilerArgs); profiler->setProgram(programPath); connect(profiler, &QProcess::started, this, &JVisualVM::profilerStarted); - connect(profiler, QOverload::of(&QProcess::finished), this, &JVisualVM::profilerFinished); + connect(profiler, QOverload::of(&QProcess::finished), this, &JVisualVM::profilerFinished); profiler->start(); m_profilerProcess = profiler; @@ -67,34 +57,31 @@ void JVisualVM::beginProfilingImpl(shared_qobject_ptr process) void JVisualVMFactory::registerSettings(SettingsObjectPtr settings) { QString defaultValue = QStandardPaths::findExecutable("jvisualvm"); - if (defaultValue.isNull()) - { + if (defaultValue.isNull()) { defaultValue = QStandardPaths::findExecutable("visualvm"); } settings->registerSetting("JVisualVMPath", defaultValue); globalSettings = settings; } -BaseExternalTool *JVisualVMFactory::createTool(InstancePtr instance, QObject *parent) +BaseExternalTool* JVisualVMFactory::createTool(InstancePtr instance, QObject* parent) { return new JVisualVM(globalSettings, instance, parent); } -bool JVisualVMFactory::check(QString *error) +bool JVisualVMFactory::check(QString* error) { return check(globalSettings->get("JVisualVMPath").toString(), error); } -bool JVisualVMFactory::check(const QString &path, QString *error) +bool JVisualVMFactory::check(const QString& path, QString* error) { - if (path.isEmpty()) - { + if (path.isEmpty()) { *error = QObject::tr("Empty path"); return false; } QFileInfo finfo(path); - if (!finfo.isExecutable() || !finfo.fileName().contains("visualvm")) - { + if (!finfo.isExecutable() || !finfo.fileName().contains("visualvm")) { *error = QObject::tr("Invalid path to JVisualVM"); return false; } diff --git a/launcher/tools/JVisualVM.h b/launcher/tools/JVisualVM.h index ebdea9f33..2828119a1 100644 --- a/launcher/tools/JVisualVM.h +++ b/launcher/tools/JVisualVM.h @@ -2,12 +2,11 @@ #include "BaseProfiler.h" -class JVisualVMFactory : public BaseProfilerFactory -{ -public: +class JVisualVMFactory : public BaseProfilerFactory { + public: QString name() const override { return "JVisualVM"; } void registerSettings(SettingsObjectPtr settings) override; - BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override; - bool check(QString *error) override; - bool check(const QString &path, QString *error) override; + BaseExternalTool* createTool(InstancePtr instance, QObject* parent = 0) override; + bool check(QString* error) override; + bool check(const QString& path, QString* error) override; }; diff --git a/launcher/tools/MCEditTool.cpp b/launcher/tools/MCEditTool.cpp index 2c1ec613c..19bd5a062 100644 --- a/launcher/tools/MCEditTool.cpp +++ b/launcher/tools/MCEditTool.cpp @@ -4,9 +4,9 @@ #include #include -#include "settings/SettingsObject.h" #include "BaseInstance.h" #include "minecraft/MinecraftInstance.h" +#include "settings/SettingsObject.h" MCEditTool::MCEditTool(SettingsObjectPtr settings) { @@ -26,19 +26,17 @@ QString MCEditTool::path() const bool MCEditTool::check(const QString& toolPath, QString& error) { - if (toolPath.isEmpty()) - { + if (toolPath.isEmpty()) { error = QObject::tr("Path is empty"); return false; } const QDir dir(toolPath); - if (!dir.exists()) - { + if (!dir.exists()) { error = QObject::tr("Path does not exist"); return false; } - if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && !dir.exists("mcedit2.exe")) - { + if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && + !dir.exists("mcedit2.exe")) { error = QObject::tr("Path does not seem to be a MCEdit path"); return false; } @@ -53,22 +51,16 @@ QString MCEditTool::getProgramPath() const QString mceditPath = path(); QDir mceditDir(mceditPath); #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - if (mceditDir.exists("mcedit.sh")) - { + if (mceditDir.exists("mcedit.sh")) { return mceditDir.absoluteFilePath("mcedit.sh"); - } - else if (mceditDir.exists("mcedit.py")) - { + } else if (mceditDir.exists("mcedit.py")) { return mceditDir.absoluteFilePath("mcedit.py"); } return QString(); #elif defined(Q_OS_WIN32) - if (mceditDir.exists("mcedit.exe")) - { + if (mceditDir.exists("mcedit.exe")) { return mceditDir.absoluteFilePath("mcedit.exe"); - } - else if (mceditDir.exists("mcedit2.exe")) - { + } else if (mceditDir.exists("mcedit2.exe")) { return mceditDir.absoluteFilePath("mcedit2.exe"); } return QString(); diff --git a/launcher/tools/MCEditTool.h b/launcher/tools/MCEditTool.h index 733dff866..fd2de1b6d 100644 --- a/launcher/tools/MCEditTool.h +++ b/launcher/tools/MCEditTool.h @@ -3,14 +3,14 @@ #include #include "settings/SettingsObject.h" -class MCEditTool -{ -public: +class MCEditTool { + public: MCEditTool(SettingsObjectPtr settings); - void setPath(QString & path); + void setPath(QString& path); QString path() const; - bool check(const QString &toolPath, QString &error); + bool check(const QString& toolPath, QString& error); QString getProgramPath(); -private: + + private: SettingsObjectPtr m_settings; }; diff --git a/launcher/translations/POTranslator.cpp b/launcher/translations/POTranslator.cpp index c77ae45d3..71d7878df 100644 --- a/launcher/translations/POTranslator.cpp +++ b/launcher/translations/POTranslator.cpp @@ -3,14 +3,12 @@ #include #include "FileSystem.h" -struct POEntry -{ +struct POEntry { QString text; bool fuzzy; }; -struct POTranslatorPrivate -{ +struct POTranslatorPrivate { QString filename; QHash mapping; QHash mapping_disambiguatrion; @@ -19,47 +17,37 @@ struct POTranslatorPrivate void reload(); }; -class ParserArray : public QByteArray -{ -public: - ParserArray(const QByteArray &in) : QByteArray(in) +class ParserArray : public QByteArray { + public: + ParserArray(const QByteArray& in) : QByteArray(in) {} + bool chomp(const char* data, int length) { - } - bool chomp(const char * data, int length) - { - if(startsWith(data)) - { + if (startsWith(data)) { remove(0, length); return true; } return false; } - bool chompString(QByteArray & appendHere) + bool chompString(QByteArray& appendHere) { QByteArray msg; bool escape = false; - if(size() < 2) - { + if (size() < 2) { qDebug() << "String fragment is too short"; return false; } - if(!startsWith('"')) - { + if (!startsWith('"')) { qDebug() << "String fragment does not start with \""; return false; } - if(!endsWith('"')) - { + if (!endsWith('"')) { qDebug() << "String fragment does not end with \", instead, there is" << at(size() - 1); return false; } - for(int i = 1; i < size() - 1; i++) - { + for (int i = 1; i < size() - 1; i++) { char c = operator[](i); - if(escape) - { - switch(c) - { + if (escape) { + switch (c) { case 'r': msg += '\r'; break; @@ -94,14 +82,11 @@ public: case '4': case '5': case '6': - case '7': - { + case '7': { int octal_start = i; - while ((c = operator[](i)) >= '0' && c <= '7') - { + while ((c = operator[](i)) >= '0' && c <= '7') { i++; - if (i == length() - 1) - { + if (i == length() - 1) { qDebug() << "Something went bad while parsing an octal escape string..."; return false; } @@ -109,16 +94,13 @@ public: msg += mid(octal_start, i - octal_start).toUInt(0, 8); break; } - case 'x': - { + case 'x': { // chomp the 'x' i++; int hex_start = i; - while (isxdigit(operator[](i))) - { + while (isxdigit(operator[](i))) { i++; - if (i == length() - 1) - { + if (i == length() - 1) { qDebug() << "Something went bad while parsing a hex escape string..."; return false; } @@ -126,25 +108,19 @@ public: msg += mid(hex_start, i - hex_start).toUInt(0, 16); break; } - default: - { + default: { qDebug() << "Invalid escape sequence character:" << c; return false; } } escape = false; - } - else if(c == '\\') - { + } else if (c == '\\') { escape = true; - } - else - { + } else { msg += c; } } - if(escape) - { + if (escape) { qDebug() << "Unterminated escape sequence..."; return false; } @@ -156,8 +132,7 @@ public: void POTranslatorPrivate::reload() { QFile file(filename); - if(!file.open(QFile::OpenMode::enum_type::ReadOnly | QFile::OpenMode::enum_type::Text)) - { + if (!file.open(QFile::OpenMode::enum_type::ReadOnly | QFile::OpenMode::enum_type::Text)) { qDebug() << "Failed to open PO file:" << filename; return; } @@ -169,13 +144,7 @@ void POTranslatorPrivate::reload() bool fuzzy = false; bool nextFuzzy = false; - enum class Mode - { - First, - MessageContext, - MessageId, - MessageString - } mode = Mode::First; + enum class Mode { First, MessageContext, MessageId, MessageString } mode = Mode::First; int lineNumber = 0; QHash newMapping; @@ -183,14 +152,12 @@ void POTranslatorPrivate::reload() auto endEntry = [&]() { auto strStr = QString::fromUtf8(str); // NOTE: PO header has empty id. We skip it. - if(!id.isEmpty()) - { + if (!id.isEmpty()) { auto normalKey = context + "|" + id; - newMapping.insert(normalKey, {strStr, fuzzy}); - if(!disambiguation.isEmpty()) - { + newMapping.insert(normalKey, { strStr, fuzzy }); + if (!disambiguation.isEmpty()) { auto disambiguationKey = context + "|" + id + "@" + disambiguation; - newMapping_disambiguation.insert(disambiguationKey, {strStr, fuzzy}); + newMapping_disambiguation.insert(disambiguationKey, { strStr, fuzzy }); } } context.clear(); @@ -200,36 +167,26 @@ void POTranslatorPrivate::reload() fuzzy = nextFuzzy; nextFuzzy = false; }; - while (!file.atEnd()) - { + while (!file.atEnd()) { ParserArray line = file.readLine(); - if(line.endsWith('\n')) - { + if (line.endsWith('\n')) { line.resize(line.size() - 1); } - if(line.endsWith('\r')) - { + if (line.endsWith('\r')) { line.resize(line.size() - 1); } - if(!line.size()) - { + if (!line.size()) { // NIL - } - else if(line[0] == '#') - { - if(line.contains(", fuzzy")) - { + } else if (line[0] == '#') { + if (line.contains(", fuzzy")) { nextFuzzy = true; } - } - else if(line.startsWith('"')) - { + } else if (line.startsWith('"')) { QByteArray temp; - QByteArray *out = &temp; + QByteArray* out = &temp; - switch(mode) - { + switch (mode) { case Mode::First: qDebug() << "Unexpected escaped string during initial state... line:" << lineNumber; return; @@ -243,16 +200,12 @@ void POTranslatorPrivate::reload() out = &id; break; } - if(!line.chompString(*out)) - { + if (!line.chompString(*out)) { qDebug() << "Badly formatted string on line:" << lineNumber; return; } - } - else if(line.chomp("msgctxt ", 8)) - { - switch(mode) - { + } else if (line.chomp("msgctxt ", 8)) { + switch (mode) { case Mode::First: break; case Mode::MessageString: @@ -263,21 +216,16 @@ void POTranslatorPrivate::reload() qDebug() << "Unexpected msgctxt line:" << lineNumber; return; } - if(line.chompString(context)) - { + if (line.chompString(context)) { auto parts = context.split('|'); context = parts[0]; - if(parts.size() > 1 && !parts[1].isEmpty()) - { + if (parts.size() > 1 && !parts[1].isEmpty()) { disambiguation = parts[1]; } mode = Mode::MessageContext; } - } - else if (line.chomp("msgid ", 6)) - { - switch(mode) - { + } else if (line.chomp("msgid ", 6)) { + switch (mode) { case Mode::MessageContext: case Mode::First: break; @@ -288,15 +236,11 @@ void POTranslatorPrivate::reload() qDebug() << "Unexpected msgid line:" << lineNumber; return; } - if(line.chompString(id)) - { + if (line.chompString(id)) { mode = Mode::MessageId; } - } - else if (line.chomp("msgstr ", 7)) - { - switch(mode) - { + } else if (line.chomp("msgstr ", 7)) { + switch (mode) { case Mode::First: case Mode::MessageString: case Mode::MessageContext: @@ -305,13 +249,10 @@ void POTranslatorPrivate::reload() case Mode::MessageId: break; } - if(line.chompString(str)) - { + if (line.chompString(str)) { mode = Mode::MessageString; } - } - else - { + } else { qDebug() << "I did not understand line: " << lineNumber << ":" << QString::fromUtf8(line); } lineNumber++; @@ -336,19 +277,15 @@ POTranslator::~POTranslator() QString POTranslator::translate(const char* context, const char* sourceText, const char* disambiguation, int n) const { - if(disambiguation) - { + if (disambiguation) { auto disambiguationKey = QByteArray(context) + "|" + QByteArray(sourceText) + "@" + QByteArray(disambiguation); auto iter = d->mapping_disambiguatrion.find(disambiguationKey); - if(iter != d->mapping_disambiguatrion.end()) - { - auto & entry = *iter; - if(entry.text.isEmpty()) - { + if (iter != d->mapping_disambiguatrion.end()) { + auto& entry = *iter; + if (entry.text.isEmpty()) { qDebug() << "Translation entry has no content:" << disambiguationKey; } - if(entry.fuzzy) - { + if (entry.fuzzy) { qDebug() << "Translation entry is fuzzy:" << disambiguationKey << "->" << entry.text; } return entry.text; @@ -356,15 +293,12 @@ QString POTranslator::translate(const char* context, const char* sourceText, con } auto key = QByteArray(context) + "|" + QByteArray(sourceText); auto iter = d->mapping.find(key); - if(iter != d->mapping.end()) - { - auto & entry = *iter; - if(entry.text.isEmpty()) - { + if (iter != d->mapping.end()) { + auto& entry = *iter; + if (entry.text.isEmpty()) { qDebug() << "Translation entry has no content:" << key; } - if(entry.fuzzy) - { + if (entry.fuzzy) { qDebug() << "Translation entry is fuzzy:" << key << "->" << entry.text; } return entry.text; diff --git a/launcher/translations/POTranslator.h b/launcher/translations/POTranslator.h index 1634018cc..58451e459 100644 --- a/launcher/translations/POTranslator.h +++ b/launcher/translations/POTranslator.h @@ -4,14 +4,14 @@ struct POTranslatorPrivate; -class POTranslator : public QTranslator -{ +class POTranslator : public QTranslator { Q_OBJECT -public: - explicit POTranslator(const QString& filename, QObject * parent = nullptr); + public: + explicit POTranslator(const QString& filename, QObject* parent = nullptr); virtual ~POTranslator(); - QString translate(const char * context, const char * sourceText, const char * disambiguation, int n) const override; + QString translate(const char* context, const char* sourceText, const char* disambiguation, int n) const override; bool isEmpty() const override; -private: - POTranslatorPrivate * d; + + private: + POTranslatorPrivate* d; }; diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 2763cca26..aa204cb72 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -37,18 +37,18 @@ #include "TranslationsModel.h" #include -#include -#include +#include #include #include -#include +#include +#include #include -#include "FileSystem.h" -#include "net/NetJob.h" -#include "net/ChecksumValidator.h" #include "BuildConfig.h" +#include "FileSystem.h" #include "Json.h" +#include "net/ChecksumValidator.h" +#include "net/NetJob.h" #include "POTranslator.h" @@ -56,50 +56,35 @@ const static QLatin1String defaultLangCode("en_US"); -enum class FileType -{ - NONE, - QM, - PO -}; +enum class FileType { NONE, QM, PO }; -struct Language -{ - Language() - { - updated = true; - } - Language(const QString & _key) +struct Language { + Language() { updated = true; } + Language(const QString& _key) { key = _key; locale = QLocale(key); updated = (key == defaultLangCode); } - QString languageName() const { + QString languageName() const + { QString result; - if(key == "ja_KANJI") { + if (key == "ja_KANJI") { result = locale.nativeLanguageName() + u8" (漢字)"; - } - else if(key == "es_UY") { + } else if (key == "es_UY") { result = u8"español de Latinoamérica"; - } - else if(key == "en_NZ") { - result = u8"New Zealand English"; // No idea why qt translates this to just english and not to New Zealand English - } - else if(key == "en@pirate") { + } else if (key == "en_NZ") { + result = u8"New Zealand English"; // No idea why qt translates this to just english and not to New Zealand English + } else if (key == "en@pirate") { result = u8"Tongue of the High Seas"; - } - else if(key == "en@uwu") { + } else if (key == "en@uwu") { result = u8"Cute Engwish"; - } - else if(key == "tok") { + } else if (key == "tok") { result = u8"toki pona"; - } - else if(key == "nan") { + } else if (key == "nan") { result = u8"閩南語"; // Using traditional Chinese script. Not sure if we should use simplified instead? - } - else { + } else { result = locale.nativeLanguageName(); } @@ -111,8 +96,7 @@ struct Language float percentTranslated() const { - if (total == 0) - { + if (total == 0) { return 100.0f; } return 100.0f * float(translated) / float(total); @@ -126,30 +110,17 @@ struct Language total = translated + untranslated + fuzzy; } - bool isOfSameNameAs(const Language& other) const - { - return key == other.key; - } + bool isOfSameNameAs(const Language& other) const { return key == other.key; } bool isIdenticalTo(const Language& other) const { - return - ( - key == other.key && - file_name == other.file_name && - file_size == other.file_size && - file_sha1 == other.file_sha1 && - translated == other.translated && - fuzzy == other.fuzzy && - total == other.fuzzy && - localFileType == other.localFileType - ); + return (key == other.key && file_name == other.file_name && file_size == other.file_size && file_sha1 == other.file_sha1 && + translated == other.translated && fuzzy == other.fuzzy && total == other.fuzzy && localFileType == other.localFileType); } - Language & apply(Language & other) + Language& apply(Language& other) { - if(!isOfSameNameAs(other)) - { + if (!isOfSameNameAs(other)) { return *this; } file_name = other.file_name; @@ -178,14 +149,11 @@ struct Language FileType localFileType = FileType::NONE; }; - - -struct TranslationsModel::Private -{ +struct TranslationsModel::Private { QDir m_dir; // initial state is just english - QVector m_languages = {Language (defaultLangCode)}; + QVector m_languages = { Language(defaultLangCode) }; QString m_selectedLanguage = defaultLangCode; std::unique_ptr m_qt_translator; @@ -198,7 +166,7 @@ struct TranslationsModel::Private QString m_nextDownload; std::unique_ptr m_po_translator; - QFileSystemWatcher *watcher; + QFileSystemWatcher* watcher; const QString m_system_locale = QLocale::system().name(); const QString m_system_language = m_system_locale.split('_').front(); @@ -206,7 +174,7 @@ struct TranslationsModel::Private bool no_language_set = false; }; -TranslationsModel::TranslationsModel(QString path, QObject* parent): QAbstractListModel(parent) +TranslationsModel::TranslationsModel(QString path, QObject* parent) : QAbstractListModel(parent) { d.reset(new Private); d->m_dir.setPath(path); @@ -218,15 +186,12 @@ TranslationsModel::TranslationsModel(QString path, QObject* parent): QAbstractLi d->watcher->addPath(d->m_dir.canonicalPath()); } -TranslationsModel::~TranslationsModel() -{ -} +TranslationsModel::~TranslationsModel() {} void TranslationsModel::translationDirChanged(const QString& path) { qDebug() << "Dir changed:" << path; - if (!d->no_language_set) - { + if (!d->no_language_set) { reloadLocalFiles(); } selectLanguage(selectedLanguage()); @@ -237,72 +202,58 @@ void TranslationsModel::indexReceived() qDebug() << "Got translations index!"; d->m_index_job.reset(); - if (d->no_language_set) - { + if (d->no_language_set) { reloadLocalFiles(); auto language = d->m_system_locale; - if (!findLanguage(language)) - { + if (!findLanguage(language)) { language = d->m_system_language; } selectLanguage(language); - if (selectedLanguage() != defaultLangCode) - { + if (selectedLanguage() != defaultLangCode) { updateLanguage(selectedLanguage()); } APPLICATION->settings()->set("Language", selectedLanguage()); d->no_language_set = false; } - else if(d->m_selectedLanguage != defaultLangCode) - { + else if (d->m_selectedLanguage != defaultLangCode) { downloadTranslation(d->m_selectedLanguage); } } namespace { -void readIndex(const QString & path, QMap& languages) +void readIndex(const QString& path, QMap& languages) { QByteArray data; - try - { + try { data = FS::read(path); - } - catch (const Exception &e) - { + } catch (const Exception& e) { qCritical() << "Translations Download Failed: index file not readable"; return; } int index = 1; - try - { + try { auto toplevel_doc = Json::requireDocument(data); auto doc = Json::requireObject(toplevel_doc); auto file_type = Json::requireString(doc, "file_type"); - if(file_type != "MMC-TRANSLATION-INDEX") - { + if (file_type != "MMC-TRANSLATION-INDEX") { qCritical() << "Translations Download Failed: index file is of unknown file type" << file_type; return; } auto version = Json::requireInteger(doc, "version"); - if(version > 2) - { + if (version > 2) { qCritical() << "Translations Download Failed: index file is of unknown format version" << file_type; return; } auto langObjs = Json::requireObject(doc, "languages"); - for(auto iter = langObjs.begin(); iter != langObjs.end(); iter++) - { + for (auto iter = langObjs.begin(); iter != langObjs.end(); iter++) { Language lang(iter.key()); - auto langObj = Json::requireObject(iter.value()); - lang.setTranslationStats( - Json::ensureInteger(langObj, "translated", 0), - Json::ensureInteger(langObj, "untranslated", 0), - Json::ensureInteger(langObj, "fuzzy", 0) - ); + auto langObj = Json::requireObject(iter.value()); + lang.setTranslationStats(Json::ensureInteger(langObj, "translated", 0), Json::ensureInteger(langObj, "untranslated", 0), + Json::ensureInteger(langObj, "fuzzy", 0)); lang.file_name = Json::requireString(langObj, "file"); lang.file_sha1 = Json::requireString(langObj, "sha1"); lang.file_size = Json::requireInteger(langObj, "size"); @@ -310,53 +261,40 @@ void readIndex(const QString & path, QMap& languages) languages.insert(lang.key, lang); index++; } - } - catch (Json::JsonException & e) - { + } catch (Json::JsonException& e) { qCritical() << "Translations Download Failed: index file could not be parsed as json"; } } -} +} // namespace void TranslationsModel::reloadLocalFiles() { - QMap languages = {{defaultLangCode, Language(defaultLangCode)}}; + QMap languages = { { defaultLangCode, Language(defaultLangCode) } }; readIndex(d->m_dir.absoluteFilePath("index_v2.json"), languages); - auto entries = d->m_dir.entryInfoList({"mmc_*.qm", "*.po"}, QDir::Files | QDir::NoDotAndDotDot); - for(auto & entry: entries) - { + auto entries = d->m_dir.entryInfoList({ "mmc_*.qm", "*.po" }, QDir::Files | QDir::NoDotAndDotDot); + for (auto& entry : entries) { auto completeSuffix = entry.completeSuffix(); QString langCode; FileType fileType = FileType::NONE; - if(completeSuffix == "qm") - { - langCode = entry.baseName().remove(0,4); + if (completeSuffix == "qm") { + langCode = entry.baseName().remove(0, 4); fileType = FileType::QM; - } - else if(completeSuffix == "po") - { + } else if (completeSuffix == "po") { langCode = entry.baseName(); fileType = FileType::PO; - } - else - { + } else { continue; } auto langIter = languages.find(langCode); - if(langIter != languages.end()) - { - auto & language = *langIter; - if(int(fileType) > int(language.localFileType)) - { + if (langIter != languages.end()) { + auto& language = *langIter; + if (int(fileType) > int(language.localFileType)) { language.localFileType = fileType; } - } - else - { - if(fileType == FileType::PO) - { + } else { + if (fileType == FileType::PO) { Language localFound(langCode); localFound.localFileType = FileType::PO; languages.insert(langCode, localFound); @@ -365,52 +303,40 @@ void TranslationsModel::reloadLocalFiles() } // changed and removed languages - for(auto iter = d->m_languages.begin(); iter != d->m_languages.end();) - { - auto &language = *iter; + for (auto iter = d->m_languages.begin(); iter != d->m_languages.end();) { + auto& language = *iter; auto row = iter - d->m_languages.begin(); auto updatedLanguageIter = languages.find(language.key); - if(updatedLanguageIter != languages.end()) - { - if(language.isIdenticalTo(*updatedLanguageIter)) - { + if (updatedLanguageIter != languages.end()) { + if (language.isIdenticalTo(*updatedLanguageIter)) { languages.remove(language.key); - } - else - { + } else { language.apply(*updatedLanguageIter); emit dataChanged(index(row), index(row)); languages.remove(language.key); } iter++; - } - else - { + } else { beginRemoveRows(QModelIndex(), row, row); iter = d->m_languages.erase(iter); endRemoveRows(); } } // added languages - if(languages.isEmpty()) - { + if (languages.isEmpty()) { return; } beginInsertRows(QModelIndex(), 0, d->m_languages.size() + languages.size() - 1); - for(auto & language: languages) - { + for (auto& language : languages) { d->m_languages.append(language); } std::sort(d->m_languages.begin(), d->m_languages.end(), [this](const Language& a, const Language& b) { - if (a.key != b.key) - { - if (a.key == d->m_system_locale || a.key == d->m_system_language) - { + if (a.key != b.key) { + if (a.key == d->m_system_locale || a.key == d->m_system_language) { return true; } - if (b.key == d->m_system_locale || b.key == d->m_system_language) - { + if (b.key == d->m_system_locale || b.key == d->m_system_language) { return false; } } @@ -420,14 +346,9 @@ void TranslationsModel::reloadLocalFiles() } namespace { -enum class Column -{ - Language, - Completeness -}; +enum class Column { Language, Completeness }; } - QVariant TranslationsModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) @@ -439,62 +360,48 @@ QVariant TranslationsModel::data(const QModelIndex& index, int role) const if (row < 0 || row >= d->m_languages.size()) return QVariant(); - auto & lang = d->m_languages[row]; - switch (role) - { - case Qt::DisplayRole: - { - switch(column) - { - case Column::Language: - { - return lang.languageName(); - } - case Column::Completeness: - { - return QString("%1%").arg(lang.percentTranslated(), 3, 'f', 1); + auto& lang = d->m_languages[row]; + switch (role) { + case Qt::DisplayRole: { + switch (column) { + case Column::Language: { + return lang.languageName(); + } + case Column::Completeness: { + return QString("%1%").arg(lang.percentTranslated(), 3, 'f', 1); + } } + qWarning("TranslationModel::data not implemented when role is DisplayRole"); } - qWarning("TranslationModel::data not implemented when role is DisplayRole"); - } - case Qt::ToolTipRole: - { - return tr("%1:\n%2 translated\n%3 fuzzy\n%4 total").arg(lang.key, QString::number(lang.translated), QString::number(lang.fuzzy), QString::number(lang.total)); - } - case Qt::UserRole: - return lang.key; - default: - return QVariant(); + case Qt::ToolTipRole: { + return tr("%1:\n%2 translated\n%3 fuzzy\n%4 total") + .arg(lang.key, QString::number(lang.translated), QString::number(lang.fuzzy), QString::number(lang.total)); + } + case Qt::UserRole: + return lang.key; + default: + return QVariant(); } } QVariant TranslationsModel::headerData(int section, Qt::Orientation orientation, int role) const { auto column = static_cast(section); - if(role == Qt::DisplayRole) - { - switch(column) - { - case Column::Language: - { + if (role == Qt::DisplayRole) { + switch (column) { + case Column::Language: { return tr("Language"); } - case Column::Completeness: - { + case Column::Completeness: { return tr("Completeness"); } } - } - else if(role == Qt::ToolTipRole) - { - switch(column) - { - case Column::Language: - { + } else if (role == Qt::ToolTipRole) { + switch (column) { + case Column::Language: { return tr("The native language name."); } - case Column::Completeness: - { + case Column::Completeness: { return tr("Completeness is the percentage of fully translated strings, not counting automatically guessed ones."); } } @@ -512,18 +419,12 @@ int TranslationsModel::columnCount(const QModelIndex& parent) const return 2; } -Language * TranslationsModel::findLanguage(const QString& key) +Language* TranslationsModel::findLanguage(const QString& key) { - auto found = std::find_if(d->m_languages.begin(), d->m_languages.end(), [&](Language & lang) - { - return lang.key == key; - }); - if(found == d->m_languages.end()) - { + auto found = std::find_if(d->m_languages.begin(), d->m_languages.end(), [&](Language& lang) { return lang.key == key; }); + if (found == d->m_languages.end()) { return nullptr; - } - else - { + } else { return found; } } @@ -568,10 +469,8 @@ bool TranslationsModel::selectLanguage(QString key) QLocale::setDefault( QLocale(APPLICATION->settings()->get("UseSystemLocale").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); - // if it's the default UI language, finish - if(langCode == defaultLangCode) - { + if (langCode == defaultLangCode) { d->m_selectedLanguage = langCode; return true; } @@ -580,70 +479,47 @@ bool TranslationsModel::selectLanguage(QString key) bool successful = false; // FIXME: this is likely never present. FIX IT. d->m_qt_translator.reset(new QTranslator()); - if (d->m_qt_translator->load("qt_" + langCode, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) - { + if (d->m_qt_translator->load("qt_" + langCode, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { qDebug() << "Loading Qt Language File for" << langCode.toLocal8Bit().constData() << "..."; - if (!QCoreApplication::installTranslator(d->m_qt_translator.get())) - { + if (!QCoreApplication::installTranslator(d->m_qt_translator.get())) { qCritical() << "Loading Qt Language File failed."; d->m_qt_translator.reset(); - } - else - { + } else { successful = true; } - } - else - { + } else { d->m_qt_translator.reset(); } - if(langPtr->localFileType == FileType::PO) - { + if (langPtr->localFileType == FileType::PO) { qDebug() << "Loading Application Language File for" << langCode.toLocal8Bit().constData() << "..."; auto poTranslator = new POTranslator(FS::PathCombine(d->m_dir.path(), langCode + ".po")); - if(!poTranslator->isEmpty()) - { - if (!QCoreApplication::installTranslator(poTranslator)) - { + if (!poTranslator->isEmpty()) { + if (!QCoreApplication::installTranslator(poTranslator)) { delete poTranslator; qCritical() << "Installing Application Language File failed."; - } - else - { + } else { d->m_app_translator.reset(poTranslator); successful = true; } - } - else - { + } else { qCritical() << "Loading Application Language File failed."; d->m_app_translator.reset(); } - } - else if(langPtr->localFileType == FileType::QM) - { + } else if (langPtr->localFileType == FileType::QM) { d->m_app_translator.reset(new QTranslator()); - if (d->m_app_translator->load("mmc_" + langCode, d->m_dir.path())) - { + if (d->m_app_translator->load("mmc_" + langCode, d->m_dir.path())) { qDebug() << "Loading Application Language File for" << langCode.toLocal8Bit().constData() << "..."; - if (!QCoreApplication::installTranslator(d->m_app_translator.get())) - { + if (!QCoreApplication::installTranslator(d->m_app_translator.get())) { qCritical() << "Installing Application Language File failed."; d->m_app_translator.reset(); - } - else - { + } else { successful = true; } - } - else - { + } else { d->m_app_translator.reset(); } - } - else - { + } else { d->m_app_translator.reset(); } d->m_selectedLanguage = langCode; @@ -653,8 +529,7 @@ bool TranslationsModel::selectLanguage(QString key) QModelIndex TranslationsModel::selectedIndex() { auto found = findLanguage(d->m_selectedLanguage); - if(found) - { + if (found) { // QVector iterator freely converts to pointer to contained type return index(found - d->m_languages.begin(), 0, QModelIndex()); } @@ -668,8 +543,7 @@ QString TranslationsModel::selectedLanguage() void TranslationsModel::downloadIndex() { - if(d->m_index_job || d->m_dl_job) - { + if (d->m_index_job || d->m_dl_job) { return; } qDebug() << "Downloading Translations Index..."; @@ -686,33 +560,28 @@ void TranslationsModel::downloadIndex() void TranslationsModel::updateLanguage(QString key) { - if(key == defaultLangCode) - { + if (key == defaultLangCode) { qWarning() << "Cannot update builtin language" << key; return; } auto found = findLanguage(key); - if(!found) - { + if (!found) { qWarning() << "Cannot update invalid language" << key; return; } - if(!found->updated) - { + if (!found->updated) { downloadTranslation(key); } } void TranslationsModel::downloadTranslation(QString key) { - if(d->m_dl_job) - { + if (d->m_dl_job) { d->m_nextDownload = key; return; } auto lang = findLanguage(key); - if(!lang) - { + if (!lang) { qWarning() << "Will not download an unknown translation" << key; return; } @@ -737,8 +606,7 @@ void TranslationsModel::downloadTranslation(QString key) void TranslationsModel::downloadNext() { - if(!d->m_nextDownload.isEmpty()) - { + if (!d->m_nextDownload.isEmpty()) { downloadTranslation(d->m_nextDownload); d->m_nextDownload.clear(); } @@ -755,8 +623,7 @@ void TranslationsModel::dlGood() { qDebug() << "Got translation:" << d->m_downloadingTranslation; - if(d->m_downloadingTranslation == d->m_selectedLanguage) - { + if (d->m_downloadingTranslation == d->m_selectedLanguage) { selectLanguage(d->m_selectedLanguage); } d->m_dl_job.reset(); diff --git a/launcher/ui/ColorCache.cpp b/launcher/ui/ColorCache.cpp index ef268dd2b..f941a6093 100644 --- a/launcher/ui/ColorCache.cpp +++ b/launcher/ui/ColorCache.cpp @@ -1,13 +1,11 @@ #include "ColorCache.h" - /** * Blend the color with the front color, adapting to the back color */ QColor ColorCache::blend(QColor color) { - if (Rainbow::luma(m_front) > Rainbow::luma(m_back)) - { + if (Rainbow::luma(m_front) > Rainbow::luma(m_back)) { // for dark color schemes, produce a fitting color first color = Rainbow::tint(m_front, color, 0.5); } @@ -27,8 +25,7 @@ QColor ColorCache::blendBackground(QColor color) void ColorCache::recolorAll() { auto iter = m_colors.begin(); - while(iter != m_colors.end()) - { + while (iter != m_colors.end()) { iter->front = blend(iter->original); iter->back = blendBackground(iter->original); } diff --git a/launcher/ui/ColorCache.h b/launcher/ui/ColorCache.h index a840664da..1cf292c13 100644 --- a/launcher/ui/ColorCache.h +++ b/launcher/ui/ColorCache.h @@ -1,12 +1,11 @@ #pragma once -#include -#include #include +#include #include +#include -class ColorCache -{ -public: +class ColorCache { + public: ColorCache(QColor front, QColor back, qreal bias) { m_front = front; @@ -14,15 +13,11 @@ public: m_bias = bias; }; - void addColor(int key, QColor color) - { - m_colors[key] = {color, blend(color), blendBackground(color)}; - } + void addColor(int key, QColor color) { m_colors[key] = { color, blend(color), blendBackground(color) }; } void setForeground(QColor front) { - if(m_front != front) - { + if (m_front != front) { m_front = front; recolorAll(); } @@ -30,8 +25,7 @@ public: void setBackground(QColor back) { - if(m_back != back) - { + if (m_back != back) { m_back = back; recolorAll(); } @@ -40,8 +34,7 @@ public: QColor getFront(int key) { auto iter = m_colors.find(key); - if(iter == m_colors.end()) - { + if (iter == m_colors.end()) { return QColor(); } return (*iter).front; @@ -50,8 +43,7 @@ public: QColor getBack(int key) { auto iter = m_colors.find(key); - if(iter == m_colors.end()) - { + if (iter == m_colors.end()) { return QColor(); } return (*iter).back; @@ -67,29 +59,26 @@ public: */ QColor blendBackground(QColor color); -protected: + protected: void recolorAll(); -protected: - struct ColorEntry - { + protected: + struct ColorEntry { QColor original; QColor front; QColor back; }; -protected: + protected: qreal m_bias; QColor m_front; QColor m_back; QMap m_colors; }; -class LogColorCache : public ColorCache -{ -public: - LogColorCache(QColor front, QColor back) - : ColorCache(front, back, 1.0) +class LogColorCache : public ColorCache { + public: + LogColorCache(QColor front, QColor back) : ColorCache(front, back, 1.0) { addColor((int)MessageLevel::Launcher, QColor("purple")); addColor((int)MessageLevel::Debug, QColor("green")); @@ -101,8 +90,7 @@ public: QColor getFront(MessageLevel::Enum level) { - if(!m_colors.contains((int) level)) - { + if (!m_colors.contains((int)level)) { return ColorCache::getFront((int)MessageLevel::Message); } return ColorCache::getFront((int)level); @@ -110,8 +98,7 @@ public: QColor getBack(MessageLevel::Enum level) { - if(level == MessageLevel::Fatal) - { + if (level == MessageLevel::Fatal) { return QColor(Qt::black); } return QColor(Qt::transparent); diff --git a/launcher/ui/GuiUtil.cpp b/launcher/ui/GuiUtil.cpp index 930e088a7..584a34710 100644 --- a/launcher/ui/GuiUtil.cpp +++ b/launcher/ui/GuiUtil.cpp @@ -37,21 +37,21 @@ #include "GuiUtil.h" -#include #include +#include #include #include -#include "ui/dialogs/ProgressDialog.h" -#include "ui/dialogs/CustomMessageBox.h" #include "net/PasteUpload.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" -#include "Application.h" -#include -#include #include +#include +#include +#include "Application.h" -std::optional GuiUtil::uploadPaste(const QString &name, const QString &text, QWidget *parentWidget) +std::optional GuiUtil::uploadPaste(const QString& name, const QString& text, QWidget* parentWidget) { ProgressDialog dialog(parentWidget); auto pasteTypeSetting = static_cast(APPLICATION->settings()->get("PastebinType").toInt()); @@ -64,8 +64,7 @@ std::optional GuiUtil::uploadPaste(const QString &name, const QString & else baseUrl = pasteCustomAPIBaseSetting; - if (baseUrl.isValid()) - { + if (baseUrl.isValid()) { auto response = CustomMessageBox::selectable(parentWidget, QObject::tr("Confirm Upload"), QObject::tr("You are about to upload \"%1\" to %2.\n" "You should double-check for personal information.\n\n" @@ -82,41 +81,38 @@ std::optional GuiUtil::uploadPaste(const QString &name, const QString & std::unique_ptr paste(new PasteUpload(parentWidget, text, pasteCustomAPIBaseSetting, pasteTypeSetting)); dialog.execWithTask(paste.get()); - if (!paste->wasSuccessful()) - { - CustomMessageBox::selectable( - parentWidget, - QObject::tr("Upload failed"), - paste->failReason(), - QMessageBox::Critical - )->exec(); + if (!paste->wasSuccessful()) { + CustomMessageBox::selectable(parentWidget, QObject::tr("Upload failed"), paste->failReason(), QMessageBox::Critical)->exec(); return QString(); - } - else - { + } else { const QString link = paste->pasteLink(); setClipboardText(link); CustomMessageBox::selectable( parentWidget, QObject::tr("Upload finished"), QObject::tr("The link to the uploaded log has been placed in your clipboard.").arg(link), - QMessageBox::Information)->exec(); + QMessageBox::Information) + ->exec(); return link; } } -void GuiUtil::setClipboardText(const QString &text) +void GuiUtil::setClipboardText(const QString& text) { QApplication::clipboard()->setText(text); } -static QStringList BrowseForFileInternal(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget, bool single) +static QStringList BrowseForFileInternal(QString context, + QString caption, + QString filter, + QString defaultPath, + QWidget* parentWidget, + bool single) { static QMap savedPaths; QFileDialog w(parentWidget, caption); QSet locations; - auto f = [&](QStandardPaths::StandardLocation l) - { + auto f = [&](QStandardPaths::StandardLocation l) { QString location = QStandardPaths::writableLocation(l); QFileInfo finfo(location); if (!finfo.exists()) { @@ -129,8 +125,7 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri f(QStandardPaths::DownloadLocation); f(QStandardPaths::HomeLocation); QList urls; - for (auto location : locations) - { + for (auto location : locations) { urls.append(QUrl::fromLocalFile(location)); } urls.append(QUrl::fromLocalFile(defaultPath)); @@ -140,27 +135,21 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri w.setNameFilter(filter); QString pathToOpen; - if(savedPaths.contains(context)) - { + if (savedPaths.contains(context)) { pathToOpen = savedPaths[context]; - } - else - { + } else { pathToOpen = defaultPath; } - if(!pathToOpen.isEmpty()) - { + if (!pathToOpen.isEmpty()) { QFileInfo finfo(pathToOpen); - if(finfo.exists() && finfo.isDir()) - { + if (finfo.exists() && finfo.isDir()) { w.setDirectory(finfo.absoluteFilePath()); } } w.setSidebarUrls(urls); - if (w.exec()) - { + if (w.exec()) { savedPaths[context] = w.directory().absolutePath(); return w.selectedFiles(); } @@ -168,18 +157,16 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri return {}; } -QString GuiUtil::BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget) +QString GuiUtil::BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget) { auto resultList = BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, true); - if(resultList.size()) - { + if (resultList.size()) { return resultList[0]; } return QString(); } - -QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget) +QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget) { return BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, false); } diff --git a/launcher/ui/GuiUtil.h b/launcher/ui/GuiUtil.h index 96ebd9a2d..8d384d3f6 100644 --- a/launcher/ui/GuiUtil.h +++ b/launcher/ui/GuiUtil.h @@ -3,10 +3,9 @@ #include #include -namespace GuiUtil -{ -std::optional uploadPaste(const QString &name, const QString &text, QWidget *parentWidget); -void setClipboardText(const QString &text); -QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget); -QString BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget); -} +namespace GuiUtil { +std::optional uploadPaste(const QString& name, const QString& text, QWidget* parentWidget); +void setClipboardText(const QString& text); +QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget); +QString BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget); +} // namespace GuiUtil diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index c62b370fd..4c54ba26e 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -36,12 +36,12 @@ #include "InstanceWindow.h" #include "Application.h" -#include -#include -#include -#include #include #include +#include +#include +#include +#include #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" @@ -51,8 +51,7 @@ #include "icons/IconList.h" -InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) - : QMainWindow(parent), m_instance(instance) +InstanceWindow::InstanceWindow(InstancePtr instance, QWidget* parent) : QMainWindow(parent), m_instance(instance) { setAttribute(Qt::WA_DeleteOnClose); @@ -143,8 +142,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus) { - if(newStatus == BaseInstance::Status::Gone) - { + if (newStatus == BaseInstance::Status::Gone) { m_doNotSave = true; close(); } @@ -152,25 +150,20 @@ void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance void InstanceWindow::updateLaunchButtons() { - if(m_instance->isRunning()) - { + if (m_instance->isRunning()) { m_launchOfflineButton->setEnabled(false); m_launchDemoButton->setEnabled(false); m_killButton->setText(tr("Kill")); m_killButton->setObjectName("killButton"); m_killButton->setToolTip(tr("Kill the running instance")); - } - else if(!m_instance->canLaunch()) - { + } else if (!m_instance->canLaunch()) { m_launchOfflineButton->setEnabled(false); m_launchDemoButton->setEnabled(false); m_killButton->setText(tr("Launch")); m_killButton->setObjectName("launchButton"); m_killButton->setToolTip(tr("Launch the instance")); m_killButton->setEnabled(false); - } - else - { + } else { m_launchOfflineButton->setEnabled(true); // Disable demo-mode if not available. @@ -207,7 +200,7 @@ void InstanceWindow::runningStateChanged(bool running) { updateLaunchButtons(); m_container->refreshContainer(); - if(running) { + if (running) { selectPage("log"); } } @@ -217,16 +210,14 @@ void InstanceWindow::on_closeButton_clicked() close(); } -void InstanceWindow::closeEvent(QCloseEvent *event) +void InstanceWindow::closeEvent(QCloseEvent* event) { bool proceed = true; - if(!m_doNotSave) - { + if (!m_doNotSave) { proceed &= m_container->prepareToClose(); } - if(!proceed) - { + if (!proceed) { return; } @@ -243,12 +234,9 @@ bool InstanceWindow::saveAll() void InstanceWindow::on_btnKillMinecraft_clicked() { - if(m_instance->isRunning()) - { + if (m_instance->isRunning()) { APPLICATION->kill(m_instance); - } - else - { + } else { APPLICATION->launch(m_instance, true, false, nullptr); } } @@ -268,14 +256,11 @@ void InstanceWindow::refreshContainer() m_container->refreshContainer(); } -InstanceWindow::~InstanceWindow() -{ -} +InstanceWindow::~InstanceWindow() {} bool InstanceWindow::requestClose() { - if(m_container->prepareToClose()) - { + if (m_container->prepareToClose()) { close(); return true; } diff --git a/launcher/ui/InstanceWindow.h b/launcher/ui/InstanceWindow.h index 554c4c740..ef9cdf4a5 100644 --- a/launcher/ui/InstanceWindow.h +++ b/launcher/ui/InstanceWindow.h @@ -47,12 +47,11 @@ class QPushButton; class PageContainer; -class InstanceWindow : public QMainWindow, public BasePageContainer -{ +class InstanceWindow : public QMainWindow, public BasePageContainer { Q_OBJECT -public: - explicit InstanceWindow(InstancePtr proc, QWidget *parent = 0); + public: + explicit InstanceWindow(InstancePtr proc, QWidget* parent = 0); virtual ~InstanceWindow(); bool selectPage(QString pageId) override; @@ -66,11 +65,10 @@ public: // request closing the window (from a page) bool requestClose() override; -signals: + signals: void isClosing(); -private -slots: + private slots: void on_closeButton_clicked(); void on_btnKillMinecraft_clicked(); void on_btnLaunchMinecraftOffline_clicked(); @@ -80,19 +78,19 @@ slots: void runningStateChanged(bool running); void on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus); -protected: - void closeEvent(QCloseEvent *) override; + protected: + void closeEvent(QCloseEvent*) override; -private: + private: void updateLaunchButtons(); -private: + private: shared_qobject_ptr m_proc; InstancePtr m_instance; bool m_doNotSave = false; - PageContainer *m_container = nullptr; - QPushButton *m_closeButton = nullptr; - QPushButton *m_killButton = nullptr; - QPushButton *m_launchOfflineButton = nullptr; - QPushButton *m_launchDemoButton = nullptr; + PageContainer* m_container = nullptr; + QPushButton* m_closeButton = nullptr; + QPushButton* m_killButton = nullptr; + QPushButton* m_launchOfflineButton = nullptr; + QPushButton* m_launchDemoButton = nullptr; }; diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 27c2756f6..e6434dae2 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -63,34 +63,32 @@ class KonamiCode; class InstanceTask; class LabeledToolButton; -namespace Ui -{ +namespace Ui { class MainWindow; } -class MainWindow : public QMainWindow -{ +class MainWindow : public QMainWindow { Q_OBJECT -public: - explicit MainWindow(QWidget *parent = 0); + public: + explicit MainWindow(QWidget* parent = 0); ~MainWindow(); - bool eventFilter(QObject *obj, QEvent *ev) override; - void closeEvent(QCloseEvent *event) override; - void changeEvent(QEvent * event) override; + bool eventFilter(QObject* obj, QEvent* ev) override; + void closeEvent(QCloseEvent* event) override; + void changeEvent(QEvent* event) override; void checkInstancePathForProblems(); void updatesAllowedChanged(bool allowed); void processURLs(QList urls); -signals: + signals: void isClosing(); -protected: - QMenu * createPopupMenu() override; + protected: + QMenu* createPopupMenu() override; -private slots: + private slots: void onCatToggled(bool); void onCatChanged(int); @@ -131,9 +129,9 @@ private slots: void on_actionClearMetadata_triggered(); - #ifdef Q_OS_MAC +#ifdef Q_OS_MAC void on_actionAddToPATH_triggered(); - #endif +#endif void on_actionOpenWiki_triggered(); @@ -154,7 +152,10 @@ private slots: void deleteGroup(); void undoTrashInstance(); - inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } + inline void on_actionExportInstance_triggered() + { + on_actionExportInstanceZip_triggered(); + } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); void on_actionExportInstanceFlamePack_triggered(); @@ -173,7 +174,7 @@ private slots: */ void iconUpdated(QString); - void showInstanceContextMenu(const QPoint &); + void showInstanceContextMenu(const QPoint&); void updateMainToolBar(); @@ -183,15 +184,15 @@ private slots: void instanceActivated(QModelIndex); - void instanceChanged(const QModelIndex ¤t, const QModelIndex &previous); + void instanceChanged(const QModelIndex& current, const QModelIndex& previous); void instanceSelectRequest(QString id); - void instanceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void instanceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); void selectionBad(); - void startTask(Task *task); + void startTask(Task* task); void defaultAccountChanged(); @@ -201,7 +202,6 @@ private slots: void updateNewsLabel(); - void konamiTriggered(); void globalSettingsClosed(); @@ -209,38 +209,38 @@ private slots: void lockToolbars(bool); #ifndef Q_OS_MAC - void keyReleaseEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent* event) override; #endif void refreshCurrentInstance(bool running); -private: + private: void retranslateUi(); void addInstance(QString url = QString()); void activateInstance(InstancePtr instance); void setCatBackground(bool enabled); void updateInstanceToolIcon(QString new_icon); - void setSelectedInstanceById(const QString &id); + void setSelectedInstanceById(const QString& id); void updateStatusCenter(); void setInstanceActionsEnabled(bool enabled); - void runModalTask(Task *task); - void instanceFromInstanceTask(InstanceTask *task); + void runModalTask(Task* task); + void instanceFromInstanceTask(InstanceTask* task); void finalizeInstance(InstancePtr inst); -private: - Ui::MainWindow *ui; + private: + Ui::MainWindow* ui; // these are managed by Qt's memory management model! - InstanceView *view = nullptr; - InstanceProxyModel *proxymodel = nullptr; - QToolButton *newsLabel = nullptr; - QLabel *m_statusLeft = nullptr; - QLabel *m_statusCenter = nullptr; - LabeledToolButton *changeIconButton = nullptr; - LabeledToolButton *renameButton = nullptr; - QToolButton *helpMenuButton = nullptr; - KonamiCode * secretEventFilter = nullptr; + InstanceView* view = nullptr; + InstanceProxyModel* proxymodel = nullptr; + QToolButton* newsLabel = nullptr; + QLabel* m_statusLeft = nullptr; + QLabel* m_statusCenter = nullptr; + LabeledToolButton* changeIconButton = nullptr; + LabeledToolButton* renameButton = nullptr; + QToolButton* helpMenuButton = nullptr; + KonamiCode* secretEventFilter = nullptr; std::shared_ptr instanceToolbarSetting = nullptr; @@ -250,5 +250,5 @@ private: QString m_currentInstIcon; // managed by the application object - Task *m_versionLoadTask = nullptr; + Task* m_versionLoadTask = nullptr; }; diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index b1734eff3..bac30b010 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -34,26 +34,28 @@ */ #include "AboutDialog.h" -#include "BuildConfig.h" -#include "ui_AboutDialog.h" #include #include "Application.h" #include "BuildConfig.h" #include "Markdown.h" +#include "ui_AboutDialog.h" #include #include namespace { -QString getLink(QString link, QString name) { +QString getLink(QString link, QString name) +{ return QString("<%2>").arg(link).arg(name); } -QString getWebsite(QString link) { +QString getWebsite(QString link) +{ return getLink(link, QObject::tr("Website")); } -QString getGitHub(QString username) { +QString getGitHub(QString username) +{ return getLink("https://github.com/" + username, "GitHub"); } @@ -70,19 +72,19 @@ QString getCreditsHtml() //: %1 is the name of the launcher, determined at build time, e.g. "Prism Launcher Developers" stream << "

    " << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "

    \n"; - stream << QString("

    Sefa Eyeoglu (Scrumplex) %1

    \n") .arg(getWebsite("https://scrumplex.net")); - stream << QString("

    d-513 %1

    \n") .arg(getGitHub("d-513")); - stream << QString("

    txtsd %1

    \n") .arg(getWebsite("https://ihavea.quest")); - stream << QString("

    timoreo %1

    \n") .arg(getGitHub("timoreo22")); - stream << QString("

    Ezekiel Smith (ZekeSmith) %1

    \n") .arg(getGitHub("ZekeSmith")); - stream << QString("

    cozyGalvinism %1

    \n") .arg(getGitHub("cozyGalvinism")); - stream << QString("

    DioEgizio %1

    \n") .arg(getGitHub("DioEgizio")); - stream << QString("

    flowln %1

    \n") .arg(getGitHub("flowln")); - stream << QString("

    ViRb3 %1

    \n") .arg(getGitHub("ViRb3")); - stream << QString("

    Rachel Powers (Ryex) %1

    \n") .arg(getGitHub("Ryex")); - stream << QString("

    TayouVR %1

    \n") .arg(getGitHub("TayouVR")); - stream << QString("

    TheKodeToad %1

    \n") .arg(getGitHub("TheKodeToad")); - stream << QString("

    getchoo %1

    \n") .arg(getGitHub("getchoo")); + stream << QString("

    Sefa Eyeoglu (Scrumplex) %1

    \n").arg(getWebsite("https://scrumplex.net")); + stream << QString("

    d-513 %1

    \n").arg(getGitHub("d-513")); + stream << QString("

    txtsd %1

    \n").arg(getWebsite("https://ihavea.quest")); + stream << QString("

    timoreo %1

    \n").arg(getGitHub("timoreo22")); + stream << QString("

    Ezekiel Smith (ZekeSmith) %1

    \n").arg(getGitHub("ZekeSmith")); + stream << QString("

    cozyGalvinism %1

    \n").arg(getGitHub("cozyGalvinism")); + stream << QString("

    DioEgizio %1

    \n").arg(getGitHub("DioEgizio")); + stream << QString("

    flowln %1

    \n").arg(getGitHub("flowln")); + stream << QString("

    ViRb3 %1

    \n").arg(getGitHub("ViRb3")); + stream << QString("

    Rachel Powers (Ryex) %1

    \n").arg(getGitHub("Ryex")); + stream << QString("

    TayouVR %1

    \n").arg(getGitHub("TayouVR")); + stream << QString("

    TheKodeToad %1

    \n").arg(getGitHub("TheKodeToad")); + stream << QString("

    getchoo %1

    \n").arg(getGitHub("getchoo")); stream << "
    \n"; // TODO: possibly retrieve from git history at build time? @@ -96,20 +98,21 @@ QString getCreditsHtml() stream << "
    \n"; stream << "

    " << QObject::tr("With thanks to", "About Credits") << "

    \n"; - stream << QString("

    Boba %1

    \n") .arg(getWebsite("https://bobaonline.neocities.org/")); - stream << QString("

    Davi Rafael %1

    \n") .arg(getWebsite("https://auti.one/")); - stream << QString("

    Fulmine %1

    \n") .arg(getWebsite("https://www.fulmine.xyz/")); - stream << QString("

    ely %1

    \n") .arg(getGitHub("elyrodso")); - stream << QString("

    gon sawa %1

    \n") .arg(getGitHub("gonsawa")); + stream << QString("

    Boba %1

    \n").arg(getWebsite("https://bobaonline.neocities.org/")); + stream << QString("

    Davi Rafael %1

    \n").arg(getWebsite("https://auti.one/")); + stream << QString("

    Fulmine %1

    \n").arg(getWebsite("https://www.fulmine.xyz/")); + stream << QString("

    ely %1

    \n").arg(getGitHub("elyrodso")); + stream << QString("

    gon sawa %1

    \n").arg(getGitHub("gonsawa")); stream << QString("

    Pankakes

    \n"); - stream << QString("

    tobimori %1

    \n") .arg(getGitHub("tobimori")); + stream << QString("

    tobimori %1

    \n").arg(getGitHub("tobimori")); stream << "

    Orochimarufan <orochimarufan.x3@gmail.com>

    \n"; stream << "

    TakSuyu <taksuyu@gmail.com>

    \n"; stream << "

    Kilobyte <stiepen22@gmx.de>

    \n"; stream << "

    Rootbear75 <@rootbear75>

    \n"; stream << "

    Zeker Zhayard <@Zeker_Zhayard>

    \n"; stream << "

    Everyone who helped establish our branding!

    \n"; - stream << "

    And everyone else who contributed!

    \n"; + stream + << "

    And everyone else who contributed!

    \n"; stream << "
    \n"; stream << "\n"; @@ -124,9 +127,9 @@ QString getLicenseHtml() return output; } -} +} // namespace -AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) +AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { ui->setupUi(this); @@ -148,7 +151,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->versionLabel->setText(BuildConfig.printableVersionString()); if (!BuildConfig.BUILD_PLATFORM.isEmpty()) - ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM); + ui->platformLabel->setText(tr("Platform") + ": " + BuildConfig.BUILD_PLATFORM); else ui->platformLabel->setVisible(false); @@ -163,7 +166,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->buildDateLabel->setVisible(false); if (!BuildConfig.VERSION_CHANNEL.isEmpty()) - ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL); + ui->channelLabel->setText(tr("Channel") + ": " + BuildConfig.VERSION_CHANNEL); else ui->channelLabel->setVisible(false); diff --git a/launcher/ui/dialogs/AboutDialog.h b/launcher/ui/dialogs/AboutDialog.h index 814fd98c6..356f005e0 100644 --- a/launcher/ui/dialogs/AboutDialog.h +++ b/launcher/ui/dialogs/AboutDialog.h @@ -15,26 +15,23 @@ #pragma once -#include #include +#include -namespace Ui -{ +namespace Ui { class AboutDialog; } -class AboutDialog : public QDialog -{ +class AboutDialog : public QDialog { Q_OBJECT -public: - explicit AboutDialog(QWidget *parent = 0); + public: + explicit AboutDialog(QWidget* parent = 0); ~AboutDialog(); -private: - Ui::AboutDialog *ui; + private: + Ui::AboutDialog* ui; NetJob::Ptr netJob; QByteArray dataSink; }; - diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index fdfae5973..727c06148 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -313,7 +313,7 @@ bool BlockedModsDialog::checkValidPath(QString path) // efectivly compare two strings ignoring all separators and case auto laxCompare = [](QString fsfilename, QString metadataFilename) { // allowed character seperators - QList allowedSeperators = { '-', '+', '.' , '_'}; + QList allowedSeperators = { '-', '+', '.', '_' }; // copy in lowercase auto fsName = fsfilename.toLower(); diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index d75bb5fe3..eac5721e0 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -107,8 +107,8 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget* parent) #if defined(Q_OS_WIN) ui->symbolicLinksCheckbox->setIcon(style()->standardIcon(QStyle::SP_VistaShield)); - ui->symbolicLinksCheckbox->setToolTip(tr("Use symbolic links instead of copying files.") + - "\n" + tr("On Windows, symbolic links may require admin permission to create.")); + ui->symbolicLinksCheckbox->setToolTip(tr("Use symbolic links instead of copying files.") + "\n" + + tr("On Windows, symbolic links may require admin permission to create.")); #endif updateLinkOptions(); diff --git a/launcher/ui/dialogs/CustomMessageBox.cpp b/launcher/ui/dialogs/CustomMessageBox.cpp index 19029f682..1af47a449 100644 --- a/launcher/ui/dialogs/CustomMessageBox.cpp +++ b/launcher/ui/dialogs/CustomMessageBox.cpp @@ -15,13 +15,15 @@ #include "CustomMessageBox.h" -namespace CustomMessageBox -{ -QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, - QMessageBox::Icon icon, QMessageBox::StandardButtons buttons, +namespace CustomMessageBox { +QMessageBox* selectable(QWidget* parent, + const QString& title, + const QString& text, + QMessageBox::Icon icon, + QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) { - QMessageBox *messageBox = new QMessageBox(parent); + QMessageBox* messageBox = new QMessageBox(parent); messageBox->setWindowTitle(title); messageBox->setText(text); messageBox->setStandardButtons(buttons); @@ -32,4 +34,4 @@ QMessageBox *selectable(QWidget *parent, const QString &title, const QString &te return messageBox; } -} +} // namespace CustomMessageBox diff --git a/launcher/ui/dialogs/CustomMessageBox.h b/launcher/ui/dialogs/CustomMessageBox.h index 712c65186..a9bc6a24a 100644 --- a/launcher/ui/dialogs/CustomMessageBox.h +++ b/launcher/ui/dialogs/CustomMessageBox.h @@ -17,9 +17,10 @@ #include -namespace CustomMessageBox -{ -QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, +namespace CustomMessageBox { +QMessageBox* selectable(QWidget* parent, + const QString& title, + const QString& text, QMessageBox::Icon icon = QMessageBox::NoIcon, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); diff --git a/launcher/ui/dialogs/EditAccountDialog.cpp b/launcher/ui/dialogs/EditAccountDialog.cpp index 002c064b4..58036fd82 100644 --- a/launcher/ui/dialogs/EditAccountDialog.cpp +++ b/launcher/ui/dialogs/EditAccountDialog.cpp @@ -14,12 +14,11 @@ */ #include "EditAccountDialog.h" -#include "ui_EditAccountDialog.h" #include #include +#include "ui_EditAccountDialog.h" -EditAccountDialog::EditAccountDialog(const QString &text, QWidget *parent, int flags) - : QDialog(parent), ui(new Ui::EditAccountDialog) +EditAccountDialog::EditAccountDialog(const QString& text, QWidget* parent, int flags) : QDialog(parent), ui(new Ui::EditAccountDialog) { ui->setupUi(this); @@ -35,12 +34,12 @@ EditAccountDialog::~EditAccountDialog() delete ui; } -void EditAccountDialog::on_label_linkActivated(const QString &link) +void EditAccountDialog::on_label_linkActivated(const QString& link) { DesktopServices::openUrl(QUrl(link)); } -void EditAccountDialog::setUsername(const QString & user) const +void EditAccountDialog::setUsername(const QString& user) const { ui->userTextBox->setText(user); } @@ -50,7 +49,7 @@ QString EditAccountDialog::username() const return ui->userTextBox->text(); } -void EditAccountDialog::setPassword(const QString & pass) const +void EditAccountDialog::setPassword(const QString& pass) const { ui->passTextBox->setText(pass); } diff --git a/launcher/ui/dialogs/EditAccountDialog.h b/launcher/ui/dialogs/EditAccountDialog.h index 6b5eb4aa9..7a9ccba79 100644 --- a/launcher/ui/dialogs/EditAccountDialog.h +++ b/launcher/ui/dialogs/EditAccountDialog.h @@ -17,28 +17,24 @@ #include -namespace Ui -{ +namespace Ui { class EditAccountDialog; } -class EditAccountDialog : public QDialog -{ +class EditAccountDialog : public QDialog { Q_OBJECT -public: - explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0, - int flags = UsernameField | PasswordField); + public: + explicit EditAccountDialog(const QString& text = "", QWidget* parent = 0, int flags = UsernameField | PasswordField); ~EditAccountDialog(); - void setUsername(const QString & user) const; - void setPassword(const QString & pass) const; + void setUsername(const QString& user) const; + void setPassword(const QString& pass) const; QString username() const; QString password() const; - enum Flags - { + enum Flags { NoFlags = 0, //! Specifies that the dialog should have a username field. @@ -48,9 +44,9 @@ public: PasswordField, }; -private slots: - void on_label_linkActivated(const QString &link); + private slots: + void on_label_linkActivated(const QString& link); -private: - Ui::EditAccountDialog *ui; + private: + Ui::EditAccountDialog* ui; }; diff --git a/launcher/ui/dialogs/IconPickerDialog.cpp b/launcher/ui/dialogs/IconPickerDialog.cpp index 5131686af..faad3ce75 100644 --- a/launcher/ui/dialogs/IconPickerDialog.cpp +++ b/launcher/ui/dialogs/IconPickerDialog.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ +#include #include #include -#include #include "Application.h" @@ -24,12 +24,11 @@ #include "ui/instanceview/InstanceDelegate.h" +#include #include "icons/IconList.h" #include "icons/IconUtils.h" -#include -IconPickerDialog::IconPickerDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::IconPickerDialog) +IconPickerDialog::IconPickerDialog(QWidget* parent) : QDialog(parent), ui(new Ui::IconPickerDialog) { ui->setupUi(this); setWindowModality(Qt::WindowModal); @@ -69,31 +68,30 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex))); - connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection))); + connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + SLOT(selectionChanged(QItemSelection, QItemSelection))); auto buttonFolder = ui->buttonBox->addButton(tr("Open Folder"), QDialogButtonBox::ResetRole); connect(buttonFolder, &QPushButton::clicked, this, &IconPickerDialog::openFolder); } -bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt) +bool IconPickerDialog::eventFilter(QObject* obj, QEvent* evt) { if (obj != ui->iconView) return QDialog::eventFilter(obj, evt); - if (evt->type() != QEvent::KeyPress) - { + if (evt->type() != QEvent::KeyPress) { return QDialog::eventFilter(obj, evt); } - QKeyEvent *keyEvent = static_cast(evt); - switch (keyEvent->key()) - { - case Qt::Key_Delete: - removeSelectedIcon(); - return true; - case Qt::Key_Plus: - addNewIcon(); - return true; - default: - break; + QKeyEvent* keyEvent = static_cast(evt); + switch (keyEvent->key()) { + case Qt::Key_Delete: + removeSelectedIcon(); + return true; + case Qt::Key_Plus: + addNewIcon(); + return true; + default: + break; } return QDialog::eventFilter(obj, evt); } @@ -142,8 +140,7 @@ int IconPickerDialog::execWithSelection(QString selection) int index_nr = list->getIconIndex(selection); auto model_index = list->index(index_nr); - contentsWidget->selectionModel()->select( - model_index, QItemSelectionModel::Current | QItemSelectionModel::Select); + contentsWidget->selectionModel()->select(model_index, QItemSelectionModel::Current | QItemSelectionModel::Select); QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection, Q_ARG(QModelIndex, model_index)); return QDialog::exec(); diff --git a/launcher/ui/dialogs/IconPickerDialog.h b/launcher/ui/dialogs/IconPickerDialog.h index c93f565f1..37e53dcce 100644 --- a/launcher/ui/dialogs/IconPickerDialog.h +++ b/launcher/ui/dialogs/IconPickerDialog.h @@ -17,30 +17,27 @@ #include #include -namespace Ui -{ +namespace Ui { class IconPickerDialog; } -class IconPickerDialog : public QDialog -{ +class IconPickerDialog : public QDialog { Q_OBJECT -public: - explicit IconPickerDialog(QWidget *parent = 0); + public: + explicit IconPickerDialog(QWidget* parent = 0); ~IconPickerDialog(); int execWithSelection(QString selection); QString selectedIconKey; -protected: - virtual bool eventFilter(QObject *, QEvent *); + protected: + virtual bool eventFilter(QObject*, QEvent*); -private: - Ui::IconPickerDialog *ui; - QPushButton *buttonRemove; + private: + Ui::IconPickerDialog* ui; + QPushButton* buttonRemove; -private -slots: + private slots: void selectionChanged(QItemSelection, QItemSelection); void activated(QModelIndex); void delayed_scroll(QModelIndex); diff --git a/launcher/ui/dialogs/ImportResourceDialog.h b/launcher/ui/dialogs/ImportResourceDialog.h index 5f2f7a92e..bbde1ba7b 100644 --- a/launcher/ui/dialogs/ImportResourceDialog.h +++ b/launcher/ui/dialogs/ImportResourceDialog.h @@ -17,7 +17,7 @@ class ImportResourceDialog : public QDialog { explicit ImportResourceDialog(QString file_path, PackedResourceType type, QWidget* parent = nullptr); ~ImportResourceDialog() override; QString selectedInstanceKey; - + private: Ui::ImportResourceDialog* ui; PackedResourceType m_resource_type; diff --git a/launcher/ui/dialogs/LoginDialog.cpp b/launcher/ui/dialogs/LoginDialog.cpp index 30394b725..7296a13ef 100644 --- a/launcher/ui/dialogs/LoginDialog.cpp +++ b/launcher/ui/dialogs/LoginDialog.cpp @@ -20,7 +20,7 @@ #include -LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LoginDialog) +LoginDialog::LoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::LoginDialog) { ui->setupUi(this); ui->progressBar->setVisible(false); @@ -59,27 +59,24 @@ void LoginDialog::setUserInputsEnabled(bool enable) } // Enable the OK button only when both textboxes contain something. -void LoginDialog::on_userTextBox_textEdited(const QString &newText) +void LoginDialog::on_userTextBox_textEdited(const QString& newText) { - ui->buttonBox->button(QDialogButtonBox::Ok) - ->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty()); } -void LoginDialog::on_passTextBox_textEdited(const QString &newText) +void LoginDialog::on_passTextBox_textEdited(const QString& newText) { - ui->buttonBox->button(QDialogButtonBox::Ok) - ->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty()); } -void LoginDialog::onTaskFailed(const QString &reason) +void LoginDialog::onTaskFailed(const QString& reason) { // Set message auto lines = reason.split('\n'); QString processed; - for(auto line: lines) { - if(line.size()) { + for (auto line : lines) { + if (line.size()) { processed += "" + line + "
    "; - } - else { + } else { processed += "
    "; } } @@ -95,7 +92,7 @@ void LoginDialog::onTaskSucceeded() QDialog::accept(); } -void LoginDialog::onTaskStatus(const QString &status) +void LoginDialog::onTaskStatus(const QString& status) { ui->label->setText(status); } @@ -107,12 +104,11 @@ void LoginDialog::onTaskProgress(qint64 current, qint64 total) } // Public interface -MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg) +MinecraftAccountPtr LoginDialog::newAccount(QWidget* parent, QString msg) { LoginDialog dlg(parent); dlg.ui->label->setText(msg); - if (dlg.exec() == QDialog::Accepted) - { + if (dlg.exec() == QDialog::Accepted) { return dlg.m_account; } return nullptr; diff --git a/launcher/ui/dialogs/LoginDialog.h b/launcher/ui/dialogs/LoginDialog.h index f8101ff57..601b5fa77 100644 --- a/launcher/ui/dialogs/LoginDialog.h +++ b/launcher/ui/dialogs/LoginDialog.h @@ -15,45 +15,42 @@ #pragma once -#include #include +#include #include "minecraft/auth/MinecraftAccount.h" #include "tasks/Task.h" -namespace Ui -{ +namespace Ui { class LoginDialog; } -class LoginDialog : public QDialog -{ +class LoginDialog : public QDialog { Q_OBJECT -public: + public: ~LoginDialog(); - static MinecraftAccountPtr newAccount(QWidget *parent, QString message); + static MinecraftAccountPtr newAccount(QWidget* parent, QString message); -private: - explicit LoginDialog(QWidget *parent = 0); + private: + explicit LoginDialog(QWidget* parent = 0); void setUserInputsEnabled(bool enable); -protected -slots: + protected slots: void accept(); - void onTaskFailed(const QString &reason); + void onTaskFailed(const QString& reason); void onTaskSucceeded(); - void onTaskStatus(const QString &status); + void onTaskStatus(const QString& status); void onTaskProgress(qint64 current, qint64 total); - void on_userTextBox_textEdited(const QString &newText); - void on_passTextBox_textEdited(const QString &newText); + void on_userTextBox_textEdited(const QString& newText); + void on_passTextBox_textEdited(const QString& newText); -private: - Ui::LoginDialog *ui; + private: + Ui::LoginDialog* ui; MinecraftAccountPtr m_account; Task::Ptr m_loginTask; }; diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp index be49babba..f8aab34d9 100644 --- a/launcher/ui/dialogs/MSALoginDialog.cpp +++ b/launcher/ui/dialogs/MSALoginDialog.cpp @@ -39,12 +39,12 @@ #include "DesktopServices.h" #include "minecraft/auth/AccountTask.h" -#include -#include #include #include +#include +#include -MSALoginDialog::MSALoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MSALoginDialog) +MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MSALoginDialog) { ui->setupUi(this); ui->progressBar->setVisible(false); @@ -55,7 +55,8 @@ MSALoginDialog::MSALoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MS connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } -int MSALoginDialog::exec() { +int MSALoginDialog::exec() +{ setUserInputsEnabled(false); ui->progressBar->setVisible(true); @@ -74,24 +75,24 @@ int MSALoginDialog::exec() { return QDialog::exec(); } - MSALoginDialog::~MSALoginDialog() { delete ui; } -void MSALoginDialog::externalLoginTick() { +void MSALoginDialog::externalLoginTick() +{ m_externalLoginElapsed++; ui->progressBar->setValue(m_externalLoginElapsed); ui->progressBar->repaint(); - if(m_externalLoginElapsed >= m_externalLoginTimeout) { + if (m_externalLoginElapsed >= m_externalLoginTimeout) { m_externalLoginTimer.stop(); } } - -void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn) { +void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn) +{ m_externalLoginElapsed = 0; m_externalLoginTimeout = expiresIn; @@ -104,7 +105,8 @@ void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& QString urlString = uri.toString(); QString linkString = QString("%2").arg(urlString, urlString); - ui->label->setText(tr("

    Please open up %1 in a browser and put in the code %2 to proceed with login.

    ").arg(linkString, code)); + ui->label->setText( + tr("

    Please open up %1 in a browser and put in the code %2 to proceed with login.

    ").arg(linkString, code)); ui->actionButton->setVisible(true); connect(ui->actionButton, &QPushButton::clicked, [=]() { DesktopServices::openUrl(uri); @@ -113,7 +115,8 @@ void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& }); } -void MSALoginDialog::hideVerificationUriAndCode() { +void MSALoginDialog::hideVerificationUriAndCode() +{ m_externalLoginTimer.stop(); ui->actionButton->setVisible(false); } @@ -123,16 +126,15 @@ void MSALoginDialog::setUserInputsEnabled(bool enable) ui->buttonBox->setEnabled(enable); } -void MSALoginDialog::onTaskFailed(const QString &reason) +void MSALoginDialog::onTaskFailed(const QString& reason) { // Set message auto lines = reason.split('\n'); QString processed; - for(auto line: lines) { - if(line.size()) { + for (auto line : lines) { + if (line.size()) { processed += "" + line + "
    "; - } - else { + } else { processed += "
    "; } } @@ -149,7 +151,7 @@ void MSALoginDialog::onTaskSucceeded() QDialog::accept(); } -void MSALoginDialog::onTaskStatus(const QString &status) +void MSALoginDialog::onTaskStatus(const QString& status) { ui->label->setText(status); } @@ -161,12 +163,11 @@ void MSALoginDialog::onTaskProgress(qint64 current, qint64 total) } // Public interface -MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg) +MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent, QString msg) { MSALoginDialog dlg(parent); dlg.ui->label->setText(msg); - if (dlg.exec() == QDialog::Accepted) - { + if (dlg.exec() == QDialog::Accepted) { return dlg.m_account; } return nullptr; diff --git a/launcher/ui/dialogs/MSALoginDialog.h b/launcher/ui/dialogs/MSALoginDialog.h index 4cf146ab3..03e276bc0 100644 --- a/launcher/ui/dialogs/MSALoginDialog.h +++ b/launcher/ui/dialogs/MSALoginDialog.h @@ -15,49 +15,45 @@ #pragma once -#include -#include #include +#include +#include #include "minecraft/auth/MinecraftAccount.h" -namespace Ui -{ +namespace Ui { class MSALoginDialog; } -class MSALoginDialog : public QDialog -{ +class MSALoginDialog : public QDialog { Q_OBJECT -public: + public: ~MSALoginDialog(); - static MinecraftAccountPtr newAccount(QWidget *parent, QString message); + static MinecraftAccountPtr newAccount(QWidget* parent, QString message); int exec() override; -private: - explicit MSALoginDialog(QWidget *parent = 0); + private: + explicit MSALoginDialog(QWidget* parent = 0); void setUserInputsEnabled(bool enable); -protected -slots: - void onTaskFailed(const QString &reason); + protected slots: + void onTaskFailed(const QString& reason); void onTaskSucceeded(); - void onTaskStatus(const QString &status); + void onTaskStatus(const QString& status); void onTaskProgress(qint64 current, qint64 total); - void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); + void showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn); void hideVerificationUriAndCode(); void externalLoginTick(); -private: - Ui::MSALoginDialog *ui; + private: + Ui::MSALoginDialog* ui; MinecraftAccountPtr m_account; shared_qobject_ptr m_loginTask; QTimer m_externalLoginTimer; int m_externalLoginElapsed = 0; int m_externalLoginTimeout = 0; }; - diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 8618b9240..0af1ec59b 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -89,15 +89,17 @@ 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); } @@ -162,7 +164,7 @@ void ModUpdateDialog::checkCandidates() if (!recover_url.isEmpty()) //: %1 is the link to download it manually text += tr("Possible solution: Getting the latest version manually:
    %1
    ") - .arg(QString("%1").arg(recover_url.toString())); + .arg(QString("%1").arg(recover_url.toString())); text += "
    "; } @@ -342,7 +344,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R } else { QString reason{ tr("Couldn't find a valid version on the selected mod provider(s)") }; - m_failed_metadata.append({mod, reason}); + m_failed_metadata.append({ mod, reason }); } } diff --git a/launcher/ui/dialogs/ModUpdateDialog.h b/launcher/ui/dialogs/ModUpdateDialog.h index 1a92f6134..12dddf5e1 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.h +++ b/launcher/ui/dialogs/ModUpdateDialog.h @@ -36,7 +36,9 @@ class ModUpdateDialog final : public ReviewMessageBox { private slots: void onMetadataEnsured(Mod*); - void onMetadataFailed(Mod*, bool try_others = false, ModPlatform::ResourceProvider first_choice = ModPlatform::ResourceProvider::MODRINTH); + void onMetadataFailed(Mod*, + bool try_others = false, + ModPlatform::ResourceProvider first_choice = ModPlatform::ResourceProvider::MODRINTH); private: QWidget* m_parent; diff --git a/launcher/ui/dialogs/NewComponentDialog.cpp b/launcher/ui/dialogs/NewComponentDialog.cpp index ea790e8c2..0d90b02e3 100644 --- a/launcher/ui/dialogs/NewComponentDialog.cpp +++ b/launcher/ui/dialogs/NewComponentDialog.cpp @@ -33,28 +33,28 @@ * limitations under the License. */ -#include "Application.h" #include "NewComponentDialog.h" +#include "Application.h" #include "ui_NewComponentDialog.h" #include +#include #include #include -#include -#include "VersionSelectDialog.h" -#include "ProgressDialog.h" #include "IconPickerDialog.h" +#include "ProgressDialog.h" +#include "VersionSelectDialog.h" +#include #include #include -#include #include #include #include -NewComponentDialog::NewComponentDialog(const QString & initialName, const QString & initialUid, QWidget *parent) +NewComponentDialog::NewComponentDialog(const QString& initialName, const QString& initialUid, QWidget* parent) : QDialog(parent), ui(new Ui::NewComponentDialog) { ui->setupUi(this); @@ -81,12 +81,9 @@ void NewComponentDialog::updateDialogState() { auto protoUid = ui->nameTextBox->text().toLower(); protoUid.remove(QRegularExpression("[^a-z]")); - if(protoUid.isEmpty()) - { + if (protoUid.isEmpty()) { ui->uidTextBox->setPlaceholderText(originalPlaceholderText); - } - else - { + } else { QString suggestedUid = "org.multimc.custom." + protoUid; ui->uidTextBox->setPlaceholderText(suggestedUid); } @@ -97,8 +94,7 @@ void NewComponentDialog::updateDialogState() QString NewComponentDialog::name() const { auto result = ui->nameTextBox->text(); - if(result.size()) - { + if (result.size()) { return result.trimmed(); } return QString(); @@ -107,13 +103,11 @@ QString NewComponentDialog::name() const QString NewComponentDialog::uid() const { auto result = ui->uidTextBox->text(); - if(result.size()) - { + if (result.size()) { return result.trimmed(); } result = ui->uidTextBox->placeholderText(); - if(result.size() && result != originalPlaceholderText) - { + if (result.size() && result != originalPlaceholderText) { return result.trimmed(); } return QString(); diff --git a/launcher/ui/dialogs/NewComponentDialog.h b/launcher/ui/dialogs/NewComponentDialog.h index 8c790beb3..4fb68ff2f 100644 --- a/launcher/ui/dialogs/NewComponentDialog.h +++ b/launcher/ui/dialogs/NewComponentDialog.h @@ -20,28 +20,26 @@ #include #include -namespace Ui -{ +namespace Ui { class NewComponentDialog; } -class NewComponentDialog : public QDialog -{ +class NewComponentDialog : public QDialog { Q_OBJECT -public: - explicit NewComponentDialog(const QString & initialName = QString(), const QString & initialUid = QString(), QWidget *parent = 0); + public: + explicit NewComponentDialog(const QString& initialName = QString(), const QString& initialUid = QString(), QWidget* parent = 0); virtual ~NewComponentDialog(); void setBlacklist(QStringList badUids); QString name() const; QString uid() const; -private slots: + private slots: void updateDialogState(); -private: - Ui::NewComponentDialog *ui; + private: + Ui::NewComponentDialog* ui; QString originalPlaceholderText; QStringList uidBlacklist; diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index 76b139fc7..8fe4c38cd 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -87,15 +87,14 @@ NewInstanceDialog::NewInstanceDialog(const QString& initialGroup, const QString& groupList.push_front(""); ui->groupBox->addItems(groupList); int index = groupList.indexOf(initialGroup); - if(index == -1) - { + if (index == -1) { index = 0; } ui->groupBox->setCurrentIndex(index); ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); - - // NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not move this below. + // NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not + // move this below. m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel); m_container = new PageContainer(this, {}, this); @@ -122,8 +121,7 @@ NewInstanceDialog::NewInstanceDialog(const QString& initialGroup, const QString& HelpButton->setAutoDefault(false); connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help); - if(!url.isEmpty()) - { + if (!url.isEmpty()) { QUrl actualUrl(url); m_container->selectPage("import"); importPage->setUrl(url); @@ -155,9 +153,9 @@ void NewInstanceDialog::accept() QDialog::accept(); } -QList NewInstanceDialog::getPages() +QList NewInstanceDialog::getPages() { - QList pages; + QList pages; importPage = new ImportPage(this); @@ -216,17 +214,17 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, I m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK); } -void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QString &name) +void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QString& name) { importIcon = true; importIconPath = path; importIconName = name; - //Hmm, for some reason they can be to small + // Hmm, for some reason they can be to small ui->iconButton->setIcon(QIcon(path)); } -void NewInstanceDialog::setSuggestedIcon(const QString &key) +void NewInstanceDialog::setSuggestedIcon(const QString& key) { auto icon = APPLICATION->icons()->getIcon(key); importIcon = false; @@ -234,9 +232,9 @@ void NewInstanceDialog::setSuggestedIcon(const QString &key) ui->iconButton->setIcon(icon); } -InstanceTask * NewInstanceDialog::extractTask() +InstanceTask* NewInstanceDialog::extractTask() { - InstanceTask * extracted = creationTask.get(); + InstanceTask* extracted = creationTask.get(); creationTask.release(); InstanceName inst_name(ui->instNameTextBox->placeholderText().trimmed(), importVersion); @@ -252,8 +250,7 @@ void NewInstanceDialog::updateDialogState() { auto allowOK = creationTask && !instName().isEmpty(); auto OkButton = m_buttons->button(QDialogButtonBox::Ok); - if(OkButton->isEnabled() != allowOK) - { + if (OkButton->isEnabled() != allowOK) { OkButton->setEnabled(allowOK); } } @@ -261,13 +258,11 @@ void NewInstanceDialog::updateDialogState() QString NewInstanceDialog::instName() const { auto result = ui->instNameTextBox->text().trimmed(); - if(result.size()) - { + if (result.size()) { return result; } result = ui->instNameTextBox->placeholderText().trimmed(); - if(result.size()) - { + if (result.size()) { return result; } return QString(); @@ -284,26 +279,25 @@ QString NewInstanceDialog::iconKey() const void NewInstanceDialog::on_iconButton_clicked() { - importIconNow(); //so the user can switch back + importIconNow(); // so the user can switch back IconPickerDialog dlg(this); dlg.execWithSelection(InstIconKey); - if (dlg.result() == QDialog::Accepted) - { + if (dlg.result() == QDialog::Accepted) { InstIconKey = dlg.selectedIconKey; ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); importIcon = false; } } -void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) +void NewInstanceDialog::on_instNameTextBox_textChanged(const QString& arg1) { updateDialogState(); } void NewInstanceDialog::importIconNow() { - if(importIcon) { + if (importIcon) { APPLICATION->icons()->installIcon(importIconPath, importIconName); InstIconKey = importIconName; importIcon = false; diff --git a/launcher/ui/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h index 961f512e2..de054cf7a 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.h +++ b/launcher/ui/dialogs/NewInstanceDialog.h @@ -37,11 +37,10 @@ #include -#include "ui/pages/BasePageProvider.h" #include "InstanceTask.h" +#include "ui/pages/BasePageProvider.h" -namespace Ui -{ +namespace Ui { class NewInstanceDialog; } @@ -50,45 +49,44 @@ class QDialogButtonBox; class ImportPage; class FlamePage; -class NewInstanceDialog : public QDialog, public BasePageProvider -{ +class NewInstanceDialog : public QDialog, public BasePageProvider { Q_OBJECT -public: - explicit NewInstanceDialog(const QString & initialGroup, const QString & url = QString(), QWidget *parent = 0); + public: + explicit NewInstanceDialog(const QString& initialGroup, const QString& url = QString(), QWidget* parent = 0); ~NewInstanceDialog(); void updateDialogState(); - void setSuggestedPack(const QString& name = QString(), InstanceTask * task = nullptr); - void setSuggestedPack(const QString& name, QString version, InstanceTask * task = nullptr); - void setSuggestedIconFromFile(const QString &path, const QString &name); - void setSuggestedIcon(const QString &key); + void setSuggestedPack(const QString& name = QString(), InstanceTask* task = nullptr); + void setSuggestedPack(const QString& name, QString version, InstanceTask* task = nullptr); + void setSuggestedIconFromFile(const QString& path, const QString& name); + void setSuggestedIcon(const QString& key); - InstanceTask * extractTask(); + InstanceTask* extractTask(); QString dialogTitle() override; - QList getPages() override; + QList getPages() override; QString instName() const; QString instGroup() const; QString iconKey() const; -public slots: + public slots: void accept() override; void reject() override; -private slots: + private slots: void on_iconButton_clicked(); - void on_instNameTextBox_textChanged(const QString &arg1); + void on_instNameTextBox_textChanged(const QString& arg1); -private: - Ui::NewInstanceDialog *ui = nullptr; - PageContainer * m_container = nullptr; - QDialogButtonBox * m_buttons = nullptr; + private: + Ui::NewInstanceDialog* ui = nullptr; + PageContainer* m_container = nullptr; + QDialogButtonBox* m_buttons = nullptr; QString InstIconKey; - ImportPage *importPage = nullptr; + ImportPage* importPage = nullptr; std::unique_ptr creationTask; bool importIcon = false; diff --git a/launcher/ui/dialogs/OfflineLoginDialog.cpp b/launcher/ui/dialogs/OfflineLoginDialog.cpp index a69537abb..137620be4 100644 --- a/launcher/ui/dialogs/OfflineLoginDialog.cpp +++ b/launcher/ui/dialogs/OfflineLoginDialog.cpp @@ -5,7 +5,7 @@ #include -OfflineLoginDialog::OfflineLoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::OfflineLoginDialog) +OfflineLoginDialog::OfflineLoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::OfflineLoginDialog) { ui->setupUi(this); ui->progressBar->setVisible(false); @@ -52,22 +52,20 @@ void OfflineLoginDialog::on_allowLongUsernames_stateChanged(int value) } // Enable the OK button only when the textbox contains something. -void OfflineLoginDialog::on_userTextBox_textEdited(const QString &newText) +void OfflineLoginDialog::on_userTextBox_textEdited(const QString& newText) { - ui->buttonBox->button(QDialogButtonBox::Ok) - ->setEnabled(!newText.isEmpty()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty()); } -void OfflineLoginDialog::onTaskFailed(const QString &reason) +void OfflineLoginDialog::onTaskFailed(const QString& reason) { // Set message auto lines = reason.split('\n'); QString processed; - for(auto line: lines) { - if(line.size()) { + for (auto line : lines) { + if (line.size()) { processed += "" + line + "
    "; - } - else { + } else { processed += "
    "; } } @@ -83,7 +81,7 @@ void OfflineLoginDialog::onTaskSucceeded() QDialog::accept(); } -void OfflineLoginDialog::onTaskStatus(const QString &status) +void OfflineLoginDialog::onTaskStatus(const QString& status) { ui->label->setText(status); } @@ -95,12 +93,11 @@ void OfflineLoginDialog::onTaskProgress(qint64 current, qint64 total) } // Public interface -MinecraftAccountPtr OfflineLoginDialog::newAccount(QWidget *parent, QString msg) +MinecraftAccountPtr OfflineLoginDialog::newAccount(QWidget* parent, QString msg) { OfflineLoginDialog dlg(parent); dlg.ui->label->setText(msg); - if (dlg.exec() == QDialog::Accepted) - { + if (dlg.exec() == QDialog::Accepted) { return dlg.m_account; } return nullptr; diff --git a/launcher/ui/dialogs/OfflineLoginDialog.h b/launcher/ui/dialogs/OfflineLoginDialog.h index fdb3d91fa..a50024a6c 100644 --- a/launcher/ui/dialogs/OfflineLoginDialog.h +++ b/launcher/ui/dialogs/OfflineLoginDialog.h @@ -1,44 +1,41 @@ #pragma once -#include #include +#include #include "minecraft/auth/MinecraftAccount.h" #include "tasks/Task.h" -namespace Ui -{ +namespace Ui { class OfflineLoginDialog; } -class OfflineLoginDialog : public QDialog -{ +class OfflineLoginDialog : public QDialog { Q_OBJECT -public: + public: ~OfflineLoginDialog(); - static MinecraftAccountPtr newAccount(QWidget *parent, QString message); + static MinecraftAccountPtr newAccount(QWidget* parent, QString message); -private: - explicit OfflineLoginDialog(QWidget *parent = 0); + private: + explicit OfflineLoginDialog(QWidget* parent = 0); void setUserInputsEnabled(bool enable); -protected -slots: + protected slots: void accept(); - void onTaskFailed(const QString &reason); + void onTaskFailed(const QString& reason); void onTaskSucceeded(); - void onTaskStatus(const QString &status); + void onTaskStatus(const QString& status); void onTaskProgress(qint64 current, qint64 total); - void on_userTextBox_textEdited(const QString &newText); + void on_userTextBox_textEdited(const QString& newText); void on_allowLongUsernames_stateChanged(int value); -private: - Ui::OfflineLoginDialog *ui; + private: + Ui::OfflineLoginDialog* ui; MinecraftAccountPtr m_account; Task::Ptr m_loginTask; }; diff --git a/launcher/ui/dialogs/ProfileSelectDialog.cpp b/launcher/ui/dialogs/ProfileSelectDialog.cpp index 7882cf45e..a62238bdb 100644 --- a/launcher/ui/dialogs/ProfileSelectDialog.cpp +++ b/launcher/ui/dialogs/ProfileSelectDialog.cpp @@ -16,43 +16,38 @@ #include "ProfileSelectDialog.h" #include "ui_ProfileSelectDialog.h" -#include #include +#include -#include "SkinUtils.h" #include "Application.h" +#include "SkinUtils.h" #include "ui/dialogs/ProgressDialog.h" -ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent) +ProfileSelectDialog::ProfileSelectDialog(const QString& message, int flags, QWidget* parent) : QDialog(parent), ui(new Ui::ProfileSelectDialog) { ui->setupUi(this); m_accounts = APPLICATION->accounts(); auto view = ui->listView; - //view->setModel(m_accounts.get()); - //view->hideColumn(AccountList::ActiveColumn); + // view->setModel(m_accounts.get()); + // view->hideColumn(AccountList::ActiveColumn); view->setColumnCount(1); view->setRootIsDecorated(false); // FIXME: use a real model, not this - if(QTreeWidgetItem* header = view->headerItem()) - { + if (QTreeWidgetItem* header = view->headerItem()) { header->setText(0, tr("Name")); - } - else - { + } else { view->setHeaderLabel(tr("Name")); } - QList items; - for (int i = 0; i < m_accounts->count(); i++) - { + QList items; + for (int i = 0; i < m_accounts->count(); i++) { MinecraftAccountPtr account = m_accounts->at(i); QString profileLabel; - if(account->isInUse()) { + if (account->isInUse()) { profileLabel = tr("%1 (in use)").arg(account->profileName()); - } - else { + } else { profileLabel = account->profileName(); } auto item = new QTreeWidgetItem(view); @@ -101,8 +96,7 @@ bool ProfileSelectDialog::useAsInstDefaullt() const void ProfileSelectDialog::on_buttonBox_accepted() { QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { + if (selection.size() > 0) { QModelIndex selected = selection.first(); m_selected = selected.data(AccountList::PointerRole).value(); } diff --git a/launcher/ui/dialogs/ProfileSelectDialog.h b/launcher/ui/dialogs/ProfileSelectDialog.h index 38aa42496..e56ba0527 100644 --- a/launcher/ui/dialogs/ProfileSelectDialog.h +++ b/launcher/ui/dialogs/ProfileSelectDialog.h @@ -21,17 +21,14 @@ #include "minecraft/auth/AccountList.h" -namespace Ui -{ +namespace Ui { class ProfileSelectDialog; } -class ProfileSelectDialog : public QDialog -{ +class ProfileSelectDialog : public QDialog { Q_OBJECT -public: - enum Flags - { + public: + enum Flags { NoFlags = 0, /*! @@ -52,7 +49,7 @@ public: * Constructs a new account select dialog with the given parent and message. * The message will be shown at the top of the dialog. It is an empty string by default. */ - explicit ProfileSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0); + explicit ProfileSelectDialog(const QString& message = "", int flags = 0, QWidget* parent = 0); ~ProfileSelectDialog(); /*! @@ -73,18 +70,17 @@ public: */ bool useAsInstDefaullt() const; -public -slots: + public slots: void on_buttonBox_accepted(); void on_buttonBox_rejected(); -protected: + protected: shared_qobject_ptr m_accounts; //! The account that was selected when the user clicked OK. MinecraftAccountPtr m_selected; -private: - Ui::ProfileSelectDialog *ui; + private: + Ui::ProfileSelectDialog* ui; }; diff --git a/launcher/ui/dialogs/ProfileSetupDialog.cpp b/launcher/ui/dialogs/ProfileSetupDialog.cpp index 64c0b924c..e203269c3 100644 --- a/launcher/ui/dialogs/ProfileSetupDialog.cpp +++ b/launcher/ui/dialogs/ProfileSetupDialog.cpp @@ -36,11 +36,11 @@ #include "ProfileSetupDialog.h" #include "ui_ProfileSetupDialog.h" -#include #include -#include -#include #include +#include +#include +#include #include "ui/dialogs/ProgressDialog.h" @@ -48,8 +48,7 @@ #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" - -ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent) +ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget* parent) : QDialog(parent), m_accountToSetup(accountToSetup), ui(new Ui::ProfileSetupDialog) { ui->setupUi(this); @@ -91,13 +90,11 @@ void ProfileSetupDialog::setNameStatus(ProfileSetupDialog::NameStatus status, QS { nameStatus = status; auto okButton = ui->buttonBox->button(QDialogButtonBox::Ok); - switch(nameStatus) - { + switch (nameStatus) { case NameStatus::Available: { validityAction->setIcon(goodIcon); okButton->setEnabled(true); - } - break; + } break; case NameStatus::NotSet: case NameStatus::Pending: validityAction->setIcon(yellowIcon); @@ -109,43 +106,44 @@ void ProfileSetupDialog::setNameStatus(ProfileSetupDialog::NameStatus status, QS okButton->setEnabled(false); break; } - if(!errorString.isEmpty()) { + if (!errorString.isEmpty()) { ui->errorLabel->setText(errorString); ui->errorLabel->setVisible(true); - } - else { + } else { ui->errorLabel->setVisible(false); } } void ProfileSetupDialog::nameEdited(const QString& name) { - if(!ui->nameEdit->hasAcceptableInput()) { + if (!ui->nameEdit->hasAcceptableInput()) { setNameStatus(NameStatus::NotSet, tr("Name is too short - must be between 3 and 16 characters long.")); return; } scheduleCheck(name); } -void ProfileSetupDialog::scheduleCheck(const QString& name) { +void ProfileSetupDialog::scheduleCheck(const QString& name) +{ queuedCheck = name; setNameStatus(NameStatus::Pending); checkStartTimer.start(1000); } -void ProfileSetupDialog::startCheck() { - if(isChecking) { +void ProfileSetupDialog::startCheck() +{ + if (isChecking) { return; } - if(queuedCheck.isNull()) { + if (queuedCheck.isNull()) { return; } checkName(queuedCheck); } - -void ProfileSetupDialog::checkName(const QString &name) { - if(isChecking) { +void ProfileSetupDialog::checkName(const QString& name) +{ + if (isChecking) { return; } @@ -160,44 +158,38 @@ void ProfileSetupDialog::checkName(const QString &name) { request.setRawHeader("Accept", "application/json"); request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8()); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::checkFinished); requestor->get(request); } -void ProfileSetupDialog::checkFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void ProfileSetupDialog::checkFinished(QNetworkReply::NetworkError error, QByteArray data, QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); - if(error == QNetworkReply::NoError) { + if (error == QNetworkReply::NoError) { auto doc = QJsonDocument::fromJson(data); auto root = doc.object(); auto statusValue = root.value("status").toString("INVALID"); - if(statusValue == "AVAILABLE") { + if (statusValue == "AVAILABLE") { setNameStatus(NameStatus::Available); - } - else if (statusValue == "DUPLICATE") { + } else if (statusValue == "DUPLICATE") { setNameStatus(NameStatus::Exists, tr("Minecraft profile with name %1 already exists.").arg(currentCheck)); - } - else if (statusValue == "NOT_ALLOWED") { + } else if (statusValue == "NOT_ALLOWED") { setNameStatus(NameStatus::Exists, tr("The name %1 is not allowed.").arg(currentCheck)); - } - else { + } else { setNameStatus(NameStatus::Error, tr("Unhandled profile name status: %1").arg(statusValue)); } - } - else { + } else { setNameStatus(NameStatus::Error, tr("Failed to check name availability.")); } isChecking = false; } -void ProfileSetupDialog::setupProfile(const QString &profileName) { - if(isWorking) { +void ProfileSetupDialog::setupProfile(const QString& profileName) +{ + if (isWorking) { return; } @@ -212,7 +204,7 @@ void ProfileSetupDialog::setupProfile(const QString &profileName) { QString payloadTemplate("{\"profileName\":\"%1\"}"); auto data = payloadTemplate.arg(profileName).toUtf8(); - AuthRequest *requestor = new AuthRequest(this); + AuthRequest* requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::setupProfileFinished); requestor->post(request, data); isWorking = true; @@ -223,8 +215,9 @@ void ProfileSetupDialog::setupProfile(const QString &profileName) { namespace { -struct MojangError{ - static MojangError fromJSON(QByteArray data) { +struct MojangError { + static MojangError fromJSON(QByteArray data) + { MojangError out; out.error = QString::fromUtf8(data); auto doc = QJsonDocument::fromJson(data, &out.parseError); @@ -247,25 +240,23 @@ struct MojangError{ QString errorMessage; }; -} +} // namespace -void ProfileSetupDialog::setupProfileFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers -) { - auto requestor = qobject_cast(QObject::sender()); +void ProfileSetupDialog::setupProfileFinished(QNetworkReply::NetworkError error, + QByteArray data, + QList headers) +{ + auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); isWorking = false; - if(error == QNetworkReply::NoError) { + if (error == QNetworkReply::NoError) { /* * data contains the profile in the response * ... we could parse it and update the account, but let's just return back to the normal login flow instead... */ accept(); - } - else { + } else { auto parsedError = MojangError::fromJSON(data); ui->errorLabel->setVisible(true); ui->errorLabel->setText(tr("The server returned the following error:") + "\n\n" + parsedError.errorMessage); diff --git a/launcher/ui/dialogs/ProfileSetupDialog.h b/launcher/ui/dialogs/ProfileSetupDialog.h index 6f413ebdf..09f8124e2 100644 --- a/launcher/ui/dialogs/ProfileSetupDialog.h +++ b/launcher/ui/dialogs/ProfileSetupDialog.h @@ -17,65 +17,48 @@ #include #include -#include #include +#include -#include #include +#include -namespace Ui -{ +namespace Ui { class ProfileSetupDialog; } -class ProfileSetupDialog : public QDialog -{ +class ProfileSetupDialog : public QDialog { Q_OBJECT -public: - - explicit ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent = 0); + public: + explicit ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget* parent = 0); ~ProfileSetupDialog(); - enum class NameStatus - { - NotSet, - Pending, - Available, - Exists, - Error - } nameStatus = NameStatus::NotSet; + enum class NameStatus { NotSet, Pending, Available, Exists, Error } nameStatus = NameStatus::NotSet; -private slots: + private slots: void on_buttonBox_accepted(); void on_buttonBox_rejected(); - void nameEdited(const QString &name); - void checkFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers - ); + void nameEdited(const QString& name); + void checkFinished(QNetworkReply::NetworkError error, QByteArray data, QList headers); void startCheck(); - void setupProfileFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList headers - ); -protected: - void scheduleCheck(const QString &name); - void checkName(const QString &name); + void setupProfileFinished(QNetworkReply::NetworkError error, QByteArray data, QList headers); + + protected: + void scheduleCheck(const QString& name); + void checkName(const QString& name); void setNameStatus(NameStatus status, QString errorString); - void setupProfile(const QString & profileName); + void setupProfile(const QString& profileName); -private: + private: MinecraftAccountPtr m_accountToSetup; - Ui::ProfileSetupDialog *ui; + Ui::ProfileSetupDialog* ui; QIcon goodIcon; QIcon yellowIcon; QIcon badIcon; - QAction * validityAction = nullptr; + QAction* validityAction = nullptr; QString queuedCheck; @@ -85,4 +68,3 @@ private: QTimer checkStartTimer; }; - diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 4243e2917..ba22e334f 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -37,18 +37,17 @@ #include #include "ui_ProgressDialog.h" -#include #include #include +#include #include "tasks/Task.h" #include "ui/widgets/SubTaskProgressBar.h" - // map a value in a numeric range of an arbitrary type to between 0 and INT_MAX // for getting the best precision out of the qt progress bar -template, bool> = true> +template , bool> = true> std::tuple map_int_zero_max(T current, T range_max, T range_min) { int int_max = std::numeric_limits::max(); @@ -57,10 +56,9 @@ std::tuple map_int_zero_max(T current, T range_max, T range_min) double percentage = static_cast(current - range_min) / static_cast(type_range); int mapped_current = percentage * int_max; - return {mapped_current, int_max}; + return { mapped_current, int_max }; } - ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ProgressDialog) { ui->setupUi(this); @@ -96,7 +94,7 @@ ProgressDialog::~ProgressDialog() } void ProgressDialog::updateSize(bool recenterParent) -{ +{ QSize lastSize = this->size(); QPoint lastPos = this->pos(); int minHeight = ui->globalStatusDetailsLabel->minimumSize().height() + (ui->verticalLayout->spacing() * 2); @@ -118,16 +116,13 @@ void ProgressDialog::updateSize(bool recenterParent) auto newX = std::max(0, parent->x() + ((parent->width() - newSize.width()) / 2)); auto newY = std::max(0, parent->y() + ((parent->height() - newSize.height()) / 2)); this->move(newX, newY); - } - else if (lastSize != newSize) - { + } else if (lastSize != newSize) { // center on old position after resize - QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative + QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative auto newX = std::max(0, lastPos.x() + (sizeDiff.width() / 2)); auto newY = std::max(0, lastPos.y() + (sizeDiff.height() / 2)); this->move(newX, newY); } - } int ProgressDialog::execWithTask(Task* task) @@ -139,7 +134,7 @@ int ProgressDialog::execWithTask(Task* task) return QDialog::DialogCode::Accepted; } - QDialog::DialogCode result {}; + QDialog::DialogCode result{}; if (handleImmediateResult(result)) { return result; } @@ -234,16 +229,15 @@ void ProgressDialog::addTaskProgress(TaskStepProgress const& progress) void ProgressDialog::changeStepProgress(TaskStepProgress const& task_progress) { m_is_multi_step = true; - if(ui->taskProgressScrollArea->isHidden()) { + if (ui->taskProgressScrollArea->isHidden()) { ui->taskProgressScrollArea->setHidden(false); updateSize(); } - + if (!taskProgress.contains(task_progress.uid)) addTaskProgress(task_progress); auto task_bar = taskProgress.value(task_progress.uid); - auto const [mapped_current, mapped_total] = map_int_zero_max(task_progress.current, task_progress.total, 0); if (task_progress.total <= 0) { task_bar->setRange(0, 0); @@ -258,14 +252,12 @@ void ProgressDialog::changeStepProgress(TaskStepProgress const& task_progress) if (task_progress.isDone()) { task_bar->setVisible(false); } - } void ProgressDialog::changeProgress(qint64 current, qint64 total) { ui->globalProgressBar->setMaximum(total); ui->globalProgressBar->setValue(current); - } void ProgressDialog::keyPressEvent(QKeyEvent* e) diff --git a/launcher/ui/dialogs/ProgressDialog.h b/launcher/ui/dialogs/ProgressDialog.h index f062be084..82067271d 100644 --- a/launcher/ui/dialogs/ProgressDialog.h +++ b/launcher/ui/dialogs/ProgressDialog.h @@ -33,13 +33,12 @@ * limitations under the License. */ - #pragma once #include -#include #include #include +#include #include "QObjectPtr.h" #include "tasks/Task.h" @@ -49,60 +48,52 @@ class Task; class SequentialTask; -namespace Ui -{ +namespace Ui { class ProgressDialog; } -class ProgressDialog : public QDialog -{ +class ProgressDialog : public QDialog { Q_OBJECT -public: - explicit ProgressDialog(QWidget *parent = 0); + public: + explicit ProgressDialog(QWidget* parent = 0); ~ProgressDialog(); void updateSize(bool recenterParent = false); int execWithTask(Task* task); - int execWithTask(std::unique_ptr &&task); - int execWithTask(std::unique_ptr &task); + int execWithTask(std::unique_ptr&& task); + int execWithTask(std::unique_ptr& task); void setSkipButton(bool present, QString label = QString()); - Task *getTask(); + Task* getTask(); -public -slots: + public slots: void onTaskStarted(); void onTaskFailed(QString failure); void onTaskSucceeded(); - void changeStatus(const QString &status); + void changeStatus(const QString& status); void changeProgress(qint64 current, qint64 total); void changeStepProgress(TaskStepProgress const& task_progress); - -private -slots: + private slots: void on_skipButton_clicked(bool checked); -protected: - virtual void keyPressEvent(QKeyEvent *e); - virtual void closeEvent(QCloseEvent *e); + protected: + virtual void keyPressEvent(QKeyEvent* e); + virtual void closeEvent(QCloseEvent* e); -private: - bool handleImmediateResult(QDialog::DialogCode &result); + private: + bool handleImmediateResult(QDialog::DialogCode& result); void addTaskProgress(TaskStepProgress const& progress); -private: - Ui::ProgressDialog *ui; + private: + Ui::ProgressDialog* ui; - Task *task; + Task* task; bool m_is_multi_step = false; QHash taskProgress; - - }; - diff --git a/launcher/ui/dialogs/ScrollMessageBox.cpp b/launcher/ui/dialogs/ScrollMessageBox.cpp index afdc4bae1..c04d87842 100644 --- a/launcher/ui/dialogs/ScrollMessageBox.cpp +++ b/launcher/ui/dialogs/ScrollMessageBox.cpp @@ -1,15 +1,16 @@ #include "ScrollMessageBox.h" #include "ui_ScrollMessageBox.h" - -ScrollMessageBox::ScrollMessageBox(QWidget *parent, const QString &title, const QString &text, const QString &body) : - QDialog(parent), ui(new Ui::ScrollMessageBox) { +ScrollMessageBox::ScrollMessageBox(QWidget* parent, const QString& title, const QString& text, const QString& body) + : QDialog(parent), ui(new Ui::ScrollMessageBox) +{ ui->setupUi(this); this->setWindowTitle(title); ui->label->setText(text); ui->textBrowser->setText(body); } -ScrollMessageBox::~ScrollMessageBox() { +ScrollMessageBox::~ScrollMessageBox() +{ delete ui; } diff --git a/launcher/ui/dialogs/ScrollMessageBox.h b/launcher/ui/dialogs/ScrollMessageBox.h index 84aa253a9..8fd6769c4 100644 --- a/launcher/ui/dialogs/ScrollMessageBox.h +++ b/launcher/ui/dialogs/ScrollMessageBox.h @@ -2,19 +2,20 @@ #include - QT_BEGIN_NAMESPACE -namespace Ui { class ScrollMessageBox; } +namespace Ui { +class ScrollMessageBox; +} QT_END_NAMESPACE class ScrollMessageBox : public QDialog { -Q_OBJECT + Q_OBJECT -public: - ScrollMessageBox(QWidget *parent, const QString &title, const QString &text, const QString &body); + public: + ScrollMessageBox(QWidget* parent, const QString& title, const QString& text, const QString& body); ~ScrollMessageBox() override; -private: - Ui::ScrollMessageBox *ui; + private: + Ui::ScrollMessageBox* ui; }; diff --git a/launcher/ui/dialogs/SkinUploadDialog.cpp b/launcher/ui/dialogs/SkinUploadDialog.cpp index 8180ac1f0..10d8089e4 100644 --- a/launcher/ui/dialogs/SkinUploadDialog.cpp +++ b/launcher/ui/dialogs/SkinUploadDialog.cpp @@ -33,20 +33,20 @@ * limitations under the License. */ -#include #include +#include #include #include -#include #include +#include #include +#include "CustomMessageBox.h" +#include "ProgressDialog.h" #include "SkinUploadDialog.h" #include "ui_SkinUploadDialog.h" -#include "ProgressDialog.h" -#include "CustomMessageBox.h" void SkinUploadDialog::on_buttonBox_rejected() { @@ -64,71 +64,51 @@ void SkinUploadDialog::on_buttonBox_accepted() QRegularExpression urlPrefixMatcher(QRegularExpression::anchoredPattern("^([a-z]+)://.+$")); bool isLocalFile = false; // it has an URL prefix -> it is an URL - if(urlPrefixMatcher.match(input).hasMatch()) - { + if (urlPrefixMatcher.match(input).hasMatch()) { QUrl fileURL = input; - if(fileURL.isValid()) - { + if (fileURL.isValid()) { // local? - if(fileURL.isLocalFile()) - { + if (fileURL.isLocalFile()) { isLocalFile = true; fileName = fileURL.toLocalFile(); - } - else - { - CustomMessageBox::selectable( - this, - tr("Skin Upload"), - tr("Using remote URLs for setting skins is not implemented yet."), - QMessageBox::Warning - )->exec(); + } else { + CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Using remote URLs for setting skins is not implemented yet."), + QMessageBox::Warning) + ->exec(); close(); return; } - } - else - { - CustomMessageBox::selectable( - this, - tr("Skin Upload"), - tr("You cannot use an invalid URL for uploading skins."), - QMessageBox::Warning - )->exec(); + } else { + CustomMessageBox::selectable(this, tr("Skin Upload"), tr("You cannot use an invalid URL for uploading skins."), + QMessageBox::Warning) + ->exec(); close(); return; } - } - else - { + } else { // just assume it's a path then isLocalFile = true; fileName = ui->skinPathTextBox->text(); } - if (isLocalFile && !QFile::exists(fileName)) - { + if (isLocalFile && !QFile::exists(fileName)) { CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec(); close(); return; } SkinUpload::Model model = SkinUpload::STEVE; - if (ui->steveBtn->isChecked()) - { + if (ui->steveBtn->isChecked()) { model = SkinUpload::STEVE; - } - else if (ui->alexBtn->isChecked()) - { + } else if (ui->alexBtn->isChecked()) { model = SkinUpload::ALEX; } skinUpload.addTask(shared_qobject_ptr(new SkinUpload(this, m_acct->accessToken(), FS::read(fileName), model))); } auto selectedCape = ui->capeCombo->currentData().toString(); - if(selectedCape != m_acct->accountData()->minecraftProfile.currentCape) { + if (selectedCape != m_acct->accountData()->minecraftProfile.currentCape) { skinUpload.addTask(shared_qobject_ptr(new CapeChange(this, m_acct->accessToken(), selectedCape))); } - if (prog.execWithTask(&skinUpload) != QDialog::Accepted) - { + if (prog.execWithTask(&skinUpload) != QDialog::Accepted) { CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec(); close(); return; @@ -141,45 +121,43 @@ void SkinUploadDialog::on_skinBrowseBtn_clicked() { auto filter = QMimeDatabase().mimeTypeForName("image/png").filterString(); QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), filter); - if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) - { + if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) { return; } QString cooked_path = FS::NormalizePath(raw_path); ui->skinPathTextBox->setText(cooked_path); } -SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent) - :QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog) +SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget* parent) : QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog) { ui->setupUi(this); // FIXME: add a model for this, download/refresh the capes on demand - auto &data = *acct->accountData(); + auto& data = *acct->accountData(); int index = 0; ui->capeCombo->addItem(tr("No Cape"), QVariant()); auto currentCape = data.minecraftProfile.currentCape; - if(currentCape.isEmpty()) { + if (currentCape.isEmpty()) { ui->capeCombo->setCurrentIndex(index); } - for(auto & cape: data.minecraftProfile.capes) { + for (auto& cape : data.minecraftProfile.capes) { index++; - if(cape.data.size()) { + if (cape.data.size()) { QPixmap capeImage; - if(capeImage.loadFromData(cape.data, "PNG")) { + if (capeImage.loadFromData(cape.data, "PNG")) { QPixmap preview = QPixmap(10, 16); QPainter painter(&preview); painter.drawPixmap(0, 0, capeImage.copy(1, 1, 10, 16)); ui->capeCombo->addItem(capeImage, cape.alias, cape.id); - if(currentCape == cape.id) { + if (currentCape == cape.id) { ui->capeCombo->setCurrentIndex(index); } continue; } } ui->capeCombo->addItem(cape.alias, cape.id); - if(currentCape == cape.id) { + if (currentCape == cape.id) { ui->capeCombo->setCurrentIndex(index); } } diff --git a/launcher/ui/dialogs/SkinUploadDialog.h b/launcher/ui/dialogs/SkinUploadDialog.h index 84d17dc6f..81d6140cc 100644 --- a/launcher/ui/dialogs/SkinUploadDialog.h +++ b/launcher/ui/dialogs/SkinUploadDialog.h @@ -1,29 +1,28 @@ #pragma once -#include #include +#include -namespace Ui -{ - class SkinUploadDialog; +namespace Ui { +class SkinUploadDialog; } class SkinUploadDialog : public QDialog { Q_OBJECT -public: - explicit SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent = 0); - virtual ~SkinUploadDialog() {}; + public: + explicit SkinUploadDialog(MinecraftAccountPtr acct, QWidget* parent = 0); + virtual ~SkinUploadDialog(){}; -public slots: + public slots: void on_buttonBox_accepted(); void on_buttonBox_rejected(); void on_skinBrowseBtn_clicked(); -protected: + protected: MinecraftAccountPtr m_acct; -private: - Ui::SkinUploadDialog *ui; + private: + Ui::SkinUploadDialog* ui; }; diff --git a/launcher/ui/dialogs/VersionSelectDialog.cpp b/launcher/ui/dialogs/VersionSelectDialog.cpp index 5feb70d20..61254c46f 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.cpp +++ b/launcher/ui/dialogs/VersionSelectDialog.cpp @@ -35,20 +35,19 @@ #include "VersionSelectDialog.h" +#include #include #include #include #include #include -#include #include "ui/widgets/VersionSelectWidget.h" #include "BaseVersion.h" #include "BaseVersionList.h" -VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable) - : QDialog(parent) +VersionSelectDialog::VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent, bool cancelable) : QDialog(parent) { setObjectName(QStringLiteral("VersionSelectDialog")); resize(400, 347); @@ -68,7 +67,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, m_buttonBox = new QDialogButtonBox(this); m_buttonBox->setObjectName(QStringLiteral("buttonBox")); m_buttonBox->setOrientation(Qt::Horizontal); - m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); m_horizontalLayout->addWidget(m_buttonBox); m_verticalLayout->addLayout(m_horizontalLayout); @@ -84,8 +83,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, m_vlist = vlist; - if (!cancelable) - { + if (!cancelable) { m_buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); } } @@ -123,8 +121,7 @@ int VersionSelectDialog::exec() { QDialog::open(); m_versionWidget->initialize(m_vlist); - if(resizeOnColumn != -1) - { + if (resizeOnColumn != -1) { m_versionWidget->setResizeOn(resizeOnColumn); } return QDialog::exec(); diff --git a/launcher/ui/dialogs/VersionSelectDialog.h b/launcher/ui/dialogs/VersionSelectDialog.h index 18a50cdb0..701020fa9 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.h +++ b/launcher/ui/dialogs/VersionSelectDialog.h @@ -18,7 +18,6 @@ #include #include - #include "BaseVersionList.h" class QVBoxLayout; @@ -27,52 +26,50 @@ class QDialogButtonBox; class VersionSelectWidget; class QPushButton; -namespace Ui -{ +namespace Ui { class VersionSelectDialog; } class VersionProxyModel; -class VersionSelectDialog : public QDialog -{ +class VersionSelectDialog : public QDialog { Q_OBJECT -public: - explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, bool cancelable = true); - virtual ~VersionSelectDialog() {}; + public: + explicit VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent = 0, bool cancelable = true); + virtual ~VersionSelectDialog(){}; int exec() override; BaseVersion::Ptr selectedVersion() const; - void setCurrentVersion(const QString & version); + void setCurrentVersion(const QString& version); void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); void setExactFilter(BaseVersionList::ModelRoles role, QString filter); void setEmptyString(QString emptyString); void setEmptyErrorString(QString emptyErrorString); void setResizeOn(int column); -private slots: + private slots: void on_refreshButton_clicked(); -private: + private: void retranslate(); void selectRecommended(); -private: + private: QString m_currentVersion; - VersionSelectWidget *m_versionWidget = nullptr; - QVBoxLayout *m_verticalLayout = nullptr; - QHBoxLayout *m_horizontalLayout = nullptr; - QPushButton *m_refreshButton = nullptr; - QDialogButtonBox *m_buttonBox = nullptr; + VersionSelectWidget* m_versionWidget = nullptr; + QVBoxLayout* m_verticalLayout = nullptr; + QHBoxLayout* m_horizontalLayout = nullptr; + QPushButton* m_refreshButton = nullptr; + QDialogButtonBox* m_buttonBox = nullptr; - BaseVersionList *m_vlist = nullptr; + BaseVersionList* m_vlist = nullptr; - VersionProxyModel *m_proxyModel = nullptr; + VersionProxyModel* m_proxyModel = nullptr; int resizeOnColumn = -1; - Task * loadTask = nullptr; + Task* loadTask = nullptr; }; diff --git a/launcher/ui/instanceview/AccessibleInstanceView.cpp b/launcher/ui/instanceview/AccessibleInstanceView.cpp index 2e7b83000..c99fe541a 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView.cpp +++ b/launcher/ui/instanceview/AccessibleInstanceView.cpp @@ -1,42 +1,40 @@ -#include "InstanceView.h" #include "AccessibleInstanceView.h" #include "AccessibleInstanceView_p.h" +#include "InstanceView.h" -#include #include #include +#include #ifndef QT_NO_ACCESSIBILITY -QAccessibleInterface *groupViewAccessibleFactory(const QString &classname, QObject *object) +QAccessibleInterface* groupViewAccessibleFactory(const QString& classname, QObject* object) { - QAccessibleInterface *iface = 0; + QAccessibleInterface* iface = 0; if (!object || !object->isWidgetType()) return iface; - QWidget *widget = static_cast(object); + QWidget* widget = static_cast(object); if (classname == QLatin1String("InstanceView")) { - iface = new AccessibleInstanceView((InstanceView *)widget); + iface = new AccessibleInstanceView((InstanceView*)widget); } return iface; } - -QAbstractItemView *AccessibleInstanceView::view() const +QAbstractItemView* AccessibleInstanceView::view() const { return qobject_cast(object()); } -int AccessibleInstanceView::logicalIndex(const QModelIndex &index) const +int AccessibleInstanceView::logicalIndex(const QModelIndex& index) const { if (!view()->model() || !index.isValid()) return -1; return index.row() * (index.model()->columnCount()) + index.column(); } -AccessibleInstanceView::AccessibleInstanceView(QWidget *w) - : QAccessibleObject(w) +AccessibleInstanceView::AccessibleInstanceView(QWidget* w) : QAccessibleObject(w) { Q_ASSERT(view()); } @@ -53,7 +51,7 @@ AccessibleInstanceView::~AccessibleInstanceView() } } -QAccessibleInterface *AccessibleInstanceView::cellAt(int row, int column) const +QAccessibleInterface* AccessibleInstanceView::cellAt(int row, int column) const { if (!view()->model()) { return 0; @@ -68,7 +66,7 @@ QAccessibleInterface *AccessibleInstanceView::cellAt(int row, int column) const return child(logicalIndex(index)); } -QAccessibleInterface *AccessibleInstanceView::caption() const +QAccessibleInterface* AccessibleInstanceView::caption() const { return 0; } @@ -123,14 +121,14 @@ QString AccessibleInstanceView::rowDescription(int row) const return view()->model()->headerData(row, Qt::Vertical).toString(); } -QList AccessibleInstanceView::selectedCells() const +QList AccessibleInstanceView::selectedCells() const { QList cells; if (!view()->selectionModel()) return cells; const QModelIndexList selectedIndexes = view()->selectionModel()->selectedIndexes(); cells.reserve(selectedIndexes.size()); - for (const QModelIndex &index : selectedIndexes) + for (const QModelIndex& index : selectedIndexes) cells.append(child(logicalIndex(index))); return cells; } @@ -145,7 +143,7 @@ QList AccessibleInstanceView::selectedColumns() const QList columns; columns.reserve(selectedColumns.size()); - for (const QModelIndex &index : selectedColumns) { + for (const QModelIndex& index : selectedColumns) { columns.append(index.column()); } @@ -163,14 +161,14 @@ QList AccessibleInstanceView::selectedRows() const const QModelIndexList selectedRows = view()->selectionModel()->selectedRows(); rows.reserve(selectedRows.size()); - for (const QModelIndex &index : selectedRows) { + for (const QModelIndex& index : selectedRows) { rows.append(index.row()); } return rows; } -QAccessibleInterface *AccessibleInstanceView::summary() const +QAccessibleInterface* AccessibleInstanceView::summary() const { return 0; } @@ -209,16 +207,17 @@ bool AccessibleInstanceView::selectRow(int row) return false; } case QAbstractItemView::SingleSelection: { - if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 ) + if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1) return false; view()->clearSelection(); break; } case QAbstractItemView::ContiguousSelection: { - if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { + if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && + !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { view()->clearSelection(); } - break; + break; } default: { break; @@ -251,7 +250,8 @@ bool AccessibleInstanceView::selectColumn(int column) } /* fallthrough */ case QAbstractItemView::ContiguousSelection: { - if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { + if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && + !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { view()->clearSelection(); } break; @@ -292,10 +292,10 @@ bool AccessibleInstanceView::unselectRow(int row) return false; } - - if ((!row || selectionModel->isRowSelected(row - 1, view()->rootIndex())) && selectionModel->isRowSelected(row + 1, view()->rootIndex())) { - //If there are rows selected both up the current row and down the current rown, - //the ones which are down the current row will be deselected + if ((!row || selectionModel->isRowSelected(row - 1, view()->rootIndex())) && + selectionModel->isRowSelected(row + 1, view()->rootIndex())) { + // If there are rows selected both up the current row and down the current rown, + // the ones which are down the current row will be deselected selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex())); } } @@ -324,8 +324,8 @@ bool AccessibleInstanceView::unselectColumn(int column) switch (view()->selectionMode()) { case QAbstractItemView::SingleSelection: { - //In SingleSelection and ContiguousSelection once an item - //is selected, there's no way for the user to unselect all items + // In SingleSelection and ContiguousSelection once an item + // is selected, there's no way for the user to unselect all items if (selectedColumnCount() == 1) { return false; } @@ -336,10 +336,10 @@ bool AccessibleInstanceView::unselectColumn(int column) return false; } - if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) - && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { - //If there are columns selected both at the left of the current row and at the right - //of the current row, the ones which are at the right will be deselected + if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && + view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { + // If there are columns selected both at the left of the current row and at the right + // of the current row, the ones which are at the right will be deselected selection = QItemSelection(index, model->index(0, columnCount() - 1, view()->rootIndex())); } default: @@ -360,9 +360,9 @@ QAccessible::State AccessibleInstanceView::state() const return QAccessible::State(); } -QAccessibleInterface *AccessibleInstanceView::childAt(int x, int y) const +QAccessibleInterface* AccessibleInstanceView::childAt(int x, int y) const { - QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); + QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0, 0)); QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); // FIXME: if indexPosition < 0 in one coordinate, return header @@ -381,22 +381,23 @@ int AccessibleInstanceView::childCount() const return (view()->model()->rowCount()) * (view()->model()->columnCount()); } -int AccessibleInstanceView::indexOfChild(const QAccessibleInterface *iface) const +int AccessibleInstanceView::indexOfChild(const QAccessibleInterface* iface) const { if (!view()->model()) return -1; - QAccessibleInterface *parent = iface->parent(); + QAccessibleInterface* parent = iface->parent(); if (parent->object() != view()) return -1; - Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class + Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { const AccessibleInstanceViewItem* cell = static_cast(iface); return logicalIndex(cell->m_index); } else if (iface->role() == QAccessible::Pane) { - return 0; // corner button + return 0; // corner button } else { - qWarning() << "AccessibleInstanceView::indexOfChild has a child with unknown role..." << iface->role() << iface->text(QAccessible::Name); + qWarning() << "AccessibleInstanceView::indexOfChild has a child with unknown role..." << iface->role() + << iface->text(QAccessible::Name); } // FIXME: we are in denial of our children. this should stop. return -1; @@ -417,7 +418,7 @@ QRect AccessibleInstanceView::rect() const return QRect(pos.x(), pos.y(), view()->width(), view()->height()); } -QAccessibleInterface *AccessibleInstanceView::parent() const +QAccessibleInterface* AccessibleInstanceView::parent() const { if (view() && view()->parent()) { if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) { @@ -428,7 +429,7 @@ QAccessibleInterface *AccessibleInstanceView::parent() const return 0; } -QAccessibleInterface *AccessibleInstanceView::child(int logicalIndex) const +QAccessibleInterface* AccessibleInstanceView::child(int logicalIndex) const { if (!view()->model()) return 0; @@ -442,7 +443,7 @@ QAccessibleInterface *AccessibleInstanceView::child(int logicalIndex) const int row = logicalIndex / columns; int column = logicalIndex % columns; - QAccessibleInterface *iface = 0; + QAccessibleInterface* iface = 0; QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); if (Q_UNLIKELY(!index.isValid())) { @@ -456,14 +457,14 @@ QAccessibleInterface *AccessibleInstanceView::child(int logicalIndex) const return iface; } -void *AccessibleInstanceView::interface_cast(QAccessible::InterfaceType t) +void* AccessibleInstanceView::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::TableInterface) - return static_cast(this); - return 0; + return static_cast(this); + return 0; } -void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event) +void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent* event) { // if there is no cache yet, we don't update anything if (childToId.isEmpty()) @@ -479,13 +480,12 @@ void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event // rows are inserted: move every row after that case QAccessibleTableModelChangeEvent::RowsInserted: case QAccessibleTableModelChangeEvent::ColumnsInserted: { - ChildCache newCache; ChildCache::ConstIterator iter = childToId.constBegin(); while (iter != childToId.constEnd()) { QAccessible::Id id = iter.value(); - QAccessibleInterface *iface = QAccessible::accessibleInterface(id); + QAccessibleInterface* iface = QAccessible::accessibleInterface(id); Q_ASSERT(iface); if (indexOfChild(iface) >= 0) { newCache.insert(indexOfChild(iface), id); @@ -507,11 +507,11 @@ void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event ChildCache::ConstIterator iter = childToId.constBegin(); while (iter != childToId.constEnd()) { QAccessible::Id id = iter.value(); - QAccessibleInterface *iface = QAccessible::accessibleInterface(id); + QAccessibleInterface* iface = QAccessible::accessibleInterface(id); Q_ASSERT(iface); if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { Q_ASSERT(iface->tableCellInterface()); - AccessibleInstanceViewItem *cell = static_cast(iface->tableCellInterface()); + AccessibleInstanceViewItem* cell = static_cast(iface->tableCellInterface()); // Since it is a QPersistentModelIndex, we only need to check if it is valid if (cell->m_index.isValid()) newCache.insert(indexOfChild(cell), id); @@ -532,14 +532,13 @@ void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event // TABLE CELL -AccessibleInstanceViewItem::AccessibleInstanceViewItem(QAbstractItemView *view_, const QModelIndex &index_) - : view(view_), m_index(index_) +AccessibleInstanceViewItem::AccessibleInstanceViewItem(QAbstractItemView* view_, const QModelIndex& index_) : view(view_), m_index(index_) { if (Q_UNLIKELY(!index_.isValid())) qWarning() << "AccessibleInstanceViewItem::AccessibleInstanceViewItem with invalid index: " << index_; } -void *AccessibleInstanceViewItem::interface_cast(QAccessible::InterfaceType t) +void* AccessibleInstanceViewItem::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::TableCellInterface) return static_cast(this); @@ -548,8 +547,14 @@ void *AccessibleInstanceViewItem::interface_cast(QAccessible::InterfaceType t) return 0; } -int AccessibleInstanceViewItem::columnExtent() const { return 1; } -int AccessibleInstanceViewItem::rowExtent() const { return 1; } +int AccessibleInstanceViewItem::columnExtent() const +{ + return 1; +} +int AccessibleInstanceViewItem::rowExtent() const +{ + return 1; +} QList AccessibleInstanceViewItem::rowHeaderCells() const { @@ -600,19 +605,17 @@ void AccessibleInstanceViewItem::doAction(const QString& actionName) if (actionName == toggleAction()) { if (isSelected()) { unselectCell(); - } - else { + } else { selectCell(); } } } -QStringList AccessibleInstanceViewItem::keyBindingsForAction(const QString &) const +QStringList AccessibleInstanceViewItem::keyBindingsForAction(const QString&) const { return QStringList(); } - void AccessibleInstanceViewItem::selectCell() { if (!isValid()) { @@ -624,7 +627,7 @@ void AccessibleInstanceViewItem::selectCell() } Q_ASSERT(table()); - QAccessibleTableInterface *cellTable = table()->tableInterface(); + QAccessibleTableInterface* cellTable = table()->tableInterface(); switch (view->selectionBehavior()) { case QAbstractItemView::SelectItems: @@ -654,7 +657,7 @@ void AccessibleInstanceViewItem::unselectCell() if (selectionMode == QAbstractItemView::NoSelection) return; - QAccessibleTableInterface *cellTable = table()->tableInterface(); + QAccessibleTableInterface* cellTable = table()->tableInterface(); switch (view->selectionBehavior()) { case QAbstractItemView::SelectItems: @@ -669,15 +672,16 @@ void AccessibleInstanceViewItem::unselectCell() return; } - //If the mode is not MultiSelection or ExtendedSelection and only - //one cell is selected it cannot be unselected by the user - if ((selectionMode != QAbstractItemView::MultiSelection) && (selectionMode != QAbstractItemView::ExtendedSelection) && (view->selectionModel()->selectedIndexes().count() <= 1)) + // If the mode is not MultiSelection or ExtendedSelection and only + // one cell is selected it cannot be unselected by the user + if ((selectionMode != QAbstractItemView::MultiSelection) && (selectionMode != QAbstractItemView::ExtendedSelection) && + (view->selectionModel()->selectedIndexes().count() <= 1)) return; view->selectionModel()->select(m_index, QItemSelectionModel::Deselect); } -QAccessibleInterface *AccessibleInstanceViewItem::table() const +QAccessibleInterface* AccessibleInstanceViewItem::table() const { return QAccessible::queryAccessibleInterface(view); } @@ -694,7 +698,7 @@ QAccessible::State AccessibleInstanceViewItem::state() const return st; QRect globalRect = view->rect(); - globalRect.translate(view->mapToGlobal(QPoint(0,0))); + globalRect.translate(view->mapToGlobal(QPoint(0, 0))); if (!globalRect.intersects(rect())) st.invisible = true; @@ -717,7 +721,6 @@ QAccessible::State AccessibleInstanceViewItem::state() const return st; } - QRect AccessibleInstanceViewItem::rect() const { QRect r; @@ -726,7 +729,7 @@ QRect AccessibleInstanceViewItem::rect() const r = view->visualRect(m_index); if (!r.isNull()) { - r.translate(view->viewport()->mapTo(view, QPoint(0,0))); + r.translate(view->viewport()->mapTo(view, QPoint(0, 0))); r.translate(view->mapToGlobal(QPoint(0, 0))); } return r; @@ -737,7 +740,7 @@ QString AccessibleInstanceViewItem::text(QAccessible::Text t) const QString value; if (!isValid()) return value; - QAbstractItemModel *model = view->model(); + QAbstractItemModel* model = view->model(); switch (t) { case QAccessible::Name: value = model->data(m_index, Qt::AccessibleTextRole).toString(); @@ -753,7 +756,7 @@ QString AccessibleInstanceViewItem::text(QAccessible::Text t) const return value; } -void AccessibleInstanceViewItem::setText(QAccessible::Text /*t*/, const QString &text) +void AccessibleInstanceViewItem::setText(QAccessible::Text /*t*/, const QString& text) { if (!isValid() || !(m_index.flags() & Qt::ItemIsEditable)) return; @@ -765,12 +768,12 @@ bool AccessibleInstanceViewItem::isValid() const return view && view->model() && m_index.isValid(); } -QAccessibleInterface *AccessibleInstanceViewItem::parent() const +QAccessibleInterface* AccessibleInstanceViewItem::parent() const { return QAccessible::queryAccessibleInterface(view); } -QAccessibleInterface *AccessibleInstanceViewItem::child(int) const +QAccessibleInterface* AccessibleInstanceViewItem::child(int) const { return 0; } diff --git a/launcher/ui/instanceview/AccessibleInstanceView.h b/launcher/ui/instanceview/AccessibleInstanceView.h index eb4222f50..19522805a 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView.h +++ b/launcher/ui/instanceview/AccessibleInstanceView.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include class QAccessibleInterface; -QAccessibleInterface *groupViewAccessibleFactory(const QString &classname, QObject *object); +QAccessibleInterface* groupViewAccessibleFactory(const QString& classname, QObject* object); diff --git a/launcher/ui/instanceview/AccessibleInstanceView_p.h b/launcher/ui/instanceview/AccessibleInstanceView_p.h index 26462f51e..e99f85069 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView_p.h +++ b/launcher/ui/instanceview/AccessibleInstanceView_p.h @@ -1,9 +1,9 @@ #pragma once -#include "QtCore/qpointer.h" #include -#include #include +#include +#include "QtCore/qpointer.h" #ifndef QT_NO_ACCESSIBILITY #include "InstanceView.h" // #include @@ -11,10 +11,9 @@ class QAccessibleTableCell; class QAccessibleTableHeaderCell; -class AccessibleInstanceView :public QAccessibleTableInterface, public QAccessibleObject -{ -public: - explicit AccessibleInstanceView(QWidget *w); +class AccessibleInstanceView : public QAccessibleTableInterface, public QAccessibleObject { + public: + explicit AccessibleInstanceView(QWidget* w); bool isValid() const override; QAccessible::Role role() const override; @@ -22,19 +21,19 @@ public: QString text(QAccessible::Text t) const override; QRect rect() const override; - QAccessibleInterface *childAt(int x, int y) const override; + QAccessibleInterface* childAt(int x, int y) const override; int childCount() const override; - int indexOfChild(const QAccessibleInterface *) const override; + int indexOfChild(const QAccessibleInterface*) const override; - QAccessibleInterface *parent() const override; - QAccessibleInterface *child(int index) const override; + QAccessibleInterface* parent() const override; + QAccessibleInterface* child(int index) const override; - void *interface_cast(QAccessible::InterfaceType t) override; + void* interface_cast(QAccessible::InterfaceType t) override; // table interface - QAccessibleInterface *cellAt(int row, int column) const override; - QAccessibleInterface *caption() const override; - QAccessibleInterface *summary() const override; + QAccessibleInterface* cellAt(int row, int column) const override; + QAccessibleInterface* caption() const override; + QAccessibleInterface* summary() const override; QString columnDescription(int column) const override; QString rowDescription(int row) const override; int columnCount() const override; @@ -54,42 +53,41 @@ public: bool unselectRow(int row) override; bool unselectColumn(int column) override; - QAbstractItemView *view() const; + QAbstractItemView* view() const; - void modelChange(QAccessibleTableModelChangeEvent *event) override; + void modelChange(QAccessibleTableModelChangeEvent* event) override; -protected: + protected: // maybe vector typedef QHash ChildCache; mutable ChildCache childToId; virtual ~AccessibleInstanceView(); -private: - inline int logicalIndex(const QModelIndex &index) const; + private: + inline int logicalIndex(const QModelIndex& index) const; }; -class AccessibleInstanceViewItem: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface -{ -public: - AccessibleInstanceViewItem(QAbstractItemView *view, const QModelIndex &m_index); +class AccessibleInstanceViewItem : public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface { + public: + AccessibleInstanceViewItem(QAbstractItemView* view, const QModelIndex& m_index); - void *interface_cast(QAccessible::InterfaceType t) override; - QObject *object() const override { return nullptr; } + void* interface_cast(QAccessible::InterfaceType t) override; + QObject* object() const override { return nullptr; } QAccessible::Role role() const override; QAccessible::State state() const override; QRect rect() const override; bool isValid() const override; - QAccessibleInterface *childAt(int, int) const override { return nullptr; } + QAccessibleInterface* childAt(int, int) const override { return nullptr; } int childCount() const override { return 0; } - int indexOfChild(const QAccessibleInterface *) const override { return -1; } + int indexOfChild(const QAccessibleInterface*) const override { return -1; } QString text(QAccessible::Text t) const override; - void setText(QAccessible::Text t, const QString &text) override; + void setText(QAccessible::Text t, const QString& text) override; - QAccessibleInterface *parent() const override; - QAccessibleInterface *child(int) const override; + QAccessibleInterface* parent() const override; + QAccessibleInterface* child(int) const override; // cell interface int columnExtent() const override; @@ -101,13 +99,13 @@ public: bool isSelected() const override; QAccessibleInterface* table() const override; - //action interface + // action interface QStringList actionNames() const override; - void doAction(const QString &actionName) override; - QStringList keyBindingsForAction(const QString &actionName) const override; + void doAction(const QString& actionName) override; + QStringList keyBindingsForAction(const QString& actionName) const override; -private: - QPointer view; + private: + QPointer view; QPersistentModelIndex m_index; void selectCell(); diff --git a/launcher/ui/instanceview/InstanceDelegate.cpp b/launcher/ui/instanceview/InstanceDelegate.cpp index 137cc8d58..0d3d1f423 100644 --- a/launcher/ui/instanceview/InstanceDelegate.cpp +++ b/launcher/ui/instanceview/InstanceDelegate.cpp @@ -34,29 +34,27 @@ */ #include "InstanceDelegate.h" -#include -#include -#include #include -#include #include +#include +#include +#include +#include -#include "InstanceView.h" -#include "BaseInstance.h" -#include "InstanceList.h" #include #include +#include "BaseInstance.h" +#include "InstanceList.h" +#include "InstanceView.h" // Origin: Qt -static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height, - qreal &widthUsed) +static void viewItemTextLayout(QTextLayout& textLayout, int lineWidth, qreal& height, qreal& widthUsed) { height = 0; widthUsed = 0; textLayout.beginLayout(); QString str = textLayout.text(); - while (true) - { + while (true) { QTextLine line = textLayout.createLine(); if (!line.isValid()) break; @@ -70,24 +68,20 @@ static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &he textLayout.endLayout(); } -ListViewDelegate::ListViewDelegate(QObject *parent) : QStyledItemDelegate(parent) -{ -} +ListViewDelegate::ListViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {} -void drawSelectionRect(QPainter *painter, const QStyleOptionViewItem &option, - const QRect &rect) +void drawSelectionRect(QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect) { if ((option.state & QStyle::State_Selected)) painter->fillRect(rect, option.palette.brush(QPalette::Highlight)); - else - { + else { QColor backgroundColor = option.palette.color(QPalette::Window); backgroundColor.setAlpha(160); painter->fillRect(rect, QBrush(backgroundColor)); } } -void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) +void drawFocusRect(QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect) { if (!(option.state & QStyle::State_HasFocus)) return; @@ -103,7 +97,7 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const // Apparently some widget styles expect this hint to not be set painter->setRenderHint(QPainter::Antialiasing, false); - QStyle *style = option.widget ? option.widget->style() : QApplication::style(); + QStyle* style = option.widget ? option.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget); @@ -111,11 +105,9 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const } // TODO this can be made a lot prettier -void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItem &option, - const int value, const int maximum) +void drawProgressOverlay(QPainter* painter, const QStyleOptionViewItem& option, const int value, const int maximum) { - if (maximum == 0 || value == maximum) - { + if (maximum == 0 || value == maximum) { return; } @@ -131,19 +123,15 @@ void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItem &option, painter->restore(); } -void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInstance *instance, QIcon::Mode mode, QIcon::State state) +void drawBadges(QPainter* painter, const QStyleOptionViewItem& option, BaseInstance* instance, QIcon::Mode mode, QIcon::State state) { QList pixmaps; - if (instance->isRunning()) - { + if (instance->isRunning()) { pixmaps.append("status-running"); - } - else if (instance->hasCrashed() || instance->hasVersionBroken()) - { + } else if (instance->hasCrashed() || instance->hasVersionBroken()) { pixmaps.append("status-bad"); } - if (instance->hasUpdateAvailable()) - { + if (instance->hasUpdateAvailable()) { pixmaps.append("checkupdate"); } @@ -153,12 +141,9 @@ void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInsta const int rows = qCeil((double)pixmaps.size() / (double)itemsPerRow); QListIterator it(pixmaps); painter->translate(option.rect.topLeft()); - for (int y = 0; y < rows; ++y) - { - for (int x = 0; x < itemsPerRow; ++x) - { - if (!it.hasNext()) - { + for (int y = 0; y < rows; ++y) { + for (int x = 0; x < itemsPerRow; ++x) { + if (!it.hasNext()) { return; } // FIXME: inject this. @@ -166,21 +151,17 @@ void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInsta // opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state); const QPixmap pixmap; // itemSide - QRect badgeRect( - option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide, - y * itemSide + qMax(y - 1, 0) * spacing, - itemSide, - itemSide - ); + QRect badgeRect(option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide, + y * itemSide + qMax(y - 1, 0) * spacing, itemSide, itemSide); icon.paint(painter, badgeRect, Qt::AlignCenter, mode, state); } } painter->translate(-option.rect.topLeft()); } -static QSize viewItemTextSize(const QStyleOptionViewItem *option) +static QSize viewItemTextSize(const QStyleOptionViewItem* option) { - QStyle *style = option->widget ? option->widget->style() : QApplication::style(); + QStyle* style = option->widget ? option->widget->style() : QApplication::style(); QTextOption textOption; textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); QTextLayout textLayout; @@ -195,8 +176,7 @@ static QSize viewItemTextSize(const QStyleOptionViewItem *option) return QSize(size.width() + 2 * textMargin, size.height()); } -void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const +void ListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); @@ -208,7 +188,7 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti opt.textElideMode = Qt::ElideRight; opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter; - QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + QStyle* style = opt.widget ? opt.widget->style() : QApplication::style(); // const int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize); const int iconSize = 48; @@ -296,16 +276,12 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state); } // set the text colors - QPalette::ColorGroup cg = - opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; + QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) cg = QPalette::Inactive; - if (opt.state & QStyle::State_Selected) - { + if (opt.state & QStyle::State_Selected) { painter->setPen(opt.palette.color(cg, QPalette::HighlightedText)); - } - else - { + } else { painter->setPen(opt.palette.color(cg, QPalette::Text)); } @@ -324,20 +300,16 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti const int lineCount = textLayout.lineCount(); - const QRect layoutRect = QStyle::alignedRect( - opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect); + const QRect layoutRect = QStyle::alignedRect(opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect); const QPointF position = layoutRect.topLeft(); - for (int i = 0; i < lineCount; ++i) - { + for (int i = 0; i < lineCount; ++i) { const QTextLine line = textLayout.lineAt(i); line.draw(painter, position); } // FIXME: this really has no business of being here. Make generic. - auto instance = (BaseInstance*)index.data(InstanceList::InstancePointerRole) - .value(); - if (instance) - { + auto instance = (BaseInstance*)index.data(InstanceList::InstancePointerRole).value(); + if (instance) { drawBadges(painter, opt, instance, mode, state); } @@ -347,8 +319,7 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti painter->restore(); } -QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const +QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); @@ -357,9 +328,9 @@ QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option, opt.textElideMode = Qt::ElideRight; opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter; - QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + QStyle* style = opt.widget ? opt.widget->style() : QApplication::style(); const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, opt.widget) + 1; - int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables + int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables QSize szz = viewItemTextSize(&opt); height += szz.height(); // FIXME: maybe the icon items could scale and keep proportions? @@ -367,36 +338,32 @@ QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option, return sz; } -class NoReturnTextEdit: public QTextEdit -{ +class NoReturnTextEdit : public QTextEdit { Q_OBJECT -public: - explicit NoReturnTextEdit(QWidget *parent) : QTextEdit(parent) + public: + explicit NoReturnTextEdit(QWidget* parent) : QTextEdit(parent) { setTextInteractionFlags(Qt::TextEditorInteraction); setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); } - bool event(QEvent * event) override + bool event(QEvent* event) override { auto eventType = event->type(); - if(eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease) - { - QKeyEvent *keyEvent = static_cast(event); + if (eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease) { + QKeyEvent* keyEvent = static_cast(event); auto key = keyEvent->key(); - if ((key == Qt::Key_Return || key == Qt::Key_Enter) && eventType == QEvent::KeyPress) - { + if ((key == Qt::Key_Return || key == Qt::Key_Enter) && eventType == QEvent::KeyPress) { emit editingDone(); return true; } - if(key == Qt::Key_Tab) - { + if (key == Qt::Key_Tab) { return true; } } return QTextEdit::event(event); } -signals: + signals: void editingDone(); }; @@ -412,7 +379,7 @@ void ListViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionV void ListViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { auto text = index.data(Qt::EditRole).toString(); - QTextEdit * realeditor = qobject_cast(editor); + QTextEdit* realeditor = qobject_cast(editor); realeditor->setAlignment(Qt::AlignHCenter | Qt::AlignTop); realeditor->append(text); realeditor->selectAll(); @@ -421,19 +388,18 @@ void ListViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) void ListViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { - QTextEdit * realeditor = qobject_cast(editor); + QTextEdit* realeditor = qobject_cast(editor); QString text = realeditor->toPlainText(); text.replace(QChar('\n'), QChar(' ')); text = text.trimmed(); // Prevent instance names longer than 128 chars text.truncate(128); - if(text.size() != 0) - { + if (text.size() != 0) { model->setData(index, text); } } -QWidget * ListViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +QWidget* ListViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { auto editor = new NoReturnTextEdit(parent); connect(editor, &NoReturnTextEdit::editingDone, this, &ListViewDelegate::editingDone); @@ -442,7 +408,7 @@ QWidget * ListViewDelegate::createEditor(QWidget* parent, const QStyleOptionView void ListViewDelegate::editingDone() { - NoReturnTextEdit *editor = qobject_cast(sender()); + NoReturnTextEdit* editor = qobject_cast(sender()); emit commitData(editor); emit closeEditor(editor); } diff --git a/launcher/ui/instanceview/InstanceDelegate.h b/launcher/ui/instanceview/InstanceDelegate.h index d95279f32..69dd32ba7 100644 --- a/launcher/ui/instanceview/InstanceDelegate.h +++ b/launcher/ui/instanceview/InstanceDelegate.h @@ -15,25 +15,24 @@ #pragma once -#include #include +#include -class ListViewDelegate : public QStyledItemDelegate -{ +class ListViewDelegate : public QStyledItemDelegate { Q_OBJECT -public: - explicit ListViewDelegate(QObject *parent = 0); + public: + explicit ListViewDelegate(QObject* parent = 0); virtual ~ListViewDelegate() {} - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; - void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const override; - QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; - void setEditorData(QWidget * editor, const QModelIndex & index) const override; - void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override; + void setEditorData(QWidget* editor, const QModelIndex& index) const override; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; -private slots: + private slots: void editingDone(); }; diff --git a/launcher/ui/instanceview/InstanceProxyModel.cpp b/launcher/ui/instanceview/InstanceProxyModel.cpp index d8de93edc..ab6bef696 100644 --- a/launcher/ui/instanceview/InstanceProxyModel.cpp +++ b/launcher/ui/instanceview/InstanceProxyModel.cpp @@ -15,57 +15,54 @@ #include "InstanceProxyModel.h" -#include "InstanceView.h" -#include "Application.h" #include #include +#include "Application.h" +#include "InstanceView.h" #include -InstanceProxyModel::InstanceProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { +InstanceProxyModel::InstanceProxyModel(QObject* parent) : QSortFilterProxyModel(parent) +{ m_naturalSort.setNumericMode(true); m_naturalSort.setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); // FIXME: use loaded translation as source of locale instead, hook this up to translation changes m_naturalSort.setLocale(QLocale::system()); } -QVariant InstanceProxyModel::data(const QModelIndex & index, int role) const +QVariant InstanceProxyModel::data(const QModelIndex& index, int role) const { QVariant data = QSortFilterProxyModel::data(index, role); - if(role == Qt::DecorationRole) - { + if (role == Qt::DecorationRole) { return QVariant(APPLICATION->icons()->getIcon(data.toString())); } return data; } -bool InstanceProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { +bool InstanceProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const +{ const QString leftCategory = left.data(InstanceViewRoles::GroupRole).toString(); const QString rightCategory = right.data(InstanceViewRoles::GroupRole).toString(); if (leftCategory == rightCategory) { return subSortLessThan(left, right); - } - else { + } else { // FIXME: real group sorting happens in InstanceView::updateGeometries(), see LocaleString auto result = leftCategory.localeAwareCompare(rightCategory); - if(result == 0) { + if (result == 0) { return subSortLessThan(left, right); } return result < 0; } } -bool InstanceProxyModel::subSortLessThan(const QModelIndex &left, const QModelIndex &right) const +bool InstanceProxyModel::subSortLessThan(const QModelIndex& left, const QModelIndex& right) const { - BaseInstance *pdataLeft = static_cast(left.internalPointer()); - BaseInstance *pdataRight = static_cast(right.internalPointer()); + BaseInstance* pdataLeft = static_cast(left.internalPointer()); + BaseInstance* pdataRight = static_cast(right.internalPointer()); QString sortMode = APPLICATION->settings()->get("InstSortMode").toString(); - if (sortMode == "LastLaunch") - { + if (sortMode == "LastLaunch") { return pdataLeft->lastLaunch() > pdataRight->lastLaunch(); - } - else - { + } else { return m_naturalSort.compare(pdataLeft->name(), pdataRight->name()) < 0; } } diff --git a/launcher/ui/instanceview/InstanceProxyModel.h b/launcher/ui/instanceview/InstanceProxyModel.h index bba8d2b50..13fec1bca 100644 --- a/launcher/ui/instanceview/InstanceProxyModel.h +++ b/launcher/ui/instanceview/InstanceProxyModel.h @@ -15,21 +15,20 @@ #pragma once -#include #include +#include -class InstanceProxyModel : public QSortFilterProxyModel -{ +class InstanceProxyModel : public QSortFilterProxyModel { Q_OBJECT -public: - InstanceProxyModel(QObject *parent = 0); + public: + InstanceProxyModel(QObject* parent = 0); -protected: - QVariant data(const QModelIndex & index, int role) const override; - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; - bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const; + protected: + QVariant data(const QModelIndex& index, int role) const override; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; + bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const; -private: + private: QCollator m_naturalSort; }; diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 05f0004d1..5a0450e07 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -35,39 +35,36 @@ #include "InstanceView.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "VisualGroup.h" #include +#include "VisualGroup.h" #include #include - -template bool listsIntersect(const QList &l1, const QList t2) +template +bool listsIntersect(const QList& l1, const QList t2) { - for (auto &item : l1) - { - if (t2.contains(item)) - { + for (auto& item : l1) { + if (t2.contains(item)) { return true; } } return false; } -InstanceView::InstanceView(QWidget *parent) - : QAbstractItemView(parent) +InstanceView::InstanceView(QWidget* parent) : QAbstractItemView(parent) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); @@ -82,23 +79,23 @@ InstanceView::~InstanceView() m_groups.clear(); } -void InstanceView::setModel(QAbstractItemModel *model) +void InstanceView::setModel(QAbstractItemModel* model) { QAbstractItemView::setModel(model); connect(model, &QAbstractItemModel::modelReset, this, &InstanceView::modelReset); connect(model, &QAbstractItemModel::rowsRemoved, this, &InstanceView::rowsRemoved); } -void InstanceView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +void InstanceView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles) { scheduleDelayedItemsLayout(); } -void InstanceView::rowsInserted(const QModelIndex &parent, int start, int end) +void InstanceView::rowsInserted(const QModelIndex& parent, int start, int end) { scheduleDelayedItemsLayout(); } -void InstanceView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +void InstanceView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { scheduleDelayedItemsLayout(); } @@ -116,7 +113,8 @@ void InstanceView::rowsRemoved() void InstanceView::currentChanged(const QModelIndex& current, const QModelIndex& previous) { QAbstractItemView::currentChanged(current, previous); - // TODO: for accessibility support, implement+register a factory, steal QAccessibleTable from Qt and return an instance of it for InstanceView. + // TODO: for accessibility support, implement+register a factory, steal QAccessibleTable from Qt and return an instance of it for + // InstanceView. #ifndef QT_NO_ACCESSIBILITY if (QAccessible::isActive() && current.isValid()) { QAccessibleEvent event(this, QAccessible::Focus); @@ -126,19 +124,13 @@ void InstanceView::currentChanged(const QModelIndex& current, const QModelIndex& #endif /* !QT_NO_ACCESSIBILITY */ } - -class LocaleString : public QString -{ -public: - LocaleString(const char *s) : QString(s) - { - } - LocaleString(const QString &s) : QString(s) - { - } +class LocaleString : public QString { + public: + LocaleString(const char* s) : QString(s) {} + LocaleString(const QString& s) : QString(s) {} }; -inline bool operator<(const LocaleString &lhs, const LocaleString &rhs) +inline bool operator<(const LocaleString& lhs, const LocaleString& rhs) { return (QString::localeAwareCompare(lhs, rhs) < 0); } @@ -146,33 +138,28 @@ inline bool operator<(const LocaleString &lhs, const LocaleString &rhs) void InstanceView::updateScrollbar() { int previousScroll = verticalScrollBar()->value(); - if (m_groups.isEmpty()) - { + if (m_groups.isEmpty()) { verticalScrollBar()->setRange(0, 0); - } - else - { + } else { int totalHeight = 0; // top margin totalHeight += m_categoryMargin; int itemScroll = 0; - for (auto category : m_groups) - { + for (auto category : m_groups) { category->m_verticalPosition = totalHeight; totalHeight += category->totalHeight() + m_categoryMargin; - if(!itemScroll && category->totalHeight() != 0) - { + if (!itemScroll && category->totalHeight() != 0) { itemScroll = category->contentHeight() / category->numRows(); } } // do not divide by zero - if(itemScroll == 0) + if (itemScroll == 0) itemScroll = 64; totalHeight += m_bottomMargin; - verticalScrollBar()->setSingleStep ( itemScroll ); - const int rowsPerPage = qMax ( viewport()->height() / itemScroll, 1 ); - verticalScrollBar()->setPageStep ( rowsPerPage * itemScroll ); + verticalScrollBar()->setSingleStep(itemScroll); + const int rowsPerPage = qMax(viewport()->height() / itemScroll, 1); + verticalScrollBar()->setPageStep(rowsPerPage * itemScroll); verticalScrollBar()->setRange(0, totalHeight - height()); } @@ -184,24 +171,19 @@ void InstanceView::updateGeometries() { geometryCache.clear(); - QMap cats; + QMap cats; - for (int i = 0; i < model()->rowCount(); ++i) - { + for (int i = 0; i < model()->rowCount(); ++i) { const QString groupName = model()->index(i, 0).data(InstanceViewRoles::GroupRole).toString(); - if (!cats.contains(groupName)) - { - VisualGroup *old = this->category(groupName); - if (old) - { + if (!cats.contains(groupName)) { + VisualGroup* old = this->category(groupName); + if (old) { auto cat = new VisualGroup(old); cats.insert(groupName, cat); cat->update(); - } - else - { + } else { auto cat = new VisualGroup(groupName, this); - if(fVisibility) { + if (fVisibility) { cat->collapsed = fVisibility(groupName); } cats.insert(groupName, cat); @@ -216,43 +198,36 @@ void InstanceView::updateGeometries() viewport()->update(); } -bool InstanceView::isIndexHidden(const QModelIndex &index) const +bool InstanceView::isIndexHidden(const QModelIndex& index) const { - VisualGroup *cat = category(index); - if (cat) - { + VisualGroup* cat = category(index); + if (cat) { return cat->collapsed; - } - else - { + } else { return false; } } -VisualGroup *InstanceView::category(const QModelIndex &index) const +VisualGroup* InstanceView::category(const QModelIndex& index) const { return category(index.data(InstanceViewRoles::GroupRole).toString()); } -VisualGroup *InstanceView::category(const QString &cat) const +VisualGroup* InstanceView::category(const QString& cat) const { - for (auto group : m_groups) - { - if (group->text == cat) - { + for (auto group : m_groups) { + if (group->text == cat) { return group; } } return nullptr; } -VisualGroup *InstanceView::categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const +VisualGroup* InstanceView::categoryAt(const QPoint& pos, VisualGroup::HitResults& result) const { - for (auto group : m_groups) - { + for (auto group : m_groups) { result = group->hitScan(pos); - if(result != VisualGroup::NoHit) - { + if (result != VisualGroup::NoHit) { return group; } } @@ -260,14 +235,13 @@ VisualGroup *InstanceView::categoryAt(const QPoint &pos, VisualGroup::HitResults return nullptr; } -QString InstanceView::groupNameAt(const QPoint &point) +QString InstanceView::groupNameAt(const QPoint& point) { executeDelayedItemsLayout(); VisualGroup::HitResults hitresult; auto group = categoryAt(point + offset(), hitresult); - if(group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit))) - { + if (group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit))) { return group->text; } return QString(); @@ -288,7 +262,7 @@ int InstanceView::itemWidth() const return m_itemWidth; } -void InstanceView::mousePressEvent(QMouseEvent *event) +void InstanceView::mousePressEvent(QMouseEvent* event) { executeDelayedItemsLayout(); @@ -303,17 +277,14 @@ void InstanceView::mousePressEvent(QMouseEvent *event) VisualGroup::HitResults hitresult; m_pressedCategory = categoryAt(geometryPos, hitresult); - if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit) - { + if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit) { setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState); event->accept(); return; } - if (index.isValid() && (index.flags() & Qt::ItemIsEnabled)) - { - if(index != currentIndex()) - { + if (index.isValid() && (index.flags() & Qt::ItemIsEnabled)) { + if (index != currentIndex()) { // FIXME: better! m_currentCursorColumn = -1; } @@ -329,15 +300,13 @@ void InstanceView::mousePressEvent(QMouseEvent *event) // signal handlers may change the model emit pressed(index); - } - else - { + } else { // Forces a finalize() even if mouse is pressed, but not on a item selectionModel()->select(QModelIndex(), QItemSelectionModel::Select); } } -void InstanceView::mouseMoveEvent(QMouseEvent *event) +void InstanceView::mouseMoveEvent(QMouseEvent* event) { executeDelayedItemsLayout(); @@ -345,16 +314,13 @@ void InstanceView::mouseMoveEvent(QMouseEvent *event) QPoint visualPos = event->pos(); QPoint geometryPos = event->pos() + offset(); - if (state() == ExpandingState || state() == CollapsingState) - { + if (state() == ExpandingState || state() == CollapsingState) { return; } - if (state() == DraggingState) - { + if (state() == DraggingState) { topLeft = m_pressedPosition - offset(); - if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance()) - { + if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance()) { m_pressedIndex = QModelIndex(); startDrag(model()->supportedDragActions()); setState(NoState); @@ -363,39 +329,31 @@ void InstanceView::mouseMoveEvent(QMouseEvent *event) return; } - if (selectionMode() != SingleSelection) - { + if (selectionMode() != SingleSelection) { topLeft = m_pressedPosition - offset(); - } - else - { + } else { topLeft = geometryPos; } - if (m_pressedIndex.isValid() && (state() != DragSelectingState) && - (event->buttons() != Qt::NoButton) && !selectedIndexes().isEmpty()) - { + if (m_pressedIndex.isValid() && (state() != DragSelectingState) && (event->buttons() != Qt::NoButton) && !selectedIndexes().isEmpty()) { setState(DraggingState); return; } - if ((event->buttons() & Qt::LeftButton) && selectionModel()) - { + if ((event->buttons() & Qt::LeftButton) && selectionModel()) { setState(DragSelectingState); setSelection(QRect(visualPos, visualPos), QItemSelectionModel::ClearAndSelect); QModelIndex index = indexAt(visualPos); // set at the end because it might scroll the view - if (index.isValid() && (index != selectionModel()->currentIndex()) && - (index.flags() & Qt::ItemIsEnabled)) - { + if (index.isValid() && (index != selectionModel()->currentIndex()) && (index.flags() & Qt::ItemIsEnabled)) { selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } } } -void InstanceView::mouseReleaseEvent(QMouseEvent *event) +void InstanceView::mouseReleaseEvent(QMouseEvent* event) { executeDelayedItemsLayout(); @@ -405,13 +363,11 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event) VisualGroup::HitResults hitresult; - bool click = (index == m_pressedIndex && index.isValid()) || - (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult)); + bool click = + (index == m_pressedIndex && index.isValid()) || (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult)); - if (click && m_pressedCategory) - { - if (state() == ExpandingState) - { + if (click && m_pressedCategory) { + if (state() == ExpandingState) { m_pressedCategory->collapsed = false; emit groupStateChanged(m_pressedCategory->text, false); @@ -421,9 +377,7 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event) m_pressedCategory = nullptr; setState(NoState); return; - } - else if (state() == CollapsingState) - { + } else if (state() == CollapsingState) { m_pressedCategory->collapsed = true; emit groupStateChanged(m_pressedCategory->text, true); @@ -440,10 +394,8 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event) setState(NoState); - if (click) - { - if (event->button() == Qt::LeftButton) - { + if (click) { + if (event->button() == Qt::LeftButton) { emit clicked(index); } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -452,34 +404,24 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event) #else QStyleOptionViewItem option = viewOptions(); #endif - if (m_pressedAlreadySelected) - { + if (m_pressedAlreadySelected) { option.state |= QStyle::State_Selected; } if ((model()->flags(index) & Qt::ItemIsEnabled) && - style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) - { + style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) { emit activated(index); } } } -void InstanceView::mouseDoubleClickEvent(QMouseEvent *event) +void InstanceView::mouseDoubleClickEvent(QMouseEvent* event) { executeDelayedItemsLayout(); QModelIndex index = indexAt(event->pos()); - if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index)) - { - QMouseEvent me( - QEvent::MouseButtonPress, - event->localPos(), - event->windowPos(), - event->screenPos(), - event->button(), - event->buttons(), - event->modifiers() - ); + if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index)) { + QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(), event->screenPos(), event->button(), + event->buttons(), event->modifiers()); mousePressEvent(&me); return; } @@ -493,8 +435,7 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent *event) #else QStyleOptionViewItem option = viewOptions(); #endif - if ((model()->flags(index) & Qt::ItemIsEnabled) && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) - { + if ((model()->flags(index) & Qt::ItemIsEnabled) && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) { emit activated(index); } } @@ -537,9 +478,8 @@ void InstanceView::paintEvent(QPaintEvent* event) int wpWidth = viewport()->width(); option.rect.setWidth(wpWidth); - for (int i = 0; i < m_groups.size(); ++i) - { - VisualGroup *category = m_groups.at(i); + for (int i = 0; i < m_groups.size(); ++i) { + VisualGroup* category = m_groups.at(i); int y = category->verticalPosition(); y -= verticalOffset(); QRect backup = option.rect; @@ -553,28 +493,21 @@ void InstanceView::paintEvent(QPaintEvent* event) option.rect = backup; } - for (int i = 0; i < model()->rowCount(); ++i) - { + for (int i = 0; i < model()->rowCount(); ++i) { const QModelIndex index = model()->index(i, 0); - if (isIndexHidden(index)) - { + if (isIndexHidden(index)) { continue; } Qt::ItemFlags flags = index.flags(); option.rect = visualRect(index); option.features |= QStyleOptionViewItem::WrapText; - if (flags & Qt::ItemIsSelectable && selectionModel()->isSelected(index)) - { - option.state |= selectionModel()->isSelected(index) ? QStyle::State_Selected - : QStyle::State_None; - } - else - { + if (flags & Qt::ItemIsSelectable && selectionModel()->isSelected(index)) { + option.state |= selectionModel()->isSelected(index) ? QStyle::State_Selected : QStyle::State_None; + } else { option.state &= ~QStyle::State_Selected; } option.state |= (index == currentIndex()) ? QStyle::State_HasFocus : QStyle::State_None; - if (!(flags & Qt::ItemIsEnabled)) - { + if (!(flags & Qt::ItemIsEnabled)) { option.state &= ~QStyle::State_Enabled; } itemDelegate()->paint(&painter, option, index); @@ -612,27 +545,23 @@ void InstanceView::paintEvent(QPaintEvent* event) #endif } -void InstanceView::resizeEvent(QResizeEvent *event) +void InstanceView::resizeEvent(QResizeEvent* event) { int newItemsPerRow = calculateItemsPerRow(); - if(newItemsPerRow != m_currentItemsPerRow) - { + if (newItemsPerRow != m_currentItemsPerRow) { m_currentCursorColumn = -1; m_currentItemsPerRow = newItemsPerRow; updateGeometries(); - } - else - { + } else { updateScrollbar(); } } -void InstanceView::dragEnterEvent(QDragEnterEvent *event) +void InstanceView::dragEnterEvent(QDragEnterEvent* event) { executeDelayedItemsLayout(); - if (!isDragEventAccepted(event)) - { + if (!isDragEventAccepted(event)) { return; } m_lastDragPosition = event->pos() + offset(); @@ -640,12 +569,11 @@ void InstanceView::dragEnterEvent(QDragEnterEvent *event) event->accept(); } -void InstanceView::dragMoveEvent(QDragMoveEvent *event) +void InstanceView::dragMoveEvent(QDragMoveEvent* event) { executeDelayedItemsLayout(); - if (!isDragEventAccepted(event)) - { + if (!isDragEventAccepted(event)) { return; } m_lastDragPosition = event->pos() + offset(); @@ -653,7 +581,7 @@ void InstanceView::dragMoveEvent(QDragMoveEvent *event) event->accept(); } -void InstanceView::dragLeaveEvent(QDragLeaveEvent *event) +void InstanceView::dragLeaveEvent(QDragLeaveEvent* event) { executeDelayedItemsLayout(); @@ -661,7 +589,7 @@ void InstanceView::dragLeaveEvent(QDragLeaveEvent *event) viewport()->update(); } -void InstanceView::dropEvent(QDropEvent *event) +void InstanceView::dropEvent(QDropEvent* event) { executeDelayedItemsLayout(); @@ -672,16 +600,13 @@ void InstanceView::dropEvent(QDropEvent *event) auto mimedata = event->mimeData(); - if (event->source() == this) - { - if(event->possibleActions() & Qt::MoveAction) - { - std::pair dropPos = rowDropPos(event->pos()); - const VisualGroup *group = dropPos.first; + if (event->source() == this) { + if (event->possibleActions() & Qt::MoveAction) { + std::pair dropPos = rowDropPos(event->pos()); + const VisualGroup* group = dropPos.first; auto hitresult = dropPos.second; - if (hitresult == VisualGroup::HitResult::NoHit) - { + if (hitresult == VisualGroup::HitResult::NoHit) { viewport()->update(); return; } @@ -698,14 +623,12 @@ void InstanceView::dropEvent(QDropEvent *event) } // check if the action is supported - if (!mimedata) - { + if (!mimedata) { return; } // files dropped from outside? - if (mimedata->hasUrls()) - { + if (mimedata->hasUrls()) { auto urls = mimedata->urls(); event->accept(); emit droppedURLs(urls); @@ -717,57 +640,52 @@ void InstanceView::startDrag(Qt::DropActions supportedActions) executeDelayedItemsLayout(); QModelIndexList indexes = selectionModel()->selectedIndexes(); - if(indexes.count() == 0) + if (indexes.count() == 0) return; - QMimeData *data = model()->mimeData(indexes); - if (!data) - { + QMimeData* data = model()->mimeData(indexes); + if (!data) { return; } QRect rect; QPixmap pixmap = renderToPixmap(indexes, &rect); - QDrag *drag = new QDrag(this); + QDrag* drag = new QDrag(this); drag->setPixmap(pixmap); drag->setMimeData(data); drag->setHotSpot(m_pressedPosition - rect.topLeft()); Qt::DropAction defaultDropAction = Qt::IgnoreAction; - if (this->defaultDropAction() != Qt::IgnoreAction && (supportedActions & this->defaultDropAction())) - { + if (this->defaultDropAction() != Qt::IgnoreAction && (supportedActions & this->defaultDropAction())) { defaultDropAction = this->defaultDropAction(); } /*auto action = */ drag->exec(supportedActions, defaultDropAction); } -QRect InstanceView::visualRect(const QModelIndex &index) const +QRect InstanceView::visualRect(const QModelIndex& index) const { const_cast(this)->executeDelayedItemsLayout(); return geometryRect(index).translated(-offset()); } -QRect InstanceView::geometryRect(const QModelIndex &index) const +QRect InstanceView::geometryRect(const QModelIndex& index) const { const_cast(this)->executeDelayedItemsLayout(); - if (!index.isValid() || isIndexHidden(index) || index.column() > 0) - { + if (!index.isValid() || isIndexHidden(index) || index.column() > 0) { return QRect(); } int row = index.row(); - if(geometryCache.contains(row)) - { + if (geometryCache.contains(row)) { return *geometryCache[row]; } - const VisualGroup *cat = category(index); + const VisualGroup* cat = category(index); QPair pos = cat->positionOf(index); int x = pos.first; // int y = pos.second; - #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStyleOptionViewItem option; initViewItemOption(&option); @@ -783,43 +701,38 @@ QRect InstanceView::geometryRect(const QModelIndex &index) const return out; } -QModelIndex InstanceView::indexAt(const QPoint &point) const +QModelIndex InstanceView::indexAt(const QPoint& point) const { const_cast(this)->executeDelayedItemsLayout(); - for (int i = 0; i < model()->rowCount(); ++i) - { + for (int i = 0; i < model()->rowCount(); ++i) { QModelIndex index = model()->index(i, 0); - if (visualRect(index).contains(point)) - { + if (visualRect(index).contains(point)) { return index; } } return QModelIndex(); } -void InstanceView::setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) +void InstanceView::setSelection(const QRect& rect, const QItemSelectionModel::SelectionFlags commands) { executeDelayedItemsLayout(); - for (int i = 0; i < model()->rowCount(); ++i) - { + for (int i = 0; i < model()->rowCount(); ++i) { QModelIndex index = model()->index(i, 0); QRect itemRect = visualRect(index); - if (itemRect.intersects(rect)) - { + if (itemRect.intersects(rect)) { selectionModel()->select(index, commands); update(itemRect.translated(-offset())); } } } -QPixmap InstanceView::renderToPixmap(const QModelIndexList &indices, QRect *r) const +QPixmap InstanceView::renderToPixmap(const QModelIndexList& indices, QRect* r) const { Q_ASSERT(r); auto paintPairs = draggablePaintPairs(indices, r); - if (paintPairs.isEmpty()) - { + if (paintPairs.isEmpty()) { return QPixmap(); } QPixmap pixmap(r->size()); @@ -832,23 +745,21 @@ QPixmap InstanceView::renderToPixmap(const QModelIndexList &indices, QRect *r) c QStyleOptionViewItem option = viewOptions(); #endif option.state |= QStyle::State_Selected; - for (int j = 0; j < paintPairs.count(); ++j) - { + for (int j = 0; j < paintPairs.count(); ++j) { option.rect = paintPairs.at(j).first.translated(-r->topLeft()); - const QModelIndex ¤t = paintPairs.at(j).second; + const QModelIndex& current = paintPairs.at(j).second; itemDelegate()->paint(&painter, option, current); } return pixmap; } -QList> InstanceView::draggablePaintPairs(const QModelIndexList &indices, QRect *r) const +QList> InstanceView::draggablePaintPairs(const QModelIndexList& indices, QRect* r) const { Q_ASSERT(r); - QRect &rect = *r; + QRect& rect = *r; QList> ret; - for (int i = 0; i < indices.count(); ++i) - { - const QModelIndex &index = indices.at(i); + for (int i = 0; i < indices.count(); ++i) { + const QModelIndex& index = indices.at(i); const QRect current = geometryRect(index); ret += std::make_pair(current, index); rect |= current; @@ -856,12 +767,12 @@ QList> InstanceView::draggablePaintPairs(const QMo return ret; } -bool InstanceView::isDragEventAccepted(QDropEvent *event) +bool InstanceView::isDragEventAccepted(QDropEvent* event) { return true; } -std::pair InstanceView::rowDropPos(const QPoint &pos) +std::pair InstanceView::rowDropPos(const QPoint& pos) { VisualGroup::HitResults hitresult; auto group = categoryAt(pos + offset(), hitresult); @@ -873,21 +784,18 @@ QPoint InstanceView::offset() const return QPoint(horizontalOffset(), verticalOffset()); } -QRegion InstanceView::visualRegionForSelection(const QItemSelection &selection) const +QRegion InstanceView::visualRegionForSelection(const QItemSelection& selection) const { QRegion region; - for (auto &range : selection) - { + for (auto& range : selection) { int start_row = range.top(); int end_row = range.bottom(); - for (int row = start_row; row <= end_row; ++row) - { + for (int row = start_row; row <= end_row; ++row) { int start_column = range.left(); int end_column = range.right(); - for (int column = start_column; column <= end_column; ++column) - { + for (int column = start_column; column <= end_column; ++column) { QModelIndex index = model()->index(row, column, rootIndex()); - region += visualRect(index); // OK + region += visualRect(index); // OK } } } @@ -897,122 +805,97 @@ QRegion InstanceView::visualRegionForSelection(const QItemSelection &selection) QModelIndex InstanceView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers) { auto current = currentIndex(); - if(!current.isValid()) - { + if (!current.isValid()) { return current; } auto cat = category(current); int group_index = m_groups.indexOf(cat); - if(group_index < 0) + if (group_index < 0) return current; QPair pos = cat->positionOf(current); int column = pos.first; int row = pos.second; - if(m_currentCursorColumn < 0) - { + if (m_currentCursorColumn < 0) { m_currentCursorColumn = column; } - switch(cursorAction) - { - case MoveUp: - { - if(row == 0) - { - int prevgroupindex = group_index-1; - while(prevgroupindex >= 0) - { + switch (cursorAction) { + case MoveUp: { + if (row == 0) { + int prevgroupindex = group_index - 1; + while (prevgroupindex >= 0) { auto prevgroup = m_groups[prevgroupindex]; - if(prevgroup->collapsed) - { + if (prevgroup->collapsed) { prevgroupindex--; continue; } int newRow = prevgroup->numRows() - 1; int newRowSize = prevgroup->rows[newRow].size(); int newColumn = m_currentCursorColumn; - if (m_currentCursorColumn >= newRowSize) - { + if (m_currentCursorColumn >= newRowSize) { newColumn = newRowSize - 1; } return prevgroup->rows[newRow][newColumn]; } - } - else - { + } else { int newRow = row - 1; int newRowSize = cat->rows[newRow].size(); int newColumn = m_currentCursorColumn; - if (m_currentCursorColumn >= newRowSize) - { + if (m_currentCursorColumn >= newRowSize) { newColumn = newRowSize - 1; } return cat->rows[newRow][newColumn]; } return current; } - case MoveDown: - { - if(row == cat->rows.size() - 1) - { - int nextgroupindex = group_index+1; - while (nextgroupindex < m_groups.size()) - { + case MoveDown: { + if (row == cat->rows.size() - 1) { + int nextgroupindex = group_index + 1; + while (nextgroupindex < m_groups.size()) { auto nextgroup = m_groups[nextgroupindex]; - if(nextgroup->collapsed) - { + if (nextgroup->collapsed) { nextgroupindex++; continue; } int newRowSize = nextgroup->rows[0].size(); int newColumn = m_currentCursorColumn; - if (m_currentCursorColumn >= newRowSize) - { + if (m_currentCursorColumn >= newRowSize) { newColumn = newRowSize - 1; } return nextgroup->rows[0][newColumn]; } - } - else - { + } else { int newRow = row + 1; int newRowSize = cat->rows[newRow].size(); int newColumn = m_currentCursorColumn; - if (m_currentCursorColumn >= newRowSize) - { + if (m_currentCursorColumn >= newRowSize) { newColumn = newRowSize - 1; } return cat->rows[newRow][newColumn]; } return current; } - case MoveLeft: - { - if(column > 0) - { + case MoveLeft: { + if (column > 0) { m_currentCursorColumn = column - 1; return cat->rows[row][column - 1]; } // TODO: moving to previous line return current; } - case MoveRight: - { - if(column < cat->rows[row].size() - 1) - { + case MoveRight: { + if (column < cat->rows[row].size() - 1) { m_currentCursorColumn = column + 1; return cat->rows[row][column + 1]; } // TODO: moving to next line return current; } - case MoveHome: - { + case MoveHome: { m_currentCursorColumn = 0; return cat->rows[row][0]; } - case MoveEnd: - { + case MoveEnd: { auto last = cat->rows[row].size() - 1; m_currentCursorColumn = last; return cat->rows[row][last]; @@ -1039,14 +922,13 @@ void InstanceView::scrollContentsBy(int dx, int dy) viewport()->scroll(dx, dy); } -void InstanceView::scrollTo(const QModelIndex &index, ScrollHint hint) +void InstanceView::scrollTo(const QModelIndex& index, ScrollHint hint) { if (!index.isValid()) return; const QRect rect = visualRect(index); - if (hint == EnsureVisible && viewport()->rect().contains(rect)) - { + if (hint == EnsureVisible && viewport()->rect().contains(rect)) { viewport()->update(rect); return; } @@ -1054,7 +936,7 @@ void InstanceView::scrollTo(const QModelIndex &index, ScrollHint hint) verticalScrollBar()->setValue(verticalScrollToValue(index, rect, hint)); } -int InstanceView::verticalScrollToValue(const QModelIndex &index, const QRect &rect, QListView::ScrollHint hint) const +int InstanceView::verticalScrollToValue(const QModelIndex& index, const QRect& rect, QListView::ScrollHint hint) const { const QRect area = viewport()->rect(); const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top()); diff --git a/launcher/ui/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index 364056751..11892b227 100644 --- a/launcher/ui/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h @@ -35,95 +35,86 @@ #pragma once -#include -#include -#include #include -#include "VisualGroup.h" +#include +#include +#include #include +#include "VisualGroup.h" -struct InstanceViewRoles -{ - enum - { - GroupRole = Qt::UserRole, - ProgressValueRole, - ProgressMaximumRole - }; +struct InstanceViewRoles { + enum { GroupRole = Qt::UserRole, ProgressValueRole, ProgressMaximumRole }; }; -class InstanceView : public QAbstractItemView -{ +class InstanceView : public QAbstractItemView { Q_OBJECT -public: - InstanceView(QWidget *parent = 0); + public: + InstanceView(QWidget* parent = 0); ~InstanceView(); - void setModel(QAbstractItemModel *model) override; + void setModel(QAbstractItemModel* model) override; - using visibilityFunction = std::function; - void setSourceOfGroupCollapseStatus(visibilityFunction f) { - fVisibility = f; - } + using visibilityFunction = std::function; + void setSourceOfGroupCollapseStatus(visibilityFunction f) { fVisibility = f; } /// return geometry rectangle occupied by the specified model item - QRect geometryRect(const QModelIndex &index) const; + QRect geometryRect(const QModelIndex& index) const; /// return visual rectangle occupied by the specified model item - virtual QRect visualRect(const QModelIndex &index) const override; + virtual QRect visualRect(const QModelIndex& index) const override; /// get the model index at the specified visual point - virtual QModelIndex indexAt(const QPoint &point) const override; - QString groupNameAt(const QPoint &point); - void setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) override; + virtual QModelIndex indexAt(const QPoint& point) const override; + QString groupNameAt(const QPoint& point); + void setSelection(const QRect& rect, const QItemSelectionModel::SelectionFlags commands) override; virtual int horizontalOffset() const override; virtual int verticalOffset() const override; virtual void scrollContentsBy(int dx, int dy) override; - virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; + virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible) override; virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override; - virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override; + virtual QRegion visualRegionForSelection(const QItemSelection& selection) const override; int spacing() const { return m_spacing; }; void setPaintCat(bool visible); -public slots: + public slots: virtual void updateGeometries() override; -protected slots: - virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) override; - virtual void rowsInserted(const QModelIndex &parent, int start, int end) override; - virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override; + protected slots: + virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles) override; + virtual void rowsInserted(const QModelIndex& parent, int start, int end) override; + virtual void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; void modelReset(); void rowsRemoved(); - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; + void currentChanged(const QModelIndex& current, const QModelIndex& previous) override; -signals: + signals: void droppedURLs(QList urls); void groupStateChanged(QString group, bool collapsed); -protected: - bool isIndexHidden(const QModelIndex &index) const override; - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - void paintEvent(QPaintEvent *event) override; - void resizeEvent(QResizeEvent *event) override; + protected: + bool isIndexHidden(const QModelIndex& index) const override; + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; + void paintEvent(QPaintEvent* event) override; + void resizeEvent(QResizeEvent* event) override; - void dragEnterEvent(QDragEnterEvent *event) override; - void dragMoveEvent(QDragMoveEvent *event) override; - void dragLeaveEvent(QDragLeaveEvent *event) override; - void dropEvent(QDropEvent *event) override; + void dragEnterEvent(QDragEnterEvent* event) override; + void dragMoveEvent(QDragMoveEvent* event) override; + void dragLeaveEvent(QDragLeaveEvent* event) override; + void dropEvent(QDropEvent* event) override; void startDrag(Qt::DropActions supportedActions) override; void updateScrollbar(); -private: + private: friend struct VisualGroup; - QList m_groups; + QList m_groups; visibilityFunction fVisibility; @@ -135,7 +126,7 @@ private: int m_spacing = 5; int m_itemWidth = 100; int m_currentItemsPerRow = -1; - int m_currentCursorColumn= -1; + int m_currentCursorColumn = -1; mutable QCache geometryCache; bool m_catVisible = false; QPixmap m_catPixmap; @@ -144,30 +135,27 @@ private: QPoint m_pressedPosition; QPersistentModelIndex m_pressedIndex; bool m_pressedAlreadySelected; - VisualGroup *m_pressedCategory; + VisualGroup* m_pressedCategory; QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag; QPoint m_lastDragPosition; - VisualGroup *category(const QModelIndex &index) const; - VisualGroup *category(const QString &cat) const; - VisualGroup *categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const; + VisualGroup* category(const QModelIndex& index) const; + VisualGroup* category(const QString& cat) const; + VisualGroup* categoryAt(const QPoint& pos, VisualGroup::HitResults& result) const; - int itemsPerRow() const - { - return m_currentItemsPerRow; - }; + int itemsPerRow() const { return m_currentItemsPerRow; }; int contentWidth() const; -private: /* methods */ + private: /* methods */ int itemWidth() const; int calculateItemsPerRow() const; - int verticalScrollToValue(const QModelIndex &index, const QRect &rect, QListView::ScrollHint hint) const; - QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const; - QList> draggablePaintPairs(const QModelIndexList &indices, QRect *r) const; + int verticalScrollToValue(const QModelIndex& index, const QRect& rect, QListView::ScrollHint hint) const; + QPixmap renderToPixmap(const QModelIndexList& indices, QRect* r) const; + QList> draggablePaintPairs(const QModelIndexList& indices, QRect* r) const; - bool isDragEventAccepted(QDropEvent *event); + bool isDragEventAccepted(QDropEvent* event); - std::pair rowDropPos(const QPoint &pos); + std::pair rowDropPos(const QPoint& pos); QPoint offset() const; }; diff --git a/launcher/ui/instanceview/VisualGroup.h b/launcher/ui/instanceview/VisualGroup.h index 697298c2d..8c6f06bcc 100644 --- a/launcher/ui/instanceview/VisualGroup.h +++ b/launcher/ui/instanceview/VisualGroup.h @@ -35,56 +35,48 @@ #pragma once -#include #include -#include +#include #include +#include class InstanceView; class QPainter; class QModelIndex; -struct VisualRow -{ +struct VisualRow { QList items; int height = 0; int top = 0; - inline int size() const - { - return items.size(); - } - inline QModelIndex &operator[](int i) - { - return items[i]; - } + inline int size() const { return items.size(); } + inline QModelIndex& operator[](int i) { return items[i]; } }; -struct VisualGroup -{ -/* constructors */ - VisualGroup(QString text, InstanceView *view); - explicit VisualGroup(const VisualGroup *other); +struct VisualGroup { + /* constructors */ + VisualGroup(QString text, InstanceView* view); + explicit VisualGroup(const VisualGroup* other); -/* data */ - InstanceView *view = nullptr; + /* data */ + InstanceView* view = nullptr; QString text; bool collapsed = false; QVector rows; int firstItemIndex = 0; int m_verticalPosition = 0; -/* logic */ + /* logic */ /// update the internal list of items and flow them into the rows. void update(); /// draw the header at y-position. - void drawHeader(QPainter *painter, const QStyleOptionViewItem &option) const; + void drawHeader(QPainter* painter, const QStyleOptionViewItem& option) const; /// height of the group, in total. includes a small bit of padding. int totalHeight() const; /// height of the group header, in pixels - static int headerHeight() ; + static int headerHeight(); /// height of the group content, in pixels int contentHeight() const; @@ -99,26 +91,19 @@ struct VisualGroup int verticalPosition() const; /// relative geometry - top of the row of the given item - int rowTopOf(const QModelIndex &index) const; + int rowTopOf(const QModelIndex& index) const; /// height of the row of the given item - int rowHeightOf(const QModelIndex &index) const; + int rowHeightOf(const QModelIndex& index) const; /// x/y position of the given item inside the group (in items!) - QPair positionOf(const QModelIndex &index) const; + QPair positionOf(const QModelIndex& index) const; - enum HitResult - { - NoHit = 0x0, - TextHit = 0x1, - CheckboxHit = 0x2, - HeaderHit = 0x4, - BodyHit = 0x8 - }; + enum HitResult { NoHit = 0x0, TextHit = 0x1, CheckboxHit = 0x2, HeaderHit = 0x4, BodyHit = 0x8 }; Q_DECLARE_FLAGS(HitResults, HitResult) /// shoot! BANG! what did we hit? - HitResults hitScan (const QPoint &pos) const; + HitResults hitScan(const QPoint& pos) const; QList items() const; }; diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index 18d61dc2f..6514217cd 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -16,9 +16,9 @@ #include "PageDialog.h" #include +#include #include #include -#include #include "Application.h" #include "settings/SettingsObject.h" @@ -26,19 +26,18 @@ #include "ui/widgets/IconLabel.h" #include "ui/widgets/PageContainer.h" -PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidget *parent) - : QDialog(parent) +PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidget* parent) : QDialog(parent) { setWindowTitle(pageProvider->dialogTitle()); m_container = new PageContainer(pageProvider, defaultId, this); - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addWidget(m_container); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0, 0, 0, 0); setLayout(mainLayout); - QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close); + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close); buttons->button(QDialogButtonBox::Close)->setDefault(true); buttons->setContentsMargins(6, 0, 6, 0); m_container->addButtons(buttons); @@ -49,11 +48,10 @@ PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidge restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } -void PageDialog::closeEvent(QCloseEvent *event) +void PageDialog::closeEvent(QCloseEvent* event) { qDebug() << "Paged dialog close requested"; - if (m_container->prepareToClose()) - { + if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); qDebug() << "Paged dialog geometry saved"; diff --git a/launcher/ui/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index 00d8b725b..aa50bc5e1 100644 --- a/launcher/ui/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -19,17 +19,15 @@ #include "ui/pages/BasePageProvider.h" class PageContainer; -class PageDialog : public QDialog -{ +class PageDialog : public QDialog { Q_OBJECT -public: - explicit PageDialog(BasePageProvider *pageProvider, QString defaultId = QString(), QWidget *parent = 0); + public: + explicit PageDialog(BasePageProvider* pageProvider, QString defaultId = QString(), QWidget* parent = 0); virtual ~PageDialog() {} -private -slots: - virtual void closeEvent(QCloseEvent *event); + private slots: + virtual void closeEvent(QCloseEvent* event); -private: - PageContainer * m_container; + private: + PageContainer* m_container; }; diff --git a/launcher/ui/pages/BasePageContainer.h b/launcher/ui/pages/BasePageContainer.h index b41fe12af..b750e8272 100644 --- a/launcher/ui/pages/BasePageContainer.h +++ b/launcher/ui/pages/BasePageContainer.h @@ -2,9 +2,8 @@ class BasePage; -class BasePageContainer -{ -public: +class BasePageContainer { + public: virtual ~BasePageContainer(){}; virtual bool selectPage(QString pageId) = 0; virtual BasePage* getPage(QString pageId) { return nullptr; }; diff --git a/launcher/ui/pages/BasePageProvider.h b/launcher/ui/pages/BasePageProvider.h index 873e8dce2..4c3ecd6c1 100644 --- a/launcher/ui/pages/BasePageProvider.h +++ b/launcher/ui/pages/BasePageProvider.h @@ -15,54 +15,43 @@ #pragma once -#include "ui/pages/BasePage.h" -#include #include +#include +#include "ui/pages/BasePage.h" -class BasePageProvider -{ -public: - virtual QList getPages() = 0; +class BasePageProvider { + public: + virtual QList getPages() = 0; virtual QString dialogTitle() = 0; }; -class GenericPageProvider : public BasePageProvider -{ - typedef std::function PageCreator; -public: - explicit GenericPageProvider(const QString &dialogTitle) - : m_dialogTitle(dialogTitle) - { - } +class GenericPageProvider : public BasePageProvider { + typedef std::function PageCreator; + + public: + explicit GenericPageProvider(const QString& dialogTitle) : m_dialogTitle(dialogTitle) {} virtual ~GenericPageProvider() {} - QList getPages() override + QList getPages() override { - QList pages; - for (PageCreator creator : m_creators) - { + QList pages; + for (PageCreator creator : m_creators) { pages.append(creator()); } return pages; } QString dialogTitle() override { return m_dialogTitle; } - void setDialogTitle(const QString &title) - { - m_dialogTitle = title; - } - void addPageCreator(PageCreator page) - { - m_creators.append(page); - } + void setDialogTitle(const QString& title) { m_dialogTitle = title; } + void addPageCreator(PageCreator page) { m_creators.append(page); } - template + template void addPage() { - addPageCreator([](){return new PageClass();}); + addPageCreator([]() { return new PageClass(); }); } -private: + private: QList m_creators; QString m_dialogTitle; }; diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index 668aa0078..82aa76a4f 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -39,37 +39,30 @@ #include "APIPage.h" #include "ui_APIPage.h" -#include #include +#include #include #include #include #include #include +#include "Application.h" +#include "BuildConfig.h" +#include "net/PasteUpload.h" #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" -#include "Application.h" -#include "net/PasteUpload.h" -#include "BuildConfig.h" -APIPage::APIPage(QWidget *parent) : - QWidget(parent), - ui(new Ui::APIPage) +APIPage::APIPage(QWidget* parent) : QWidget(parent), ui(new Ui::APIPage) { // This is here so you can reorder the entries in the combobox without messing stuff up - int comboBoxEntries[] = { - PasteUpload::PasteType::Mclogs, - PasteUpload::PasteType::NullPointer, - PasteUpload::PasteType::PasteGG, - PasteUpload::PasteType::Hastebin - }; + int comboBoxEntries[] = { PasteUpload::PasteType::Mclogs, PasteUpload::PasteType::NullPointer, PasteUpload::PasteType::PasteGG, + PasteUpload::PasteType::Hastebin }; static QRegularExpression validUrlRegExp("https?://.+"); - static QRegularExpression validMSAClientID(QRegularExpression::anchoredPattern( - "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")); - static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern( - "\\$2[ayb]\\$.{56}")); + static QRegularExpression validMSAClientID( + QRegularExpression::anchoredPattern("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")); + static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern("\\$2[ayb]\\$.{56}")); ui->setupUi(this); @@ -77,7 +70,7 @@ APIPage::APIPage(QWidget *parent) : ui->pasteTypeComboBox->addItem(PasteUpload::PasteTypes.at(pasteType).name, pasteType); } - void (QComboBox::*currentIndexChangedSignal)(int) (&QComboBox::currentIndexChanged); + void (QComboBox::*currentIndexChangedSignal)(int)(&QComboBox::currentIndexChanged); connect(ui->pasteTypeComboBox, currentIndexChangedSignal, this, &APIPage::updateBaseURLPlaceholder); // This function needs to be called even when the ComboBox's index is still in its default state. updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex()); @@ -110,12 +103,9 @@ void APIPage::resetBaseURLNote() void APIPage::updateBaseURLNote(int index) { - if (baseURLPasteType == index) - { + if (baseURLPasteType == index) { ui->baseURLNote->hide(); - } - else if (!ui->baseURLEntry->text().isEmpty()) - { + } else if (!ui->baseURLEntry->text().isEmpty()) { ui->baseURLNote->show(); } } @@ -136,8 +126,7 @@ void APIPage::loadSettings() ui->baseURLEntry->setText(pastebinURL); int pasteTypeIndex = ui->pasteTypeComboBox->findData(pasteType); - if (pasteTypeIndex == -1) - { + if (pasteTypeIndex == -1) { pasteTypeIndex = ui->pasteTypeComboBox->findData(PasteUpload::PasteType::Mclogs); ui->baseURLEntry->clear(); } @@ -167,15 +156,13 @@ void APIPage::applySettings() s->set("MSAClientIDOverride", msaClientID); QUrl metaURL(ui->metaURL->text()); // Add required trailing slash - if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) - { + if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) { QString path = metaURL.path(); path.append('/'); metaURL.setPath(path); } // Don't allow HTTP, since meta is basically RCE with all the jar files. - if(!metaURL.isEmpty() && metaURL.scheme() == "http") - { + if (!metaURL.isEmpty() && metaURL.scheme() == "http") { metaURL.setScheme("https"); } diff --git a/launcher/ui/pages/global/APIPage.h b/launcher/ui/pages/global/APIPage.h index 17e62ae7f..8d8f06454 100644 --- a/launcher/ui/pages/global/APIPage.h +++ b/launcher/ui/pages/global/APIPage.h @@ -39,41 +39,28 @@ #include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" namespace Ui { class APIPage; } -class APIPage : public QWidget, public BasePage -{ +class APIPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit APIPage(QWidget *parent = 0); + public: + explicit APIPage(QWidget* parent = 0); ~APIPage(); - QString displayName() const override - { - return tr("APIs"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("worlds"); - } - QString id() const override - { - return "apis"; - } - QString helpPage() const override - { - return "APIs"; - } + QString displayName() const override { return tr("APIs"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("worlds"); } + QString id() const override { return "apis"; } + QString helpPage() const override { return "APIs"; } virtual bool apply() override; void retranslate() override; -private: + private: int baseURLPasteType; void resetBaseURLNote(); void updateBaseURLNote(int index); @@ -81,7 +68,6 @@ private: void loadSettings(); void applySettings(); -private: - Ui::APIPage *ui; + private: + Ui::APIPage* ui; }; - diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index fced5ff4a..41e78bf4d 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -44,29 +44,27 @@ #include "net/NetJob.h" -#include "ui/dialogs/ProgressDialog.h" -#include "ui/dialogs/OfflineLoginDialog.h" +#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/LoginDialog.h" #include "ui/dialogs/MSALoginDialog.h" -#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/OfflineLoginDialog.h" +#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/SkinUploadDialog.h" -#include "tasks/Task.h" #include "minecraft/auth/AccountTask.h" #include "minecraft/services/SkinDelete.h" +#include "tasks/Task.h" #include "Application.h" #include "BuildConfig.h" -AccountListPage::AccountListPage(QWidget *parent) - : QMainWindow(parent), ui(new Ui::AccountListPage) +AccountListPage::AccountListPage(QWidget* parent) : QMainWindow(parent), ui(new Ui::AccountListPage) { ui->setupUi(this); - ui->listView->setEmptyString(tr( - "Welcome!\n" - "If you're new here, you can click the \"Add\" button to add your Mojang or Minecraft account." - )); + ui->listView->setEmptyString( + tr("Welcome!\n" + "If you're new here, you can click the \"Add\" button to add your Mojang or Minecraft account.")); ui->listView->setEmptyMode(VersionListView::String); ui->listView->setContextMenuPolicy(Qt::CustomContextMenu); @@ -82,11 +80,10 @@ AccountListPage::AccountListPage(QWidget *parent) // Expand the account column - QItemSelectionModel *selectionModel = ui->listView->selectionModel(); + QItemSelectionModel* selectionModel = ui->listView->selectionModel(); - connect(selectionModel, &QItemSelectionModel::selectionChanged, [this](const QItemSelection &sel, const QItemSelection &dsel) { - updateButtonStates(); - }); + connect(selectionModel, &QItemSelectionModel::selectionChanged, + [this](const QItemSelection& sel, const QItemSelection& dsel) { updateButtonStates(); }); connect(ui->listView, &VersionListView::customContextMenuRequested, this, &AccountListPage::ShowContextMenu); connect(m_accounts.get(), &AccountList::listChanged, this, &AccountListPage::listChanged); @@ -121,21 +118,19 @@ void AccountListPage::ShowContextMenu(const QPoint& pos) void AccountListPage::changeEvent(QEvent* event) { - if (event->type() == QEvent::LanguageChange) - { + if (event->type() == QEvent::LanguageChange) { ui->retranslateUi(this); } QMainWindow::changeEvent(event); } -QMenu * AccountListPage::createPopupMenu() +QMenu* AccountListPage::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); - filteredMenu->removeAction(ui->toolBar->toggleViewAction() ); + filteredMenu->removeAction(ui->toolBar->toggleViewAction()); return filteredMenu; } - void AccountListPage::listChanged() { updateButtonStates(); @@ -143,13 +138,10 @@ void AccountListPage::listChanged() void AccountListPage::on_actionAddMojang_triggered() { - MinecraftAccountPtr account = LoginDialog::newAccount( - this, - tr("Please enter your Mojang account email and password to add your account.") - ); + MinecraftAccountPtr account = + LoginDialog::newAccount(this, tr("Please enter your Mojang account email and password to add your account.")); - if (account) - { + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { m_accounts->setDefaultAccount(account); @@ -159,13 +151,10 @@ void AccountListPage::on_actionAddMojang_triggered() void AccountListPage::on_actionAddMicrosoft_triggered() { - MinecraftAccountPtr account = MSALoginDialog::newAccount( - this, - tr("Please enter your Mojang account email and password to add your account.") - ); + MinecraftAccountPtr account = + MSALoginDialog::newAccount(this, tr("Please enter your Mojang account email and password to add your account.")); - if (account) - { + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { m_accounts->setDefaultAccount(account); @@ -176,25 +165,17 @@ void AccountListPage::on_actionAddMicrosoft_triggered() void AccountListPage::on_actionAddOffline_triggered() { if (!m_accounts->anyAccountIsValid()) { - QMessageBox::warning( - this, - tr("Error"), - tr( - "You must add a Microsoft or Mojang account that owns Minecraft before you can add an offline account." - "

    " - "If you have lost your account you can contact Microsoft for support." - ) - ); + QMessageBox::warning(this, tr("Error"), + tr("You must add a Microsoft or Mojang account that owns Minecraft before you can add an offline account." + "

    " + "If you have lost your account you can contact Microsoft for support.")); return; } - MinecraftAccountPtr account = OfflineLoginDialog::newAccount( - this, - tr("Please enter your desired username to add your offline account.") - ); + MinecraftAccountPtr account = + OfflineLoginDialog::newAccount(this, tr("Please enter your desired username to add your offline account.")); - if (account) - { + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { m_accounts->setDefaultAccount(account); @@ -205,14 +186,14 @@ void AccountListPage::on_actionAddOffline_triggered() void AccountListPage::on_actionRemove_triggered() { QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { + if (selection.size() > 0) { QModelIndex selected = selection.first(); m_accounts->removeAccount(selected); } } -void AccountListPage::on_actionRefresh_triggered() { +void AccountListPage::on_actionRefresh_triggered() +{ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); if (selection.size() > 0) { QModelIndex selected = selection.first(); @@ -221,12 +202,10 @@ void AccountListPage::on_actionRefresh_triggered() { } } - void AccountListPage::on_actionSetDefault_triggered() { QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { + if (selection.size() > 0) { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); m_accounts->setDefaultAccount(account); @@ -245,8 +224,7 @@ void AccountListPage::updateButtonStates() bool hasSelection = !selection.empty(); bool accountIsReady = false; bool accountIsOnline = false; - if (hasSelection) - { + if (hasSelection) { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); accountIsReady = !account->isActive(); @@ -258,11 +236,10 @@ void AccountListPage::updateButtonStates() ui->actionDeleteSkin->setEnabled(accountIsReady && accountIsOnline); ui->actionRefresh->setEnabled(accountIsReady && accountIsOnline); - if(m_accounts->defaultAccount().get() == nullptr) { + if (m_accounts->defaultAccount().get() == nullptr) { ui->actionNoDefault->setEnabled(false); ui->actionNoDefault->setChecked(true); - } - else { + } else { ui->actionNoDefault->setEnabled(true); ui->actionNoDefault->setChecked(false); } @@ -271,8 +248,7 @@ void AccountListPage::updateButtonStates() void AccountListPage::on_actionUploadSkin_triggered() { QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { + if (selection.size() > 0) { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); SkinUploadDialog dialog(account, this); diff --git a/launcher/ui/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h index 9395e92bf..483d7924f 100644 --- a/launcher/ui/pages/global/AccountListPage.h +++ b/launcher/ui/pages/global/AccountListPage.h @@ -41,47 +41,35 @@ #include "ui/pages/BasePage.h" -#include "minecraft/auth/AccountList.h" #include "Application.h" +#include "minecraft/auth/AccountList.h" -namespace Ui -{ +namespace Ui { class AccountListPage; } class AuthenticateTask; -class AccountListPage : public QMainWindow, public BasePage -{ +class AccountListPage : public QMainWindow, public BasePage { Q_OBJECT -public: - explicit AccountListPage(QWidget *parent = 0); + public: + explicit AccountListPage(QWidget* parent = 0); ~AccountListPage(); - QString displayName() const override - { - return tr("Accounts"); - } + QString displayName() const override { return tr("Accounts"); } QIcon icon() const override { auto icon = APPLICATION->getThemedIcon("accounts"); - if(icon.isNull()) - { + if (icon.isNull()) { icon = APPLICATION->getThemedIcon("noaccount"); } return icon; } - QString id() const override - { - return "accounts"; - } - QString helpPage() const override - { - return "Getting-Started#adding-an-account"; - } + QString id() const override { return "accounts"; } + QString helpPage() const override { return "Getting-Started#adding-an-account"; } void retranslate() override; -public slots: + public slots: void on_actionAddMojang_triggered(); void on_actionAddMicrosoft_triggered(); void on_actionAddOffline_triggered(); @@ -97,12 +85,12 @@ public slots: //! Updates the states of the dialog's buttons. void updateButtonStates(); -protected slots: - void ShowContextMenu(const QPoint &pos); + protected slots: + void ShowContextMenu(const QPoint& pos); -private: - void changeEvent(QEvent * event) override; - QMenu * createPopupMenu() override; + private: + void changeEvent(QEvent* event) override; + QMenu* createPopupMenu() override; shared_qobject_ptr m_accounts; - Ui::AccountListPage *ui; + Ui::AccountListPage* ui; }; diff --git a/launcher/ui/pages/global/CustomCommandsPage.cpp b/launcher/ui/pages/global/CustomCommandsPage.cpp index df1420ca6..fad69050b 100644 --- a/launcher/ui/pages/global/CustomCommandsPage.cpp +++ b/launcher/ui/pages/global/CustomCommandsPage.cpp @@ -35,13 +35,12 @@ */ #include "CustomCommandsPage.h" -#include -#include #include +#include +#include -CustomCommandsPage::CustomCommandsPage(QWidget* parent): QWidget(parent) +CustomCommandsPage::CustomCommandsPage(QWidget* parent) : QWidget(parent) { - auto verticalLayout = new QVBoxLayout(this); verticalLayout->setObjectName(QStringLiteral("verticalLayout")); verticalLayout->setContentsMargins(0, 0, 0, 0); @@ -56,9 +55,7 @@ CustomCommandsPage::CustomCommandsPage(QWidget* parent): QWidget(parent) loadSettings(); } -CustomCommandsPage::~CustomCommandsPage() -{ -} +CustomCommandsPage::~CustomCommandsPage() {} bool CustomCommandsPage::apply() { @@ -77,13 +74,8 @@ void CustomCommandsPage::applySettings() void CustomCommandsPage::loadSettings() { auto s = APPLICATION->settings(); - commands->initialize( - false, - true, - s->get("PreLaunchCommand").toString(), - s->get("WrapperCommand").toString(), - s->get("PostExitCommand").toString() - ); + commands->initialize(false, true, s->get("PreLaunchCommand").toString(), s->get("WrapperCommand").toString(), + s->get("PostExitCommand").toString()); } void CustomCommandsPage::retranslate() diff --git a/launcher/ui/pages/global/CustomCommandsPage.h b/launcher/ui/pages/global/CustomCommandsPage.h index 865503ff7..c69b02e5a 100644 --- a/launcher/ui/pages/global/CustomCommandsPage.h +++ b/launcher/ui/pages/global/CustomCommandsPage.h @@ -35,42 +35,29 @@ #pragma once -#include #include +#include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" #include "ui/widgets/CustomCommands.h" -class CustomCommandsPage : public QWidget, public BasePage -{ +class CustomCommandsPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit CustomCommandsPage(QWidget *parent = 0); + public: + explicit CustomCommandsPage(QWidget* parent = 0); ~CustomCommandsPage(); - QString displayName() const override - { - return tr("Custom Commands"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("custom-commands"); - } - QString id() const override - { - return "custom-commands"; - } - QString helpPage() const override - { - return "Custom-commands"; - } + QString displayName() const override { return tr("Custom Commands"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("custom-commands"); } + QString id() const override { return "custom-commands"; } + QString helpPage() const override { return "Custom-commands"; } bool apply() override; void retranslate() override; -private: + private: void applySettings(); void loadSettings(); - CustomCommands * commands; + CustomCommands* commands; }; diff --git a/launcher/ui/pages/global/ExternalToolsPage.cpp b/launcher/ui/pages/global/ExternalToolsPage.cpp index 5ba0ebc28..abe157f09 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.cpp +++ b/launcher/ui/pages/global/ExternalToolsPage.cpp @@ -36,20 +36,18 @@ #include "ExternalToolsPage.h" #include "ui_ExternalToolsPage.h" -#include #include +#include #include #include +#include +#include +#include "Application.h" #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" -#include -#include "Application.h" -#include -ExternalToolsPage::ExternalToolsPage(QWidget *parent) : - QWidget(parent), - ui(new Ui::ExternalToolsPage) +ExternalToolsPage::ExternalToolsPage(QWidget* parent) : QWidget(parent), ui(new Ui::ExternalToolsPage) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); @@ -87,12 +85,9 @@ void ExternalToolsPage::applySettings() // Editors QString jsonEditor = ui->jsonEditorTextBox->text(); - if (!jsonEditor.isEmpty() && - (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable())) - { + if (!jsonEditor.isEmpty() && (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable())) { QString found = QStandardPaths::findExecutable(jsonEditor); - if (!found.isEmpty()) - { + if (!found.isEmpty()) { jsonEditor = found; } } @@ -103,21 +98,16 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked() { QString raw_dir = ui->jprofilerPathEdit->text(); QString error; - do - { + do { raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Folder"), raw_dir); - if (raw_dir.isEmpty()) - { + if (raw_dir.isEmpty()) { break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!APPLICATION->profilers()["jprofiler"]->check(cooked_dir, &error)) - { + if (!APPLICATION->profilers()["jprofiler"]->check(cooked_dir, &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error)); continue; - } - else - { + } else { ui->jprofilerPathEdit->setText(cooked_dir); break; } @@ -126,12 +116,9 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked() void ExternalToolsPage::on_jprofilerCheckBtn_clicked() { QString error; - if (!APPLICATION->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) - { + if (!APPLICATION->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error)); - } - else - { + } else { QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK")); } } @@ -140,21 +127,16 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() { QString raw_dir = ui->jvisualvmPathEdit->text(); QString error; - do - { + do { raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir); - if (raw_dir.isEmpty()) - { + if (raw_dir.isEmpty()) { break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error)) - { + if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); continue; - } - else - { + } else { ui->jvisualvmPathEdit->setText(cooked_dir); break; } @@ -163,12 +145,9 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() void ExternalToolsPage::on_jvisualvmCheckBtn_clicked() { QString error; - if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) - { + if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); - } - else - { + } else { QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK")); } } @@ -177,25 +156,20 @@ void ExternalToolsPage::on_mceditPathBtn_clicked() { QString raw_dir = ui->mceditPathEdit->text(); QString error; - do - { + do { #ifdef Q_OS_OSX raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir); #else raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Folder"), raw_dir); #endif - if (raw_dir.isEmpty()) - { + if (raw_dir.isEmpty()) { break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!APPLICATION->mcedit()->check(cooked_dir, error)) - { + if (!APPLICATION->mcedit()->check(cooked_dir, error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error)); continue; - } - else - { + } else { ui->mceditPathEdit->setText(cooked_dir); break; } @@ -204,43 +178,34 @@ void ExternalToolsPage::on_mceditPathBtn_clicked() void ExternalToolsPage::on_mceditCheckBtn_clicked() { QString error; - if (!APPLICATION->mcedit()->check(ui->mceditPathEdit->text(), error)) - { + if (!APPLICATION->mcedit()->check(ui->mceditPathEdit->text(), error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error)); - } - else - { + } else { QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK")); } } void ExternalToolsPage::on_jsonEditorBrowseBtn_clicked() { - QString raw_file = QFileDialog::getOpenFileName( - this, tr("JSON Editor"), - ui->jsonEditorTextBox->text().isEmpty() + QString raw_file = QFileDialog::getOpenFileName(this, tr("JSON Editor"), + ui->jsonEditorTextBox->text().isEmpty() #if defined(Q_OS_LINUX) - ? QString("/usr/bin") + ? QString("/usr/bin") #else - ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first() + ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first() #endif - : ui->jsonEditorTextBox->text()); + : ui->jsonEditorTextBox->text()); - if (raw_file.isEmpty()) - { + if (raw_file.isEmpty()) { return; } QString cooked_file = FS::NormalizePath(raw_file); // it has to exist and be an executable - if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable()) - { + if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable()) { ui->jsonEditorTextBox->setText(cooked_file); - } - else - { - QMessageBox::warning(this, tr("Invalid"), - tr("The file chosen does not seem to be an executable")); + } else { + QMessageBox::warning(this, tr("Invalid"), tr("The file chosen does not seem to be an executable")); } } diff --git a/launcher/ui/pages/global/ExternalToolsPage.h b/launcher/ui/pages/global/ExternalToolsPage.h index 8bd38a196..0b38b80f9 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.h +++ b/launcher/ui/pages/global/ExternalToolsPage.h @@ -37,54 +37,42 @@ #include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" namespace Ui { class ExternalToolsPage; } -class ExternalToolsPage : public QWidget, public BasePage -{ +class ExternalToolsPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit ExternalToolsPage(QWidget *parent = 0); + public: + explicit ExternalToolsPage(QWidget* parent = 0); ~ExternalToolsPage(); - QString displayName() const override - { - return tr("External Tools"); - } + QString displayName() const override { return tr("External Tools"); } QIcon icon() const override { auto icon = APPLICATION->getThemedIcon("externaltools"); - if(icon.isNull()) - { + if (icon.isNull()) { icon = APPLICATION->getThemedIcon("loadermods"); } return icon; } - QString id() const override - { - return "external-tools"; - } - QString helpPage() const override - { - return "Tools"; - } + QString id() const override { return "external-tools"; } + QString helpPage() const override { return "Tools"; } virtual bool apply() override; void retranslate() override; -private: + private: void loadSettings(); void applySettings(); -private: - Ui::ExternalToolsPage *ui; + private: + Ui::ExternalToolsPage* ui; -private -slots: + private slots: void on_jprofilerPathBtn_clicked(); void on_jprofilerCheckBtn_clicked(); void on_jvisualvmPathBtn_clicked(); diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 81dd4cc12..775638403 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -38,22 +38,22 @@ #include "JavaCommon.h" #include "ui_JavaPage.h" +#include #include #include -#include #include #include "ui/dialogs/VersionSelectDialog.h" -#include "java/JavaUtils.h" #include "java/JavaInstallList.h" +#include "java/JavaUtils.h" -#include "settings/SettingsObject.h" #include -#include "Application.h" #include +#include "Application.h" +#include "settings/SettingsObject.h" -JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) +JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); @@ -80,13 +80,10 @@ void JavaPage::applySettings() // Memory int min = ui->minMemSpinBox->value(); int max = ui->maxMemSpinBox->value(); - if(min < max) - { + if (min < max) { s->set("MinMemAlloc", min); s->set("MaxMemAlloc", max); - } - else - { + } else { s->set("MinMemAlloc", max); s->set("MaxMemAlloc", min); } @@ -105,13 +102,10 @@ void JavaPage::loadSettings() // Memory int min = s->get("MinMemAlloc").toInt(); int max = s->get("MaxMemAlloc").toInt(); - if(min < max) - { + if (min < max) { ui->minMemSpinBox->setValue(min); ui->maxMemSpinBox->setValue(max); - } - else - { + } else { ui->minMemSpinBox->setValue(max); ui->maxMemSpinBox->setValue(min); } @@ -137,8 +131,7 @@ void JavaPage::on_javaDetectBtn_clicked() vselect.setResizeOn(2); vselect.exec(); - if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) - { + if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) { java = std::dynamic_pointer_cast(vselect.selectedVersion()); ui->javaPathTextBox->setText(java->path); } @@ -149,15 +142,14 @@ void JavaPage::on_javaBrowseBtn_clicked() QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable")); // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if(raw_path.isEmpty()) - { + if (raw_path.isEmpty()) { return; } QString cooked_path = FS::NormalizePath(raw_path); - QFileInfo javaInfo(cooked_path);; - if(!javaInfo.exists() || !javaInfo.isExecutable()) - { + QFileInfo javaInfo(cooked_path); + ; + if (!javaInfo.exists() || !javaInfo.isExecutable()) { return; } ui->javaPathTextBox->setText(cooked_path); @@ -165,13 +157,11 @@ void JavaPage::on_javaBrowseBtn_clicked() void JavaPage::on_javaTestBtn_clicked() { - if(checker) - { + if (checker) { return; } - checker.reset(new JavaCommon::TestCheck( - this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "), - ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value())); + checker.reset(new JavaCommon::TestCheck(this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "), + ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value())); connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished())); checker->run(); } diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 2ef6d7493..64f2a296e 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -35,62 +35,47 @@ #pragma once -#include -#include -#include "ui/pages/BasePage.h" -#include "JavaCommon.h" #include #include +#include +#include +#include "JavaCommon.h" +#include "ui/pages/BasePage.h" class SettingsObject; -namespace Ui -{ +namespace Ui { class JavaPage; } -class JavaPage : public QWidget, public BasePage -{ +class JavaPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit JavaPage(QWidget *parent = 0); + public: + explicit JavaPage(QWidget* parent = 0); ~JavaPage(); - QString displayName() const override - { - return tr("Java"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("java"); - } - QString id() const override - { - return "java-settings"; - } - QString helpPage() const override - { - return "Java-settings"; - } + QString displayName() const override { return tr("Java"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("java"); } + QString id() const override { return "java-settings"; } + QString helpPage() const override { return "Java-settings"; } bool apply() override; void retranslate() override; void updateThresholds(); -private: + private: void applySettings(); void loadSettings(); -private -slots: + private slots: void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); void on_maxMemSpinBox_valueChanged(int i); void checkerFinished(); -private: - Ui::JavaPage *ui; + private: + Ui::JavaPage* ui; unique_qobject_ptr checker; }; diff --git a/launcher/ui/pages/global/LanguagePage.cpp b/launcher/ui/pages/global/LanguagePage.cpp index fcd174bdb..27af91d84 100644 --- a/launcher/ui/pages/global/LanguagePage.cpp +++ b/launcher/ui/pages/global/LanguagePage.cpp @@ -36,23 +36,20 @@ #include "LanguagePage.h" -#include "ui/widgets/LanguageSelectionWidget.h" #include +#include "ui/widgets/LanguageSelectionWidget.h" -LanguagePage::LanguagePage(QWidget* parent) : - QWidget(parent) +LanguagePage::LanguagePage(QWidget* parent) : QWidget(parent) { setObjectName(QStringLiteral("languagePage")); auto layout = new QVBoxLayout(this); mainWidget = new LanguageSelectionWidget(this); - layout->setContentsMargins(0,0,0,0); + layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(mainWidget); retranslate(); } -LanguagePage::~LanguagePage() -{ -} +LanguagePage::~LanguagePage() {} bool LanguagePage::apply() { diff --git a/launcher/ui/pages/global/LanguagePage.h b/launcher/ui/pages/global/LanguagePage.h index 2fd4ab0de..ea358851a 100644 --- a/launcher/ui/pages/global/LanguagePage.h +++ b/launcher/ui/pages/global/LanguagePage.h @@ -36,45 +36,32 @@ #pragma once -#include -#include "ui/pages/BasePage.h" #include #include +#include +#include "ui/pages/BasePage.h" class LanguageSelectionWidget; -class LanguagePage : public QWidget, public BasePage -{ +class LanguagePage : public QWidget, public BasePage { Q_OBJECT -public: - explicit LanguagePage(QWidget *parent = 0); + public: + explicit LanguagePage(QWidget* parent = 0); virtual ~LanguagePage(); - QString displayName() const override - { - return tr("Language"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("language"); - } - QString id() const override - { - return "language-settings"; - } - QString helpPage() const override - { - return "Language-settings"; - } + QString displayName() const override { return tr("Language"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("language"); } + QString id() const override { return "language-settings"; } + QString helpPage() const override { return "Language-settings"; } bool apply() override; void retranslate() override; -private: + private: void applySettings(); void loadSettings(); -private: - LanguageSelectionWidget *mainWidget; + private: + LanguageSelectionWidget* mainWidget; }; diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 2080b56f0..7f22fdb50 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -38,17 +38,17 @@ #include "LauncherPage.h" #include "ui_LauncherPage.h" -#include -#include #include -#include +#include #include +#include +#include -#include "settings/SettingsObject.h" #include #include "Application.h" #include "BuildConfig.h" #include "DesktopServices.h" +#include "settings/SettingsObject.h" #include "ui/themes/ITheme.h" #include "updater/ExternalUpdater.h" @@ -56,15 +56,14 @@ #include // FIXME: possibly move elsewhere -enum InstSortMode -{ +enum InstSortMode { // Sort alphabetically by name. Sort_Name, // Sort by which instance was launched most recently. Sort_LastLaunch }; -LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::LauncherPage) +LauncherPage::LauncherPage(QWidget* parent) : QWidget(parent), ui(new Ui::LauncherPage) { ui->setupUi(this); auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole()); @@ -104,46 +103,39 @@ void LauncherPage::on_instDirBrowseBtn_clicked() QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text()); // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { QString cooked_dir = FS::NormalizePath(raw_dir); - if (FS::checkProblemticPathJava(QDir(cooked_dir))) - { + if (FS::checkProblemticPathJava(QDir(cooked_dir))) { QMessageBox warning; - warning.setText(tr("You're trying to specify an instance folder which\'s path " - "contains at least one \'!\'. " - "Java is known to cause problems if that is the case, your " - "instances (probably) won't start!")); + warning.setText( + tr("You're trying to specify an instance folder which\'s path " + "contains at least one \'!\'. " + "Java is known to cause problems if that is the case, your " + "instances (probably) won't start!")); warning.setInformativeText( tr("Do you really want to use this path? " "Selecting \"No\" will close this and not alter your instance path.")); warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); int result = warning.exec(); - if (result == QMessageBox::Ok) - { + if (result == QMessageBox::Ok) { ui->instDirTextBox->setText(cooked_dir); } - } - else if(DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user")) - { + } else if (DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user")) { QMessageBox warning; warning.setText(tr("You're trying to specify an instance folder " - "which was granted temporarily via Flatpak.\n" - "This is known to cause problems. " - "After a restart the launcher might break, " - "because it will no longer have access to that directory.\n\n" - "Granting %1 access to it via Flatseal is recommended.").arg(BuildConfig.LAUNCHER_DISPLAYNAME)); - warning.setInformativeText( - tr("Do you want to proceed anyway?")); + "which was granted temporarily via Flatpak.\n" + "This is known to cause problems. " + "After a restart the launcher might break, " + "because it will no longer have access to that directory.\n\n" + "Granting %1 access to it via Flatseal is recommended.") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME)); + warning.setInformativeText(tr("Do you want to proceed anyway?")); warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); int result = warning.exec(); - if (result == QMessageBox::Ok) - { + if (result == QMessageBox::Ok) { ui->instDirTextBox->setText(cooked_dir); } - } - else - { + } else { ui->instDirTextBox->setText(cooked_dir); } } @@ -154,8 +146,7 @@ void LauncherPage::on_iconsDirBrowseBtn_clicked() QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text()); // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { QString cooked_dir = FS::NormalizePath(raw_dir); ui->iconsDirTextBox->setText(cooked_dir); } @@ -166,8 +157,7 @@ void LauncherPage::on_modsDirBrowseBtn_clicked() QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text()); // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { QString cooked_dir = FS::NormalizePath(raw_dir); ui->modsDirTextBox->setText(cooked_dir); } @@ -177,8 +167,7 @@ void LauncherPage::on_downloadsDirBrowseBtn_clicked() { QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Downloads Folder"), ui->downloadsDirTextBox->text()); - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) { QString cooked_dir = FS::NormalizePath(raw_dir); ui->downloadsDirTextBox->setText(cooked_dir); } @@ -194,8 +183,7 @@ void LauncherPage::applySettings() auto s = APPLICATION->settings(); // Updates - if (APPLICATION->updater()) - { + if (APPLICATION->updater()) { APPLICATION->updater()->setAutomaticallyChecksForUpdates(ui->autoUpdateCheckBox->isChecked()); } @@ -220,15 +208,14 @@ void LauncherPage::applySettings() s->set("DownloadsDirWatchRecursive", ui->downloadsDirWatchRecursiveCheckBox->isChecked()); auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); - switch (sortMode) - { - case Sort_LastLaunch: - s->set("InstSortMode", "LastLaunch"); - break; - case Sort_Name: - default: - s->set("InstSortMode", "Name"); - break; + switch (sortMode) { + case Sort_LastLaunch: + s->set("InstSortMode", "LastLaunch"); + break; + case Sort_Name: + default: + s->set("InstSortMode", "Name"); + break; } // Mods @@ -238,12 +225,10 @@ void LauncherPage::loadSettings() { auto s = APPLICATION->settings(); // Updates - if (APPLICATION->updater()) - { + if (APPLICATION->updater()) { ui->autoUpdateCheckBox->setChecked(APPLICATION->updater()->getAutomaticallyChecksForUpdates()); } - // Toolbar/menu bar settings (not applicable if native menu bar is present) ui->toolsBox->setEnabled(!QMenuBar().isNativeMenuBar()); #ifdef Q_OS_MACOS @@ -261,8 +246,7 @@ void LauncherPage::loadSettings() bool conversionOk = true; int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); - if(!conversionOk) - { + if (!conversionOk) { fontSize = 11; } ui->fontSizeBox->setValue(fontSize); @@ -279,12 +263,9 @@ void LauncherPage::loadSettings() QString sortMode = s->get("InstSortMode").toString(); - if (sortMode == "LastLaunch") - { + if (sortMode == "LastLaunch") { ui->sortLastLaunchedBtn->setChecked(true); - } - else - { + } else { ui->sortByNameBtn->setChecked(true); } diff --git a/launcher/ui/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index e06d98971..238e31bb4 100644 --- a/launcher/ui/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -35,56 +35,41 @@ #pragma once -#include #include +#include -#include "java/JavaChecker.h" -#include "ui/pages/BasePage.h" #include -#include "ui/ColorCache.h" #include +#include "java/JavaChecker.h" +#include "ui/ColorCache.h" +#include "ui/pages/BasePage.h" class QTextCharFormat; class SettingsObject; -namespace Ui -{ +namespace Ui { class LauncherPage; } -class LauncherPage : public QWidget, public BasePage -{ +class LauncherPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit LauncherPage(QWidget *parent = 0); + public: + explicit LauncherPage(QWidget* parent = 0); ~LauncherPage(); - QString displayName() const override - { - return tr("Launcher"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("launcher"); - } - QString id() const override - { - return "launcher-settings"; - } - QString helpPage() const override - { - return "Launcher-settings"; - } + QString displayName() const override { return tr("Launcher"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("launcher"); } + QString id() const override { return "launcher-settings"; } + QString helpPage() const override { return "Launcher-settings"; } bool apply() override; void retranslate() override; -private: + private: void applySettings(); void loadSettings(); -private -slots: + private slots: void on_instDirBrowseBtn_clicked(); void on_modsDirBrowseBtn_clicked(); void on_iconsDirBrowseBtn_clicked(); @@ -96,8 +81,8 @@ slots: */ void refreshFontPreview(); -private: - Ui::LauncherPage *ui; + private: + Ui::LauncherPage* ui; /*! * Stores the currently selected update channel. @@ -105,7 +90,7 @@ private: QString m_currentUpdateChannel; // default format for the font preview... - QTextCharFormat *defaultFormat; + QTextCharFormat* defaultFormat; std::unique_ptr m_colors; diff --git a/launcher/ui/pages/global/MinecraftPage.cpp b/launcher/ui/pages/global/MinecraftPage.cpp index 954823564..55ad12ac8 100644 --- a/launcher/ui/pages/global/MinecraftPage.cpp +++ b/launcher/ui/pages/global/MinecraftPage.cpp @@ -37,14 +37,14 @@ #include "MinecraftPage.h" #include "ui_MinecraftPage.h" -#include #include +#include #include -#include "settings/SettingsObject.h" #include "Application.h" +#include "settings/SettingsObject.h" -MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage) +MinecraftPage::MinecraftPage(QWidget* parent) : QWidget(parent), ui(new Ui::MinecraftPage) { ui->setupUi(this); loadSettings(); diff --git a/launcher/ui/pages/global/MinecraftPage.h b/launcher/ui/pages/global/MinecraftPage.h index cf5f95eb7..a9e2e8024 100644 --- a/launcher/ui/pages/global/MinecraftPage.h +++ b/launcher/ui/pages/global/MinecraftPage.h @@ -35,57 +35,41 @@ #pragma once -#include #include +#include +#include #include "java/JavaChecker.h" #include "ui/pages/BasePage.h" -#include class SettingsObject; -namespace Ui -{ +namespace Ui { class MinecraftPage; } -class MinecraftPage : public QWidget, public BasePage -{ +class MinecraftPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit MinecraftPage(QWidget *parent = 0); + public: + explicit MinecraftPage(QWidget* parent = 0); ~MinecraftPage(); - QString displayName() const override - { - return tr("Minecraft"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("minecraft"); - } - QString id() const override - { - return "minecraft-settings"; - } - QString helpPage() const override - { - return "Minecraft-settings"; - } + QString displayName() const override { return tr("Minecraft"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("minecraft"); } + QString id() const override { return "minecraft-settings"; } + QString helpPage() const override { return "Minecraft-settings"; } bool apply() override; void retranslate() override; -private: + private: void updateCheckboxStuff(); void applySettings(); void loadSettings(); -private -slots: + private slots: void on_maximizedCheckBox_clicked(bool checked); -private: - Ui::MinecraftPage *ui; - + private: + Ui::MinecraftPage* ui; }; diff --git a/launcher/ui/pages/global/ProxyPage.cpp b/launcher/ui/pages/global/ProxyPage.cpp index ffff8456c..931adac52 100644 --- a/launcher/ui/pages/global/ProxyPage.cpp +++ b/launcher/ui/pages/global/ProxyPage.cpp @@ -40,18 +40,17 @@ #include #include -#include "settings/SettingsObject.h" #include "Application.h" +#include "settings/SettingsObject.h" -ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage) +ProxyPage::ProxyPage(QWidget* parent) : QWidget(parent), ui(new Ui::ProxyPage) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); loadSettings(); updateCheckboxStuff(); - connect(ui->proxyGroup, QOverload::of(&QButtonGroup::buttonClicked), - this, &ProxyPage::proxyGroupChanged); + connect(ui->proxyGroup, QOverload::of(&QButtonGroup::buttonClicked), this, &ProxyPage::proxyGroupChanged); } ProxyPage::~ProxyPage() @@ -67,13 +66,12 @@ bool ProxyPage::apply() void ProxyPage::updateCheckboxStuff() { - bool enableEditing = ui->proxyHTTPBtn->isChecked() - || ui->proxySOCKS5Btn->isChecked(); + bool enableEditing = ui->proxyHTTPBtn->isChecked() || ui->proxySOCKS5Btn->isChecked(); ui->proxyAddrBox->setEnabled(enableEditing); ui->proxyAuthBox->setEnabled(enableEditing); } -void ProxyPage::proxyGroupChanged(QAbstractButton *button) +void ProxyPage::proxyGroupChanged(QAbstractButton* button) { updateCheckboxStuff(); } @@ -99,13 +97,8 @@ void ProxyPage::applySettings() s->set("ProxyUser", ui->proxyUserEdit->text()); s->set("ProxyPass", ui->proxyPassEdit->text()); - APPLICATION->updateProxySettings( - proxyType, - ui->proxyAddrEdit->text(), - ui->proxyPortEdit->value(), - ui->proxyUserEdit->text(), - ui->proxyPassEdit->text() - ); + APPLICATION->updateProxySettings(proxyType, ui->proxyAddrEdit->text(), ui->proxyPortEdit->value(), ui->proxyUserEdit->text(), + ui->proxyPassEdit->text()); } void ProxyPage::loadSettings() { diff --git a/launcher/ui/pages/global/ProxyPage.h b/launcher/ui/pages/global/ProxyPage.h index 279a90295..092a11d2f 100644 --- a/launcher/ui/pages/global/ProxyPage.h +++ b/launcher/ui/pages/global/ProxyPage.h @@ -36,53 +36,39 @@ #pragma once -#include #include #include +#include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class ProxyPage; } -class ProxyPage : public QWidget, public BasePage -{ +class ProxyPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit ProxyPage(QWidget *parent = 0); + public: + explicit ProxyPage(QWidget* parent = 0); ~ProxyPage(); - QString displayName() const override - { - return tr("Proxy"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("proxy"); - } - QString id() const override - { - return "proxy-settings"; - } - QString helpPage() const override - { - return "Proxy-settings"; - } + QString displayName() const override { return tr("Proxy"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("proxy"); } + QString id() const override { return "proxy-settings"; } + QString helpPage() const override { return "Proxy-settings"; } bool apply() override; void retranslate() override; -private slots: - void proxyGroupChanged(QAbstractButton *button); + private slots: + void proxyGroupChanged(QAbstractButton* button); -private: + private: void updateCheckboxStuff(); void applySettings(); void loadSettings(); -private: - Ui::ProxyPage *ui; + private: + Ui::ProxyPage* ui; }; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index 97d922d88..d29be0fc3 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -4,8 +4,8 @@ #include #include "Application.h" -#include "settings/Setting.h" #include "minecraft/MinecraftInstance.h" +#include "settings/Setting.h" #include "ui/pages/BasePage.h" class ResourceFolderModel; @@ -52,7 +52,7 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { virtual void addItem(); void removeItem(); - virtual void removeItems(const QItemSelection &selection); + virtual void removeItems(const QItemSelection& selection); virtual void enableItem(); virtual void disableItem(); diff --git a/launcher/ui/pages/instance/GameOptionsPage.cpp b/launcher/ui/pages/instance/GameOptionsPage.cpp index 63443166b..e90041709 100644 --- a/launcher/ui/pages/instance/GameOptionsPage.cpp +++ b/launcher/ui/pages/instance/GameOptionsPage.cpp @@ -34,23 +34,20 @@ */ #include "GameOptionsPage.h" -#include "ui_GameOptionsPage.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/gameoptions/GameOptions.h" +#include "ui_GameOptionsPage.h" -GameOptionsPage::GameOptionsPage(MinecraftInstance * inst, QWidget* parent) - : QWidget(parent), ui(new Ui::GameOptionsPage) +GameOptionsPage::GameOptionsPage(MinecraftInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::GameOptionsPage) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); m_model = inst->gameOptionsModel(); ui->optionsView->setModel(m_model.get()); auto head = ui->optionsView->header(); - if(head->count()) - { + if (head->count()) { head->setSectionResizeMode(0, QHeaderView::ResizeToContents); - for(int i = 1; i < head->count(); i++) - { + for (int i = 1; i < head->count(); i++) { head->setSectionResizeMode(i, QHeaderView::Stretch); } } diff --git a/launcher/ui/pages/instance/GameOptionsPage.h b/launcher/ui/pages/instance/GameOptionsPage.h index de8c421e7..563bd10ae 100644 --- a/launcher/ui/pages/instance/GameOptionsPage.h +++ b/launcher/ui/pages/instance/GameOptionsPage.h @@ -35,50 +35,36 @@ #pragma once -#include #include +#include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class GameOptionsPage; } class GameOptions; class MinecraftInstance; -class GameOptionsPage : public QWidget, public BasePage -{ +class GameOptionsPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit GameOptionsPage(MinecraftInstance *inst, QWidget *parent = 0); + public: + explicit GameOptionsPage(MinecraftInstance* inst, QWidget* parent = 0); virtual ~GameOptionsPage(); void openedImpl() override; void closedImpl() override; - virtual QString displayName() const override - { - return tr("Game Options"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("settings"); - } - virtual QString id() const override - { - return "gameoptions"; - } - virtual QString helpPage() const override - { - return "Game-Options-management"; - } + virtual QString displayName() const override { return tr("Game Options"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("settings"); } + virtual QString id() const override { return "gameoptions"; } + virtual QString helpPage() const override { return "Game-Options-management"; } void retranslate() override; -private: // data - Ui::GameOptionsPage *ui = nullptr; + private: // data + Ui::GameOptionsPage* ui = nullptr; std::shared_ptr m_model; }; diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 25cc1a0de..d25459d5f 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -38,8 +38,8 @@ #include "InstanceSettingsPage.h" #include "ui_InstanceSettingsPage.h" -#include #include +#include #include #include @@ -47,15 +47,15 @@ #include "ui/dialogs/VersionSelectDialog.h" #include "ui/widgets/CustomCommands.h" -#include "JavaCommon.h" #include "Application.h" +#include "JavaCommon.h" #include "minecraft/auth/AccountList.h" #include "FileSystem.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" -InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) +InstanceSettingsPage::InstanceSettingsPage(BaseInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) { m_settings = inst->settings(); @@ -78,7 +78,7 @@ InstanceSettingsPage::~InstanceSettingsPage() void InstanceSettingsPage::globalSettingsButtonClicked(bool) { - switch(ui->settingsTabs->currentIndex()) { + switch (ui->settingsTabs->currentIndex()) { case 0: APPLICATION->ShowGlobalSettings(this, "java-settings"); return; @@ -104,13 +104,10 @@ void InstanceSettingsPage::applySettings() // Miscellaneous bool miscellaneous = ui->miscellaneousSettingsBox->isChecked(); m_settings->set("OverrideMiscellaneous", miscellaneous); - if (miscellaneous) - { + if (miscellaneous) { m_settings->set("CloseAfterLaunch", ui->closeAfterLaunchCheck->isChecked()); m_settings->set("QuitAfterGameStop", ui->quitAfterGameStopCheck->isChecked()); - } - else - { + } else { m_settings->reset("CloseAfterLaunch"); m_settings->reset("QuitAfterGameStop"); } @@ -118,14 +115,11 @@ void InstanceSettingsPage::applySettings() // Console bool console = ui->consoleSettingsBox->isChecked(); m_settings->set("OverrideConsole", console); - if (console) - { + if (console) { m_settings->set("ShowConsole", ui->showConsoleCheck->isChecked()); m_settings->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); m_settings->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked()); - } - else - { + } else { m_settings->reset("ShowConsole"); m_settings->reset("AutoCloseConsole"); m_settings->reset("ShowConsoleOnError"); @@ -134,14 +128,11 @@ void InstanceSettingsPage::applySettings() // Window Size bool window = ui->windowSizeGroupBox->isChecked(); m_settings->set("OverrideWindow", window); - if (window) - { + if (window) { m_settings->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); m_settings->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); m_settings->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); - } - else - { + } else { m_settings->reset("LaunchMaximized"); m_settings->reset("MinecraftWinWidth"); m_settings->reset("MinecraftWinHeight"); @@ -150,24 +141,18 @@ void InstanceSettingsPage::applySettings() // Memory bool memory = ui->memoryGroupBox->isChecked(); m_settings->set("OverrideMemory", memory); - if (memory) - { + if (memory) { int min = ui->minMemSpinBox->value(); int max = ui->maxMemSpinBox->value(); - if(min < max) - { + if (min < max) { m_settings->set("MinMemAlloc", min); m_settings->set("MaxMemAlloc", max); - } - else - { + } else { m_settings->set("MinMemAlloc", max); m_settings->set("MaxMemAlloc", min); } m_settings->set("PermGen", ui->permGenSpinBox->value()); - } - else - { + } else { m_settings->reset("MinMemAlloc"); m_settings->reset("MaxMemAlloc"); m_settings->reset("PermGen"); @@ -176,13 +161,10 @@ void InstanceSettingsPage::applySettings() // Java Install Settings bool javaInstall = ui->javaSettingsGroupBox->isChecked(); m_settings->set("OverrideJavaLocation", javaInstall); - if (javaInstall) - { + if (javaInstall) { m_settings->set("JavaPath", ui->javaPathTextBox->text()); m_settings->set("IgnoreJavaCompatibility", ui->skipCompatibilityCheckbox->isChecked()); - } - else - { + } else { m_settings->reset("JavaPath"); m_settings->reset("IgnoreJavaCompatibility"); } @@ -190,12 +172,9 @@ void InstanceSettingsPage::applySettings() // Java arguments bool javaArgs = ui->javaArgumentsGroupBox->isChecked(); m_settings->set("OverrideJavaArgs", javaArgs); - if(javaArgs) - { + if (javaArgs) { m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " ")); - } - else - { + } else { m_settings->reset("JvmArgs"); } @@ -205,14 +184,11 @@ void InstanceSettingsPage::applySettings() // Custom Commands bool custcmd = ui->customCommands->checked(); m_settings->set("OverrideCommands", custcmd); - if (custcmd) - { + if (custcmd) { m_settings->set("PreLaunchCommand", ui->customCommands->prelaunchCommand()); m_settings->set("WrapperCommand", ui->customCommands->wrapperCommand()); m_settings->set("PostExitCommand", ui->customCommands->postexitCommand()); - } - else - { + } else { m_settings->reset("PreLaunchCommand"); m_settings->reset("WrapperCommand"); m_settings->reset("PostExitCommand"); @@ -221,13 +197,10 @@ void InstanceSettingsPage::applySettings() // Workarounds bool workarounds = ui->nativeWorkaroundsGroupBox->isChecked(); m_settings->set("OverrideNativeWorkarounds", workarounds); - if(workarounds) - { + if (workarounds) { m_settings->set("UseNativeOpenAL", ui->useNativeOpenALCheck->isChecked()); m_settings->set("UseNativeGLFW", ui->useNativeGLFWCheck->isChecked()); - } - else - { + } else { m_settings->reset("UseNativeOpenAL"); m_settings->reset("UseNativeGLFW"); } @@ -235,14 +208,11 @@ void InstanceSettingsPage::applySettings() // Performance bool performance = ui->perfomanceGroupBox->isChecked(); m_settings->set("OverridePerformance", performance); - if(performance) - { + if (performance) { m_settings->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked()); m_settings->set("EnableMangoHud", ui->enableMangoHud->isChecked()); m_settings->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked()); - } - else - { + } else { m_settings->reset("EnableFeralGamemode"); m_settings->reset("EnableMangoHud"); m_settings->reset("UseDiscreteGpu"); @@ -251,13 +221,10 @@ void InstanceSettingsPage::applySettings() // Game time bool gameTime = ui->gameTimeGroupBox->isChecked(); m_settings->set("OverrideGameTime", gameTime); - if (gameTime) - { + if (gameTime) { m_settings->set("ShowGameTime", ui->showGameTime->isChecked()); m_settings->set("RecordGameTime", ui->recordGameTime->isChecked()); - } - else - { + } else { m_settings->reset("ShowGameTime"); m_settings->reset("RecordGameTime"); } @@ -265,12 +232,9 @@ void InstanceSettingsPage::applySettings() // Join server on launch bool joinServerOnLaunch = ui->serverJoinGroupBox->isChecked(); m_settings->set("JoinServerOnLaunch", joinServerOnLaunch); - if (joinServerOnLaunch) - { + if (joinServerOnLaunch) { m_settings->set("JoinServerOnLaunchAddress", ui->serverJoinAddress->text()); - } - else - { + } else { m_settings->reset("JoinServerOnLaunchAddress"); } @@ -316,13 +280,10 @@ void InstanceSettingsPage::loadSettings() ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool()); int min = m_settings->get("MinMemAlloc").toInt(); int max = m_settings->get("MaxMemAlloc").toInt(); - if(min < max) - { + if (min < max) { ui->minMemSpinBox->setValue(min); ui->maxMemSpinBox->setValue(max); - } - else - { + } else { ui->minMemSpinBox->setValue(max); ui->maxMemSpinBox->setValue(min); } @@ -332,7 +293,6 @@ void InstanceSettingsPage::loadSettings() ui->labelPermGen->setVisible(permGenVisible); ui->labelPermgenNote->setVisible(permGenVisible); - // Java Settings bool overrideJava = m_settings->get("OverrideJava").toBool(); bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava; @@ -346,13 +306,8 @@ void InstanceSettingsPage::loadSettings() ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString()); // Custom commands - ui->customCommands->initialize( - true, - m_settings->get("OverrideCommands").toBool(), - m_settings->get("PreLaunchCommand").toString(), - m_settings->get("WrapperCommand").toString(), - m_settings->get("PostExitCommand").toString() - ); + ui->customCommands->initialize(true, m_settings->get("OverrideCommands").toBool(), m_settings->get("PreLaunchCommand").toString(), + m_settings->get("WrapperCommand").toString(), m_settings->get("PostExitCommand").toString()); // Workarounds ui->nativeWorkaroundsGroupBox->setChecked(m_settings->get("OverrideNativeWorkarounds").toBool()); @@ -408,8 +363,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() vselect.setResizeOn(2); vselect.exec(); - if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) - { + if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) { java = std::dynamic_pointer_cast(vselect.selectedVersion()); ui->javaPathTextBox->setText(java->path); bool visible = java->id.requiresPermGen() && m_settings->get("OverrideMemory").toBool(); @@ -425,15 +379,13 @@ void InstanceSettingsPage::on_javaBrowseBtn_clicked() QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable")); // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if(raw_path.isEmpty()) - { + if (raw_path.isEmpty()) { return; } QString cooked_path = FS::NormalizePath(raw_path); QFileInfo javaInfo(cooked_path); - if(!javaInfo.exists() || !javaInfo.isExecutable()) - { + if (!javaInfo.exists() || !javaInfo.isExecutable()) { return; } ui->javaPathTextBox->setText(cooked_path); @@ -447,13 +399,11 @@ void InstanceSettingsPage::on_javaBrowseBtn_clicked() void InstanceSettingsPage::on_javaTestBtn_clicked() { - if(checker) - { + if (checker) { return; } - checker.reset(new JavaCommon::TestCheck( - this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "), - ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value())); + checker.reset(new JavaCommon::TestCheck(this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "), + ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value())); connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished())); checker->run(); } @@ -470,7 +420,6 @@ void InstanceSettingsPage::updateAccountsMenu() if (i == accountIndex) ui->instanceAccountSelector->setCurrentIndex(i); } - } QIcon InstanceSettingsPage::getFaceForAccount(MinecraftAccountPtr account) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index 036b41818..9f1355939 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -46,35 +46,21 @@ #include "ui/pages/BasePage.h" class JavaChecker; -namespace Ui -{ +namespace Ui { class InstanceSettingsPage; } -class InstanceSettingsPage : public QWidget, public BasePage -{ +class InstanceSettingsPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0); + public: + explicit InstanceSettingsPage(BaseInstance* inst, QWidget* parent = 0); virtual ~InstanceSettingsPage(); - virtual QString displayName() const override - { - return tr("Settings"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("instance-settings"); - } - virtual QString id() const override - { - return "settings"; - } + virtual QString displayName() const override { return tr("Settings"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("instance-settings"); } + virtual QString id() const override { return "settings"; } virtual bool apply() override; - virtual QString helpPage() const override - { - return "Instance-settings"; - } + virtual QString helpPage() const override { return "Instance-settings"; } void retranslate() override; void updateThresholds(); @@ -96,9 +82,9 @@ public: QIcon getFaceForAccount(MinecraftAccountPtr account); void changeInstanceAccount(int index); -private: - Ui::InstanceSettingsPage *ui; - BaseInstance *m_instance; + private: + Ui::InstanceSettingsPage* ui; + BaseInstance* m_instance; SettingsObjectPtr m_settings; unique_qobject_ptr checker; }; diff --git a/launcher/ui/pages/instance/LogPage.cpp b/launcher/ui/pages/instance/LogPage.cpp index 639cd7118..8e1e53762 100644 --- a/launcher/ui/pages/instance/LogPage.cpp +++ b/launcher/ui/pages/instance/LogPage.cpp @@ -47,56 +47,42 @@ #include "launch/LaunchTask.h" #include "settings/Setting.h" -#include "ui/GuiUtil.h" #include "ui/ColorCache.h" +#include "ui/GuiUtil.h" #include -class LogFormatProxyModel : public QIdentityProxyModel -{ -public: - LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent) +class LogFormatProxyModel : public QIdentityProxyModel { + public: + LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent) {} + QVariant data(const QModelIndex& index, int role) const override { - } - QVariant data(const QModelIndex &index, int role) const override - { - switch(role) - { + switch (role) { case Qt::FontRole: return m_font; - case Qt::ForegroundRole: - { - MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt(); + case Qt::ForegroundRole: { + MessageLevel::Enum level = (MessageLevel::Enum)QIdentityProxyModel::data(index, LogModel::LevelRole).toInt(); return m_colors->getFront(level); } - case Qt::BackgroundRole: - { - MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt(); + case Qt::BackgroundRole: { + MessageLevel::Enum level = (MessageLevel::Enum)QIdentityProxyModel::data(index, LogModel::LevelRole).toInt(); return m_colors->getBack(level); } default: return QIdentityProxyModel::data(index, role); - } + } } - void setFont(QFont font) - { - m_font = font; - } + void setFont(QFont font) { m_font = font; } - void setColors(LogColorCache* colors) - { - m_colors.reset(colors); - } + void setColors(LogColorCache* colors) { m_colors.reset(colors); } - QModelIndex find(const QModelIndex &start, const QString &value, bool reverse) const + QModelIndex find(const QModelIndex& start, const QString& value, bool reverse) const { QModelIndex parentIndex = parent(start); - auto compare = [&](int r) -> QModelIndex - { + auto compare = [&](int r) -> QModelIndex { QModelIndex idx = index(r, start.column(), parentIndex); - if (!idx.isValid() || idx == start) - { + if (!idx.isValid() || idx == start) { return QModelIndex(); } QVariant v = data(idx, Qt::DisplayRole); @@ -105,35 +91,28 @@ public: return idx; return QModelIndex(); }; - if(reverse) - { + if (reverse) { int from = start.row(); int to = 0; - for (int i = 0; i < 2; ++i) - { - for (int r = from; (r >= to); --r) - { + for (int i = 0; i < 2; ++i) { + for (int r = from; (r >= to); --r) { auto idx = compare(r); - if(idx.isValid()) + if (idx.isValid()) return idx; } // prepare for the next iteration from = rowCount() - 1; to = start.row(); } - } - else - { + } else { int from = start.row(); int to = rowCount(parentIndex); - for (int i = 0; i < 2; ++i) - { - for (int r = from; (r < to); ++r) - { + for (int i = 0; i < 2; ++i) { + for (int r = from; (r < to); ++r) { auto idx = compare(r); - if(idx.isValid()) + if (idx.isValid()) return idx; } // prepare for the next iteration @@ -143,13 +122,13 @@ public: } return QModelIndex(); } -private: + + private: QFont m_font; std::unique_ptr m_colors; }; -LogPage::LogPage(InstancePtr instance, QWidget *parent) - : QWidget(parent), ui(new Ui::LogPage), m_instance(instance) +LogPage::LogPage(InstancePtr instance, QWidget* parent) : QWidget(parent), ui(new Ui::LogPage), m_instance(instance) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); @@ -167,8 +146,7 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent) QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); bool conversionOk = false; int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); - if(!conversionOk) - { + if (!conversionOk) { fontSize = 11; } m_proxy->setFont(QFont(fontFamily, fontSize)); @@ -179,8 +157,7 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent) // set up instance and launch process recognition { auto launchTask = m_instance->getLaunchTask(); - if(launchTask) - { + if (launchTask) { setInstanceLaunchTaskChanged(launchTask, true); } connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged); @@ -202,30 +179,23 @@ LogPage::~LogPage() void LogPage::modelStateToUI() { - if(m_model->wrapLines()) - { + if (m_model->wrapLines()) { ui->text->setWordWrap(true); ui->wrapCheckbox->setCheckState(Qt::Checked); - } - else - { + } else { ui->text->setWordWrap(false); ui->wrapCheckbox->setCheckState(Qt::Unchecked); } - if(m_model->suspended()) - { + if (m_model->suspended()) { ui->trackLogCheckbox->setCheckState(Qt::Unchecked); - } - else - { + } else { ui->trackLogCheckbox->setCheckState(Qt::Checked); } } void LogPage::UIToModelState() { - if(!m_model) - { + if (!m_model) { return; } m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked); @@ -235,21 +205,15 @@ void LogPage::UIToModelState() void LogPage::setInstanceLaunchTaskChanged(shared_qobject_ptr proc, bool initial) { m_process = proc; - if(m_process) - { + if (m_process) { m_model = proc->getLogModel(); m_proxy->setSourceModel(m_model.get()); - if(initial) - { + if (initial) { modelStateToUI(); - } - else - { + } else { UIToModelState(); } - } - else - { + } else { m_proxy->setSourceModel(nullptr); m_model.reset(); } @@ -272,34 +236,25 @@ bool LogPage::shouldDisplay() const void LogPage::on_btnPaste_clicked() { - if(!m_model) + if (!m_model) return; - //FIXME: turn this into a proper task and move the upload logic out of GuiUtil! - m_model->append( - MessageLevel::Launcher, - QString("Log upload triggered at: %1").arg( - QDateTime::currentDateTime().toString(Qt::RFC2822Date) - ) - ); + // FIXME: turn this into a proper task and move the upload logic out of GuiUtil! + m_model->append(MessageLevel::Launcher, + QString("Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date))); auto url = GuiUtil::uploadPaste(tr("Minecraft Log"), m_model->toPlainText(), this); - if(!url.has_value()) - { + if (!url.has_value()) { m_model->append(MessageLevel::Error, QString("Log upload canceled")); - } - else if (url->isNull()) - { + } else if (url->isNull()) { m_model->append(MessageLevel::Error, QString("Log upload failed!")); - } - else - { + } else { m_model->append(MessageLevel::Launcher, QString("Log uploaded to: %1").arg(url.value())); } } void LogPage::on_btnCopy_clicked() { - if(!m_model) + if (!m_model) return; m_model->append(MessageLevel::Launcher, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date))); GuiUtil::setClipboardText(m_model->toPlainText()); @@ -307,7 +262,7 @@ void LogPage::on_btnCopy_clicked() void LogPage::on_btnClear_clicked() { - if(!m_model) + if (!m_model) return; m_model->clear(); m_container->refreshContainer(); @@ -320,7 +275,7 @@ void LogPage::on_btnBottom_clicked() void LogPage::on_trackLogCheckbox_clicked(bool checked) { - if(!m_model) + if (!m_model) return; m_model->suspend(!checked); } @@ -328,7 +283,7 @@ void LogPage::on_trackLogCheckbox_clicked(bool checked) void LogPage::on_wrapCheckbox_clicked(bool checked) { ui->text->setWordWrap(checked); - if(!m_model) + if (!m_model) return; m_model->setLineWrap(checked); } @@ -353,8 +308,7 @@ void LogPage::findPreviousActivated() void LogPage::findActivated() { // focus the search bar if it doesn't have focus - if (!ui->searchBar->hasFocus()) - { + if (!ui->searchBar->hasFocus()) { ui->searchBar->setFocus(); ui->searchBar->selectAll(); } diff --git a/launcher/ui/pages/instance/LogPage.h b/launcher/ui/pages/instance/LogPage.h index f6fe87c41..33b6cc39f 100644 --- a/launcher/ui/pages/instance/LogPage.h +++ b/launcher/ui/pages/instance/LogPage.h @@ -37,46 +37,32 @@ #include +#include #include "BaseInstance.h" #include "launch/LaunchTask.h" #include "ui/pages/BasePage.h" -#include -namespace Ui -{ +namespace Ui { class LogPage; } class QTextCharFormat; class LogFormatProxyModel; -class LogPage : public QWidget, public BasePage -{ +class LogPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit LogPage(InstancePtr instance, QWidget *parent = 0); + public: + explicit LogPage(InstancePtr instance, QWidget* parent = 0); virtual ~LogPage(); - virtual QString displayName() const override - { - return tr("Minecraft Log"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("log"); - } - virtual QString id() const override - { - return "console"; - } + virtual QString displayName() const override { return tr("Minecraft Log"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("log"); } + virtual QString id() const override { return "console"; } virtual bool apply() override; - virtual QString helpPage() const override - { - return "Minecraft-Logs"; - } + virtual QString helpPage() const override { return "Minecraft-Logs"; } virtual bool shouldDisplay() const override; void retranslate() override; -private slots: + private slots: void on_btnPaste_clicked(); void on_btnCopy_clicked(); void on_btnClear_clicked(); @@ -92,16 +78,16 @@ private slots: void onInstanceLaunchTaskChanged(shared_qobject_ptr proc); -private: + private: void modelStateToUI(); void UIToModelState(); void setInstanceLaunchTaskChanged(shared_qobject_ptr proc, bool initial); -private: - Ui::LogPage *ui; + private: + Ui::LogPage* ui; InstancePtr m_instance; shared_qobject_ptr m_process; - LogFormatProxyModel * m_proxy; - shared_qobject_ptr m_model; + LogFormatProxyModel* m_proxy; + shared_qobject_ptr m_model; }; diff --git a/launcher/ui/pages/instance/NotesPage.cpp b/launcher/ui/pages/instance/NotesPage.cpp index 95a9fad22..887bad85a 100644 --- a/launcher/ui/pages/instance/NotesPage.cpp +++ b/launcher/ui/pages/instance/NotesPage.cpp @@ -34,11 +34,10 @@ */ #include "NotesPage.h" -#include "ui_NotesPage.h" #include +#include "ui_NotesPage.h" -NotesPage::NotesPage(BaseInstance *inst, QWidget *parent) - : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst) +NotesPage::NotesPage(BaseInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst) { ui->setupUi(this); ui->noteEditor->setText(m_inst->notes()); diff --git a/launcher/ui/pages/instance/NotesPage.h b/launcher/ui/pages/instance/NotesPage.h index 80a7279bc..aa6083062 100644 --- a/launcher/ui/pages/instance/NotesPage.h +++ b/launcher/ui/pages/instance/NotesPage.h @@ -37,45 +37,34 @@ #include +#include #include "BaseInstance.h" #include "ui/pages/BasePage.h" -#include -namespace Ui -{ +namespace Ui { class NotesPage; } -class NotesPage : public QWidget, public BasePage -{ +class NotesPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit NotesPage(BaseInstance *inst, QWidget *parent = 0); + public: + explicit NotesPage(BaseInstance* inst, QWidget* parent = 0); virtual ~NotesPage(); - virtual QString displayName() const override - { - return tr("Notes"); - } + virtual QString displayName() const override { return tr("Notes"); } virtual QIcon icon() const override { auto icon = APPLICATION->getThemedIcon("notes"); - if(icon.isNull()) + if (icon.isNull()) icon = APPLICATION->getThemedIcon("news"); return icon; } - virtual QString id() const override - { - return "notes"; - } + virtual QString id() const override { return "notes"; } virtual bool apply() override; - virtual QString helpPage() const override - { - return "Notes"; - } + virtual QString helpPage() const override { return "Notes"; } void retranslate() override; -private: - Ui::NotesPage *ui; - BaseInstance *m_inst; + private: + Ui::NotesPage* ui; + BaseInstance* m_inst; }; diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index bbdd73248..b80c08e1b 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -41,14 +41,13 @@ #include "ui/GuiUtil.h" -#include "RecursiveFileSystemWatcher.h" -#include #include +#include #include +#include "RecursiveFileSystemWatcher.h" -OtherLogsPage::OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent) - : QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter), - m_watcher(new RecursiveFileSystemWatcher(this)) +OtherLogsPage::OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget* parent) + : QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter), m_watcher(new RecursiveFileSystemWatcher(this)) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); @@ -94,21 +93,15 @@ void OtherLogsPage::populateSelectLogBox() { ui->selectLogBox->clear(); ui->selectLogBox->addItems(m_watcher->files()); - if (m_currentFile.isEmpty()) - { + if (m_currentFile.isEmpty()) { setControlsEnabled(false); ui->selectLogBox->setCurrentIndex(-1); - } - else - { + } else { const int index = ui->selectLogBox->findText(m_currentFile); - if (index != -1) - { + if (index != -1) { ui->selectLogBox->setCurrentIndex(index); setControlsEnabled(true); - } - else - { + } else { setControlsEnabled(false); } } @@ -117,19 +110,15 @@ void OtherLogsPage::populateSelectLogBox() void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) { QString file; - if (index != -1) - { + if (index != -1) { file = ui->selectLogBox->itemText(index); } - if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file))) - { + if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file))) { m_currentFile = QString(); ui->text->clear(); setControlsEnabled(false); - } - else - { + } else { m_currentFile = file; on_btnReload_clicked(); setControlsEnabled(true); @@ -138,64 +127,49 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) void OtherLogsPage::on_btnReload_clicked() { - if(m_currentFile.isEmpty()) - { + if (m_currentFile.isEmpty()) { setControlsEnabled(false); return; } QFile file(FS::PathCombine(m_path, m_currentFile)); - if (!file.open(QFile::ReadOnly)) - { + if (!file.open(QFile::ReadOnly)) { setControlsEnabled(false); - ui->btnReload->setEnabled(true); // allow reload + ui->btnReload->setEnabled(true); // allow reload m_currentFile = QString(); - QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2") - .arg(m_currentFile, file.errorString())); - } - else - { - auto setPlainText = [&](const QString & text) - { + QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2").arg(m_currentFile, file.errorString())); + } else { + auto setPlainText = [&](const QString& text) { QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); bool conversionOk = false; int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); - if(!conversionOk) - { + if (!conversionOk) { fontSize = 11; } - QTextDocument *doc = ui->text->document(); + QTextDocument* doc = ui->text->document(); doc->setDefaultFont(QFont(fontFamily, fontSize)); ui->text->setPlainText(text); }; - auto showTooBig = [&]() - { - setPlainText( - tr("The file (%1) is too big. You may want to open it in a viewer optimized " - "for large files.").arg(file.fileName())); + auto showTooBig = [&]() { + setPlainText(tr("The file (%1) is too big. You may want to open it in a viewer optimized " + "for large files.") + .arg(file.fileName())); }; - if(file.size() > (1024ll * 1024ll * 12ll)) - { + if (file.size() > (1024ll * 1024ll * 12ll)) { showTooBig(); return; } QString content; - if(file.fileName().endsWith(".gz")) - { + if (file.fileName().endsWith(".gz")) { QByteArray temp; - if(!GZip::unzip(file.readAll(), temp)) - { - setPlainText( - tr("The file (%1) is not readable.").arg(file.fileName())); + if (!GZip::unzip(file.readAll(), temp)) { + setPlainText(tr("The file (%1) is not readable.").arg(file.fileName())); return; } content = QString::fromUtf8(temp); - } - else - { + } else { content = QString::fromUtf8(file.readAll()); } - if (content.size() >= 50000000ll) - { + if (content.size() >= 50000000ll) { showTooBig(); return; } @@ -215,8 +189,7 @@ void OtherLogsPage::on_btnCopy_clicked() void OtherLogsPage::on_btnDelete_clicked() { - if(m_currentFile.isEmpty()) - { + if (m_currentFile.isEmpty()) { setControlsEnabled(false); return; } @@ -230,36 +203,27 @@ void OtherLogsPage::on_btnDelete_clicked() } QFile file(FS::PathCombine(m_path, m_currentFile)); - if (FS::trash(file.fileName())) - { + if (FS::trash(file.fileName())) { return; } - if (!file.remove()) - { - QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2") - .arg(m_currentFile, file.errorString())); + if (!file.remove()) { + QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2").arg(m_currentFile, file.errorString())); } } - - void OtherLogsPage::on_btnClean_clicked() { auto toDelete = m_watcher->files(); - if(toDelete.isEmpty()) - { + if (toDelete.isEmpty()) { return; } - QMessageBox *messageBox = new QMessageBox(this); + QMessageBox* messageBox = new QMessageBox(this); messageBox->setWindowTitle(tr("Confirm Cleanup")); - if(toDelete.size() > 5) - { + if (toDelete.size() > 5) { messageBox->setText(tr("Are you sure you want to delete all log files?")); messageBox->setDetailedText(toDelete.join('\n')); - } - else - { + } else { messageBox->setText(tr("Are you sure you want to delete all these files?\n%1").arg(toDelete.join('\n'))); } messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); @@ -268,34 +232,26 @@ void OtherLogsPage::on_btnClean_clicked() messageBox->setIcon(QMessageBox::Question); messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction); - if (messageBox->exec() != QMessageBox::Ok) - { + if (messageBox->exec() != QMessageBox::Ok) { return; } QStringList failed; - for(auto item: toDelete) - { + for (auto item : toDelete) { QFile file(FS::PathCombine(m_path, item)); - if (FS::trash(file.fileName())) - { + if (FS::trash(file.fileName())) { continue; } - if (!file.remove()) - { + if (!file.remove()) { failed.push_back(item); } } - if(!failed.empty()) - { - QMessageBox *messageBox = new QMessageBox(this); + if (!failed.empty()) { + QMessageBox* messageBox = new QMessageBox(this); messageBox->setWindowTitle(tr("Error")); - if(failed.size() > 5) - { + if (failed.size() > 5) { messageBox->setText(tr("Couldn't delete some files!")); messageBox->setDetailedText(failed.join('\n')); - } - else - { + } else { messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n'))); } messageBox->setStandardButtons(QMessageBox::Ok); @@ -307,7 +263,6 @@ void OtherLogsPage::on_btnClean_clicked() } } - void OtherLogsPage::setControlsEnabled(const bool enabled) { ui->btnReload->setEnabled(enabled); @@ -319,7 +274,7 @@ void OtherLogsPage::setControlsEnabled(const bool enabled) } // FIXME: HACK, use LogView instead? -static void findNext(QPlainTextEdit * _this, const QString& what, bool reverse) +static void findNext(QPlainTextEdit* _this, const QString& what, bool reverse) { _this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0)); } @@ -344,8 +299,7 @@ void OtherLogsPage::findPreviousActivated() void OtherLogsPage::findActivated() { // focus the search bar if it doesn't have focus - if (!ui->searchBar->hasFocus()) - { + if (!ui->searchBar->hasFocus()) { ui->searchBar->setFocus(); ui->searchBar->selectAll(); } diff --git a/launcher/ui/pages/instance/OtherLogsPage.h b/launcher/ui/pages/instance/OtherLogsPage.h index 95591638b..ecb896fca 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.h +++ b/launcher/ui/pages/instance/OtherLogsPage.h @@ -37,47 +37,33 @@ #include -#include "ui/pages/BasePage.h" #include #include +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class OtherLogsPage; } class RecursiveFileSystemWatcher; -class OtherLogsPage : public QWidget, public BasePage -{ +class OtherLogsPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent = 0); + public: + explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget* parent = 0); ~OtherLogsPage(); - QString id() const override - { - return "logs"; - } - QString displayName() const override - { - return tr("Other logs"); - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("log"); - } - QString helpPage() const override - { - return "Minecraft-Logs"; - } + QString id() const override { return "logs"; } + QString displayName() const override { return tr("Other logs"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("log"); } + QString helpPage() const override { return "Minecraft-Logs"; } void retranslate() override; void openedImpl() override; void closedImpl() override; -private slots: + private slots: void populateSelectLogBox(); void on_selectLogBox_currentIndexChanged(const int index); void on_btnReload_clicked(); @@ -91,13 +77,13 @@ private slots: void findNextActivated(); void findPreviousActivated(); -private: + private: void setControlsEnabled(const bool enabled); -private: - Ui::OtherLogsPage *ui; + private: + Ui::OtherLogsPage* ui; QString m_path; QString m_currentFile; IPathMatcher::Ptr m_fileFilter; - RecursiveFileSystemWatcher *m_watcher; + RecursiveFileSystemWatcher* m_watcher; }; diff --git a/launcher/ui/pages/instance/ResourcePackPage.h b/launcher/ui/pages/instance/ResourcePackPage.h index b04aa2e96..cb84ca96d 100644 --- a/launcher/ui/pages/instance/ResourcePackPage.h +++ b/launcher/ui/pages/instance/ResourcePackPage.h @@ -42,11 +42,10 @@ #include "minecraft/mod/ResourcePackFolderModel.h" -class ResourcePackPage : public ExternalResourcesPage -{ +class ResourcePackPage : public ExternalResourcesPage { Q_OBJECT -public: - explicit ResourcePackPage(MinecraftInstance *instance, std::shared_ptr model, QWidget *parent = 0); + public: + explicit ResourcePackPage(MinecraftInstance* instance, std::shared_ptr model, QWidget* parent = 0); QString displayName() const override { return tr("Resource packs"); } QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); } @@ -55,12 +54,10 @@ public: virtual bool shouldDisplay() const override { - return !m_instance->traits().contains("no-texturepacks") && - !m_instance->traits().contains("texturepacks"); + return !m_instance->traits().contains("no-texturepacks") && !m_instance->traits().contains("texturepacks"); } public slots: bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override; void downloadRPs(); }; - diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index bcce5f572..29c835fc1 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -39,52 +39,50 @@ #include "BuildConfig.h" #include "ui_ScreenshotsPage.h" -#include -#include -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include +#include #include +#include +#include #include -#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" #include "net/NetJob.h" -#include "screenshots/ImgurUpload.h" #include "screenshots/ImgurAlbumCreation.h" +#include "screenshots/ImgurUpload.h" #include "tasks/SequentialTask.h" -#include "RWStorage.h" -#include #include +#include +#include "RWStorage.h" typedef RWStorage SharedIconCache; typedef std::shared_ptr SharedIconCachePtr; -class ThumbnailingResult : public QObject -{ +class ThumbnailingResult : public QObject { Q_OBJECT -public slots: - inline void emitResultsReady(const QString &path) { emit resultsReady(path); } - inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); } -signals: - void resultsReady(const QString &path); - void resultsFailed(const QString &path); + public slots: + inline void emitResultsReady(const QString& path) { emit resultsReady(path); } + inline void emitResultsFailed(const QString& path) { emit resultsFailed(path); } + signals: + void resultsReady(const QString& path); + void resultsFailed(const QString& path); }; -class ThumbnailRunnable : public QRunnable -{ -public: +class ThumbnailRunnable : public QRunnable { + public: ThumbnailRunnable(QString path, SharedIconCachePtr cache) { m_path = path; @@ -129,57 +127,50 @@ public: // this is about as elegant and well written as a bag of bricks with scribbles done by insane // asylum patients. -class FilterModel : public QIdentityProxyModel -{ +class FilterModel : public QIdentityProxyModel { Q_OBJECT -public: - explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent) + public: + explicit FilterModel(QObject* parent = 0) : QIdentityProxyModel(parent) { m_thumbnailingPool.setMaxThreadCount(4); m_thumbnailCache = std::make_shared(); m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); } - virtual ~FilterModel() { + virtual ~FilterModel() + { m_thumbnailingPool.clear(); if (!m_thumbnailingPool.waitForDone(500)) qDebug() << "Thumbnail pool took longer than 500ms to finish"; } - virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const + virtual QVariant data(const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const { auto model = sourceModel(); if (!model) return QVariant(); - if (role == Qt::DisplayRole || role == Qt::EditRole) - { + if (role == Qt::DisplayRole || role == Qt::EditRole) { QVariant result = sourceModel()->data(mapToSource(proxyIndex), role); return result.toString().remove(QRegularExpression("\\.png$")); } - if (role == Qt::DecorationRole) - { - QVariant result = - sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole); + if (role == Qt::DecorationRole) { + QVariant result = sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole); QString filePath = result.toString(); QIcon temp; - if (!watched.contains(filePath)) - { - ((QFileSystemWatcher &)watcher).addPath(filePath); - ((QSet &)watched).insert(filePath); + if (!watched.contains(filePath)) { + ((QFileSystemWatcher&)watcher).addPath(filePath); + ((QSet&)watched).insert(filePath); } - if (m_thumbnailCache->get(filePath, temp)) - { + if (m_thumbnailCache->get(filePath, temp)) { return temp; } - if (!m_failed.contains(filePath)) - { - ((FilterModel *)this)->thumbnailImage(filePath); + if (!m_failed.contains(filePath)) { + ((FilterModel*)this)->thumbnailImage(filePath); } return (m_thumbnailCache->get("placeholder")); } return sourceModel()->data(mapToSource(proxyIndex), role); } - virtual bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) + virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) { auto model = sourceModel(); if (!model) @@ -189,23 +180,21 @@ public: // FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't // sort after renames { - ((QFileSystemModel *)model)->setNameFilterDisables(true); - ((QFileSystemModel *)model)->setNameFilterDisables(false); + ((QFileSystemModel*)model)->setNameFilterDisables(true); + ((QFileSystemModel*)model)->setNameFilterDisables(false); } return model->setData(mapToSource(index), value.toString() + ".png", role); } -private: + private: void thumbnailImage(QString path) { auto runnable = new ThumbnailRunnable(path, m_thumbnailCache); - connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)), - SLOT(thumbnailReady(QString))); - connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)), - SLOT(thumbnailFailed(QString))); - ((QThreadPool &)m_thumbnailingPool).start(runnable); + connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)), SLOT(thumbnailReady(QString))); + connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)), SLOT(thumbnailFailed(QString))); + ((QThreadPool&)m_thumbnailingPool).start(runnable); } -private slots: + private slots: void thumbnailReady(QString path) { emit layoutChanged(); } void thumbnailFailed(QString path) { m_failed.insert(path); } void fileChanged(QString filepath) @@ -219,7 +208,7 @@ private slots: } } -private: + private: SharedIconCachePtr m_thumbnailCache; QThreadPool m_thumbnailingPool; QSet m_failed; @@ -227,18 +216,15 @@ private: QFileSystemWatcher watcher; }; -class CenteredEditingDelegate : public QStyledItemDelegate -{ -public: - explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {} +class CenteredEditingDelegate : public QStyledItemDelegate { + public: + explicit CenteredEditingDelegate(QObject* parent = 0) : QStyledItemDelegate(parent) {} virtual ~CenteredEditingDelegate() {} - virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { auto widget = QStyledItemDelegate::createEditor(parent, option, index); - auto foo = dynamic_cast(widget); - if (foo) - { + auto foo = dynamic_cast(widget); + if (foo) { foo->setAlignment(Qt::AlignHCenter); foo->setFrame(true); foo->setMaximumWidth(192); @@ -247,15 +233,14 @@ public: } }; -ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent) - : QMainWindow(parent), ui(new Ui::ScreenshotsPage) +ScreenshotsPage::ScreenshotsPage(QString path, QWidget* parent) : QMainWindow(parent), ui(new Ui::ScreenshotsPage) { m_model.reset(new QFileSystemModel()); m_filterModel.reset(new FilterModel()); m_filterModel->setSourceModel(m_model.get()); m_model->setFilter(QDir::Files); m_model->setReadOnly(false); - m_model->setNameFilters({"*.png"}); + m_model->setNameFilters({ "*.png" }); m_model->setNameFilterDisables(false); m_folder = path; m_valid = FS::ensureFolderPathExists(m_folder); @@ -278,31 +263,29 @@ ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent) connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex))); } -bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt) +bool ScreenshotsPage::eventFilter(QObject* obj, QEvent* evt) { if (obj != ui->listView) return QWidget::eventFilter(obj, evt); - if (evt->type() != QEvent::KeyPress) - { + if (evt->type() != QEvent::KeyPress) { return QWidget::eventFilter(obj, evt); } - QKeyEvent *keyEvent = static_cast(evt); + QKeyEvent* keyEvent = static_cast(evt); if (keyEvent->matches(QKeySequence::Copy)) { on_actionCopy_File_s_triggered(); return true; } - switch (keyEvent->key()) - { - case Qt::Key_Delete: - on_actionDelete_triggered(); - return true; - case Qt::Key_F2: - on_actionRename_triggered(); - return true; - default: - break; + switch (keyEvent->key()) { + case Qt::Key_Delete: + on_actionDelete_triggered(); + return true; + case Qt::Key_F2: + on_actionRename_triggered(); + return true; + default: + break; } return QWidget::eventFilter(obj, evt); } @@ -322,17 +305,17 @@ void ScreenshotsPage::ShowContextMenu(const QPoint& pos) auto menu = ui->toolBar->createContextMenu(this, tr("Context menu")); if (ui->listView->selectionModel()->selectedRows().size() > 1) { - menu->removeAction( ui->actionCopy_Image ); + menu->removeAction(ui->actionCopy_Image); } menu->exec(ui->listView->mapToGlobal(pos)); delete menu; } -QMenu * ScreenshotsPage::createPopupMenu() +QMenu* ScreenshotsPage::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); - filteredMenu->removeAction( ui->toolBar->toggleViewAction() ); + filteredMenu->removeAction(ui->toolBar->toggleViewAction()); return filteredMenu; } @@ -345,13 +328,12 @@ void ScreenshotsPage::onItemActivated(QModelIndex index) DesktopServices::openFile(info.absoluteFilePath()); } -void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection &selected) +void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection& selected) { bool allReadable = !selected.isEmpty(); bool allWritable = !selected.isEmpty(); - for (auto index : selected.indexes()) - { + for (auto index : selected.indexes()) { if (!index.isValid()) break; auto info = m_model->fileInfo(index); @@ -401,8 +383,7 @@ void ScreenshotsPage::on_actionUpload_triggered() QList uploaded; auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network())); - if(selection.size() < 2) - { + if (selection.size() < 2) { auto item = selection.at(0); auto info = m_model->fileInfo(item); auto screenshot = std::make_shared(info); @@ -411,31 +392,24 @@ void ScreenshotsPage::on_actionUpload_triggered() m_uploadActive = true; ProgressDialog dialog(this); - if(dialog.execWithTask(job.get()) != QDialog::Accepted) - { - CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), - tr("Unknown error"), QMessageBox::Warning)->exec(); - } - else - { + if (dialog.execWithTask(job.get()) != QDialog::Accepted) { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + } else { auto link = screenshot->m_url; - QClipboard *clipboard = QApplication::clipboard(); + QClipboard* clipboard = QApplication::clipboard(); clipboard->setText(link); CustomMessageBox::selectable( - this, - tr("Upload finished"), - tr("The link to the uploaded screenshot has been placed in your clipboard.") - .arg(link), - QMessageBox::Information - )->exec(); + this, tr("Upload finished"), + tr("The link to the uploaded screenshot has been placed in your clipboard.").arg(link), + QMessageBox::Information) + ->exec(); } m_uploadActive = false; return; } - for (auto item : selection) - { + for (auto item : selection) { auto info = m_model->fileInfo(item); auto screenshot = std::make_shared(info); uploaded.push_back(screenshot); @@ -449,26 +423,16 @@ void ScreenshotsPage::on_actionUpload_triggered() task.addTask(albumTask); m_uploadActive = true; ProgressDialog prog(this); - if (prog.execWithTask(&task) != QDialog::Accepted) - { - CustomMessageBox::selectable( - this, - tr("Failed to upload screenshots!"), - tr("Unknown error"), - QMessageBox::Warning - )->exec(); - } - else - { + if (prog.execWithTask(&task) != QDialog::Accepted) { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + } else { auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id()); - QClipboard *clipboard = QApplication::clipboard(); + QClipboard* clipboard = QApplication::clipboard(); clipboard->setText(link); - CustomMessageBox::selectable( - this, - tr("Upload finished"), - tr("The link to the uploaded album has been placed in your clipboard.") .arg(link), - QMessageBox::Information - )->exec(); + CustomMessageBox::selectable(this, tr("Upload finished"), + tr("The link to the uploaded album has been placed in your clipboard.").arg(link), + QMessageBox::Information) + ->exec(); } m_uploadActive = false; } @@ -476,8 +440,7 @@ void ScreenshotsPage::on_actionUpload_triggered() void ScreenshotsPage::on_actionCopy_Image_triggered() { auto selection = ui->listView->selectionModel()->selectedRows(); - if(selection.size() < 1) - { + if (selection.size() < 1) { return; } @@ -492,15 +455,13 @@ void ScreenshotsPage::on_actionCopy_Image_triggered() void ScreenshotsPage::on_actionCopy_File_s_triggered() { auto selection = ui->listView->selectionModel()->selectedRows(); - if(selection.size() < 1) - { + if (selection.size() < 1) { // Don't do anything so we don't empty the users clipboard return; } QString buf = ""; - for (auto item : selection) - { + for (auto item : selection) { auto info = m_model->fileInfo(item); buf += "file:///" + info.absoluteFilePath() + "\r\n"; } @@ -532,8 +493,7 @@ void ScreenshotsPage::on_actionDelete_triggered() if (response != QMessageBox::Yes) return; - for (auto item : selected) - { + for (auto item : selected) { if (FS::trash(m_model->filePath(item))) continue; @@ -552,23 +512,19 @@ void ScreenshotsPage::on_actionRename_triggered() void ScreenshotsPage::openedImpl() { - if(!m_valid) - { + if (!m_valid) { m_valid = FS::ensureFolderPathExists(m_folder); } - if (m_valid) - { + if (m_valid) { QString path = QDir(m_folder).absolutePath(); auto idx = m_model->setRootPath(path); - if(idx.isValid()) - { + if (idx.isValid()) { ui->listView->setModel(m_filterModel.get()); - connect(ui->listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ScreenshotsPage::onCurrentSelectionChanged); - onCurrentSelectionChanged(ui->listView->selectionModel()->selection()); // set initial button enable states + connect(ui->listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, + &ScreenshotsPage::onCurrentSelectionChanged); + onCurrentSelectionChanged(ui->listView->selectionModel()->selection()); // set initial button enable states ui->listView->setRootIndex(m_filterModel->mapFromSource(idx)); - } - else - { + } else { ui->listView->setModel(nullptr); } } diff --git a/launcher/ui/pages/instance/ScreenshotsPage.h b/launcher/ui/pages/instance/ScreenshotsPage.h index 89611b6d1..0f824a056 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.h +++ b/launcher/ui/pages/instance/ScreenshotsPage.h @@ -37,16 +37,15 @@ #include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" #include "settings/Setting.h" class QFileSystemModel; class QIdentityProxyModel; class QItemSelection; -namespace Ui -{ +namespace Ui { class ScreenshotsPage; } @@ -54,49 +53,30 @@ struct ScreenShot; class ScreenshotList; class ImgurAlbumCreation; -class ScreenshotsPage : public QMainWindow, public BasePage -{ +class ScreenshotsPage : public QMainWindow, public BasePage { Q_OBJECT -public: - explicit ScreenshotsPage(QString path, QWidget *parent = 0); + public: + explicit ScreenshotsPage(QString path, QWidget* parent = 0); virtual ~ScreenshotsPage(); void openedImpl() override; void closedImpl() override; - enum - { - NothingDone = 0x42 - }; + enum { NothingDone = 0x42 }; - virtual bool eventFilter(QObject *, QEvent *) override; - virtual QString displayName() const override - { - return tr("Screenshots"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("screenshots"); - } - virtual QString id() const override - { - return "screenshots"; - } - virtual QString helpPage() const override - { - return "Screenshots-management"; - } - virtual bool apply() override - { - return !m_uploadActive; - } + virtual bool eventFilter(QObject*, QEvent*) override; + virtual QString displayName() const override { return tr("Screenshots"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("screenshots"); } + virtual QString id() const override { return "screenshots"; } + virtual QString helpPage() const override { return "Screenshots-management"; } + virtual bool apply() override { return !m_uploadActive; } void retranslate() override; -protected: - QMenu * createPopupMenu() override; + protected: + QMenu* createPopupMenu() override; -private slots: + private slots: void on_actionUpload_triggered(); void on_actionCopy_Image_triggered(); void on_actionCopy_File_s_triggered(); @@ -104,11 +84,11 @@ private slots: void on_actionRename_triggered(); void on_actionView_Folder_triggered(); void onItemActivated(QModelIndex); - void onCurrentSelectionChanged(const QItemSelection &selected); - void ShowContextMenu(const QPoint &pos); + void onCurrentSelectionChanged(const QItemSelection& selected); + void ShowContextMenu(const QPoint& pos); -private: - Ui::ScreenshotsPage *ui; + private: + Ui::ScreenshotsPage* ui; std::shared_ptr m_model; std::shared_ptr m_filterModel; QString m_folder; diff --git a/launcher/ui/pages/instance/ServersPage.cpp b/launcher/ui/pages/instance/ServersPage.cpp index 4b1fa08a3..07daca219 100644 --- a/launcher/ui/pages/instance/ServersPage.cpp +++ b/launcher/ui/pages/instance/ServersPage.cpp @@ -40,36 +40,27 @@ #include "ui_ServersPage.h" #include -#include #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include #include #include -static const int COLUMN_COUNT = 2; // 3 , TBD: latency and other nice things. +static const int COLUMN_COUNT = 2; // 3 , TBD: latency and other nice things. -struct Server -{ +struct Server { // Types - enum class AcceptsTextures : int - { - ASK = 0, - ALWAYS = 1, - NEVER = 2 - }; + enum class AcceptsTextures : int { ASK = 0, ALWAYS = 1, NEVER = 2 }; // Methods - Server() - { - m_name = QObject::tr("Minecraft Server"); - } - Server(const QString & name, const QString & address) + Server() { m_name = QObject::tr("Minecraft Server"); } + Server(const QString& name, const QString& address) { m_name = name; m_address = address; @@ -82,21 +73,16 @@ struct Server std::string nameStr(server["name"]); m_name = QString::fromUtf8(nameStr.c_str()); - if(server["icon"]) - { + if (server["icon"]) { std::string base64str(server["icon"]); m_icon = QByteArray::fromBase64(base64str.c_str()); } - if(server.has_key("acceptTextures", nbt::tag_type::Byte)) - { + if (server.has_key("acceptTextures", nbt::tag_type::Byte)) { bool value = server["acceptTextures"].as().get(); - if(value) - { + if (value) { m_acceptsTextures = AcceptsTextures::ALWAYS; - } - else - { + } else { m_acceptsTextures = AcceptsTextures::NEVER; } } @@ -106,12 +92,10 @@ struct Server { server.insert("name", m_name.trimmed().toUtf8().toStdString()); server.insert("ip", m_address.trimmed().toUtf8().toStdString()); - if(m_icon.size()) - { + if (m_icon.size()) { server.insert("icon", m_icon.toBase64().toStdString()); } - if(m_acceptsTextures != AcceptsTextures::ASK) - { + if (m_acceptsTextures != AcceptsTextures::ASK) { server.insert("acceptTextures", nbt::tag_byte(m_acceptsTextures == AcceptsTextures::ALWAYS)); } } @@ -127,64 +111,54 @@ struct Server // Data - temporary bool m_checked = false; bool m_up = false; - QString m_motd; // https://mctools.org/motd-creator + QString m_motd; // https://mctools.org/motd-creator int m_ping = 0; int m_currentPlayers = 0; int m_maxPlayers = 0; }; -static std::unique_ptr parseServersDat(const QString& filename) +static std::unique_ptr parseServersDat(const QString& filename) { - try - { + try { QByteArray input = FS::read(filename); std::istringstream foo(std::string(input.constData(), input.size())); auto pair = nbt::io::read_compound(foo); - if(pair.first != "") + if (pair.first != "") return nullptr; - if(pair.second == nullptr) + if (pair.second == nullptr) return nullptr; return std::move(pair.second); - } - catch (...) - { + } catch (...) { return nullptr; } } -static bool serializeServerDat(const QString& filename, nbt::tag_compound * levelInfo) +static bool serializeServerDat(const QString& filename, nbt::tag_compound* levelInfo) { - try - { - if(!FS::ensureFilePathExists(filename)) - { + try { + if (!FS::ensureFilePathExists(filename)) { return false; } std::ostringstream s; nbt::io::write_tag("", *levelInfo, s); - QByteArray val(s.str().data(), (int) s.str().size() ); + QByteArray val(s.str().data(), (int)s.str().size()); FS::write(filename, val); return true; - } - catch (...) - { + } catch (...) { return false; } } -class ServersModel: public QAbstractListModel -{ +class ServersModel : public QAbstractListModel { Q_OBJECT -public: - enum Roles - { + public: + enum Roles { ServerPtrRole = Qt::UserRole, }; - explicit ServersModel(const QString &path, QObject *parent = 0) - : QAbstractListModel(parent) + explicit ServersModel(const QString& path, QObject* parent = 0) : QAbstractListModel(parent) { m_path = path; m_watcher = new QFileSystemWatcher(this); @@ -194,18 +168,16 @@ public: m_saveTimer.setInterval(5000); connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal); } - virtual ~ServersModel() {}; + virtual ~ServersModel(){}; void observe() { - if(m_observed) - { + if (m_observed) { return; } m_observed = true; - if(!m_loaded) - { + if (!m_loaded) { load(); } @@ -214,8 +186,7 @@ public: void unobserve() { - if(!m_observed) - { + if (!m_observed) { return; } m_observed = false; @@ -225,8 +196,7 @@ public: void lock() { - if(m_locked) - { + if (m_locked) { return; } saveNow(); @@ -237,8 +207,7 @@ public: void unlock() { - if(!m_locked) - { + if (!m_locked) { return; } m_locked = false; @@ -248,12 +217,10 @@ public: int addEmptyRow(int position) { - if(m_locked) - { + if (m_locked) { return -1; } - if(position < 0 || position >= rowCount()) - { + if (position < 0 || position >= rowCount()) { position = rowCount(); } beginInsertRows(QModelIndex(), position, position); @@ -265,36 +232,32 @@ public: bool removeRow(int row) { - if(m_locked) - { + if (m_locked) { return false; } - if(row < 0 || row >= rowCount()) - { + if (row < 0 || row >= rowCount()) { return false; } beginRemoveRows(QModelIndex(), row, row); m_servers.removeAt(row); - endRemoveRows(); // does absolutely nothing, the selected server stays as the next line... + endRemoveRows(); // does absolutely nothing, the selected server stays as the next line... scheduleSave(); return true; } bool moveUp(int row) { - if(m_locked) - { + if (m_locked) { return false; } - if(row <= 0) - { + if (row <= 0) { return false; } beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1); #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - m_servers.swapItemsAt(row-1, row); + m_servers.swapItemsAt(row - 1, row); #else - m_servers.swap(row-1, row); + m_servers.swap(row - 1, row); #endif endMoveRows(); scheduleSave(); @@ -303,20 +266,18 @@ public: bool moveDown(int row) { - if(m_locked) - { + if (m_locked) { return false; } int count = rowCount(); - if(row + 1 >= count) - { + if (row + 1 >= count) { return false; } beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 2); #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - m_servers.swapItemsAt(row+1, row); + m_servers.swapItemsAt(row + 1, row); #else - m_servers.swap(row+1, row); + m_servers.swap(row + 1, row); #endif endMoveRows(); scheduleSave(); @@ -328,10 +289,8 @@ public: if (section < 0 || section >= COLUMN_COUNT) return QVariant(); - if(role == Qt::DisplayRole) - { - switch(section) - { + if (role == Qt::DisplayRole) { + switch (section) { case 0: return tr("Name"); case 1: @@ -344,90 +303,81 @@ public: return QAbstractListModel::headerData(section, orientation, role); } - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override { if (!index.isValid()) return QVariant(); int row = index.row(); int column = index.column(); - if(column < 0 || column >= COLUMN_COUNT) + if (column < 0 || column >= COLUMN_COUNT) return QVariant(); if (row < 0 || row >= m_servers.size()) return QVariant(); - switch(column) - { + switch (column) { case 0: - switch (role) - { - case Qt::DecorationRole: - { - auto & bytes = m_servers[row].m_icon; - if(bytes.size()) - { - QPixmap px; - if(px.loadFromData(bytes)) - return QIcon(px); + switch (role) { + case Qt::DecorationRole: { + auto& bytes = m_servers[row].m_icon; + if (bytes.size()) { + QPixmap px; + if (px.loadFromData(bytes)) + return QIcon(px); + } + return APPLICATION->getThemedIcon("unknown_server"); } - return APPLICATION->getThemedIcon("unknown_server"); - } - case Qt::DisplayRole: - return m_servers[row].m_name; - case ServerPtrRole: - return QVariant::fromValue((void *)&m_servers[row]); - default: - return QVariant(); + case Qt::DisplayRole: + return m_servers[row].m_name; + case ServerPtrRole: + return QVariant::fromValue((void*)&m_servers[row]); + default: + return QVariant(); } case 1: - switch (role) - { - case Qt::DisplayRole: - return m_servers[row].m_address; - default: - return QVariant(); + switch (role) { + case Qt::DisplayRole: + return m_servers[row].m_address; + default: + return QVariant(); } case 2: - switch (role) - { - case Qt::DisplayRole: - return m_servers[row].m_ping; - default: - return QVariant(); + switch (role) { + case Qt::DisplayRole: + return m_servers[row].m_ping; + default: + return QVariant(); } default: return QVariant(); } } - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override { return parent.isValid() ? 0 : m_servers.size(); } - int columnCount(const QModelIndex & parent) const override + int columnCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : COLUMN_COUNT; } - Server * at(int index) + Server* at(int index) { - if(index < 0 || index >= rowCount()) - { + if (index < 0 || index >= rowCount()) { return nullptr; } return &m_servers[index]; } - void setName(int row, const QString & name) + void setName(int row, const QString& name) { - if(m_locked) - { + if (m_locked) { return; } auto server = at(row); - if(!server || server->m_name == name) - { + if (!server || server->m_name == name) { return; } server->m_name = name; @@ -435,15 +385,13 @@ public: scheduleSave(); } - void setAddress(int row, const QString & address) + void setAddress(int row, const QString& address) { - if(m_locked) - { + if (m_locked) { return; } auto server = at(row); - if(!server || server->m_address == address) - { + if (!server || server->m_address == address) { return; } server->m_address = address; @@ -453,13 +401,11 @@ public: void setAcceptsTextures(int row, Server::AcceptsTextures textures) { - if(m_locked) - { + if (m_locked) { return; } auto server = at(row); - if(!server || server->m_acceptsTextures == textures) - { + if (!server || server->m_acceptsTextures == textures) { return; } server->m_acceptsTextures = textures; @@ -473,12 +419,10 @@ public: beginResetModel(); QList servers; auto serversDat = parseServersDat(serversPath()); - if(serversDat) - { - auto &serversList = serversDat->at("servers").as(); - for(auto iter = serversList.begin(); iter != serversList.end(); iter++) - { - auto & serverTag = (*iter).as(); + if (serversDat) { + auto& serversList = serversDat->at("servers").as(); + for (auto iter = serversList.begin(); iter != serversList.end(); iter++) { + auto& serverTag = (*iter).as(); Server s(serverTag); servers.append(s); } @@ -490,14 +434,12 @@ public: void saveNow() { - if(saveIsScheduled()) - { + if (saveIsScheduled()) { save_internal(); } } - -public slots: + public slots: void dirChanged(const QString& path) { qDebug() << "Changed:" << path; @@ -508,7 +450,7 @@ public slots: qDebug() << "Changed:" << path; } -private slots: + private slots: void save_internal() { cancelSave(); @@ -517,31 +459,27 @@ private slots: nbt::tag_compound out; nbt::tag_list list; - for(auto & server: m_servers) - { + for (auto& server : m_servers) { nbt::tag_compound serverNbt; server.serialize(serverNbt); list.push_back(std::move(serverNbt)); } out.insert("servers", nbt::value(std::move(list))); - if(!serializeServerDat(path, &out)) - { + if (!serializeServerDat(path, &out)) { qDebug() << "Failed to save server list:" << path << "Will try again."; scheduleSave(); } } -private: + private: void scheduleSave() { - if(!m_loaded) - { + if (!m_loaded) { qDebug() << "Server list should never save if it didn't successfully load, path:" << m_path; return; } - if(!m_dirty) - { + if (!m_dirty) { m_dirty = true; qDebug() << "Server list save is scheduled for" << m_path; } @@ -562,24 +500,17 @@ private: void updateFSObserver() { bool observingFS = m_watcher->directories().contains(m_path); - if(m_observed && m_locked) - { - if(!observingFS) - { + if (m_observed && m_locked) { + if (!observingFS) { qWarning() << "Will watch" << m_path; - if(!m_watcher->addPath(m_path)) - { + if (!m_watcher->addPath(m_path)) { qWarning() << "Failed to start watching" << m_path; } } - } - else - { - if(observingFS) - { + } else { + if (observingFS) { qWarning() << "Will stop watching" << m_path; - if(!m_watcher->removePath(m_path)) - { + if (!m_watcher->removePath(m_path)) { qWarning() << "Failed to stop watching" << m_path; } } @@ -592,34 +523,31 @@ private: return foo.filePath(); } -private: + private: bool m_loaded = false; bool m_locked = false; bool m_observed = false; bool m_dirty = false; QString m_path; QList m_servers; - QFileSystemWatcher *m_watcher = nullptr; + QFileSystemWatcher* m_watcher = nullptr; QTimer m_saveTimer; }; -ServersPage::ServersPage(InstancePtr inst, QWidget* parent) - : QMainWindow(parent), ui(new Ui::ServersPage) +ServersPage::ServersPage(InstancePtr inst, QWidget* parent) : QMainWindow(parent), ui(new Ui::ServersPage) { ui->setupUi(this); m_inst = inst; m_model = new ServersModel(inst->gameRoot(), this); - ui->serversView->setIconSize(QSize(64,64)); + ui->serversView->setIconSize(QSize(64, 64)); ui->serversView->setModel(m_model); ui->serversView->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->serversView, &QTreeView::customContextMenuRequested, this, &ServersPage::ShowContextMenu); auto head = ui->serversView->header(); - if(head->count()) - { + if (head->count()) { head->setSectionResizeMode(0, QHeaderView::Stretch); - for(int i = 1; i < head->count(); i++) - { + for (int i = 1; i < head->count(); i++) { head->setSectionResizeMode(i, QHeaderView::ResizeToContents); } } @@ -633,8 +561,7 @@ ServersPage::ServersPage(InstancePtr inst, QWidget* parent) connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ServersPage::rowsRemoved); m_locked = m_inst->isRunning(); - if(m_locked) - { + if (m_locked) { m_model->lock(); } @@ -659,40 +586,33 @@ void ServersPage::ShowContextMenu(const QPoint& pos) delete menu; } -QMenu * ServersPage::createPopupMenu() +QMenu* ServersPage::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); - filteredMenu->removeAction( ui->toolBar->toggleViewAction() ); + filteredMenu->removeAction(ui->toolBar->toggleViewAction()); return filteredMenu; } void ServersPage::runningStateChanged(bool running) { - if(m_locked == running) - { + if (m_locked == running) { return; } m_locked = running; - if(m_locked) - { + if (m_locked) { m_model->lock(); - } - else - { + } else { m_model->unlock(); } updateState(); } -void ServersPage::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +void ServersPage::currentChanged(const QModelIndex& current, const QModelIndex& previous) { int nextServer = -1; - if (!current.isValid()) - { + if (!current.isValid()) { nextServer = -1; - } - else - { + } else { nextServer = current.row(); } currentServer = nextServer; @@ -702,18 +622,13 @@ void ServersPage::currentChanged(const QModelIndex ¤t, const QModelIndex & // WARNING: this is here because currentChanged is not accurate when removing rows. the current item needs to be fixed up after removal. void ServersPage::rowsRemoved(const QModelIndex& parent, int first, int last) { - if(currentServer < first) - { + if (currentServer < first) { // current was before the removal return; - } - else if(currentServer >= first && currentServer <= last) - { + } else if (currentServer >= first && currentServer <= last) { // current got removed... return; - } - else - { + } else { // current was past the removal int count = last - first + 1; currentServer -= count; @@ -749,14 +664,11 @@ void ServersPage::updateState() ui->actionRemove->setEnabled(serverEditEnabled); ui->actionJoin->setEnabled(serverEditEnabled); - if(server) - { + if (server) { ui->addressLine->setText(server->m_address); ui->nameLine->setText(server->m_name); ui->resourceComboBox->setCurrentIndex(int(server->m_acceptsTextures)); - } - else - { + } else { ui->addressLine->setText(QString()); ui->nameLine->setText(QString()); ui->resourceComboBox->setCurrentIndex(0); @@ -788,27 +700,25 @@ void ServersPage::closedImpl() void ServersPage::on_actionAdd_triggered() { int position = m_model->addEmptyRow(currentServer + 1); - if(position < 0) - { + if (position < 0) { return; } // select the new row ui->serversView->selectionModel()->setCurrentIndex( - m_model->index(position), - QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows - ); + m_model->index(position), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows); currentServer = position; } void ServersPage::on_actionRemove_triggered() { - auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"), - tr("You are about to remove \"%1\".\n" - "This is permanent and the server will be gone from your list forever (A LONG TIME).\n\n" - "Are you sure?") - .arg(m_model->at(currentServer)->m_name), - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) - ->exec(); + auto response = + CustomMessageBox::selectable(this, tr("Confirm Removal"), + tr("You are about to remove \"%1\".\n" + "This is permanent and the server will be gone from your list forever (A LONG TIME).\n\n" + "Are you sure?") + .arg(m_model->at(currentServer)->m_name), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); if (response != QMessageBox::Yes) return; @@ -818,23 +728,21 @@ void ServersPage::on_actionRemove_triggered() void ServersPage::on_actionMove_Up_triggered() { - if(m_model->moveUp(currentServer)) - { - currentServer --; + if (m_model->moveUp(currentServer)) { + currentServer--; } } void ServersPage::on_actionMove_Down_triggered() { - if(m_model->moveDown(currentServer)) - { - currentServer ++; + if (m_model->moveDown(currentServer)) { + currentServer++; } } void ServersPage::on_actionJoin_triggered() { - const auto &address = m_model->at(currentServer)->m_address; + const auto& address = m_model->at(currentServer)->m_address; APPLICATION->launch(m_inst, true, false, nullptr, std::make_shared(MinecraftServerTarget::parse(address))); } diff --git a/launcher/ui/pages/instance/ServersPage.h b/launcher/ui/pages/instance/ServersPage.h index 476e7d70d..96a8dd7d4 100644 --- a/launcher/ui/pages/instance/ServersPage.h +++ b/launcher/ui/pages/instance/ServersPage.h @@ -39,13 +39,12 @@ #include #include -#include "ui/pages/BasePage.h" #include +#include "ui/pages/BasePage.h" #include "settings/Setting.h" -namespace Ui -{ +namespace Ui { class ServersPage; } @@ -53,46 +52,33 @@ struct Server; class ServersModel; class MinecraftInstance; -class ServersPage : public QMainWindow, public BasePage -{ +class ServersPage : public QMainWindow, public BasePage { Q_OBJECT -public: - explicit ServersPage(InstancePtr inst, QWidget *parent = 0); + public: + explicit ServersPage(InstancePtr inst, QWidget* parent = 0); virtual ~ServersPage(); void openedImpl() override; void closedImpl() override; - virtual QString displayName() const override - { - return tr("Servers"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("server"); - } - virtual QString id() const override - { - return "servers"; - } - virtual QString helpPage() const override - { - return "Servers-management"; - } + virtual QString displayName() const override { return tr("Servers"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("server"); } + virtual QString id() const override { return "servers"; } + virtual QString helpPage() const override { return "Servers-management"; } void retranslate() override; -protected: - QMenu * createPopupMenu() override; + protected: + QMenu* createPopupMenu() override; -private: + private: void updateState(); void scheduleSave(); bool saveIsScheduled() const; -private slots: - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - void rowsRemoved(const QModelIndex &parent, int first, int last); + private slots: + void currentChanged(const QModelIndex& current, const QModelIndex& previous); + void rowsRemoved(const QModelIndex& parent, int first, int last); void on_actionAdd_triggered(); void on_actionRemove_triggered(); @@ -102,19 +88,18 @@ private slots: void runningStateChanged(bool running); - void nameEdited(const QString & name); - void addressEdited(const QString & address); - void resourceIndexChanged(int index);\ + void nameEdited(const QString& name); + void addressEdited(const QString& address); + void resourceIndexChanged(int index); - void ShowContextMenu(const QPoint &pos); + void ShowContextMenu(const QPoint& pos); -private: // data + private: // data int currentServer = -1; bool m_locked = true; - Ui::ServersPage *ui = nullptr; - ServersModel * m_model = nullptr; + Ui::ServersPage* ui = nullptr; + ServersModel* m_model = nullptr; InstancePtr m_inst = nullptr; std::shared_ptr m_wide_bar_setting = nullptr; }; - diff --git a/launcher/ui/pages/instance/ShaderPackPage.h b/launcher/ui/pages/instance/ShaderPackPage.h index a779fd8cc..7c43a3756 100644 --- a/launcher/ui/pages/instance/ShaderPackPage.h +++ b/launcher/ui/pages/instance/ShaderPackPage.h @@ -39,11 +39,10 @@ #include "ExternalResourcesPage.h" -class ShaderPackPage : public ExternalResourcesPage -{ +class ShaderPackPage : public ExternalResourcesPage { Q_OBJECT -public: - explicit ShaderPackPage(MinecraftInstance *instance, std::shared_ptr model, QWidget *parent = nullptr); + public: + explicit ShaderPackPage(MinecraftInstance* instance, std::shared_ptr model, QWidget* parent = nullptr); ~ShaderPackPage() override = default; QString displayName() const override { return tr("Shader packs"); } diff --git a/launcher/ui/pages/instance/TexturePackPage.h b/launcher/ui/pages/instance/TexturePackPage.h index 47a8fa60d..9c4f24b70 100644 --- a/launcher/ui/pages/instance/TexturePackPage.h +++ b/launcher/ui/pages/instance/TexturePackPage.h @@ -42,21 +42,17 @@ #include "minecraft/mod/TexturePackFolderModel.h" -class TexturePackPage : public ExternalResourcesPage -{ +class TexturePackPage : public ExternalResourcesPage { Q_OBJECT -public: - explicit TexturePackPage(MinecraftInstance *instance, std::shared_ptr model, QWidget* parent = nullptr); + public: + explicit TexturePackPage(MinecraftInstance* instance, std::shared_ptr model, QWidget* parent = nullptr); QString displayName() const override { return tr("Texture packs"); } QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); } QString id() const override { return "texturepacks"; } QString helpPage() const override { return "Texture-packs"; } - virtual bool shouldDisplay() const override - { - return m_instance->traits().contains("texturepacks"); - } + virtual bool shouldDisplay() const override { return m_instance->traits().contains("texturepacks"); } public slots: bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override; diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index b2200b1a7..fe4776163 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -36,45 +36,42 @@ */ #include "WorldListPage.h" +#include "minecraft/WorldList.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui_WorldListPage.h" -#include "minecraft/WorldList.h" -#include -#include -#include #include +#include +#include +#include +#include #include #include #include -#include #include -#include "tools/MCEditTool.h" #include "FileSystem.h" +#include "tools/MCEditTool.h" -#include "ui/GuiUtil.h" #include "DesktopServices.h" +#include "ui/GuiUtil.h" #include "Application.h" - -class WorldListProxyModel : public QSortFilterProxyModel -{ +class WorldListProxyModel : public QSortFilterProxyModel { Q_OBJECT -public: - WorldListProxyModel(QObject *parent) : QSortFilterProxyModel(parent) {} + public: + WorldListProxyModel(QObject* parent) : QSortFilterProxyModel(parent) {} - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const { QModelIndex sourceIndex = mapToSource(index); - if (index.column() == 0 && role == Qt::DecorationRole) - { - WorldList *worlds = qobject_cast(sourceModel()); + if (index.column() == 0 && role == Qt::DecorationRole) { + WorldList* worlds = qobject_cast(sourceModel()); auto iconFile = worlds->data(sourceIndex, WorldList::IconFileRole).toString(); - if(iconFile.isNull()) { + if (iconFile.isNull()) { // NOTE: Minecraft uses the same placeholder for servers AND worlds return APPLICATION->getThemedIcon("unknown_server"); } @@ -85,15 +82,14 @@ public: } }; - -WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr worlds, QWidget *parent) +WorldListPage::WorldListPage(BaseInstance* inst, std::shared_ptr worlds, QWidget* parent) : QMainWindow(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds) { ui->setupUi(this); ui->toolBar->insertSpacer(ui->actionRefresh); - WorldListProxyModel * proxy = new WorldListProxyModel(this); + WorldListProxyModel* proxy = new WorldListProxyModel(this); proxy->setSortCaseSensitivity(Qt::CaseInsensitive); proxy->setSourceModel(m_worlds.get()); proxy->setSortRole(Qt::UserRole); @@ -101,7 +97,7 @@ WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr worl ui->worldTreeView->setModel(proxy); ui->worldTreeView->installEventFilter(this); ui->worldTreeView->setContextMenuPolicy(Qt::CustomContextMenu); - ui->worldTreeView->setIconSize(QSize(64,64)); + ui->worldTreeView->setIconSize(QSize(64, 64)); connect(ui->worldTreeView, &QTreeView::customContextMenuRequested, this, &WorldListPage::ShowContextMenu); auto head = ui->worldTreeView->header(); @@ -146,10 +142,10 @@ void WorldListPage::ShowContextMenu(const QPoint& pos) delete menu; } -QMenu * WorldListPage::createPopupMenu() +QMenu* WorldListPage::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); - filteredMenu->removeAction( ui->toolBar->toggleViewAction() ); + filteredMenu->removeAction(ui->toolBar->toggleViewAction()); return filteredMenu; } @@ -163,26 +159,24 @@ void WorldListPage::retranslate() ui->retranslateUi(this); } -bool WorldListPage::worldListFilter(QKeyEvent *keyEvent) +bool WorldListPage::worldListFilter(QKeyEvent* keyEvent) { - switch (keyEvent->key()) - { - case Qt::Key_Delete: - on_actionRemove_triggered(); - return true; - default: - break; + switch (keyEvent->key()) { + case Qt::Key_Delete: + on_actionRemove_triggered(); + return true; + default: + break; } return QWidget::eventFilter(ui->worldTreeView, keyEvent); } -bool WorldListPage::eventFilter(QObject *obj, QEvent *ev) +bool WorldListPage::eventFilter(QObject* obj, QEvent* ev) { - if (ev->type() != QEvent::KeyPress) - { + if (ev->type() != QEvent::KeyPress) { return QWidget::eventFilter(obj, ev); } - QKeyEvent *keyEvent = static_cast(ev); + QKeyEvent* keyEvent = static_cast(ev); if (obj == ui->worldTreeView) return worldListFilter(keyEvent); return QWidget::eventFilter(obj, ev); @@ -192,7 +186,7 @@ void WorldListPage::on_actionRemove_triggered() { auto proxiedIndex = getSelectedWorld(); - if(!proxiedIndex.isValid()) + if (!proxiedIndex.isValid()) return; auto result = CustomMessageBox::selectable(this, tr("Confirm Deletion"), @@ -203,8 +197,7 @@ void WorldListPage::on_actionRemove_triggered() QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ->exec(); - if(result != QMessageBox::Yes) - { + if (result != QMessageBox::Yes) { return; } m_worlds->stopWatching(); @@ -221,12 +214,11 @@ void WorldListPage::on_actionDatapacks_triggered() { QModelIndex index = getSelectedWorld(); - if (!index.isValid()) - { + if (!index.isValid()) { return; } - if(!worldSafetyNagQuestion(tr("Open World Datapacks Folder"))) + if (!worldSafetyNagQuestion(tr("Open World Datapacks Folder"))) return; auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString(); @@ -234,25 +226,23 @@ void WorldListPage::on_actionDatapacks_triggered() DesktopServices::openDirectory(FS::PathCombine(fullPath, "datapacks"), true); } - void WorldListPage::on_actionReset_Icon_triggered() { auto proxiedIndex = getSelectedWorld(); - if(!proxiedIndex.isValid()) + if (!proxiedIndex.isValid()) return; - if(m_worlds->resetIcon(proxiedIndex.row())) { + if (m_worlds->resetIcon(proxiedIndex.row())) { ui->actionReset_Icon->setEnabled(false); } } - QModelIndex WorldListPage::getSelectedWorld() { auto index = ui->worldTreeView->selectionModel()->currentIndex(); - auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model(); + auto proxy = (QSortFilterProxyModel*)ui->worldTreeView->model(); return proxy->mapToSource(index); } @@ -260,8 +250,7 @@ void WorldListPage::on_actionCopy_Seed_triggered() { QModelIndex index = getSelectedWorld(); - if (!index.isValid()) - { + if (!index.isValid()) { return; } int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong(); @@ -270,7 +259,7 @@ void WorldListPage::on_actionCopy_Seed_triggered() void WorldListPage::on_actionMCEdit_triggered() { - if(m_mceditStarting) + if (m_mceditStarting) return; auto mcedit = APPLICATION->mcedit(); @@ -279,81 +268,66 @@ void WorldListPage::on_actionMCEdit_triggered() QModelIndex index = getSelectedWorld(); - if (!index.isValid()) - { + if (!index.isValid()) { return; } - if(!worldSafetyNagQuestion(tr("Open World in MCEdit"))) + if (!worldSafetyNagQuestion(tr("Open World in MCEdit"))) return; auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString(); auto program = mcedit->getProgramPath(); - if(program.size()) - { + if (program.size()) { #ifdef Q_OS_WIN32 - if(!QProcess::startDetached(program, {fullPath}, mceditPath)) - { + if (!QProcess::startDetached(program, { fullPath }, mceditPath)) { mceditError(); } #else m_mceditProcess.reset(new LoggedProcess()); m_mceditProcess->setDetachable(true); connect(m_mceditProcess.get(), &LoggedProcess::stateChanged, this, &WorldListPage::mceditState); - m_mceditProcess->start(program, {fullPath}); + m_mceditProcess->start(program, { fullPath }); m_mceditProcess->setWorkingDirectory(mceditPath); m_mceditStarting = true; #endif - } - else - { - QMessageBox::warning( - this->parentWidget(), - tr("No MCEdit found or set up!"), - tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.") - ); + } else { + QMessageBox::warning(this->parentWidget(), tr("No MCEdit found or set up!"), + tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.")); } } void WorldListPage::mceditError() { - QMessageBox::warning( - this->parentWidget(), - tr("MCEdit failed to start!"), - tr("MCEdit failed to start.\nIt may be necessary to reinstall it.") - ); + QMessageBox::warning(this->parentWidget(), tr("MCEdit failed to start!"), + tr("MCEdit failed to start.\nIt may be necessary to reinstall it.")); } void WorldListPage::mceditState(LoggedProcess::State state) { bool failed = false; - switch(state) - { + switch (state) { case LoggedProcess::NotRunning: case LoggedProcess::Starting: return; case LoggedProcess::FailedToStart: case LoggedProcess::Crashed: - case LoggedProcess::Aborted: - { + case LoggedProcess::Aborted: { failed = true; } /* fallthrough */ case LoggedProcess::Running: - case LoggedProcess::Finished: - { + case LoggedProcess::Finished: { m_mceditStarting = false; break; } } - if(failed) - { + if (failed) { mceditError(); } } -void WorldListPage::worldChanged(const QModelIndex ¤t, const QModelIndex &previous) +void WorldListPage::worldChanged(const QModelIndex& current, const QModelIndex& previous) { QModelIndex index = getSelectedWorld(); bool enable = index.isValid(); @@ -369,15 +343,11 @@ void WorldListPage::worldChanged(const QModelIndex ¤t, const QModelIndex & void WorldListPage::on_actionAdd_triggered() { - auto list = GuiUtil::BrowseForFiles( - displayName(), - tr("Select a Minecraft world zip"), - tr("Minecraft World Zip File (*.zip)"), QString(), this->parentWidget()); - if (!list.empty()) - { + 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(); - for (auto filename : list) - { + for (auto filename : list) { m_worlds->installWorld(QFileInfo(filename)); } m_worlds->startWatching(); @@ -389,38 +359,35 @@ bool WorldListPage::isWorldSafe(QModelIndex) return !m_inst->isRunning(); } -bool WorldListPage::worldSafetyNagQuestion(const QString &actionType) +bool WorldListPage::worldSafetyNagQuestion(const QString& actionType) { - if(!isWorldSafe(getSelectedWorld())) - { - auto result = QMessageBox::question(this, actionType, tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?")); - if(result == QMessageBox::No) - { + if (!isWorldSafe(getSelectedWorld())) { + auto result = QMessageBox::question( + this, actionType, tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?")); + if (result == QMessageBox::No) { return false; } } return true; } - void WorldListPage::on_actionCopy_triggered() { QModelIndex index = getSelectedWorld(); - if (!index.isValid()) - { + if (!index.isValid()) { return; } - if(!worldSafetyNagQuestion(tr("Copy World"))) + if (!worldSafetyNagQuestion(tr("Copy World"))) return; auto worldVariant = m_worlds->data(index, WorldList::ObjectRole); - auto world = (World *) worldVariant.value(); + auto world = (World*)worldVariant.value(); bool ok = false; - QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok); + QString name = + QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok); - if (ok && name.length() > 0) - { + if (ok && name.length() > 0) { world->install(m_worlds->dir().absolutePath(), name); } } @@ -428,22 +395,20 @@ void WorldListPage::on_actionCopy_triggered() void WorldListPage::on_actionRename_triggered() { QModelIndex index = getSelectedWorld(); - if (!index.isValid()) - { + if (!index.isValid()) { return; } - if(!worldSafetyNagQuestion(tr("Rename World"))) + if (!worldSafetyNagQuestion(tr("Rename World"))) return; auto worldVariant = m_worlds->data(index, WorldList::ObjectRole); - auto world = (World *) worldVariant.value(); + auto world = (World*)worldVariant.value(); bool ok = false; QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new world name."), QLineEdit::Normal, world->name(), &ok); - if (ok && name.length() > 0) - { + if (ok && name.length() > 0) { world->rename(name); } } diff --git a/launcher/ui/pages/instance/WorldListPage.h b/launcher/ui/pages/instance/WorldListPage.h index 925521bec..df8b512ff 100644 --- a/launcher/ui/pages/instance/WorldListPage.h +++ b/launcher/ui/pages/instance/WorldListPage.h @@ -37,76 +37,58 @@ #include -#include "minecraft/MinecraftInstance.h" -#include "ui/pages/BasePage.h" #include #include +#include "minecraft/MinecraftInstance.h" +#include "ui/pages/BasePage.h" #include "settings/Setting.h" class WorldList; -namespace Ui -{ +namespace Ui { class WorldListPage; } -class WorldListPage : public QMainWindow, public BasePage -{ +class WorldListPage : public QMainWindow, public BasePage { Q_OBJECT -public: - explicit WorldListPage( - BaseInstance *inst, - std::shared_ptr worlds, - QWidget *parent = 0 - ); + public: + explicit WorldListPage(BaseInstance* inst, std::shared_ptr worlds, QWidget* parent = 0); virtual ~WorldListPage(); - virtual QString displayName() const override - { - return tr("Worlds"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("worlds"); - } - virtual QString id() const override - { - return "worlds"; - } - virtual QString helpPage() const override - { - return "Worlds"; - } + virtual QString displayName() const override { return tr("Worlds"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("worlds"); } + virtual QString id() const override { return "worlds"; } + virtual QString helpPage() const override { return "Worlds"; } virtual bool shouldDisplay() const override; void retranslate() override; virtual void openedImpl() override; virtual void closedImpl() override; -protected: - bool eventFilter(QObject *obj, QEvent *ev) override; - bool worldListFilter(QKeyEvent *ev); - QMenu * createPopupMenu() override; + protected: + bool eventFilter(QObject* obj, QEvent* ev) override; + bool worldListFilter(QKeyEvent* ev); + QMenu* createPopupMenu() override; -protected: - BaseInstance *m_inst; + protected: + BaseInstance* m_inst; -private: + private: QModelIndex getSelectedWorld(); bool isWorldSafe(QModelIndex index); - bool worldSafetyNagQuestion(const QString &actionType); + bool worldSafetyNagQuestion(const QString& actionType); void mceditError(); -private: - Ui::WorldListPage *ui; + private: + Ui::WorldListPage* ui; std::shared_ptr m_worlds; unique_qobject_ptr m_mceditProcess; bool m_mceditStarting = false; std::shared_ptr m_wide_bar_setting = nullptr; -private slots: + private slots: void on_actionCopy_Seed_triggered(); void on_actionMCEdit_triggered(); void on_actionRemove_triggered(); @@ -117,8 +99,8 @@ private slots: void on_actionView_Folder_triggered(); void on_actionDatapacks_triggered(); void on_actionReset_Icon_triggered(); - void worldChanged(const QModelIndex ¤t, const QModelIndex &previous); + void worldChanged(const QModelIndex& current, const QModelIndex& previous); void mceditState(LoggedProcess::State state); - void ShowContextMenu(const QPoint &pos); + void ShowContextMenu(const QPoint& pos); }; diff --git a/launcher/ui/pages/modplatform/CustomPage.cpp b/launcher/ui/pages/modplatform/CustomPage.cpp index e164171a4..ae5cae30f 100644 --- a/launcher/ui/pages/modplatform/CustomPage.cpp +++ b/launcher/ui/pages/modplatform/CustomPage.cpp @@ -46,8 +46,7 @@ #include "minecraft/VanillaInstanceCreationTask.h" #include "ui/dialogs/NewInstanceDialog.h" -CustomPage::CustomPage(NewInstanceDialog *dialog, QWidget *parent) - : QWidget(parent), dialog(dialog), ui(new Ui::CustomPage) +CustomPage::CustomPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), dialog(dialog), ui(new Ui::CustomPage) { ui->setupUi(this); ui->tabWidget->tabBar()->hide(); @@ -68,19 +67,15 @@ CustomPage::CustomPage(NewInstanceDialog *dialog, QWidget *parent) connect(ui->quiltFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &CustomPage::loaderRefresh); - } void CustomPage::openedImpl() { - if(!initialized) - { + if (!initialized) { auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); ui->versionList->initialize(vlist.get()); initialized = true; - } - else - { + } else { suggestCurrent(); } } @@ -92,7 +87,7 @@ void CustomPage::refresh() void CustomPage::loaderRefresh() { - if(ui->noneFilter->isChecked()) + if (ui->noneFilter->isChecked()) return; ui->loaderVersionList->loadList(); } @@ -100,17 +95,17 @@ void CustomPage::loaderRefresh() void CustomPage::filterChanged() { QStringList out; - if(ui->alphaFilter->isChecked()) + if (ui->alphaFilter->isChecked()) out << "(old_alpha)"; - if(ui->betaFilter->isChecked()) + if (ui->betaFilter->isChecked()) out << "(old_beta)"; - if(ui->snapshotFilter->isChecked()) + if (ui->snapshotFilter->isChecked()) out << "(snapshot)"; - if(ui->oldSnapshotFilter->isChecked()) + if (ui->oldSnapshotFilter->isChecked()) out << "(old_snapshot)"; - if(ui->releaseFilter->isChecked()) + if (ui->releaseFilter->isChecked()) out << "(release)"; - if(ui->experimentsFilter->isChecked()) + if (ui->experimentsFilter->isChecked()) out << "(experiment)"; auto regexp = out.join('|'); ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); @@ -119,49 +114,37 @@ void CustomPage::filterChanged() void CustomPage::loaderFilterChanged() { QString minecraftVersion; - if (m_selectedVersion) - { + if (m_selectedVersion) { minecraftVersion = m_selectedVersion->descriptor(); - } - else - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list + } else { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list ui->loaderVersionList->setEmptyString(tr("No Minecraft version is selected.")); ui->loaderVersionList->setEmptyMode(VersionListView::String); return; } - if(ui->noneFilter->isChecked()) - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list + if (ui->noneFilter->isChecked()) { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list ui->loaderVersionList->setEmptyString(tr("No mod loader is selected.")); ui->loaderVersionList->setEmptyMode(VersionListView::String); return; - } - else if(ui->forgeFilter->isChecked()) - { + } else if (ui->forgeFilter->isChecked()) { ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); m_selectedLoader = "net.minecraftforge"; - } - else if(ui->fabricFilter->isChecked()) - { + } else if (ui->fabricFilter->isChecked()) { // FIXME: dirty hack because the launcher is unaware of Fabric's dependencies - if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported + if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, ""); - else // Fabric/Quilt unsupported - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list + else // Fabric/Quilt unsupported + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list m_selectedLoader = "net.fabricmc.fabric-loader"; - } - else if(ui->quiltFilter->isChecked()) - { + } else if (ui->quiltFilter->isChecked()) { // FIXME: dirty hack because the launcher is unaware of Quilt's dependencies (same as Fabric) - if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported + if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, ""); - else // Fabric/Quilt unsupported - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list + else // Fabric/Quilt unsupported + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list m_selectedLoader = "org.quiltmc.quilt-loader"; - } - else if(ui->liteLoaderFilter->isChecked()) - { + } else if (ui->liteLoaderFilter->isChecked()) { ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); m_selectedLoader = "com.mumfrey.liteloader"; } @@ -204,25 +187,21 @@ QString CustomPage::selectedLoader() const void CustomPage::suggestCurrent() { - if (!isOpened) - { + if (!isOpened) { return; } - - if(!m_selectedVersion) - { + + if (!m_selectedVersion) { dialog->setSuggestedPack(); return; } // There isn't a selected version if the version list is empty - if(ui->loaderVersionList->selectedVersion() == nullptr) + if (ui->loaderVersionList->selectedVersion() == nullptr) dialog->setSuggestedPack(m_selectedVersion->descriptor(), new VanillaCreationTask(m_selectedVersion)); - else - { + else { dialog->setSuggestedPack(m_selectedVersion->descriptor(), - new VanillaCreationTask(m_selectedVersion, m_selectedLoader, - m_selectedLoaderVersion)); + new VanillaCreationTask(m_selectedVersion, m_selectedLoader, m_selectedLoaderVersion)); } dialog->setSuggestedIcon("default"); } diff --git a/launcher/ui/pages/modplatform/CustomPage.h b/launcher/ui/pages/modplatform/CustomPage.h index 8b5a5011c..273a60790 100644 --- a/launcher/ui/pages/modplatform/CustomPage.h +++ b/launcher/ui/pages/modplatform/CustomPage.h @@ -37,40 +37,26 @@ #include -#include "ui/pages/BasePage.h" #include #include "tasks/Task.h" +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class CustomPage; } class NewInstanceDialog; -class CustomPage : public QWidget, public BasePage -{ +class CustomPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit CustomPage(NewInstanceDialog *dialog, QWidget *parent = 0); + public: + explicit CustomPage(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~CustomPage(); - virtual QString displayName() const override - { - return tr("Custom"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("minecraft"); - } - virtual QString id() const override - { - return "vanilla"; - } - virtual QString helpPage() const override - { - return "Vanilla-platform"; - } + virtual QString displayName() const override { return tr("Custom"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("minecraft"); } + virtual QString id() const override { return "vanilla"; } + virtual QString helpPage() const override { return "Vanilla-platform"; } virtual bool shouldDisplay() const override; void retranslate() override; @@ -80,23 +66,23 @@ public: BaseVersion::Ptr selectedLoaderVersion() const; QString selectedLoader() const; -public slots: + public slots: void setSelectedVersion(BaseVersion::Ptr version); void setSelectedLoaderVersion(BaseVersion::Ptr version); -private slots: + private slots: void filterChanged(); void loaderFilterChanged(); -private: + private: void refresh(); void loaderRefresh(); void suggestCurrent(); -private: + private: bool initialized = false; - NewInstanceDialog *dialog = nullptr; - Ui::CustomPage *ui = nullptr; + NewInstanceDialog* dialog = nullptr; + Ui::CustomPage* ui = nullptr; bool m_versionSetByUser = false; BaseVersion::Ptr m_selectedVersion; BaseVersion::Ptr m_selectedLoaderVersion; diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 30196aad6..b7f4d1baf 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -44,32 +44,24 @@ #include "InstanceImportTask.h" - -class UrlValidator : public QValidator -{ -public: +class UrlValidator : public QValidator { + public: using QValidator::QValidator; - State validate(QString &in, int &pos) const + State validate(QString& in, int& pos) const { const QUrl url(in); - if (url.isValid() && !url.isRelative() && !url.isEmpty()) - { + if (url.isValid() && !url.isRelative() && !url.isEmpty()) { return Acceptable; - } - else if (QFile::exists(in)) - { + } else if (QFile::exists(in)) { return Acceptable; - } - else - { + } else { return Intermediate; } } }; -ImportPage::ImportPage(NewInstanceDialog* dialog, QWidget *parent) - : QWidget(parent), ui(new Ui::ImportPage), dialog(dialog) +ImportPage::ImportPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::ImportPage), dialog(dialog) { ui->setupUi(this); ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit)); @@ -98,16 +90,13 @@ void ImportPage::openedImpl() void ImportPage::updateState() { - if(!isOpened) - { + if (!isOpened) { return; } - if(ui->modpackEdit->hasAcceptableInput()) - { + if (ui->modpackEdit->hasAcceptableInput()) { QString input = ui->modpackEdit->text(); auto url = QUrl::fromUserInput(input); - if(url.isLocalFile()) - { + if (url.isLocalFile()) { // FIXME: actually do some validation of what's inside here... this is fake AF QFileInfo fi(input); @@ -116,28 +105,23 @@ void ImportPage::updateState() // mrpack is a modrinth pack bool isMRPack = fi.suffix() == "mrpack"; - if(fi.exists() && (isZip || isMRPack)) - { + if (fi.exists() && (isZip || isMRPack)) { QFileInfo fi(url.fileName()); - dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url,this)); + dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this)); dialog->setSuggestedIcon("default"); } - } - else - { - if(input.endsWith("?client=y")) { + } else { + if (input.endsWith("?client=y")) { input.chop(9); input.append("/file"); url = QUrl::fromUserInput(input); } // hook, line and sinker. QFileInfo fi(url.fileName()); - dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url,this)); + dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this)); dialog->setSuggestedIcon("default"); } - } - else - { + } else { dialog->setSuggestedPack(); } } @@ -154,29 +138,21 @@ void ImportPage::on_modpackBtn_clicked() //: Option for filtering for *.mrpack files when importing filter += ";;" + tr("Modrinth pack") + " (*.mrpack)"; const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter); - if (url.isValid()) - { - if (url.isLocalFile()) - { + if (url.isValid()) { + if (url.isLocalFile()) { ui->modpackEdit->setText(url.toLocalFile()); - } - else - { + } else { ui->modpackEdit->setText(url.toString()); } } } - QUrl ImportPage::modpackUrl() const { const QUrl url(ui->modpackEdit->text()); - if (url.isValid() && !url.isRelative() && !url.host().isEmpty()) - { + if (url.isValid() && !url.isRelative() && !url.host().isEmpty()) { return url; - } - else - { + } else { return QUrl::fromLocalFile(ui->modpackEdit->text()); } } diff --git a/launcher/ui/pages/modplatform/ImportPage.h b/launcher/ui/pages/modplatform/ImportPage.h index c2acb92da..66c452b9f 100644 --- a/launcher/ui/pages/modplatform/ImportPage.h +++ b/launcher/ui/pages/modplatform/ImportPage.h @@ -37,55 +37,40 @@ #include -#include "ui/pages/BasePage.h" #include #include "tasks/Task.h" +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class ImportPage; } class NewInstanceDialog; -class ImportPage : public QWidget, public BasePage -{ +class ImportPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit ImportPage(NewInstanceDialog* dialog, QWidget *parent = 0); + public: + explicit ImportPage(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~ImportPage(); - virtual QString displayName() const override - { - return tr("Import"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("viewfolder"); - } - virtual QString id() const override - { - return "import"; - } - virtual QString helpPage() const override - { - return "Zip-import"; - } + virtual QString displayName() const override { return tr("Import"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("viewfolder"); } + virtual QString id() const override { return "import"; } + virtual QString helpPage() const override { return "Zip-import"; } virtual bool shouldDisplay() const override; void retranslate() override; - void setUrl(const QString & url); + void setUrl(const QString& url); void openedImpl() override; -private slots: + private slots: void on_modpackBtn_clicked(); void updateState(); -private: + private: QUrl modpackUrl() const; -private: - Ui::ImportPage *ui = nullptr; + private: + Ui::ImportPage* ui = nullptr; NewInstanceDialog* dialog = nullptr; }; - diff --git a/launcher/ui/pages/modplatform/ResourcePackPage.cpp b/launcher/ui/pages/modplatform/ResourcePackPage.cpp index 52fb4802c..2a4d02815 100644 --- a/launcher/ui/pages/modplatform/ResourcePackPage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePackPage.cpp @@ -13,8 +13,7 @@ namespace ResourceDownload { -ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance) - : ResourcePage(dialog, instance) +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); @@ -38,7 +37,8 @@ QMap ResourcePackResourcePage::urlHandlers() const { QMap map; map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth"); - map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"), "curseforge"); + map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"), + "curseforge"); map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge"); return map; } diff --git a/launcher/ui/pages/modplatform/ResourcePackPage.h b/launcher/ui/pages/modplatform/ResourcePackPage.h index 8c5cf08b7..6015aec0b 100644 --- a/launcher/ui/pages/modplatform/ResourcePackPage.h +++ b/launcher/ui/pages/modplatform/ResourcePackPage.h @@ -4,8 +4,8 @@ #pragma once -#include "ui/pages/modplatform/ResourcePage.h" #include "ui/pages/modplatform/ResourcePackModel.h" +#include "ui/pages/modplatform/ResourcePage.h" namespace Ui { class ResourcePage; diff --git a/launcher/ui/pages/modplatform/TexturePackPage.h b/launcher/ui/pages/modplatform/TexturePackPage.h index 0bdce2f90..948e5286b 100644 --- a/launcher/ui/pages/modplatform/TexturePackPage.h +++ b/launcher/ui/pages/modplatform/TexturePackPage.h @@ -4,10 +4,10 @@ #pragma once -#include "ui_ResourcePage.h" #include "ui/dialogs/ResourceDownloadDialog.h" #include "ui/pages/modplatform/ResourcePackPage.h" #include "ui/pages/modplatform/TexturePackModel.h" +#include "ui_ResourcePage.h" namespace Ui { class ResourcePage; @@ -39,8 +39,7 @@ class TexturePackResourcePage : public ResourcePackResourcePage { [[nodiscard]] inline QString resourceString() const override { return tr("texture pack"); } protected: - TexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance) - : ResourcePackResourcePage(dialog, instance) + 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/pages/modplatform/atlauncher/AtlFilterModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp index 0887ebeef..9cd5eed53 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp @@ -18,14 +18,14 @@ #include -#include #include +#include #include "StringUtils.h" namespace Atl { -FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent) +FilterModel::FilterModel(QObject* parent) : QSortFilterProxyModel(parent) { currentSorting = Sorting::ByPopularity; sortings.insert(tr("Sort by Popularity"), Sorting::ByPopularity); @@ -62,7 +62,7 @@ void FilterModel::setSearchTerm(const QString term) invalidate(); } -bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { if (searchTerm.isEmpty()) { return true; @@ -73,20 +73,18 @@ bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParen return pack.name.contains(searchTerm, Qt::CaseInsensitive); } -bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { ATLauncher::IndexedPack leftPack = sourceModel()->data(left, Qt::UserRole).value(); ATLauncher::IndexedPack rightPack = sourceModel()->data(right, Qt::UserRole).value(); if (currentSorting == ByPopularity) { return leftPack.position > rightPack.position; - } - else if (currentSorting == ByGameVersion) { + } else if (currentSorting == ByGameVersion) { Version lv(leftPack.versions.at(0).minecraft); Version rv(rightPack.versions.at(0).minecraft); return lv < rv; - } - else if (currentSorting == ByName) { + } else if (currentSorting == ByName) { return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; } @@ -95,4 +93,4 @@ bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) co return true; } -} +} // namespace Atl diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h index 5235ccdbf..0ab46ed2d 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h @@ -20,10 +20,9 @@ namespace Atl { -class FilterModel : public QSortFilterProxyModel -{ +class FilterModel : public QSortFilterProxyModel { Q_OBJECT -public: + public: FilterModel(QObject* parent = Q_NULLPTR); enum Sorting { ByPopularity, @@ -36,15 +35,14 @@ public: Sorting getCurrentSorting(); void setSearchTerm(QString term); -protected: - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; -private: + private: QMap sortings; Sorting currentSorting; QString searchTerm; - }; -} +} // namespace Atl diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index 7b61daa71..9b0206f98 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -38,15 +38,13 @@ #include #include +#include "Application.h" #include "BuildConfig.h" #include "Json.h" #include "modplatform/atlauncher/ATLShareCode.h" -#include "Application.h" AtlOptionalModListModel::AtlOptionalModListModel(QWidget* parent, ATLauncher::PackVersion version, QVector mods) - : QAbstractListModel(parent) - , m_version(version) - , m_mods(mods) + : QAbstractListModel(parent), m_version(version), m_mods(mods) { // fill mod index for (int i = 0; i < m_mods.size(); i++) { @@ -62,7 +60,8 @@ AtlOptionalModListModel::AtlOptionalModListModel(QWidget* parent, ATLauncher::Pa } } -QVector AtlOptionalModListModel::getResult() { +QVector AtlOptionalModListModel::getResult() +{ QVector result; for (const auto& mod : m_mods) { @@ -74,16 +73,19 @@ QVector AtlOptionalModListModel::getResult() { return result; } -int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const { +int AtlOptionalModListModel::rowCount(const QModelIndex& parent) const +{ return parent.isValid() ? 0 : m_mods.size(); } -int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const { +int AtlOptionalModListModel::columnCount(const QModelIndex& parent) const +{ // Enabled, Name, Description return parent.isValid() ? 0 : 3; } -QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const { +QVariant AtlOptionalModListModel::data(const QModelIndex& index, int role) const +{ auto row = index.row(); auto mod = m_mods.at(row); @@ -94,18 +96,15 @@ QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const if (index.column() == DescriptionColumn) { return mod.description; } - } - else if (role == Qt::ToolTipRole) { + } else if (role == Qt::ToolTipRole) { if (index.column() == DescriptionColumn) { return mod.description; } - } - else if (role == Qt::ForegroundRole) { + } else if (role == Qt::ForegroundRole) { if (!mod.colour.isEmpty() && m_version.colours.contains(mod.colour)) { return QColor(QString("#%1").arg(m_version.colours[mod.colour])); } - } - else if (role == Qt::CheckStateRole) { + } else if (role == Qt::CheckStateRole) { if (index.column() == EnabledColumn) { return m_selection[mod.name] ? Qt::Checked : Qt::Unchecked; } @@ -114,7 +113,8 @@ QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const return {}; } -bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant &value, int role) { +bool AtlOptionalModListModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ if (role == Qt::CheckStateRole) { auto row = index.row(); auto mod = m_mods.at(row); @@ -126,7 +126,8 @@ bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant & return false; } -QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orientation, int role) const { +QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case EnabledColumn: @@ -141,7 +142,8 @@ QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orient return {}; } -Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const { +Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex& index) const +{ auto flags = QAbstractListModel::flags(index); if (index.isValid() && index.column() == EnabledColumn) { flags |= Qt::ItemIsUserCheckable; @@ -149,23 +151,23 @@ Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const { return flags; } -void AtlOptionalModListModel::useShareCode(const QString& code) { +void AtlOptionalModListModel::useShareCode(const QString& code) +{ m_jobPtr.reset(new NetJob("Atl::Request", APPLICATION->network())); auto url = QString(BuildConfig.ATL_API_BASE_URL + "share-codes/" + code); m_jobPtr->addNetAction(Net::Download::makeByteArray(QUrl(url), m_response)); - connect(m_jobPtr.get(), &NetJob::succeeded, - this, &AtlOptionalModListModel::shareCodeSuccess); - connect(m_jobPtr.get(), &NetJob::failed, - this, &AtlOptionalModListModel::shareCodeFailure); + connect(m_jobPtr.get(), &NetJob::succeeded, this, &AtlOptionalModListModel::shareCodeSuccess); + connect(m_jobPtr.get(), &NetJob::failed, this, &AtlOptionalModListModel::shareCodeFailure); m_jobPtr->start(); } -void AtlOptionalModListModel::shareCodeSuccess() { +void AtlOptionalModListModel::shareCodeSuccess() +{ m_jobPtr.reset(); - QJsonParseError parse_error {}; + QJsonParseError parse_error{}; auto doc = QJsonDocument::fromJson(*m_response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from ATL at " << parse_error.offset << " reason: " << parse_error.errorString(); @@ -177,8 +179,7 @@ void AtlOptionalModListModel::shareCodeSuccess() { ATLauncher::ShareCodeResponse response; try { ATLauncher::loadShareCodeResponse(response, obj); - } - catch (const JSONValidationError& e) { + } catch (const JSONValidationError& e) { qDebug() << QString::fromUtf8(*m_response); qWarning() << "Error while reading response from ATLauncher: " << e.cause(); return; @@ -202,44 +203,44 @@ void AtlOptionalModListModel::shareCodeSuccess() { m_selection[mod.name] = mod.selected; } - emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), - AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); + emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); } -void AtlOptionalModListModel::shareCodeFailure(const QString& reason) { +void AtlOptionalModListModel::shareCodeFailure(const QString& reason) +{ m_jobPtr.reset(); // fixme: plumb in an error message } -void AtlOptionalModListModel::selectRecommended() { +void AtlOptionalModListModel::selectRecommended() +{ for (const auto& mod : m_mods) { m_selection[mod.name] = mod.recommended; } - emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), - AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); + emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); } -void AtlOptionalModListModel::clearAll() { +void AtlOptionalModListModel::clearAll() +{ for (const auto& mod : m_mods) { m_selection[mod.name] = false; } - emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), - AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); + emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); } -void AtlOptionalModListModel::toggleMod(ATLauncher::VersionMod mod, int index) { +void AtlOptionalModListModel::toggleMod(ATLauncher::VersionMod mod, int index) +{ auto enable = !m_selection[mod.name]; // If there is a warning for the mod, display that first (if we would be enabling the mod) if (enable && !mod.warning.isEmpty() && m_version.warnings.contains(mod.warning)) { - auto message = QString("%1

    %2") - .arg(m_version.warnings[mod.warning], tr("Are you sure that you want to enable this mod?")); + auto message = QString("%1

    %2").arg(m_version.warnings[mod.warning], tr("Are you sure that you want to enable this mod?")); // fixme: avoid casting here - auto result = QMessageBox::warning((QWidget*) this->parent(), tr("Warning"), message, QMessageBox::Yes | QMessageBox::No); + auto result = QMessageBox::warning((QWidget*)this->parent(), tr("Warning"), message, QMessageBox::Yes | QMessageBox::No); if (result != QMessageBox::Yes) { return; } @@ -248,15 +249,18 @@ void AtlOptionalModListModel::toggleMod(ATLauncher::VersionMod mod, int index) { setMod(mod, index, enable); } -void AtlOptionalModListModel::setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit) { - if (m_selection[mod.name] == enable) return; +void AtlOptionalModListModel::setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit) +{ + if (m_selection[mod.name] == enable) + return; m_selection[mod.name] = enable; // disable other mods in the group, if applicable if (enable && !mod.group.isEmpty()) { for (int i = 0; i < m_mods.size(); i++) { - if (index == i) continue; + if (index == i) + continue; auto other = m_mods.at(i); if (mod.group == other.group) { @@ -281,8 +285,7 @@ void AtlOptionalModListModel::setMod(ATLauncher::VersionMod mod, int index, bool if (enable) { dependants.append(mod.name); - } - else { + } else { dependants.removeAll(mod.name); // if there are no longer any dependents, let's disable the mod @@ -304,14 +307,12 @@ void AtlOptionalModListModel::setMod(ATLauncher::VersionMod mod, int index, bool } if (shouldEmit) { - emit dataChanged(AtlOptionalModListModel::index(index, EnabledColumn), - AtlOptionalModListModel::index(index, EnabledColumn)); + emit dataChanged(AtlOptionalModListModel::index(index, EnabledColumn), AtlOptionalModListModel::index(index, EnabledColumn)); } } AtlOptionalModDialog::AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVersion version, QVector mods) - : QDialog(parent) - , ui(new Ui::AtlOptionalModDialog) + : QDialog(parent), ui(new Ui::AtlOptionalModDialog) { ui->setupUi(this); @@ -319,35 +320,24 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVers ui->treeView->setModel(listModel); ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->treeView->header()->setSectionResizeMode( - AtlOptionalModListModel::NameColumn, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode( - AtlOptionalModListModel::DescriptionColumn, QHeaderView::Stretch); + ui->treeView->header()->setSectionResizeMode(AtlOptionalModListModel::NameColumn, QHeaderView::ResizeToContents); + ui->treeView->header()->setSectionResizeMode(AtlOptionalModListModel::DescriptionColumn, QHeaderView::Stretch); - connect(ui->shareCodeButton, &QPushButton::clicked, - this, &AtlOptionalModDialog::useShareCode); - connect(ui->selectRecommendedButton, &QPushButton::clicked, - listModel, &AtlOptionalModListModel::selectRecommended); - connect(ui->clearAllButton, &QPushButton::clicked, - listModel, &AtlOptionalModListModel::clearAll); - connect(ui->installButton, &QPushButton::clicked, - this, &QDialog::accept); + connect(ui->shareCodeButton, &QPushButton::clicked, this, &AtlOptionalModDialog::useShareCode); + connect(ui->selectRecommendedButton, &QPushButton::clicked, listModel, &AtlOptionalModListModel::selectRecommended); + connect(ui->clearAllButton, &QPushButton::clicked, listModel, &AtlOptionalModListModel::clearAll); + connect(ui->installButton, &QPushButton::clicked, this, &QDialog::accept); } -AtlOptionalModDialog::~AtlOptionalModDialog() { +AtlOptionalModDialog::~AtlOptionalModDialog() +{ delete ui; } -void AtlOptionalModDialog::useShareCode() { +void AtlOptionalModDialog::useShareCode() +{ bool ok; - auto shareCode = QInputDialog::getText( - this, - tr("Select a share code"), - tr("Share code:"), - QLineEdit::Normal, - "", - &ok - ); + auto shareCode = QInputDialog::getText(this, tr("Select a share code"), tr("Share code:"), QLineEdit::Normal, "", &ok); if (!ok) { // If the user cancels the dialog, we don't need to show any error dialogs. diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h index 639f0d489..a23b16539 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h @@ -35,8 +35,8 @@ #pragma once -#include #include +#include #include "modplatform/atlauncher/ATLPackIndex.h" #include "net/NetJob.h" @@ -48,37 +48,36 @@ class AtlOptionalModDialog; class AtlOptionalModListModel : public QAbstractListModel { Q_OBJECT -public: - enum Columns - { + public: + enum Columns { EnabledColumn = 0, NameColumn, DescriptionColumn, }; - AtlOptionalModListModel(QWidget *parent, ATLauncher::PackVersion version, QVector mods); + AtlOptionalModListModel(QWidget* parent, ATLauncher::PackVersion version, QVector mods); QVector getResult(); - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role) override; + QVariant data(const QModelIndex& index, int role) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; void useShareCode(const QString& code); -public slots: + public slots: void shareCodeSuccess(); void shareCodeFailure(const QString& reason); void selectRecommended(); void clearAll(); -private: + private: void toggleMod(ATLauncher::VersionMod mod, int index); void setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit = true); @@ -97,18 +96,16 @@ private: class AtlOptionalModDialog : public QDialog { Q_OBJECT -public: - AtlOptionalModDialog(QWidget *parent, ATLauncher::PackVersion version, QVector mods); + public: + AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVersion version, QVector mods); ~AtlOptionalModDialog() override; - QVector getResult() { - return listModel->getResult(); - } + QVector getResult() { return listModel->getResult(); } void useShareCode(); -private: - Ui::AtlOptionalModDialog *ui; + private: + Ui::AtlOptionalModDialog* ui; - AtlOptionalModListModel *listModel; + AtlOptionalModListModel* listModel; }; diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp index 875444451..6e1e16a2f 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp @@ -46,10 +46,7 @@ #include -AtlPage::AtlPage(NewInstanceDialog* dialog, QWidget* parent) - : QWidget(parent) - , ui(new Ui::AtlPage) - , dialog(dialog) +AtlPage::AtlPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::AtlPage), dialog(dialog) { ui->setupUi(this); @@ -65,8 +62,7 @@ AtlPage::AtlPage(NewInstanceDialog* dialog, QWidget* parent) ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300); - for(int i = 0; i < filterModel->getAvailableSortings().size(); i++) - { + for (int i = 0; i < filterModel->getAvailableSortings().size(); i++) { ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i)); } ui->sortByBox->setCurrentText(filterModel->translateCurrentSorting()); @@ -94,8 +90,7 @@ void AtlPage::retranslate() void AtlPage::openedImpl() { - if(!initialized) - { + if (!initialized) { listModel->request(); initialized = true; } @@ -105,13 +100,11 @@ void AtlPage::openedImpl() void AtlPage::suggestCurrent() { - if(!isOpened) - { + if (!isOpened) { return; } - if (selectedVersion.isEmpty()) - { + if (selectedVersion.isEmpty()) { dialog->setSuggestedPack(); return; } @@ -121,10 +114,8 @@ void AtlPage::suggestCurrent() auto editedLogoName = selected.safeName; auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(selected.safeName.toLower()); - listModel->getLogo(selected.safeName, url, [this, editedLogoName](QString logo) - { - dialog->setSuggestedIconFromFile(logo, editedLogoName); - }); + listModel->getLogo(selected.safeName, url, + [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo, editedLogoName); }); } void AtlPage::triggerSearch() @@ -142,10 +133,8 @@ void AtlPage::onSelectionChanged(QModelIndex first, QModelIndex second) { ui->versionSelectionBox->clear(); - if(!first.isValid()) - { - if(isOpened) - { + if (!first.isValid()) { + if (isOpened) { dialog->setSuggestedPack(); } return; @@ -155,7 +144,7 @@ void AtlPage::onSelectionChanged(QModelIndex first, QModelIndex second) ui->packDescription->setHtml(selected.description.replace("\n", "
    ")); - for(const auto& version : selected.versions) { + for (const auto& version : selected.versions) { ui->versionSelectionBox->addItem(version.version); } @@ -164,8 +153,7 @@ void AtlPage::onSelectionChanged(QModelIndex first, QModelIndex second) void AtlPage::onVersionSelectionChanged(QString data) { - if(data.isNull() || data.isEmpty()) - { + if (data.isNull() || data.isEmpty()) { selectedVersion = ""; return; } diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h index 1b3b15c1a..ac336ec10 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h @@ -38,52 +38,38 @@ #include "AtlFilterModel.h" #include "AtlListModel.h" -#include #include +#include #include "Application.h" -#include "ui/pages/BasePage.h" #include "tasks/Task.h" +#include "ui/pages/BasePage.h" -namespace Ui -{ - class AtlPage; +namespace Ui { +class AtlPage; } class NewInstanceDialog; -class AtlPage : public QWidget, public BasePage -{ -Q_OBJECT +class AtlPage : public QWidget, public BasePage { + Q_OBJECT -public: - explicit AtlPage(NewInstanceDialog* dialog, QWidget *parent = 0); + public: + explicit AtlPage(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~AtlPage(); - virtual QString displayName() const override - { - return "ATLauncher"; - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("atlauncher"); - } - virtual QString id() const override - { - return "atl"; - } - virtual QString helpPage() const override - { - return "ATL-platform"; - } + virtual QString displayName() const override { return "ATLauncher"; } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("atlauncher"); } + virtual QString id() const override { return "atl"; } + virtual QString helpPage() const override { return "ATL-platform"; } virtual bool shouldDisplay() const override; void retranslate() override; void openedImpl() override; -private: + private: void suggestCurrent(); -private slots: + private slots: void triggerSearch(); void onSortingSelectionChanged(QString data); @@ -91,8 +77,8 @@ private slots: void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); -private: - Ui::AtlPage *ui = nullptr; + private: + Ui::AtlPage* ui = nullptr; NewInstanceDialog* dialog = nullptr; Atl::ListModel* listModel = nullptr; Atl::FilterModel* filterModel = nullptr; diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp index 3d2d568a1..9ed75bccf 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp @@ -33,17 +33,16 @@ * limitations under the License. */ -#include #include "AtlUserInteractionSupportImpl.h" +#include #include "AtlOptionalModDialog.h" #include "ui/dialogs/VersionSelectDialog.h" -AtlUserInteractionSupportImpl::AtlUserInteractionSupportImpl(QWidget *parent) : m_parent(parent) -{ -} +AtlUserInteractionSupportImpl::AtlUserInteractionSupportImpl(QWidget* parent) : m_parent(parent) {} -std::optional> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) +std::optional> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, + QVector mods) { AtlOptionalModDialog optionalModDialog(m_parent, version, mods); auto result = optionalModDialog.exec(); @@ -59,8 +58,7 @@ QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionList::Ptr vlis if (minecraftVersion != nullptr) { vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); - } - else { + } else { vselect.setEmptyString(tr("No versions are currently available")); } vselect.setEmptyErrorString(tr("Couldn't load or download the version lists!")); @@ -72,9 +70,7 @@ QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionList::Ptr vlis // filter by minecraft version, if the loader depends on a certain version. if (minecraftVersion != nullptr) { - auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require& req) { - return req.uid == "net.minecraft"; - }); + auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require& req) { return req.uid == "net.minecraft"; }); if (iter == reqs.end()) continue; if (iter->equalsVersion != minecraftVersion) diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index fa55aa686..83c1270bd 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -40,14 +40,16 @@ QVariant ListModel::data(const QModelIndex& index, int role) const return edit; } return pack.description; - } case Qt::DecorationRole: { + } + case Qt::DecorationRole: { if (m_logoMap.contains(pack.logoName)) { return (m_logoMap.value(pack.logoName)); } QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; - } case Qt::UserRole: { + } + case Qt::UserRole: { QVariant v; v.setValue(pack); return v; @@ -68,7 +70,7 @@ QVariant ListModel::data(const QModelIndex& index, int role) const return QVariant(); } -bool ListModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool ListModel::setData(const QModelIndex& index, const QVariant& value, int role) { int pos = index.row(); if (pos >= modpacks.size() || pos < 0 || !index.isValid()) diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index cef26bb6b..4a59a0b2a 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -42,9 +42,9 @@ #include "FlameModel.h" #include "InstanceImportTask.h" #include "Json.h" +#include "modplatform/flame/FlameAPI.h" #include "ui/dialogs/NewInstanceDialog.h" #include "ui/widgets/ProjectItem.h" -#include "modplatform/flame/FlameAPI.h" static FlameAPI api; @@ -252,10 +252,8 @@ void FlamePage::updateUi() text += "
    " + tr(" by ") + authorStrs.join(", "); } - if(current.extraInfoLoaded) { - if (!current.extra.issuesUrl.isEmpty() - || !current.extra.sourceUrl.isEmpty() - || !current.extra.wikiUrl.isEmpty()) { + if (current.extraInfoLoaded) { + if (!current.extra.issuesUrl.isEmpty() || !current.extra.sourceUrl.isEmpty() || !current.extra.wikiUrl.isEmpty()) { text += "

    " + tr("External links:") + "
    "; } @@ -267,7 +265,6 @@ void FlamePage::updateUi() text += "- " + tr("Source code: %1").arg(current.extra.sourceUrl) + "
    "; } - text += "
    "; text += api.getModDescription(current.addonId).toUtf8(); diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.h b/launcher/ui/pages/modplatform/flame/FlamePage.h index 8bdca38e8..ad54c13a8 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.h +++ b/launcher/ui/pages/modplatform/flame/FlamePage.h @@ -37,45 +37,31 @@ #include -#include "ui/pages/BasePage.h" #include -#include "tasks/Task.h" #include +#include "tasks/Task.h" +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class FlamePage; } class NewInstanceDialog; namespace Flame { - class ListModel; +class ListModel; } -class FlamePage : public QWidget, public BasePage -{ +class FlamePage : public QWidget, public BasePage { Q_OBJECT -public: - explicit FlamePage(NewInstanceDialog* dialog, QWidget *parent = 0); + public: + explicit FlamePage(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~FlamePage(); - virtual QString displayName() const override - { - return "CurseForge"; - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("flame"); - } - virtual QString id() const override - { - return "flame"; - } - virtual QString helpPage() const override - { - return "Flame-platform"; - } + virtual QString displayName() const override { return "CurseForge"; } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("flame"); } + virtual QString id() const override { return "flame"; } + virtual QString helpPage() const override { return "Flame-platform"; } virtual bool shouldDisplay() const override; void retranslate() override; @@ -83,18 +69,18 @@ public: void openedImpl() override; - bool eventFilter(QObject * watched, QEvent * event) override; + bool eventFilter(QObject* watched, QEvent* event) override; -private: + private: void suggestCurrent(); -private slots: + private slots: void triggerSearch(); void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); -private: - Ui::FlamePage *ui = nullptr; + private: + Ui::FlamePage* ui = nullptr; NewInstanceDialog* dialog = nullptr; Flame::ListModel* listModel = nullptr; Flame::IndexedPack current; diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp index f93e27e64..dc17e705a 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp @@ -49,8 +49,7 @@ static bool isOptedOut(ModPlatform::IndexedVersion const& ver) return ver.downloadUrl.isEmpty(); } -FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance) - : ModPage(dialog, instance) +FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ModPage(dialog, instance) { m_model = new FlameModModel(instance); m_ui->packView->setModel(m_model); @@ -67,7 +66,9 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance) m_ui->packDescription->setMetaEntry(metaEntryBase()); } -auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional loaders) const -> bool +auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, + QString mineVer, + std::optional loaders) const -> bool { Q_UNUSED(loaders); return ver.mcVersion.contains(mineVer) && !ver.downloadUrl.isEmpty(); @@ -86,7 +87,7 @@ void FlameModPage::openUrl(const QUrl& url) if (query.startsWith("remoteUrl=")) { // attempt to resolve url from warning page query.remove(0, 10); - ModPage::openUrl({QUrl::fromPercentEncoding(query.toUtf8())}); // double decoding is necessary + ModPage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary return; } } @@ -125,7 +126,7 @@ void FlameResourcePackPage::openUrl(const QUrl& url) if (query.startsWith("remoteUrl=")) { // attempt to resolve url from warning page query.remove(0, 10); - ResourcePackResourcePage::openUrl({QUrl::fromPercentEncoding(query.toUtf8())}); // double decoding is necessary + ResourcePackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary return; } } @@ -164,7 +165,7 @@ void FlameTexturePackPage::openUrl(const QUrl& url) if (query.startsWith("remoteUrl=")) { // attempt to resolve url from warning page query.remove(0, 10); - ResourcePackResourcePage::openUrl({QUrl::fromPercentEncoding(query.toUtf8())}); // double decoding is necessary + ResourcePackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary return; } } @@ -175,8 +176,17 @@ void FlameTexturePackPage::openUrl(const QUrl& url) // I don't know why, but doing this on the parent class makes it so that // other mod providers start loading before being selected, at least with // my Qt, so we need to implement this in every derived class... -auto FlameModPage::shouldDisplay() const -> bool { return true; } -auto FlameResourcePackPage::shouldDisplay() const -> bool { return true; } -auto FlameTexturePackPage::shouldDisplay() const -> bool { return true; } +auto FlameModPage::shouldDisplay() const -> bool +{ + return true; +} +auto FlameResourcePackPage::shouldDisplay() const -> bool +{ + return true; +} +auto FlameTexturePackPage::shouldDisplay() const -> bool +{ + return true; +} } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h index 103a6bb92..c6ebc1eac 100644 --- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h +++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h @@ -49,12 +49,27 @@ namespace ResourceDownload { namespace Flame { -static inline QString displayName() { return "CurseForge"; } -static inline QIcon icon() { return APPLICATION->getThemedIcon("flame"); } -static inline QString id() { return "curseforge"; } -static inline QString debugName() { return "Flame"; } -static inline QString metaEntryBase() { return "FlameMods"; } +static inline QString displayName() +{ + return "CurseForge"; } +static inline QIcon icon() +{ + return APPLICATION->getThemedIcon("flame"); +} +static inline QString id() +{ + return "curseforge"; +} +static inline QString debugName() +{ + return "Flame"; +} +static inline QString metaEntryBase() +{ + return "FlameMods"; +} +} // namespace Flame class FlameModPage : public ModPage { Q_OBJECT @@ -78,7 +93,9 @@ 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 validateVersion(ModPlatform::IndexedVersion& ver, + QString mineVer, + std::optional loaders = {}) const override; bool optedOut(ModPlatform::IndexedVersion& ver) const override; void openUrl(const QUrl& url) override; diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.h b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.h index c55df0009..51a58d991 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.h +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.h @@ -1,13 +1,13 @@ #pragma once -#include #include +#include #include -#include -#include #include +#include #include +#include #include @@ -16,34 +16,28 @@ namespace LegacyFTB { typedef QMap FTBLogoMap; typedef std::function LogoCallback; -class FilterModel : public QSortFilterProxyModel -{ +class FilterModel : public QSortFilterProxyModel { Q_OBJECT -public: + public: FilterModel(QObject* parent = Q_NULLPTR); - enum Sorting { - ByName, - ByGameVersion - }; + enum Sorting { ByName, ByGameVersion }; const QMap getAvailableSortings(); QString translateCurrentSorting(); void setSorting(Sorting sorting); Sorting getCurrentSorting(); -protected: - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; -private: + private: QMap sortings; Sorting currentSorting; - }; -class ListModel : public QAbstractListModel -{ +class ListModel : public QAbstractListModel { Q_OBJECT -private: + private: ModpackList modpacks; QStringList m_failedLogos; QStringList m_loadingLogos; @@ -53,18 +47,17 @@ private: void requestLogo(QString file); QString translatePackType(PackType type) const; - -private slots: + private slots: void logoFailed(QString logo); void logoLoaded(QString logo, QIcon out); -public: - ListModel(QObject *parent); + public: + ListModel(QObject* parent); ~ListModel(); - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - QVariant data(const QModelIndex &index, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; void fill(ModpackList modpacks); void addPack(Modpack modpack); @@ -72,7 +65,7 @@ public: void remove(int row); Modpack at(int row); - void getLogo(const QString &logo, LogoCallback callback); + void getLogo(const QString& logo, LogoCallback callback); }; -} +} // namespace LegacyFTB diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp index b3f6261fe..e322419ba 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp @@ -44,15 +44,14 @@ #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/NewInstanceDialog.h" +#include "ListModel.h" #include "modplatform/legacy_ftb/PackFetchTask.h" #include "modplatform/legacy_ftb/PackInstallTask.h" #include "modplatform/legacy_ftb/PrivatePackManager.h" -#include "ListModel.h" namespace LegacyFTB { -Page::Page(NewInstanceDialog* dialog, QWidget *parent) - : QWidget(parent), dialog(dialog), ui(new Ui::Page) +Page::Page(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), dialog(dialog), ui(new Ui::Page) { ftbFetchTask.reset(new PackFetchTask(APPLICATION->network())); ftbPrivatePacks.reset(new PrivatePackManager()); @@ -70,8 +69,7 @@ Page::Page(NewInstanceDialog* dialog, QWidget *parent) ui->publicPackList->setIndentation(0); ui->publicPackList->setIconSize(QSize(42, 42)); - for(int i = 0; i < publicFilterModel->getAvailableSortings().size(); i++) - { + for (int i = 0; i < publicFilterModel->getAvailableSortings().size(); i++) { ui->sortByBox->addItem(publicFilterModel->getAvailableSortings().keys().at(i)); } @@ -142,8 +140,7 @@ bool Page::shouldDisplay() const void Page::openedImpl() { - if(!initialized) - { + if (!initialized) { connect(ftbFetchTask.get(), &PackFetchTask::finished, this, &Page::ftbPackDataDownloadSuccessfully); connect(ftbFetchTask.get(), &PackFetchTask::failed, this, &Page::ftbPackDataDownloadFailed); connect(ftbFetchTask.get(), &PackFetchTask::aborted, this, &Page::ftbPackDataDownloadAborted); @@ -166,50 +163,34 @@ void Page::retranslate() void Page::suggestCurrent() { - if(!isOpened) - { + if (!isOpened) { return; } - if(selected.broken || selectedVersion.isEmpty()) - { + if (selected.broken || selectedVersion.isEmpty()) { dialog->setSuggestedPack(); return; } dialog->setSuggestedPack(selected.name, selectedVersion, new PackInstallTask(APPLICATION->network(), selected, selectedVersion)); QString editedLogoName; - if(selected.logo.toLower().startsWith("ftb")) - { + if (selected.logo.toLower().startsWith("ftb")) { editedLogoName = selected.logo; - } - else - { + } else { editedLogoName = "ftb_" + selected.logo; } editedLogoName = editedLogoName.left(editedLogoName.lastIndexOf(".png")); - if(selected.type == PackType::Public) - { - publicListModel->getLogo(selected.logo, [this, editedLogoName](QString logo) - { - dialog->setSuggestedIconFromFile(logo, editedLogoName); - }); - } - else if (selected.type == PackType::ThirdParty) - { - thirdPartyModel->getLogo(selected.logo, [this, editedLogoName](QString logo) - { - dialog->setSuggestedIconFromFile(logo, editedLogoName); - }); - } - else if (selected.type == PackType::Private) - { - privateListModel->getLogo(selected.logo, [this, editedLogoName](QString logo) - { - dialog->setSuggestedIconFromFile(logo, editedLogoName); - }); + if (selected.type == PackType::Public) { + publicListModel->getLogo(selected.logo, + [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo, editedLogoName); }); + } else if (selected.type == PackType::ThirdParty) { + thirdPartyModel->getLogo(selected.logo, + [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo, editedLogoName); }); + } else if (selected.type == PackType::Private) { + privateListModel->getLogo(selected.logo, + [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo, editedLogoName); }); } } @@ -236,21 +217,16 @@ void Page::ftbPrivatePackDataDownloadSuccessfully(Modpack pack) void Page::ftbPrivatePackDataDownloadFailed(QString reason, QString packCode) { - auto reply = QMessageBox::question( - this, - tr("FTB private packs"), - tr("Failed to download pack information for code %1.\nShould it be removed now?").arg(packCode) - ); - if(reply == QMessageBox::Yes) - { + auto reply = QMessageBox::question(this, tr("FTB private packs"), + tr("Failed to download pack information for code %1.\nShould it be removed now?").arg(packCode)); + if (reply == QMessageBox::Yes) { ftbPrivatePacks->remove(packCode); } } void Page::onPublicPackSelectionChanged(QModelIndex now, QModelIndex prev) { - if(!now.isValid()) - { + if (!now.isValid()) { onPackSelectionChanged(); return; } @@ -260,8 +236,7 @@ void Page::onPublicPackSelectionChanged(QModelIndex now, QModelIndex prev) void Page::onThirdPartyPackSelectionChanged(QModelIndex now, QModelIndex prev) { - if(!now.isValid()) - { + if (!now.isValid()) { onPackSelectionChanged(); return; } @@ -271,8 +246,7 @@ void Page::onThirdPartyPackSelectionChanged(QModelIndex now, QModelIndex prev) void Page::onPrivatePackSelectionChanged(QModelIndex now, QModelIndex prev) { - if(!now.isValid()) - { + if (!now.isValid()) { onPackSelectionChanged(); return; } @@ -283,34 +257,26 @@ void Page::onPrivatePackSelectionChanged(QModelIndex now, QModelIndex prev) void Page::onPackSelectionChanged(Modpack* pack) { ui->versionSelectionBox->clear(); - if(pack) - { - currentModpackInfo->setHtml("Pack by " + pack->author + "" + - "
    Minecraft " + pack->mcVersion + "
    " + "
    " + pack->description + "
    • " + pack->mods.replace(";", "
    • ") - + "
    "); + if (pack) { + currentModpackInfo->setHtml("Pack by " + pack->author + "" + "
    Minecraft " + pack->mcVersion + "
    " + "
    " + + pack->description + "
    • " + pack->mods.replace(";", "
    • ") + "
    "); bool currentAdded = false; - for(int i = 0; i < pack->oldVersions.size(); i++) - { - if(pack->currentVersion == pack->oldVersions.at(i)) - { + for (int i = 0; i < pack->oldVersions.size(); i++) { + if (pack->currentVersion == pack->oldVersions.at(i)) { currentAdded = true; } ui->versionSelectionBox->addItem(pack->oldVersions.at(i)); } - if(!currentAdded) - { + if (!currentAdded) { ui->versionSelectionBox->addItem(pack->currentVersion); } selected = *pack; - } - else - { + } else { currentModpackInfo->setHtml(""); ui->versionSelectionBox->clear(); - if(isOpened) - { + if (isOpened) { dialog->setSuggestedPack(); } return; @@ -320,8 +286,7 @@ void Page::onPackSelectionChanged(Modpack* pack) void Page::onVersionSelectionItemChanged(QString data) { - if(data.isNull() || data.isEmpty()) - { + if (data.isNull() || data.isEmpty()) { selectedVersion = ""; return; } @@ -340,20 +305,15 @@ void Page::onSortingSelectionChanged(QString data) void Page::onTabChanged(int tab) { - if(tab == 1) - { + if (tab == 1) { currentModel = thirdPartyFilterModel; currentList = ui->thirdPartyPackList; currentModpackInfo = ui->thirdPartyPackDescription; - } - else if(tab == 2) - { + } else if (tab == 2) { currentModel = privateFilterModel; currentList = ui->privatePackList; currentModpackInfo = ui->privatePackDescription; - } - else - { + } else { currentModel = publicFilterModel; currentList = ui->publicPackList; currentModpackInfo = ui->publicPackDescription; @@ -361,13 +321,10 @@ void Page::onTabChanged(int tab) currentList->selectionModel()->reset(); QModelIndex idx = currentList->currentIndex(); - if(idx.isValid()) - { + if (idx.isValid()) { auto pack = currentModel->data(idx, Qt::UserRole).value(); onPackSelectionChanged(&pack); - } - else - { + } else { onPackSelectionChanged(); } } @@ -375,38 +332,24 @@ void Page::onTabChanged(int tab) void Page::onAddPackClicked() { bool ok; - QString text = QInputDialog::getText( - this, - tr("Add FTB pack"), - tr("Enter pack code:"), - QLineEdit::Normal, - QString(), - &ok - ); - if(ok && !text.isEmpty()) - { + QString text = QInputDialog::getText(this, tr("Add FTB pack"), tr("Enter pack code:"), QLineEdit::Normal, QString(), &ok); + if (ok && !text.isEmpty()) { ftbPrivatePacks->add(text); - ftbFetchTask->fetchPrivate({text}); + ftbFetchTask->fetchPrivate({ text }); } } void Page::onRemovePackClicked() { auto index = ui->privatePackList->currentIndex(); - if(!index.isValid()) - { + if (!index.isValid()) { return; } auto row = index.row(); Modpack pack = privateListModel->at(row); - auto answer = QMessageBox::question( - this, - tr("Remove pack"), - tr("Are you sure you want to remove pack %1?").arg(pack.name), - QMessageBox::Yes | QMessageBox::No - ); - if(answer != QMessageBox::Yes) - { + auto answer = QMessageBox::question(this, tr("Remove pack"), tr("Are you sure you want to remove pack %1?").arg(pack.name), + QMessageBox::Yes | QMessageBox::No); + if (answer != QMessageBox::Yes) { return; } @@ -415,4 +358,4 @@ void Page::onRemovePackClicked() onPackSelectionChanged(); } -} +} // namespace LegacyFTB diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.h b/launcher/ui/pages/modplatform/legacy_ftb/Page.h index 1de8b40ab..32b4a8146 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.h +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.h @@ -35,23 +35,22 @@ #pragma once -#include -#include #include +#include +#include -#include "ui/pages/BasePage.h" #include -#include "tasks/Task.h" -#include "modplatform/legacy_ftb/PackHelpers.h" -#include "modplatform/legacy_ftb/PackFetchTask.h" #include "QObjectPtr.h" +#include "modplatform/legacy_ftb/PackFetchTask.h" +#include "modplatform/legacy_ftb/PackHelpers.h" +#include "tasks/Task.h" +#include "ui/pages/BasePage.h" class NewInstanceDialog; namespace LegacyFTB { -namespace Ui -{ +namespace Ui { class Page; } @@ -61,38 +60,25 @@ class PrivatePackListModel; class PrivatePackFilterModel; class PrivatePackManager; -class Page : public QWidget, public BasePage -{ +class Page : public QWidget, public BasePage { Q_OBJECT -public: - explicit Page(NewInstanceDialog * dialog, QWidget *parent = 0); + public: + explicit Page(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~Page(); - QString displayName() const override - { - return "FTB Legacy"; - } - QIcon icon() const override - { - return APPLICATION->getThemedIcon("ftb_logo"); - } - QString id() const override - { - return "legacy_ftb"; - } - QString helpPage() const override - { - return "FTB-platform"; - } + QString displayName() const override { return "FTB Legacy"; } + QIcon icon() const override { return APPLICATION->getThemedIcon("ftb_logo"); } + QString id() const override { return "legacy_ftb"; } + QString helpPage() const override { return "FTB-platform"; } bool shouldDisplay() const override; void openedImpl() override; void retranslate() override; -private: + private: void suggestCurrent(); - void onPackSelectionChanged(Modpack *pack = nullptr); + void onPackSelectionChanged(Modpack* pack = nullptr); -private slots: + private slots: void ftbPackDataDownloadSuccessfully(ModpackList publicPacks, ModpackList thirdPartyPacks); void ftbPackDataDownloadFailed(QString reason); void ftbPackDataDownloadAborted(); @@ -112,7 +98,7 @@ private slots: void onAddPackClicked(); void onRemovePackClicked(); -private: + private: FilterModel* currentModel = nullptr; QTreeView* currentList = nullptr; QTextBrowser* currentModpackInfo = nullptr; @@ -124,18 +110,18 @@ private: ListModel* publicListModel = nullptr; FilterModel* publicFilterModel = nullptr; - ListModel *thirdPartyModel = nullptr; - FilterModel *thirdPartyFilterModel = nullptr; + ListModel* thirdPartyModel = nullptr; + FilterModel* thirdPartyFilterModel = nullptr; - ListModel *privateListModel = nullptr; - FilterModel *privateFilterModel = nullptr; + ListModel* privateListModel = nullptr; + FilterModel* privateFilterModel = nullptr; unique_qobject_ptr ftbFetchTask; std::unique_ptr ftbPrivatePacks; NewInstanceDialog* dialog = nullptr; - Ui::Page *ui = nullptr; + Ui::Page* ui = nullptr; }; -} +} // namespace LegacyFTB diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index e0046d887..9c392fcab 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -115,7 +115,7 @@ auto ModpackListModel::data(const QModelIndex& index, int role) const -> QVarian return {}; } -bool ModpackListModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool ModpackListModel::setData(const QModelIndex& index, const QVariant& value, int role) { int pos = index.row(); if (pos >= modpacks.size() || pos < 0 || !index.isValid()) @@ -181,18 +181,18 @@ void ModpackListModel::refresh() static auto sortFromIndex(int index) -> QString { - switch(index){ - default: - case 0: - return "relevance"; - case 1: - return "downloads"; - case 2: - return "follows"; - case 3: - return "newest"; - case 4: - return "updated"; + switch (index) { + default: + case 0: + return "relevance"; + case 1: + return "downloads"; + case 2: + return "follows"; + case 3: + return "newest"; + case 4: + return "updated"; } return {}; @@ -200,7 +200,7 @@ static auto sortFromIndex(int index) -> QString void ModpackListModel::searchWithTerm(const QString& term, const int sort) { - if(sort > 5 || sort < 0) + if (sort > 5 || sort < 0) return; auto sort_str = sortFromIndex(sort); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index b9e9c3da5..47c2d55b4 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -47,7 +47,7 @@ class Version; namespace Modrinth { using LogoMap = QMap; -using LogoCallback = std::function; +using LogoCallback = std::function; class ModpackListModel : public QAbstractListModel { Q_OBJECT @@ -64,7 +64,7 @@ class ModpackListModel : public QAbstractListModel { /* Retrieve information from the model at a given index with the given role */ auto data(const QModelIndex& index, int role) const -> QVariant override; - bool setData(const QModelIndex &index, const QVariant &value, int role) override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; inline void setActiveJob(NetJob::Ptr ptr) { jobPtr = ptr; } @@ -75,7 +75,10 @@ class ModpackListModel : public QAbstractListModel { void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); - inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return parent.isValid() ? false : searchState == CanPossiblyFetchMore; }; + inline auto canFetchMore(const QModelIndex& parent) const -> bool override + { + return parent.isValid() ? false : searchState == CanPossiblyFetchMore; + }; public slots: void searchRequestFinished(QJsonDocument& doc_all); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp index dd143700c..ff809c7bb 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp @@ -46,8 +46,7 @@ namespace ResourceDownload { -ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance) - : ModPage(dialog, instance) +ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ModPage(dialog, instance) { m_model = new ModrinthModModel(instance); m_ui->packView->setModel(m_model); @@ -64,14 +63,15 @@ ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instan m_ui->packDescription->setMetaEntry(metaEntryBase()); } -auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional loaders) const -> bool +auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, + QString mineVer, + std::optional loaders) const -> bool { auto loaderCompatible = !loaders.has_value(); if (!loaderCompatible) { auto loaderStrings = ModrinthAPI::getModLoaderStrings(loaders.value()); - for (auto remoteLoader : ver.loaders) - { + for (auto remoteLoader : ver.loaders) { if (loaderStrings.contains(remoteLoader)) { loaderCompatible = true; break; @@ -139,9 +139,21 @@ ModrinthShaderPackPage::ModrinthShaderPackPage(ShaderPackDownloadDialog* dialog, // I don't know why, but doing this on the parent class makes it so that // other mod providers start loading before being selected, at least with // my Qt, so we need to implement this in every derived class... -auto ModrinthModPage::shouldDisplay() const -> bool { return true; } -auto ModrinthResourcePackPage::shouldDisplay() const -> bool { return true; } -auto ModrinthTexturePackPage::shouldDisplay() const -> bool { return true; } -auto ModrinthShaderPackPage::shouldDisplay() const -> bool { return true; } +auto ModrinthModPage::shouldDisplay() const -> bool +{ + return true; +} +auto ModrinthResourcePackPage::shouldDisplay() const -> bool +{ + return true; +} +auto ModrinthTexturePackPage::shouldDisplay() const -> bool +{ + return true; +} +auto ModrinthShaderPackPage::shouldDisplay() const -> bool +{ + return true; +} } // namespace ResourceDownload diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h index f4eb5ce09..26037f0cd 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h @@ -43,18 +43,33 @@ #include "ui/pages/modplatform/ModPage.h" #include "ui/pages/modplatform/ResourcePackPage.h" -#include "ui/pages/modplatform/TexturePackPage.h" #include "ui/pages/modplatform/ShaderPackPage.h" +#include "ui/pages/modplatform/TexturePackPage.h" namespace ResourceDownload { namespace Modrinth { -static inline QString displayName() { return "Modrinth"; } -static inline QIcon icon() { return APPLICATION->getThemedIcon("modrinth"); } -static inline QString id() { return "modrinth"; } -static inline QString debugName() { return "Modrinth"; } -static inline QString metaEntryBase() { return "ModrinthPacks"; } +static inline QString displayName() +{ + return "Modrinth"; } +static inline QIcon icon() +{ + return APPLICATION->getThemedIcon("modrinth"); +} +static inline QString id() +{ + return "modrinth"; +} +static inline QString debugName() +{ + return "Modrinth"; +} +static inline QString metaEntryBase() +{ + return "ModrinthPacks"; +} +} // namespace Modrinth class ModrinthModPage : public ModPage { Q_OBJECT @@ -78,7 +93,8 @@ 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; + auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional loaders = {}) const + -> bool override; }; class ModrinthResourcePackPage : public ResourcePackResourcePage { diff --git a/launcher/ui/pages/modplatform/technic/TechnicData.h b/launcher/ui/pages/modplatform/technic/TechnicData.h index cd2ea8e14..81488811a 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicData.h +++ b/launcher/ui/pages/modplatform/technic/TechnicData.h @@ -63,6 +63,6 @@ struct Modpack { QString recommended; QVector versions; }; -} +} // namespace Technic Q_DECLARE_METATYPE(Technic::Modpack) diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp index fc678fa20..589d3da59 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp @@ -41,16 +41,15 @@ #include "ui/dialogs/NewInstanceDialog.h" #include "BuildConfig.h" +#include "Json.h" #include "TechnicModel.h" #include "modplatform/technic/SingleZipPackInstallTask.h" #include "modplatform/technic/SolderPackInstallTask.h" -#include "Json.h" #include "Application.h" #include "modplatform/technic/SolderPackManifest.h" -TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget *parent) - : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog) +TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog) { ui->setupUi(this); connect(ui->searchButton, &QPushButton::clicked, this, &TechnicPage::triggerSearch); @@ -96,7 +95,8 @@ void TechnicPage::openedImpl() triggerSearch(); } -void TechnicPage::triggerSearch() { +void TechnicPage::triggerSearch() +{ model->searchWithTerm(ui->searchEdit->text()); } @@ -104,10 +104,8 @@ void TechnicPage::onSelectionChanged(QModelIndex first, QModelIndex second) { ui->versionSelectionBox->clear(); - if(!first.isValid()) - { - if(isOpened) - { + if (!first.isValid()) { + if (isOpened) { dialog->setSuggestedPack(); } return; @@ -119,74 +117,60 @@ void TechnicPage::onSelectionChanged(QModelIndex first, QModelIndex second) void TechnicPage::suggestCurrent() { - if (!isOpened) - { + if (!isOpened) { return; } - if (current.broken) - { + if (current.broken) { dialog->setSuggestedPack(); return; } QString editedLogoName = "technic_" + current.logoName.section(".", 0, 0); - model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo) - { - dialog->setSuggestedIconFromFile(logo, editedLogoName); - }); + model->getLogo(current.logoName, current.logoUrl, + [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo, editedLogoName); }); - if (current.metadataLoaded) - { + if (current.metadataLoaded) { metadataLoaded(); return; } auto netJob = makeShared(QString("Technic::PackMeta(%1)").arg(current.name), APPLICATION->network()); QString slug = current.slug; - netJob->addNetAction(Net::Download::makeByteArray(QString("%1modpack/%2?build=%3").arg(BuildConfig.TECHNIC_API_BASE_URL, slug, BuildConfig.TECHNIC_API_BUILD), response)); - QObject::connect(netJob.get(), &NetJob::succeeded, this, [this, slug] - { + netJob->addNetAction(Net::Download::makeByteArray( + QString("%1modpack/%2?build=%3").arg(BuildConfig.TECHNIC_API_BASE_URL, slug, BuildConfig.TECHNIC_API_BUILD), response)); + QObject::connect(netJob.get(), &NetJob::succeeded, this, [this, slug] { jobPtr.reset(); - if (current.slug != slug) - { + if (current.slug != slug) { return; } - QJsonParseError parse_error {}; + QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); QJsonObject obj = doc.object(); - if(parse_error.error != QJsonParseError::NoError) - { - qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString(); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset + << " reason: " << parse_error.errorString(); qWarning() << *response; return; } - if (!obj.contains("url")) - { + if (!obj.contains("url")) { qWarning() << "Json doesn't contain an url key"; return; } QJsonValueRef url = obj["url"]; - if (url.isString()) - { + if (url.isString()) { current.url = url.toString(); - } - else - { - if (!obj.contains("solder")) - { + } else { + if (!obj.contains("solder")) { qWarning() << "Json doesn't contain a valid url or solder key"; return; } QJsonValueRef solderUrl = obj["solder"]; - if (solderUrl.isString()) - { + if (solderUrl.isString()) { current.url = solderUrl.toString(); current.isSolder = true; - } - else - { + } else { qWarning() << "Json doesn't contain a valid url or solder key"; return; } @@ -227,22 +211,21 @@ void TechnicPage::metadataLoaded() // Strip trailing forward-slashes from Solder URL's if (current.isSolder) { - while (current.url.endsWith('/')) current.url.chop(1); + while (current.url.endsWith('/')) + current.url.chop(1); } // Display versions from Solder if (!current.isSolder) { // If the pack isn't a Solder pack, it only has the single version ui->versionSelectionBox->addItem(current.currentVersion); - } - else if (current.versionsLoaded) { + } else if (current.versionsLoaded) { // reverse foreach, so that the newest versions are first for (auto i = current.versions.size(); i--;) { ui->versionSelectionBox->addItem(current.versions.at(i)); } ui->versionSelectionBox->setCurrentText(current.recommended); - } - else { + } else { // For now, until the versions are pulled from the Solder instance, display the current // version so we can display something quicker ui->versionSelectionBox->addItem(current.currentVersion); @@ -260,7 +243,8 @@ void TechnicPage::metadataLoaded() selectVersion(); } -void TechnicPage::selectVersion() { +void TechnicPage::selectVersion() +{ if (!isOpened) { return; } @@ -269,17 +253,18 @@ void TechnicPage::selectVersion() { return; } - if (!current.isSolder) - { - dialog->setSuggestedPack(current.name, selectedVersion, new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion)); - } - else - { - dialog->setSuggestedPack(current.name, selectedVersion, new Technic::SolderPackInstallTask(APPLICATION->network(), current.url, current.slug, selectedVersion, current.minecraftVersion)); + if (!current.isSolder) { + dialog->setSuggestedPack(current.name, selectedVersion, + new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion)); + } else { + dialog->setSuggestedPack(current.name, selectedVersion, + new Technic::SolderPackInstallTask(APPLICATION->network(), current.url, current.slug, selectedVersion, + current.minecraftVersion)); } } -void TechnicPage::onSolderLoaded() { +void TechnicPage::onSolderLoaded() +{ jobPtr.reset(); auto fallback = [this]() { @@ -319,7 +304,8 @@ void TechnicPage::onSolderLoaded() { metadataLoaded(); } -void TechnicPage::onVersionSelectionChanged(QString data) { +void TechnicPage::onVersionSelectionChanged(QString data) +{ if (data.isNull() || data.isEmpty()) { selectedVersion = ""; return; diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.h b/launcher/ui/pages/modplatform/technic/TechnicPage.h index 753261b30..d33656ebb 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicPage.h +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.h @@ -37,46 +37,32 @@ #include -#include "ui/pages/BasePage.h" #include +#include "TechnicData.h" #include "net/NetJob.h" #include "tasks/Task.h" -#include "TechnicData.h" +#include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class TechnicPage; } class NewInstanceDialog; namespace Technic { - class ListModel; +class ListModel; } -class TechnicPage : public QWidget, public BasePage -{ +class TechnicPage : public QWidget, public BasePage { Q_OBJECT -public: - explicit TechnicPage(NewInstanceDialog* dialog, QWidget *parent = 0); + public: + explicit TechnicPage(NewInstanceDialog* dialog, QWidget* parent = 0); virtual ~TechnicPage(); - virtual QString displayName() const override - { - return "Technic"; - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("technic"); - } - virtual QString id() const override - { - return "technic"; - } - virtual QString helpPage() const override - { - return "Technic-platform"; - } + virtual QString displayName() const override { return "Technic"; } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("technic"); } + virtual QString id() const override { return "technic"; } + virtual QString helpPage() const override { return "Technic-platform"; } virtual bool shouldDisplay() const override; void retranslate() override; @@ -84,19 +70,19 @@ public: bool eventFilter(QObject* watched, QEvent* event) override; -private: + private: void suggestCurrent(); void metadataLoaded(); void selectVersion(); -private slots: + private slots: void triggerSearch(); void onSelectionChanged(QModelIndex first, QModelIndex second); void onSolderLoaded(); void onVersionSelectionChanged(QString data); -private: - Ui::TechnicPage *ui = nullptr; + private: + Ui::TechnicPage* ui = nullptr; NewInstanceDialog* dialog = nullptr; Technic::ListModel* model = nullptr; diff --git a/launcher/ui/setupwizard/BaseWizardPage.h b/launcher/ui/setupwizard/BaseWizardPage.h index 72dbecfd5..80cc64969 100644 --- a/launcher/ui/setupwizard/BaseWizardPage.h +++ b/launcher/ui/setupwizard/BaseWizardPage.h @@ -1,31 +1,21 @@ #pragma once -#include #include +#include -class BaseWizardPage : public QWizardPage -{ -public: - explicit BaseWizardPage(QWidget *parent = Q_NULLPTR) - : QWizardPage(parent) - { - } - virtual ~BaseWizardPage() {}; +class BaseWizardPage : public QWizardPage { + public: + explicit BaseWizardPage(QWidget* parent = Q_NULLPTR) : QWizardPage(parent) {} + virtual ~BaseWizardPage(){}; - virtual bool wantsRefreshButton() - { - return false; - } - virtual void refresh() - { - } + virtual bool wantsRefreshButton() { return false; } + virtual void refresh() {} -protected: + protected: virtual void retranslate() = 0; - void changeEvent(QEvent * event) override + void changeEvent(QEvent* event) override { - if (event->type() == QEvent::LanguageChange) - { + if (event->type() == QEvent::LanguageChange) { retranslate(); } QWizardPage::changeEvent(event); diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index 2b70c47c3..e2c444373 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -1,29 +1,27 @@ #include "JavaWizardPage.h" #include "Application.h" -#include +#include #include -#include #include #include #include +#include #include -#include +#include #include #include "FileSystem.h" +#include "JavaCommon.h" #include "java/JavaInstall.h" #include "java/JavaUtils.h" -#include "JavaCommon.h" -#include "ui/widgets/VersionSelectWidget.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/widgets/JavaSettingsWidget.h" +#include "ui/widgets/VersionSelectWidget.h" - -JavaWizardPage::JavaWizardPage(QWidget *parent) - :BaseWizardPage(parent) +JavaWizardPage::JavaWizardPage(QWidget* parent) : BaseWizardPage(parent) { setupUi(); } @@ -31,7 +29,7 @@ JavaWizardPage::JavaWizardPage(QWidget *parent) void JavaWizardPage::setupUi() { setObjectName(QStringLiteral("javaPage")); - QVBoxLayout * layout = new QVBoxLayout(this); + QVBoxLayout* layout = new QVBoxLayout(this); m_java_widget = new JavaSettingsWidget(this); layout->addWidget(m_java_widget); @@ -59,30 +57,23 @@ bool JavaWizardPage::validatePage() { auto settings = APPLICATION->settings(); auto result = m_java_widget->validate(); - switch(result) - { + switch (result) { default: - case JavaSettingsWidget::ValidationStatus::Bad: - { + case JavaSettingsWidget::ValidationStatus::Bad: { return false; } - case JavaSettingsWidget::ValidationStatus::AllOK: - { + case JavaSettingsWidget::ValidationStatus::AllOK: { settings->set("JavaPath", m_java_widget->javaPath()); return true; } - case JavaSettingsWidget::ValidationStatus::JavaBad: - { + case JavaSettingsWidget::ValidationStatus::JavaBad: { // Memory auto s = APPLICATION->settings(); s->set("MinMemAlloc", m_java_widget->minHeapSize()); s->set("MaxMemAlloc", m_java_widget->maxHeapSize()); - if (m_java_widget->permGenEnabled()) - { + if (m_java_widget->permGenEnabled()) { s->set("PermGen", m_java_widget->permGenSize()); - } - else - { + } else { s->reset("PermGen"); } return true; @@ -93,7 +84,8 @@ bool JavaWizardPage::validatePage() void JavaWizardPage::retranslate() { setTitle(tr("Java")); - setSubTitle(tr("You do not have a working Java set up yet or it went missing.\n" - "Please select one of the following or browse for a Java executable.")); + setSubTitle( + tr("You do not have a working Java set up yet or it went missing.\n" + "Please select one of the following or browse for a Java executable.")); m_java_widget->retranslate(); } diff --git a/launcher/ui/setupwizard/JavaWizardPage.h b/launcher/ui/setupwizard/JavaWizardPage.h index 0d749039c..6c083dc96 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.h +++ b/launcher/ui/setupwizard/JavaWizardPage.h @@ -4,26 +4,22 @@ class JavaSettingsWidget; -class JavaWizardPage : public BaseWizardPage -{ +class JavaWizardPage : public BaseWizardPage { Q_OBJECT -public: - explicit JavaWizardPage(QWidget *parent = Q_NULLPTR); + public: + explicit JavaWizardPage(QWidget* parent = Q_NULLPTR); - virtual ~JavaWizardPage() - { - }; + virtual ~JavaWizardPage(){}; bool wantsRefreshButton() override; void refresh() override; void initializePage() override; bool validatePage() override; -protected: /* methods */ + protected: /* methods */ void setupUi(); void retranslate() override; -private: /* data */ - JavaSettingsWidget *m_java_widget = nullptr; + private: /* data */ + JavaSettingsWidget* m_java_widget = nullptr; }; - diff --git a/launcher/ui/setupwizard/LanguageWizardPage.cpp b/launcher/ui/setupwizard/LanguageWizardPage.cpp index 6bd19b6ff..09cdb807e 100644 --- a/launcher/ui/setupwizard/LanguageWizardPage.cpp +++ b/launcher/ui/setupwizard/LanguageWizardPage.cpp @@ -2,25 +2,22 @@ #include #include -#include "ui/widgets/LanguageSelectionWidget.h" -#include #include +#include +#include "ui/widgets/LanguageSelectionWidget.h" -LanguageWizardPage::LanguageWizardPage(QWidget *parent) - : BaseWizardPage(parent) +LanguageWizardPage::LanguageWizardPage(QWidget* parent) : BaseWizardPage(parent) { setObjectName(QStringLiteral("languagePage")); auto layout = new QVBoxLayout(this); mainWidget = new LanguageSelectionWidget(this); - layout->setContentsMargins(0,0,0,0); + layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(mainWidget); retranslate(); } -LanguageWizardPage::~LanguageWizardPage() -{ -} +LanguageWizardPage::~LanguageWizardPage() {} bool LanguageWizardPage::wantsRefreshButton() { diff --git a/launcher/ui/setupwizard/LanguageWizardPage.h b/launcher/ui/setupwizard/LanguageWizardPage.h index 45a0e5c04..44a062399 100644 --- a/launcher/ui/setupwizard/LanguageWizardPage.h +++ b/launcher/ui/setupwizard/LanguageWizardPage.h @@ -4,11 +4,10 @@ class LanguageSelectionWidget; -class LanguageWizardPage : public BaseWizardPage -{ +class LanguageWizardPage : public BaseWizardPage { Q_OBJECT -public: - explicit LanguageWizardPage(QWidget *parent = Q_NULLPTR); + public: + explicit LanguageWizardPage(QWidget* parent = Q_NULLPTR); virtual ~LanguageWizardPage(); @@ -18,9 +17,9 @@ public: bool validatePage() override; -protected: + protected: void retranslate() override; -private: - LanguageSelectionWidget *mainWidget = nullptr; + private: + LanguageSelectionWidget* mainWidget = nullptr; }; diff --git a/launcher/ui/setupwizard/PasteWizardPage.cpp b/launcher/ui/setupwizard/PasteWizardPage.cpp index 0f47da4b1..777fd3a44 100644 --- a/launcher/ui/setupwizard/PasteWizardPage.cpp +++ b/launcher/ui/setupwizard/PasteWizardPage.cpp @@ -4,9 +4,7 @@ #include "Application.h" #include "net/PasteUpload.h" -PasteWizardPage::PasteWizardPage(QWidget *parent) : - BaseWizardPage(parent), - ui(new Ui::PasteWizardPage) +PasteWizardPage::PasteWizardPage(QWidget* parent) : BaseWizardPage(parent), ui(new Ui::PasteWizardPage) { ui->setupUi(this); } @@ -16,17 +14,14 @@ PasteWizardPage::~PasteWizardPage() delete ui; } -void PasteWizardPage::initializePage() -{ -} +void PasteWizardPage::initializePage() {} bool PasteWizardPage::validatePage() { auto s = APPLICATION->settings(); QString prevPasteURL = s->get("PastebinURL").toString(); s->reset("PastebinURL"); - if (ui->previousSettingsRadioButton->isChecked()) - { + if (ui->previousSettingsRadioButton->isChecked()) { bool usingDefaultBase = prevPasteURL == PasteUpload::PasteTypes.at(PasteUpload::PasteType::NullPointer).defaultBase; s->set("PastebinType", PasteUpload::PasteType::NullPointer); if (!usingDefaultBase) diff --git a/launcher/ui/setupwizard/PasteWizardPage.h b/launcher/ui/setupwizard/PasteWizardPage.h index 513a14cb5..dece81c42 100644 --- a/launcher/ui/setupwizard/PasteWizardPage.h +++ b/launcher/ui/setupwizard/PasteWizardPage.h @@ -8,20 +8,19 @@ namespace Ui { class PasteWizardPage; } -class PasteWizardPage : public BaseWizardPage -{ +class PasteWizardPage : public BaseWizardPage { Q_OBJECT -public: - explicit PasteWizardPage(QWidget *parent = nullptr); + public: + explicit PasteWizardPage(QWidget* parent = nullptr); ~PasteWizardPage(); void initializePage() override; bool validatePage() override; void retranslate() override; -private: - Ui::PasteWizardPage *ui; + private: + Ui::PasteWizardPage* ui; }; -#endif // PASTEDEFAULTSCONFIRMATIONWIZARD_H +#endif // PASTEDEFAULTSCONFIRMATIONWIZARD_H diff --git a/launcher/ui/setupwizard/SetupWizard.cpp b/launcher/ui/setupwizard/SetupWizard.cpp index 0a47334fc..4e5bd1dca 100644 --- a/launcher/ui/setupwizard/SetupWizard.cpp +++ b/launcher/ui/setupwizard/SetupWizard.cpp @@ -1,16 +1,16 @@ #include "SetupWizard.h" -#include "LanguageWizardPage.h" #include "JavaWizardPage.h" +#include "LanguageWizardPage.h" -#include "translations/TranslationsModel.h" #include #include +#include "translations/TranslationsModel.h" -#include #include +#include -SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent) +SetupWizard::SetupWizard(QWidget* parent) : QWizard(parent) { setObjectName(QStringLiteral("SetupWizard")); resize(620, 660); @@ -33,17 +33,17 @@ void SetupWizard::retranslate() setWindowTitle(tr("%1 Quick Setup").arg(BuildConfig.LAUNCHER_DISPLAYNAME)); } -BaseWizardPage * SetupWizard::getBasePage(int id) +BaseWizardPage* SetupWizard::getBasePage(int id) { - if(id == -1) + if (id == -1) return nullptr; auto pagePtr = page(id); - if(!pagePtr) + if (!pagePtr) return nullptr; - return dynamic_cast(pagePtr); + return dynamic_cast(pagePtr); } -BaseWizardPage * SetupWizard::getCurrentBasePage() +BaseWizardPage* SetupWizard::getCurrentBasePage() { return getBasePage(currentId()); } @@ -51,38 +51,29 @@ BaseWizardPage * SetupWizard::getCurrentBasePage() void SetupWizard::pageChanged(int id) { auto basePagePtr = getBasePage(id); - if(!basePagePtr) - { + if (!basePagePtr) { return; } - if(basePagePtr->wantsRefreshButton()) - { - setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton}); + if (basePagePtr->wantsRefreshButton()) { + setButtonLayout({ QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton }); auto customButton = button(QWizard::CustomButton1); - connect(customButton, &QAbstractButton::clicked, [&](){ + connect(customButton, &QAbstractButton::clicked, [&]() { auto basePagePtr = getCurrentBasePage(); - if(basePagePtr) - { + if (basePagePtr) { basePagePtr->refresh(); } }); - } - else - { - setButtonLayout({QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton}); + } else { + setButtonLayout({ QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton }); } } - -void SetupWizard::changeEvent(QEvent *event) +void SetupWizard::changeEvent(QEvent* event) { - if (event->type() == QEvent::LanguageChange) - { + if (event->type() == QEvent::LanguageChange) { retranslate(); } QWizard::changeEvent(event); } -SetupWizard::~SetupWizard() -{ -} +SetupWizard::~SetupWizard() {} diff --git a/launcher/ui/setupwizard/SetupWizard.h b/launcher/ui/setupwizard/SetupWizard.h index 9b8adb4df..c26c59fdb 100644 --- a/launcher/ui/setupwizard/SetupWizard.h +++ b/launcher/ui/setupwizard/SetupWizard.h @@ -17,29 +17,26 @@ #include -namespace Ui -{ +namespace Ui { class SetupWizard; } class BaseWizardPage; -class SetupWizard : public QWizard -{ +class SetupWizard : public QWizard { Q_OBJECT -public: /* con/destructors */ - explicit SetupWizard(QWidget *parent = 0); + public: /* con/destructors */ + explicit SetupWizard(QWidget* parent = 0); virtual ~SetupWizard(); - void changeEvent(QEvent * event) override; - BaseWizardPage *getBasePage(int id); - BaseWizardPage *getCurrentBasePage(); + void changeEvent(QEvent* event) override; + BaseWizardPage* getBasePage(int id); + BaseWizardPage* getCurrentBasePage(); -private slots: + private slots: void pageChanged(int id); -private: /* methods */ + private: /* methods */ void retranslate(); }; - diff --git a/launcher/ui/themes/BrightTheme.cpp b/launcher/ui/themes/BrightTheme.cpp index 696ffdfb4..ffccdaab1 100644 --- a/launcher/ui/themes/BrightTheme.cpp +++ b/launcher/ui/themes/BrightTheme.cpp @@ -20,18 +20,18 @@ bool BrightTheme::hasColorScheme() QPalette BrightTheme::colorScheme() { QPalette brightPalette; - brightPalette.setColor(QPalette::Window, QColor(255,255,255)); - brightPalette.setColor(QPalette::WindowText, QColor(17,17,17)); - brightPalette.setColor(QPalette::Base, QColor(250,250,250)); - brightPalette.setColor(QPalette::AlternateBase, QColor(240,240,240)); - brightPalette.setColor(QPalette::ToolTipBase, QColor(17,17,17)); - brightPalette.setColor(QPalette::ToolTipText, QColor(255,255,255)); - brightPalette.setColor(QPalette::Text, Qt::black); - brightPalette.setColor(QPalette::Button, QColor(249,249,249)); + brightPalette.setColor(QPalette::Window, QColor(255, 255, 255)); + brightPalette.setColor(QPalette::WindowText, QColor(17, 17, 17)); + brightPalette.setColor(QPalette::Base, QColor(250, 250, 250)); + brightPalette.setColor(QPalette::AlternateBase, QColor(240, 240, 240)); + brightPalette.setColor(QPalette::ToolTipBase, QColor(17, 17, 17)); + brightPalette.setColor(QPalette::ToolTipText, QColor(255, 255, 255)); + brightPalette.setColor(QPalette::Text, Qt::black); + brightPalette.setColor(QPalette::Button, QColor(249, 249, 249)); brightPalette.setColor(QPalette::ButtonText, Qt::black); brightPalette.setColor(QPalette::BrightText, Qt::red); - brightPalette.setColor(QPalette::Link, QColor(37,137,164)); - brightPalette.setColor(QPalette::Highlight, QColor(137,207,84)); + brightPalette.setColor(QPalette::Link, QColor(37, 137, 164)); + brightPalette.setColor(QPalette::Highlight, QColor(137, 207, 84)); brightPalette.setColor(QPalette::HighlightedText, Qt::black); return fadeInactive(brightPalette, fadeAmount(), fadeColor()); } @@ -43,7 +43,7 @@ double BrightTheme::fadeAmount() QColor BrightTheme::fadeColor() { - return QColor(255,255,255); + return QColor(255, 255, 255); } bool BrightTheme::hasStyleSheet() @@ -55,4 +55,3 @@ QString BrightTheme::appStyleSheet() { return QString(); } - diff --git a/launcher/ui/themes/BrightTheme.h b/launcher/ui/themes/BrightTheme.h index c61f52d58..44a767492 100644 --- a/launcher/ui/themes/BrightTheme.h +++ b/launcher/ui/themes/BrightTheme.h @@ -2,9 +2,8 @@ #include "FusionTheme.h" -class BrightTheme: public FusionTheme -{ -public: +class BrightTheme : public FusionTheme { + public: virtual ~BrightTheme() {} QString id() override; @@ -16,4 +15,3 @@ public: double fadeAmount() override; QColor fadeColor() override; }; - diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 177edefad..d1eaf1571 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -183,7 +183,8 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest return; } - // FIXME: This is kinda jank, it only actually checks if the qss file path is not present. It should actually check for any relevant missing data (e.g. name, colors) + // FIXME: This is kinda jank, it only actually checks if the qss file path is not present. It should actually check for any relevant + // missing data (e.g. name, colors) if (jsonDataIncomplete) { writeThemeJson(fileInfo.absoluteFilePath(), m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath); } diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp index 48231b53e..c3a68a2d4 100644 --- a/launcher/ui/themes/DarkTheme.cpp +++ b/launcher/ui/themes/DarkTheme.cpp @@ -20,21 +20,21 @@ bool DarkTheme::hasColorScheme() QPalette DarkTheme::colorScheme() { QPalette darkPalette; - darkPalette.setColor(QPalette::Window, QColor(49,49,49)); + darkPalette.setColor(QPalette::Window, QColor(49, 49, 49)); darkPalette.setColor(QPalette::WindowText, Qt::white); - darkPalette.setColor(QPalette::Base, QColor(34,34,34)); - darkPalette.setColor(QPalette::AlternateBase, QColor(42,42,42)); + darkPalette.setColor(QPalette::Base, QColor(34, 34, 34)); + darkPalette.setColor(QPalette::AlternateBase, QColor(42, 42, 42)); darkPalette.setColor(QPalette::ToolTipBase, Qt::white); darkPalette.setColor(QPalette::ToolTipText, Qt::white); darkPalette.setColor(QPalette::Text, Qt::white); - darkPalette.setColor(QPalette::Button, QColor(48,48,48)); + darkPalette.setColor(QPalette::Button, QColor(48, 48, 48)); darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); - darkPalette.setColor(QPalette::Link, QColor(47,163,198)); - darkPalette.setColor(QPalette::Highlight, QColor(150,219,89)); + darkPalette.setColor(QPalette::Link, QColor(47, 163, 198)); + darkPalette.setColor(QPalette::Highlight, QColor(150, 219, 89)); darkPalette.setColor(QPalette::HighlightedText, Qt::black); darkPalette.setColor(QPalette::PlaceholderText, Qt::darkGray); - return fadeInactive(darkPalette, fadeAmount(), fadeColor()); + return fadeInactive(darkPalette, fadeAmount(), fadeColor()); } double DarkTheme::fadeAmount() @@ -44,7 +44,7 @@ double DarkTheme::fadeAmount() QColor DarkTheme::fadeColor() { - return QColor(49,49,49); + return QColor(49, 49, 49); } bool DarkTheme::hasStyleSheet() diff --git a/launcher/ui/themes/DarkTheme.h b/launcher/ui/themes/DarkTheme.h index 9bd2f3439..431e9a735 100644 --- a/launcher/ui/themes/DarkTheme.h +++ b/launcher/ui/themes/DarkTheme.h @@ -2,9 +2,8 @@ #include "FusionTheme.h" -class DarkTheme: public FusionTheme -{ -public: +class DarkTheme : public FusionTheme { + public: virtual ~DarkTheme() {} QString id() override; diff --git a/launcher/ui/themes/FusionTheme.h b/launcher/ui/themes/FusionTheme.h index ee34245ac..826fae1db 100644 --- a/launcher/ui/themes/FusionTheme.h +++ b/launcher/ui/themes/FusionTheme.h @@ -2,9 +2,8 @@ #include "ITheme.h" -class FusionTheme: public ITheme -{ -public: +class FusionTheme : public ITheme { + public: virtual ~FusionTheme() {} QString qtTheme() override; diff --git a/launcher/ui/themes/ITheme.cpp b/launcher/ui/themes/ITheme.cpp index 42d63b113..316b0f2ed 100644 --- a/launcher/ui/themes/ITheme.cpp +++ b/launcher/ui/themes/ITheme.cpp @@ -33,10 +33,10 @@ * limitations under the License. */ #include "ITheme.h" -#include "rainbow.h" -#include #include +#include #include "Application.h" +#include "rainbow.h" void ITheme::apply(bool) { @@ -51,8 +51,7 @@ void ITheme::apply(bool) QPalette ITheme::fadeInactive(QPalette in, qreal bias, QColor color) { - auto blend = [&in, bias, color](QPalette::ColorRole role) - { + auto blend = [&in, bias, color](QPalette::ColorRole role) { QColor from = in.color(QPalette::Active, role); QColor blended = Rainbow::mix(from, color, bias); in.setColor(QPalette::Disabled, role, blended); diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index 3b8cb24a4..7ad144c7a 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -65,7 +65,7 @@ void SystemTheme::apply(bool initial) // See https://github.com/MultiMC/Launcher/issues/1790 // or https://github.com/PrismLauncher/PrismLauncher/issues/490 if (initial) - return; + return; ITheme::apply(initial); } diff --git a/launcher/ui/widgets/CustomCommands.cpp b/launcher/ui/widgets/CustomCommands.cpp index 5ab903950..98a1b7e86 100644 --- a/launcher/ui/widgets/CustomCommands.cpp +++ b/launcher/ui/widgets/CustomCommands.cpp @@ -41,9 +41,7 @@ CustomCommands::~CustomCommands() delete ui; } -CustomCommands::CustomCommands(QWidget* parent): - QWidget(parent), - ui(new Ui::CustomCommands) +CustomCommands::CustomCommands(QWidget* parent) : QWidget(parent), ui(new Ui::CustomCommands) { ui->setupUi(this); } @@ -51,8 +49,7 @@ CustomCommands::CustomCommands(QWidget* parent): void CustomCommands::initialize(bool checkable, bool checked, const QString& prelaunch, const QString& wrapper, const QString& postexit) { ui->customCommandsGroupBox->setCheckable(checkable); - if(checkable) - { + if (checkable) { ui->customCommandsGroupBox->setChecked(checked); } ui->preLaunchCmdTextBox->setText(prelaunch); @@ -60,14 +57,14 @@ void CustomCommands::initialize(bool checkable, bool checked, const QString& pre ui->postExitCmdTextBox->setText(postexit); } - -void CustomCommands::retranslate() { +void CustomCommands::retranslate() +{ ui->retranslateUi(this); } bool CustomCommands::checked() const { - if(!ui->customCommandsGroupBox->isCheckable()) + if (!ui->customCommandsGroupBox->isCheckable()) return true; return ui->customCommandsGroupBox->isChecked(); } diff --git a/launcher/ui/widgets/CustomCommands.h b/launcher/ui/widgets/CustomCommands.h index ed10ba956..96a3fa627 100644 --- a/launcher/ui/widgets/CustomCommands.h +++ b/launcher/ui/widgets/CustomCommands.h @@ -37,19 +37,17 @@ #include -namespace Ui -{ +namespace Ui { class CustomCommands; } -class CustomCommands : public QWidget -{ +class CustomCommands : public QWidget { Q_OBJECT -public: - explicit CustomCommands(QWidget *parent = 0); + public: + explicit CustomCommands(QWidget* parent = 0); virtual ~CustomCommands(); - void initialize(bool checkable, bool checked, const QString & prelaunch, const QString & wrapper, const QString & postexit); + void initialize(bool checkable, bool checked, const QString& prelaunch, const QString& wrapper, const QString& postexit); void retranslate(); bool checked() const; @@ -57,8 +55,6 @@ public: QString wrapperCommand() const; QString postexitCommand() const; -private: - Ui::CustomCommands *ui; + private: + Ui::CustomCommands* ui; }; - - diff --git a/launcher/ui/widgets/DropLabel.cpp b/launcher/ui/widgets/DropLabel.cpp index a900e57cf..b1473b358 100644 --- a/launcher/ui/widgets/DropLabel.cpp +++ b/launcher/ui/widgets/DropLabel.cpp @@ -1,34 +1,33 @@ #include "DropLabel.h" -#include #include +#include -DropLabel::DropLabel(QWidget *parent) : QLabel(parent) +DropLabel::DropLabel(QWidget* parent) : QLabel(parent) { setAcceptDrops(true); } -void DropLabel::dragEnterEvent(QDragEnterEvent *event) +void DropLabel::dragEnterEvent(QDragEnterEvent* event) { event->acceptProposedAction(); } -void DropLabel::dragMoveEvent(QDragMoveEvent *event) +void DropLabel::dragMoveEvent(QDragMoveEvent* event) { event->acceptProposedAction(); } -void DropLabel::dragLeaveEvent(QDragLeaveEvent *event) +void DropLabel::dragLeaveEvent(QDragLeaveEvent* event) { event->accept(); } -void DropLabel::dropEvent(QDropEvent *event) +void DropLabel::dropEvent(QDropEvent* event) { - const QMimeData *mimeData = event->mimeData(); + const QMimeData* mimeData = event->mimeData(); - if (!mimeData) - { + if (!mimeData) { return; } diff --git a/launcher/ui/widgets/DropLabel.h b/launcher/ui/widgets/DropLabel.h index c5ca0bcca..0027f48b1 100644 --- a/launcher/ui/widgets/DropLabel.h +++ b/launcher/ui/widgets/DropLabel.h @@ -2,19 +2,18 @@ #include -class DropLabel : public QLabel -{ +class DropLabel : public QLabel { Q_OBJECT -public: - explicit DropLabel(QWidget *parent = nullptr); + public: + explicit DropLabel(QWidget* parent = nullptr); -signals: + signals: void droppedURLs(QList urls); -protected: - void dropEvent(QDropEvent *event) override; - void dragEnterEvent(QDragEnterEvent *event) override; - void dragMoveEvent(QDragMoveEvent *event) override; - void dragLeaveEvent(QDragLeaveEvent *event) override; + protected: + void dropEvent(QDropEvent* event) override; + void dragEnterEvent(QDragEnterEvent* event) override; + void dragMoveEvent(QDragMoveEvent* event) override; + void dragLeaveEvent(QDragLeaveEvent* event) override; }; diff --git a/launcher/ui/widgets/ErrorFrame.cpp b/launcher/ui/widgets/ErrorFrame.cpp index b3e410361..213c26b76 100644 --- a/launcher/ui/widgets/ErrorFrame.cpp +++ b/launcher/ui/widgets/ErrorFrame.cpp @@ -27,9 +27,7 @@ void ErrorFrame::clear() setDescription(QString()); } -ErrorFrame::ErrorFrame(QWidget *parent) : - QFrame(parent), - ui(new Ui::ErrorFrame) +ErrorFrame::ErrorFrame(QWidget* parent) : QFrame(parent), ui(new Ui::ErrorFrame) { ui->setupUi(this); ui->label_Description->setHidden(true); @@ -44,24 +42,18 @@ ErrorFrame::~ErrorFrame() void ErrorFrame::updateHiddenState() { - if(ui->label_Description->isHidden() && ui->label_Title->isHidden()) - { + if (ui->label_Description->isHidden() && ui->label_Title->isHidden()) { setHidden(true); - } - else - { + } else { setHidden(false); } } void ErrorFrame::setTitle(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->label_Title->setHidden(true); - } - else - { + } else { ui->label_Title->setText(text); ui->label_Title->setHidden(false); } @@ -70,14 +62,11 @@ void ErrorFrame::setTitle(QString text) void ErrorFrame::setDescription(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->label_Description->setHidden(true); updateHiddenState(); return; - } - else - { + } else { ui->label_Description->setHidden(false); updateHiddenState(); } @@ -87,9 +76,8 @@ void ErrorFrame::setDescription(QString text) QChar rem('\n'); QString finaltext; finaltext.reserve(intermediatetext.size()); - foreach(const QChar& c, intermediatetext) - { - if(c == rem && prev){ + foreach (const QChar& c, intermediatetext) { + if (c == rem && prev) { continue; } prev = c == rem; @@ -97,33 +85,27 @@ void ErrorFrame::setDescription(QString text) } QString labeltext; labeltext.reserve(300); - if(finaltext.length() > 290) - { + if (finaltext.length() > 290) { ui->label_Description->setOpenExternalLinks(false); ui->label_Description->setTextFormat(Qt::TextFormat::RichText); desc = text; // This allows injecting HTML here. labeltext.append("" + finaltext.left(287) + "..."); QObject::connect(ui->label_Description, &QLabel::linkActivated, this, &ErrorFrame::ellipsisHandler); - } - else - { + } else { ui->label_Description->setTextFormat(Qt::TextFormat::PlainText); labeltext.append(finaltext); } ui->label_Description->setText(labeltext); } -void ErrorFrame::ellipsisHandler(const QString &link) +void ErrorFrame::ellipsisHandler(const QString& link) { - if(!currentBox) - { + if (!currentBox) { currentBox = CustomMessageBox::selectable(this, QString(), desc); connect(currentBox, &QMessageBox::finished, this, &ErrorFrame::boxClosed); currentBox->show(); - } - else - { + } else { currentBox->setText(desc); } } diff --git a/launcher/ui/widgets/ErrorFrame.h b/launcher/ui/widgets/ErrorFrame.h index d5069a14b..1aea6a1d8 100644 --- a/launcher/ui/widgets/ErrorFrame.h +++ b/launcher/ui/widgets/ErrorFrame.h @@ -17,17 +17,15 @@ #include -namespace Ui -{ +namespace Ui { class ErrorFrame; } -class ErrorFrame : public QFrame -{ +class ErrorFrame : public QFrame { Q_OBJECT -public: - explicit ErrorFrame(QWidget *parent = 0); + public: + explicit ErrorFrame(QWidget* parent = 0); ~ErrorFrame(); void setTitle(QString text); @@ -35,15 +33,15 @@ public: void clear(); -public slots: - void ellipsisHandler(const QString& link ); + public slots: + void ellipsisHandler(const QString& link); void boxClosed(int result); -private: + private: void updateHiddenState(); -private: - Ui::ErrorFrame *ui; + private: + Ui::ErrorFrame* ui; QString desc; - class QMessageBox * currentBox = nullptr; + class QMessageBox* currentBox = nullptr; }; diff --git a/launcher/ui/widgets/FocusLineEdit.cpp b/launcher/ui/widgets/FocusLineEdit.cpp index b272100c0..6570227bb 100644 --- a/launcher/ui/widgets/FocusLineEdit.cpp +++ b/launcher/ui/widgets/FocusLineEdit.cpp @@ -1,23 +1,22 @@ #include "FocusLineEdit.h" #include -FocusLineEdit::FocusLineEdit(QWidget *parent) : QLineEdit(parent) +FocusLineEdit::FocusLineEdit(QWidget* parent) : QLineEdit(parent) { _selectOnMousePress = false; } -void FocusLineEdit::focusInEvent(QFocusEvent *e) +void FocusLineEdit::focusInEvent(QFocusEvent* e) { QLineEdit::focusInEvent(e); selectAll(); _selectOnMousePress = true; } -void FocusLineEdit::mousePressEvent(QMouseEvent *me) +void FocusLineEdit::mousePressEvent(QMouseEvent* me) { QLineEdit::mousePressEvent(me); - if (_selectOnMousePress) - { + if (_selectOnMousePress) { selectAll(); _selectOnMousePress = false; } diff --git a/launcher/ui/widgets/FocusLineEdit.h b/launcher/ui/widgets/FocusLineEdit.h index 71b4f140a..f5ea6602e 100644 --- a/launcher/ui/widgets/FocusLineEdit.h +++ b/launcher/ui/widgets/FocusLineEdit.h @@ -1,17 +1,14 @@ #include -class FocusLineEdit : public QLineEdit -{ +class FocusLineEdit : public QLineEdit { Q_OBJECT -public: - FocusLineEdit(QWidget *parent); - virtual ~FocusLineEdit() - { - } + public: + FocusLineEdit(QWidget* parent); + virtual ~FocusLineEdit() {} -protected: - void focusInEvent(QFocusEvent *e); - void mousePressEvent(QMouseEvent *me); + protected: + void focusInEvent(QFocusEvent* e); + void mousePressEvent(QMouseEvent* me); bool _selectOnMousePress; }; diff --git a/launcher/ui/widgets/IconLabel.cpp b/launcher/ui/widgets/IconLabel.cpp index bf1c23584..28776686b 100644 --- a/launcher/ui/widgets/IconLabel.cpp +++ b/launcher/ui/widgets/IconLabel.cpp @@ -1,13 +1,12 @@ #include "IconLabel.h" -#include -#include #include #include #include +#include +#include -IconLabel::IconLabel(QWidget *parent, QIcon icon, QSize size) - : QWidget(parent), m_size(size), m_icon(icon) +IconLabel::IconLabel(QWidget* parent, QIcon icon, QSize size) : QWidget(parent), m_size(size), m_icon(icon) { setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); } @@ -23,19 +22,16 @@ void IconLabel::setIcon(QIcon icon) update(); } -void IconLabel::paintEvent(QPaintEvent *) +void IconLabel::paintEvent(QPaintEvent*) { QPainter p(this); QRect rect = contentsRect(); int width = rect.width(); int height = rect.height(); - if(width < height) - { + if (width < height) { rect.setHeight(width); rect.translate(0, (height - width) / 2); - } - else if (width > height) - { + } else if (width > height) { rect.setWidth(height); rect.translate((width - height) / 2, 0); } diff --git a/launcher/ui/widgets/IconLabel.h b/launcher/ui/widgets/IconLabel.h index 6d212c4ca..41d97f694 100644 --- a/launcher/ui/widgets/IconLabel.h +++ b/launcher/ui/widgets/IconLabel.h @@ -1,26 +1,25 @@ #pragma once -#include #include +#include class QStyleOption; /** * This is a trivial widget that paints a QIcon of the specified size. */ -class IconLabel : public QWidget -{ +class IconLabel : public QWidget { Q_OBJECT -public: + public: /// Create a line separator. orientation is the orientation of the line. - explicit IconLabel(QWidget *parent, QIcon icon, QSize size); + explicit IconLabel(QWidget* parent, QIcon icon, QSize size); virtual QSize sizeHint() const; - virtual void paintEvent(QPaintEvent *); + virtual void paintEvent(QPaintEvent*); void setIcon(QIcon icon); -private: + private: QSize m_size; QIcon m_icon; }; diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index c94fdd8d5..8c4048ff2 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -1,20 +1,20 @@ #include "JavaSettingsWidget.h" -#include +#include #include -#include #include #include #include +#include #include -#include +#include #include +#include "FileSystem.h" #include "JavaCommon.h" #include "java/JavaInstall.h" #include "java/JavaUtils.h" -#include "FileSystem.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/widgets/VersionSelectWidget.h" @@ -149,40 +149,30 @@ void JavaSettingsWidget::refresh() JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() { - switch(javaStatus) - { + switch (javaStatus) { default: case JavaStatus::NotSet: case JavaStatus::DoesNotExist: case JavaStatus::DoesNotStart: - case JavaStatus::ReturnedInvalidData: - { - int button = CustomMessageBox::selectable( - this, - tr("No Java version selected"), - tr("You didn't select a Java version or selected something that doesn't work.\n" - "%1 will not be able to start Minecraft.\n" - "Do you wish to proceed without any Java?" - "\n\n" - "You can change the Java version in the settings later.\n" - ).arg(BuildConfig.LAUNCHER_DISPLAYNAME), - QMessageBox::Warning, - QMessageBox::Yes | QMessageBox::No, - QMessageBox::NoButton - )->exec(); - if(button == QMessageBox::No) - { + case JavaStatus::ReturnedInvalidData: { + int button = CustomMessageBox::selectable(this, tr("No Java version selected"), + tr("You didn't select a Java version or selected something that doesn't work.\n" + "%1 will not be able to start Minecraft.\n" + "Do you wish to proceed without any Java?" + "\n\n" + "You can change the Java version in the settings later.\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton) + ->exec(); + if (button == QMessageBox::No) { return ValidationStatus::Bad; } return ValidationStatus::JavaBad; - } - break; - case JavaStatus::Pending: - { + } break; + case JavaStatus::Pending: { return ValidationStatus::Bad; } - case JavaStatus::Good: - { + case JavaStatus::Good: { return ValidationStatus::AllOK; } } @@ -219,34 +209,26 @@ void JavaSettingsWidget::memoryValueChanged(int) unsigned int min = m_minMemSpinBox->value(); unsigned int max = m_maxMemSpinBox->value(); unsigned int permgen = m_permGenSpinBox->value(); - QObject *obj = sender(); - if (obj == m_minMemSpinBox && min != observedMinMemory) - { + QObject* obj = sender(); + if (obj == m_minMemSpinBox && min != observedMinMemory) { observedMinMemory = min; actuallyChanged = true; - if (min > max) - { + if (min > max) { observedMaxMemory = min; m_maxMemSpinBox->setValue(min); } - } - else if (obj == m_maxMemSpinBox && max != observedMaxMemory) - { + } else if (obj == m_maxMemSpinBox && max != observedMaxMemory) { observedMaxMemory = max; actuallyChanged = true; - if (min > max) - { + if (min > max) { observedMinMemory = max; m_minMemSpinBox->setValue(max); } - } - else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory) - { + } else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory) { observedPermGenMemory = permgen; actuallyChanged = true; } - if(actuallyChanged) - { + if (actuallyChanged) { checkJavaPathOnEdit(m_javaPathTextBox->text()); updateThresholds(); } @@ -255,8 +237,7 @@ void JavaSettingsWidget::memoryValueChanged(int) void JavaSettingsWidget::javaVersionSelected(BaseVersion::Ptr version) { auto java = std::dynamic_pointer_cast(version); - if(!java) - { + if (!java) { return; } auto visible = java->id.requiresPermGen(); @@ -275,8 +256,7 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() filter = "Java (java)"; #endif QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter); - if(raw_path.isEmpty()) - { + if (raw_path.isEmpty()) { return; } QString cooked_path = FS::NormalizePath(raw_path); @@ -288,8 +268,7 @@ void JavaSettingsWidget::on_javaStatusBtn_clicked() { QString text; bool failed = false; - switch(javaStatus) - { + switch (javaStatus) { case JavaStatus::NotSet: checkJavaPath(m_javaPathTextBox->text()); return; @@ -297,24 +276,20 @@ void JavaSettingsWidget::on_javaStatusBtn_clicked() text += QObject::tr("The specified file either doesn't exist or is not a proper executable."); failed = true; break; - case JavaStatus::DoesNotStart: - { + case JavaStatus::DoesNotStart: { text += QObject::tr("The specified Java binary didn't start properly.
    "); auto htmlError = m_result.errorLog; - if(!htmlError.isEmpty()) - { + if (!htmlError.isEmpty()) { htmlError.replace('\n', "
    "); text += QString("%1").arg(htmlError); } failed = true; break; } - case JavaStatus::ReturnedInvalidData: - { + case JavaStatus::ReturnedInvalidData: { text += QObject::tr("The specified Java binary returned unexpected results:
    "); auto htmlOut = m_result.outLog; - if(!htmlOut.isEmpty()) - { + if (!htmlOut.isEmpty()) { htmlOut.replace('\n', "
    "); text += QString("%1").arg(htmlOut); } @@ -322,26 +297,24 @@ void JavaSettingsWidget::on_javaStatusBtn_clicked() break; } case JavaStatus::Good: - text += QObject::tr("Java test succeeded!
    Platform reported: %1
    Java version " - "reported: %2
    ").arg(m_result.realPlatform, m_result.javaVersion.toString()); + text += QObject::tr( + "Java test succeeded!
    Platform reported: %1
    Java version " + "reported: %2
    ") + .arg(m_result.realPlatform, m_result.javaVersion.toString()); break; case JavaStatus::Pending: // TODO: abort here? return; } - CustomMessageBox::selectable( - this, - failed ? QObject::tr("Java test failure") : QObject::tr("Java test success"), - text, - failed ? QMessageBox::Critical : QMessageBox::Information - )->show(); + CustomMessageBox::selectable(this, failed ? QObject::tr("Java test failure") : QObject::tr("Java test success"), text, + failed ? QMessageBox::Critical : QMessageBox::Information) + ->show(); } void JavaSettingsWidget::setJavaStatus(JavaSettingsWidget::JavaStatus status) { javaStatus = status; - switch(javaStatus) - { + switch (javaStatus) { case JavaStatus::Good: m_javaStatusBtn->setIcon(goodIcon); break; @@ -364,29 +337,23 @@ void JavaSettingsWidget::checkJavaPathOnEdit(const QString& path) { auto realPath = FS::ResolveExecutable(path); QFileInfo pathInfo(realPath); - if (pathInfo.baseName().toLower().contains("java")) - { + if (pathInfo.baseName().toLower().contains("java")) { checkJavaPath(path); - } - else - { - if(!m_checker) - { + } else { + if (!m_checker) { setJavaStatus(JavaStatus::NotSet); } } } -void JavaSettingsWidget::checkJavaPath(const QString &path) +void JavaSettingsWidget::checkJavaPath(const QString& path) { - if(m_checker) - { + if (m_checker) { queuedCheck = path; return; } auto realPath = FS::ResolveExecutable(path); - if(realPath.isNull()) - { + if (realPath.isNull()) { setJavaStatus(JavaStatus::DoesNotExist); return; } @@ -395,8 +362,7 @@ void JavaSettingsWidget::checkJavaPath(const QString &path) m_checker->m_path = path; m_checker->m_minMem = m_minMemSpinBox->value(); m_checker->m_maxMem = m_maxMemSpinBox->value(); - if(m_permGenSpinBox->isVisible()) - { + if (m_permGenSpinBox->isVisible()) { m_checker->m_permGen = m_permGenSpinBox->value(); } connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished); @@ -406,27 +372,22 @@ void JavaSettingsWidget::checkJavaPath(const QString &path) void JavaSettingsWidget::checkFinished(JavaCheckResult result) { m_result = result; - switch(result.validity) - { - case JavaCheckResult::Validity::Valid: - { + switch (result.validity) { + case JavaCheckResult::Validity::Valid: { setJavaStatus(JavaStatus::Good); break; } - case JavaCheckResult::Validity::ReturnedInvalidData: - { + case JavaCheckResult::Validity::ReturnedInvalidData: { setJavaStatus(JavaStatus::ReturnedInvalidData); break; } - case JavaCheckResult::Validity::Errored: - { + case JavaCheckResult::Validity::Errored: { setJavaStatus(JavaStatus::DoesNotStart); break; } } m_checker.reset(); - if(!queuedCheck.isNull()) - { + if (!queuedCheck.isNull()) { checkJavaPath(queuedCheck); queuedCheck.clear(); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index e4b7c7129..6ea73da60 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -1,9 +1,9 @@ #pragma once #include -#include #include #include +#include #include class QLineEdit; @@ -20,30 +20,16 @@ class QToolButton; /** * This is a widget for all the Java settings dialogs and pages. */ -class JavaSettingsWidget : public QWidget -{ +class JavaSettingsWidget : public QWidget { Q_OBJECT -public: - explicit JavaSettingsWidget(QWidget *parent); - virtual ~JavaSettingsWidget() {}; + public: + explicit JavaSettingsWidget(QWidget* parent); + virtual ~JavaSettingsWidget(){}; - enum class JavaStatus - { - NotSet, - Pending, - Good, - DoesNotExist, - DoesNotStart, - ReturnedInvalidData - } javaStatus = JavaStatus::NotSet; + enum class JavaStatus { NotSet, Pending, Good, DoesNotExist, DoesNotStart, ReturnedInvalidData } javaStatus = JavaStatus::NotSet; - enum class ValidationStatus - { - Bad, - JavaBad, - AllOK - }; + enum class ValidationStatus { Bad, JavaBad, AllOK }; void refresh(); void initialize(); @@ -58,39 +44,38 @@ public: void updateThresholds(); - -protected slots: + protected slots: void memoryValueChanged(int); - void javaPathEdited(const QString &path); + void javaPathEdited(const QString& path); void javaVersionSelected(BaseVersion::Ptr version); void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); void checkFinished(JavaCheckResult result); -protected: /* methods */ - void checkJavaPathOnEdit(const QString &path); - void checkJavaPath(const QString &path); + protected: /* methods */ + void checkJavaPathOnEdit(const QString& path); + void checkJavaPath(const QString& path); void setJavaStatus(JavaStatus status); void setupUi(); -private: /* data */ - VersionSelectWidget *m_versionWidget = nullptr; - QVBoxLayout *m_verticalLayout = nullptr; + private: /* data */ + VersionSelectWidget* m_versionWidget = nullptr; + QVBoxLayout* m_verticalLayout = nullptr; - QLineEdit * m_javaPathTextBox = nullptr; - QPushButton * m_javaBrowseBtn = nullptr; - QToolButton * m_javaStatusBtn = nullptr; - QHBoxLayout *m_horizontalLayout = nullptr; + QLineEdit* m_javaPathTextBox = nullptr; + QPushButton* m_javaBrowseBtn = nullptr; + QToolButton* m_javaStatusBtn = nullptr; + QHBoxLayout* m_horizontalLayout = nullptr; - QGroupBox *m_memoryGroupBox = nullptr; - QGridLayout *m_gridLayout_2 = nullptr; - QSpinBox *m_maxMemSpinBox = nullptr; - QLabel *m_labelMinMem = nullptr; - QLabel *m_labelMaxMem = nullptr; - QLabel *m_labelMaxMemIcon = nullptr; - QSpinBox *m_minMemSpinBox = nullptr; - QLabel *m_labelPermGen = nullptr; - QSpinBox *m_permGenSpinBox = nullptr; + QGroupBox* m_memoryGroupBox = nullptr; + QGridLayout* m_gridLayout_2 = nullptr; + QSpinBox* m_maxMemSpinBox = nullptr; + QLabel* m_labelMinMem = nullptr; + QLabel* m_labelMaxMem = nullptr; + QLabel* m_labelMaxMemIcon = nullptr; + QSpinBox* m_minMemSpinBox = nullptr; + QLabel* m_labelPermGen = nullptr; + QSpinBox* m_permGenSpinBox = nullptr; QIcon goodIcon; QIcon yellowIcon; QIcon badIcon; diff --git a/launcher/ui/widgets/LabeledToolButton.cpp b/launcher/ui/widgets/LabeledToolButton.cpp index f52e49c98..7af48b0c9 100644 --- a/launcher/ui/widgets/LabeledToolButton.cpp +++ b/launcher/ui/widgets/LabeledToolButton.cpp @@ -33,31 +33,29 @@ * limitations under the License. */ -#include -#include -#include -#include #include "LabeledToolButton.h" #include #include +#include +#include +#include +#include /* - * + * * Tool Button with a label on it, instead of the normal text rendering - * + * */ -LabeledToolButton::LabeledToolButton(QWidget * parent) - : QToolButton(parent) - , m_label(new QLabel(this)) +LabeledToolButton::LabeledToolButton(QWidget* parent) : QToolButton(parent), m_label(new QLabel(this)) { - //QToolButton::setText(" "); + // QToolButton::setText(" "); m_label->setWordWrap(true); m_label->setMouseTracking(false); m_label->setAlignment(Qt::AlignCenter); m_label->setTextInteractionFlags(Qt::NoTextInteraction); // somehow, this makes word wrap work in the QLabel. yay. - //m_label->setMinimumWidth(100); + // m_label->setMinimumWidth(100); } QString LabeledToolButton::text() const @@ -65,7 +63,7 @@ QString LabeledToolButton::text() const return m_label->text(); } -void LabeledToolButton::setText(const QString & text) +void LabeledToolButton::setText(const QString& text) { m_label->setText(text); } @@ -76,7 +74,6 @@ void LabeledToolButton::setIcon(QIcon icon) resetIcon(); } - /*! \reimp */ @@ -92,24 +89,21 @@ QSize LabeledToolButton::sizeHint() const int w = 0, h = 0; QStyleOptionToolButton opt; initStyleOption(&opt); - QSize sz =m_label->sizeHint(); + QSize sz = m_label->sizeHint(); w = sz.width(); h = sz.height(); - opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height + opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height if (popupMode() == MenuButtonPopup) w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this); - + return style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this); } - - -void LabeledToolButton::resizeEvent(QResizeEvent * event) +void LabeledToolButton::resizeEvent(QResizeEvent* event) { - m_label->setGeometry(QRect(4, 4, width()-8, height()-8)); - if(!m_icon.isNull()) - { + m_label->setGeometry(QRect(4, 4, width() - 8, height() - 8)); + if (!m_icon.isNull()) { resetIcon(); } QWidget::resizeEvent(event); @@ -120,14 +114,14 @@ void LabeledToolButton::resetIcon() auto iconSz = m_icon.actualSize(QSize(160, 80)); float w = iconSz.width(); float h = iconSz.height(); - float ar = w/h; + float ar = w / h; // FIXME: hardcoded max size of 160x80 int newW = 80 * ar; - if(newW > 160) + if (newW > 160) newW = 160; - QSize newSz (newW, 80); + QSize newSz(newW, 80); auto pixmap = m_icon.pixmap(newSz); m_label->setPixmap(pixmap); m_label->setMinimumHeight(80); - m_label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); + m_label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); } diff --git a/launcher/ui/widgets/LabeledToolButton.h b/launcher/ui/widgets/LabeledToolButton.h index 51f99e9ba..0bb5e28de 100644 --- a/launcher/ui/widgets/LabeledToolButton.h +++ b/launcher/ui/widgets/LabeledToolButton.h @@ -20,21 +20,21 @@ class QLabel; -class LabeledToolButton : public QToolButton -{ +class LabeledToolButton : public QToolButton { Q_OBJECT - QLabel * m_label; + QLabel* m_label; QIcon m_icon; -public: - LabeledToolButton(QWidget * parent = 0); + public: + LabeledToolButton(QWidget* parent = 0); QString text() const; - void setText(const QString & text); + void setText(const QString& text); void setIcon(QIcon icon); virtual QSize sizeHint() const; -protected: - void resizeEvent(QResizeEvent * event); + + protected: + void resizeEvent(QResizeEvent* event); void resetIcon(); }; diff --git a/launcher/ui/widgets/LineSeparator.cpp b/launcher/ui/widgets/LineSeparator.cpp index d03e67623..2d6239a2f 100644 --- a/launcher/ui/widgets/LineSeparator.cpp +++ b/launcher/ui/widgets/LineSeparator.cpp @@ -1,11 +1,11 @@ #include "LineSeparator.h" -#include -#include #include #include +#include +#include -void LineSeparator::initStyleOption(QStyleOption *option) const +void LineSeparator::initStyleOption(QStyleOption* option) const { option->initFrom(this); // in a horizontal layout, the line is vertical (and vice versa) @@ -13,8 +13,7 @@ void LineSeparator::initStyleOption(QStyleOption *option) const option->state |= QStyle::State_Horizontal; } -LineSeparator::LineSeparator(QWidget *parent, Qt::Orientation orientation) - : QWidget(parent), m_orientation(orientation) +LineSeparator::LineSeparator(QWidget* parent, Qt::Orientation orientation) : QWidget(parent), m_orientation(orientation) { setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); } @@ -23,12 +22,11 @@ QSize LineSeparator::sizeHint() const { QStyleOption opt; initStyleOption(&opt); - const int extent = - style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget()); + const int extent = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget()); return QSize(extent, extent); } -void LineSeparator::paintEvent(QPaintEvent *) +void LineSeparator::paintEvent(QPaintEvent*) { QPainter p(this); QStyleOption opt; diff --git a/launcher/ui/widgets/LineSeparator.h b/launcher/ui/widgets/LineSeparator.h index 22927b68d..719facb99 100644 --- a/launcher/ui/widgets/LineSeparator.h +++ b/launcher/ui/widgets/LineSeparator.h @@ -3,16 +3,16 @@ class QStyleOption; -class LineSeparator : public QWidget -{ +class LineSeparator : public QWidget { Q_OBJECT -public: + public: /// Create a line separator. orientation is the orientation of the line. - explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Horizontal); + explicit LineSeparator(QWidget* parent, Qt::Orientation orientation = Qt::Horizontal); QSize sizeHint() const; - void paintEvent(QPaintEvent *); - void initStyleOption(QStyleOption *option) const; -private: + void paintEvent(QPaintEvent*); + void initStyleOption(QStyleOption* option) const; + + private: Qt::Orientation m_orientation = Qt::Horizontal; }; diff --git a/launcher/ui/widgets/LogView.cpp b/launcher/ui/widgets/LogView.cpp index 9c46438d6..8c960ebb1 100644 --- a/launcher/ui/widgets/LogView.cpp +++ b/launcher/ui/widgets/LogView.cpp @@ -34,8 +34,8 @@ */ #include "LogView.h" -#include #include +#include LogView::LogView(QWidget* parent) : QPlainTextEdit(parent) { @@ -50,13 +50,10 @@ LogView::~LogView() void LogView::setWordWrap(bool wrapping) { - if(wrapping) - { + if (wrapping) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setLineWrapMode(QPlainTextEdit::WidgetWidth); - } - else - { + } else { setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setLineWrapMode(QPlainTextEdit::NoWrap); } @@ -64,16 +61,14 @@ void LogView::setWordWrap(bool wrapping) void LogView::setModel(QAbstractItemModel* model) { - if(m_model) - { + if (m_model) { disconnect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate); disconnect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted); disconnect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted); disconnect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved); } m_model = model; - if(m_model) - { + if (m_model) { connect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate); connect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted); connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted); @@ -83,15 +78,14 @@ void LogView::setModel(QAbstractItemModel* model) repopulate(); } -QAbstractItemModel * LogView::model() const +QAbstractItemModel* LogView::model() const { return m_model; } void LogView::modelDestroyed(QObject* model) { - if(m_model == model) - { + if (m_model == model) { setModel(nullptr); } } @@ -100,8 +94,7 @@ void LogView::repopulate() { auto doc = document(); doc->clear(); - if(!m_model) - { + if (!m_model) { return; } rowsInserted(QModelIndex(), 0, m_model->rowCount() - 1); @@ -112,39 +105,32 @@ void LogView::rowsAboutToBeInserted(const QModelIndex& parent, int first, int la Q_UNUSED(parent) Q_UNUSED(first) Q_UNUSED(last) - QScrollBar *bar = verticalScrollBar(); + QScrollBar* bar = verticalScrollBar(); int max_bar = bar->maximum(); int val_bar = bar->value(); - if (m_scroll) - { + if (m_scroll) { m_scroll = (max_bar - val_bar) <= 1; - } - else - { + } else { m_scroll = val_bar == max_bar; } } void LogView::rowsInserted(const QModelIndex& parent, int first, int last) { - for(int i = first; i <= last; i++) - { + for (int i = first; i <= last; i++) { auto idx = m_model->index(i, 0, parent); auto text = m_model->data(idx, Qt::DisplayRole).toString(); QTextCharFormat format(*m_defaultFormat); auto font = m_model->data(idx, Qt::FontRole); - if(font.isValid()) - { + if (font.isValid()) { format.setFont(font.value()); } auto fg = m_model->data(idx, Qt::ForegroundRole); - if(fg.isValid()) - { + if (fg.isValid()) { format.setForeground(fg.value()); } auto bg = m_model->data(idx, Qt::BackgroundRole); - if(bg.isValid()) - { + if (bg.isValid()) { format.setBackground(bg.value()); } auto workCursor = textCursor(); @@ -152,10 +138,9 @@ void LogView::rowsInserted(const QModelIndex& parent, int first, int last) workCursor.insertText(text, format); workCursor.insertBlock(); } - if(m_scroll && !m_scrolling) - { + if (m_scroll && !m_scrolling) { m_scrolling = true; - QMetaObject::invokeMethod( this, "scrollToBottom", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "scrollToBottom", Qt::QueuedConnection); } } diff --git a/launcher/ui/widgets/LogView.h b/launcher/ui/widgets/LogView.h index 3143360aa..dde5f8f76 100644 --- a/launcher/ui/widgets/LogView.h +++ b/launcher/ui/widgets/LogView.h @@ -1,36 +1,35 @@ #pragma once -#include #include +#include class QAbstractItemModel; -class LogView: public QPlainTextEdit -{ +class LogView : public QPlainTextEdit { Q_OBJECT -public: - explicit LogView(QWidget *parent = nullptr); + public: + explicit LogView(QWidget* parent = nullptr); virtual ~LogView(); - virtual void setModel(QAbstractItemModel *model); - QAbstractItemModel *model() const; + virtual void setModel(QAbstractItemModel* model); + QAbstractItemModel* model() const; -public slots: + public slots: void setWordWrap(bool wrapping); - void findNext(const QString & what, bool reverse); + void findNext(const QString& what, bool reverse); void scrollToBottom(); -protected slots: + protected slots: void repopulate(); // note: this supports only appending - void rowsInserted(const QModelIndex &parent, int first, int last); - void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last); + void rowsInserted(const QModelIndex& parent, int first, int last); + void rowsAboutToBeInserted(const QModelIndex& parent, int first, int last); // note: this supports only removing from front - void rowsRemoved(const QModelIndex &parent, int first, int last); - void modelDestroyed(QObject * model); + void rowsRemoved(const QModelIndex& parent, int first, int last); + void modelDestroyed(QObject* model); -protected: - QAbstractItemModel *m_model = nullptr; - QTextCharFormat *m_defaultFormat = nullptr; + protected: + QAbstractItemModel* m_model = nullptr; + QTextCharFormat* m_defaultFormat = nullptr; bool m_scroll = false; bool m_scrolling = false; }; diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index ea052c41a..c2c099eeb 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -18,9 +18,8 @@ unique_qobject_ptr ModFilterWidget::create(Version default_vers auto task = filter_widget->versionList()->getLoadTask(); - connect(task.get(), &Task::failed, [filter_widget]{ - filter_widget->disableVersionButton(VersionButtonID::Major, tr("failed to get version index")); - }); + connect(task.get(), &Task::failed, + [filter_widget] { filter_widget->disableVersionButton(VersionButtonID::Major, tr("failed to get version index")); }); connect(task.get(), &Task::finished, &load_version_list_loop, &QEventLoop::quit); if (!task->isRunning()) @@ -34,16 +33,15 @@ unique_qobject_ptr ModFilterWidget::create(Version default_vers return unique_qobject_ptr(filter_widget); } -ModFilterWidget::ModFilterWidget(Version def, QWidget* parent) - : QTabWidget(parent), m_filter(new Filter()), ui(new Ui::ModFilterWidget) +ModFilterWidget::ModFilterWidget(Version def, QWidget* parent) : QTabWidget(parent), m_filter(new Filter()), ui(new Ui::ModFilterWidget) { ui->setupUi(this); - m_mcVersion_buttons.addButton(ui->strictVersionButton, VersionButtonID::Strict); + 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); + 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))); @@ -57,25 +55,19 @@ void ModFilterWidget::setInstance(MinecraftInstance* instance) { m_instance = instance; - ui->strictVersionButton->setText( - tr("Strict match (= %1)").arg(mcVersionStr())); + ui->strictVersionButton->setText(tr("Strict match (= %1)").arg(mcVersionStr())); // we can't do this for snapshots sadly - if(mcVersionStr().contains('.')) - { + 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 (= %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")); + ui->allVersionsButton->setText(tr("Any version")); + // ui->betweenVersionsButton->setText( + // tr("Between two versions")); } auto ModFilterWidget::getFilter() -> std::shared_ptr @@ -89,19 +81,19 @@ 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; + 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) { @@ -113,12 +105,12 @@ void ModFilterWidget::disableVersionButton(VersionButtonID id, QString reason) void ModFilterWidget::onVersionFilterChanged(int id) { - //ui->lowerVersionComboBox->setEnabled(id == VersionButtonID::Between); - //ui->upperVersionComboBox->setEnabled(id == VersionButtonID::Between); + // ui->lowerVersionComboBox->setEnabled(id == VersionButtonID::Between); + // ui->upperVersionComboBox->setEnabled(id == VersionButtonID::Between); int index = 1; - auto cast_id = (VersionButtonID) id; + auto cast_id = (VersionButtonID)id; if (cast_id != m_version_id) { m_version_id = cast_id; } else { @@ -127,32 +119,32 @@ void ModFilterWidget::onVersionFilterChanged(int id) m_filter->versions.clear(); - switch(cast_id){ - case(VersionButtonID::Strict): - m_filter->versions.push_front(mcVersion()); - break; - case(VersionButtonID::Major): { - auto versionSplit = mcVersionStr().split("."); + 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; + 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++)); + 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; } - - break; - } - case(VersionButtonID::All): - // Empty list to avoid enumerating all versions :P - break; - case(VersionButtonID::Between): - // TODO - break; + case (VersionButtonID::All): + // Empty list to avoid enumerating all versions :P + break; + case (VersionButtonID::Between): + // TODO + break; } - if(changed()) + if (changed()) emit filterChanged(); else emit filterUnchanged(); diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 706ffd21a..ed6cd0ea7 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include "Version.h" @@ -17,16 +17,10 @@ namespace Ui { class ModFilterWidget; } -class ModFilterWidget : public QTabWidget -{ +class ModFilterWidget : public QTabWidget { Q_OBJECT -public: - enum VersionButtonID { - Strict = 0, - Major = 1, - All = 2, - Between = 3 - }; + public: + enum VersionButtonID { Strict = 0, Major = 1, All = 2, Between = 3 }; struct Filter { std::list versions; @@ -37,7 +31,7 @@ public: std::shared_ptr m_filter; -public: + public: static unique_qobject_ptr create(Version default_version, QWidget* parent = nullptr); ~ModFilterWidget(); @@ -51,26 +45,29 @@ public: Meta::VersionList::Ptr versionList() { return m_version_list; } -private: + private: ModFilterWidget(Version def, QWidget* parent = nullptr); - inline auto mcVersionStr() const -> QString { return m_instance ? m_instance->getPackProfile()->getComponentVersion("net.minecraft") : ""; } + inline auto mcVersionStr() const -> QString + { + return m_instance ? m_instance->getPackProfile()->getComponentVersion("net.minecraft") : ""; + } inline auto mcVersion() const -> Version { return { mcVersionStr() }; } -private slots: + private slots: void onVersionFilterChanged(int id); -public: signals: + public: + signals: void filterChanged(); void filterUnchanged(); -private: + private: Ui::ModFilterWidget* ui; MinecraftInstance* m_instance = nullptr; - -/* Version stuff */ + /* Version stuff */ QButtonGroup m_mcVersion_buttons; Meta::VersionList::Ptr m_version_list; diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index 80a918b64..c72d4c522 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -14,61 +14,55 @@ */ #include "ModListView.h" +#include #include #include #include -#include #include -ModListView::ModListView ( QWidget* parent ) - :QTreeView ( parent ) +ModListView::ModListView(QWidget* parent) : QTreeView(parent) { - setAllColumnsShowFocus ( true ); - setExpandsOnDoubleClick ( false ); - setRootIsDecorated ( false ); - setSortingEnabled ( true ); - setAlternatingRowColors ( true ); - setSelectionMode ( QAbstractItemView::ExtendedSelection ); - setHeaderHidden ( false ); + setAllColumnsShowFocus(true); + setExpandsOnDoubleClick(false); + setRootIsDecorated(false); + setSortingEnabled(true); + setAlternatingRowColors(true); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setHeaderHidden(false); setSelectionBehavior(QAbstractItemView::SelectRows); - setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); + setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setDropIndicatorShown(true); setDragEnabled(true); setDragDropMode(QAbstractItemView::DropOnly); viewport()->setAcceptDrops(true); } -void ModListView::setModel ( QAbstractItemModel* model ) +void ModListView::setModel(QAbstractItemModel* model) { - QTreeView::setModel ( model ); + QTreeView::setModel(model); auto head = header(); head->setStretchLastSection(false); // HACK: this is true for the checkbox column of mod lists - auto string = model->headerData(0,head->orientation()).toString(); - if(head->count() < 1) - { + auto string = model->headerData(0, head->orientation()).toString(); + if (head->count() < 1) { return; } - if(!string.size()) - { + if (!string.size()) { head->setSectionResizeMode(0, QHeaderView::ResizeToContents); head->setSectionResizeMode(1, QHeaderView::Stretch); - for(int i = 2; i < head->count(); i++) + for (int i = 2; i < head->count(); i++) head->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } - else - { + } else { head->setSectionResizeMode(0, QHeaderView::Stretch); - for(int i = 1; i < head->count(); i++) + for (int i = 1; i < head->count(); i++) head->setSectionResizeMode(i, QHeaderView::ResizeToContents); } } -void ModListView::setResizeModes(const QList &modes) +void ModListView::setResizeModes(const QList& modes) { auto head = header(); - for(int i = 0; i < modes.count(); i++) { + for (int i = 0; i < modes.count(); i++) { head->setSectionResizeMode(i, modes[i]); } } - diff --git a/launcher/ui/widgets/ModListView.h b/launcher/ui/widgets/ModListView.h index 3f0b3b0e1..86316459f 100644 --- a/launcher/ui/widgets/ModListView.h +++ b/launcher/ui/widgets/ModListView.h @@ -17,11 +17,10 @@ #include #include -class ModListView: public QTreeView -{ +class ModListView : public QTreeView { Q_OBJECT -public: - explicit ModListView ( QWidget* parent = 0 ); - virtual void setModel ( QAbstractItemModel* model ); - virtual void setResizeModes (const QList& modes); + public: + explicit ModListView(QWidget* parent = 0); + virtual void setModel(QAbstractItemModel* model); + virtual void setResizeModes(const QList& modes); }; diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index b98c9796f..c3b70c447 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -38,36 +38,33 @@ #include "BuildConfig.h" #include "PageContainer_p.h" -#include -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "settings/SettingsObject.h" #include "ui/widgets/IconLabel.h" -#include "DesktopServices.h" #include "Application.h" +#include "DesktopServices.h" -class PageEntryFilterModel : public QSortFilterProxyModel -{ -public: - explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) - { - } +class PageEntryFilterModel : public QSortFilterProxyModel { + public: + explicit PageEntryFilterModel(QObject* parent = 0) : QSortFilterProxyModel(parent) {} -protected: - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const + protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { const QString pattern = filterRegularExpression().pattern(); - const auto model = static_cast(sourceModel()); + const auto model = static_cast(sourceModel()); const auto page = model->pages().at(sourceRow); if (!page->shouldDisplay()) return false; @@ -76,18 +73,15 @@ protected: } }; -PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, - QWidget *parent) - : QWidget(parent) +PageContainer::PageContainer(BasePageProvider* pageProvider, QString defaultId, QWidget* parent) : QWidget(parent) { createUI(); m_model = new PageModel(this); m_proxyModel = new PageEntryFilterModel(this); int counter = 0; auto pages = pageProvider->getPages(); - for (auto page : pages) - { - auto widget = dynamic_cast(page); + for (auto page : pages) { + auto widget = dynamic_cast(page); widget->setParent(this); page->stackIndex = m_pageStack->addWidget(widget); page->listIndex = counter; @@ -108,8 +102,7 @@ PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); m_pageList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); m_pageList->setModel(m_proxyModel); - connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), - this, SLOT(currentChanged(QModelIndex))); + connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex))); m_pageStack->setStackingMode(QStackedLayout::StackOne); m_pageList->setFocus(); selectPage(defaultId); @@ -120,16 +113,13 @@ bool PageContainer::selectPage(QString pageId) // now find what we want to have selected... auto page = m_model->findPageEntryById(pageId); QModelIndex index; - if (page) - { + if (page) { index = m_proxyModel->mapFromSource(m_model->index(page->listIndex)); } - if(!index.isValid()) - { + if (!index.isValid()) { index = m_proxyModel->index(0, 0); } - if (index.isValid()) - { + if (index.isValid()) { m_pageList->setCurrentIndex(index); return true; } @@ -149,15 +139,11 @@ const QList PageContainer::getPages() const void PageContainer::refreshContainer() { m_proxyModel->invalidate(); - if(!m_currentPage->shouldDisplay()) - { + if (!m_currentPage->shouldDisplay()) { auto index = m_proxyModel->index(0, 0); - if(index.isValid()) - { + if (index.isValid()) { m_pageList->setCurrentIndex(index); - } - else - { + } else { // FIXME: unhandled corner case: what to do when there's no page to select? } } @@ -177,7 +163,7 @@ void PageContainer::createUI() headerLabelFont.setPointSize(pointSize + 2); m_header->setFont(headerLabelFont); - QHBoxLayout *headerHLayout = new QHBoxLayout; + QHBoxLayout* headerHLayout = new QHBoxLayout; const int leftMargin = APPLICATION->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); headerHLayout->addWidget(m_header); @@ -195,7 +181,7 @@ void PageContainer::createUI() m_layout->addWidget(m_pageList, 0, 0, 2, 1); m_layout->addLayout(m_pageStack, 1, 1, 1, 1); m_layout->setColumnStretch(1, 4); - m_layout->setContentsMargins(0,0,0,6); + m_layout->setContentsMargins(0, 0, 0, 6); setLayout(m_layout); } @@ -208,39 +194,32 @@ void PageContainer::retranslate() page->retranslate(); } -void PageContainer::addButtons(QWidget *buttons) +void PageContainer::addButtons(QWidget* buttons) { m_layout->addWidget(buttons, 2, 0, 1, 2); } -void PageContainer::addButtons(QLayout *buttons) +void PageContainer::addButtons(QLayout* buttons) { m_layout->addLayout(buttons, 2, 0, 1, 2); } void PageContainer::showPage(int row) { - if (m_currentPage) - { + if (m_currentPage) { m_currentPage->closed(); } - if (row != -1) - { + if (row != -1) { m_currentPage = m_model->pages().at(row); - } - else - { + } else { m_currentPage = nullptr; } - if (m_currentPage) - { + if (m_currentPage) { m_pageStack->setCurrentIndex(m_currentPage->stackIndex); m_header->setText(m_currentPage->displayName()); m_iconHeader->setIcon(m_currentPage->icon()); m_currentPage->opened(); - } - else - { + } else { m_pageStack->setCurrentIndex(0); m_header->setText(QString()); m_iconHeader->setIcon(APPLICATION->getThemedIcon("bug")); @@ -249,8 +228,7 @@ void PageContainer::showPage(int row) void PageContainer::help() { - if (m_currentPage) - { + if (m_currentPage) { QString pageId = m_currentPage->helpPage(); if (pageId.isEmpty()) return; @@ -258,7 +236,7 @@ void PageContainer::help() } } -void PageContainer::currentChanged(const QModelIndex ¤t) +void PageContainer::currentChanged(const QModelIndex& current) { int selected_index = current.isValid() ? m_proxyModel->mapToSource(current).row() : -1; @@ -272,12 +250,10 @@ void PageContainer::currentChanged(const QModelIndex ¤t) bool PageContainer::prepareToClose() { - if(!saveAll()) - { + if (!saveAll()) { return false; } - if (m_currentPage) - { + if (m_currentPage) { m_currentPage->closed(); } return true; @@ -285,8 +261,7 @@ bool PageContainer::prepareToClose() bool PageContainer::saveAll() { - for (auto page : m_model->pages()) - { + for (auto page : m_model->pages()) { if (!page->apply()) return false; } diff --git a/launcher/ui/widgets/PageContainer.h b/launcher/ui/widgets/PageContainer.h index ad74d43a2..f5978dbaa 100644 --- a/launcher/ui/widgets/PageContainer.h +++ b/launcher/ui/widgets/PageContainer.h @@ -35,11 +35,11 @@ #pragma once -#include #include +#include -#include "ui/pages/BasePageProvider.h" #include "ui/pages/BasePageContainer.h" +#include "ui/pages/BasePageProvider.h" class QLayout; class IconLabel; @@ -51,16 +51,14 @@ class QLineEdit; class QStackedLayout; class QGridLayout; -class PageContainer : public QWidget, public BasePageContainer -{ +class PageContainer : public QWidget, public BasePageContainer { Q_OBJECT -public: - explicit PageContainer(BasePageProvider *pageProvider, QString defaultId = QString(), - QWidget *parent = 0); + public: + explicit PageContainer(BasePageProvider* pageProvider, QString defaultId = QString(), QWidget* parent = 0); virtual ~PageContainer() {} - void addButtons(QWidget * buttons); - void addButtons(QLayout * buttons); + void addButtons(QWidget* buttons); + void addButtons(QLayout* buttons); /* * Save any unsaved state and prepare to be closed. * @return true if everything can be saved, false if there is something that requires attention @@ -71,8 +69,7 @@ public: /* request close - used by individual pages */ bool requestClose() override { - if(m_container) - { + if (m_container) { return m_container->requestClose(); } return false; @@ -83,36 +80,33 @@ public: const QList getPages() const; void refreshContainer() override; - virtual void setParentContainer(BasePageContainer * container) - { - m_container = container; - }; + virtual void setParentContainer(BasePageContainer* container) { m_container = container; }; void changeEvent(QEvent*) override; -private: + private: void createUI(); void retranslate(); -public slots: + public slots: void help(); -signals: + signals: /** Emitted when the currently selected page is changed */ void selectedPageChanged(BasePage* previous, BasePage* selected); -private slots: - void currentChanged(const QModelIndex ¤t); + private slots: + void currentChanged(const QModelIndex& current); void showPage(int row); -private: - BasePageContainer * m_container = nullptr; - BasePage * m_currentPage = 0; - QSortFilterProxyModel *m_proxyModel; - PageModel *m_model; - QStackedLayout *m_pageStack; - QListView *m_pageList; - QLabel *m_header; - IconLabel *m_iconHeader; - QGridLayout *m_layout; + private: + BasePageContainer* m_container = nullptr; + BasePage* m_currentPage = 0; + QSortFilterProxyModel* m_proxyModel; + PageModel* m_model; + QStackedLayout* m_pageStack; + QListView* m_pageList; + QLabel* m_header; + IconLabel* m_iconHeader; + QGridLayout* m_layout; }; diff --git a/launcher/ui/widgets/PageContainer_p.h b/launcher/ui/widgets/PageContainer_p.h index da1a66f46..9a7651c75 100644 --- a/launcher/ui/widgets/PageContainer_p.h +++ b/launcher/ui/widgets/PageContainer_p.h @@ -15,21 +15,18 @@ #pragma once -#include -#include #include +#include #include +#include class BasePage; const int pageIconSize = 24; -class PageViewDelegate : public QStyledItemDelegate -{ -public: - PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent) - { - } - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +class PageViewDelegate : public QStyledItemDelegate { + public: + PageViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {} + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); size.setHeight(qMax(size.height(), 32)); @@ -37,10 +34,9 @@ public: } }; -class PageModel : public QAbstractListModel -{ -public: - PageModel(QObject *parent = 0) : QAbstractListModel(parent) +class PageModel : public QAbstractListModel { + public: + PageModel(QObject* parent = 0) : QAbstractListModel(parent) { QPixmap empty(pageIconSize, pageIconSize); empty.fill(Qt::transparent); @@ -48,57 +44,47 @@ public: } virtual ~PageModel() {} - int rowCount(const QModelIndex &parent = QModelIndex()) const + int rowCount(const QModelIndex& parent = QModelIndex()) const { return parent.isValid() ? 0 : m_pages.size(); } + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const { - return parent.isValid() ? 0 : m_pages.size(); - } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const - { - switch (role) - { - case Qt::DisplayRole: - return m_pages.at(index.row())->displayName(); - case Qt::DecorationRole: - { - QIcon icon = m_pages.at(index.row())->icon(); - if (icon.isNull()) - icon = m_emptyIcon; - // HACK: fixes icon stretching on windows. TODO: report Qt bug for this - return QIcon(icon.pixmap(QSize(48,48))); - } + switch (role) { + case Qt::DisplayRole: + return m_pages.at(index.row())->displayName(); + case Qt::DecorationRole: { + QIcon icon = m_pages.at(index.row())->icon(); + if (icon.isNull()) + icon = m_emptyIcon; + // HACK: fixes icon stretching on windows. TODO: report Qt bug for this + return QIcon(icon.pixmap(QSize(48, 48))); + } } return QVariant(); } - void setPages(const QList &pages) + void setPages(const QList& pages) { beginResetModel(); m_pages = pages; endResetModel(); } - const QList &pages() const - { - return m_pages; - } + const QList& pages() const { return m_pages; } - BasePage * findPageEntryById(QString id) + BasePage* findPageEntryById(QString id) { - for(auto page: m_pages) - { + for (auto page : m_pages) { if (page->id() == id) return page; } return nullptr; } - QList m_pages; + QList m_pages; QIcon m_emptyIcon; }; -class PageView : public QListView -{ -public: - PageView(QWidget *parent = 0) : QListView(parent) +class PageView : public QListView { + public: + PageView(QWidget* parent = 0) : QListView(parent) { setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); setItemDelegate(new PageViewDelegate(this)); @@ -113,10 +99,9 @@ public: return QSize(width, 100); } - virtual bool eventFilter(QObject *obj, QEvent *event) + virtual bool eventFilter(QObject* obj, QEvent* event) { - if (obj == verticalScrollBar() && - (event->type() == QEvent::Show || event->type() == QEvent::Hide)) + if (obj == verticalScrollBar() && (event->type() == QEvent::Show || event->type() == QEvent::Hide)) updateGeometry(); return QListView::eventFilter(obj, event); } diff --git a/launcher/ui/widgets/ProjectItem.cpp b/launcher/ui/widgets/ProjectItem.cpp index 0085d6b2b..1481c1b6b 100644 --- a/launcher/ui/widgets/ProjectItem.cpp +++ b/launcher/ui/widgets/ProjectItem.cpp @@ -116,7 +116,6 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o } int description_x = rect.x(); - // Have the y-value be set based on the number of lines in the description, to centralize the // description text with the space between the base and the title. @@ -127,8 +126,8 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o description_y -= opt.fontMetrics.height(); // On the bottom, aligned to the left after the icon, and featuring at most two lines of text (with some margin space to spare) - painter->drawText(description_x, description_y, remaining_width, - cut_text.size() * opt.fontMetrics.height(), Qt::TextWordWrap, description); + painter->drawText(description_x, description_y, remaining_width, cut_text.size() * opt.fontMetrics.height(), Qt::TextWordWrap, + description); } painter->restore(); diff --git a/launcher/ui/widgets/ProjectItem.h b/launcher/ui/widgets/ProjectItem.h index 196055ea4..c3d0dce70 100644 --- a/launcher/ui/widgets/ProjectItem.h +++ b/launcher/ui/widgets/ProjectItem.h @@ -18,9 +18,8 @@ enum UserDataTypes { class ProjectItemDelegate final : public QStyledItemDelegate { Q_OBJECT - public: - ProjectItemDelegate(QWidget* parent); - - void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const override; + public: + ProjectItemDelegate(QWidget* parent); + void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const override; }; diff --git a/launcher/ui/widgets/SubTaskProgressBar.cpp b/launcher/ui/widgets/SubTaskProgressBar.cpp index 84ea5f207..391021977 100644 --- a/launcher/ui/widgets/SubTaskProgressBar.cpp +++ b/launcher/ui/widgets/SubTaskProgressBar.cpp @@ -26,12 +26,11 @@ unique_qobject_ptr SubTaskProgressBar::create(QWidget* paren return unique_qobject_ptr(progress_bar); } -SubTaskProgressBar::SubTaskProgressBar(QWidget* parent) - : ui(new Ui::SubTaskProgressBar) +SubTaskProgressBar::SubTaskProgressBar(QWidget* parent) : ui(new Ui::SubTaskProgressBar) { ui->setupUi(this); } -SubTaskProgressBar::~SubTaskProgressBar() +SubTaskProgressBar::~SubTaskProgressBar() { delete ui; } @@ -55,4 +54,3 @@ void SubTaskProgressBar::setDetails(QString details) { ui->statusDetailsLabel->setText(details); } - diff --git a/launcher/ui/widgets/SubTaskProgressBar.h b/launcher/ui/widgets/SubTaskProgressBar.h index 8f8aeea2a..cd08809f1 100644 --- a/launcher/ui/widgets/SubTaskProgressBar.h +++ b/launcher/ui/widgets/SubTaskProgressBar.h @@ -25,11 +25,10 @@ namespace Ui { class SubTaskProgressBar; } -class SubTaskProgressBar : public QWidget -{ +class SubTaskProgressBar : public QWidget { Q_OBJECT -public: + public: static unique_qobject_ptr create(QWidget* parent = nullptr); SubTaskProgressBar(QWidget* parent = nullptr); @@ -40,9 +39,6 @@ public: void setStatus(QString status); void setDetails(QString details); - - -private: + private: Ui::SubTaskProgressBar* ui; - }; diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp index 291f8ed9e..d26906bd3 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp @@ -22,13 +22,14 @@ #include "ui/themes/ITheme.h" #include "ui/themes/ThemeManager.h" -ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget) +ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget* parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget) { ui->setupUi(this); loadSettings(); connect(ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme); - connect(ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyWidgetTheme); + connect(ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, + &ThemeCustomizationWidget::applyWidgetTheme); connect(ui->backgroundCatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme); } @@ -40,7 +41,7 @@ ThemeCustomizationWidget::~ThemeCustomizationWidget() /// /// The layout was not quite right, so currently this just disables the UI elements, which should be hidden instead /// TODO FIXME -/// +/// /// Original Method One: /// ui->iconsComboBox->setVisible(features& ThemeFields::ICONS); /// ui->iconsLabel->setVisible(features& ThemeFields::ICONS); @@ -48,7 +49,7 @@ ThemeCustomizationWidget::~ThemeCustomizationWidget() /// ui->widgetThemeLabel->setVisible(features& ThemeFields::WIDGETS); /// ui->backgroundCatComboBox->setVisible(features& ThemeFields::CAT); /// ui->backgroundCatLabel->setVisible(features& ThemeFields::CAT); -/// +/// /// original Method Two: /// if (!(features & ThemeFields::ICONS)) { /// ui->formLayout->setRowVisible(0, false); @@ -61,7 +62,8 @@ ThemeCustomizationWidget::~ThemeCustomizationWidget() /// } /// /// -void ThemeCustomizationWidget::showFeatures(ThemeFields features) { +void ThemeCustomizationWidget::showFeatures(ThemeFields features) +{ ui->iconsComboBox->setEnabled(features & ThemeFields::ICONS); ui->iconsLabel->setEnabled(features & ThemeFields::ICONS); ui->widgetStyleComboBox->setEnabled(features & ThemeFields::WIDGETS); @@ -70,7 +72,8 @@ void ThemeCustomizationWidget::showFeatures(ThemeFields features) { ui->backgroundCatLabel->setEnabled(features & ThemeFields::CAT); } -void ThemeCustomizationWidget::applyIconTheme(int index) { +void ThemeCustomizationWidget::applyIconTheme(int index) +{ auto settings = APPLICATION->settings(); auto originalIconTheme = settings->get("IconTheme").toString(); auto& newIconTheme = m_iconThemeOptions[index].first; @@ -83,7 +86,8 @@ void ThemeCustomizationWidget::applyIconTheme(int index) { emit currentIconThemeChanged(index); } -void ThemeCustomizationWidget::applyWidgetTheme(int index) { +void ThemeCustomizationWidget::applyWidgetTheme(int index) +{ auto settings = APPLICATION->settings(); auto originalAppTheme = settings->get("ApplicationTheme").toString(); auto newAppTheme = ui->widgetStyleComboBox->currentData().toString(); diff --git a/launcher/ui/widgets/VersionListView.cpp b/launcher/ui/widgets/VersionListView.cpp index 06e58d221..7701d1271 100644 --- a/launcher/ui/widgets/VersionListView.cpp +++ b/launcher/ui/widgets/VersionListView.cpp @@ -34,35 +34,33 @@ * limitations under the License. */ -#include -#include -#include -#include -#include #include "VersionListView.h" +#include +#include +#include +#include +#include -VersionListView::VersionListView(QWidget *parent) - :QTreeView ( parent ) +VersionListView::VersionListView(QWidget* parent) : QTreeView(parent) { m_emptyString = tr("No versions are currently available."); } -void VersionListView::rowsInserted(const QModelIndex &parent, int start, int end) +void VersionListView::rowsInserted(const QModelIndex& parent, int start, int end) { - m_itemCount += end-start+1; + m_itemCount += end - start + 1; updateEmptyViewPort(); QTreeView::rowsInserted(parent, start, end); } - -void VersionListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +void VersionListView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - m_itemCount -= end-start+1; + m_itemCount -= end - start + 1; updateEmptyViewPort(); QTreeView::rowsInserted(parent, start, end); } -void VersionListView::setModel(QAbstractItemModel *model) +void VersionListView::setModel(QAbstractItemModel* model) { m_itemCount = model->rowCount(); updateEmptyViewPort(); @@ -71,11 +69,9 @@ void VersionListView::setModel(QAbstractItemModel *model) void VersionListView::reset() { - if(model()) - { + if (model()) { m_itemCount = model()->rowCount(); - } - else { + } else { m_itemCount = 0; } updateEmptyViewPort(); @@ -106,28 +102,23 @@ void VersionListView::updateEmptyViewPort() setAccessibleDescription(currentEmptyString()); #endif /* !QT_NO_ACCESSIBILITY */ - if(!m_itemCount) - { + if (!m_itemCount) { viewport()->update(); } } -void VersionListView::paintEvent(QPaintEvent *event) +void VersionListView::paintEvent(QPaintEvent* event) { - if(m_itemCount) - { + if (m_itemCount) { QTreeView::paintEvent(event); - } - else - { + } else { paintInfoLabel(event); } } QString VersionListView::currentEmptyString() const { - switch(m_emptyMode) - { + switch (m_emptyMode) { default: case VersionListView::String: return m_emptyString; @@ -136,12 +127,11 @@ QString VersionListView::currentEmptyString() const } } - -void VersionListView::paintInfoLabel(QPaintEvent *event) const +void VersionListView::paintInfoLabel(QPaintEvent* event) const { QString emptyString = currentEmptyString(); - //calculate the rect for the overlay + // calculate the rect for the overlay QPainter painter(viewport()); painter.setRenderHint(QPainter::Antialiasing, true); QFont font("sans", 20); @@ -163,7 +153,7 @@ void VersionListView::paintInfoLabel(QPaintEvent *event) const auto wrapRect = textRect; wrapRect.adjust(-10, -10, 10, 10); - //check if we are allowed to draw in our area + // check if we are allowed to draw in our area if (!event->rect().intersects(wrapRect)) { return; } diff --git a/launcher/ui/widgets/VersionListView.h b/launcher/ui/widgets/VersionListView.h index 4153b314a..07792db52 100644 --- a/launcher/ui/widgets/VersionListView.h +++ b/launcher/ui/widgets/VersionListView.h @@ -16,39 +16,32 @@ #pragma once #include -class VersionListView : public QTreeView -{ +class VersionListView : public QTreeView { Q_OBJECT -public: - - explicit VersionListView(QWidget *parent = 0); - virtual void paintEvent(QPaintEvent *event) override; + public: + explicit VersionListView(QWidget* parent = 0); + virtual void paintEvent(QPaintEvent* event) override; virtual void setModel(QAbstractItemModel* model) override; - enum EmptyMode - { - Empty, - String, - ErrorString - }; + enum EmptyMode { Empty, String, ErrorString }; void setEmptyString(QString emptyString); void setEmptyErrorString(QString emptyErrorString); void setEmptyMode(EmptyMode mode); -public slots: + public slots: virtual void reset() override; -protected slots: - virtual void rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) override; - virtual void rowsInserted(const QModelIndex &parent, int start, int end) override; + protected slots: + virtual void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; + virtual void rowsInserted(const QModelIndex& parent, int start, int end) override; -private: /* methods */ - void paintInfoLabel(QPaintEvent *event) const; + private: /* methods */ + void paintInfoLabel(QPaintEvent* event) const; void updateEmptyViewPort(); QString currentEmptyString() const; -private: /* variables */ + private: /* variables */ int m_itemCount = 0; QString m_emptyString; QString m_emptyErrorString; diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp index a956ddb3c..9647dc799 100644 --- a/launcher/ui/widgets/VersionSelectWidget.cpp +++ b/launcher/ui/widgets/VersionSelectWidget.cpp @@ -13,8 +13,7 @@ VersionSelectWidget::VersionSelectWidget(QWidget* parent) : VersionSelectWidget(false, parent) {} -VersionSelectWidget::VersionSelectWidget(bool focusSearch, QWidget* parent) - : QWidget(parent), focusSearch(focusSearch) +VersionSelectWidget::VersionSelectWidget(bool focusSearch, QWidget* parent) : QWidget(parent), focusSearch(focusSearch) { setObjectName(QStringLiteral("VersionSelectWidget")); verticalLayout = new QVBoxLayout(this); @@ -81,9 +80,7 @@ void VersionSelectWidget::setEmptyMode(VersionListView::EmptyMode mode) listView->setEmptyMode(mode); } -VersionSelectWidget::~VersionSelectWidget() -{ -} +VersionSelectWidget::~VersionSelectWidget() {} void VersionSelectWidget::setResizeOn(int column) { @@ -92,7 +89,8 @@ void VersionSelectWidget::setResizeOn(int column) listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); } -bool VersionSelectWidget::eventFilter(QObject *watched, QEvent *event) { +bool VersionSelectWidget::eventFilter(QObject* watched, QEvent* event) +{ if (watched == search && event->type() == QEvent::KeyPress) { const QKeyEvent* keyEvent = (QKeyEvent*)event; const bool up = keyEvent->key() == Qt::Key_Up; @@ -109,7 +107,7 @@ bool VersionSelectWidget::eventFilter(QObject *watched, QEvent *event) { return QObject::eventFilter(watched, event); } -void VersionSelectWidget::initialize(BaseVersionList *vlist) +void VersionSelectWidget::initialize(BaseVersionList* vlist) { m_vlist = vlist; m_proxyModel->setSourceModel(vlist); @@ -119,21 +117,17 @@ void VersionSelectWidget::initialize(BaseVersionList *vlist) if (focusSearch) search->setFocus(); - if (!m_vlist->isLoaded()) - { + if (!m_vlist->isLoaded()) { loadList(); - } - else - { - if (m_proxyModel->rowCount() == 0) - { + } else { + if (m_proxyModel->rowCount() == 0) { listView->setEmptyMode(VersionListView::String); } preselect(); } } -void VersionSelectWidget::closeEvent(QCloseEvent * event) +void VersionSelectWidget::closeEvent(QCloseEvent* event) { QWidget::closeEvent(event); } @@ -141,16 +135,14 @@ void VersionSelectWidget::closeEvent(QCloseEvent * event) void VersionSelectWidget::loadList() { auto newTask = m_vlist->getLoadTask(); - if (!newTask) - { + if (!newTask) { return; } loadTask = newTask.get(); connect(loadTask, &Task::succeeded, this, &VersionSelectWidget::onTaskSucceeded); connect(loadTask, &Task::failed, this, &VersionSelectWidget::onTaskFailed); connect(loadTask, &Task::progress, this, &VersionSelectWidget::changeProgress); - if(!loadTask->isRunning()) - { + if (!loadTask->isRunning()) { loadTask->start(); } sneakyProgressBar->setHidden(false); @@ -158,8 +150,7 @@ void VersionSelectWidget::loadList() void VersionSelectWidget::onTaskSucceeded() { - if (m_proxyModel->rowCount() == 0) - { + if (m_proxyModel->rowCount() == 0) { listView->setEmptyMode(VersionListView::String); } sneakyProgressBar->setHidden(true); @@ -187,25 +178,23 @@ void VersionSelectWidget::currentRowChanged(const QModelIndex& current, const QM void VersionSelectWidget::preselect() { - if(preselectedAlready) + if (preselectedAlready) return; selectCurrent(); - if(preselectedAlready) + if (preselectedAlready) return; selectRecommended(); } void VersionSelectWidget::selectCurrent() { - if(m_currentVersion.isEmpty()) - { + if (m_currentVersion.isEmpty()) { return; } auto idx = m_proxyModel->getVersion(m_currentVersion); - if(idx.isValid()) - { + if (idx.isValid()) { preselectedAlready = true; - listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + listView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); } } @@ -213,10 +202,9 @@ void VersionSelectWidget::selectCurrent() void VersionSelectWidget::selectRecommended() { auto idx = m_proxyModel->getRecommended(); - if(idx.isValid()) - { + if (idx.isValid()) { preselectedAlready = true; - listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + listView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); } } @@ -243,7 +231,7 @@ void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QStri m_proxyModel->setFilter(role, new ContainsFilter(filter)); } -void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter *filter) +void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter* filter) { m_proxyModel->setFilter(role, filter); } diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h index be4ba768d..b7f401019 100644 --- a/launcher/ui/widgets/VersionSelectWidget.h +++ b/launcher/ui/widgets/VersionSelectWidget.h @@ -35,9 +35,9 @@ #pragma once -#include -#include #include +#include +#include #include "BaseVersionList.h" #include "VersionListView.h" @@ -47,16 +47,15 @@ class QVBoxLayout; class QProgressBar; class Filter; -class VersionSelectWidget: public QWidget -{ +class VersionSelectWidget : public QWidget { Q_OBJECT -public: - explicit VersionSelectWidget(QWidget *parent); - explicit VersionSelectWidget(bool focusSearch = false, QWidget *parent = 0); + public: + explicit VersionSelectWidget(QWidget* parent); + explicit VersionSelectWidget(bool focusSearch = false, QWidget* parent = 0); ~VersionSelectWidget(); //! loads the list if needed. - void initialize(BaseVersionList *vlist); + void initialize(BaseVersionList* vlist); //! Starts a task that loads the list. void loadList(); @@ -66,42 +65,42 @@ public: void selectRecommended(); void selectCurrent(); - void setCurrentVersion(const QString & version); + void setCurrentVersion(const QString& version); void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); void setExactFilter(BaseVersionList::ModelRoles role, QString filter); - void setFilter(BaseVersionList::ModelRoles role, Filter *filter); + void setFilter(BaseVersionList::ModelRoles role, Filter* filter); void setEmptyString(QString emptyString); void setEmptyErrorString(QString emptyErrorString); void setEmptyMode(VersionListView::EmptyMode mode); void setResizeOn(int column); bool eventFilter(QObject* watched, QEvent* event) override; -signals: + signals: void selectedVersionChanged(BaseVersion::Ptr version); -protected: - virtual void closeEvent ( QCloseEvent* ); + protected: + virtual void closeEvent(QCloseEvent*); -private slots: + private slots: void onTaskSucceeded(); - void onTaskFailed(const QString &reason); + void onTaskFailed(const QString& reason); void changeProgress(qint64 current, qint64 total); - void currentRowChanged(const QModelIndex ¤t, const QModelIndex &); + void currentRowChanged(const QModelIndex& current, const QModelIndex&); -private: + private: void preselect(); -private: + private: QString m_currentVersion; - BaseVersionList *m_vlist = nullptr; - VersionProxyModel *m_proxyModel = nullptr; + BaseVersionList* m_vlist = nullptr; + VersionProxyModel* m_proxyModel = nullptr; int resizeOnColumn = 0; - Task * loadTask; + Task* loadTask; bool preselectedAlready = false; bool focusSearch; - QVBoxLayout *verticalLayout = nullptr; - VersionListView *listView = nullptr; - QLineEdit *search; - QProgressBar *sneakyProgressBar = nullptr; + QVBoxLayout* verticalLayout = nullptr; + VersionListView* listView = nullptr; + QLineEdit* search; + QProgressBar* sneakyProgressBar = nullptr; }; diff --git a/launcher/ui/widgets/WideBar.cpp b/launcher/ui/widgets/WideBar.cpp index a77c45fee..b793d84f5 100644 --- a/launcher/ui/widgets/WideBar.cpp +++ b/launcher/ui/widgets/WideBar.cpp @@ -7,8 +7,8 @@ class ActionButton : public QToolButton { Q_OBJECT public: - ActionButton(QAction* action, QWidget* parent = nullptr, bool use_default_action = false) : QToolButton(parent), - m_action(action), m_use_default_action(use_default_action) + ActionButton(QAction* action, QWidget* parent = nullptr, bool use_default_action = false) + : QToolButton(parent), m_action(action), m_use_default_action(use_default_action) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -227,7 +227,7 @@ void WideBar::showVisibilityMenu(QPoint const& position) act->setCheckable(true); act->setChecked(entry.bar_action->isVisible()); - connect(act, &QAction::toggled, entry.bar_action, [this, &entry](bool toggled){ + connect(act, &QAction::toggled, entry.bar_action, [this, &entry](bool toggled) { entry.bar_action->setVisible(toggled); // NOTE: This is needed so that disabled actions get reflected on the button when it is made visible. @@ -243,7 +243,8 @@ void WideBar::showVisibilityMenu(QPoint const& position) m_bar_menu->popup(mapToGlobal(position)); } -void WideBar::addContextMenuAction(QAction* action) { +void WideBar::addContextMenuAction(QAction* action) +{ m_context_menu_actions.append(action); } @@ -306,5 +307,4 @@ bool WideBar::checkHash(QByteArray const& old_hash) const return old_hash == getHash(); } - #include "WideBar.moc" diff --git a/launcher/updater/ExternalUpdater.h b/launcher/updater/ExternalUpdater.h index a053e081f..6c0803a7e 100644 --- a/launcher/updater/ExternalUpdater.h +++ b/launcher/updater/ExternalUpdater.h @@ -31,11 +31,10 @@ * The initializer of the new class should have the side effect of starting the automatic updater. That is, * once the class is initialized, the program should automatically check for updates if necessary. */ -class ExternalUpdater : public QObject -{ +class ExternalUpdater : public QObject { Q_OBJECT -public: + public: /*! * Check for updates manually, showing the user a progress bar and an alert if no updates are found. */ @@ -71,7 +70,7 @@ public: */ virtual void setBetaAllowed(bool allowed) = 0; -signals: + signals: /*! * Emits whenever the user's ability to check for updates changes. * @@ -84,4 +83,4 @@ signals: void canCheckForUpdatesChanged(bool canCheck); }; -#endif //LAUNCHER_EXTERNALUPDATER_H +#endif // LAUNCHER_EXTERNALUPDATER_H diff --git a/launcher/updater/MacSparkleUpdater.h b/launcher/updater/MacSparkleUpdater.h index cee19f7c7..3f6b5f4ad 100644 --- a/launcher/updater/MacSparkleUpdater.h +++ b/launcher/updater/MacSparkleUpdater.h @@ -26,11 +26,10 @@ /*! * An implementation for the updater on macOS that uses the Sparkle framework. */ -class MacSparkleUpdater : public ExternalUpdater -{ +class MacSparkleUpdater : public ExternalUpdater { Q_OBJECT -public: + public: /*! * Start the Sparkle updater, which automatically checks for updates if necessary. */ @@ -115,10 +114,10 @@ public: */ void setBetaAllowed(bool allowed) override; -private: + private: class Private; - Private *priv; + Private* priv; }; -#endif //LAUNCHER_MACSPARKLEUPDATER_H +#endif // LAUNCHER_MACSPARKLEUPDATER_H diff --git a/launcher/updater/MacSparkleUpdater.mm b/launcher/updater/MacSparkleUpdater.mm index 07337176d..1c1f5cd27 100644 --- a/launcher/updater/MacSparkleUpdater.mm +++ b/launcher/updater/MacSparkleUpdater.mm @@ -28,7 +28,7 @@ @property(nonatomic, readonly) SPUUpdater* updater; /// A callback to run when the state of `canCheckForUpdates` for the `updater` changes. -@property(nonatomic, copy) void (^callback) (bool); +@property(nonatomic, copy) void (^callback)(bool); - (id)initWithUpdater:(SPUUpdater*)updater; @@ -36,8 +36,7 @@ @implementation UpdaterObserver -- (id)initWithUpdater:(SPUUpdater*)updater -{ +- (id)initWithUpdater:(SPUUpdater*)updater { self = [super init]; _updater = updater; [self addObserver:self forKeyPath:@"updater.canCheckForUpdates" options:NSKeyValueObservingOptionNew context:nil]; @@ -45,13 +44,11 @@ return self; } -- (void)observeValueForKeyPath:(NSString *)keyPath +- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context -{ - if ([keyPath isEqualToString:@"updater.canCheckForUpdates"]) - { + change:(NSDictionary*)change + context:(void*)context { + if ([keyPath isEqualToString:@"updater.canCheckForUpdates"]) { bool canCheck = [change[NSKeyValueChangeNewKey] boolValue]; self.callback(canCheck); } @@ -59,34 +56,29 @@ @end - @interface UpdaterDelegate : NSObject -@property(nonatomic, copy) NSSet *allowedChannels; +@property(nonatomic, copy) NSSet* allowedChannels; @end @implementation UpdaterDelegate -- (NSSet *)allowedChannelsForUpdater:(SPUUpdater *)updater -{ +- (NSSet*)allowedChannelsForUpdater:(SPUUpdater*)updater { return _allowedChannels; } @end - -class MacSparkleUpdater::Private -{ -public: - SPUStandardUpdaterController *updaterController; - UpdaterObserver *updaterObserver; - UpdaterDelegate *updaterDelegate; - NSAutoreleasePool *autoReleasePool; +class MacSparkleUpdater::Private { + public: + SPUStandardUpdaterController* updaterController; + UpdaterObserver* updaterObserver; + UpdaterDelegate* updaterDelegate; + NSAutoreleasePool* autoReleasePool; }; -MacSparkleUpdater::MacSparkleUpdater() -{ +MacSparkleUpdater::MacSparkleUpdater() { priv = new MacSparkleUpdater::Private(); // Enable Cocoa's memory management. @@ -98,18 +90,17 @@ MacSparkleUpdater::MacSparkleUpdater() // Controller is the interface for actually doing the updates. priv->updaterController = [[SPUStandardUpdaterController alloc] initWithStartingUpdater:true - updaterDelegate:priv->updaterDelegate - userDriverDelegate:nil]; + updaterDelegate:priv->updaterDelegate + userDriverDelegate:nil]; priv->updaterObserver = [[UpdaterObserver alloc] initWithUpdater:priv->updaterController.updater]; // Use KVO to run a callback that emits a Qt signal when `canCheckForUpdates` changes, so the UI can respond accordingly. priv->updaterObserver.callback = ^(bool canCheck) { - emit canCheckForUpdatesChanged(canCheck); + emit canCheckForUpdatesChanged(canCheck); }; } -MacSparkleUpdater::~MacSparkleUpdater() -{ +MacSparkleUpdater::~MacSparkleUpdater() { [priv->updaterObserver removeObserver:priv->updaterObserver forKeyPath:@"updater.canCheckForUpdates"]; [priv->updaterController release]; @@ -119,77 +110,63 @@ MacSparkleUpdater::~MacSparkleUpdater() delete priv; } -void MacSparkleUpdater::checkForUpdates() -{ +void MacSparkleUpdater::checkForUpdates() { [priv->updaterController checkForUpdates:nil]; } -bool MacSparkleUpdater::getAutomaticallyChecksForUpdates() -{ +bool MacSparkleUpdater::getAutomaticallyChecksForUpdates() { return priv->updaterController.updater.automaticallyChecksForUpdates; } -double MacSparkleUpdater::getUpdateCheckInterval() -{ +double MacSparkleUpdater::getUpdateCheckInterval() { return priv->updaterController.updater.updateCheckInterval; } -QSet MacSparkleUpdater::getAllowedChannels() -{ +QSet MacSparkleUpdater::getAllowedChannels() { // Convert NSSet -> QSet __block QSet channels; - [priv->updaterDelegate.allowedChannels enumerateObjectsUsingBlock:^(NSString *channel, BOOL *stop) - { - channels.insert(QString::fromNSString(channel)); + [priv->updaterDelegate.allowedChannels enumerateObjectsUsingBlock:^(NSString* channel, BOOL* stop) { + channels.insert(QString::fromNSString(channel)); }]; return channels; } -bool MacSparkleUpdater::getBetaAllowed() -{ +bool MacSparkleUpdater::getBetaAllowed() { return getAllowedChannels().contains("beta"); } -void MacSparkleUpdater::setAutomaticallyChecksForUpdates(bool check) -{ - priv->updaterController.updater.automaticallyChecksForUpdates = check ? YES : NO; // make clang-tidy happy +void MacSparkleUpdater::setAutomaticallyChecksForUpdates(bool check) { + priv->updaterController.updater.automaticallyChecksForUpdates = check ? YES : NO; // make clang-tidy happy } -void MacSparkleUpdater::setUpdateCheckInterval(double seconds) -{ +void MacSparkleUpdater::setUpdateCheckInterval(double seconds) { priv->updaterController.updater.updateCheckInterval = seconds; } -void MacSparkleUpdater::clearAllowedChannels() -{ +void MacSparkleUpdater::clearAllowedChannels() { priv->updaterDelegate.allowedChannels = [NSSet set]; } -void MacSparkleUpdater::setAllowedChannel(const QString &channel) -{ - if (channel.isEmpty()) - { +void MacSparkleUpdater::setAllowedChannel(const QString& channel) { + if (channel.isEmpty()) { clearAllowedChannels(); return; } - NSSet *nsChannels = [NSSet setWithObject:channel.toNSString()]; + NSSet* nsChannels = [NSSet setWithObject:channel.toNSString()]; priv->updaterDelegate.allowedChannels = nsChannels; } -void MacSparkleUpdater::setAllowedChannels(const QSet &channels) -{ - if (channels.isEmpty()) - { +void MacSparkleUpdater::setAllowedChannels(const QSet& channels) { + if (channels.isEmpty()) { clearAllowedChannels(); return; } QString channelsConfig = ""; // Convert QSet -> NSSet - NSMutableSet *nsChannels = [NSMutableSet setWithCapacity:channels.count()]; - foreach (const QString channel, channels) - { + NSMutableSet* nsChannels = [NSMutableSet setWithCapacity:channels.count()]; + foreach (const QString channel, channels) { [nsChannels addObject:channel.toNSString()]; channelsConfig += channel + " "; } @@ -197,14 +174,10 @@ void MacSparkleUpdater::setAllowedChannels(const QSet &channels) priv->updaterDelegate.allowedChannels = nsChannels; } -void MacSparkleUpdater::setBetaAllowed(bool allowed) -{ - if (allowed) - { +void MacSparkleUpdater::setBetaAllowed(bool allowed) { + if (allowed) { setAllowedChannel("beta"); - } - else - { + } else { clearAllowedChannels(); } } diff --git a/libraries/LocalPeer/include/LocalPeer.h b/libraries/LocalPeer/include/LocalPeer.h index 3619ed5d1..c370102fd 100644 --- a/libraries/LocalPeer/include/LocalPeer.h +++ b/libraries/LocalPeer/include/LocalPeer.h @@ -43,56 +43,46 @@ #include #include - class QLocalServer; class LockedFile; -class ApplicationId -{ -public: /* methods */ +class ApplicationId { + public: /* methods */ // traditional app = installed system wide and used in a multi-user environment static ApplicationId fromTraditionalApp(); // ID based on a path with all the application data (no two instances with the same data path should run) - static ApplicationId fromPathAndVersion(const QString & dataPath, const QString & version); + static ApplicationId fromPathAndVersion(const QString& dataPath, const QString& version); // custom ID - static ApplicationId fromCustomId(const QString & id); + static ApplicationId fromCustomId(const QString& id); // custom ID, based on a raw string previously acquired from 'toString' - static ApplicationId fromRawString(const QString & id); + static ApplicationId fromRawString(const QString& id); + QString toString() { return m_id; } - QString toString() - { - return m_id; - } + private: /* methods */ + ApplicationId(const QString& value) { m_id = value; } -private: /* methods */ - ApplicationId(const QString & value) - { - m_id = value; - } - -private: /* data */ + private: /* data */ QString m_id; }; -class LocalPeer : public QObject -{ +class LocalPeer : public QObject { Q_OBJECT -public: - LocalPeer(QObject *parent, const ApplicationId &appId); + public: + LocalPeer(QObject* parent, const ApplicationId& appId); ~LocalPeer(); bool isClient(); - bool sendMessage(const QByteArray &message, int timeout); + bool sendMessage(const QByteArray& message, int timeout); ApplicationId applicationId() const; -Q_SIGNALS: - void messageReceived(const QByteArray &message); + Q_SIGNALS: + void messageReceived(const QByteArray& message); -protected Q_SLOTS: + protected Q_SLOTS: void receiveConnection(); -protected: + protected: ApplicationId id; QString socketName; std::unique_ptr server; diff --git a/libraries/LocalPeer/src/LocalPeer.cpp b/libraries/LocalPeer/src/LocalPeer.cpp index b7149c408..ab528c2a1 100644 --- a/libraries/LocalPeer/src/LocalPeer.cpp +++ b/libraries/LocalPeer/src/LocalPeer.cpp @@ -38,21 +38,20 @@ ** ****************************************************************************/ - #include "LocalPeer.h" #include #include -#include +#include #include #include -#include #include +#include #include "LockedFile.h" #if defined(Q_OS_WIN) -#include #include -typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); +#include +typedef BOOL(WINAPI* PProcessIdToSessionId)(DWORD, DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) @@ -60,9 +59,9 @@ static PProcessIdToSessionId pProcessIdToSessionId = 0; #include #endif +#include #include #include -#include static const char* ack = "ack"; @@ -79,13 +78,11 @@ ApplicationId ApplicationId::fromTraditionalApp() quint16 idNum = qChecksum(idc.constData(), idc.size()); auto socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) - if (!pProcessIdToSessionId) - { + if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } - if (pProcessIdToSessionId) - { + if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); @@ -114,8 +111,7 @@ ApplicationId ApplicationId::fromRawString(const QString& id) return ApplicationId(id); } -LocalPeer::LocalPeer(QObject * parent, const ApplicationId &appId) - : QObject(parent), id(appId) +LocalPeer::LocalPeer(QObject* parent, const ApplicationId& appId) : QObject(parent), id(appId) { socketName = id.toString(); server.reset(new QLocalServer()); @@ -124,9 +120,7 @@ LocalPeer::LocalPeer(QObject * parent, const ApplicationId &appId) lockFile->open(QIODevice::ReadWrite); } -LocalPeer::~LocalPeer() -{ -} +LocalPeer::~LocalPeer() {} ApplicationId LocalPeer::applicationId() const { @@ -145,7 +139,7 @@ bool LocalPeer::isClient() #if defined(Q_OS_UNIX) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { - QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); + QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName); res = server->listen(socketName); } #endif @@ -155,8 +149,7 @@ bool LocalPeer::isClient() return false; } - -bool LocalPeer::sendMessage(const QByteArray &message, int timeout) +bool LocalPeer::sendMessage(const QByteArray& message, int timeout) { if (!isClient()) return false; @@ -164,17 +157,15 @@ bool LocalPeer::sendMessage(const QByteArray &message, int timeout) QLocalSocket socket; bool connOk = false; int tries = 2; - for(int i = 0; i < tries; i++) { + for (int i = 0; i < tries; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); - connOk = socket.waitForConnected(timeout/2); - if (!connOk && i < (tries - 1)) - { + connOk = socket.waitForConnected(timeout / 2); + if (!connOk && i < (tries - 1)) { std::this_thread::sleep_for(std::chrono::milliseconds(250)); } } - if (!connOk) - { + if (!connOk) { return false; } @@ -182,36 +173,30 @@ bool LocalPeer::sendMessage(const QByteArray &message, int timeout) QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); - if(!socket.waitForBytesWritten(timeout)) - { + if (!socket.waitForBytesWritten(timeout)) { return false; } // wait for 'ack' - if(!socket.waitForReadyRead(timeout)) - { + if (!socket.waitForReadyRead(timeout)) { return false; } // make sure we got 'ack' - if(!(socket.read(qstrlen(ack)) == ack)) - { + if (!(socket.read(qstrlen(ack)) == ack)) { return false; } return true; } - void LocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); - if (!socket) - { + if (!socket) { return; } - while (socket->bytesAvailable() < static_cast(sizeof(quint32))) - { + while (socket->bytesAvailable() < static_cast(sizeof(quint32))) { socket->waitForReadyRead(); } QDataStream ds(socket); @@ -221,21 +206,19 @@ void LocalPeer::receiveConnection() uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); - do - { + do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); - if (got < 0) - { + if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); - socket->waitForDisconnected(1000); // make sure client reads ack + socket->waitForDisconnected(1000); // make sure client reads ack delete socket; - emit messageReceived(uMsg); //### (might take a long time to return) + emit messageReceived(uMsg); //### (might take a long time to return) } diff --git a/libraries/LocalPeer/src/LockedFile.cpp b/libraries/LocalPeer/src/LockedFile.cpp index 73294a16e..e93eabc96 100644 --- a/libraries/LocalPeer/src/LockedFile.cpp +++ b/libraries/LocalPeer/src/LockedFile.cpp @@ -80,8 +80,7 @@ \sa QFile::QFile() */ -LockedFile::LockedFile() - : QFile() +LockedFile::LockedFile() : QFile() { #ifdef Q_OS_WIN wmutex = 0; @@ -97,8 +96,7 @@ LockedFile::LockedFile() \sa QFile::QFile() */ -LockedFile::LockedFile(const QString &name) - : QFile(name) +LockedFile::LockedFile(const QString& name) : QFile(name) { #ifdef Q_OS_WIN wmutex = 0; diff --git a/libraries/LocalPeer/src/LockedFile.h b/libraries/LocalPeer/src/LockedFile.h index 2f29ee201..e8023251c 100644 --- a/libraries/LocalPeer/src/LockedFile.h +++ b/libraries/LocalPeer/src/LockedFile.h @@ -45,13 +45,12 @@ #include #endif -class LockedFile : public QFile -{ -public: +class LockedFile : public QFile { + public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; LockedFile(); - LockedFile(const QString &name); + LockedFile(const QString& name); ~LockedFile(); bool open(OpenMode mode); @@ -61,8 +60,7 @@ public: bool isLocked() const; LockMode lockMode() const; - private: - + private: #ifdef Q_OS_WIN Qt::HANDLE wmutex; Qt::HANDLE rmutex; diff --git a/libraries/LocalPeer/src/LockedFile_unix.cpp b/libraries/LocalPeer/src/LockedFile_unix.cpp index 6becc89e2..d17e625e4 100644 --- a/libraries/LocalPeer/src/LockedFile_unix.cpp +++ b/libraries/LocalPeer/src/LockedFile_unix.cpp @@ -38,10 +38,10 @@ ** ****************************************************************************/ -#include #include -#include #include +#include +#include #include "LockedFile.h" @@ -75,12 +75,10 @@ bool LockedFile::lock(LockMode mode, bool block) return false; } - m_lock_mode = mode; return true; } - bool LockedFile::unlock() { if (!isOpen()) { diff --git a/libraries/LocalPeer/src/LockedFile_win.cpp b/libraries/LocalPeer/src/LockedFile_win.cpp index 93d2c73b3..a8dbead36 100644 --- a/libraries/LocalPeer/src/LockedFile_win.cpp +++ b/libraries/LocalPeer/src/LockedFile_win.cpp @@ -38,9 +38,9 @@ ** ****************************************************************************/ -#include "LockedFile.h" #include #include +#include "LockedFile.h" #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS @@ -50,8 +50,7 @@ Qt::HANDLE LockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); - mutexname = QString::fromLatin1(MUTEX_PREFIX) - + fi.absoluteFilePath().toLower(); + mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) @@ -64,8 +63,7 @@ Qt::HANDLE LockedFile::getMutexHandle(int idx, bool doCreate) qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } - } - else { + } else { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (LPCWSTR)mname.utf16()); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) @@ -81,20 +79,18 @@ bool LockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { - case WAIT_OBJECT_0: - case WAIT_ABANDONED: - return true; - break; - case WAIT_TIMEOUT: - break; - default: - qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + return true; + break; + case WAIT_TIMEOUT: + break; + default: + qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } - - bool LockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { @@ -130,8 +126,7 @@ bool LockedFile::lock(LockMode mode, bool block) qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; - } - else if (!rmutex) { + } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; @@ -143,8 +138,7 @@ bool LockedFile::lock(LockMode mode, bool block) ReleaseMutex(wmutex); if (!ok) return false; - } - else { + } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); @@ -152,8 +146,7 @@ bool LockedFile::lock(LockMode mode, bool block) rmutexes.append(mutex); } if (rmutexes.size()) { - DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), - TRUE, block ? INFINITE : 0); + DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); @@ -182,9 +175,8 @@ bool LockedFile::unlock() ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; - } - else { - foreach(Qt::HANDLE mutex, rmutexes) { + } else { + foreach (Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } diff --git a/libraries/gamemode/include/gamemode_client.h b/libraries/gamemode/include/gamemode_client.h index b6f7afd4c..b186cd489 100644 --- a/libraries/gamemode/include/gamemode_client.h +++ b/libraries/gamemode/include/gamemode_client.h @@ -94,7 +94,7 @@ static volatile int internal_libgamemode_loaded = 1; /* Typedefs for the functions to load */ typedef int (*api_call_return_int)(void); -typedef const char *(*api_call_return_cstring)(void); +typedef const char* (*api_call_return_cstring)(void); typedef int (*api_call_pid_return_int)(pid_t); /* Storage for functors */ @@ -111,26 +111,26 @@ static api_call_pid_return_int REAL_internal_gamemode_query_status_for = NULL; * * Returns 0 on success and -1 on failure */ -__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol( - void *handle, const char *name, void **out_func, size_t func_size, bool required) +__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol(void* handle, + const char* name, + void** out_func, + size_t func_size, + bool required) { - void *symbol_lookup = NULL; - char *dl_error = NULL; + void* symbol_lookup = NULL; + char* dl_error = NULL; - /* Safely look up the symbol */ - symbol_lookup = dlsym(handle, name); - dl_error = dlerror(); - if (required && (dl_error || !symbol_lookup)) { - snprintf(internal_gamemode_client_error_string, - sizeof(internal_gamemode_client_error_string), - "dlsym failed - %s", - dl_error); - return -1; - } + /* Safely look up the symbol */ + symbol_lookup = dlsym(handle, name); + dl_error = dlerror(); + if (required && (dl_error || !symbol_lookup)) { + snprintf(internal_gamemode_client_error_string, sizeof(internal_gamemode_client_error_string), "dlsym failed - %s", dl_error); + return -1; + } - /* Have the symbol correctly, copy it to make it usable */ - memcpy(out_func, &symbol_lookup, func_size); - return 0; + /* Have the symbol correctly, copy it to make it usable */ + memcpy(out_func, &symbol_lookup, func_size); + return 0; } /** @@ -140,98 +140,74 @@ __attribute__((always_inline)) static inline int internal_bind_libgamemode_symbo */ __attribute__((always_inline)) static inline int internal_load_libgamemode(void) { - /* We start at 1, 0 is a success and -1 is a fail */ - if (internal_libgamemode_loaded != 1) { - return internal_libgamemode_loaded; - } + /* We start at 1, 0 is a success and -1 is a fail */ + if (internal_libgamemode_loaded != 1) { + return internal_libgamemode_loaded; + } - /* Anonymous struct type to define our bindings */ - struct binding { - const char *name; - void **functor; - size_t func_size; - bool required; - } bindings[] = { - { "real_gamemode_request_start", - (void **)&REAL_internal_gamemode_request_start, - sizeof(REAL_internal_gamemode_request_start), - true }, - { "real_gamemode_request_end", - (void **)&REAL_internal_gamemode_request_end, - sizeof(REAL_internal_gamemode_request_end), - true }, - { "real_gamemode_query_status", - (void **)&REAL_internal_gamemode_query_status, - sizeof(REAL_internal_gamemode_query_status), - false }, - { "real_gamemode_error_string", - (void **)&REAL_internal_gamemode_error_string, - sizeof(REAL_internal_gamemode_error_string), - true }, - { "real_gamemode_request_start_for", - (void **)&REAL_internal_gamemode_request_start_for, - sizeof(REAL_internal_gamemode_request_start_for), - false }, - { "real_gamemode_request_end_for", - (void **)&REAL_internal_gamemode_request_end_for, - sizeof(REAL_internal_gamemode_request_end_for), - false }, - { "real_gamemode_query_status_for", - (void **)&REAL_internal_gamemode_query_status_for, - sizeof(REAL_internal_gamemode_query_status_for), - false }, - }; + /* Anonymous struct type to define our bindings */ + struct binding { + const char* name; + void** functor; + size_t func_size; + bool required; + } bindings[] = { + { "real_gamemode_request_start", (void**)&REAL_internal_gamemode_request_start, sizeof(REAL_internal_gamemode_request_start), + true }, + { "real_gamemode_request_end", (void**)&REAL_internal_gamemode_request_end, sizeof(REAL_internal_gamemode_request_end), true }, + { "real_gamemode_query_status", (void**)&REAL_internal_gamemode_query_status, sizeof(REAL_internal_gamemode_query_status), false }, + { "real_gamemode_error_string", (void**)&REAL_internal_gamemode_error_string, sizeof(REAL_internal_gamemode_error_string), true }, + { "real_gamemode_request_start_for", (void**)&REAL_internal_gamemode_request_start_for, + sizeof(REAL_internal_gamemode_request_start_for), false }, + { "real_gamemode_request_end_for", (void**)&REAL_internal_gamemode_request_end_for, sizeof(REAL_internal_gamemode_request_end_for), + false }, + { "real_gamemode_query_status_for", (void**)&REAL_internal_gamemode_query_status_for, + sizeof(REAL_internal_gamemode_query_status_for), false }, + }; - void *libgamemode = NULL; + void* libgamemode = NULL; - /* Try and load libgamemode */ - libgamemode = dlopen("libgamemode.so.0", RTLD_NOW); - if (!libgamemode) { - /* Attempt to load unversioned library for compatibility with older - * versions (as of writing, there are no ABI changes between the two - - * this may need to change if ever ABI-breaking changes are made) */ - libgamemode = dlopen("libgamemode.so", RTLD_NOW); - if (!libgamemode) { - snprintf(internal_gamemode_client_error_string, - sizeof(internal_gamemode_client_error_string), - "dlopen failed - %s", - dlerror()); - internal_libgamemode_loaded = -1; - return -1; - } - } + /* Try and load libgamemode */ + libgamemode = dlopen("libgamemode.so.0", RTLD_NOW); + if (!libgamemode) { + /* Attempt to load unversioned library for compatibility with older + * versions (as of writing, there are no ABI changes between the two - + * this may need to change if ever ABI-breaking changes are made) */ + libgamemode = dlopen("libgamemode.so", RTLD_NOW); + if (!libgamemode) { + snprintf(internal_gamemode_client_error_string, sizeof(internal_gamemode_client_error_string), "dlopen failed - %s", dlerror()); + internal_libgamemode_loaded = -1; + return -1; + } + } - /* Attempt to bind all symbols */ - for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) { - struct binding *binder = &bindings[i]; + /* Attempt to bind all symbols */ + for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) { + struct binding* binder = &bindings[i]; - if (internal_bind_libgamemode_symbol(libgamemode, - binder->name, - binder->functor, - binder->func_size, - binder->required)) { - internal_libgamemode_loaded = -1; - return -1; - }; - } + if (internal_bind_libgamemode_symbol(libgamemode, binder->name, binder->functor, binder->func_size, binder->required)) { + internal_libgamemode_loaded = -1; + return -1; + }; + } - /* Success */ - internal_libgamemode_loaded = 0; - return 0; + /* Success */ + internal_libgamemode_loaded = 0; + return 0; } /** * Redirect to the real libgamemode */ -__attribute__((always_inline)) static inline const char *gamemode_error_string(void) +__attribute__((always_inline)) static inline const char* gamemode_error_string(void) { - /* If we fail to load the system gamemode, or we have an error string already, return our error - * string instead of diverting to the system version */ - if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') { - return internal_gamemode_client_error_string; - } + /* If we fail to load the system gamemode, or we have an error string already, return our error + * string instead of diverting to the system version */ + if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') { + return internal_gamemode_client_error_string; + } - return REAL_internal_gamemode_error_string(); + return REAL_internal_gamemode_error_string(); } /** @@ -246,22 +222,22 @@ __attribute__((always_inline)) static inline #endif int gamemode_request_start(void) { - /* Need to load gamemode */ - if (internal_load_libgamemode() < 0) { + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { #ifdef GAMEMODE_AUTO - fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); #endif - return -1; - } + return -1; + } - if (REAL_internal_gamemode_request_start() < 0) { + if (REAL_internal_gamemode_request_start() < 0) { #ifdef GAMEMODE_AUTO - fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); #endif - return -1; - } + return -1; + } - return 0; + return 0; } /* Redirect to the real libgamemode */ @@ -272,94 +248,90 @@ __attribute__((always_inline)) static inline #endif int gamemode_request_end(void) { - /* Need to load gamemode */ - if (internal_load_libgamemode() < 0) { + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { #ifdef GAMEMODE_AUTO - fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); #endif - return -1; - } + return -1; + } - if (REAL_internal_gamemode_request_end() < 0) { + if (REAL_internal_gamemode_request_end() < 0) { #ifdef GAMEMODE_AUTO - fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); #endif - return -1; - } + return -1; + } - return 0; + return 0; } /* Redirect to the real libgamemode */ __attribute__((always_inline)) static inline int gamemode_query_status(void) { - /* Need to load gamemode */ - if (internal_load_libgamemode() < 0) { - return -1; - } + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } - if (REAL_internal_gamemode_query_status == NULL) { - snprintf(internal_gamemode_client_error_string, - sizeof(internal_gamemode_client_error_string), - "gamemode_query_status missing (older host?)"); - return -1; - } + if (REAL_internal_gamemode_query_status == NULL) { + snprintf(internal_gamemode_client_error_string, sizeof(internal_gamemode_client_error_string), + "gamemode_query_status missing (older host?)"); + return -1; + } - return REAL_internal_gamemode_query_status(); + return REAL_internal_gamemode_query_status(); } /* Redirect to the real libgamemode */ __attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid) { - /* Need to load gamemode */ - if (internal_load_libgamemode() < 0) { - return -1; - } + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } - if (REAL_internal_gamemode_request_start_for == NULL) { - snprintf(internal_gamemode_client_error_string, - sizeof(internal_gamemode_client_error_string), - "gamemode_request_start_for missing (older host?)"); - return -1; - } + if (REAL_internal_gamemode_request_start_for == NULL) { + snprintf(internal_gamemode_client_error_string, sizeof(internal_gamemode_client_error_string), + "gamemode_request_start_for missing (older host?)"); + return -1; + } - return REAL_internal_gamemode_request_start_for(pid); + return REAL_internal_gamemode_request_start_for(pid); } /* Redirect to the real libgamemode */ __attribute__((always_inline)) static inline int gamemode_request_end_for(pid_t pid) { - /* Need to load gamemode */ - if (internal_load_libgamemode() < 0) { - return -1; - } + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } - if (REAL_internal_gamemode_request_end_for == NULL) { - snprintf(internal_gamemode_client_error_string, - sizeof(internal_gamemode_client_error_string), - "gamemode_request_end_for missing (older host?)"); - return -1; - } + if (REAL_internal_gamemode_request_end_for == NULL) { + snprintf(internal_gamemode_client_error_string, sizeof(internal_gamemode_client_error_string), + "gamemode_request_end_for missing (older host?)"); + return -1; + } - return REAL_internal_gamemode_request_end_for(pid); + return REAL_internal_gamemode_request_end_for(pid); } /* Redirect to the real libgamemode */ __attribute__((always_inline)) static inline int gamemode_query_status_for(pid_t pid) { - /* Need to load gamemode */ - if (internal_load_libgamemode() < 0) { - return -1; - } + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } - if (REAL_internal_gamemode_query_status_for == NULL) { - snprintf(internal_gamemode_client_error_string, - sizeof(internal_gamemode_client_error_string), - "gamemode_query_status_for missing (older host?)"); - return -1; - } + if (REAL_internal_gamemode_query_status_for == NULL) { + snprintf(internal_gamemode_client_error_string, sizeof(internal_gamemode_client_error_string), + "gamemode_query_status_for missing (older host?)"); + return -1; + } - return REAL_internal_gamemode_query_status_for(pid); + return REAL_internal_gamemode_query_status_for(pid); } -#endif // CLIENT_GAMEMODE_H +#endif // CLIENT_GAMEMODE_H diff --git a/libraries/javacheck/JavaCheck.java b/libraries/javacheck/JavaCheck.java index 4bf43a544..7cde86cf2 100644 --- a/libraries/javacheck/JavaCheck.java +++ b/libraries/javacheck/JavaCheck.java @@ -1,10 +1,5 @@ public final class JavaCheck { - - private static final String[] CHECKED_PROPERTIES = new String[] { - "os.arch", - "java.version", - "java.vendor" - }; + private static final String[] CHECKED_PROPERTIES = new String[] {"os.arch", "java.version", "java.vendor"}; public static void main(String[] args) { int returnCode = 0; @@ -21,5 +16,4 @@ public final class JavaCheck { System.exit(returnCode); } - } diff --git a/libraries/katabasis/include/katabasis/Bits.h b/libraries/katabasis/include/katabasis/Bits.h index f11f25d25..15da2a5a8 100644 --- a/libraries/katabasis/include/katabasis/Bits.h +++ b/libraries/katabasis/include/katabasis/Bits.h @@ -1,8 +1,8 @@ #pragma once -#include #include #include +#include #include namespace Katabasis { @@ -11,17 +11,13 @@ enum class Activity { LoggingIn, LoggingOut, Refreshing, - FailedSoft, //!< soft failure. this generally means the user auth details haven't been invalidated - FailedHard, //!< hard failure. auth is invalid - FailedGone, //!< hard failure. auth is invalid, and the account no longer exists + FailedSoft, //!< soft failure. this generally means the user auth details haven't been invalidated + FailedHard, //!< hard failure. auth is invalid + FailedGone, //!< hard failure. auth is invalid, and the account no longer exists Succeeded }; -enum class Validity { - None, - Assumed, - Certain -}; +enum class Validity { None, Assumed, Certain }; struct Token { QDateTime issueInstant; @@ -34,4 +30,4 @@ struct Token { bool persistent = true; }; -} +} // namespace Katabasis diff --git a/libraries/katabasis/include/katabasis/DeviceFlow.h b/libraries/katabasis/include/katabasis/DeviceFlow.h index 0401df3c0..98724d81b 100644 --- a/libraries/katabasis/include/katabasis/DeviceFlow.h +++ b/libraries/katabasis/include/katabasis/DeviceFlow.h @@ -2,13 +2,13 @@ #include #include -#include #include +#include #include +#include "Bits.h" #include "Reply.h" #include "RequestParameter.h" -#include "Bits.h" namespace Katabasis { @@ -16,14 +16,12 @@ class ReplyServer; class PollServer; /// Simple OAuth2 Device Flow authenticator. -class DeviceFlow: public QObject -{ +class DeviceFlow : public QObject { Q_OBJECT -public: + public: Q_ENUMS(GrantFlow) -public: - + public: struct Options { QString userAgent = QStringLiteral("Katabasis/1.0"); QString responseType = QStringLiteral("code"); @@ -34,7 +32,7 @@ public: QUrl accessTokenUrl; }; -public: + public: /// Are we authenticated? bool linked(); @@ -44,21 +42,21 @@ public: /// Provider-specific extra tokens, available after a successful authentication QVariantMap extraTokens(); -public: + public: // TODO: put in `Options` /// User-defined extra parameters to append to request URL QVariantMap extraRequestParams(); - void setExtraRequestParams(const QVariantMap &value); + void setExtraRequestParams(const QVariantMap& value); // TODO: split up the class into multiple, each implementing one OAuth2 flow /// Grant type (if non-standard) QString grantType(); - void setGrantType(const QString &value); + void setGrantType(const QString& value); -public: + public: /// Constructor. /// @param parent Parent object. - explicit DeviceFlow(Options & opts, Token & token, QObject *parent = 0, QNetworkAccessManager *manager = 0); + explicit DeviceFlow(Options& opts, Token& token, QObject* parent = 0, QNetworkAccessManager* manager = 0); /// Get refresh token. QString refreshToken(); @@ -66,7 +64,7 @@ public: /// Get token expiration time QDateTime expires(); -public slots: + public slots: /// Authenticate. void login(); @@ -79,24 +77,24 @@ public slots: /// Handle situation where reply server has opted to close its connection void serverHasClosed(bool paramsfound = false); -signals: + signals: /// Emitted when client needs to open a web browser window, with the given URL. - void openBrowser(const QUrl &url); + void openBrowser(const QUrl& url); /// Emitted when client can close the browser window. void closeBrowser(); /// Emitted when client needs to show a verification uri and user code - void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); + void showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn); /// Emitted when the internal state changes void activityChanged(Activity activity); -public slots: + public slots: /// Handle verification response. void onVerificationReceived(QMap); -protected slots: + protected slots: /// Handle completion of a Device Authorization Request void onDeviceAuthReplyFinished(); @@ -104,20 +102,20 @@ protected slots: void onRefreshFinished(); /// Handle failure of a refresh request. - void onRefreshError(QNetworkReply::NetworkError error, QNetworkReply *reply); + void onRefreshError(QNetworkReply::NetworkError error, QNetworkReply* reply); -protected: + protected: /// Set refresh token. - void setRefreshToken(const QString &v); + void setRefreshToken(const QString& v); /// Set token expiration time. void setExpires(QDateTime v); /// Start polling authorization server - void startPollServer(const QVariantMap ¶ms, int expiresIn); + void startPollServer(const QVariantMap& params, int expiresIn); /// Set authentication token. - void setToken(const QString &v); + void setToken(const QString& v); /// Set the linked state void setLinked(bool v); @@ -126,26 +124,26 @@ protected: void setExtraTokens(QVariantMap extraTokens); /// Set local poll server - void setPollServer(PollServer *server); + void setPollServer(PollServer* server); - PollServer * pollServer() const; + PollServer* pollServer() const; void updateActivity(Activity activity); -protected: + protected: Options options_; QVariantMap extraReqParams_; - QNetworkAccessManager *manager_ = nullptr; + QNetworkAccessManager* manager_ = nullptr; ReplyList timedReplies_; QString grantType_; -protected: - Token &token_; + protected: + Token& token_; -private: - PollServer *pollServer_ = nullptr; + private: + PollServer* pollServer_ = nullptr; Activity activity_ = Activity::Idle; }; -} +} // namespace Katabasis diff --git a/libraries/katabasis/include/katabasis/Globals.h b/libraries/katabasis/include/katabasis/Globals.h index 512745d3c..02fe1cf45 100644 --- a/libraries/katabasis/include/katabasis/Globals.h +++ b/libraries/katabasis/include/katabasis/Globals.h @@ -45,7 +45,7 @@ const char OAUTH2_EXPIRES_IN[] = "expires_in"; const char OAUTH2_DEVICE_CODE[] = "device_code"; const char OAUTH2_USER_CODE[] = "user_code"; const char OAUTH2_VERIFICATION_URI[] = "verification_uri"; -const char OAUTH2_VERIFICATION_URL[] = "verification_url"; // Google sign-in +const char OAUTH2_VERIFICATION_URL[] = "verification_url"; // Google sign-in const char OAUTH2_VERIFICATION_URI_COMPLETE[] = "verification_uri_complete"; const char OAUTH2_INTERVAL[] = "interval"; @@ -56,4 +56,4 @@ const char AUTHORIZATION_CODE[] = "authorization_code"; const char HTTP_HTTP_HEADER[] = "HTTP"; const char HTTP_AUTHORIZATION_HEADER[] = "Authorization"; -} +} // namespace Katabasis diff --git a/libraries/katabasis/include/katabasis/PollServer.h b/libraries/katabasis/include/katabasis/PollServer.h index 77103867c..fd6a5351c 100644 --- a/libraries/katabasis/include/katabasis/PollServer.h +++ b/libraries/katabasis/include/katabasis/PollServer.h @@ -12,32 +12,35 @@ class QNetworkAccessManager; namespace Katabasis { /// Poll an authorization server for token -class PollServer : public QObject -{ +class PollServer : public QObject { Q_OBJECT -public: - explicit PollServer(QNetworkAccessManager * manager, const QNetworkRequest &request, const QByteArray & payload, int expiresIn, QObject *parent = 0); + public: + explicit PollServer(QNetworkAccessManager* manager, + const QNetworkRequest& request, + const QByteArray& payload, + int expiresIn, + QObject* parent = 0); /// Seconds to wait between polling requests Q_PROPERTY(int interval READ interval WRITE setInterval) int interval() const; void setInterval(int interval); -signals: + signals: void verificationReceived(QMap); - void serverClosed(bool); // whether it has found parameters + void serverClosed(bool); // whether it has found parameters -public slots: + public slots: void startPolling(); -protected slots: + protected slots: void onPollTimeout(); void onExpiration(); void onReplyFinished(); -protected: - QNetworkAccessManager *manager_; + protected: + QNetworkAccessManager* manager_; const QNetworkRequest request_; const QByteArray payload_; const int expiresIn_; @@ -45,4 +48,4 @@ protected: QTimer pollTimer; }; -} +} // namespace Katabasis diff --git a/libraries/katabasis/include/katabasis/Reply.h b/libraries/katabasis/include/katabasis/Reply.h index 415cf4ec8..89ee90e98 100644 --- a/libraries/katabasis/include/katabasis/Reply.h +++ b/libraries/katabasis/include/katabasis/Reply.h @@ -1,38 +1,38 @@ #pragma once -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include namespace Katabasis { constexpr int defaultTimeout = 30 * 1000; /// A network request/reply pair that can time out. -class Reply: public QTimer { +class Reply : public QTimer { Q_OBJECT -public: - Reply(QNetworkReply *reply, int timeOut = defaultTimeout, QObject *parent = 0); + public: + Reply(QNetworkReply* reply, int timeOut = defaultTimeout, QObject* parent = 0); -signals: + signals: void error(QNetworkReply::NetworkError); -public slots: + public slots: /// When time out occurs, the QNetworkReply's error() signal is triggered. void onTimeOut(); -public: - QNetworkReply *reply; + public: + QNetworkReply* reply; bool timedOut = false; }; /// List of O2Replies. class ReplyList { -public: + public: ReplyList() { ignoreSslErrors_ = false; } /// Destructor. @@ -40,24 +40,24 @@ public: virtual ~ReplyList(); /// Create a new O2Reply from a QNetworkReply, and add it to this list. - void add(QNetworkReply *reply, int timeOut = defaultTimeout); + void add(QNetworkReply* reply, int timeOut = defaultTimeout); /// Add an O2Reply to the list, while taking ownership of it. - void add(Reply *reply); + void add(Reply* reply); /// Remove item from the list that corresponds to a QNetworkReply. - void remove(QNetworkReply *reply); + void remove(QNetworkReply* reply); /// Find an O2Reply in the list, corresponding to a QNetworkReply. /// @return Matching O2Reply or NULL. - Reply *find(QNetworkReply *reply); + Reply* find(QNetworkReply* reply); bool ignoreSslErrors(); void setIgnoreSslErrors(bool ignoreSslErrors); -protected: - QList replies_; + protected: + QList replies_; bool ignoreSslErrors_; }; -} +} // namespace Katabasis diff --git a/libraries/katabasis/include/katabasis/RequestParameter.h b/libraries/katabasis/include/katabasis/RequestParameter.h index ca36934a3..1d23cf0e1 100644 --- a/libraries/katabasis/include/katabasis/RequestParameter.h +++ b/libraries/katabasis/include/katabasis/RequestParameter.h @@ -4,12 +4,10 @@ namespace Katabasis { /// Request parameter (name-value pair) participating in authentication. struct RequestParameter { - RequestParameter(const QByteArray &n, const QByteArray &v): name(n), value(v) {} - bool operator <(const RequestParameter &other) const { - return (name == other.name)? (value < other.value): (name < other.name); - } + RequestParameter(const QByteArray& n, const QByteArray& v) : name(n), value(v) {} + bool operator<(const RequestParameter& other) const { return (name == other.name) ? (value < other.value) : (name < other.name); } QByteArray name; QByteArray value; }; -} +} // namespace Katabasis diff --git a/libraries/katabasis/src/DeviceFlow.cpp b/libraries/katabasis/src/DeviceFlow.cpp index f49fcb7d7..3b9d9c53f 100644 --- a/libraries/katabasis/src/DeviceFlow.cpp +++ b/libraries/katabasis/src/DeviceFlow.cpp @@ -1,26 +1,26 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include "katabasis/DeviceFlow.h" -#include "katabasis/PollServer.h" #include "katabasis/Globals.h" +#include "katabasis/PollServer.h" -#include "KatabasisLogging.h" #include "JsonResponse.h" +#include "KatabasisLogging.h" namespace { @@ -43,10 +43,11 @@ bool hasMandatoryDeviceAuthParams(const QVariantMap& params) return true; } -QByteArray createQueryParameters(const QList ¶meters) { +QByteArray createQueryParameters(const QList& parameters) +{ QByteArray ret; bool first = true; - for( auto & h: parameters) { + for (auto& h : parameters) { if (first) { first = false; } else { @@ -56,32 +57,35 @@ QByteArray createQueryParameters(const QList ¶m } return ret; } -} +} // namespace namespace Katabasis { -DeviceFlow::DeviceFlow(Options & opts, Token & token, QObject *parent, QNetworkAccessManager *manager) : QObject(parent), token_(token) { +DeviceFlow::DeviceFlow(Options& opts, Token& token, QObject* parent, QNetworkAccessManager* manager) : QObject(parent), token_(token) +{ manager_ = manager ? manager : new QNetworkAccessManager(this); qRegisterMetaType("QNetworkReply::NetworkError"); options_ = opts; } -bool DeviceFlow::linked() { +bool DeviceFlow::linked() +{ return token_.validity != Validity::None; } -void DeviceFlow::setLinked(bool v) { - qDebug() << "DeviceFlow::setLinked:" << (v? "true": "false"); +void DeviceFlow::setLinked(bool v) +{ + qDebug() << "DeviceFlow::setLinked:" << (v ? "true" : "false"); token_.validity = v ? Validity::Certain : Validity::None; } void DeviceFlow::updateActivity(Activity activity) { - if(activity_ == activity) { + if (activity_ == activity) { return; } activity_ = activity; - switch(activity) { + switch (activity) { case Katabasis::Activity::Idle: case Katabasis::Activity::LoggingIn: case Katabasis::Activity::LoggingOut: @@ -103,22 +107,26 @@ void DeviceFlow::updateActivity(Activity activity) emit activityChanged(activity_); } -QString DeviceFlow::token() { +QString DeviceFlow::token() +{ return token_.token; } -void DeviceFlow::setToken(const QString &v) { +void DeviceFlow::setToken(const QString& v) +{ token_.token = v; } -QVariantMap DeviceFlow::extraTokens() { +QVariantMap DeviceFlow::extraTokens() +{ return token_.extra; } -void DeviceFlow::setExtraTokens(QVariantMap extraTokens) { +void DeviceFlow::setExtraTokens(QVariantMap extraTokens) +{ token_.extra = extraTokens; } -void DeviceFlow::setPollServer(PollServer *server) +void DeviceFlow::setPollServer(PollServer* server) { if (pollServer_) pollServer_->deleteLater(); @@ -126,7 +134,7 @@ void DeviceFlow::setPollServer(PollServer *server) pollServer_ = server; } -PollServer *DeviceFlow::pollServer() const +PollServer* DeviceFlow::pollServer() const { return pollServer_; } @@ -136,7 +144,7 @@ QVariantMap DeviceFlow::extraRequestParams() return extraReqParams_; } -void DeviceFlow::setExtraRequestParams(const QVariantMap &value) +void DeviceFlow::setExtraRequestParams(const QVariantMap& value) { extraReqParams_ = value; } @@ -149,13 +157,14 @@ QString DeviceFlow::grantType() return OAUTH2_GRANT_TYPE_DEVICE; } -void DeviceFlow::setGrantType(const QString &value) +void DeviceFlow::setGrantType(const QString& value) { grantType_ = value; } // First get the URL and token to display to the user -void DeviceFlow::login() { +void DeviceFlow::login() +{ qDebug() << "DeviceFlow::link"; updateActivity(Activity::LoggingIn); @@ -173,7 +182,7 @@ void DeviceFlow::login() { QUrl url(options_.authorizationUrl); QNetworkRequest deviceRequest(url); deviceRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - QNetworkReply *tokenReply = manager_->post(deviceRequest, payload); + QNetworkReply* tokenReply = manager_->post(deviceRequest, payload); connect(tokenReply, &QNetworkReply::finished, this, &DeviceFlow::onDeviceAuthReplyFinished, Qt::QueuedConnection); } @@ -182,19 +191,18 @@ void DeviceFlow::login() { void DeviceFlow::onDeviceAuthReplyFinished() { qDebug() << "DeviceFlow::onDeviceAuthReplyFinished"; - QNetworkReply *tokenReply = qobject_cast(sender()); - if (!tokenReply) - { - qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: reply is null"; - return; + QNetworkReply* tokenReply = qobject_cast(sender()); + if (!tokenReply) { + qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: reply is null"; + return; } if (tokenReply->error() == QNetworkReply::NoError) { QByteArray replyData = tokenReply->readAll(); // Dump replyData // SENSITIVE DATA in RelWithDebInfo or Debug builds - //qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: replyData\n"; - //qDebug() << QString( replyData ); + // qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: replyData\n"; + // qDebug() << QString( replyData ); QVariantMap params = parseJsonResponse(replyData); @@ -202,7 +210,7 @@ void DeviceFlow::onDeviceAuthReplyFinished() qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: Tokens returned:\n"; foreach (QString key, params.keys()) { // SENSITIVE DATA in RelWithDebInfo or Debug builds, so it is truncated first - qDebug() << key << ": "<< params.value( key ).toString(); + qDebug() << key << ": " << params.value(key).toString(); } // Check for mandatory parameters @@ -237,7 +245,7 @@ void DeviceFlow::onDeviceAuthReplyFinished() } // Spin up polling for the user completing the login flow out of band -void DeviceFlow::startPollServer(const QVariantMap ¶ms, int expiresIn) +void DeviceFlow::startPollServer(const QVariantMap& params, int expiresIn) { qDebug() << "DeviceFlow::startPollServer: device_ and user_code expires in" << expiresIn << "seconds"; @@ -250,14 +258,14 @@ void DeviceFlow::startPollServer(const QVariantMap ¶ms, int expiresIn) QList parameters; parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); - if ( !options_.clientSecret.isEmpty() ) { + if (!options_.clientSecret.isEmpty()) { parameters.append(RequestParameter(OAUTH2_CLIENT_SECRET, options_.clientSecret.toUtf8())); } parameters.append(RequestParameter(OAUTH2_CODE, deviceCode.toUtf8())); parameters.append(RequestParameter(OAUTH2_GRANT_TYPE, grantType.toUtf8())); QByteArray payload = createQueryParameters(parameters); - PollServer * pollServer = new PollServer(manager_, authRequest, payload, expiresIn, this); + PollServer* pollServer = new PollServer(manager_, authRequest, payload, expiresIn, this); if (params.contains(OAUTH2_INTERVAL)) { bool ok = false; int interval = params[OAUTH2_INTERVAL].toInt(&ok); @@ -272,7 +280,8 @@ void DeviceFlow::startPollServer(const QVariantMap ¶ms, int expiresIn) } // Once the user completes the flow, update the internal state and report it to observers -void DeviceFlow::onVerificationReceived(const QMap response) { +void DeviceFlow::onVerificationReceived(const QMap response) +{ qDebug() << "DeviceFlow::onVerificationReceived: Emitting closeBrowser()"; emit closeBrowser(); @@ -307,7 +316,7 @@ void DeviceFlow::onVerificationReceived(const QMap response) { // Or if the flow fails or the polling times out, update the internal state with error and report it to observers void DeviceFlow::serverHasClosed(bool paramsfound) { - if ( !paramsfound ) { + if (!paramsfound) { // server has probably timed out after receiving first response updateActivity(Activity::FailedHard); } @@ -315,7 +324,8 @@ void DeviceFlow::serverHasClosed(bool paramsfound) setPollServer(NULL); } -void DeviceFlow::logout() { +void DeviceFlow::logout() +{ qDebug() << "DeviceFlow::unlink"; updateActivity(Activity::LoggingOut); // FIXME: implement logout flows... if they exist @@ -323,24 +333,29 @@ void DeviceFlow::logout() { updateActivity(Activity::FailedHard); } -QDateTime DeviceFlow::expires() { +QDateTime DeviceFlow::expires() +{ return token_.notAfter; } -void DeviceFlow::setExpires(QDateTime v) { +void DeviceFlow::setExpires(QDateTime v) +{ token_.notAfter = v; } -QString DeviceFlow::refreshToken() { +QString DeviceFlow::refreshToken() +{ return token_.refresh_token; } -void DeviceFlow::setRefreshToken(const QString &v) { +void DeviceFlow::setRefreshToken(const QString& v) +{ qCDebug(katabasisCredentials) << "new refresh token:" << v; token_.refresh_token = v; } namespace { -QByteArray buildRequestBody(const QMap ¶meters) { +QByteArray buildRequestBody(const QMap& parameters) +{ QByteArray body; bool first = true; foreach (QString key, parameters.keys()) { @@ -354,9 +369,10 @@ QByteArray buildRequestBody(const QMap ¶meters) { } return body; } -} +} // namespace -bool DeviceFlow::refresh() { +bool DeviceFlow::refresh() +{ qDebug() << "DeviceFlow::refresh: Token: ..." << refreshToken().right(7); updateActivity(Activity::Refreshing); @@ -376,21 +392,22 @@ bool DeviceFlow::refresh() { refreshRequest.setHeader(QNetworkRequest::ContentTypeHeader, MIME_TYPE_XFORM); QMap parameters; parameters.insert(OAUTH2_CLIENT_ID, options_.clientIdentifier); - if ( !options_.clientSecret.isEmpty() ) { + if (!options_.clientSecret.isEmpty()) { parameters.insert(OAUTH2_CLIENT_SECRET, options_.clientSecret); } parameters.insert(OAUTH2_REFRESH_TOKEN, refreshToken()); parameters.insert(OAUTH2_GRANT_TYPE, OAUTH2_REFRESH_TOKEN); QByteArray data = buildRequestBody(parameters); - QNetworkReply *refreshReply = manager_->post(refreshRequest, data); + QNetworkReply* refreshReply = manager_->post(refreshRequest, data); timedReplies_.add(refreshReply); connect(refreshReply, &QNetworkReply::finished, this, &DeviceFlow::onRefreshFinished, Qt::QueuedConnection); return true; } -void DeviceFlow::onRefreshFinished() { - QNetworkReply *refreshReply = qobject_cast(sender()); +void DeviceFlow::onRefreshFinished() +{ + QNetworkReply* refreshReply = qobject_cast(sender()); auto networkError = refreshReply->error(); if (networkError == QNetworkReply::NoError) { @@ -399,10 +416,9 @@ void DeviceFlow::onRefreshFinished() { setToken(tokens.value(OAUTH2_ACCESS_TOKEN).toString()); setExpires(QDateTime::currentDateTimeUtc().addSecs(tokens.value(OAUTH2_EXPIRES_IN).toInt())); QString refreshToken = tokens.value(OAUTH2_REFRESH_TOKEN).toString(); - if(!refreshToken.isEmpty()) { + if (!refreshToken.isEmpty()) { setRefreshToken(refreshToken); - } - else { + } else { qDebug() << "No new refresh token. Keep the old one."; } timedReplies_.remove(refreshReply); @@ -415,37 +431,37 @@ void DeviceFlow::onRefreshFinished() { } } -void DeviceFlow::onRefreshError(QNetworkReply::NetworkError error, QNetworkReply *refreshReply) { +void DeviceFlow::onRefreshError(QNetworkReply::NetworkError error, QNetworkReply* refreshReply) +{ QString errorString = "No Reply"; - if(refreshReply) { + if (refreshReply) { timedReplies_.remove(refreshReply); errorString = refreshReply->errorString(); } - switch (error) - { - // used for invalid credentials and similar errors. Fall through. - case QNetworkReply::AuthenticationRequiredError: - case QNetworkReply::ContentAccessDenied: - case QNetworkReply::ContentOperationNotPermittedError: - case QNetworkReply::ProtocolInvalidOperationError: - updateActivity(Activity::FailedHard); - break; - case QNetworkReply::ContentGoneError: { - updateActivity(Activity::FailedGone); - break; + switch (error) { + // used for invalid credentials and similar errors. Fall through. + case QNetworkReply::AuthenticationRequiredError: + case QNetworkReply::ContentAccessDenied: + case QNetworkReply::ContentOperationNotPermittedError: + case QNetworkReply::ProtocolInvalidOperationError: + updateActivity(Activity::FailedHard); + break; + case QNetworkReply::ContentGoneError: { + updateActivity(Activity::FailedGone); + break; + } + case QNetworkReply::TimeoutError: + case QNetworkReply::OperationCanceledError: + case QNetworkReply::SslHandshakeFailedError: + default: + updateActivity(Activity::FailedSoft); + return; } - case QNetworkReply::TimeoutError: - case QNetworkReply::OperationCanceledError: - case QNetworkReply::SslHandshakeFailedError: - default: - updateActivity(Activity::FailedSoft); - return; - } - if(refreshReply) { + if (refreshReply) { refreshReply->deleteLater(); } qDebug() << "DeviceFlow::onRefreshFinished: Error" << static_cast(error) << " - " << errorString; } -} +} // namespace Katabasis diff --git a/libraries/katabasis/src/JsonResponse.cpp b/libraries/katabasis/src/JsonResponse.cpp index 63384d121..6840627ac 100644 --- a/libraries/katabasis/src/JsonResponse.cpp +++ b/libraries/katabasis/src/JsonResponse.cpp @@ -7,7 +7,8 @@ namespace Katabasis { -QVariantMap parseJsonResponse(const QByteArray &data) { +QVariantMap parseJsonResponse(const QByteArray& data) +{ QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(data, &err); if (err.error != QJsonParseError::NoError) { @@ -23,4 +24,4 @@ QVariantMap parseJsonResponse(const QByteArray &data) { return doc.object().toVariantMap(); } -} +} // namespace Katabasis diff --git a/libraries/katabasis/src/JsonResponse.h b/libraries/katabasis/src/JsonResponse.h index e7fe7e30d..ff3471752 100644 --- a/libraries/katabasis/src/JsonResponse.h +++ b/libraries/katabasis/src/JsonResponse.h @@ -6,7 +6,7 @@ class QByteArray; namespace Katabasis { - /// Parse JSON data into a QVariantMap -QVariantMap parseJsonResponse(const QByteArray &data); +/// Parse JSON data into a QVariantMap +QVariantMap parseJsonResponse(const QByteArray& data); -} +} // namespace Katabasis diff --git a/libraries/katabasis/src/PollServer.cpp b/libraries/katabasis/src/PollServer.cpp index 1083c5994..c1c316df9 100644 --- a/libraries/katabasis/src/PollServer.cpp +++ b/libraries/katabasis/src/PollServer.cpp @@ -1,30 +1,28 @@ #include #include -#include "katabasis/PollServer.h" #include "JsonResponse.h" +#include "katabasis/PollServer.h" namespace { -QMap toVerificationParams(const QVariantMap &map) +QMap toVerificationParams(const QVariantMap& map) { QMap params; - for (QVariantMap::const_iterator i = map.constBegin(); - i != map.constEnd(); ++i) - { + for (QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i) { params[i.key()] = i.value().toString(); } return params; } -} +} // namespace namespace Katabasis { -PollServer::PollServer(QNetworkAccessManager *manager, const QNetworkRequest &request, const QByteArray &payload, int expiresIn, QObject *parent) - : QObject(parent) - , manager_(manager) - , request_(request) - , payload_(payload) - , expiresIn_(expiresIn) +PollServer::PollServer(QNetworkAccessManager* manager, + const QNetworkRequest& request, + const QByteArray& payload, + int expiresIn, + QObject* parent) + : QObject(parent), manager_(manager), request_(request), payload_(payload), expiresIn_(expiresIn) { expirationTimer.setTimerType(Qt::VeryCoarseTimer); expirationTimer.setInterval(expiresIn * 1000); @@ -58,7 +56,7 @@ void PollServer::startPolling() void PollServer::onPollTimeout() { qDebug() << "PollServer::onPollTimeout: retrying"; - QNetworkReply * reply = manager_->post(request_, payload_); + QNetworkReply* reply = manager_->post(request_, payload_); connect(reply, SIGNAL(finished()), this, SLOT(onReplyFinished())); } @@ -70,7 +68,7 @@ void PollServer::onExpiration() void PollServer::onReplyFinished() { - QNetworkReply *reply = qobject_cast(sender()); + QNetworkReply* reply = qobject_cast(sender()); if (!reply) { qDebug() << "PollServer::onReplyFinished: reply is null"; @@ -93,8 +91,7 @@ void PollServer::onReplyFinished() // polling interval on each such connection timeout, is RECOMMENDED." setInterval(interval() * 2); pollTimer.start(); - } - else { + } else { QString error = params.value("error"); if (error == "slow_down") { // rfc8628#section-3.2 @@ -103,14 +100,12 @@ void PollServer::onReplyFinished() // be increased by 5 seconds for this and all subsequent requests." setInterval(interval() + 5); pollTimer.start(); - } - else if (error == "authorization_pending") { + } else if (error == "authorization_pending") { // keep trying - rfc8628#section-3.2 // "The authorization request is still pending as the end user hasn't // yet completed the user-interaction steps (Section 3.3)." pollTimer.start(); - } - else { + } else { expirationTimer.stop(); emit serverClosed(true); // let O2 handle the other cases @@ -120,4 +115,4 @@ void PollServer::onReplyFinished() reply->deleteLater(); } -} +} // namespace Katabasis diff --git a/libraries/katabasis/src/Reply.cpp b/libraries/katabasis/src/Reply.cpp index c26079005..4a5017e22 100644 --- a/libraries/katabasis/src/Reply.cpp +++ b/libraries/katabasis/src/Reply.cpp @@ -1,42 +1,48 @@ -#include #include +#include #include "katabasis/Reply.h" namespace Katabasis { -Reply::Reply(QNetworkReply *r, int timeOut, QObject *parent): QTimer(parent), reply(r) { +Reply::Reply(QNetworkReply* r, int timeOut, QObject* parent) : QTimer(parent), reply(r) +{ setSingleShot(true); connect(this, &Reply::timeout, this, &Reply::onTimeOut, Qt::QueuedConnection); start(timeOut); } -void Reply::onTimeOut() { +void Reply::onTimeOut() +{ timedOut = true; reply->abort(); } // ---------------------------- -ReplyList::~ReplyList() { - foreach (Reply *timedReply, replies_) { +ReplyList::~ReplyList() +{ + foreach (Reply* timedReply, replies_) { delete timedReply; } } -void ReplyList::add(QNetworkReply *reply, int timeOut) { +void ReplyList::add(QNetworkReply* reply, int timeOut) +{ if (reply && ignoreSslErrors()) { reply->ignoreSslErrors(); } add(new Reply(reply, timeOut)); } -void ReplyList::add(Reply *reply) { +void ReplyList::add(Reply* reply) +{ replies_.append(reply); } -void ReplyList::remove(QNetworkReply *reply) { - Reply *o2Reply = find(reply); +void ReplyList::remove(QNetworkReply* reply) +{ + Reply* o2Reply = find(reply); if (o2Reply) { o2Reply->stop(); (void)replies_.removeOne(o2Reply); @@ -45,8 +51,9 @@ void ReplyList::remove(QNetworkReply *reply) { } } -Reply *ReplyList::find(QNetworkReply *reply) { - foreach (Reply *timedReply, replies_) { +Reply* ReplyList::find(QNetworkReply* reply) +{ + foreach (Reply* timedReply, replies_) { if (timedReply->reply == reply) { return timedReply; } @@ -64,4 +71,4 @@ void ReplyList::setIgnoreSslErrors(bool ignoreSslErrors) ignoreSslErrors_ = ignoreSslErrors; } -} +} // namespace Katabasis diff --git a/libraries/launcher/net/minecraft/Launcher.java b/libraries/launcher/net/minecraft/Launcher.java index 646e2e3ea..10cfa2ac0 100644 --- a/libraries/launcher/net/minecraft/Launcher.java +++ b/libraries/launcher/net/minecraft/Launcher.java @@ -71,7 +71,6 @@ import java.util.Map; * recommended. */ public final class Launcher extends Applet implements AppletStub { - private static final long serialVersionUID = 1L; private final Map params = new HashMap<>(); @@ -207,12 +206,10 @@ public final class Launcher extends Applet implements AppletStub { } @Override - public void paint(Graphics graphics) { - } + public void paint(Graphics graphics) {} @Override - public void update(Graphics graphics) { - } + public void update(Graphics graphics) {} public void setParameter(String key, String value) { params.put(key, value); @@ -221,5 +218,4 @@ public final class Launcher extends Applet implements AppletStub { public void setParameter(String key, boolean value) { setParameter(key, value ? "true" : "false"); } - } diff --git a/libraries/launcher/org/prismlauncher/EntryPoint.java b/libraries/launcher/org/prismlauncher/EntryPoint.java index 78804b3e8..4b59c1da6 100644 --- a/libraries/launcher/org/prismlauncher/EntryPoint.java +++ b/libraries/launcher/org/prismlauncher/EntryPoint.java @@ -54,10 +54,6 @@ package org.prismlauncher; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - import org.prismlauncher.exception.ParseException; import org.prismlauncher.launcher.Launcher; import org.prismlauncher.launcher.impl.StandardLauncher; @@ -65,8 +61,11 @@ import org.prismlauncher.launcher.impl.legacy.LegacyLauncher; import org.prismlauncher.utils.Parameters; import org.prismlauncher.utils.logging.Log; -public final class EntryPoint { +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +public final class EntryPoint { public static void main(String[] args) { ExitCode code = listen(); @@ -160,19 +159,18 @@ public final class EntryPoint { return PreLaunchAction.PROCEED; } - private enum PreLaunchAction { - PROCEED, LAUNCH, ABORT - } + private enum PreLaunchAction { PROCEED, LAUNCH, ABORT } private enum ExitCode { - NORMAL(0), ABORT(1), ERROR(2), ILLEGAL_ARGUMENT(65); + NORMAL(0), + ABORT(1), + ERROR(2), + ILLEGAL_ARGUMENT(65); private final int numeric; ExitCode(int numeric) { this.numeric = numeric; } - } - } diff --git a/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java b/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java index 524076ff7..e9abc5ee3 100644 --- a/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java +++ b/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java @@ -38,11 +38,9 @@ package org.prismlauncher.exception; public final class ParameterNotFoundException extends IllegalArgumentException { - private static final long serialVersionUID = 1L; public ParameterNotFoundException(String key) { super(String.format("Required parameter '%s' was not found", key)); } - } diff --git a/libraries/launcher/org/prismlauncher/exception/ParseException.java b/libraries/launcher/org/prismlauncher/exception/ParseException.java index 4608fdd17..ae0578958 100644 --- a/libraries/launcher/org/prismlauncher/exception/ParseException.java +++ b/libraries/launcher/org/prismlauncher/exception/ParseException.java @@ -38,11 +38,9 @@ package org.prismlauncher.exception; public final class ParseException extends IllegalArgumentException { - private static final long serialVersionUID = 1L; public ParseException(String input, String format) { super(String.format("For input '%s' - should match '%s'", input, format)); } - } diff --git a/libraries/launcher/org/prismlauncher/launcher/Launcher.java b/libraries/launcher/org/prismlauncher/launcher/Launcher.java index 049a83d84..5dc0bb10d 100644 --- a/libraries/launcher/org/prismlauncher/launcher/Launcher.java +++ b/libraries/launcher/org/prismlauncher/launcher/Launcher.java @@ -38,7 +38,5 @@ package org.prismlauncher.launcher; public interface Launcher { - void launch() throws Throwable; - } diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java index 0c2153a9d..761837041 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java @@ -54,15 +54,14 @@ package org.prismlauncher.launcher.impl; -import java.util.ArrayList; -import java.util.List; - import org.prismlauncher.exception.ParseException; import org.prismlauncher.launcher.Launcher; import org.prismlauncher.utils.Parameters; -public abstract class AbstractLauncher implements Launcher { +import java.util.ArrayList; +import java.util.List; +public abstract class AbstractLauncher implements Launcher { private static final int DEFAULT_WINDOW_WIDTH = 854, DEFAULT_WINDOW_HEIGHT = 480; // parameters, separated from ParamBucket @@ -106,5 +105,4 @@ public abstract class AbstractLauncher implements Launcher { throw new ParseException(windowParams, "[width]x[height]"); } } - } diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java index 9436ff15e..186909123 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java @@ -54,13 +54,12 @@ package org.prismlauncher.launcher.impl; -import java.lang.invoke.MethodHandle; - import org.prismlauncher.utils.Parameters; import org.prismlauncher.utils.ReflectionUtils; -public final class StandardLauncher extends AbstractLauncher { +import java.lang.invoke.MethodHandle; +public final class StandardLauncher extends AbstractLauncher { public StandardLauncher(Parameters params) { super(params); } @@ -87,5 +86,4 @@ public final class StandardLauncher extends AbstractLauncher { MethodHandle method = ReflectionUtils.findMainMethod(mainClassName); method.invokeExact(gameArgs.toArray(new String[0])); } - } diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java index c215e7fe0..6cfe35d86 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java @@ -54,6 +54,8 @@ package org.prismlauncher.launcher.impl.legacy; +import org.prismlauncher.utils.logging.Log; + import java.applet.Applet; import java.awt.Dimension; import java.awt.event.WindowAdapter; @@ -70,12 +72,9 @@ import java.util.List; import javax.imageio.ImageIO; import javax.swing.JFrame; -import org.prismlauncher.utils.logging.Log; - import net.minecraft.Launcher; public final class LegacyFrame extends JFrame { - private static final long serialVersionUID = 1L; private final Launcher launcher; @@ -96,8 +95,8 @@ public final class LegacyFrame extends JFrame { addWindowListener(new ForceExitHandler()); } - public void start(String user, String session, int width, int height, boolean maximize, String serverAddress, - String serverPort, boolean demo) { + public void start( + String user, String session, int width, int height, boolean maximize, String serverAddress, String serverPort, boolean demo) { // Implements support for launching in to multiplayer on classic servers using a // mpticket file generated by an external program and stored in the instance's // root folder. @@ -157,7 +156,6 @@ public final class LegacyFrame extends JFrame { } private final class ForceExitHandler extends WindowAdapter { - @Override public void windowClosing(WindowEvent event) { // FIXME better solution @@ -184,7 +182,5 @@ public final class LegacyFrame extends JFrame { // old minecraft versions can hang without this >_< System.exit(0); } - } - } diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java index d349177b2..5c5f86d47 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java @@ -55,22 +55,21 @@ package org.prismlauncher.launcher.impl.legacy; +import org.prismlauncher.launcher.impl.AbstractLauncher; +import org.prismlauncher.utils.Parameters; +import org.prismlauncher.utils.ReflectionUtils; +import org.prismlauncher.utils.logging.Log; + import java.io.File; import java.lang.invoke.MethodHandle; import java.lang.reflect.Field; import java.util.Collections; import java.util.List; -import org.prismlauncher.launcher.impl.AbstractLauncher; -import org.prismlauncher.utils.Parameters; -import org.prismlauncher.utils.ReflectionUtils; -import org.prismlauncher.utils.logging.Log; - /** * Used to launch old versions that support applets. */ public final class LegacyLauncher extends AbstractLauncher { - private final String user, session; private final String title; private final String appletClass; @@ -109,8 +108,7 @@ public final class LegacyLauncher extends AbstractLauncher { try { LegacyFrame window = new LegacyFrame(title, ReflectionUtils.createAppletClass(appletClass)); - window.start(user, session, width, height, maximize, serverAddress, serverPort, - gameArgs.contains("--demo")); + window.start(user, session, width, height, maximize, serverAddress, serverPort, gameArgs.contains("--demo")); return; } catch (Throwable e) { Log.error("Running applet wrapper failed with exception; falling back to main class", e); @@ -122,5 +120,4 @@ public final class LegacyLauncher extends AbstractLauncher { MethodHandle method = ReflectionUtils.findMainMethod(main); method.invokeExact(gameArgs.toArray(new String[0])); } - } diff --git a/libraries/launcher/org/prismlauncher/utils/Parameters.java b/libraries/launcher/org/prismlauncher/utils/Parameters.java index 6365753e2..2b0aed22a 100644 --- a/libraries/launcher/org/prismlauncher/utils/Parameters.java +++ b/libraries/launcher/org/prismlauncher/utils/Parameters.java @@ -54,15 +54,14 @@ package org.prismlauncher.utils; +import org.prismlauncher.exception.ParameterNotFoundException; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.prismlauncher.exception.ParameterNotFoundException; - public final class Parameters { - private final Map> map = new HashMap<>(); public void add(String key, String value) { @@ -112,5 +111,4 @@ public final class Parameters { return params.get(0); } - } diff --git a/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java b/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java index dd212ef93..ad222bd2a 100644 --- a/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java +++ b/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java @@ -54,6 +54,8 @@ package org.prismlauncher.utils; +import org.prismlauncher.utils.logging.Log; + import java.applet.Applet; import java.io.File; import java.lang.invoke.MethodHandle; @@ -62,10 +64,7 @@ import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import org.prismlauncher.utils.logging.Log; - public final class ReflectionUtils { - private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); private static final ClassLoader LOADER = ClassLoader.getSystemClassLoader(); @@ -146,9 +145,7 @@ public final class ReflectionUtils { * @throws NoSuchMethodException * @throws IllegalAccessException */ - public static MethodHandle findMainMethod(String clazz) - throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException { + public static MethodHandle findMainMethod(String clazz) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException { return findMainMethod(LOADER.loadClass(clazz)); } - } diff --git a/libraries/launcher/org/prismlauncher/utils/logging/Level.java b/libraries/launcher/org/prismlauncher/utils/logging/Level.java index 552b0b55e..7af9c34a0 100644 --- a/libraries/launcher/org/prismlauncher/utils/logging/Level.java +++ b/libraries/launcher/org/prismlauncher/utils/logging/Level.java @@ -55,5 +55,4 @@ public enum Level { this.name = name; this.stderr = stderr; } - } diff --git a/libraries/launcher/org/prismlauncher/utils/logging/Log.java b/libraries/launcher/org/prismlauncher/utils/logging/Log.java index e3aa538b2..992698e55 100644 --- a/libraries/launcher/org/prismlauncher/utils/logging/Log.java +++ b/libraries/launcher/org/prismlauncher/utils/logging/Log.java @@ -43,9 +43,8 @@ import java.io.PrintStream; * messages. */ public final class Log { - // original before possibly overridden by MC - private static final PrintStream OUT = new PrintStream(System.out), ERR = new PrintStream(System.err); + private static final PrintStream OUT = new PrintStream(System.out), ERR = new PrintStream(System.err); private static final boolean DEBUG = Boolean.getBoolean("org.prismlauncher.debug"); public static void launcher(String message) { @@ -100,5 +99,4 @@ public final class Log { else OUT.println(message); } - } diff --git a/libraries/murmur2/src/MurmurHash2.h b/libraries/murmur2/src/MurmurHash2.h index dc2c9681d..5d4f48713 100644 --- a/libraries/murmur2/src/MurmurHash2.h +++ b/libraries/murmur2/src/MurmurHash2.h @@ -16,11 +16,11 @@ //----------------------------------------------------------------------------- #define KiB 1024 -#define MiB 1024*KiB +#define MiB 1024 * KiB uint32_t MurmurHash2( std::ifstream&& file_stream, - std::size_t buffer_size = 4*MiB, + std::size_t buffer_size = 4 * MiB, std::function filter_out = [](char) { return false; }); struct IncrementalHashInfo { diff --git a/libraries/rainbow/include/rainbow.h b/libraries/rainbow/include/rainbow.h index 57be87f14..a75e53ee7 100644 --- a/libraries/rainbow/include/rainbow.h +++ b/libraries/rainbow/include/rainbow.h @@ -29,8 +29,7 @@ class QColor; /** * A set of methods used to work with colors. */ -namespace Rainbow -{ +namespace Rainbow { /** * Calculate the luma of a color. Luma is weighted sum of gamma-adjusted * R'G'B' components of a color. The result is similar to qGray. The range @@ -41,14 +40,13 @@ namespace Rainbow * * @see http://en.wikipedia.org/wiki/Luma_(video) */ -qreal luma(const QColor &); +qreal luma(const QColor&); /** * Calculate hue, chroma and luma of a color in one call. * @since 5.0 */ -void getHcy(const QColor &, qreal *hue, qreal *chroma, qreal *luma, - qreal *alpha = 0); +void getHcy(const QColor&, qreal* hue, qreal* chroma, qreal* luma, qreal* alpha = 0); /** * Calculate the contrast ratio between two colors, according to the @@ -62,7 +60,7 @@ void getHcy(const QColor &, qreal *hue, qreal *chroma, qreal *luma, * * @see Rainbow::luma */ -qreal contrastRatio(const QColor &, const QColor &); +qreal contrastRatio(const QColor&, const QColor&); /** * Adjust the luma of a color by changing its distance from white. @@ -79,8 +77,7 @@ qreal contrastRatio(const QColor &, const QColor &); * component of the color; 1.0 means no change, 0.0 maximizes chroma * @see Rainbow::shade */ -QColor -lighten(const QColor &, qreal amount = 0.5, qreal chromaInverseGain = 1.0); +QColor lighten(const QColor&, qreal amount = 0.5, qreal chromaInverseGain = 1.0); /** * Adjust the luma of a color by changing its distance from black. @@ -97,7 +94,7 @@ lighten(const QColor &, qreal amount = 0.5, qreal chromaInverseGain = 1.0); * component of the color; 1.0 means no change, 0.0 minimizes chroma * @see Rainbow::shade */ -QColor darken(const QColor &, qreal amount = 0.5, qreal chromaGain = 1.0); +QColor darken(const QColor&, qreal amount = 0.5, qreal chromaGain = 1.0); /** * Adjust the luma and chroma components of a color. The amount is added @@ -111,7 +108,7 @@ QColor darken(const QColor &, qreal amount = 0.5, qreal chromaGain = 1.0); * 1.0 maximizes chroma * @see Rainbow::luma */ -QColor shade(const QColor &, qreal lumaAmount, qreal chromaAmount = 0.0); +QColor shade(const QColor&, qreal lumaAmount, qreal chromaAmount = 0.0); /** * Create a new color by tinting one color with another. This function is @@ -125,7 +122,7 @@ QColor shade(const QColor &, qreal lumaAmount, qreal chromaAmount = 0.0); * @param amount how strongly to tint the base; 0.0 gives @p base, * 1.0 gives @p color */ -QColor tint(const QColor &base, const QColor &color, qreal amount = 0.3); +QColor tint(const QColor& base, const QColor& color, qreal amount = 0.3); /** * Blend two colors into a new color by linear combination. @@ -138,7 +135,7 @@ QColor tint(const QColor &base, const QColor &color, qreal amount = 0.3); * @p bias >= 1 gives @p c2. @p bias == 0.5 gives a 50% blend of @p c1 * and @p c2. */ -QColor mix(const QColor &c1, const QColor &c2, qreal bias = 0.5); +QColor mix(const QColor& c1, const QColor& c2, qreal bias = 0.5); /** * Blend two colors into a new color by painting the second color over the @@ -152,7 +149,5 @@ QColor mix(const QColor &c1, const QColor &c2, qreal bias = 0.5); * @param paint the color to be overlayed onto the base color. * @param comp the CompositionMode used to do the blending. */ -QColor -overlayColors(const QColor &base, const QColor &paint, - QPainter::CompositionMode comp = QPainter::CompositionMode_SourceOver); -} +QColor overlayColors(const QColor& base, const QColor& paint, QPainter::CompositionMode comp = QPainter::CompositionMode_SourceOver); +} // namespace Rainbow diff --git a/libraries/rainbow/src/rainbow.cpp b/libraries/rainbow/src/rainbow.cpp index 9054d71dd..5ef196520 100644 --- a/libraries/rainbow/src/rainbow.cpp +++ b/libraries/rainbow/src/rainbow.cpp @@ -25,11 +25,11 @@ #include #include -#include // qIsNaN +#include // qIsNaN #include -//BEGIN internal helper functions +// BEGIN internal helper functions static inline qreal wrap(qreal a, qreal d = 1.0) { @@ -44,23 +44,21 @@ static inline qreal normalize(qreal a) return (a < 1.0 ? (a > 0.0 ? a : 0.0) : 1.0); } - /////////////////////////////////////////////////////////////////////////////// // HCY color space -#define HCY_REC 709 // use 709 for now +#define HCY_REC 709 // use 709 for now #if HCY_REC == 601 -static const qreal yc[3] = {0.299, 0.587, 0.114}; +static const qreal yc[3] = { 0.299, 0.587, 0.114 }; #elif HCY_REC == 709 -static const qreal yc[3] = {0.2126, 0.7152, 0.0722}; -#else // use Qt values -static const qreal yc[3] = {0.34375, 0.5, 0.15625}; +static const qreal yc[3] = { 0.2126, 0.7152, 0.0722 }; +#else // use Qt values +static const qreal yc[3] = { 0.34375, 0.5, 0.15625 }; #endif -class KHCY -{ -public: - explicit KHCY(const QColor &color) +class KHCY { + public: + explicit KHCY(const QColor& color) { qreal r = gamma(color.redF()); qreal g = gamma(color.greenF()); @@ -74,30 +72,20 @@ public: qreal p = qMax(qMax(r, g), b); qreal n = qMin(qMin(r, g), b); qreal d = 6.0 * (p - n); - if (n == p) - { + if (n == p) { h = 0.0; - } - else if (r == p) - { + } else if (r == p) { h = ((g - b) / d); - } - else if (g == p) - { + } else if (g == p) { h = ((b - r) / d) + (1.0 / 3.0); - } - else - { + } else { h = ((r - g) / d) + (2.0 / 3.0); } // chroma component - if (r == g && g == b) - { + if (r == g && g == b) { c = 0.0; - } - else - { + } else { c = qMax((y - n) / y, (p - y) / (1 - y)); } } @@ -118,145 +106,103 @@ public: // calculate some needed variables qreal _hs = _h * 6.0, th, tm; - if (_hs < 1.0) - { + if (_hs < 1.0) { th = _hs; tm = yc[0] + yc[1] * th; - } - else if (_hs < 2.0) - { + } else if (_hs < 2.0) { th = 2.0 - _hs; tm = yc[1] + yc[0] * th; - } - else if (_hs < 3.0) - { + } else if (_hs < 3.0) { th = _hs - 2.0; tm = yc[1] + yc[2] * th; - } - else if (_hs < 4.0) - { + } else if (_hs < 4.0) { th = 4.0 - _hs; tm = yc[2] + yc[1] * th; - } - else if (_hs < 5.0) - { + } else if (_hs < 5.0) { th = _hs - 4.0; tm = yc[2] + yc[0] * th; - } - else - { + } else { th = 6.0 - _hs; tm = yc[0] + yc[2] * th; } // calculate RGB channels in sorted order qreal tn, to, tp; - if (tm >= _y) - { + if (tm >= _y) { tp = _y + _y * _c * (1.0 - tm) / tm; to = _y + _y * _c * (th - tm) / tm; tn = _y - (_y * _c); - } - else - { + } else { tp = _y + (1.0 - _y) * _c; to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm); tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm); } // return RGB channels in appropriate order - if (_hs < 1.0) - { + if (_hs < 1.0) { return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a); - } - else if (_hs < 2.0) - { + } else if (_hs < 2.0) { return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a); - } - else if (_hs < 3.0) - { + } else if (_hs < 3.0) { return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a); - } - else if (_hs < 4.0) - { + } else if (_hs < 4.0) { return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a); - } - else if (_hs < 5.0) - { + } else if (_hs < 5.0) { return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a); - } - else - { + } else { return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a); } } qreal h, c, y, a; - static qreal luma(const QColor &color) - { - return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF())); - } + static qreal luma(const QColor& color) { return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF())); } -private: - static qreal gamma(qreal n) - { - return pow(normalize(n), 2.2); - } - static qreal igamma(qreal n) - { - return pow(normalize(n), 1.0 / 2.2); - } - static qreal lumag(qreal r, qreal g, qreal b) - { - return r * yc[0] + g * yc[1] + b * yc[2]; - } + private: + static qreal gamma(qreal n) { return pow(normalize(n), 2.2); } + static qreal igamma(qreal n) { return pow(normalize(n), 1.0 / 2.2); } + static qreal lumag(qreal r, qreal g, qreal b) { return r * yc[0] + g * yc[1] + b * yc[2]; } }; static inline qreal mixQreal(qreal a, qreal b, qreal bias) { return a + (b - a) * bias; } -//END internal helper functions +// END internal helper functions -qreal Rainbow::luma(const QColor &color) +qreal Rainbow::luma(const QColor& color) { return KHCY::luma(color); } -void Rainbow::getHcy(const QColor &color, qreal *h, qreal *c, qreal *y, qreal *a) +void Rainbow::getHcy(const QColor& color, qreal* h, qreal* c, qreal* y, qreal* a) { - if (!c || !h || !y) - { + if (!c || !h || !y) { return; } KHCY khcy(color); *c = khcy.c; *h = khcy.h; *y = khcy.y; - if (a) - { + if (a) { *a = khcy.a; } } static qreal contrastRatioForLuma(qreal y1, qreal y2) { - if (y1 > y2) - { + if (y1 > y2) { return (y1 + 0.05) / (y2 + 0.05); - } - else - { + } else { return (y2 + 0.05) / (y1 + 0.05); } } -qreal Rainbow::contrastRatio(const QColor &c1, const QColor &c2) +qreal Rainbow::contrastRatio(const QColor& c1, const QColor& c2) { return contrastRatioForLuma(luma(c1), luma(c2)); } -QColor Rainbow::lighten(const QColor &color, qreal ky, qreal kc) +QColor Rainbow::lighten(const QColor& color, qreal ky, qreal kc) { KHCY c(color); c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky)); @@ -264,7 +210,7 @@ QColor Rainbow::lighten(const QColor &color, qreal ky, qreal kc) return c.qColor(); } -QColor Rainbow::darken(const QColor &color, qreal ky, qreal kc) +QColor Rainbow::darken(const QColor& color, qreal ky, qreal kc) { KHCY c(color); c.y = normalize(c.y * (1.0 - ky)); @@ -272,7 +218,7 @@ QColor Rainbow::darken(const QColor &color, qreal ky, qreal kc) return c.qColor(); } -QColor Rainbow::shade(const QColor &color, qreal ky, qreal kc) +QColor Rainbow::shade(const QColor& color, qreal ky, qreal kc) { KHCY c(color); c.y = normalize(c.y + ky); @@ -280,7 +226,7 @@ QColor Rainbow::shade(const QColor &color, qreal ky, qreal kc) return c.qColor(); } -static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color, qreal amount) +static QColor tintHelper(const QColor& base, qreal baseLuma, const QColor& color, qreal amount) { KHCY result(Rainbow::mix(base, color, pow(amount, 0.3))); result.y = mixQreal(baseLuma, result.y, amount); @@ -288,55 +234,45 @@ static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color return result.qColor(); } -QColor Rainbow::tint(const QColor &base, const QColor &color, qreal amount) +QColor Rainbow::tint(const QColor& base, const QColor& color, qreal amount) { - if (amount <= 0.0) - { + if (amount <= 0.0) { return base; } - if (amount >= 1.0) - { + if (amount >= 1.0) { return color; } - if (qIsNaN(amount)) - { + if (qIsNaN(amount)) { return base; } - qreal baseLuma = luma(base); // cache value because luma call is expensive + qreal baseLuma = luma(base); // cache value because luma call is expensive double ri = contrastRatioForLuma(baseLuma, luma(color)); double rg = 1.0 + ((ri + 1.0) * amount * amount * amount); double u = 1.0, l = 0.0; QColor result; - for (int i = 12; i; --i) - { + for (int i = 12; i; --i) { double a = 0.5 * (l + u); result = tintHelper(base, baseLuma, color, a); double ra = contrastRatioForLuma(baseLuma, luma(result)); - if (ra > rg) - { + if (ra > rg) { u = a; - } - else - { + } else { l = a; } } return result; } -QColor Rainbow::mix(const QColor &c1, const QColor &c2, qreal bias) +QColor Rainbow::mix(const QColor& c1, const QColor& c2, qreal bias) { - if (bias <= 0.0) - { + if (bias <= 0.0) { return c1; } - if (bias >= 1.0) - { + if (bias >= 1.0) { return c2; } - if (qIsNaN(bias)) - { + if (qIsNaN(bias)) { return c1; } @@ -348,15 +284,14 @@ QColor Rainbow::mix(const QColor &c1, const QColor &c2, qreal bias) return QColor::fromRgbF(r, g, b, a); } -QColor Rainbow::overlayColors(const QColor &base, const QColor &paint, - QPainter::CompositionMode comp) +QColor Rainbow::overlayColors(const QColor& base, const QColor& paint, QPainter::CompositionMode comp) { // This isn't the fastest way, but should be "fast enough". // It's also the only safe way to use QPainter::CompositionMode QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); QPainter p(&img); QColor start = base; - start.setAlpha(255); // opaque + start.setAlpha(255); // opaque p.fillRect(0, 0, 1, 1, start); p.setCompositionMode(comp); p.fillRect(0, 0, 1, 1, paint); diff --git a/libraries/systeminfo/include/distroutils.h b/libraries/systeminfo/include/distroutils.h index 2e85f4336..caa2688cf 100644 --- a/libraries/systeminfo/include/distroutils.h +++ b/libraries/systeminfo/include/distroutils.h @@ -1,23 +1,22 @@ -#include "sys.h" #include +#include "sys.h" namespace Sys { -struct LsbInfo -{ +struct LsbInfo { QString distributor; QString version; QString description; QString codename; }; -bool main_lsb_info(LsbInfo & out); -bool fallback_lsb_info(Sys::LsbInfo & out); -void lsb_postprocess(Sys::LsbInfo & lsb, Sys::DistributionInfo & out); +bool main_lsb_info(LsbInfo& out); +bool fallback_lsb_info(Sys::LsbInfo& out); +void lsb_postprocess(Sys::LsbInfo& lsb, Sys::DistributionInfo& out); Sys::DistributionInfo read_lsb_release(); -QString _extract_distribution(const QString & x); -QString _extract_version(const QString & x); +QString _extract_distribution(const QString& x); +QString _extract_version(const QString& x); Sys::DistributionInfo read_legacy_release(); Sys::DistributionInfo read_os_release(); -} +} // namespace Sys diff --git a/libraries/systeminfo/include/sys.h b/libraries/systeminfo/include/sys.h index 6a6a7c82f..dfebbe90b 100644 --- a/libraries/systeminfo/include/sys.h +++ b/libraries/systeminfo/include/sys.h @@ -1,19 +1,12 @@ #pragma once #include -namespace Sys -{ +namespace Sys { const uint64_t mebibyte = 1024ull * 1024ull; -enum class KernelType { - Undetermined, - Windows, - Darwin, - Linux -}; +enum class KernelType { Undetermined, Windows, Darwin, Linux }; -struct KernelInfo -{ +struct KernelInfo { QString kernelName; QString kernelVersion; @@ -26,25 +19,18 @@ struct KernelInfo KernelInfo getKernelInfo(); -struct DistributionInfo -{ +struct DistributionInfo { DistributionInfo operator+(const DistributionInfo& rhs) const { DistributionInfo out; - if(!distributionName.isEmpty()) - { + if (!distributionName.isEmpty()) { out.distributionName = distributionName; - } - else - { + } else { out.distributionName = rhs.distributionName; } - if(!distributionVersion.isEmpty()) - { + if (!distributionVersion.isEmpty()) { out.distributionVersion = distributionVersion; - } - else - { + } else { out.distributionVersion = rhs.distributionVersion; } return out; @@ -56,4 +42,4 @@ struct DistributionInfo DistributionInfo getDistributionInfo(); uint64_t getSystemRam(); -} +} // namespace Sys diff --git a/libraries/systeminfo/src/distroutils.cpp b/libraries/systeminfo/src/distroutils.cpp index 05e1bb8cd..57e6c8320 100644 --- a/libraries/systeminfo/src/distroutils.cpp +++ b/libraries/systeminfo/src/distroutils.cpp @@ -29,14 +29,14 @@ SOFTWARE. #include "distroutils.h" -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include +#include +#include #include @@ -46,38 +46,27 @@ Sys::DistributionInfo Sys::read_os_release() QStringList files = { "/etc/os-release", "/usr/lib/os-release" }; QString name; QString version; - for (auto &file: files) - { - if(!QFile::exists(file)) - { + for (auto& file : files) { + if (!QFile::exists(file)) { continue; } QSettings settings(file, QSettings::IniFormat); - if(settings.contains("ID")) - { + if (settings.contains("ID")) { name = settings.value("ID").toString().toLower(); - } - else if (settings.contains("NAME")) - { + } else if (settings.contains("NAME")) { name = settings.value("NAME").toString().toLower(); - } - else - { + } else { continue; } - if(settings.contains("VERSION_ID")) - { + if (settings.contains("VERSION_ID")) { version = settings.value("VERSION_ID").toString().toLower(); - } - else if(settings.contains("VERSION")) - { + } else if (settings.contains("VERSION")) { version = settings.value("VERSION").toString().toLower(); } break; } - if(name.isEmpty()) - { + if (name.isEmpty()) { return out; } out.distributionName = name; @@ -85,33 +74,31 @@ Sys::DistributionInfo Sys::read_os_release() return out; } -bool Sys::main_lsb_info(Sys::LsbInfo & out) +bool Sys::main_lsb_info(Sys::LsbInfo& out) { - int status=0; + int status = 0; QProcess lsbProcess; QStringList arguments; arguments << "-a"; - lsbProcess.start("lsb_release", arguments); + lsbProcess.start("lsb_release", arguments); lsbProcess.waitForFinished(); status = lsbProcess.exitStatus(); QString output = lsbProcess.readAllStandardOutput(); qDebug() << output; lsbProcess.close(); - if(status == 0) - { + if (status == 0) { auto lines = output.split('\n'); - for(auto line:lines) - { + for (auto line : lines) { int index = line.indexOf(':'); auto key = line.left(index).trimmed(); auto value = line.mid(index + 1).toLower().trimmed(); - if(key == "Distributor ID") + if (key == "Distributor ID") out.distributor = value; - else if(key == "Release") + else if (key == "Release") out.version = value; - else if(key == "Description") + else if (key == "Description") out.description = value; - else if(key == "Codename") + else if (key == "Codename") out.codename = value; } return !out.distributor.isEmpty(); @@ -119,7 +106,7 @@ bool Sys::main_lsb_info(Sys::LsbInfo & out) return false; } -bool Sys::fallback_lsb_info(Sys::LsbInfo & out) +bool Sys::fallback_lsb_info(Sys::LsbInfo& out) { // running lsb_release failed, try to read the file instead // /etc/lsb-release format, if the file even exists, is non-standard. @@ -127,15 +114,12 @@ bool Sys::fallback_lsb_info(Sys::LsbInfo & out) // distributions install an /etc/lsb-release as part of the base // distribution, but `lsb_release` remains optional. QString file = "/etc/lsb-release"; - if (QFile::exists(file)) - { + if (QFile::exists(file)) { QSettings settings(file, QSettings::IniFormat); - if(settings.contains("DISTRIB_ID")) - { + if (settings.contains("DISTRIB_ID")) { out.distributor = settings.value("DISTRIB_ID").toString().toLower(); } - if(settings.contains("DISTRIB_RELEASE")) - { + if (settings.contains("DISTRIB_RELEASE")) { out.version = settings.value("DISTRIB_RELEASE").toString().toLower(); } return !out.distributor.isEmpty(); @@ -143,48 +127,34 @@ bool Sys::fallback_lsb_info(Sys::LsbInfo & out) return false; } -void Sys::lsb_postprocess(Sys::LsbInfo & lsb, Sys::DistributionInfo & out) +void Sys::lsb_postprocess(Sys::LsbInfo& lsb, Sys::DistributionInfo& out) { QString dist = lsb.distributor; QString vers = lsb.version; - if(dist.startsWith("redhatenterprise")) - { + if (dist.startsWith("redhatenterprise")) { dist = "rhel"; - } - else if(dist == "archlinux") - { + } else if (dist == "archlinux") { dist = "arch"; - } - else if (dist.startsWith("suse")) - { - if(lsb.description.startsWith("opensuse")) - { + } else if (dist.startsWith("suse")) { + if (lsb.description.startsWith("opensuse")) { dist = "opensuse"; - } - else if (lsb.description.startsWith("suse linux enterprise")) - { + } else if (lsb.description.startsWith("suse linux enterprise")) { dist = "sles"; } - } - else if (dist == "debian" and vers == "testing") - { + } else if (dist == "debian" and vers == "testing") { vers = lsb.codename; - } - else - { + } else { // ubuntu, debian, gentoo, scientific, slackware, ... ? #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto parts = dist.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); #else auto parts = dist.split(QRegularExpression("\\s+"), QString::SkipEmptyParts); #endif - if(parts.size()) - { + if (parts.size()) { dist = parts[0]; } } - if(!dist.isEmpty()) - { + if (!dist.isEmpty()) { out.distributionName = dist; out.distributionVersion = vers; } @@ -193,10 +163,8 @@ void Sys::lsb_postprocess(Sys::LsbInfo & lsb, Sys::DistributionInfo & out) Sys::DistributionInfo Sys::read_lsb_release() { LsbInfo lsb; - if(!main_lsb_info(lsb)) - { - if(!fallback_lsb_info(lsb)) - { + if (!main_lsb_info(lsb)) { + if (!fallback_lsb_info(lsb)) { return Sys::DistributionInfo(); } } @@ -205,15 +173,13 @@ Sys::DistributionInfo Sys::read_lsb_release() return out; } -QString Sys::_extract_distribution(const QString & x) +QString Sys::_extract_distribution(const QString& x) { QString release = x.toLower(); - if (release.startsWith("red hat enterprise")) - { + if (release.startsWith("red hat enterprise")) { return "rhel"; } - if (release.startsWith("suse linux enterprise")) - { + if (release.startsWith("suse linux enterprise")) { return "sles"; } #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -221,14 +187,13 @@ QString Sys::_extract_distribution(const QString & x) #else QStringList list = release.split(QRegularExpression("\\s+"), QString::SkipEmptyParts); #endif - if(list.size()) - { + if (list.size()) { return list[0]; } return QString(); } -QString Sys::_extract_version(const QString & x) +QString Sys::_extract_version(const QString& x) { QRegularExpression versionish_string(QRegularExpression::anchoredPattern("\\d+(?:\\.\\d+)*$")); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -236,11 +201,9 @@ QString Sys::_extract_version(const QString & x) #else QStringList list = x.split(QRegularExpression("\\s+"), QString::SkipEmptyParts); #endif - for(int i = list.size() - 1; i >= 0; --i) - { + for (int i = list.size() - 1; i >= 0; --i) { QString chunk = list[i]; - if(versionish_string.match(chunk).hasMatch()) - { + if (versionish_string.match(chunk).hasMatch()) { return chunk; } } @@ -249,43 +212,35 @@ QString Sys::_extract_version(const QString & x) Sys::DistributionInfo Sys::read_legacy_release() { - struct checkEntry - { + struct checkEntry { QString file; - std::function extract_distro; - std::function extract_version; + std::function extract_distro; + std::function extract_version; }; - QList checks = - { - {"/etc/arch-release", [](const QString &){ return "arch";}, [](const QString &){ return "rolling";}}, - {"/etc/slackware-version", &Sys::_extract_distribution, &Sys::_extract_version}, - {QString(), &Sys::_extract_distribution, &Sys::_extract_version}, - {"/etc/debian_version", [](const QString &){ return "debian";}, [](const QString & x){ return x;}}, + QList checks = { + { "/etc/arch-release", [](const QString&) { return "arch"; }, [](const QString&) { return "rolling"; } }, + { "/etc/slackware-version", &Sys::_extract_distribution, &Sys::_extract_version }, + { QString(), &Sys::_extract_distribution, &Sys::_extract_version }, + { "/etc/debian_version", [](const QString&) { return "debian"; }, [](const QString& x) { return x; } }, }; - for(auto & check: checks) - { + for (auto& check : checks) { QStringList files; - if(check.file.isNull()) - { + if (check.file.isNull()) { QDir etcDir("/etc"); - etcDir.setNameFilters({"*-release"}); + etcDir.setNameFilters({ "*-release" }); etcDir.setFilter(QDir::Files | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden); files = etcDir.entryList(); - } - else - { + } else { files.append(check.file); } - for (auto file : files) - { + for (auto file : files) { QFile relfile(file); - if(!relfile.open(QIODevice::ReadOnly | QIODevice::Text)) + if (!relfile.open(QIODevice::ReadOnly | QIODevice::Text)) continue; QString contents = QString::fromUtf8(relfile.readLine()).trimmed(); QString dist = check.extract_distro(contents); QString vers = check.extract_version(contents); - if(!dist.isEmpty()) - { + if (!dist.isEmpty()) { Sys::DistributionInfo out; out.distributionName = dist; out.distributionVersion = vers; @@ -295,4 +250,3 @@ Sys::DistributionInfo Sys::read_legacy_release() } return Sys::DistributionInfo(); } - diff --git a/libraries/systeminfo/src/sys_apple.cpp b/libraries/systeminfo/src/sys_apple.cpp index b6d62c1ae..5cf70f1aa 100644 --- a/libraries/systeminfo/src/sys_apple.cpp +++ b/libraries/systeminfo/src/sys_apple.cpp @@ -2,9 +2,9 @@ #include +#include #include #include -#include Sys::KernelInfo Sys::getKernelInfo() { @@ -22,18 +22,16 @@ Sys::KernelInfo Sys::getKernelInfo() out.kernelMinor = 0; out.kernelPatch = 0; auto sections = release.split('-'); - if(sections.size() >= 1) { + if (sections.size() >= 1) { auto versionParts = sections[0].split('.'); - if(versionParts.size() >= 3) { + if (versionParts.size() >= 3) { out.kernelMajor = versionParts[0].toInt(); out.kernelMinor = versionParts[1].toInt(); out.kernelPatch = versionParts[2].toInt(); - } - else { + } else { qWarning() << "Not enough version numbers in " << sections[0] << " found " << versionParts.size(); } - } - else { + } else { qWarning() << "Not enough '-' sections in " << release << " found " << sections.size(); } return out; @@ -45,12 +43,9 @@ uint64_t Sys::getSystemRam() { uint64_t memsize; size_t memsizesize = sizeof(memsize); - if(!sysctlbyname("hw.memsize", &memsize, &memsizesize, NULL, 0)) - { + if (!sysctlbyname("hw.memsize", &memsize, &memsizesize, NULL, 0)) { return memsize; - } - else - { + } else { return 0; } } diff --git a/libraries/systeminfo/src/sys_test.cpp b/libraries/systeminfo/src/sys_test.cpp index 9a5f9dfa2..50c75eb77 100644 --- a/libraries/systeminfo/src/sys_test.cpp +++ b/libraries/systeminfo/src/sys_test.cpp @@ -2,11 +2,9 @@ #include -class SysTest : public QObject -{ +class SysTest : public QObject { Q_OBJECT -private -slots: + private slots: void test_kernelNotNull() { @@ -14,15 +12,15 @@ slots: QVERIFY(!kinfo.kernelName.isEmpty()); QVERIFY(kinfo.kernelVersion != "0.0"); } -/* - void test_systemDistroNotNull() - { - auto kinfo = Sys::getDistributionInfo(); - QVERIFY(!kinfo.distributionName.isEmpty()); - QVERIFY(!kinfo.distributionVersion.isEmpty()); - qDebug() << "Distro: " << kinfo.distributionName << "version" << kinfo.distributionVersion; - } -*/ + /* + void test_systemDistroNotNull() + { + auto kinfo = Sys::getDistributionInfo(); + QVERIFY(!kinfo.distributionName.isEmpty()); + QVERIFY(!kinfo.distributionVersion.isEmpty()); + qDebug() << "Distro: " << kinfo.distributionName << "version" << kinfo.distributionVersion; + } + */ }; QTEST_GUILESS_MAIN(SysTest) diff --git a/libraries/systeminfo/src/sys_unix.cpp b/libraries/systeminfo/src/sys_unix.cpp index 3c63e73a4..4e075959a 100644 --- a/libraries/systeminfo/src/sys_unix.cpp +++ b/libraries/systeminfo/src/sys_unix.cpp @@ -6,9 +6,9 @@ #include #include +#include #include #include -#include Sys::KernelInfo Sys::getKernelInfo() { @@ -27,18 +27,16 @@ Sys::KernelInfo Sys::getKernelInfo() out.kernelMinor = 0; out.kernelPatch = 0; auto sections = release.split('-'); - if(sections.size() >= 1) { + if (sections.size() >= 1) { auto versionParts = sections[0].split('.'); - if(versionParts.size() >= 3) { + if (versionParts.size() >= 3) { out.kernelMajor = versionParts[0].toInt(); out.kernelMinor = versionParts[1].toInt(); out.kernelPatch = versionParts[2].toInt(); - } - else { + } else { qWarning() << "Not enough version numbers in " << sections[0] << " found " << versionParts.size(); } - } - else { + } else { qWarning() << "Not enough '-' sections in " << release << " found " << sections.size(); } return out; @@ -49,17 +47,12 @@ uint64_t Sys::getSystemRam() std::string token; #ifdef Q_OS_LINUX std::ifstream file("/proc/meminfo"); - while(file >> token) - { - if(token == "MemTotal:") - { + while (file >> token) { + if (token == "MemTotal:") { uint64_t mem; - if(file >> mem) - { + if (file >> mem) { return mem * 1024ull; - } - else - { + } else { return 0; } } @@ -68,18 +61,16 @@ uint64_t Sys::getSystemRam() } #elif defined(Q_OS_FREEBSD) char buff[512]; - FILE *fp = popen("sysctl hw.physmem", "r"); - if (fp != NULL) - { - while(fgets(buff, 512, fp) != NULL) - { - std::string str(buff); - uint64_t mem = std::stoull(str.substr(12, std::string::npos)); - return mem * 1024ull; - } + FILE* fp = popen("sysctl hw.physmem", "r"); + if (fp != NULL) { + while (fgets(buff, 512, fp) != NULL) { + std::string str(buff); + uint64_t mem = std::stoull(str.substr(12, std::string::npos)); + return mem * 1024ull; + } } #endif - return 0; // nothing found + return 0; // nothing found } Sys::DistributionInfo Sys::getDistributionInfo() @@ -88,18 +79,13 @@ Sys::DistributionInfo Sys::getDistributionInfo() DistributionInfo lsb_info = read_lsb_release(); DistributionInfo legacy_info = read_legacy_release(); DistributionInfo result = systemd_info + lsb_info + legacy_info; - if(result.distributionName.isNull()) - { + if (result.distributionName.isNull()) { result.distributionName = "unknown"; } - if(result.distributionVersion.isNull()) - { - if(result.distributionName == "arch") - { + if (result.distributionVersion.isNull()) { + if (result.distributionName == "arch") { result.distributionVersion = "rolling"; - } - else - { + } else { result.distributionVersion = "unknown"; } } diff --git a/libraries/systeminfo/src/sys_win32.cpp b/libraries/systeminfo/src/sys_win32.cpp index 5bf510cf8..2627761d1 100644 --- a/libraries/systeminfo/src/sys_win32.cpp +++ b/libraries/systeminfo/src/sys_win32.cpp @@ -22,7 +22,7 @@ uint64_t Sys::getSystemRam() { MEMORYSTATUSEX status; status.dwLength = sizeof(status); - GlobalMemoryStatusEx( &status ); + GlobalMemoryStatusEx(&status); // bytes return (uint64_t)status.ullTotalPhys; } diff --git a/renovate.json b/renovate.json index d97a8dc6c..71581e3b0 100644 --- a/renovate.json +++ b/renovate.json @@ -1,12 +1,12 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:base" - ], - "nix": { - "enabled": true - }, - "lockFileMaintenance": { - "enabled": true - } + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ], + "nix": { + "enabled": true + }, + "lockFileMaintenance": { + "enabled": true + } } diff --git a/tests/DataPackParse_test.cpp b/tests/DataPackParse_test.cpp index 61ce1e2b1..cd6ae8e8f 100644 --- a/tests/DataPackParse_test.cpp +++ b/tests/DataPackParse_test.cpp @@ -30,13 +30,13 @@ class DataPackParseTest : public QObject { Q_OBJECT - private slots: + private slots: void test_parseZIP() { QString source = QFINDTESTDATA("testdata/DataPackParse"); QString zip_dp = FS::PathCombine(source, "test_data_pack_boogaloo.zip"); - DataPack pack { QFileInfo(zip_dp) }; + DataPack pack{ QFileInfo(zip_dp) }; bool valid = DataPackUtils::processZIP(pack); @@ -50,7 +50,7 @@ class DataPackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/DataPackParse"); QString folder_dp = FS::PathCombine(source, "test_folder"); - DataPack pack { QFileInfo(folder_dp) }; + DataPack pack{ QFileInfo(folder_dp) }; bool valid = DataPackUtils::processFolder(pack); @@ -64,7 +64,7 @@ class DataPackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/DataPackParse"); QString folder_dp = FS::PathCombine(source, "another_test_folder"); - DataPack pack { QFileInfo(folder_dp) }; + DataPack pack{ QFileInfo(folder_dp) }; bool valid = DataPackUtils::process(pack); diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp index a41345c2e..3adcd3432 100644 --- a/tests/FileSystem_test.cpp +++ b/tests/FileSystem_test.cpp @@ -1,7 +1,7 @@ -#include #include -#include #include +#include +#include #include @@ -11,16 +11,16 @@ // Snippet from https://github.com/gulrak/filesystem#using-it-as-single-file-header #ifdef __APPLE__ -#include // for deployment target to support pre-catalina targets without std::fs -#endif // __APPLE__ +#include // for deployment target to support pre-catalina targets without std::fs +#endif // __APPLE__ #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include) #if __has_include() && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) #define GHC_USE_STD_FS #include namespace fs = std::filesystem; -#endif // MacOS min version check -#endif // Other OSes version check +#endif // MacOS min version check +#endif // Other OSes version check #ifndef GHC_USE_STD_FS #include @@ -29,8 +29,6 @@ namespace fs = ghc::filesystem; #include - - class LinkTask : public Task { Q_OBJECT @@ -42,41 +40,30 @@ class LinkTask : public Task { m_lnk->debug(true); } - ~LinkTask() { - delete m_lnk; - } + ~LinkTask() { delete m_lnk; } - void matcher(const IPathMatcher *filter) - { - m_lnk->matcher(filter); - } + void matcher(const IPathMatcher* filter) { m_lnk->matcher(filter); } - void linkRecursively(bool recursive) + void linkRecursively(bool recursive) { m_lnk->linkRecursively(recursive); m_linkRecursive = recursive; } - void whitelist(bool b) - { - m_lnk->whitelist(b); - } + void whitelist(bool b) { m_lnk->whitelist(b); } - void setMaxDepth(int depth) - { - m_lnk->setMaxDepth(depth); - } + void setMaxDepth(int depth) { m_lnk->setMaxDepth(depth); } private: void executeTask() override { - if(!(*m_lnk)()){ + if (!(*m_lnk)()) { #if defined Q_OS_WIN32 if (!m_useHard) { qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks"; qDebug() << "atempting to run with privelage"; - connect(m_lnk, &FS::create_link::finishedPrivileged, this, [&](bool gotResults){ + connect(m_lnk, &FS::create_link::finishedPrivileged, this, [&](bool gotResults) { if (gotResults) { emitSucceeded(); } else { @@ -87,32 +74,28 @@ class LinkTask : public Task { m_lnk->runPrivileged(); } else { qDebug() << "Link Failed!" << m_lnk->getOSError().value() << m_lnk->getOSError().message().c_str(); - } + } #else qDebug() << "Link Failed!" << m_lnk->getOSError().value() << m_lnk->getOSError().message().c_str(); #endif } else { emitSucceeded(); } - }; - FS::create_link *m_lnk; + FS::create_link* m_lnk; bool m_useHard = false; bool m_linkRecursive = true; }; - -class FileSystemTest : public QObject -{ +class FileSystemTest : public QObject { Q_OBJECT const QString bothSlash = "/foo/"; const QString trailingSlash = "foo/"; const QString leadingSlash = "/foo"; -private -slots: + private slots: void test_pathCombine() { QCOMPARE(QString("/foo/foo"), FS::PathCombine(bothSlash, bothSlash)); @@ -130,12 +113,22 @@ slots: QTest::addColumn("path1"); QTest::addColumn("path2"); - QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc/def" << "ghi/jkl"; - QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/def/" << "ghi/jkl"; + QTest::newRow("qt 1") << "/abc/def/ghi/jkl" + << "/abc/def" + << "ghi/jkl"; + QTest::newRow("qt 2") << "/abc/def/ghi/jkl" + << "/abc/def/" + << "ghi/jkl"; #if defined(Q_OS_WIN) - QTest::newRow("win native, from C:") << "C:/abc" << "C:" << "abc"; - QTest::newRow("win native 1") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def" << "ghi\\jkl"; - QTest::newRow("win native 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def\\" << "ghi\\jkl"; + QTest::newRow("win native, from C:") << "C:/abc" + << "C:" + << "abc"; + QTest::newRow("win native 1") << "C:/abc/def/ghi/jkl" + << "C:\\abc\\def" + << "ghi\\jkl"; + QTest::newRow("win native 2") << "C:/abc/def/ghi/jkl" + << "C:\\abc\\def\\" + << "ghi\\jkl"; #endif } @@ -155,15 +148,39 @@ slots: QTest::addColumn("path2"); QTest::addColumn("path3"); - QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc" << "def" << "ghi/jkl"; - QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/" << "def" << "ghi/jkl"; - QTest::newRow("qt 3") << "/abc/def/ghi/jkl" << "/abc" << "def/" << "ghi/jkl"; - QTest::newRow("qt 4") << "/abc/def/ghi/jkl" << "/abc/" << "def/" << "ghi/jkl"; + QTest::newRow("qt 1") << "/abc/def/ghi/jkl" + << "/abc" + << "def" + << "ghi/jkl"; + QTest::newRow("qt 2") << "/abc/def/ghi/jkl" + << "/abc/" + << "def" + << "ghi/jkl"; + QTest::newRow("qt 3") << "/abc/def/ghi/jkl" + << "/abc" + << "def/" + << "ghi/jkl"; + QTest::newRow("qt 4") << "/abc/def/ghi/jkl" + << "/abc/" + << "def/" + << "ghi/jkl"; #if defined(Q_OS_WIN) - QTest::newRow("win 1") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def" << "ghi\\jkl"; - QTest::newRow("win 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl"; - QTest::newRow("win 3") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def\\" << "ghi\\jkl"; - QTest::newRow("win 4") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl"; + QTest::newRow("win 1") << "C:/abc/def/ghi/jkl" + << "C:\\abc" + << "def" + << "ghi\\jkl"; + QTest::newRow("win 2") << "C:/abc/def/ghi/jkl" + << "C:\\abc\\" + << "def" + << "ghi\\jkl"; + QTest::newRow("win 3") << "C:/abc/def/ghi/jkl" + << "C:\\abc" + << "def\\" + << "ghi\\jkl"; + QTest::newRow("win 4") << "C:/abc/def/ghi/jkl" + << "C:\\abc\\" + << "def" + << "ghi\\jkl"; #endif } @@ -180,8 +197,7 @@ slots: void test_copy() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -192,8 +208,7 @@ slots: FS::copy c(folder, target_dir.path()); c(); - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; } QVERIFY(target_dir.entryList().contains("pack.mcmeta")); @@ -213,8 +228,7 @@ slots: void test_copy_with_blacklist() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -227,8 +241,7 @@ slots: c.matcher(&re); c(); - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; } QVERIFY(!target_dir.entryList().contains("pack.mcmeta")); @@ -248,8 +261,7 @@ slots: void test_copy_with_whitelist() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -263,8 +275,7 @@ slots: c.whitelist(true); c(); - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; } QVERIFY(target_dir.entryList().contains("pack.mcmeta")); @@ -284,8 +295,7 @@ slots: void test_copy_with_dot_hidden() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -298,7 +308,7 @@ slots: auto filter = QDir::Filter::Files | QDir::Filter::Dirs | QDir::Filter::Hidden; - for (auto entry: target_dir.entryList(filter)) { + for (auto entry : target_dir.entryList(filter)) { qDebug() << entry; } @@ -335,7 +345,7 @@ slots: auto filter = QDir::Filter::Files; - for (auto entry: target_dir.entryList(filter)) { + for (auto entry : target_dir.entryList(filter)) { qDebug() << entry; } @@ -348,12 +358,10 @@ slots: QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); } - void test_link() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder, this]() - { + auto f = [&folder, this]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -364,17 +372,13 @@ slots: LinkTask lnk_tsk(folder, target_dir.path()); lnk_tsk.linkRecursively(false); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; QFileInfo entry_lnk_info(target_dir.filePath(entry)); if (!entry_lnk_info.isDir()) @@ -402,10 +406,9 @@ slots: void test_hard_link() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { // use working dir to prevent makeing a hard link to a tmpfs or across devices - QTemporaryDir tempDir("./tmp"); + QTemporaryDir tempDir("./tmp"); tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -415,23 +418,20 @@ slots: FS::create_link lnk(folder, target_dir.path()); lnk.useHardLinks(true); lnk.debug(true); - if(!lnk()){ + if (!lnk()) { qDebug() << "Link Failed!" << lnk.getOSError().value() << lnk.getOSError().message().c_str(); } - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; QFileInfo entry_lnk_info(target_dir.filePath(entry)); QVERIFY(!entry_lnk_info.isSymLink()); QFileInfo entry_orig_info(QDir(folder).filePath(entry)); if (!entry_lnk_info.isDir()) { qDebug() << "hard link equivalency?" << entry_lnk_info.absoluteFilePath() << "vs" << entry_orig_info.absoluteFilePath(); - QVERIFY(fs::equivalent( - fs::path(StringUtils::toStdString(entry_lnk_info.absoluteFilePath())), - fs::path(StringUtils::toStdString(entry_orig_info.absoluteFilePath())) - )); - } + QVERIFY(fs::equivalent(fs::path(StringUtils::toStdString(entry_lnk_info.absoluteFilePath())), + fs::path(StringUtils::toStdString(entry_orig_info.absoluteFilePath())))); + } } QFileInfo lnk_info(target_dir.path()); @@ -455,8 +455,7 @@ slots: void test_link_with_blacklist() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -469,18 +468,13 @@ slots: RegexpMatcher re("[.]?mcmeta"); lnk_tsk.matcher(&re); lnk_tsk.linkRecursively(true); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); - - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; QFileInfo entry_lnk_info(target_dir.filePath(entry)); if (!entry_lnk_info.isDir()) @@ -507,8 +501,7 @@ slots: void test_link_with_whitelist() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -522,17 +515,13 @@ slots: lnk_tsk.matcher(&re); lnk_tsk.linkRecursively(true); lnk_tsk.whitelist(true); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); - for(auto entry: target_dir.entryList()) - { + for (auto entry : target_dir.entryList()) { qDebug() << entry; QFileInfo entry_lnk_info(target_dir.filePath(entry)); if (!entry_lnk_info.isDir()) @@ -559,8 +548,7 @@ slots: void test_link_with_dot_hidden() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -571,18 +559,15 @@ slots: LinkTask lnk_tsk(folder, target_dir.path()); lnk_tsk.linkRecursively(true); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); auto filter = QDir::Filter::Files | QDir::Filter::Dirs | QDir::Filter::Hidden; - for (auto entry: target_dir.entryList(filter)) { + for (auto entry : target_dir.entryList(filter)) { qDebug() << entry; QFileInfo entry_lnk_info(target_dir.filePath(entry)); if (!entry_lnk_info.isDir()) @@ -621,19 +606,16 @@ slots: qDebug() << tempDir.path(); qDebug() << target_dir.path(); - LinkTask lnk_tsk(file, target_dir.filePath("pack.mcmeta")); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + LinkTask lnk_tsk(file, target_dir.filePath("pack.mcmeta")); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); auto filter = QDir::Filter::Files; - for (auto entry: target_dir.entryList(filter)) { + for (auto entry : target_dir.entryList(filter)) { qDebug() << entry; } @@ -648,8 +630,7 @@ slots: void test_link_with_max_depth() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder, this]() - { + auto f = [&folder, this]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -661,22 +642,19 @@ slots: LinkTask lnk_tsk(folder, target_dir.path()); lnk_tsk.linkRecursively(true); lnk_tsk.setMaxDepth(0); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); QVERIFY(!QFileInfo(target_dir.path()).isSymLink()); auto filter = QDir::Filter::Files | QDir::Filter::Dirs | QDir::Filter::Hidden; - for(auto entry: target_dir.entryList(filter)) - { + for (auto entry : target_dir.entryList(filter)) { qDebug() << entry; - if (entry == "." || entry == "..") continue; + if (entry == "." || entry == "..") + continue; QFileInfo entry_lnk_info(target_dir.filePath(entry)); QVERIFY(entry_lnk_info.isSymLink()); } @@ -687,8 +665,6 @@ slots: QVERIFY(target_dir.entryList().contains("pack.mcmeta")); QVERIFY(target_dir.entryList().contains("assets")); - - }; // first try variant without trailing / @@ -704,8 +680,7 @@ slots: void test_link_with_no_max_depth() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); - auto f = [&folder]() - { + auto f = [&folder]() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); qDebug() << "From:" << folder << "To:" << tempDir.path(); @@ -717,24 +692,19 @@ slots: LinkTask lnk_tsk(folder, target_dir.path()); lnk_tsk.linkRecursively(true); lnk_tsk.setMaxDepth(-1); - QObject::connect(&lnk_tsk, &Task::finished, [&]{ - QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); - }); + QObject::connect(&lnk_tsk, &Task::finished, + [&] { QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been."); }); lnk_tsk.start(); - QVERIFY2(QTest::qWaitFor([&]() { - return lnk_tsk.isFinished(); - }, 100000), "Task didn't finish as it should."); - + QVERIFY2(QTest::qWaitFor([&]() { return lnk_tsk.isFinished(); }, 100000), "Task didn't finish as it should."); std::function verify_check = [&](QString check_path) { QDir check_dir(check_path); auto filter = QDir::Filter::Files | QDir::Filter::Dirs | QDir::Filter::Hidden; - for(auto entry: check_dir.entryList(filter)) - { + for (auto entry : check_dir.entryList(filter)) { QFileInfo entry_lnk_info(check_dir.filePath(entry)); qDebug() << entry << check_dir.filePath(entry); - if (!entry_lnk_info.isDir()){ + if (!entry_lnk_info.isDir()) { QVERIFY(entry_lnk_info.isSymLink()); } else if (entry != "." && entry != "..") { qDebug() << "Decending tree to verify symlinks:" << check_dir.filePath(entry); @@ -742,9 +712,8 @@ slots: } } }; - + verify_check(target_dir.path()); - QFileInfo lnk_info(target_dir.path()); QVERIFY(lnk_info.exists()); @@ -763,7 +732,8 @@ slots: f(); } - void test_path_depth() { + void test_path_depth() + { QCOMPARE(FS::pathDepth(""), 0); QCOMPARE(FS::pathDepth("."), 0); QCOMPARE(FS::pathDepth("foo.txt"), 0); @@ -777,7 +747,8 @@ slots: QCOMPARE(FS::pathDepth("/baz/../bar/foo.txt"), 1); } - void test_path_trunc() { + void test_path_trunc() + { QCOMPARE(FS::pathTruncate("", 0), QDir::toNativeSeparators("")); QCOMPARE(FS::pathTruncate("foo.txt", 0), QDir::toNativeSeparators("")); QCOMPARE(FS::pathTruncate("foo.txt", 1), QDir::toNativeSeparators("")); diff --git a/tests/GZip_test.cpp b/tests/GZip_test.cpp index 82503d81d..4c1259c22 100644 --- a/tests/GZip_test.cpp +++ b/tests/GZip_test.cpp @@ -3,18 +3,16 @@ #include #include -void fib(int &prev, int &cur) +void fib(int& prev, int& cur) { auto ret = prev + cur; prev = cur; cur = ret; } -class GZipTest : public QObject -{ +class GZipTest : public QObject { Q_OBJECT -private -slots: + private slots: void test_Through() { @@ -27,8 +25,7 @@ slots: std::uniform_int_distribution idis(0, std::numeric_limits::max()); // initialize random buffer - for(int i = 0; i < size; i++) - { + for (int i = 0; i < size; i++) { random.append((char)idis(eng)); } @@ -37,8 +34,7 @@ slots: int cur = 1; // test if fibonacci long random buffers pass through GZip - do - { + do { QByteArray copy = random; copy.resize(cur); compressed.clear(); diff --git a/tests/GradleSpecifier_test.cpp b/tests/GradleSpecifier_test.cpp index 850f83881..fa3c4ad9b 100644 --- a/tests/GradleSpecifier_test.cpp +++ b/tests/GradleSpecifier_test.cpp @@ -2,19 +2,11 @@ #include -class GradleSpecifierTest : public QObject -{ +class GradleSpecifierTest : public QObject { Q_OBJECT -private -slots: - void initTestCase() - { - - } - void cleanupTestCase() - { - - } + private slots: + void initTestCase() {} + void cleanupTestCase() {} void test_Positive_data() { @@ -40,8 +32,10 @@ slots: QTest::addColumn("spec"); QTest::addColumn("expected"); - QTest::newRow("3 parter") << "group.id:artifact:1.0" << "group/id/artifact/1.0/artifact-1.0.jar"; - QTest::newRow("doom") << "id.software:doom:1.666:demons@wad" << "id/software/doom/1.666/doom-1.666-demons.wad"; + QTest::newRow("3 parter") << "group.id:artifact:1.0" + << "group/id/artifact/1.0/artifact-1.0.jar"; + QTest::newRow("doom") << "id.software:doom:1.666:demons@wad" + << "id/software/doom/1.666/doom-1.666-demons.wad"; } void test_Path() { diff --git a/tests/Index_test.cpp b/tests/Index_test.cpp index 436b753e5..888021e24 100644 --- a/tests/Index_test.cpp +++ b/tests/Index_test.cpp @@ -3,14 +3,13 @@ #include #include -class IndexTest : public QObject -{ +class IndexTest : public QObject { Q_OBJECT -private -slots: + private slots: void test_hasUid_and_getList() { - Meta::Index windex({std::make_shared("list1"), std::make_shared("list2"), std::make_shared("list3")}); + Meta::Index windex({ std::make_shared("list1"), std::make_shared("list2"), + std::make_shared("list3") }); QVERIFY(windex.hasUid("list1")); QVERIFY(!windex.hasUid("asdf")); QVERIFY(windex.get("list2") != nullptr); @@ -20,13 +19,18 @@ slots: void test_merge() { - Meta::Index windex({std::make_shared("list1"), std::make_shared("list2"), std::make_shared("list3")}); + Meta::Index windex({ std::make_shared("list1"), std::make_shared("list2"), + std::make_shared("list3") }); QCOMPARE(windex.lists().size(), 3); - windex.merge(std::shared_ptr(new Meta::Index({std::make_shared("list1"), std::make_shared("list2"), std::make_shared("list3")}))); + windex.merge(std::shared_ptr( + new Meta::Index({ std::make_shared("list1"), std::make_shared("list2"), + std::make_shared("list3") }))); QCOMPARE(windex.lists().size(), 3); - windex.merge(std::shared_ptr(new Meta::Index({std::make_shared("list4"), std::make_shared("list2"), std::make_shared("list5")}))); + windex.merge(std::shared_ptr( + new Meta::Index({ std::make_shared("list4"), std::make_shared("list2"), + std::make_shared("list5") }))); QCOMPARE(windex.lists().size(), 5); - windex.merge(std::shared_ptr(new Meta::Index({std::make_shared("list6")}))); + windex.merge(std::shared_ptr(new Meta::Index({ std::make_shared("list6") }))); QCOMPARE(windex.lists().size(), 6); } }; diff --git a/tests/JavaVersion_test.cpp b/tests/JavaVersion_test.cpp index 76d9af2fe..fd2851954 100644 --- a/tests/JavaVersion_test.cpp +++ b/tests/JavaVersion_test.cpp @@ -2,11 +2,9 @@ #include -class JavaVersionTest : public QObject -{ +class JavaVersionTest : public QObject { Q_OBJECT -private -slots: + private slots: void test_Parse_data() { QTest::addColumn("string"); @@ -50,33 +48,54 @@ slots: QTest::addColumn("bigger"); // old format and new format equivalence - QTest::newRow("1.6.0_33 == 6.0.33") << "1.6.0_33" << "6.0.33" << false << true << false; + QTest::newRow("1.6.0_33 == 6.0.33") << "1.6.0_33" + << "6.0.33" << false << true << false; // old format major version - QTest::newRow("1.5.0_33 < 1.6.0_33") << "1.5.0_33" << "1.6.0_33" << true << false << false; + QTest::newRow("1.5.0_33 < 1.6.0_33") << "1.5.0_33" + << "1.6.0_33" << true << false << false; // new format - first release vs first security patch - QTest::newRow("9 < 9.0.1") << "9" << "9.0.1" << true << false << false; - QTest::newRow("9.0.1 > 9") << "9.0.1" << "9" << false << false << true; + QTest::newRow("9 < 9.0.1") << "9" + << "9.0.1" << true << false << false; + QTest::newRow("9.0.1 > 9") << "9.0.1" + << "9" << false << false << true; // new format - first minor vs first release/security patch - QTest::newRow("9.1 > 9.0.1") << "9.1" << "9.0.1" << false << false << true; - QTest::newRow("9.0.1 < 9.1") << "9.0.1" << "9.1" << true << false << false; - QTest::newRow("9.1 > 9") << "9.1" << "9" << false << false << true; - QTest::newRow("9 > 9.1") << "9" << "9.1" << true << false << false; + QTest::newRow("9.1 > 9.0.1") << "9.1" + << "9.0.1" << false << false << true; + QTest::newRow("9.0.1 < 9.1") << "9.0.1" + << "9.1" << true << false << false; + QTest::newRow("9.1 > 9") << "9.1" + << "9" << false << false << true; + QTest::newRow("9 > 9.1") << "9" + << "9.1" << true << false << false; // new format - omitted numbers - QTest::newRow("9 == 9.0") << "9" << "9.0" << false << true << false; - QTest::newRow("9 == 9.0.0") << "9" << "9.0.0" << false << true << false; - QTest::newRow("9.0 == 9.0.0") << "9.0" << "9.0.0" << false << true << false; + QTest::newRow("9 == 9.0") << "9" + << "9.0" << false << true << false; + QTest::newRow("9 == 9.0.0") << "9" + << "9.0.0" << false << true << false; + QTest::newRow("9.0 == 9.0.0") << "9.0" + << "9.0.0" << false << true << false; // early access and prereleases compared to final release - QTest::newRow("9-ea < 9") << "9-ea" << "9" << true << false << false; - QTest::newRow("9 < 9.0.1-ea") << "9" << "9.0.1-ea" << true << false << false; - QTest::newRow("9.0.1-ea > 9") << "9.0.1-ea" << "9" << false << false << true; + QTest::newRow("9-ea < 9") << "9-ea" + << "9" << true << false << false; + QTest::newRow("9 < 9.0.1-ea") << "9" + << "9.0.1-ea" << true << false << false; + QTest::newRow("9.0.1-ea > 9") << "9.0.1-ea" + << "9" << false << false << true; // prerelease difference only testing - QTest::newRow("9-1 == 9-1") << "9-1" << "9-1" << false << true << false; - QTest::newRow("9-1 < 9-2") << "9-1" << "9-2" << true << false << false; - QTest::newRow("9-5 < 9-20") << "9-5" << "9-20" << true << false << false; - QTest::newRow("9-rc1 < 9-rc2") << "9-rc1" << "9-rc2" << true << false << false; - QTest::newRow("9-rc5 < 9-rc20") << "9-rc5" << "9-rc20" << true << false << false; - QTest::newRow("9-rc < 9-rc2") << "9-rc" << "9-rc2" << true << false << false; - QTest::newRow("9-ea < 9-rc") << "9-ea" << "9-rc" << true << false << false; + QTest::newRow("9-1 == 9-1") << "9-1" + << "9-1" << false << true << false; + QTest::newRow("9-1 < 9-2") << "9-1" + << "9-2" << true << false << false; + QTest::newRow("9-5 < 9-20") << "9-5" + << "9-20" << true << false << false; + QTest::newRow("9-rc1 < 9-rc2") << "9-rc1" + << "9-rc2" << true << false << false; + QTest::newRow("9-rc5 < 9-rc20") << "9-rc5" + << "9-rc20" << true << false << false; + QTest::newRow("9-rc < 9-rc2") << "9-rc" + << "9-rc2" << true << false << false; + QTest::newRow("9-ea < 9-rc") << "9-ea" + << "9-rc" << true << false << false; } void test_Sort() { diff --git a/tests/Library_test.cpp b/tests/Library_test.cpp index db8380c7f..e8090c097 100644 --- a/tests/Library_test.cpp +++ b/tests/Library_test.cpp @@ -35,17 +35,16 @@ #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include -class LibraryTest : public QObject -{ +class LibraryTest : public QObject { Q_OBJECT -private: + private: LibraryPtr readMojangJson(const QString path) { QFile jsonFile(path); @@ -56,20 +55,17 @@ private: return MojangVersionFormat::libraryFromJson(problems, QJsonDocument::fromJson(data).object(), path); } // get absolute path to expected storage, assuming default cache prefix - QStringList getStorage(QString relative) - { - return {FS::PathCombine(cache->getBasePath("libraries"), relative)}; - } + QStringList getStorage(QString relative) { return { FS::PathCombine(cache->getBasePath("libraries"), relative) }; } - RuntimeContext dummyContext(QString system = "linux", QString arch = "64", QString realArch = "amd64") { + RuntimeContext dummyContext(QString system = "linux", QString arch = "64", QString realArch = "amd64") + { RuntimeContext r; r.javaArchitecture = arch; r.javaRealArchitecture = realArch; r.system = system; return r; } -private -slots: + private slots: void initTestCase() { cache.reset(new HttpMetaCache()); @@ -111,7 +107,7 @@ slots: test.setHint("local"); auto downloads = test.getDownloads(r, cache.get(), failedFiles, QString()); QCOMPARE(downloads.size(), 0); - QCOMPARE(failedFiles, {"testname-testversion.jar"}); + QCOMPARE(failedFiles, { "testname-testversion.jar" }); } void test_legacy_url_local_override() { @@ -127,7 +123,7 @@ slots: QStringList jar, native, native32, native64; test.getApplicableFiles(r, jar, native, native32, native64, QFINDTESTDATA("testdata/Library")); - QCOMPARE(jar, {QFileInfo(QFINDTESTDATA("testdata/Library/codecwav-20101023.jar")).absoluteFilePath()}); + QCOMPARE(jar, { QFileInfo(QFINDTESTDATA("testdata/Library/codecwav-20101023.jar")).absoluteFilePath() }); QCOMPARE(native, {}); QCOMPARE(native32, {}); QCOMPARE(native64, {}); @@ -158,9 +154,9 @@ slots: { RuntimeContext r = dummyContext(); Library test("test.package:testname:testversion"); - test.m_nativeClassifiers["linux"]="linux-${arch}"; - test.m_nativeClassifiers["osx"]="osx-${arch}"; - test.m_nativeClassifiers["windows"]="windows-${arch}"; + test.m_nativeClassifiers["linux"] = "linux-${arch}"; + test.m_nativeClassifiers["osx"] = "osx-${arch}"; + test.m_nativeClassifiers["windows"] = "windows-${arch}"; QCOMPARE(test.isNative(), true); test.setRepositoryURL("file://foo/bar"); { @@ -212,7 +208,7 @@ slots: { RuntimeContext r = dummyContext(); Library test("test.package:testname:testversion"); - test.m_nativeClassifiers["linux"]="linux-${arch}"; + test.m_nativeClassifiers["linux"] = "linux-${arch}"; test.setHint("local"); QCOMPARE(test.isNative(), true); test.setRepositoryURL("file://foo/bar"); @@ -221,12 +217,13 @@ slots: test.getApplicableFiles(r, jar, native, native32, native64, QFINDTESTDATA("testdata/Library")); QCOMPARE(jar, {}); QCOMPARE(native, {}); - QCOMPARE(native32, {QFileInfo(QFINDTESTDATA("testdata/Library/testname-testversion-linux-32.jar")).absoluteFilePath()}); - QCOMPARE(native64, {QFileInfo(QFINDTESTDATA("testdata/Library") + "/testname-testversion-linux-64.jar").absoluteFilePath()}); + QCOMPARE(native32, { QFileInfo(QFINDTESTDATA("testdata/Library/testname-testversion-linux-32.jar")).absoluteFilePath() }); + QCOMPARE(native64, { QFileInfo(QFINDTESTDATA("testdata/Library") + "/testname-testversion-linux-64.jar").absoluteFilePath() }); QStringList failedFiles; auto dls = test.getDownloads(r, cache.get(), failedFiles, QFINDTESTDATA("testdata/Library")); QCOMPARE(dls.size(), 0); - QCOMPARE(failedFiles, {QFileInfo(QFINDTESTDATA("testdata/Library") + "/testname-testversion-linux-64.jar").absoluteFilePath()}); + QCOMPARE(failedFiles, + { QFileInfo(QFINDTESTDATA("testdata/Library") + "/testname-testversion-linux-64.jar").absoluteFilePath() }); } } void test_onenine() @@ -254,7 +251,7 @@ slots: { QStringList jar, native, native32, native64; test->getApplicableFiles(r, jar, native, native32, native64, QFINDTESTDATA("testdata/Library")); - QCOMPARE(jar, {QFileInfo(QFINDTESTDATA("testdata/Library/codecwav-20101023.jar")).absoluteFilePath()}); + QCOMPARE(jar, { QFileInfo(QFINDTESTDATA("testdata/Library/codecwav-20101023.jar")).absoluteFilePath() }); QCOMPARE(native, {}); QCOMPARE(native32, {}); QCOMPARE(native64, {}); @@ -275,7 +272,7 @@ slots: { QStringList jar, native, native32, native64; test->getApplicableFiles(r, jar, native, native32, native64, QFINDTESTDATA("testdata/Library")); - QCOMPARE(jar, {QFileInfo(QFINDTESTDATA("testdata/Library/codecwav-20101023.jar")).absoluteFilePath()}); + QCOMPARE(jar, { QFileInfo(QFINDTESTDATA("testdata/Library/codecwav-20101023.jar")).absoluteFilePath() }); QCOMPARE(native, {}); QCOMPARE(native32, {}); QCOMPARE(native64, {}); @@ -295,14 +292,16 @@ slots: QStringList jar, native, native32, native64; test->getApplicableFiles(r, jar, native, native32, native64, QString()); QCOMPARE(jar, QStringList()); - QCOMPARE(native, getStorage("org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar")); + QCOMPARE(native, + getStorage("org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar")); QCOMPARE(native32, {}); QCOMPARE(native64, {}); QStringList failedFiles; auto dls = test->getDownloads(r, cache.get(), failedFiles, QString()); QCOMPARE(dls.size(), 1); QCOMPARE(failedFiles, {}); - QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar")); + QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/" + "lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar")); } void test_onenine_native_arch() { @@ -318,10 +317,13 @@ slots: auto dls = test->getDownloads(r, cache.get(), failedFiles, QString()); QCOMPARE(dls.size(), 2); QCOMPARE(failedFiles, {}); - QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar")); - QCOMPARE(dls[1]->m_url, QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar")); + QCOMPARE(dls[0]->m_url, + QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar")); + QCOMPARE(dls[1]->m_url, + QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar")); } -private: + + private: std::unique_ptr cache; QString dataDir; }; diff --git a/tests/MojangVersionFormat_test.cpp b/tests/MojangVersionFormat_test.cpp index 219fbfa25..9ff5d78c0 100644 --- a/tests/MojangVersionFormat_test.cpp +++ b/tests/MojangVersionFormat_test.cpp @@ -1,10 +1,9 @@ -#include #include +#include #include -class MojangVersionFormatTest : public QObject -{ +class MojangVersionFormatTest : public QObject { Q_OBJECT static QJsonDocument readJson(const QString path) @@ -15,7 +14,7 @@ class MojangVersionFormatTest : public QObject jsonFile.close(); return QJsonDocument::fromJson(data); } - static void writeJson(const char *file, QJsonDocument doc) + static void writeJson(const char* file, QJsonDocument doc) { QFile jsonFile(file); jsonFile.open(QIODevice::WriteOnly | QIODevice::Text); @@ -25,8 +24,7 @@ class MojangVersionFormatTest : public QObject jsonFile.close(); } -private -slots: + private slots: void test_Through_Simple() { QJsonDocument doc = readJson(QFINDTESTDATA("testdata/MojangVersionFormat/1.9-simple.json")); @@ -50,4 +48,3 @@ slots: QTEST_GUILESS_MAIN(MojangVersionFormatTest) #include "MojangVersionFormat_test.moc" - diff --git a/tests/Packwiz_test.cpp b/tests/Packwiz_test.cpp index 292894699..6f4aa5d1b 100644 --- a/tests/Packwiz_test.cpp +++ b/tests/Packwiz_test.cpp @@ -26,9 +26,9 @@ class PackwizTest : public QObject { Q_OBJECT private slots: - // Files taken from https://github.com/packwiz/packwiz-example-pack - void loadFromFile_Modrinth() - { + // Files taken from https://github.com/packwiz/packwiz-example-pack + void loadFromFile_Modrinth() + { QString source = QFINDTESTDATA("testdata/Packwiz"); QDir index_dir(source); @@ -43,15 +43,17 @@ class PackwizTest : public QObject { QCOMPARE(metadata.name, "Borderless Mining"); QCOMPARE(metadata.filename, "borderless-mining-1.1.1+1.18.jar"); QCOMPARE(metadata.side, "client"); - + QCOMPARE(metadata.url, QUrl("https://cdn.modrinth.com/data/kYq5qkSL/versions/1.1.1+1.18/borderless-mining-1.1.1+1.18.jar")); QCOMPARE(metadata.hash_format, "sha512"); - QCOMPARE(metadata.hash, "c8fe6e15ddea32668822dddb26e1851e5f03834be4bcb2eff9c0da7fdc086a9b6cead78e31a44d3bc66335cba11144ee0337c6d5346f1ba63623064499b3188d"); + QCOMPARE(metadata.hash, + "c8fe6e15ddea32668822dddb26e1851e5f03834be4bcb2eff9c0da7fdc086a9b6cead78e31a44d3bc66335cba11144ee0337c6d5346f1ba6362306449" + "9b3188d"); QCOMPARE(metadata.provider, ModPlatform::ResourceProvider::MODRINTH); QCOMPARE(metadata.version(), "ug2qKTPR"); QCOMPARE(metadata.mod_id(), "kYq5qkSL"); - } + } void loadFromFile_Curseforge() { @@ -71,7 +73,7 @@ class PackwizTest : public QObject { QCOMPARE(metadata.name, "Screenshot to Clipboard (Fabric)"); QCOMPARE(metadata.filename, "screenshot-to-clipboard-1.0.7-fabric.jar"); QCOMPARE(metadata.side, "both"); - + QCOMPARE(metadata.url, QUrl("https://edge.forgecdn.net/files/3509/43/screenshot-to-clipboard-1.0.7-fabric.jar")); QCOMPARE(metadata.hash_format, "murmur2"); QCOMPARE(metadata.hash, "1781245820"); diff --git a/tests/ParseUtils_test.cpp b/tests/ParseUtils_test.cpp index 02208fdf2..0f64a6017 100644 --- a/tests/ParseUtils_test.cpp +++ b/tests/ParseUtils_test.cpp @@ -2,27 +2,16 @@ #include -class ParseUtilsTest : public QObject -{ +class ParseUtilsTest : public QObject { Q_OBJECT -private -slots: + private slots: void test_Through_data() { QTest::addColumn("timestamp"); - const char * timestamps[] = - { - "2016-02-29T13:49:54+01:00", - "2016-02-26T15:21:11+00:01", - "2016-02-24T15:52:36+01:13", - "2016-02-18T17:41:00+00:00", - "2016-02-17T15:23:19+00:00", - "2016-02-16T15:22:39+09:22", - "2016-02-10T15:06:41+00:00", - "2016-02-04T15:28:02-05:33" - }; - for(unsigned i = 0; i < (sizeof(timestamps) / sizeof(const char *)); i++) - { + const char* timestamps[] = { "2016-02-29T13:49:54+01:00", "2016-02-26T15:21:11+00:01", "2016-02-24T15:52:36+01:13", + "2016-02-18T17:41:00+00:00", "2016-02-17T15:23:19+00:00", "2016-02-16T15:22:39+09:22", + "2016-02-10T15:06:41+00:00", "2016-02-04T15:28:02-05:33" }; + for (unsigned i = 0; i < (sizeof(timestamps) / sizeof(const char*)); i++) { QTest::newRow(timestamps[i]) << QString(timestamps[i]); } } @@ -35,7 +24,6 @@ slots: QCOMPARE(time_serialized, timestamp); } - }; QTEST_GUILESS_MAIN(ParseUtilsTest) diff --git a/tests/ResourceFolderModel_test.cpp b/tests/ResourceFolderModel_test.cpp index 962d89f11..8012d4df0 100644 --- a/tests/ResourceFolderModel_test.cpp +++ b/tests/ResourceFolderModel_test.cpp @@ -1,40 +1,40 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (C) 2022 Sefa Eyeoglu -* -* 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. -*/ + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu + * + * 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 #include +#include #include #include "BaseInstance.h" @@ -61,12 +61,10 @@ \ disconnect(&model, nullptr, &loop, nullptr); -class ResourceFolderModelTest : public QObject -{ +class ResourceFolderModelTest : public QObject { Q_OBJECT -private -slots: + private slots: // test for GH-1178 - install a folder with files to a mod list void test_1178() { @@ -76,8 +74,7 @@ slots: // sanity check QVERIFY(!source.endsWith('/')); - auto verify = [](QString path) - { + auto verify = [](QString path) { QDir target_dir(FS::PathCombine(path, "test_folder")); QVERIFY(target_dir.entryList().contains("pack.mcmeta")); QVERIFY(target_dir.entryList().contains("assets")); @@ -161,23 +158,17 @@ slots: QCOMPARE(model.size(), 0); - { - EXEC_UPDATE_TASK(model.installResource(file_mod), QVERIFY) - } + { EXEC_UPDATE_TASK(model.installResource(file_mod), QVERIFY) } QCOMPARE(model.size(), 1); qDebug() << "Added first mod."; - { - EXEC_UPDATE_TASK(model.startWatching(), ) - } + { EXEC_UPDATE_TASK(model.startWatching(), ) } QCOMPARE(model.size(), 1); qDebug() << "Started watching the temp folder."; - - { - EXEC_UPDATE_TASK(model.installResource(folder_resource), QVERIFY) - } + + { EXEC_UPDATE_TASK(model.installResource(folder_resource), QVERIFY) } QCOMPARE(model.size(), 2); qDebug() << "Added second mod."; @@ -189,7 +180,7 @@ slots: QCOMPARE(model.size(), 1); qDebug() << "Removed first mod."; - QString mod_file_name {model.at(0).fileinfo().fileName()}; + QString mod_file_name{ model.at(0).fileinfo().fileName() }; QVERIFY(!mod_file_name.isEmpty()); { @@ -212,10 +203,7 @@ slots: 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) } @@ -228,8 +216,8 @@ slots: auto& res_2 = model.at(0).type() == ResourceType::FOLDER ? model.at(0) : model.at(1); auto id_1 = res_1.internal_id(); auto id_2 = res_2.internal_id(); - bool initial_enabled_res_2 = res_2.enabled(); - bool initial_enabled_res_1 = res_1.enabled(); + bool initial_enabled_res_2 = res_2.enabled(); + bool initial_enabled_res_1 = res_1.enabled(); QVERIFY(res_1.type() != ResourceType::FOLDER && res_1.type() != ResourceType::UNKNOWN); qDebug() << "res_1 is of the correct type."; diff --git a/tests/ResourceModel_test.cpp b/tests/ResourceModel_test.cpp index 30353d3f9..9626c64ef 100644 --- a/tests/ResourceModel_test.cpp +++ b/tests/ResourceModel_test.cpp @@ -59,7 +59,8 @@ class DummyResourceModel : public ResourceModel { class ResourceModelTest : public QObject { Q_OBJECT private slots: - void test_abstract_item_model() { + void test_abstract_item_model() + { auto dummy = DummyResourceModel(); auto tester = QAbstractItemModelTester(&dummy); } diff --git a/tests/ResourcePackParse_test.cpp b/tests/ResourcePackParse_test.cpp index 7f2f86bf1..1dcce3249 100644 --- a/tests/ResourcePackParse_test.cpp +++ b/tests/ResourcePackParse_test.cpp @@ -27,18 +27,20 @@ class ResourcePackParseTest : public QObject { Q_OBJECT - private slots: + private slots: void test_parseZIP() { QString source = QFINDTESTDATA("testdata/ResourcePackParse"); QString zip_rp = FS::PathCombine(source, "test_resource_pack_idk.zip"); - ResourcePack pack { QFileInfo(zip_rp) }; + ResourcePack pack{ QFileInfo(zip_rp) }; bool valid = ResourcePackUtils::processZIP(pack, ResourcePackUtils::ProcessingLevel::BasicInfoOnly); QVERIFY(pack.packFormat() == 3); - QVERIFY(pack.description() == "um dois, feijão com arroz, três quatro, feijão no prato, cinco seis, café inglês, sete oito, comer biscoito, nove dez comer pastéis!!"); + QVERIFY(pack.description() == + "um dois, feijão com arroz, três quatro, feijão no prato, cinco seis, café inglês, sete oito, comer biscoito, nove dez " + "comer pastéis!!"); QVERIFY(valid == true); } @@ -47,7 +49,7 @@ class ResourcePackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/ResourcePackParse"); QString folder_rp = FS::PathCombine(source, "test_folder"); - ResourcePack pack { QFileInfo(folder_rp) }; + ResourcePack pack{ QFileInfo(folder_rp) }; bool valid = ResourcePackUtils::processFolder(pack, ResourcePackUtils::ProcessingLevel::BasicInfoOnly); @@ -61,13 +63,13 @@ class ResourcePackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/ResourcePackParse"); QString folder_rp = FS::PathCombine(source, "another_test_folder"); - ResourcePack pack { QFileInfo(folder_rp) }; + ResourcePack pack{ QFileInfo(folder_rp) }; bool valid = ResourcePackUtils::process(pack, ResourcePackUtils::ProcessingLevel::BasicInfoOnly); QVERIFY(pack.packFormat() == 6); QVERIFY(pack.description() == "o quartel pegou fogo, policia deu sinal, acode acode acode a bandeira nacional"); - QVERIFY(valid == false); // no assets dir + QVERIFY(valid == false); // no assets dir } }; diff --git a/tests/ShaderPackParse_test.cpp b/tests/ShaderPackParse_test.cpp index 7df105c61..898278103 100644 --- a/tests/ShaderPackParse_test.cpp +++ b/tests/ShaderPackParse_test.cpp @@ -31,13 +31,13 @@ class ShaderPackParseTest : public QObject { Q_OBJECT - private slots: + private slots: void test_parseZIP() { QString source = QFINDTESTDATA("testdata/ShaderPackParse"); QString zip_sp = FS::PathCombine(source, "shaderpack1.zip"); - ShaderPack pack { QFileInfo(zip_sp) }; + ShaderPack pack{ QFileInfo(zip_sp) }; bool valid = ShaderPackUtils::processZIP(pack); @@ -50,7 +50,7 @@ class ShaderPackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/ShaderPackParse"); QString folder_sp = FS::PathCombine(source, "shaderpack2"); - ShaderPack pack { QFileInfo(folder_sp) }; + ShaderPack pack{ QFileInfo(folder_sp) }; bool valid = ShaderPackUtils::processFolder(pack); @@ -63,7 +63,7 @@ class ShaderPackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/ShaderPackParse"); QString folder_sp = FS::PathCombine(source, "shaderpack3.zip"); - ShaderPack pack { QFileInfo(folder_sp) }; + ShaderPack pack{ QFileInfo(folder_sp) }; bool valid = ShaderPackUtils::process(pack); diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index c59d4bb73..95d927c68 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -66,7 +66,10 @@ class BigConcurrentTaskThread : public QThread { } connect(&big_task, &Task::finished, this, &QThread::quit); - connect(&m_deadline, &QTimer::timeout, this, [&] { passed_the_deadline = true; quit(); }); + connect(&m_deadline, &QTimer::timeout, this, [&] { + passed_the_deadline = true; + quit(); + }); m_deadline.start(); big_task.run(); diff --git a/tests/TexturePackParse_test.cpp b/tests/TexturePackParse_test.cpp index 4ddc0a3a1..558529287 100644 --- a/tests/TexturePackParse_test.cpp +++ b/tests/TexturePackParse_test.cpp @@ -28,13 +28,13 @@ class TexturePackParseTest : public QObject { Q_OBJECT - private slots: + private slots: void test_parseZIP() { QString source = QFINDTESTDATA("testdata/TexturePackParse"); QString zip_rp = FS::PathCombine(source, "test_texture_pack_idk.zip"); - TexturePack pack { QFileInfo(zip_rp) }; + TexturePack pack{ QFileInfo(zip_rp) }; bool valid = TexturePackUtils::processZIP(pack); @@ -47,7 +47,7 @@ class TexturePackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/TexturePackParse"); QString folder_rp = FS::PathCombine(source, "test_texturefolder"); - TexturePack pack { QFileInfo(folder_rp) }; + TexturePack pack{ QFileInfo(folder_rp) }; bool valid = TexturePackUtils::processFolder(pack, TexturePackUtils::ProcessingLevel::BasicInfoOnly); @@ -60,7 +60,7 @@ class TexturePackParseTest : public QObject { QString source = QFINDTESTDATA("testdata/TexturePackParse"); QString folder_rp = FS::PathCombine(source, "another_test_texturefolder"); - TexturePack pack { QFileInfo(folder_rp) }; + TexturePack pack{ QFileInfo(folder_rp) }; bool valid = TexturePackUtils::process(pack, TexturePackUtils::ProcessingLevel::BasicInfoOnly); diff --git a/tests/Version_test.cpp b/tests/Version_test.cpp index f5488cbce..d25bf7bb5 100644 --- a/tests/Version_test.cpp +++ b/tests/Version_test.cpp @@ -34,33 +34,48 @@ class VersionTest : public QObject { { addDataColumns(); - QTest::newRow("equal, explicit") << "1.2.0" << "1.2.0" << false << true; - QTest::newRow("equal, two-digit") << "1.42" << "1.42" << false << true; + QTest::newRow("equal, explicit") << "1.2.0" + << "1.2.0" << false << true; + QTest::newRow("equal, two-digit") << "1.42" + << "1.42" << false << true; - QTest::newRow("lessThan, explicit 1") << "1.2.0" << "1.2.1" << true << false; - QTest::newRow("lessThan, explicit 2") << "1.2.0" << "1.3.0" << true << false; - QTest::newRow("lessThan, explicit 3") << "1.2.0" << "2.2.0" << true << false; - QTest::newRow("lessThan, implicit 1") << "1.2" << "1.2.0" << true << false; - QTest::newRow("lessThan, implicit 2") << "1.2" << "1.2.1" << true << false; - QTest::newRow("lessThan, implicit 3") << "1.2" << "1.3.0" << true << false; - QTest::newRow("lessThan, implicit 4") << "1.2" << "2.2.0" << true << false; - QTest::newRow("lessThan, two-digit") << "1.41" << "1.42" << true << false; + QTest::newRow("lessThan, explicit 1") << "1.2.0" + << "1.2.1" << true << false; + QTest::newRow("lessThan, explicit 2") << "1.2.0" + << "1.3.0" << true << false; + QTest::newRow("lessThan, explicit 3") << "1.2.0" + << "2.2.0" << true << false; + QTest::newRow("lessThan, implicit 1") << "1.2" + << "1.2.0" << true << false; + QTest::newRow("lessThan, implicit 2") << "1.2" + << "1.2.1" << true << false; + QTest::newRow("lessThan, implicit 3") << "1.2" + << "1.3.0" << true << false; + QTest::newRow("lessThan, implicit 4") << "1.2" + << "2.2.0" << true << false; + QTest::newRow("lessThan, two-digit") << "1.41" + << "1.42" << true << false; - QTest::newRow("greaterThan, explicit 1") << "1.2.1" << "1.2.0" << false << false; - QTest::newRow("greaterThan, explicit 2") << "1.3.0" << "1.2.0" << false << false; - QTest::newRow("greaterThan, explicit 3") << "2.2.0" << "1.2.0" << false << false; - QTest::newRow("greaterThan, implicit 1") << "1.2.0" << "1.2" << false << false; - QTest::newRow("greaterThan, implicit 2") << "1.2.1" << "1.2" << false << false; - QTest::newRow("greaterThan, implicit 3") << "1.3.0" << "1.2" << false << false; - QTest::newRow("greaterThan, implicit 4") << "2.2.0" << "1.2" << false << false; - QTest::newRow("greaterThan, two-digit") << "1.42" << "1.41" << false << false; + QTest::newRow("greaterThan, explicit 1") << "1.2.1" + << "1.2.0" << false << false; + QTest::newRow("greaterThan, explicit 2") << "1.3.0" + << "1.2.0" << false << false; + QTest::newRow("greaterThan, explicit 3") << "2.2.0" + << "1.2.0" << false << false; + QTest::newRow("greaterThan, implicit 1") << "1.2.0" + << "1.2" << false << false; + QTest::newRow("greaterThan, implicit 2") << "1.2.1" + << "1.2" << false << false; + QTest::newRow("greaterThan, implicit 3") << "1.3.0" + << "1.2" << false << false; + QTest::newRow("greaterThan, implicit 4") << "2.2.0" + << "1.2" << false << false; + QTest::newRow("greaterThan, two-digit") << "1.42" + << "1.41" << false << false; } private slots: - void test_versionCompare_data() - { - setupVersions(); - } + void test_versionCompare_data() { setupVersions(); } void test_versionCompare() { @@ -85,12 +100,12 @@ class VersionTest : public QObject { QDir test_vector_dir(QFINDTESTDATA("testdata/Version")); - QFile vector_file{test_vector_dir.absoluteFilePath("test_vectors.txt")}; + QFile vector_file{ test_vector_dir.absoluteFilePath("test_vectors.txt") }; vector_file.open(QFile::OpenModeFlag::ReadOnly); int test_number = 0; - const QString test_name_template { "FlexVer test #%1 (%2)" }; + const QString test_name_template{ "FlexVer test #%1 (%2)" }; for (auto line = vector_file.readLine(); !vector_file.atEnd(); line = vector_file.readLine()) { line = line.simplified(); if (line.startsWith('#') || line.isEmpty()) @@ -100,8 +115,8 @@ class VersionTest : public QObject { auto split_line = line.split('<'); if (split_line.size() == 2) { - QString first{split_line.first().simplified()}; - QString second{split_line.last().simplified()}; + QString first{ split_line.first().simplified() }; + QString second{ split_line.last().simplified() }; auto new_test_name = test_name_template.arg(QString::number(test_number), "lessThan"); m_flex_test_names.append(new_test_name); @@ -112,8 +127,8 @@ class VersionTest : public QObject { split_line = line.split('='); if (split_line.size() == 2) { - QString first{split_line.first().simplified()}; - QString second{split_line.last().simplified()}; + QString first{ split_line.first().simplified() }; + QString second{ split_line.last().simplified() }; auto new_test_name = test_name_template.arg(QString::number(test_number), "equals"); m_flex_test_names.append(new_test_name); @@ -124,8 +139,8 @@ class VersionTest : public QObject { split_line = line.split('>'); if (split_line.size() == 2) { - QString first{split_line.first().simplified()}; - QString second{split_line.last().simplified()}; + QString first{ split_line.first().simplified() }; + QString second{ split_line.last().simplified() }; auto new_test_name = test_name_template.arg(QString::number(test_number), "greaterThan"); m_flex_test_names.append(new_test_name); diff --git a/tests/WorldSaveParse_test.cpp b/tests/WorldSaveParse_test.cpp index 4a8c3d29c..8dabaeb51 100644 --- a/tests/WorldSaveParse_test.cpp +++ b/tests/WorldSaveParse_test.cpp @@ -31,13 +31,13 @@ class WorldSaveParseTest : public QObject { Q_OBJECT - private slots: + private slots: void test_parseZIP() { QString source = QFINDTESTDATA("testdata/WorldSaveParse"); - QString zip_ws = FS::PathCombine(source, "minecraft_save_1.zip") ; - WorldSave save { QFileInfo(zip_ws) }; + QString zip_ws = FS::PathCombine(source, "minecraft_save_1.zip"); + WorldSave save{ QFileInfo(zip_ws) }; bool valid = WorldSaveUtils::processZIP(save); @@ -45,13 +45,13 @@ class WorldSaveParseTest : public QObject { QVERIFY(save.saveDirName() == "world_1"); QVERIFY(valid == true); } - + void test_parse_ZIP2() { QString source = QFINDTESTDATA("testdata/WorldSaveParse"); - QString zip_ws = FS::PathCombine(source, "minecraft_save_2.zip") ; - WorldSave save { QFileInfo(zip_ws) }; + QString zip_ws = FS::PathCombine(source, "minecraft_save_2.zip"); + WorldSave save{ QFileInfo(zip_ws) }; bool valid = WorldSaveUtils::processZIP(save); @@ -59,13 +59,13 @@ class WorldSaveParseTest : public QObject { QVERIFY(save.saveDirName() == "world_2"); QVERIFY(valid == true); } - + void test_parseFolder() { QString source = QFINDTESTDATA("testdata/WorldSaveParse"); QString folder_ws = FS::PathCombine(source, "minecraft_save_3"); - WorldSave save { QFileInfo(folder_ws) }; + WorldSave save{ QFileInfo(folder_ws) }; bool valid = WorldSaveUtils::processFolder(save); @@ -79,7 +79,7 @@ class WorldSaveParseTest : public QObject { QString source = QFINDTESTDATA("testdata/WorldSaveParse"); QString folder_ws = FS::PathCombine(source, "minecraft_save_4"); - WorldSave save { QFileInfo(folder_ws) }; + WorldSave save{ QFileInfo(folder_ws) }; bool valid = WorldSaveUtils::process(save); diff --git a/tests/testdata/MojangVersionFormat/1.9-simple.json b/tests/testdata/MojangVersionFormat/1.9-simple.json index 574c5b065..c71bc6553 100644 --- a/tests/testdata/MojangVersionFormat/1.9-simple.json +++ b/tests/testdata/MojangVersionFormat/1.9-simple.json @@ -190,7 +190,8 @@ } ], "mainClass": "net.minecraft.client.main.Main", - "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", + "minecraftArguments": + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", "minimumLauncherVersion": 18, "releaseTime": "2016-02-29T13:49:54+00:00", "time": "2016-03-01T13:14:53+00:00", diff --git a/tests/testdata/MojangVersionFormat/1.9.json b/tests/testdata/MojangVersionFormat/1.9.json index 697c60590..b298634ad 100644 --- a/tests/testdata/MojangVersionFormat/1.9.json +++ b/tests/testdata/MojangVersionFormat/1.9.json @@ -335,7 +335,8 @@ "path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", "size": 173887, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar" } }, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", @@ -357,26 +358,33 @@ "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", "size": 22, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" }, "classifiers": { "natives-linux": { - "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", + "path": + "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", "size": 578680, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" }, "natives-osx": { - "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", + "path": + "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", "size": 426822, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" }, "natives-windows": { - "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", + "path": + "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", "size": 613748, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar" } } }, @@ -428,7 +436,8 @@ "path": "org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar", "sha1": "f0e612c840a7639c1f77f68d72a28dae2f0c8490", "size": 173887, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar" } }, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.2-nightly-20140822", @@ -445,22 +454,28 @@ "downloads": { "classifiers": { "natives-linux": { - "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar", + "path": + "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar", "sha1": "d898a33b5d0a6ef3fed3a4ead506566dce6720a5", "size": 578539, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar" }, "natives-osx": { - "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar", + "path": + "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar", "sha1": "79f5ce2fea02e77fe47a3c745219167a542121d7", "size": 468116, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar" }, "natives-windows": { - "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar", + "path": + "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar", "sha1": "78b2a55ce4dc29c6b3ec4df8ca165eba05f9b341", "size": 613680, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar" } } }, @@ -491,7 +506,8 @@ "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795", "size": 10362, - "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar" + "url": + "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar" }, "natives-osx": { "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar", @@ -503,7 +519,8 @@ "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar", "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16", "size": 155179, - "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar" + "url": + "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar" } } }, @@ -521,7 +538,8 @@ } ], "mainClass": "net.minecraft.client.main.Main", - "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", + "minecraftArguments": + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", "minimumLauncherVersion": 18, "releaseTime": "2016-02-29T13:49:54+00:00", "time": "2016-03-01T13:14:53+00:00", diff --git a/tests/testdata/MojangVersionFormat/lib-native.json b/tests/testdata/MojangVersionFormat/lib-native.json index 5b9f3b556..e7a6094f9 100644 --- a/tests/testdata/MojangVersionFormat/lib-native.json +++ b/tests/testdata/MojangVersionFormat/lib-native.json @@ -4,26 +4,30 @@ "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", "size": 22, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" }, "classifiers": { "natives-linux": { "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", "size": 578680, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" }, "natives-osx": { "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", "size": 426822, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" }, "natives-windows": { "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", "size": 613748, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar" + "url": + "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar" } } }, diff --git a/tests/testdata/PackageManifest/1.8.0_202-x64.json b/tests/testdata/PackageManifest/1.8.0_202-x64.json index 3d99d719b..eaf67a7ac 100644 --- a/tests/testdata/PackageManifest/1.8.0_202-x64.json +++ b/tests/testdata/PackageManifest/1.8.0_202-x64.json @@ -1 +1,4667 @@ -{"files": {"COPYRIGHT": {"downloads": {"lzma": {"sha1": "dd860e040807f7e53ae89da5f28dd73d57ac605d", "size": 1431, "url": "https://launcher.mojang.com/v1/objects/dd860e040807f7e53ae89da5f28dd73d57ac605d/COPYRIGHT"}, "raw": {"sha1": "c725183c757011e7ba96c83c1e86ee7e8b516a2b", "size": 3244, "url": "https://launcher.mojang.com/v1/objects/c725183c757011e7ba96c83c1e86ee7e8b516a2b/COPYRIGHT"}}, "executable": false, "type": "file"}, "LICENSE": {"downloads": {"raw": {"sha1": "3e86865deec0814c958bcf7fb87f790bccc0e8bd", "size": 40, "url": "https://launcher.mojang.com/v1/objects/3e86865deec0814c958bcf7fb87f790bccc0e8bd/LICENSE"}}, "executable": false, "type": "file"}, "README": {"downloads": {"raw": {"sha1": "f90331df1e5badeadc501d8dd70714c62a920204", "size": 46, "url": "https://launcher.mojang.com/v1/objects/f90331df1e5badeadc501d8dd70714c62a920204/README"}}, "executable": false, "type": "file"}, "THIRDPARTYLICENSEREADME-JAVAFX.txt": {"downloads": {"lzma": {"sha1": "4fee85109d7ff04b982d0576dabd15397f599125", "size": 15455, "url": "https://launcher.mojang.com/v1/objects/4fee85109d7ff04b982d0576dabd15397f599125/THIRDPARTYLICENSEREADME-JAVAFX.txt"}, "raw": {"sha1": "56ff42f87607b997b52ae0ef8bf315e36932e870", "size": 112724, "url": "https://launcher.mojang.com/v1/objects/56ff42f87607b997b52ae0ef8bf315e36932e870/THIRDPARTYLICENSEREADME-JAVAFX.txt"}}, "executable": false, "type": "file"}, "THIRDPARTYLICENSEREADME.txt": {"downloads": {"lzma": {"sha1": "419c1414ba46ae9dbfd38cf4e0601fff61644429", "size": 32266, "url": "https://launcher.mojang.com/v1/objects/419c1414ba46ae9dbfd38cf4e0601fff61644429/THIRDPARTYLICENSEREADME.txt"}, "raw": {"sha1": "b83c3f32261de3e48ccd20614a11e066b1ec9027", "size": 153824, "url": "https://launcher.mojang.com/v1/objects/b83c3f32261de3e48ccd20614a11e066b1ec9027/THIRDPARTYLICENSEREADME.txt"}}, "executable": false, "type": "file"}, "Welcome.html": {"downloads": {"lzma": {"sha1": "01c21a74b4aafb7cbe0388233c43cbdf77dcaaea", "size": 528, "url": "https://launcher.mojang.com/v1/objects/01c21a74b4aafb7cbe0388233c43cbdf77dcaaea/Welcome.html"}, "raw": {"sha1": "d98ae54f03dac87419abc19b97e315830c2da55f", "size": 955, "url": "https://launcher.mojang.com/v1/objects/d98ae54f03dac87419abc19b97e315830c2da55f/Welcome.html"}}, "executable": false, "type": "file"}, "bin": {"type": "directory"}, "bin/ControlPanel": {"target": "jcontrol", "type": "link"}, "bin/java": {"downloads": {"lzma": {"sha1": "3857eea1d59e1bc545c67a753ed2768254807b8a", "size": 2088, "url": "https://launcher.mojang.com/v1/objects/3857eea1d59e1bc545c67a753ed2768254807b8a/java"}, "raw": {"sha1": "3d20560fb5d1a49cb689c2226972e92e06d27ba6", "size": 8464, "url": "https://launcher.mojang.com/v1/objects/3d20560fb5d1a49cb689c2226972e92e06d27ba6/java"}}, "executable": true, "type": "file"}, "bin/javaws": {"downloads": {"lzma": {"sha1": "a6bec5c049e76c4488294a256a2084ea23ddb440", "size": 38173, "url": "https://launcher.mojang.com/v1/objects/a6bec5c049e76c4488294a256a2084ea23ddb440/javaws"}, "raw": {"sha1": "955c0f0066e2f893b0c2b3ccd83e223722e4ab74", "size": 140296, "url": "https://launcher.mojang.com/v1/objects/955c0f0066e2f893b0c2b3ccd83e223722e4ab74/javaws"}}, "executable": true, "type": "file"}, "bin/jcontrol": {"downloads": {"lzma": {"sha1": "40c5e33748f252e1d950b579a4185ab2c23fc908", "size": 2166, "url": "https://launcher.mojang.com/v1/objects/40c5e33748f252e1d950b579a4185ab2c23fc908/jcontrol"}, "raw": {"sha1": "ed541733c8b51e34349c1f8010b277e58ad73f1e", "size": 6264, "url": "https://launcher.mojang.com/v1/objects/ed541733c8b51e34349c1f8010b277e58ad73f1e/jcontrol"}}, "executable": true, "type": "file"}, "bin/jjs": {"downloads": {"lzma": {"sha1": "d44d1ac421979f7671921986214812095a5b0e3b", "size": 2168, "url": "https://launcher.mojang.com/v1/objects/d44d1ac421979f7671921986214812095a5b0e3b/jjs"}, "raw": {"sha1": "f00f944c3dbe556793b5dc686aaeee3e5722e99b", "size": 8584, "url": "https://launcher.mojang.com/v1/objects/f00f944c3dbe556793b5dc686aaeee3e5722e99b/jjs"}}, "executable": true, "type": "file"}, "bin/keytool": {"downloads": {"lzma": {"sha1": "93c607dce450976667c382f609a367167bdec05c", "size": 2175, "url": "https://launcher.mojang.com/v1/objects/93c607dce450976667c382f609a367167bdec05c/keytool"}, "raw": {"sha1": "7114b561546270e441e9ed1bcc24e5188c068a42", "size": 8584, "url": "https://launcher.mojang.com/v1/objects/7114b561546270e441e9ed1bcc24e5188c068a42/keytool"}}, "executable": true, "type": "file"}, "bin/orbd": {"downloads": {"lzma": {"sha1": "b27dfded5e2b2f6f02c555971c94e46ca14ac81b", "size": 2254, "url": "https://launcher.mojang.com/v1/objects/b27dfded5e2b2f6f02c555971c94e46ca14ac81b/orbd"}, "raw": {"sha1": "7f31217fecb3dbbd89f1dd3783fca58793a66fd2", "size": 8656, "url": "https://launcher.mojang.com/v1/objects/7f31217fecb3dbbd89f1dd3783fca58793a66fd2/orbd"}}, "executable": true, "type": "file"}, "bin/pack200": {"downloads": {"lzma": {"sha1": "b52da4497b49b1508b6225a5740857ddb8f52e97", "size": 2183, "url": "https://launcher.mojang.com/v1/objects/b52da4497b49b1508b6225a5740857ddb8f52e97/pack200"}, "raw": {"sha1": "16ef3e801efb57e50bc6477a27a9d95d02d0775b", "size": 8584, "url": "https://launcher.mojang.com/v1/objects/16ef3e801efb57e50bc6477a27a9d95d02d0775b/pack200"}}, "executable": true, "type": "file"}, "bin/policytool": {"downloads": {"lzma": {"sha1": "87da4c07da45f3d1a1a9d732af197cd39bf69d10", "size": 2182, "url": "https://launcher.mojang.com/v1/objects/87da4c07da45f3d1a1a9d732af197cd39bf69d10/policytool"}, "raw": {"sha1": "a52a29424470cb9b8db5c2fb1751d0b697a7ec8e", "size": 8592, "url": "https://launcher.mojang.com/v1/objects/a52a29424470cb9b8db5c2fb1751d0b697a7ec8e/policytool"}}, "executable": true, "type": "file"}, "bin/rmid": {"downloads": {"lzma": {"sha1": "1494c1174fde0c0a93ea117bc7edf7eb936c0512", "size": 2172, "url": "https://launcher.mojang.com/v1/objects/1494c1174fde0c0a93ea117bc7edf7eb936c0512/rmid"}, "raw": {"sha1": "5c8710e1ab924e5b09a07bcb4c6e106293bbd1a8", "size": 8584, "url": "https://launcher.mojang.com/v1/objects/5c8710e1ab924e5b09a07bcb4c6e106293bbd1a8/rmid"}}, "executable": true, "type": "file"}, "bin/rmiregistry": {"downloads": {"lzma": {"sha1": "7070cf2ec5a5e520a880bae699431edf02083e7e", "size": 2174, "url": "https://launcher.mojang.com/v1/objects/7070cf2ec5a5e520a880bae699431edf02083e7e/rmiregistry"}, "raw": {"sha1": "5f518daa7050028d5d9d849634c73136f2b23a54", "size": 8592, "url": "https://launcher.mojang.com/v1/objects/5f518daa7050028d5d9d849634c73136f2b23a54/rmiregistry"}}, "executable": true, "type": "file"}, "bin/servertool": {"downloads": {"lzma": {"sha1": "1db683a11cc9b7313426c84412f4d95be2fa7ccd", "size": 2185, "url": "https://launcher.mojang.com/v1/objects/1db683a11cc9b7313426c84412f4d95be2fa7ccd/servertool"}, "raw": {"sha1": "49d0ebfeb265ce5a8733e1014541ea2525674a60", "size": 8592, "url": "https://launcher.mojang.com/v1/objects/49d0ebfeb265ce5a8733e1014541ea2525674a60/servertool"}}, "executable": true, "type": "file"}, "bin/tnameserv": {"downloads": {"lzma": {"sha1": "36da9c9a2c5a8b662a3f8d52ca67339bce1c2714", "size": 2291, "url": "https://launcher.mojang.com/v1/objects/36da9c9a2c5a8b662a3f8d52ca67339bce1c2714/tnameserv"}, "raw": {"sha1": "09d998f8efcb6f55d0d87f59e08f8b89662796d9", "size": 8656, "url": "https://launcher.mojang.com/v1/objects/09d998f8efcb6f55d0d87f59e08f8b89662796d9/tnameserv"}}, "executable": true, "type": "file"}, "bin/unpack200": {"downloads": {"lzma": {"sha1": "344959e32fc7ee19eebe7b3cf5ab6d1a7d6641f2", "size": 79721, "url": "https://launcher.mojang.com/v1/objects/344959e32fc7ee19eebe7b3cf5ab6d1a7d6641f2/unpack200"}, "raw": {"sha1": "5dd933132f1b202e19e0c8e093f7113711cfdfc1", "size": 182616, "url": "https://launcher.mojang.com/v1/objects/5dd933132f1b202e19e0c8e093f7113711cfdfc1/unpack200"}}, "executable": true, "type": "file"}, "lib": {"type": "directory"}, "lib/amd64": {"type": "directory"}, "lib/amd64/jli": {"type": "directory"}, "lib/amd64/jli/libjli.so": {"downloads": {"lzma": {"sha1": "372331ee8e375888f798a2e88180a94493e141b0", "size": 48327, "url": "https://launcher.mojang.com/v1/objects/372331ee8e375888f798a2e88180a94493e141b0/libjli.so"}, "raw": {"sha1": "73b0cf8b7415686bc40c561ff77ff2740ccf7a44", "size": 108616, "url": "https://launcher.mojang.com/v1/objects/73b0cf8b7415686bc40c561ff77ff2740ccf7a44/libjli.so"}}, "executable": true, "type": "file"}, "lib/amd64/jvm.cfg": {"downloads": {"lzma": {"sha1": "86bcfebec37b38415525ffd77d3eaf70d0b1b4ca", "size": 435, "url": "https://launcher.mojang.com/v1/objects/86bcfebec37b38415525ffd77d3eaf70d0b1b4ca/jvm.cfg"}, "raw": {"sha1": "84b38bdc745de446ba0ca0232ea3aaf2efd721da", "size": 627, "url": "https://launcher.mojang.com/v1/objects/84b38bdc745de446ba0ca0232ea3aaf2efd721da/jvm.cfg"}}, "executable": false, "type": "file"}, "lib/amd64/libavplugin-53.so": {"downloads": {"lzma": {"sha1": "a332366762d9efc7b845a682b7edce62db44618c", "size": 14747, "url": "https://launcher.mojang.com/v1/objects/a332366762d9efc7b845a682b7edce62db44618c/libavplugin-53.so"}, "raw": {"sha1": "9bd1473dd8a0dc7950c7af1cc69a45548df26eb5", "size": 51720, "url": "https://launcher.mojang.com/v1/objects/9bd1473dd8a0dc7950c7af1cc69a45548df26eb5/libavplugin-53.so"}}, "executable": true, "type": "file"}, "lib/amd64/libavplugin-54.so": {"downloads": {"lzma": {"sha1": "2c615852a0720a275163e00597c1f711f11341da", "size": 15153, "url": "https://launcher.mojang.com/v1/objects/2c615852a0720a275163e00597c1f711f11341da/libavplugin-54.so"}, "raw": {"sha1": "8808050c5949c4800b42d1b19b1f8b0d120bcacb", "size": 51768, "url": "https://launcher.mojang.com/v1/objects/8808050c5949c4800b42d1b19b1f8b0d120bcacb/libavplugin-54.so"}}, "executable": true, "type": "file"}, "lib/amd64/libavplugin-55.so": {"downloads": {"lzma": {"sha1": "39ee8e7fe14f0010c78973962800f539c3e4c16b", "size": 15168, "url": "https://launcher.mojang.com/v1/objects/39ee8e7fe14f0010c78973962800f539c3e4c16b/libavplugin-55.so"}, "raw": {"sha1": "f10ea4ea3489e96d8d161a96790133c417ec44e1", "size": 51784, "url": "https://launcher.mojang.com/v1/objects/f10ea4ea3489e96d8d161a96790133c417ec44e1/libavplugin-55.so"}}, "executable": true, "type": "file"}, "lib/amd64/libavplugin-56.so": {"downloads": {"lzma": {"sha1": "abe7feced5a559f1bdc868526dc69484e0e591a0", "size": 15169, "url": "https://launcher.mojang.com/v1/objects/abe7feced5a559f1bdc868526dc69484e0e591a0/libavplugin-56.so"}, "raw": {"sha1": "e5bfcbff5a5a5a5993a3e689a05ef358c131a3ed", "size": 51784, "url": "https://launcher.mojang.com/v1/objects/e5bfcbff5a5a5a5993a3e689a05ef358c131a3ed/libavplugin-56.so"}}, "executable": true, "type": "file"}, "lib/amd64/libavplugin-57.so": {"downloads": {"lzma": {"sha1": "4dd26b4ef2294b6929dcb2c7546b47eac5cc78a9", "size": 15174, "url": "https://launcher.mojang.com/v1/objects/4dd26b4ef2294b6929dcb2c7546b47eac5cc78a9/libavplugin-57.so"}, "raw": {"sha1": "2949e7ff9b0ac90e8943c211cff141ab12eec3f8", "size": 51784, "url": "https://launcher.mojang.com/v1/objects/2949e7ff9b0ac90e8943c211cff141ab12eec3f8/libavplugin-57.so"}}, "executable": true, "type": "file"}, "lib/amd64/libavplugin-ffmpeg-56.so": {"downloads": {"lzma": {"sha1": "c688ba1cfa442bf18bee43b2fa870b4dc1ce3fb6", "size": 15231, "url": "https://launcher.mojang.com/v1/objects/c688ba1cfa442bf18bee43b2fa870b4dc1ce3fb6/libavplugin-ffmpeg-56.so"}, "raw": {"sha1": "0d36c971a9ad99fc2292092fdec3a4179b1021b9", "size": 51920, "url": "https://launcher.mojang.com/v1/objects/0d36c971a9ad99fc2292092fdec3a4179b1021b9/libavplugin-ffmpeg-56.so"}}, "executable": true, "type": "file"}, "lib/amd64/libavplugin-ffmpeg-57.so": {"downloads": {"lzma": {"sha1": "087426bdbffebcfa372a438e863785f4ffbe9a6b", "size": 15180, "url": "https://launcher.mojang.com/v1/objects/087426bdbffebcfa372a438e863785f4ffbe9a6b/libavplugin-ffmpeg-57.so"}, "raw": {"sha1": "5e9c4eb4b49eb8e57c01003ec73a1eb8d6d8c462", "size": 51784, "url": "https://launcher.mojang.com/v1/objects/5e9c4eb4b49eb8e57c01003ec73a1eb8d6d8c462/libavplugin-ffmpeg-57.so"}}, "executable": true, "type": "file"}, "lib/amd64/libawt.so": {"downloads": {"lzma": {"sha1": "018be58b205b73c842a55df811b70d0e8237216e", "size": 195720, "url": "https://launcher.mojang.com/v1/objects/018be58b205b73c842a55df811b70d0e8237216e/libawt.so"}, "raw": {"sha1": "02632cd326e3161c00a7e784599dd7b9ee053dce", "size": 759184, "url": "https://launcher.mojang.com/v1/objects/02632cd326e3161c00a7e784599dd7b9ee053dce/libawt.so"}}, "executable": true, "type": "file"}, "lib/amd64/libawt_headless.so": {"downloads": {"lzma": {"sha1": "7ac2517cff75d4bbb0a0412a9b5f18c74ea188fa", "size": 11211, "url": "https://launcher.mojang.com/v1/objects/7ac2517cff75d4bbb0a0412a9b5f18c74ea188fa/libawt_headless.so"}, "raw": {"sha1": "862157ec957008d0911c5daedc004b3a202623a4", "size": 39176, "url": "https://launcher.mojang.com/v1/objects/862157ec957008d0911c5daedc004b3a202623a4/libawt_headless.so"}}, "executable": true, "type": "file"}, "lib/amd64/libawt_xawt.so": {"downloads": {"lzma": {"sha1": "d536a96af27dfe35de6bb2c8759d51c488cdd8d4", "size": 149598, "url": "https://launcher.mojang.com/v1/objects/d536a96af27dfe35de6bb2c8759d51c488cdd8d4/libawt_xawt.so"}, "raw": {"sha1": "28232b3e01b6f11bfe098bfc6eafc3a513dcebf1", "size": 470232, "url": "https://launcher.mojang.com/v1/objects/28232b3e01b6f11bfe098bfc6eafc3a513dcebf1/libawt_xawt.so"}}, "executable": true, "type": "file"}, "lib/amd64/libbci.so": {"downloads": {"lzma": {"sha1": "c36fad091d11e64c815d5ca17c0ef7a55b0776b1", "size": 3509, "url": "https://launcher.mojang.com/v1/objects/c36fad091d11e64c815d5ca17c0ef7a55b0776b1/libbci.so"}, "raw": {"sha1": "33824051db1ccb6332e22c2b63231055240d0af0", "size": 12760, "url": "https://launcher.mojang.com/v1/objects/33824051db1ccb6332e22c2b63231055240d0af0/libbci.so"}}, "executable": true, "type": "file"}, "lib/amd64/libdcpr.so": {"downloads": {"lzma": {"sha1": "70c6b0933a37f2b1124d6e7c131039241fe796ee", "size": 75969, "url": "https://launcher.mojang.com/v1/objects/70c6b0933a37f2b1124d6e7c131039241fe796ee/libdcpr.so"}, "raw": {"sha1": "fa7001bc5d80579e2716590f3eee8027da0beae7", "size": 204456, "url": "https://launcher.mojang.com/v1/objects/fa7001bc5d80579e2716590f3eee8027da0beae7/libdcpr.so"}}, "executable": true, "type": "file"}, "lib/amd64/libdecora_sse.so": {"downloads": {"lzma": {"sha1": "514acc017dfb6cefaf8cc6d18006ce55781cc9bc", "size": 24397, "url": "https://launcher.mojang.com/v1/objects/514acc017dfb6cefaf8cc6d18006ce55781cc9bc/libdecora_sse.so"}, "raw": {"sha1": "d0c84233504c916e548e29f513e25f6a7479abfc", "size": 74912, "url": "https://launcher.mojang.com/v1/objects/d0c84233504c916e548e29f513e25f6a7479abfc/libdecora_sse.so"}}, "executable": true, "type": "file"}, "lib/amd64/libdeploy.so": {"downloads": {"lzma": {"sha1": "6cf31fd98301c749ac0d2c7825f6d925a4409760", "size": 168999, "url": "https://launcher.mojang.com/v1/objects/6cf31fd98301c749ac0d2c7825f6d925a4409760/libdeploy.so"}, "raw": {"sha1": "b3832e97ed8ca794884b56a591b83d02a2c0c06f", "size": 642368, "url": "https://launcher.mojang.com/v1/objects/b3832e97ed8ca794884b56a591b83d02a2c0c06f/libdeploy.so"}}, "executable": true, "type": "file"}, "lib/amd64/libdt_socket.so": {"downloads": {"lzma": {"sha1": "4cc5c880dbb6fa180436d12d60f0abec8ebb59dc", "size": 7784, "url": "https://launcher.mojang.com/v1/objects/4cc5c880dbb6fa180436d12d60f0abec8ebb59dc/libdt_socket.so"}, "raw": {"sha1": "91ce96f252b8139fc12f0f224ed5b1a041767ab7", "size": 24616, "url": "https://launcher.mojang.com/v1/objects/91ce96f252b8139fc12f0f224ed5b1a041767ab7/libdt_socket.so"}}, "executable": true, "type": "file"}, "lib/amd64/libfontmanager.so": {"downloads": {"lzma": {"sha1": "f94e5e94c71c603ff4d3cd1e7e3d9e181fcc145d", "size": 146951, "url": "https://launcher.mojang.com/v1/objects/f94e5e94c71c603ff4d3cd1e7e3d9e181fcc145d/libfontmanager.so"}, "raw": {"sha1": "2428e805f2c53d1283a033dfd11a86fbb7bd7159", "size": 490672, "url": "https://launcher.mojang.com/v1/objects/2428e805f2c53d1283a033dfd11a86fbb7bd7159/libfontmanager.so"}}, "executable": true, "type": "file"}, "lib/amd64/libfxplugins.so": {"downloads": {"lzma": {"sha1": "a640143365d382a5ad743a784bc2f3706d9d6d67", "size": 50048, "url": "https://launcher.mojang.com/v1/objects/a640143365d382a5ad743a784bc2f3706d9d6d67/libfxplugins.so"}, "raw": {"sha1": "0fd4ac04a84c131f1aaee9e6b0898ff9ea69e3ee", "size": 151448, "url": "https://launcher.mojang.com/v1/objects/0fd4ac04a84c131f1aaee9e6b0898ff9ea69e3ee/libfxplugins.so"}}, "executable": true, "type": "file"}, "lib/amd64/libglass.so": {"downloads": {"lzma": {"sha1": "f1ff517714fa5f2c861f33b32db823fe851541f1", "size": 2856, "url": "https://launcher.mojang.com/v1/objects/f1ff517714fa5f2c861f33b32db823fe851541f1/libglass.so"}, "raw": {"sha1": "e7f4fece30ac727be8148d33b8256abd3a41cef9", "size": 13072, "url": "https://launcher.mojang.com/v1/objects/e7f4fece30ac727be8148d33b8256abd3a41cef9/libglass.so"}}, "executable": true, "type": "file"}, "lib/amd64/libglassgtk2.so": {"downloads": {"lzma": {"sha1": "15b90f7a2baacd15e80aa9785d87cf1e4258376d", "size": 220476, "url": "https://launcher.mojang.com/v1/objects/15b90f7a2baacd15e80aa9785d87cf1e4258376d/libglassgtk2.so"}, "raw": {"sha1": "e30a634c2ff2143bdee512360553d6e0304f33b2", "size": 844984, "url": "https://launcher.mojang.com/v1/objects/e30a634c2ff2143bdee512360553d6e0304f33b2/libglassgtk2.so"}}, "executable": true, "type": "file"}, "lib/amd64/libglassgtk3.so": {"downloads": {"lzma": {"sha1": "868c231165f8c9043b7f0e7de208ec023f06a6e7", "size": 220560, "url": "https://launcher.mojang.com/v1/objects/868c231165f8c9043b7f0e7de208ec023f06a6e7/libglassgtk3.so"}, "raw": {"sha1": "762a11a2b376b7b5a2a7cad780715524fdd176d5", "size": 845304, "url": "https://launcher.mojang.com/v1/objects/762a11a2b376b7b5a2a7cad780715524fdd176d5/libglassgtk3.so"}}, "executable": true, "type": "file"}, "lib/amd64/libglib-lite.so": {"downloads": {"lzma": {"sha1": "61b8871242febe1be262de167dc20ae94bf964b4", "size": 457046, "url": "https://launcher.mojang.com/v1/objects/61b8871242febe1be262de167dc20ae94bf964b4/libglib-lite.so"}, "raw": {"sha1": "63afa060fc3f120af76128e51d32603fc4336fa8", "size": 1538352, "url": "https://launcher.mojang.com/v1/objects/63afa060fc3f120af76128e51d32603fc4336fa8/libglib-lite.so"}}, "executable": true, "type": "file"}, "lib/amd64/libgstreamer-lite.so": {"downloads": {"lzma": {"sha1": "2447dc368406ba1b989a29937d41924620e01988", "size": 673056, "url": "https://launcher.mojang.com/v1/objects/2447dc368406ba1b989a29937d41924620e01988/libgstreamer-lite.so"}, "raw": {"sha1": "5505e7ca592ac64371d3db8fe53bcb602e9723d3", "size": 2263872, "url": "https://launcher.mojang.com/v1/objects/5505e7ca592ac64371d3db8fe53bcb602e9723d3/libgstreamer-lite.so"}}, "executable": true, "type": "file"}, "lib/amd64/libhprof.so": {"downloads": {"lzma": {"sha1": "94a5589c818db1fb1cf1881e24e217c309fce2e4", "size": 64471, "url": "https://launcher.mojang.com/v1/objects/94a5589c818db1fb1cf1881e24e217c309fce2e4/libhprof.so"}, "raw": {"sha1": "4bb9bdeef6133b6dd558d52d691b077c03e9b0ee", "size": 175504, "url": "https://launcher.mojang.com/v1/objects/4bb9bdeef6133b6dd558d52d691b077c03e9b0ee/libhprof.so"}}, "executable": true, "type": "file"}, "lib/amd64/libinstrument.so": {"downloads": {"lzma": {"sha1": "84ffea356caf725b42c86a8ebc9587f477ddde29", "size": 18603, "url": "https://launcher.mojang.com/v1/objects/84ffea356caf725b42c86a8ebc9587f477ddde29/libinstrument.so"}, "raw": {"sha1": "cb8009769601e3fecd7ea2b36c344f737b1a9da7", "size": 51560, "url": "https://launcher.mojang.com/v1/objects/cb8009769601e3fecd7ea2b36c344f737b1a9da7/libinstrument.so"}}, "executable": true, "type": "file"}, "lib/amd64/libj2gss.so": {"downloads": {"lzma": {"sha1": "4b2aa699506b126098b585a9617ce1c05707fa29", "size": 14132, "url": "https://launcher.mojang.com/v1/objects/4b2aa699506b126098b585a9617ce1c05707fa29/libj2gss.so"}, "raw": {"sha1": "cbce4a302b255d4d1924ef7606f038af766c5e86", "size": 47688, "url": "https://launcher.mojang.com/v1/objects/cbce4a302b255d4d1924ef7606f038af766c5e86/libj2gss.so"}}, "executable": true, "type": "file"}, "lib/amd64/libj2pcsc.so": {"downloads": {"lzma": {"sha1": "2361d3b2e3da48593c391b29b0d2b5409e4c55e5", "size": 5074, "url": "https://launcher.mojang.com/v1/objects/2361d3b2e3da48593c391b29b0d2b5409e4c55e5/libj2pcsc.so"}, "raw": {"sha1": "1274178492e7a3e997e12f67794616f7c3d8d0b9", "size": 18296, "url": "https://launcher.mojang.com/v1/objects/1274178492e7a3e997e12f67794616f7c3d8d0b9/libj2pcsc.so"}}, "executable": true, "type": "file"}, "lib/amd64/libj2pkcs11.so": {"downloads": {"lzma": {"sha1": "ef927e2790ba05931d0f0bdd63da3d275a834946", "size": 21573, "url": "https://launcher.mojang.com/v1/objects/ef927e2790ba05931d0f0bdd63da3d275a834946/libj2pkcs11.so"}, "raw": {"sha1": "bd4f2af9bfdc6168633d1920c1a1415de06bb45a", "size": 79472, "url": "https://launcher.mojang.com/v1/objects/bd4f2af9bfdc6168633d1920c1a1415de06bb45a/libj2pkcs11.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjaas_unix.so": {"downloads": {"lzma": {"sha1": "7f7e843544ee1eb1454a5826bdd4218685b79430", "size": 2404, "url": "https://launcher.mojang.com/v1/objects/7f7e843544ee1eb1454a5826bdd4218685b79430/libjaas_unix.so"}, "raw": {"sha1": "4c517925c7d464a5b719898eb0bea1b04df31f1f", "size": 8192, "url": "https://launcher.mojang.com/v1/objects/4c517925c7d464a5b719898eb0bea1b04df31f1f/libjaas_unix.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjava.so": {"downloads": {"lzma": {"sha1": "5eee7a42600a44a8bb8d6d7f510fd96a29637ac0", "size": 63113, "url": "https://launcher.mojang.com/v1/objects/5eee7a42600a44a8bb8d6d7f510fd96a29637ac0/libjava.so"}, "raw": {"sha1": "e280aeddf3fc0ec664aef7efc0e0e197a54aaf02", "size": 227672, "url": "https://launcher.mojang.com/v1/objects/e280aeddf3fc0ec664aef7efc0e0e197a54aaf02/libjava.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjava_crw_demo.so": {"downloads": {"lzma": {"sha1": "b197cf23ae3556eb0b45c663f0a8cb62408b961e", "size": 10412, "url": "https://launcher.mojang.com/v1/objects/b197cf23ae3556eb0b45c663f0a8cb62408b961e/libjava_crw_demo.so"}, "raw": {"sha1": "18f20f906977c90d0090b41dbda8dd5cfead5a4c", "size": 26144, "url": "https://launcher.mojang.com/v1/objects/18f20f906977c90d0090b41dbda8dd5cfead5a4c/libjava_crw_demo.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjavafx_font.so": {"downloads": {"lzma": {"sha1": "ffbba0e5022f829412b86063d8a90f95f16709b1", "size": 5608, "url": "https://launcher.mojang.com/v1/objects/ffbba0e5022f829412b86063d8a90f95f16709b1/libjavafx_font.so"}, "raw": {"sha1": "8634a0aca612fc40420a4a7cc8af4cc46cfc6725", "size": 17104, "url": "https://launcher.mojang.com/v1/objects/8634a0aca612fc40420a4a7cc8af4cc46cfc6725/libjavafx_font.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjavafx_font_freetype.so": {"downloads": {"lzma": {"sha1": "310271eda8a2ac264ffc3640a9d847b49438d0bd", "size": 6942, "url": "https://launcher.mojang.com/v1/objects/310271eda8a2ac264ffc3640a9d847b49438d0bd/libjavafx_font_freetype.so"}, "raw": {"sha1": "3e7572d047c12ba2bc43acec7f98a67c20af8042", "size": 27616, "url": "https://launcher.mojang.com/v1/objects/3e7572d047c12ba2bc43acec7f98a67c20af8042/libjavafx_font_freetype.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjavafx_font_pango.so": {"downloads": {"lzma": {"sha1": "a7bcf0669e70b0f43099a99c81e6b6440cb40ac0", "size": 5820, "url": "https://launcher.mojang.com/v1/objects/a7bcf0669e70b0f43099a99c81e6b6440cb40ac0/libjavafx_font_pango.so"}, "raw": {"sha1": "f0b775cc9a514c7ee8b4d6fb300653ce548caf10", "size": 25560, "url": "https://launcher.mojang.com/v1/objects/f0b775cc9a514c7ee8b4d6fb300653ce548caf10/libjavafx_font_pango.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjavafx_font_t2k.so": {"downloads": {"lzma": {"sha1": "551c29dc7c7fc83223aa36a6187f7e0c5d650538", "size": 431450, "url": "https://launcher.mojang.com/v1/objects/551c29dc7c7fc83223aa36a6187f7e0c5d650538/libjavafx_font_t2k.so"}, "raw": {"sha1": "91e5813057c3b852d411540160f8ad05fb9f1ed3", "size": 1486128, "url": "https://launcher.mojang.com/v1/objects/91e5813057c3b852d411540160f8ad05fb9f1ed3/libjavafx_font_t2k.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjavafx_iio.so": {"downloads": {"lzma": {"sha1": "c832998fd5e06ed6dcd6428816194c350785420c", "size": 101479, "url": "https://launcher.mojang.com/v1/objects/c832998fd5e06ed6dcd6428816194c350785420c/libjavafx_iio.so"}, "raw": {"sha1": "dcdf68cb25677b76c1cf0bb94294e6e9880a6678", "size": 256336, "url": "https://launcher.mojang.com/v1/objects/dcdf68cb25677b76c1cf0bb94294e6e9880a6678/libjavafx_iio.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjawt.so": {"downloads": {"lzma": {"sha1": "c1ced6aad5c69ff444dc67d0fd7e333558953831", "size": 1872, "url": "https://launcher.mojang.com/v1/objects/c1ced6aad5c69ff444dc67d0fd7e333558953831/libjawt.so"}, "raw": {"sha1": "c5032f2c6fa40bea24e56605cf76b26a27e87b67", "size": 8048, "url": "https://launcher.mojang.com/v1/objects/c5032f2c6fa40bea24e56605cf76b26a27e87b67/libjawt.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjdwp.so": {"downloads": {"lzma": {"sha1": "c1aabbb3f5a624b9ad10ed871a1d83510a99b646", "size": 94884, "url": "https://launcher.mojang.com/v1/objects/c1aabbb3f5a624b9ad10ed871a1d83510a99b646/libjdwp.so"}, "raw": {"sha1": "a043e97be47937f6f552e94cf79c76c1c57f9594", "size": 272248, "url": "https://launcher.mojang.com/v1/objects/a043e97be47937f6f552e94cf79c76c1c57f9594/libjdwp.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjfr.so": {"downloads": {"lzma": {"sha1": "11b8e6bfffdccbacbf9dd29dea4b90b753f3c1b7", "size": 8780, "url": "https://launcher.mojang.com/v1/objects/11b8e6bfffdccbacbf9dd29dea4b90b753f3c1b7/libjfr.so"}, "raw": {"sha1": "312392dd186b11c418183e818f1928e8685a07e5", "size": 28384, "url": "https://launcher.mojang.com/v1/objects/312392dd186b11c418183e818f1928e8685a07e5/libjfr.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjfxmedia.so": {"downloads": {"lzma": {"sha1": "a4e7a126eb648ce6e5e6dc151831da37d8334139", "size": 391897, "url": "https://launcher.mojang.com/v1/objects/a4e7a126eb648ce6e5e6dc151831da37d8334139/libjfxmedia.so"}, "raw": {"sha1": "5fa54944327a6012c3d34cb5c1c4432762178dc8", "size": 1636376, "url": "https://launcher.mojang.com/v1/objects/5fa54944327a6012c3d34cb5c1c4432762178dc8/libjfxmedia.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjfxwebkit.so": {"downloads": {"lzma": {"sha1": "b274debd222cdcc2ee84160ebb95144b3880bc97", "size": 20492825, "url": "https://launcher.mojang.com/v1/objects/b274debd222cdcc2ee84160ebb95144b3880bc97/libjfxwebkit.so"}, "raw": {"sha1": "ecee564c3b2f645131b35bb3004abd4caeabd291", "size": 91014584, "url": "https://launcher.mojang.com/v1/objects/ecee564c3b2f645131b35bb3004abd4caeabd291/libjfxwebkit.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjpeg.so": {"downloads": {"lzma": {"sha1": "9ad55e370c5eaaa73c3158339db3c368b1aaf0cb", "size": 113072, "url": "https://launcher.mojang.com/v1/objects/9ad55e370c5eaaa73c3158339db3c368b1aaf0cb/libjpeg.so"}, "raw": {"sha1": "651e6d53ae67db1f0efbf7f104447a9b49b7e333", "size": 292520, "url": "https://launcher.mojang.com/v1/objects/651e6d53ae67db1f0efbf7f104447a9b49b7e333/libjpeg.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjsdt.so": {"downloads": {"lzma": {"sha1": "04b6d1361a34c496b5f652b2477784d69b8b6baf", "size": 3964, "url": "https://launcher.mojang.com/v1/objects/04b6d1361a34c496b5f652b2477784d69b8b6baf/libjsdt.so"}, "raw": {"sha1": "82b48a82bf6183d34cf00a0f81661b45c616f31b", "size": 12904, "url": "https://launcher.mojang.com/v1/objects/82b48a82bf6183d34cf00a0f81661b45c616f31b/libjsdt.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjsig.so": {"downloads": {"lzma": {"sha1": "37d3b89abde397216cc4ecb1339d8543d99b8428", "size": 3536, "url": "https://launcher.mojang.com/v1/objects/37d3b89abde397216cc4ecb1339d8543d99b8428/libjsig.so"}, "raw": {"sha1": "42e52ba1bcbe0362ab24bcf65c93797354db6fb9", "size": 13336, "url": "https://launcher.mojang.com/v1/objects/42e52ba1bcbe0362ab24bcf65c93797354db6fb9/libjsig.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjsound.so": {"downloads": {"lzma": {"sha1": "7e3c565d74d8ffae716f32b05544fa4a6f108adc", "size": 2002, "url": "https://launcher.mojang.com/v1/objects/7e3c565d74d8ffae716f32b05544fa4a6f108adc/libjsound.so"}, "raw": {"sha1": "0c0fc63b92d7b83c9960fa80d45c80553ea20254", "size": 8232, "url": "https://launcher.mojang.com/v1/objects/0c0fc63b92d7b83c9960fa80d45c80553ea20254/libjsound.so"}}, "executable": true, "type": "file"}, "lib/amd64/libjsoundalsa.so": {"downloads": {"lzma": {"sha1": "b06c51858a25ff776519495f1b9b3d9f604b089f", "size": 23097, "url": "https://launcher.mojang.com/v1/objects/b06c51858a25ff776519495f1b9b3d9f604b089f/libjsoundalsa.so"}, "raw": {"sha1": "281d37f0326d4a12dc7ea316ead09c198ff7bdf7", "size": 83256, "url": "https://launcher.mojang.com/v1/objects/281d37f0326d4a12dc7ea316ead09c198ff7bdf7/libjsoundalsa.so"}}, "executable": true, "type": "file"}, "lib/amd64/liblcms.so": {"downloads": {"lzma": {"sha1": "7a239baba2086cae49114b382b74b971da02f08e", "size": 176175, "url": "https://launcher.mojang.com/v1/objects/7a239baba2086cae49114b382b74b971da02f08e/liblcms.so"}, "raw": {"sha1": "c8895cc3c3d023d9e059225969ab67954772c0a1", "size": 526872, "url": "https://launcher.mojang.com/v1/objects/c8895cc3c3d023d9e059225969ab67954772c0a1/liblcms.so"}}, "executable": true, "type": "file"}, "lib/amd64/libmanagement.so": {"downloads": {"lzma": {"sha1": "aed3fdbcefd1716abfc6a306687c8b741cbb318e", "size": 12838, "url": "https://launcher.mojang.com/v1/objects/aed3fdbcefd1716abfc6a306687c8b741cbb318e/libmanagement.so"}, "raw": {"sha1": "eba35f61e0d50e30874b7c7b335edf2d52662423", "size": 51808, "url": "https://launcher.mojang.com/v1/objects/eba35f61e0d50e30874b7c7b335edf2d52662423/libmanagement.so"}}, "executable": true, "type": "file"}, "lib/amd64/libmlib_image.so": {"downloads": {"lzma": {"sha1": "1bb181f079492d55c7a458e96488cd17fe0a7b86", "size": 310272, "url": "https://launcher.mojang.com/v1/objects/1bb181f079492d55c7a458e96488cd17fe0a7b86/libmlib_image.so"}, "raw": {"sha1": "c973c450d33873675945d4694be484e3427f58f1", "size": 1048136, "url": "https://launcher.mojang.com/v1/objects/c973c450d33873675945d4694be484e3427f58f1/libmlib_image.so"}}, "executable": true, "type": "file"}, "lib/amd64/libnet.so": {"downloads": {"lzma": {"sha1": "9dd79703b6deb86e0321afe01c6ac508263c8312", "size": 38123, "url": "https://launcher.mojang.com/v1/objects/9dd79703b6deb86e0321afe01c6ac508263c8312/libnet.so"}, "raw": {"sha1": "b3a17b7d53fcdf1e689e1ec29ce851eee6022ead", "size": 116920, "url": "https://launcher.mojang.com/v1/objects/b3a17b7d53fcdf1e689e1ec29ce851eee6022ead/libnet.so"}}, "executable": true, "type": "file"}, "lib/amd64/libnio.so": {"downloads": {"lzma": {"sha1": "5697c89d5d5d9b74f2e1555fcbba79dd4049e287", "size": 24445, "url": "https://launcher.mojang.com/v1/objects/5697c89d5d5d9b74f2e1555fcbba79dd4049e287/libnio.so"}, "raw": {"sha1": "573bf8f64dbcc397f8abd3e1da28f90ab0679f5b", "size": 93872, "url": "https://launcher.mojang.com/v1/objects/573bf8f64dbcc397f8abd3e1da28f90ab0679f5b/libnio.so"}}, "executable": true, "type": "file"}, "lib/amd64/libnpjp2.so": {"downloads": {"lzma": {"sha1": "6fe53b5951ff740e7f2ef7ffe5975af26da06718", "size": 57892, "url": "https://launcher.mojang.com/v1/objects/6fe53b5951ff740e7f2ef7ffe5975af26da06718/libnpjp2.so"}, "raw": {"sha1": "2bb13c53a4280379253475e51216b97eed1d4ce3", "size": 216592, "url": "https://launcher.mojang.com/v1/objects/2bb13c53a4280379253475e51216b97eed1d4ce3/libnpjp2.so"}}, "executable": true, "type": "file"}, "lib/amd64/libnpt.so": {"downloads": {"lzma": {"sha1": "1b170b09a32b1b8b6624fa5d1f94ec60b2bf3876", "size": 5070, "url": "https://launcher.mojang.com/v1/objects/1b170b09a32b1b8b6624fa5d1f94ec60b2bf3876/libnpt.so"}, "raw": {"sha1": "6b1ff6b9b4624f3cc7801f221c82b8046fb76364", "size": 17504, "url": "https://launcher.mojang.com/v1/objects/6b1ff6b9b4624f3cc7801f221c82b8046fb76364/libnpt.so"}}, "executable": true, "type": "file"}, "lib/amd64/libprism_common.so": {"downloads": {"lzma": {"sha1": "f4aca04c90bc7505851c074a08b2c31cae1f94fa", "size": 23315, "url": "https://launcher.mojang.com/v1/objects/f4aca04c90bc7505851c074a08b2c31cae1f94fa/libprism_common.so"}, "raw": {"sha1": "b00866b6ed8646a29a334d46e297267552f27de8", "size": 59008, "url": "https://launcher.mojang.com/v1/objects/b00866b6ed8646a29a334d46e297267552f27de8/libprism_common.so"}}, "executable": true, "type": "file"}, "lib/amd64/libprism_es2.so": {"downloads": {"lzma": {"sha1": "7ff4173c338c7a6f370f231670055737e032da3e", "size": 18416, "url": "https://launcher.mojang.com/v1/objects/7ff4173c338c7a6f370f231670055737e032da3e/libprism_es2.so"}, "raw": {"sha1": "1390a1dc14345e5a948148e59195d62f3a83863f", "size": 63808, "url": "https://launcher.mojang.com/v1/objects/1390a1dc14345e5a948148e59195d62f3a83863f/libprism_es2.so"}}, "executable": true, "type": "file"}, "lib/amd64/libprism_sw.so": {"downloads": {"lzma": {"sha1": "6728e8bf7b214067d715be6fe0325910d63c2468", "size": 29457, "url": "https://launcher.mojang.com/v1/objects/6728e8bf7b214067d715be6fe0325910d63c2468/libprism_sw.so"}, "raw": {"sha1": "7a6c34cb2bbcde411778d1b3f8677c39e32c3ac4", "size": 71608, "url": "https://launcher.mojang.com/v1/objects/7a6c34cb2bbcde411778d1b3f8677c39e32c3ac4/libprism_sw.so"}}, "executable": true, "type": "file"}, "lib/amd64/libresource.so": {"downloads": {"lzma": {"sha1": "1e35e63f1e74915fba620f1febf420b919d49bc5", "size": 2633, "url": "https://launcher.mojang.com/v1/objects/1e35e63f1e74915fba620f1febf420b919d49bc5/libresource.so"}, "raw": {"sha1": "57490353ad0d83ab1930355213dea269795434fe", "size": 13456, "url": "https://launcher.mojang.com/v1/objects/57490353ad0d83ab1930355213dea269795434fe/libresource.so"}}, "executable": true, "type": "file"}, "lib/amd64/libsctp.so": {"downloads": {"lzma": {"sha1": "4340132ed250d7849a016e071be773eaedd33aa8", "size": 9332, "url": "https://launcher.mojang.com/v1/objects/4340132ed250d7849a016e071be773eaedd33aa8/libsctp.so"}, "raw": {"sha1": "4a80e743750f127c0d5a359f5cd60b97e7ee12ae", "size": 29552, "url": "https://launcher.mojang.com/v1/objects/4a80e743750f127c0d5a359f5cd60b97e7ee12ae/libsctp.so"}}, "executable": true, "type": "file"}, "lib/amd64/libsplashscreen.so": {"downloads": {"lzma": {"sha1": "b226c8dbd73a548fc2b042ee6db6cc80e727597c", "size": 190305, "url": "https://launcher.mojang.com/v1/objects/b226c8dbd73a548fc2b042ee6db6cc80e727597c/libsplashscreen.so"}, "raw": {"sha1": "87d6a491f5ba7e6c4d972264a0c9063afea567a2", "size": 441376, "url": "https://launcher.mojang.com/v1/objects/87d6a491f5ba7e6c4d972264a0c9063afea567a2/libsplashscreen.so"}}, "executable": true, "type": "file"}, "lib/amd64/libsunec.so": {"downloads": {"lzma": {"sha1": "6ebba98fab1e3d872d1363235b76497f6f9babdc", "size": 88829, "url": "https://launcher.mojang.com/v1/objects/6ebba98fab1e3d872d1363235b76497f6f9babdc/libsunec.so"}, "raw": {"sha1": "3b262a0a530f6e4e539aed2cd27b4de1d0ed8859", "size": 283368, "url": "https://launcher.mojang.com/v1/objects/3b262a0a530f6e4e539aed2cd27b4de1d0ed8859/libsunec.so"}}, "executable": true, "type": "file"}, "lib/amd64/libt2k.so": {"downloads": {"lzma": {"sha1": "602cb812ef0b350ccf56ce209a260ddbe3743d92", "size": 190720, "url": "https://launcher.mojang.com/v1/objects/602cb812ef0b350ccf56ce209a260ddbe3743d92/libt2k.so"}, "raw": {"sha1": "b072c56df997f61e15e6b5a43b8907b0d25c2043", "size": 504840, "url": "https://launcher.mojang.com/v1/objects/b072c56df997f61e15e6b5a43b8907b0d25c2043/libt2k.so"}}, "executable": true, "type": "file"}, "lib/amd64/libunpack.so": {"downloads": {"lzma": {"sha1": "7107b615e941074f0b14c31c88fb67200aacd37f", "size": 70308, "url": "https://launcher.mojang.com/v1/objects/7107b615e941074f0b14c31c88fb67200aacd37f/libunpack.so"}, "raw": {"sha1": "b05ff862ed87928ed91e80e5604673c5ea710a53", "size": 197712, "url": "https://launcher.mojang.com/v1/objects/b05ff862ed87928ed91e80e5604673c5ea710a53/libunpack.so"}}, "executable": true, "type": "file"}, "lib/amd64/libverify.so": {"downloads": {"lzma": {"sha1": "ecd98efb8c7da441a8c3580e8f5598f3cb4165b1", "size": 21885, "url": "https://launcher.mojang.com/v1/objects/ecd98efb8c7da441a8c3580e8f5598f3cb4165b1/libverify.so"}, "raw": {"sha1": "e2c8d92531c45ab9be69ffb72c87fa12e9e59827", "size": 66112, "url": "https://launcher.mojang.com/v1/objects/e2c8d92531c45ab9be69ffb72c87fa12e9e59827/libverify.so"}}, "executable": true, "type": "file"}, "lib/amd64/libzip.so": {"downloads": {"lzma": {"sha1": "7c562342e3f7b138dc978495447e3e6a96c2cf45", "size": 54876, "url": "https://launcher.mojang.com/v1/objects/7c562342e3f7b138dc978495447e3e6a96c2cf45/libzip.so"}, "raw": {"sha1": "5f4bf35a5c3e8f8c650e891d1031589b8ab6d77f", "size": 127016, "url": "https://launcher.mojang.com/v1/objects/5f4bf35a5c3e8f8c650e891d1031589b8ab6d77f/libzip.so"}}, "executable": true, "type": "file"}, "lib/amd64/server": {"type": "directory"}, "lib/amd64/server/Xusage.txt": {"downloads": {"lzma": {"sha1": "acb2da24a4c765887df83985e4c26d6be302a0a3", "size": 629, "url": "https://launcher.mojang.com/v1/objects/acb2da24a4c765887df83985e4c26d6be302a0a3/Xusage.txt"}, "raw": {"sha1": "6983727eafe140f9dd793c78aa6f3e007438243a", "size": 1423, "url": "https://launcher.mojang.com/v1/objects/6983727eafe140f9dd793c78aa6f3e007438243a/Xusage.txt"}}, "executable": false, "type": "file"}, "lib/amd64/server/libjsig.so": {"target": "../libjsig.so", "type": "link"}, "lib/amd64/server/libjvm.so": {"downloads": {"lzma": {"sha1": "d5c6f3338aaa6712f79d680ac8c3e31beebaa886", "size": 4154311, "url": "https://launcher.mojang.com/v1/objects/d5c6f3338aaa6712f79d680ac8c3e31beebaa886/libjvm.so"}, "raw": {"sha1": "23a98e1eb505cc3fb91bc0cb2adb71ab9270e9ca", "size": 17045016, "url": "https://launcher.mojang.com/v1/objects/23a98e1eb505cc3fb91bc0cb2adb71ab9270e9ca/libjvm.so"}}, "executable": true, "type": "file"}, "lib/applet": {"type": "directory"}, "lib/calendars.properties": {"downloads": {"lzma": {"sha1": "4a757c23f2942bd802a4f80235131146d9267750", "size": 558, "url": "https://launcher.mojang.com/v1/objects/4a757c23f2942bd802a4f80235131146d9267750/calendars.properties"}, "raw": {"sha1": "42ebb0988124433b8f2a6e5d9a74ed41240bcfc6", "size": 1378, "url": "https://launcher.mojang.com/v1/objects/42ebb0988124433b8f2a6e5d9a74ed41240bcfc6/calendars.properties"}}, "executable": false, "type": "file"}, "lib/charsets.jar": {"downloads": {"lzma": {"sha1": "2bf44143b2ad9d7d55045a4de4a562330c194dc0", "size": 412367, "url": "https://launcher.mojang.com/v1/objects/2bf44143b2ad9d7d55045a4de4a562330c194dc0/charsets.jar"}, "raw": {"sha1": "d73ab9f8de255a7e112ddd13622bf7f6b18c8447", "size": 3135615, "url": "https://launcher.mojang.com/v1/objects/d73ab9f8de255a7e112ddd13622bf7f6b18c8447/charsets.jar"}}, "executable": false, "type": "file"}, "lib/classlist": {"downloads": {"lzma": {"sha1": "14e7c73d21b8513b0aff8d86e5cb34c52021fbca", "size": 15024, "url": "https://launcher.mojang.com/v1/objects/14e7c73d21b8513b0aff8d86e5cb34c52021fbca/classlist"}, "raw": {"sha1": "9c0404b63c87e2fed35e3a6cd137d6cf876c42bd", "size": 84311, "url": "https://launcher.mojang.com/v1/objects/9c0404b63c87e2fed35e3a6cd137d6cf876c42bd/classlist"}}, "executable": false, "type": "file"}, "lib/cmm": {"type": "directory"}, "lib/cmm/CIEXYZ.pf": {"downloads": {"lzma": {"sha1": "fcc5ca2fd3f45cac3434b480fa3ce00007e96529", "size": 8964, "url": "https://launcher.mojang.com/v1/objects/fcc5ca2fd3f45cac3434b480fa3ce00007e96529/CIEXYZ.pf"}, "raw": {"sha1": "b7779924c70554647b87c2a86159ca7781e929f8", "size": 51236, "url": "https://launcher.mojang.com/v1/objects/b7779924c70554647b87c2a86159ca7781e929f8/CIEXYZ.pf"}}, "executable": false, "type": "file"}, "lib/cmm/GRAY.pf": {"downloads": {"lzma": {"sha1": "5388ccfe67d3131d6d02143d8e8895003ab14ff6", "size": 299, "url": "https://launcher.mojang.com/v1/objects/5388ccfe67d3131d6d02143d8e8895003ab14ff6/GRAY.pf"}, "raw": {"sha1": "27f93961d66b8230d0cdb8b166bc8b4153d5bc2d", "size": 632, "url": "https://launcher.mojang.com/v1/objects/27f93961d66b8230d0cdb8b166bc8b4153d5bc2d/GRAY.pf"}}, "executable": false, "type": "file"}, "lib/cmm/LINEAR_RGB.pf": {"downloads": {"lzma": {"sha1": "2bd90f09c8deb64b1729d6b8173c78f9e9cab27b", "size": 678, "url": "https://launcher.mojang.com/v1/objects/2bd90f09c8deb64b1729d6b8173c78f9e9cab27b/LINEAR_RGB.pf"}, "raw": {"sha1": "7913274c2f73bafcf888f09ff60990b100214ede", "size": 1044, "url": "https://launcher.mojang.com/v1/objects/7913274c2f73bafcf888f09ff60990b100214ede/LINEAR_RGB.pf"}}, "executable": false, "type": "file"}, "lib/cmm/PYCC.pf": {"downloads": {"lzma": {"sha1": "dbb2197ecff3fcdd142e9006490c8cb5c8d19af8", "size": 171521, "url": "https://launcher.mojang.com/v1/objects/dbb2197ecff3fcdd142e9006490c8cb5c8d19af8/PYCC.pf"}, "raw": {"sha1": "4f7eed05b8f0eea7bcdc8f8f7aaeb1925ce7b144", "size": 274474, "url": "https://launcher.mojang.com/v1/objects/4f7eed05b8f0eea7bcdc8f8f7aaeb1925ce7b144/PYCC.pf"}}, "executable": false, "type": "file"}, "lib/cmm/sRGB.pf": {"downloads": {"raw": {"sha1": "9eaea0911d89d63e39e95f2e2116eaec7e0bb91e", "size": 3144, "url": "https://launcher.mojang.com/v1/objects/9eaea0911d89d63e39e95f2e2116eaec7e0bb91e/sRGB.pf"}}, "executable": false, "type": "file"}, "lib/content-types.properties": {"downloads": {"lzma": {"sha1": "43a23d9a6c637c128b14cfa3feced93cbcf85b1a", "size": 1617, "url": "https://launcher.mojang.com/v1/objects/43a23d9a6c637c128b14cfa3feced93cbcf85b1a/content-types.properties"}, "raw": {"sha1": "b21698017c4a2866b5fabe59681b7592e72c83b1", "size": 5916, "url": "https://launcher.mojang.com/v1/objects/b21698017c4a2866b5fabe59681b7592e72c83b1/content-types.properties"}}, "executable": false, "type": "file"}, "lib/currency.data": {"downloads": {"lzma": {"sha1": "451b3f166ea34ef2aefbb01606ea5adcc0d65b42", "size": 1184, "url": "https://launcher.mojang.com/v1/objects/451b3f166ea34ef2aefbb01606ea5adcc0d65b42/currency.data"}, "raw": {"sha1": "bf524381a7a9b9d5bbab48069c583d2936e367a1", "size": 4134, "url": "https://launcher.mojang.com/v1/objects/bf524381a7a9b9d5bbab48069c583d2936e367a1/currency.data"}}, "executable": false, "type": "file"}, "lib/deploy": {"type": "directory"}, "lib/deploy.jar": {"downloads": {"raw": {"sha1": "fbe1de8fcd9a3d482c59414dce9311e4194766c9", "size": 2255881, "url": "https://launcher.mojang.com/v1/objects/fbe1de8fcd9a3d482c59414dce9311e4194766c9/deploy.jar"}}, "executable": false, "type": "file"}, "lib/deploy/MixedCodeMainDialog.ui": {"downloads": {"lzma": {"sha1": "7d812964343d1e978442f5c847c709784fc18fc0", "size": 683, "url": "https://launcher.mojang.com/v1/objects/7d812964343d1e978442f5c847c709784fc18fc0/MixedCodeMainDialog.ui"}, "raw": {"sha1": "c9b1af1c229e54b2d8a3d642d4f0bb31dc15be79", "size": 4507, "url": "https://launcher.mojang.com/v1/objects/c9b1af1c229e54b2d8a3d642d4f0bb31dc15be79/MixedCodeMainDialog.ui"}}, "executable": false, "type": "file"}, "lib/deploy/MixedCodeMainDialogJs.ui": {"downloads": {"lzma": {"sha1": "54fb58dbcc59e35e0ae896d0e266ae0c5bcf85c2", "size": 792, "url": "https://launcher.mojang.com/v1/objects/54fb58dbcc59e35e0ae896d0e266ae0c5bcf85c2/MixedCodeMainDialogJs.ui"}, "raw": {"sha1": "ad6337fb6d46750e14c12b439a5856f4b6864d0d", "size": 6110, "url": "https://launcher.mojang.com/v1/objects/ad6337fb6d46750e14c12b439a5856f4b6864d0d/MixedCodeMainDialogJs.ui"}}, "executable": false, "type": "file"}, "lib/deploy/cautionshield.icns": {"downloads": {"lzma": {"sha1": "7cea751dc168605054ec38ce8bfa71812be405c1", "size": 2333, "url": "https://launcher.mojang.com/v1/objects/7cea751dc168605054ec38ce8bfa71812be405c1/cautionshield.icns"}, "raw": {"sha1": "1de7ed5d5fc75aa1bcede088c655bee3bde64c38", "size": 3588, "url": "https://launcher.mojang.com/v1/objects/1de7ed5d5fc75aa1bcede088c655bee3bde64c38/cautionshield.icns"}}, "executable": false, "type": "file"}, "lib/deploy/ffjcext.zip": {"downloads": {"lzma": {"sha1": "80bcb9b3794f69d87dba93e90230f288e651e798", "size": 1809, "url": "https://launcher.mojang.com/v1/objects/80bcb9b3794f69d87dba93e90230f288e651e798/ffjcext.zip"}, "raw": {"sha1": "76d051ca7d3666ff25ea8eb9957a05574a45287f", "size": 13454, "url": "https://launcher.mojang.com/v1/objects/76d051ca7d3666ff25ea8eb9957a05574a45287f/ffjcext.zip"}}, "executable": false, "type": "file"}, "lib/deploy/java-icon.ico": {"downloads": {"lzma": {"sha1": "2a24f0207d7ab5976a8b0d92b4b381d49e895c9d", "size": 8468, "url": "https://launcher.mojang.com/v1/objects/2a24f0207d7ab5976a8b0d92b4b381d49e895c9d/java-icon.ico"}, "raw": {"sha1": "2997ceb26ff49a7d7c5e7a2405b5fb50b62c7914", "size": 29926, "url": "https://launcher.mojang.com/v1/objects/2997ceb26ff49a7d7c5e7a2405b5fb50b62c7914/java-icon.ico"}}, "executable": false, "type": "file"}, "lib/deploy/messages.properties": {"downloads": {"lzma": {"sha1": "c1e16f80dc0b1f1a591cecf3cbab4ba5e47492f4", "size": 1225, "url": "https://launcher.mojang.com/v1/objects/c1e16f80dc0b1f1a591cecf3cbab4ba5e47492f4/messages.properties"}, "raw": {"sha1": "dc52841c708e3c1eb2a044088a43396d1291bb5e", "size": 2860, "url": "https://launcher.mojang.com/v1/objects/dc52841c708e3c1eb2a044088a43396d1291bb5e/messages.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_de.properties": {"downloads": {"lzma": {"sha1": "42b42e6e1d2cb2d781f2226bde612ce519b29bc8", "size": 1394, "url": "https://launcher.mojang.com/v1/objects/42b42e6e1d2cb2d781f2226bde612ce519b29bc8/messages_de.properties"}, "raw": {"sha1": "d989fe1b8f7904888d5102294ebefd28d932ecdb", "size": 3306, "url": "https://launcher.mojang.com/v1/objects/d989fe1b8f7904888d5102294ebefd28d932ecdb/messages_de.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_es.properties": {"downloads": {"lzma": {"sha1": "c4a653e9802ca982e892b45d88c1e259c09e8c8e", "size": 1404, "url": "https://launcher.mojang.com/v1/objects/c4a653e9802ca982e892b45d88c1e259c09e8c8e/messages_es.properties"}, "raw": {"sha1": "1b0334b79db481c3a59be6915d5118d760c97baa", "size": 3600, "url": "https://launcher.mojang.com/v1/objects/1b0334b79db481c3a59be6915d5118d760c97baa/messages_es.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_fr.properties": {"downloads": {"lzma": {"sha1": "2d8dee07e3f5aab7318a22e169810b216ac44f97", "size": 1401, "url": "https://launcher.mojang.com/v1/objects/2d8dee07e3f5aab7318a22e169810b216ac44f97/messages_fr.properties"}, "raw": {"sha1": "69bd2d03c2064f8679de5b4e430ea61b567c69c5", "size": 3409, "url": "https://launcher.mojang.com/v1/objects/69bd2d03c2064f8679de5b4e430ea61b567c69c5/messages_fr.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_it.properties": {"downloads": {"lzma": {"sha1": "7c28cdd8d9e34355ba0fc03004c4f64749cae57e", "size": 1375, "url": "https://launcher.mojang.com/v1/objects/7c28cdd8d9e34355ba0fc03004c4f64749cae57e/messages_it.properties"}, "raw": {"sha1": "dbe49949308f28540a42ae6cd2ad58afbf615592", "size": 3223, "url": "https://launcher.mojang.com/v1/objects/dbe49949308f28540a42ae6cd2ad58afbf615592/messages_it.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_ja.properties": {"downloads": {"lzma": {"sha1": "9a6a4c086e48b9e615b72b6bbebb3c724d178ff4", "size": 1680, "url": "https://launcher.mojang.com/v1/objects/9a6a4c086e48b9e615b72b6bbebb3c724d178ff4/messages_ja.properties"}, "raw": {"sha1": "751170a7cdefcb1226604ac3f8196e06a04fd7ac", "size": 6349, "url": "https://launcher.mojang.com/v1/objects/751170a7cdefcb1226604ac3f8196e06a04fd7ac/messages_ja.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_ko.properties": {"downloads": {"lzma": {"sha1": "0c57c2ebfa0830f816657a384898487fc492efac", "size": 1645, "url": "https://launcher.mojang.com/v1/objects/0c57c2ebfa0830f816657a384898487fc492efac/messages_ko.properties"}, "raw": {"sha1": "bf9e055b5ab138ad6d49769e2b7630b7938848d6", "size": 5712, "url": "https://launcher.mojang.com/v1/objects/bf9e055b5ab138ad6d49769e2b7630b7938848d6/messages_ko.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_pt_BR.properties": {"downloads": {"lzma": {"sha1": "f8364dba0aa0a7e445a1a8d0e7ad66b996f70063", "size": 1388, "url": "https://launcher.mojang.com/v1/objects/f8364dba0aa0a7e445a1a8d0e7ad66b996f70063/messages_pt_BR.properties"}, "raw": {"sha1": "24e4951743521ab9a11381c77bd0cdb1ed30f5b5", "size": 3285, "url": "https://launcher.mojang.com/v1/objects/24e4951743521ab9a11381c77bd0cdb1ed30f5b5/messages_pt_BR.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_sv.properties": {"downloads": {"lzma": {"sha1": "65e5897d552258141aacf02f087c7c9c33ad0727", "size": 1355, "url": "https://launcher.mojang.com/v1/objects/65e5897d552258141aacf02f087c7c9c33ad0727/messages_sv.properties"}, "raw": {"sha1": "bb5a4aa0ba499f6b1916a83e3c7922a4583b4adb", "size": 3384, "url": "https://launcher.mojang.com/v1/objects/bb5a4aa0ba499f6b1916a83e3c7922a4583b4adb/messages_sv.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_zh_CN.properties": {"downloads": {"lzma": {"sha1": "de7d39a6e6748e9f47e842c9da90f515921c222c", "size": 1506, "url": "https://launcher.mojang.com/v1/objects/de7d39a6e6748e9f47e842c9da90f515921c222c/messages_zh_CN.properties"}, "raw": {"sha1": "1c2b96673dddd3596890ef4fc22017d484a1f652", "size": 4072, "url": "https://launcher.mojang.com/v1/objects/1c2b96673dddd3596890ef4fc22017d484a1f652/messages_zh_CN.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_zh_HK.properties": {"downloads": {"lzma": {"sha1": "e8d0e3a63caa2535a4f361033941f34dcc170a7e", "size": 1529, "url": "https://launcher.mojang.com/v1/objects/e8d0e3a63caa2535a4f361033941f34dcc170a7e/messages_zh_TW.properties"}, "raw": {"sha1": "37a57aad121c14c25e149206179728fa62203bf0", "size": 3752, "url": "https://launcher.mojang.com/v1/objects/37a57aad121c14c25e149206179728fa62203bf0/messages_zh_TW.properties"}}, "executable": false, "type": "file"}, "lib/deploy/messages_zh_TW.properties": {"downloads": {"lzma": {"sha1": "e8d0e3a63caa2535a4f361033941f34dcc170a7e", "size": 1529, "url": "https://launcher.mojang.com/v1/objects/e8d0e3a63caa2535a4f361033941f34dcc170a7e/messages_zh_TW.properties"}, "raw": {"sha1": "37a57aad121c14c25e149206179728fa62203bf0", "size": 3752, "url": "https://launcher.mojang.com/v1/objects/37a57aad121c14c25e149206179728fa62203bf0/messages_zh_TW.properties"}}, "executable": false, "type": "file"}, "lib/deploy/mixcode_s.png": {"downloads": {"raw": {"sha1": "4604e9f265eec97bccd0151c3a81afa9e69499e5", "size": 3115, "url": "https://launcher.mojang.com/v1/objects/4604e9f265eec97bccd0151c3a81afa9e69499e5/mixcode_s.png"}}, "executable": false, "type": "file"}, "lib/deploy/splash.gif": {"downloads": {"raw": {"sha1": "20e7aec75f6d036d504277542e507eb7dc24aae8", "size": 8590, "url": "https://launcher.mojang.com/v1/objects/20e7aec75f6d036d504277542e507eb7dc24aae8/splash.gif"}}, "executable": false, "type": "file"}, "lib/deploy/splash@2x.gif": {"downloads": {"raw": {"sha1": "0ae4a5bda2a6d628fac51462390b503c99509fdc", "size": 15276, "url": "https://launcher.mojang.com/v1/objects/0ae4a5bda2a6d628fac51462390b503c99509fdc/splash2x.gif"}}, "executable": false, "type": "file"}, "lib/deploy/splash_11-lic.gif": {"downloads": {"raw": {"sha1": "8def364e07f40142822df84b5bb4f50846cb5e4e", "size": 7805, "url": "https://launcher.mojang.com/v1/objects/8def364e07f40142822df84b5bb4f50846cb5e4e/splash_11-lic.gif"}}, "executable": false, "type": "file"}, "lib/deploy/splash_11@2x-lic.gif": {"downloads": {"raw": {"sha1": "d2bff9bbf7920ca743b81a0ee23b0719b4d057ca", "size": 12250, "url": "https://launcher.mojang.com/v1/objects/d2bff9bbf7920ca743b81a0ee23b0719b4d057ca/splash_11%402x-lic.gif"}}, "executable": false, "type": "file"}, "lib/desktop": {"type": "directory"}, "lib/desktop/applications": {"type": "directory"}, "lib/desktop/applications/sun-java.desktop": {"downloads": {"lzma": {"sha1": "109d1cdf165f38da92da70b403ca940192a7a9a8", "size": 536, "url": "https://launcher.mojang.com/v1/objects/109d1cdf165f38da92da70b403ca940192a7a9a8/sun-java.desktop"}, "raw": {"sha1": "d346dfe90505603ce5aff5a3c6c2e4a23d5bd990", "size": 777, "url": "https://launcher.mojang.com/v1/objects/d346dfe90505603ce5aff5a3c6c2e4a23d5bd990/sun-java.desktop"}}, "executable": false, "type": "file"}, "lib/desktop/applications/sun-javaws.desktop": {"downloads": {"lzma": {"sha1": "5e1815e7f83515881e6998584dc6bb02c5bef09a", "size": 451, "url": "https://launcher.mojang.com/v1/objects/5e1815e7f83515881e6998584dc6bb02c5bef09a/sun-javaws.desktop"}, "raw": {"sha1": "50ce8e519b836e0f53d58ce1a359d98b6cafdda6", "size": 619, "url": "https://launcher.mojang.com/v1/objects/50ce8e519b836e0f53d58ce1a359d98b6cafdda6/sun-javaws.desktop"}}, "executable": false, "type": "file"}, "lib/desktop/applications/sun_java.desktop": {"downloads": {"lzma": {"sha1": "49ab0ccb54c3be68281d05055bc56a88b1281d3c", "size": 447, "url": "https://launcher.mojang.com/v1/objects/49ab0ccb54c3be68281d05055bc56a88b1281d3c/sun_java.desktop"}, "raw": {"sha1": "79120ee8160ad6f3c9b90c2641fb7edf3af96b5d", "size": 624, "url": "https://launcher.mojang.com/v1/objects/79120ee8160ad6f3c9b90c2641fb7edf3af96b5d/sun_java.desktop"}}, "executable": false, "type": "file"}, "lib/desktop/icons": {"type": "directory"}, "lib/desktop/icons/HighContrast": {"type": "directory"}, "lib/desktop/icons/HighContrast/16x16": {"type": "directory"}, "lib/desktop/icons/HighContrast/16x16/apps": {"type": "directory"}, "lib/desktop/icons/HighContrast/16x16/apps/sun-java.png": {"downloads": {"raw": {"sha1": "366e7a48e9e4fb92eaeabbcaeb4626122a66cecb", "size": 417, "url": "https://launcher.mojang.com/v1/objects/366e7a48e9e4fb92eaeabbcaeb4626122a66cecb/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/16x16/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "366e7a48e9e4fb92eaeabbcaeb4626122a66cecb", "size": 417, "url": "https://launcher.mojang.com/v1/objects/366e7a48e9e4fb92eaeabbcaeb4626122a66cecb/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/16x16/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "366e7a48e9e4fb92eaeabbcaeb4626122a66cecb", "size": 417, "url": "https://launcher.mojang.com/v1/objects/366e7a48e9e4fb92eaeabbcaeb4626122a66cecb/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/16x16/mimetypes": {"type": "directory"}, "lib/desktop/icons/HighContrast/16x16/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "629c48907368ecf32d2395b6459c367f79d84689", "size": 464, "url": "https://launcher.mojang.com/v1/objects/629c48907368ecf32d2395b6459c367f79d84689/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "629c48907368ecf32d2395b6459c367f79d84689", "size": 464, "url": "https://launcher.mojang.com/v1/objects/629c48907368ecf32d2395b6459c367f79d84689/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/16x16/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "629c48907368ecf32d2395b6459c367f79d84689", "size": 464, "url": "https://launcher.mojang.com/v1/objects/629c48907368ecf32d2395b6459c367f79d84689/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/48x48": {"type": "directory"}, "lib/desktop/icons/HighContrast/48x48/apps": {"type": "directory"}, "lib/desktop/icons/HighContrast/48x48/apps/sun-java.png": {"downloads": {"raw": {"sha1": "8373482d072684e09830dbdb97a76ea264c9f4e9", "size": 3451, "url": "https://launcher.mojang.com/v1/objects/8373482d072684e09830dbdb97a76ea264c9f4e9/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/48x48/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "8373482d072684e09830dbdb97a76ea264c9f4e9", "size": 3451, "url": "https://launcher.mojang.com/v1/objects/8373482d072684e09830dbdb97a76ea264c9f4e9/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/48x48/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "8373482d072684e09830dbdb97a76ea264c9f4e9", "size": 3451, "url": "https://launcher.mojang.com/v1/objects/8373482d072684e09830dbdb97a76ea264c9f4e9/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/48x48/mimetypes": {"type": "directory"}, "lib/desktop/icons/HighContrast/48x48/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "56a4996519f8f3541eba7b7a7a69bcdcd8ed0410", "size": 2088, "url": "https://launcher.mojang.com/v1/objects/56a4996519f8f3541eba7b7a7a69bcdcd8ed0410/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "56a4996519f8f3541eba7b7a7a69bcdcd8ed0410", "size": 2088, "url": "https://launcher.mojang.com/v1/objects/56a4996519f8f3541eba7b7a7a69bcdcd8ed0410/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrast/48x48/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "56a4996519f8f3541eba7b7a7a69bcdcd8ed0410", "size": 2088, "url": "https://launcher.mojang.com/v1/objects/56a4996519f8f3541eba7b7a7a69bcdcd8ed0410/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/16x16": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/16x16/apps": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/16x16/apps/sun-java.png": {"downloads": {"raw": {"sha1": "bf0995acb94aa794e73c5b971282ff13ffe42793", "size": 402, "url": "https://launcher.mojang.com/v1/objects/bf0995acb94aa794e73c5b971282ff13ffe42793/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/16x16/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "bf0995acb94aa794e73c5b971282ff13ffe42793", "size": 402, "url": "https://launcher.mojang.com/v1/objects/bf0995acb94aa794e73c5b971282ff13ffe42793/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/16x16/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "bf0995acb94aa794e73c5b971282ff13ffe42793", "size": 402, "url": "https://launcher.mojang.com/v1/objects/bf0995acb94aa794e73c5b971282ff13ffe42793/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/16x16/mimetypes": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/16x16/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "1477eceda25e162fcda2e69ee3906091973d8344", "size": 473, "url": "https://launcher.mojang.com/v1/objects/1477eceda25e162fcda2e69ee3906091973d8344/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "1477eceda25e162fcda2e69ee3906091973d8344", "size": 473, "url": "https://launcher.mojang.com/v1/objects/1477eceda25e162fcda2e69ee3906091973d8344/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/16x16/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "1477eceda25e162fcda2e69ee3906091973d8344", "size": 473, "url": "https://launcher.mojang.com/v1/objects/1477eceda25e162fcda2e69ee3906091973d8344/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/48x48": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/48x48/apps": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/48x48/apps/sun-java.png": {"downloads": {"raw": {"sha1": "413da160dd9899b95f53d4cc11f5ee0550cc6585", "size": 3410, "url": "https://launcher.mojang.com/v1/objects/413da160dd9899b95f53d4cc11f5ee0550cc6585/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/48x48/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "413da160dd9899b95f53d4cc11f5ee0550cc6585", "size": 3410, "url": "https://launcher.mojang.com/v1/objects/413da160dd9899b95f53d4cc11f5ee0550cc6585/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/48x48/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "413da160dd9899b95f53d4cc11f5ee0550cc6585", "size": 3410, "url": "https://launcher.mojang.com/v1/objects/413da160dd9899b95f53d4cc11f5ee0550cc6585/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/48x48/mimetypes": {"type": "directory"}, "lib/desktop/icons/HighContrastInverse/48x48/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "d66e04dfa25c196bec2e201547325b79846ab674", "size": 2085, "url": "https://launcher.mojang.com/v1/objects/d66e04dfa25c196bec2e201547325b79846ab674/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "d66e04dfa25c196bec2e201547325b79846ab674", "size": 2085, "url": "https://launcher.mojang.com/v1/objects/d66e04dfa25c196bec2e201547325b79846ab674/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/HighContrastInverse/48x48/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "d66e04dfa25c196bec2e201547325b79846ab674", "size": 2085, "url": "https://launcher.mojang.com/v1/objects/d66e04dfa25c196bec2e201547325b79846ab674/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast": {"type": "directory"}, "lib/desktop/icons/LowContrast/16x16": {"type": "directory"}, "lib/desktop/icons/LowContrast/16x16/apps": {"type": "directory"}, "lib/desktop/icons/LowContrast/16x16/apps/sun-java.png": {"downloads": {"raw": {"sha1": "f93b7cf0a6d27d664a7f09dab6933b2768536f52", "size": 519, "url": "https://launcher.mojang.com/v1/objects/f93b7cf0a6d27d664a7f09dab6933b2768536f52/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/16x16/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "f93b7cf0a6d27d664a7f09dab6933b2768536f52", "size": 519, "url": "https://launcher.mojang.com/v1/objects/f93b7cf0a6d27d664a7f09dab6933b2768536f52/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/16x16/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "f93b7cf0a6d27d664a7f09dab6933b2768536f52", "size": 519, "url": "https://launcher.mojang.com/v1/objects/f93b7cf0a6d27d664a7f09dab6933b2768536f52/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/16x16/mimetypes": {"type": "directory"}, "lib/desktop/icons/LowContrast/16x16/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "0aa1605877280b88de1f1cc3e7e4bdbeed968a73", "size": 525, "url": "https://launcher.mojang.com/v1/objects/0aa1605877280b88de1f1cc3e7e4bdbeed968a73/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "0aa1605877280b88de1f1cc3e7e4bdbeed968a73", "size": 525, "url": "https://launcher.mojang.com/v1/objects/0aa1605877280b88de1f1cc3e7e4bdbeed968a73/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/16x16/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "0aa1605877280b88de1f1cc3e7e4bdbeed968a73", "size": 525, "url": "https://launcher.mojang.com/v1/objects/0aa1605877280b88de1f1cc3e7e4bdbeed968a73/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/48x48": {"type": "directory"}, "lib/desktop/icons/LowContrast/48x48/apps": {"type": "directory"}, "lib/desktop/icons/LowContrast/48x48/apps/sun-java.png": {"downloads": {"raw": {"sha1": "1fcf4fd6da61873b5f21b39412da26509734b7cc", "size": 1507, "url": "https://launcher.mojang.com/v1/objects/1fcf4fd6da61873b5f21b39412da26509734b7cc/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/48x48/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "1fcf4fd6da61873b5f21b39412da26509734b7cc", "size": 1507, "url": "https://launcher.mojang.com/v1/objects/1fcf4fd6da61873b5f21b39412da26509734b7cc/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/48x48/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "1fcf4fd6da61873b5f21b39412da26509734b7cc", "size": 1507, "url": "https://launcher.mojang.com/v1/objects/1fcf4fd6da61873b5f21b39412da26509734b7cc/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/48x48/mimetypes": {"type": "directory"}, "lib/desktop/icons/LowContrast/48x48/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "e36636b1c04dc283c18adf669b892d54b15d3ee6", "size": 1948, "url": "https://launcher.mojang.com/v1/objects/e36636b1c04dc283c18adf669b892d54b15d3ee6/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "e36636b1c04dc283c18adf669b892d54b15d3ee6", "size": 1948, "url": "https://launcher.mojang.com/v1/objects/e36636b1c04dc283c18adf669b892d54b15d3ee6/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/LowContrast/48x48/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "e36636b1c04dc283c18adf669b892d54b15d3ee6", "size": 1948, "url": "https://launcher.mojang.com/v1/objects/e36636b1c04dc283c18adf669b892d54b15d3ee6/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor": {"type": "directory"}, "lib/desktop/icons/hicolor/16x16": {"type": "directory"}, "lib/desktop/icons/hicolor/16x16/apps": {"type": "directory"}, "lib/desktop/icons/hicolor/16x16/apps/sun-java.png": {"downloads": {"raw": {"sha1": "e91d05bfe9b889bf8a227908b597cab4630da8f2", "size": 383, "url": "https://launcher.mojang.com/v1/objects/e91d05bfe9b889bf8a227908b597cab4630da8f2/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/16x16/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "e91d05bfe9b889bf8a227908b597cab4630da8f2", "size": 383, "url": "https://launcher.mojang.com/v1/objects/e91d05bfe9b889bf8a227908b597cab4630da8f2/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/16x16/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "e91d05bfe9b889bf8a227908b597cab4630da8f2", "size": 383, "url": "https://launcher.mojang.com/v1/objects/e91d05bfe9b889bf8a227908b597cab4630da8f2/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/16x16/mimetypes": {"type": "directory"}, "lib/desktop/icons/hicolor/16x16/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "d2f6abe8e498aeecb334fb43f63001d34dbf6ea5", "size": 783, "url": "https://launcher.mojang.com/v1/objects/d2f6abe8e498aeecb334fb43f63001d34dbf6ea5/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "d2f6abe8e498aeecb334fb43f63001d34dbf6ea5", "size": 783, "url": "https://launcher.mojang.com/v1/objects/d2f6abe8e498aeecb334fb43f63001d34dbf6ea5/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/16x16/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "d2f6abe8e498aeecb334fb43f63001d34dbf6ea5", "size": 783, "url": "https://launcher.mojang.com/v1/objects/d2f6abe8e498aeecb334fb43f63001d34dbf6ea5/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/48x48": {"type": "directory"}, "lib/desktop/icons/hicolor/48x48/apps": {"type": "directory"}, "lib/desktop/icons/hicolor/48x48/apps/sun-java.png": {"downloads": {"raw": {"sha1": "6c90a38eaada9c32a678a282be18ec5b43a84264", "size": 1439, "url": "https://launcher.mojang.com/v1/objects/6c90a38eaada9c32a678a282be18ec5b43a84264/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/48x48/apps/sun-javaws.png": {"downloads": {"raw": {"sha1": "6c90a38eaada9c32a678a282be18ec5b43a84264", "size": 1439, "url": "https://launcher.mojang.com/v1/objects/6c90a38eaada9c32a678a282be18ec5b43a84264/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/48x48/apps/sun-jcontrol.png": {"downloads": {"raw": {"sha1": "6c90a38eaada9c32a678a282be18ec5b43a84264", "size": 1439, "url": "https://launcher.mojang.com/v1/objects/6c90a38eaada9c32a678a282be18ec5b43a84264/sun-javaws.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/48x48/mimetypes": {"type": "directory"}, "lib/desktop/icons/hicolor/48x48/mimetypes/gnome-mime-application-x-java-archive.png": {"downloads": {"raw": {"sha1": "4d5e6e0c41d1076bc86f3ab157c88a41a5716997", "size": 3202, "url": "https://launcher.mojang.com/v1/objects/4d5e6e0c41d1076bc86f3ab157c88a41a5716997/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": {"downloads": {"raw": {"sha1": "4d5e6e0c41d1076bc86f3ab157c88a41a5716997", "size": 3202, "url": "https://launcher.mojang.com/v1/objects/4d5e6e0c41d1076bc86f3ab157c88a41a5716997/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/icons/hicolor/48x48/mimetypes/gnome-mime-text-x-java.png": {"downloads": {"raw": {"sha1": "4d5e6e0c41d1076bc86f3ab157c88a41a5716997", "size": 3202, "url": "https://launcher.mojang.com/v1/objects/4d5e6e0c41d1076bc86f3ab157c88a41a5716997/gnome-mime-application-x-java-archive.png"}}, "executable": false, "type": "file"}, "lib/desktop/mime": {"type": "directory"}, "lib/desktop/mime/packages": {"type": "directory"}, "lib/desktop/mime/packages/x-java-archive.xml": {"downloads": {"lzma": {"sha1": "841230729f0a59de2a1071d155d96358232b2ba1", "size": 591, "url": "https://launcher.mojang.com/v1/objects/841230729f0a59de2a1071d155d96358232b2ba1/x-java-archive.xml"}, "raw": {"sha1": "b6297fd36efa799312961f95ebf0c85c920d5037", "size": 1822, "url": "https://launcher.mojang.com/v1/objects/b6297fd36efa799312961f95ebf0c85c920d5037/x-java-archive.xml"}}, "executable": false, "type": "file"}, "lib/desktop/mime/packages/x-java-jnlp-file.xml": {"downloads": {"lzma": {"sha1": "abf9acbe7c18027c4f036c4e42bb2cf1115525fa", "size": 302, "url": "https://launcher.mojang.com/v1/objects/abf9acbe7c18027c4f036c4e42bb2cf1115525fa/x-java-jnlp-file.xml"}, "raw": {"sha1": "72f03da83ddb76c9105f619fcfa4dbdad70e6b30", "size": 412, "url": "https://launcher.mojang.com/v1/objects/72f03da83ddb76c9105f619fcfa4dbdad70e6b30/x-java-jnlp-file.xml"}}, "executable": false, "type": "file"}, "lib/ext": {"type": "directory"}, "lib/ext/cldrdata.jar": {"downloads": {"raw": {"sha1": "6cacc961942d3f02a88907aa8f2eaae8e20c95a0", "size": 3860502, "url": "https://launcher.mojang.com/v1/objects/6cacc961942d3f02a88907aa8f2eaae8e20c95a0/cldrdata.jar"}}, "executable": false, "type": "file"}, "lib/ext/dnsns.jar": {"downloads": {"raw": {"sha1": "93bebdd7514e53ae31d60c5daba673878c8822ec", "size": 8286, "url": "https://launcher.mojang.com/v1/objects/93bebdd7514e53ae31d60c5daba673878c8822ec/dnsns.jar"}}, "executable": false, "type": "file"}, "lib/ext/jaccess.jar": {"downloads": {"raw": {"sha1": "2f54879df7c29ec67c40d40cfc95c0d4a968bea1", "size": 44516, "url": "https://launcher.mojang.com/v1/objects/2f54879df7c29ec67c40d40cfc95c0d4a968bea1/jaccess.jar"}}, "executable": false, "type": "file"}, "lib/ext/jfxrt.jar": {"downloads": {"lzma": {"sha1": "a6c5b6a782ba360ada6651f5322dcab88c75711c", "size": 3374270, "url": "https://launcher.mojang.com/v1/objects/a6c5b6a782ba360ada6651f5322dcab88c75711c/jfxrt.jar"}, "raw": {"sha1": "1ad7a876f045399c23ee4ab7dee380a04ca2ac08", "size": 18508094, "url": "https://launcher.mojang.com/v1/objects/1ad7a876f045399c23ee4ab7dee380a04ca2ac08/jfxrt.jar"}}, "executable": false, "type": "file"}, "lib/ext/localedata.jar": {"downloads": {"raw": {"sha1": "0cc9f550d4e410b5aa29dbfd2c1b5c99391c7f70", "size": 1178926, "url": "https://launcher.mojang.com/v1/objects/0cc9f550d4e410b5aa29dbfd2c1b5c99391c7f70/localedata.jar"}}, "executable": false, "type": "file"}, "lib/ext/meta-index": {"downloads": {"lzma": {"sha1": "1359457529f42bacf495afcb68149ae036442dd9", "size": 594, "url": "https://launcher.mojang.com/v1/objects/1359457529f42bacf495afcb68149ae036442dd9/meta-index"}, "raw": {"sha1": "334649c6e2d5d7248211f30855e97cfcb4558851", "size": 1269, "url": "https://launcher.mojang.com/v1/objects/334649c6e2d5d7248211f30855e97cfcb4558851/meta-index"}}, "executable": false, "type": "file"}, "lib/ext/nashorn.jar": {"downloads": {"raw": {"sha1": "dec5dd17a0f52ae79dfbfb38840bffb8b7a679a5", "size": 2023869, "url": "https://launcher.mojang.com/v1/objects/dec5dd17a0f52ae79dfbfb38840bffb8b7a679a5/nashorn.jar"}}, "executable": false, "type": "file"}, "lib/ext/sunec.jar": {"downloads": {"raw": {"sha1": "bf1c817820341a246f7130fe046e8310b03d04f6", "size": 41672, "url": "https://launcher.mojang.com/v1/objects/bf1c817820341a246f7130fe046e8310b03d04f6/sunec.jar"}}, "executable": false, "type": "file"}, "lib/ext/sunjce_provider.jar": {"downloads": {"raw": {"sha1": "bb3494e4b5cb3c3e60da767207731f18b267cb34", "size": 279326, "url": "https://launcher.mojang.com/v1/objects/bb3494e4b5cb3c3e60da767207731f18b267cb34/sunjce_provider.jar"}}, "executable": false, "type": "file"}, "lib/ext/sunpkcs11.jar": {"downloads": {"raw": {"sha1": "5bb1dedc3344cd3bb86828d4aa8ca82f4a606ed4", "size": 250218, "url": "https://launcher.mojang.com/v1/objects/5bb1dedc3344cd3bb86828d4aa8ca82f4a606ed4/sunpkcs11.jar"}}, "executable": false, "type": "file"}, "lib/ext/zipfs.jar": {"downloads": {"raw": {"sha1": "37b338f0e8e60d6396f51275130e8110816d7b30", "size": 68964, "url": "https://launcher.mojang.com/v1/objects/37b338f0e8e60d6396f51275130e8110816d7b30/zipfs.jar"}}, "executable": false, "type": "file"}, "lib/flavormap.properties": {"downloads": {"lzma": {"sha1": "2d5ef19ee77ccfc95c9413eea155cde59a48fadd", "size": 1541, "url": "https://launcher.mojang.com/v1/objects/2d5ef19ee77ccfc95c9413eea155cde59a48fadd/flavormap.properties"}, "raw": {"sha1": "4e66e8fe12d7f8b3b0c4e1a1915f329bb1fbf6d2", "size": 3901, "url": "https://launcher.mojang.com/v1/objects/4e66e8fe12d7f8b3b0c4e1a1915f329bb1fbf6d2/flavormap.properties"}}, "executable": false, "type": "file"}, "lib/fontconfig.RedHat.5.bfc": {"downloads": {"lzma": {"sha1": "5197f6e387f16458b7408134e38b06f20f625e4c", "size": 795, "url": "https://launcher.mojang.com/v1/objects/5197f6e387f16458b7408134e38b06f20f625e4c/fontconfig.RedHat.5.bfc"}, "raw": {"sha1": "fb806ada6e68f16a9fe2b726a39d9ef5a835c0c2", "size": 4532, "url": "https://launcher.mojang.com/v1/objects/fb806ada6e68f16a9fe2b726a39d9ef5a835c0c2/fontconfig.RedHat.5.bfc"}}, "executable": false, "type": "file"}, "lib/fontconfig.RedHat.5.properties.src": {"downloads": {"lzma": {"sha1": "3897ae198e96e5a687c9c9b218ff5df60c868e0d", "size": 1089, "url": "https://launcher.mojang.com/v1/objects/3897ae198e96e5a687c9c9b218ff5df60c868e0d/fontconfig.RedHat.5.properties.src"}, "raw": {"sha1": "c67d1a06cb37b66e69560c9f5e4be7cf08af0493", "size": 8841, "url": "https://launcher.mojang.com/v1/objects/c67d1a06cb37b66e69560c9f5e4be7cf08af0493/fontconfig.RedHat.5.properties.src"}}, "executable": false, "type": "file"}, "lib/fontconfig.RedHat.6.bfc": {"downloads": {"lzma": {"sha1": "ef2f5d1f8d620be9927db45d3a28bd75777245cb", "size": 818, "url": "https://launcher.mojang.com/v1/objects/ef2f5d1f8d620be9927db45d3a28bd75777245cb/fontconfig.RedHat.6.bfc"}, "raw": {"sha1": "9ba3b3e2c621c31d0ef1b2053c80f77419a19965", "size": 4250, "url": "https://launcher.mojang.com/v1/objects/9ba3b3e2c621c31d0ef1b2053c80f77419a19965/fontconfig.RedHat.6.bfc"}}, "executable": false, "type": "file"}, "lib/fontconfig.RedHat.6.properties.src": {"downloads": {"lzma": {"sha1": "74f4148f9d7ec3d67bbd724834d478a72cfdb0db", "size": 1111, "url": "https://launcher.mojang.com/v1/objects/74f4148f9d7ec3d67bbd724834d478a72cfdb0db/fontconfig.RedHat.6.properties.src"}, "raw": {"sha1": "768e58d4d314621c38daf9fde6d67119f370acd9", "size": 8735, "url": "https://launcher.mojang.com/v1/objects/768e58d4d314621c38daf9fde6d67119f370acd9/fontconfig.RedHat.6.properties.src"}}, "executable": false, "type": "file"}, "lib/fontconfig.SuSE.10.bfc": {"downloads": {"lzma": {"sha1": "d8fe9b1d8d02368dcd452de93024c6f60670eb87", "size": 1083, "url": "https://launcher.mojang.com/v1/objects/d8fe9b1d8d02368dcd452de93024c6f60670eb87/fontconfig.SuSE.10.bfc"}, "raw": {"sha1": "ffd0dfbd1553e15b11649a73a0b3f48318138e0d", "size": 6702, "url": "https://launcher.mojang.com/v1/objects/ffd0dfbd1553e15b11649a73a0b3f48318138e0d/fontconfig.SuSE.10.bfc"}}, "executable": false, "type": "file"}, "lib/fontconfig.SuSE.10.properties.src": {"downloads": {"lzma": {"sha1": "2c382bd741a9e23114be3da82dee8290ebfca8a9", "size": 1555, "url": "https://launcher.mojang.com/v1/objects/2c382bd741a9e23114be3da82dee8290ebfca8a9/fontconfig.SuSE.10.properties.src"}, "raw": {"sha1": "a38dbdbbc514567b8281e1aea726865f37e97894", "size": 16772, "url": "https://launcher.mojang.com/v1/objects/a38dbdbbc514567b8281e1aea726865f37e97894/fontconfig.SuSE.10.properties.src"}}, "executable": false, "type": "file"}, "lib/fontconfig.SuSE.11.bfc": {"downloads": {"lzma": {"sha1": "2b78cbf11289c9858951fea7180696ba3b7176d6", "size": 1092, "url": "https://launcher.mojang.com/v1/objects/2b78cbf11289c9858951fea7180696ba3b7176d6/fontconfig.SuSE.11.bfc"}, "raw": {"sha1": "a4d8500fcb47f6327460a95851b1368660da8302", "size": 7032, "url": "https://launcher.mojang.com/v1/objects/a4d8500fcb47f6327460a95851b1368660da8302/fontconfig.SuSE.11.bfc"}}, "executable": false, "type": "file"}, "lib/fontconfig.SuSE.11.properties.src": {"downloads": {"lzma": {"sha1": "5c1635803906e2c59d36492dec724dd7ae49a5ab", "size": 1589, "url": "https://launcher.mojang.com/v1/objects/5c1635803906e2c59d36492dec724dd7ae49a5ab/fontconfig.SuSE.11.properties.src"}, "raw": {"sha1": "c4b69589e41a7279a71866a9134213be19cdf88d", "size": 16781, "url": "https://launcher.mojang.com/v1/objects/c4b69589e41a7279a71866a9134213be19cdf88d/fontconfig.SuSE.11.properties.src"}}, "executable": false, "type": "file"}, "lib/fontconfig.Turbo.bfc": {"downloads": {"lzma": {"sha1": "1c771325d9ee4af209a3db92294451d58962c7a4", "size": 822, "url": "https://launcher.mojang.com/v1/objects/1c771325d9ee4af209a3db92294451d58962c7a4/fontconfig.Turbo.bfc"}, "raw": {"sha1": "f24368deeb85cc9d0781083bc56e773518d72219", "size": 4668, "url": "https://launcher.mojang.com/v1/objects/f24368deeb85cc9d0781083bc56e773518d72219/fontconfig.Turbo.bfc"}}, "executable": false, "type": "file"}, "lib/fontconfig.Turbo.properties.src": {"downloads": {"lzma": {"sha1": "7748ffa17e2c8a34754138efa963ba39bd1cbbb3", "size": 1113, "url": "https://launcher.mojang.com/v1/objects/7748ffa17e2c8a34754138efa963ba39bd1cbbb3/fontconfig.Turbo.properties.src"}, "raw": {"sha1": "2bb7258bed7ccd4f117e4e5f892c9b13424b0c82", "size": 9192, "url": "https://launcher.mojang.com/v1/objects/2bb7258bed7ccd4f117e4e5f892c9b13424b0c82/fontconfig.Turbo.properties.src"}}, "executable": false, "type": "file"}, "lib/fontconfig.bfc": {"downloads": {"lzma": {"sha1": "be6d49ee8c64f458c4f0e64254963fec48d25150", "size": 286, "url": "https://launcher.mojang.com/v1/objects/be6d49ee8c64f458c4f0e64254963fec48d25150/fontconfig.bfc"}, "raw": {"sha1": "de39b0e19637f58d92a0188122514aa7247ebb5b", "size": 1678, "url": "https://launcher.mojang.com/v1/objects/de39b0e19637f58d92a0188122514aa7247ebb5b/fontconfig.bfc"}}, "executable": false, "type": "file"}, "lib/fontconfig.properties.src": {"downloads": {"lzma": {"sha1": "9498d5e00e5401200667687e826e28c60fa60ba4", "size": 417, "url": "https://launcher.mojang.com/v1/objects/9498d5e00e5401200667687e826e28c60fa60ba4/fontconfig.properties.src"}, "raw": {"sha1": "3617ff1424fd204415242565541facf862b16eb4", "size": 1938, "url": "https://launcher.mojang.com/v1/objects/3617ff1424fd204415242565541facf862b16eb4/fontconfig.properties.src"}}, "executable": false, "type": "file"}, "lib/fonts": {"type": "directory"}, "lib/fonts/LucidaBrightDemiBold.ttf": {"downloads": {"lzma": {"sha1": "4f748750831a7719440dff5457f4d207d0f24d21", "size": 42347, "url": "https://launcher.mojang.com/v1/objects/4f748750831a7719440dff5457f4d207d0f24d21/LucidaBrightDemiBold.ttf"}, "raw": {"sha1": "b5c97f985639e19a3b712193ee48b55dda581fd1", "size": 75144, "url": "https://launcher.mojang.com/v1/objects/b5c97f985639e19a3b712193ee48b55dda581fd1/LucidaBrightDemiBold.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaBrightDemiItalic.ttf": {"downloads": {"lzma": {"sha1": "f82e9a688553c100ecb98412b985807ed56dff5d", "size": 43119, "url": "https://launcher.mojang.com/v1/objects/f82e9a688553c100ecb98412b985807ed56dff5d/LucidaBrightDemiItalic.ttf"}, "raw": {"sha1": "1fd1f757febf3e5f5fbb7fbf7a56587a40d57de7", "size": 75124, "url": "https://launcher.mojang.com/v1/objects/1fd1f757febf3e5f5fbb7fbf7a56587a40d57de7/LucidaBrightDemiItalic.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaBrightItalic.ttf": {"downloads": {"lzma": {"sha1": "6d630df719271319c3d53f90a3d425118b908266", "size": 46206, "url": "https://launcher.mojang.com/v1/objects/6d630df719271319c3d53f90a3d425118b908266/LucidaBrightItalic.ttf"}, "raw": {"sha1": "aa5c037865c563726ecd63d61ca26443589be425", "size": 80856, "url": "https://launcher.mojang.com/v1/objects/aa5c037865c563726ecd63d61ca26443589be425/LucidaBrightItalic.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaBrightRegular.ttf": {"downloads": {"lzma": {"sha1": "4b2e31aaec2238b6ecf9f845bad0a1c6d09fbbfe", "size": 181085, "url": "https://launcher.mojang.com/v1/objects/4b2e31aaec2238b6ecf9f845bad0a1c6d09fbbfe/LucidaBrightRegular.ttf"}, "raw": {"sha1": "5d7ed564791c900a8786936930ba99385653139c", "size": 344908, "url": "https://launcher.mojang.com/v1/objects/5d7ed564791c900a8786936930ba99385653139c/LucidaBrightRegular.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaSansDemiBold.ttf": {"downloads": {"lzma": {"sha1": "079b16dc3c4918ab1f4f760b6dc5e6586c219042", "size": 173229, "url": "https://launcher.mojang.com/v1/objects/079b16dc3c4918ab1f4f760b6dc5e6586c219042/LucidaSansDemiBold.ttf"}, "raw": {"sha1": "92b79fefc35e96190250c602a8fed85276b32a95", "size": 317896, "url": "https://launcher.mojang.com/v1/objects/92b79fefc35e96190250c602a8fed85276b32a95/LucidaSansDemiBold.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaSansRegular.ttf": {"downloads": {"lzma": {"sha1": "64a65d7b94d7153d20957ef6d06bebb4dd0f48e4", "size": 326062, "url": "https://launcher.mojang.com/v1/objects/64a65d7b94d7153d20957ef6d06bebb4dd0f48e4/LucidaSansRegular.ttf"}, "raw": {"sha1": "39cc8bcb8d4a71d4657fc92ef0b9f4e3e9e67add", "size": 698236, "url": "https://launcher.mojang.com/v1/objects/39cc8bcb8d4a71d4657fc92ef0b9f4e3e9e67add/LucidaSansRegular.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaTypewriterBold.ttf": {"downloads": {"lzma": {"sha1": "cdb017f7c34bea0802bc5ea5583aef721ed99c49", "size": 130412, "url": "https://launcher.mojang.com/v1/objects/cdb017f7c34bea0802bc5ea5583aef721ed99c49/LucidaTypewriterBold.ttf"}, "raw": {"sha1": "a5da2eb49448f461470387c939f0e69119310e0b", "size": 234068, "url": "https://launcher.mojang.com/v1/objects/a5da2eb49448f461470387c939f0e69119310e0b/LucidaTypewriterBold.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/LucidaTypewriterRegular.ttf": {"downloads": {"lzma": {"sha1": "aeda4a09a53783b0dc97de8e20071bea874cbfe5", "size": 135184, "url": "https://launcher.mojang.com/v1/objects/aeda4a09a53783b0dc97de8e20071bea874cbfe5/LucidaTypewriterRegular.ttf"}, "raw": {"sha1": "c144dcafe4faf2e79cfd74d8134a631f30234db1", "size": 242700, "url": "https://launcher.mojang.com/v1/objects/c144dcafe4faf2e79cfd74d8134a631f30234db1/LucidaTypewriterRegular.ttf"}}, "executable": false, "type": "file"}, "lib/fonts/fonts.dir": {"downloads": {"lzma": {"sha1": "68f2dd93b215ec8b8d9409d2b9c825632c6b907d", "size": 273, "url": "https://launcher.mojang.com/v1/objects/68f2dd93b215ec8b8d9409d2b9c825632c6b907d/fonts.dir"}, "raw": {"sha1": "97f40cca185c954adf5cc582345a7cb8e4c50578", "size": 4041, "url": "https://launcher.mojang.com/v1/objects/97f40cca185c954adf5cc582345a7cb8e4c50578/fonts.dir"}}, "executable": false, "type": "file"}, "lib/hijrah-config-umalqura.properties": {"downloads": {"lzma": {"sha1": "02e8d296e3b18a450f1ed1547cbf2b7275664c9a", "size": 1969, "url": "https://launcher.mojang.com/v1/objects/02e8d296e3b18a450f1ed1547cbf2b7275664c9a/hijrah-config-umalqura.properties"}, "raw": {"sha1": "84aa425100740722e91f4725caf849e7863d12ba", "size": 13962, "url": "https://launcher.mojang.com/v1/objects/84aa425100740722e91f4725caf849e7863d12ba/hijrah-config-umalqura.properties"}}, "executable": false, "type": "file"}, "lib/images": {"type": "directory"}, "lib/images/cursors": {"type": "directory"}, "lib/images/cursors/cursors.properties": {"downloads": {"lzma": {"sha1": "612bd0f610ee1023947c4a2a8d3fc7d6f97e7d8f", "size": 385, "url": "https://launcher.mojang.com/v1/objects/612bd0f610ee1023947c4a2a8d3fc7d6f97e7d8f/cursors.properties"}, "raw": {"sha1": "f2b9a22ddd0a77869497a64f28f07e89a7d41f48", "size": 1274, "url": "https://launcher.mojang.com/v1/objects/f2b9a22ddd0a77869497a64f28f07e89a7d41f48/cursors.properties"}}, "executable": false, "type": "file"}, "lib/images/cursors/invalid32x32.gif": {"downloads": {"raw": {"sha1": "259edc45b4569427e8319895a444f4295d54348f", "size": 153, "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/cursors/motif_CopyDrop32x32.gif": {"downloads": {"raw": {"sha1": "eb7620fae702172aa663a19d170a0b929d3b11d1", "size": 158, "url": "https://launcher.mojang.com/v1/objects/eb7620fae702172aa663a19d170a0b929d3b11d1/motif_CopyDrop32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/cursors/motif_CopyNoDrop32x32.gif": {"downloads": {"raw": {"sha1": "259edc45b4569427e8319895a444f4295d54348f", "size": 153, "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/cursors/motif_LinkDrop32x32.gif": {"downloads": {"raw": {"sha1": "9699137f990c240e714481563181069c8f6c17bb", "size": 162, "url": "https://launcher.mojang.com/v1/objects/9699137f990c240e714481563181069c8f6c17bb/motif_LinkDrop32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/cursors/motif_LinkNoDrop32x32.gif": {"downloads": {"raw": {"sha1": "259edc45b4569427e8319895a444f4295d54348f", "size": 153, "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/cursors/motif_MoveDrop32x32.gif": {"downloads": {"raw": {"sha1": "03c1617ce3c5ab8af03e46d30a8c8f31ab57fb1b", "size": 141, "url": "https://launcher.mojang.com/v1/objects/03c1617ce3c5ab8af03e46d30a8c8f31ab57fb1b/motif_MoveDrop32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/cursors/motif_MoveNoDrop32x32.gif": {"downloads": {"raw": {"sha1": "259edc45b4569427e8319895a444f4295d54348f", "size": 153, "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif"}}, "executable": false, "type": "file"}, "lib/images/icons": {"type": "directory"}, "lib/images/icons/sun-java.png": {"downloads": {"raw": {"sha1": "d101b693aa054f51097eebdfeed8b8a6ca7b55b8", "size": 4707, "url": "https://launcher.mojang.com/v1/objects/d101b693aa054f51097eebdfeed8b8a6ca7b55b8/sun-java.png"}}, "executable": false, "type": "file"}, "lib/images/icons/sun-java_HighContrast.png": {"downloads": {"raw": {"sha1": "a6b1e418d6b5d03719b96f61f0c5236a60970151", "size": 3729, "url": "https://launcher.mojang.com/v1/objects/a6b1e418d6b5d03719b96f61f0c5236a60970151/sun-java_HighContrast.png"}}, "executable": false, "type": "file"}, "lib/images/icons/sun-java_HighContrastInverse.png": {"downloads": {"raw": {"sha1": "2dda28b9bddc9b5b018e3e8a8b062a99d9b2f887", "size": 3777, "url": "https://launcher.mojang.com/v1/objects/2dda28b9bddc9b5b018e3e8a8b062a99d9b2f887/sun-java_HighContrastInverse.png"}}, "executable": false, "type": "file"}, "lib/images/icons/sun-java_LowContrast.png": {"downloads": {"raw": {"sha1": "7714cc4e894c3626c8da6fe742ed22b2829122d9", "size": 4012, "url": "https://launcher.mojang.com/v1/objects/7714cc4e894c3626c8da6fe742ed22b2829122d9/sun-java_LowContrast.png"}}, "executable": false, "type": "file"}, "lib/javafx.properties": {"downloads": {"raw": {"sha1": "49e6b75d109e5fd3f6cbe7cc5fa9a7980796d14d", "size": 56, "url": "https://launcher.mojang.com/v1/objects/49e6b75d109e5fd3f6cbe7cc5fa9a7980796d14d/javafx.properties"}}, "executable": false, "type": "file"}, "lib/javaws.jar": {"downloads": {"raw": {"sha1": "04fa5ae04ead65b91be5dee575497e49ffd49fe9", "size": 488118, "url": "https://launcher.mojang.com/v1/objects/04fa5ae04ead65b91be5dee575497e49ffd49fe9/javaws.jar"}}, "executable": false, "type": "file"}, "lib/jce.jar": {"downloads": {"raw": {"sha1": "5460adee09cc5fc8829c0acfc46c34670a7d70a0", "size": 115646, "url": "https://launcher.mojang.com/v1/objects/5460adee09cc5fc8829c0acfc46c34670a7d70a0/jce.jar"}}, "executable": false, "type": "file"}, "lib/jexec": {"downloads": {"lzma": {"sha1": "2d4323d4e060f8126d026ca6c03b8972aedd2fab", "size": 3311, "url": "https://launcher.mojang.com/v1/objects/2d4323d4e060f8126d026ca6c03b8972aedd2fab/jexec"}, "raw": {"sha1": "6aa01f1d8d103974164bcfaea03c04eeeefd7d41", "size": 13376, "url": "https://launcher.mojang.com/v1/objects/6aa01f1d8d103974164bcfaea03c04eeeefd7d41/jexec"}}, "executable": true, "type": "file"}, "lib/jfr": {"type": "directory"}, "lib/jfr.jar": {"downloads": {"lzma": {"sha1": "5b9d615c91c72f4fe356d9b4105946679452d1e1", "size": 137982, "url": "https://launcher.mojang.com/v1/objects/5b9d615c91c72f4fe356d9b4105946679452d1e1/jfr.jar"}, "raw": {"sha1": "0f3fd66a336703d935bdc22ad8082bc51d34e534", "size": 560713, "url": "https://launcher.mojang.com/v1/objects/0f3fd66a336703d935bdc22ad8082bc51d34e534/jfr.jar"}}, "executable": false, "type": "file"}, "lib/jfr/default.jfc": {"downloads": {"lzma": {"sha1": "373ddd878146dd8ce8991c2c5115a05a82859bdb", "size": 2207, "url": "https://launcher.mojang.com/v1/objects/373ddd878146dd8ce8991c2c5115a05a82859bdb/default.jfc"}, "raw": {"sha1": "1a64b68d0e7d43f8149faba94440be54f4f24527", "size": 20109, "url": "https://launcher.mojang.com/v1/objects/1a64b68d0e7d43f8149faba94440be54f4f24527/default.jfc"}}, "executable": false, "type": "file"}, "lib/jfr/profile.jfc": {"downloads": {"lzma": {"sha1": "3dcdc5feee3ccfb66bc8726b666944cd4bdadae3", "size": 2199, "url": "https://launcher.mojang.com/v1/objects/3dcdc5feee3ccfb66bc8726b666944cd4bdadae3/profile.jfc"}, "raw": {"sha1": "5d7d08a595f76322c51ae43ea966fbba6b69eebe", "size": 20065, "url": "https://launcher.mojang.com/v1/objects/5d7d08a595f76322c51ae43ea966fbba6b69eebe/profile.jfc"}}, "executable": false, "type": "file"}, "lib/jfxswt.jar": {"downloads": {"raw": {"sha1": "99d9a264c898d84c01e1c42565e7fe1a89dcd72d", "size": 33932, "url": "https://launcher.mojang.com/v1/objects/99d9a264c898d84c01e1c42565e7fe1a89dcd72d/jfxswt.jar"}}, "executable": false, "type": "file"}, "lib/jsse.jar": {"downloads": {"lzma": {"sha1": "94a17dfbc2e76cd12c33970a15341424f875a9ce", "size": 187549, "url": "https://launcher.mojang.com/v1/objects/94a17dfbc2e76cd12c33970a15341424f875a9ce/jsse.jar"}, "raw": {"sha1": "92c5c626e8a2d16f41272c0e404d4f992dd8310a", "size": 675599, "url": "https://launcher.mojang.com/v1/objects/92c5c626e8a2d16f41272c0e404d4f992dd8310a/jsse.jar"}}, "executable": false, "type": "file"}, "lib/jvm.hprof.txt": {"downloads": {"lzma": {"sha1": "eccdb240a815b2a83a502749339b27bb8669965b", "size": 1863, "url": "https://launcher.mojang.com/v1/objects/eccdb240a815b2a83a502749339b27bb8669965b/jvm.hprof.txt"}, "raw": {"sha1": "fbd61d52534cdd0c15df332114d469c65d001e33", "size": 4226, "url": "https://launcher.mojang.com/v1/objects/fbd61d52534cdd0c15df332114d469c65d001e33/jvm.hprof.txt"}}, "executable": false, "type": "file"}, "lib/locale": {"type": "directory"}, "lib/locale/de": {"type": "directory"}, "lib/locale/de/LC_MESSAGES": {"type": "directory"}, "lib/locale/de/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "3061d922907cc557208109088fc6ab81d577ff6f", "size": 970, "url": "https://launcher.mojang.com/v1/objects/3061d922907cc557208109088fc6ab81d577ff6f/sunw_java_plugin.mo"}, "raw": {"sha1": "5b223a3d723ac1cfce63623fb109f2868d47d1b7", "size": 2483, "url": "https://launcher.mojang.com/v1/objects/5b223a3d723ac1cfce63623fb109f2868d47d1b7/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/es": {"type": "directory"}, "lib/locale/es/LC_MESSAGES": {"type": "directory"}, "lib/locale/es/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "24338049a89b323e17182b3a3006b50565d4fa0f", "size": 979, "url": "https://launcher.mojang.com/v1/objects/24338049a89b323e17182b3a3006b50565d4fa0f/sunw_java_plugin.mo"}, "raw": {"sha1": "6cc63dc97f2fdb2ed799e48b1dc98c4f37cdecc1", "size": 2477, "url": "https://launcher.mojang.com/v1/objects/6cc63dc97f2fdb2ed799e48b1dc98c4f37cdecc1/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/fr": {"type": "directory"}, "lib/locale/fr/LC_MESSAGES": {"type": "directory"}, "lib/locale/fr/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "22796a48ef39f57d2d6fa70f41308e493d7f05c1", "size": 1033, "url": "https://launcher.mojang.com/v1/objects/22796a48ef39f57d2d6fa70f41308e493d7f05c1/sunw_java_plugin.mo"}, "raw": {"sha1": "d9d5b458db6e83fdf85c3526aeee3f57c4929840", "size": 2746, "url": "https://launcher.mojang.com/v1/objects/d9d5b458db6e83fdf85c3526aeee3f57c4929840/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/it": {"type": "directory"}, "lib/locale/it/LC_MESSAGES": {"type": "directory"}, "lib/locale/it/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "59a4cae38bfb8927745674d0efc2f284bc277987", "size": 958, "url": "https://launcher.mojang.com/v1/objects/59a4cae38bfb8927745674d0efc2f284bc277987/sunw_java_plugin.mo"}, "raw": {"sha1": "f6e72e3b2141ccc3dffab10ae14a754e494577ba", "size": 2434, "url": "https://launcher.mojang.com/v1/objects/f6e72e3b2141ccc3dffab10ae14a754e494577ba/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/ja": {"type": "directory"}, "lib/locale/ja/LC_MESSAGES": {"type": "directory"}, "lib/locale/ja/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "7d6aeed563e1cefcf0224cf522048468088884a9", "size": 1036, "url": "https://launcher.mojang.com/v1/objects/7d6aeed563e1cefcf0224cf522048468088884a9/sunw_java_plugin.mo"}, "raw": {"sha1": "378881a8cb8dd2aebb43eacd0c68519be4f258b1", "size": 2415, "url": "https://launcher.mojang.com/v1/objects/378881a8cb8dd2aebb43eacd0c68519be4f258b1/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/ko": {"type": "directory"}, "lib/locale/ko.UTF-8": {"type": "directory"}, "lib/locale/ko.UTF-8/LC_MESSAGES": {"type": "directory"}, "lib/locale/ko.UTF-8/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "12ee3b21511e8497d95ea0ba9d6fe519227d0b16", "size": 1069, "url": "https://launcher.mojang.com/v1/objects/12ee3b21511e8497d95ea0ba9d6fe519227d0b16/sunw_java_plugin.mo"}, "raw": {"sha1": "cb19df01c59662dbe2f4050b1290d374b82fe1fa", "size": 2753, "url": "https://launcher.mojang.com/v1/objects/cb19df01c59662dbe2f4050b1290d374b82fe1fa/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/ko/LC_MESSAGES": {"type": "directory"}, "lib/locale/ko/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "6e2e47c64c360517fd436bc79c823b5679a1efe6", "size": 996, "url": "https://launcher.mojang.com/v1/objects/6e2e47c64c360517fd436bc79c823b5679a1efe6/sunw_java_plugin.mo"}, "raw": {"sha1": "12c8a118d150c78f719314df6dec49a967af71e9", "size": 2399, "url": "https://launcher.mojang.com/v1/objects/12c8a118d150c78f719314df6dec49a967af71e9/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/pt_BR": {"type": "directory"}, "lib/locale/pt_BR/LC_MESSAGES": {"type": "directory"}, "lib/locale/pt_BR/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "bcaa7e7916493f071f1bf64bf58c6b038e3569c9", "size": 940, "url": "https://launcher.mojang.com/v1/objects/bcaa7e7916493f071f1bf64bf58c6b038e3569c9/sunw_java_plugin.mo"}, "raw": {"sha1": "a3bc0c43994c53c59bba94982cf95f6d36283dd0", "size": 2420, "url": "https://launcher.mojang.com/v1/objects/a3bc0c43994c53c59bba94982cf95f6d36283dd0/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/sv": {"type": "directory"}, "lib/locale/sv/LC_MESSAGES": {"type": "directory"}, "lib/locale/sv/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "76017835d6261fe2eedbcbe5eb08a7484c3080c5", "size": 946, "url": "https://launcher.mojang.com/v1/objects/76017835d6261fe2eedbcbe5eb08a7484c3080c5/sunw_java_plugin.mo"}, "raw": {"sha1": "09a47686edec4bbb34e82fbd08559f8bb6266544", "size": 2359, "url": "https://launcher.mojang.com/v1/objects/09a47686edec4bbb34e82fbd08559f8bb6266544/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/zh": {"type": "directory"}, "lib/locale/zh.GBK": {"type": "directory"}, "lib/locale/zh.GBK/LC_MESSAGES": {"type": "directory"}, "lib/locale/zh.GBK/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "75fd04045bf5890b8bb822770bfdb90a2e9ea65b", "size": 902, "url": "https://launcher.mojang.com/v1/objects/75fd04045bf5890b8bb822770bfdb90a2e9ea65b/sunw_java_plugin.mo"}, "raw": {"sha1": "7006fe7767b8807441a1f359a90509b3e507b0d1", "size": 2002, "url": "https://launcher.mojang.com/v1/objects/7006fe7767b8807441a1f359a90509b3e507b0d1/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/zh/LC_MESSAGES": {"type": "directory"}, "lib/locale/zh/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "75fd04045bf5890b8bb822770bfdb90a2e9ea65b", "size": 902, "url": "https://launcher.mojang.com/v1/objects/75fd04045bf5890b8bb822770bfdb90a2e9ea65b/sunw_java_plugin.mo"}, "raw": {"sha1": "7006fe7767b8807441a1f359a90509b3e507b0d1", "size": 2002, "url": "https://launcher.mojang.com/v1/objects/7006fe7767b8807441a1f359a90509b3e507b0d1/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/zh_HK.BIG5HK": {"type": "directory"}, "lib/locale/zh_HK.BIG5HK/LC_MESSAGES": {"type": "directory"}, "lib/locale/zh_HK.BIG5HK/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "3a1397bb1b1741697be1479232b6d9599940c851", "size": 912, "url": "https://launcher.mojang.com/v1/objects/3a1397bb1b1741697be1479232b6d9599940c851/sunw_java_plugin.mo"}, "raw": {"sha1": "c6023544067278c78599921f1032de353ff7da42", "size": 2025, "url": "https://launcher.mojang.com/v1/objects/c6023544067278c78599921f1032de353ff7da42/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/zh_TW": {"type": "directory"}, "lib/locale/zh_TW.BIG5": {"type": "directory"}, "lib/locale/zh_TW.BIG5/LC_MESSAGES": {"type": "directory"}, "lib/locale/zh_TW.BIG5/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "3a1397bb1b1741697be1479232b6d9599940c851", "size": 912, "url": "https://launcher.mojang.com/v1/objects/3a1397bb1b1741697be1479232b6d9599940c851/sunw_java_plugin.mo"}, "raw": {"sha1": "c6023544067278c78599921f1032de353ff7da42", "size": 2025, "url": "https://launcher.mojang.com/v1/objects/c6023544067278c78599921f1032de353ff7da42/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/locale/zh_TW/LC_MESSAGES": {"type": "directory"}, "lib/locale/zh_TW/LC_MESSAGES/sunw_java_plugin.mo": {"downloads": {"lzma": {"sha1": "c05e610e75182f0c4e77f3e7a4d9670ed62bf63c", "size": 897, "url": "https://launcher.mojang.com/v1/objects/c05e610e75182f0c4e77f3e7a4d9670ed62bf63c/sunw_java_plugin.mo"}, "raw": {"sha1": "f9b972dd059eae3cd337dfcef6a178e8ed8a7db6", "size": 2025, "url": "https://launcher.mojang.com/v1/objects/f9b972dd059eae3cd337dfcef6a178e8ed8a7db6/sunw_java_plugin.mo"}}, "executable": false, "type": "file"}, "lib/logging.properties": {"downloads": {"lzma": {"sha1": "642202a58e5216d086ad37c0b5a633be802edc78", "size": 896, "url": "https://launcher.mojang.com/v1/objects/642202a58e5216d086ad37c0b5a633be802edc78/logging.properties"}, "raw": {"sha1": "89da8094484891f9ec1fa40c6c8b61f94c5869d0", "size": 2455, "url": "https://launcher.mojang.com/v1/objects/89da8094484891f9ec1fa40c6c8b61f94c5869d0/logging.properties"}}, "executable": false, "type": "file"}, "lib/management": {"type": "directory"}, "lib/management-agent.jar": {"downloads": {"lzma": {"sha1": "3ea0bf17e14b3428296a0f4011bf4025fcbfa4bd", "size": 243, "url": "https://launcher.mojang.com/v1/objects/3ea0bf17e14b3428296a0f4011bf4025fcbfa4bd/management-agent.jar"}, "raw": {"sha1": "9fbed36522aa3a80bac08a328942cbc5ef39ca8e", "size": 381, "url": "https://launcher.mojang.com/v1/objects/9fbed36522aa3a80bac08a328942cbc5ef39ca8e/management-agent.jar"}}, "executable": false, "type": "file"}, "lib/management/jmxremote.access": {"downloads": {"lzma": {"sha1": "69042ff1b14165db19c9d728614639dec16d6a31", "size": 1419, "url": "https://launcher.mojang.com/v1/objects/69042ff1b14165db19c9d728614639dec16d6a31/jmxremote.access"}, "raw": {"sha1": "21200eaad898ba4a2a8834a032efb6616fabb930", "size": 3998, "url": "https://launcher.mojang.com/v1/objects/21200eaad898ba4a2a8834a032efb6616fabb930/jmxremote.access"}}, "executable": false, "type": "file"}, "lib/management/jmxremote.password.template": {"downloads": {"lzma": {"sha1": "556c64b1e920766f8867be3964de6e49f5b81a60", "size": 1129, "url": "https://launcher.mojang.com/v1/objects/556c64b1e920766f8867be3964de6e49f5b81a60/jmxremote.password.template"}, "raw": {"sha1": "c1e0f01408bf20fbbb8b4810520c725f70050db5", "size": 2856, "url": "https://launcher.mojang.com/v1/objects/c1e0f01408bf20fbbb8b4810520c725f70050db5/jmxremote.password.template"}}, "executable": false, "type": "file"}, "lib/management/management.properties": {"downloads": {"lzma": {"sha1": "3e52f9baa6394ca6956845424c607e5cde5d3c67", "size": 3176, "url": "https://launcher.mojang.com/v1/objects/3e52f9baa6394ca6956845424c607e5cde5d3c67/management.properties"}, "raw": {"sha1": "e0451d8d7d9e84d7b1c39ec7d00993307a5cbbf1", "size": 14630, "url": "https://launcher.mojang.com/v1/objects/e0451d8d7d9e84d7b1c39ec7d00993307a5cbbf1/management.properties"}}, "executable": false, "type": "file"}, "lib/management/snmp.acl.template": {"downloads": {"lzma": {"sha1": "9a4aa6396c3b488b0663bed5e5ecb762985669c9", "size": 1121, "url": "https://launcher.mojang.com/v1/objects/9a4aa6396c3b488b0663bed5e5ecb762985669c9/snmp.acl.template"}, "raw": {"sha1": "2e9f9ac287274532eb1f0d1afcefd7f3e97cc794", "size": 3376, "url": "https://launcher.mojang.com/v1/objects/2e9f9ac287274532eb1f0d1afcefd7f3e97cc794/snmp.acl.template"}}, "executable": false, "type": "file"}, "lib/meta-index": {"downloads": {"lzma": {"sha1": "1ac60b31362fda4725c665b591c5fbe384cbc8c1", "size": 788, "url": "https://launcher.mojang.com/v1/objects/1ac60b31362fda4725c665b591c5fbe384cbc8c1/meta-index"}, "raw": {"sha1": "bf204f09242203e713c31785158a0792f9edb600", "size": 2034, "url": "https://launcher.mojang.com/v1/objects/bf204f09242203e713c31785158a0792f9edb600/meta-index"}}, "executable": false, "type": "file"}, "lib/net.properties": {"downloads": {"lzma": {"sha1": "e9ec3981a0797bf55bb87b24d9eb651ce7e6916b", "size": 1830, "url": "https://launcher.mojang.com/v1/objects/e9ec3981a0797bf55bb87b24d9eb651ce7e6916b/net.properties"}, "raw": {"sha1": "fd9471742eb759f4478bb1de9a0dc0527265b6ea", "size": 5352, "url": "https://launcher.mojang.com/v1/objects/fd9471742eb759f4478bb1de9a0dc0527265b6ea/net.properties"}}, "executable": false, "type": "file"}, "lib/oblique-fonts": {"type": "directory"}, "lib/oblique-fonts/LucidaSansDemiOblique.ttf": {"downloads": {"lzma": {"sha1": "49c8980c1b89bbdbab59d0f5bd5bebf0afcb93b2", "size": 38580, "url": "https://launcher.mojang.com/v1/objects/49c8980c1b89bbdbab59d0f5bd5bebf0afcb93b2/LucidaSansDemiOblique.ttf"}, "raw": {"sha1": "53e4e12a675ac222469341c3dbc102464a1be4c7", "size": 91352, "url": "https://launcher.mojang.com/v1/objects/53e4e12a675ac222469341c3dbc102464a1be4c7/LucidaSansDemiOblique.ttf"}}, "executable": false, "type": "file"}, "lib/oblique-fonts/LucidaSansOblique.ttf": {"downloads": {"lzma": {"sha1": "553123c0edcd08035dede4ffd92b5b81c9a7538a", "size": 116575, "url": "https://launcher.mojang.com/v1/objects/553123c0edcd08035dede4ffd92b5b81c9a7538a/LucidaSansOblique.ttf"}, "raw": {"sha1": "95a195ad4fc520b3e395c85b747fc3024d118dd9", "size": 253724, "url": "https://launcher.mojang.com/v1/objects/95a195ad4fc520b3e395c85b747fc3024d118dd9/LucidaSansOblique.ttf"}}, "executable": false, "type": "file"}, "lib/oblique-fonts/LucidaTypewriterBoldOblique.ttf": {"downloads": {"lzma": {"sha1": "2475b08151556ad4d89bb1d2b6494c6bee9abd82", "size": 29954, "url": "https://launcher.mojang.com/v1/objects/2475b08151556ad4d89bb1d2b6494c6bee9abd82/LucidaTypewriterBoldOblique.ttf"}, "raw": {"sha1": "f331fc8b0cc494702bc46b690f2b8eed36469a02", "size": 63168, "url": "https://launcher.mojang.com/v1/objects/f331fc8b0cc494702bc46b690f2b8eed36469a02/LucidaTypewriterBoldOblique.ttf"}}, "executable": false, "type": "file"}, "lib/oblique-fonts/LucidaTypewriterOblique.ttf": {"downloads": {"lzma": {"sha1": "5b970bc3b7abb21dce1aa28ff7f03459d351e552", "size": 60133, "url": "https://launcher.mojang.com/v1/objects/5b970bc3b7abb21dce1aa28ff7f03459d351e552/LucidaTypewriterOblique.ttf"}, "raw": {"sha1": "f8ea00db73f8a89a27674d050edc37c2280930e1", "size": 137484, "url": "https://launcher.mojang.com/v1/objects/f8ea00db73f8a89a27674d050edc37c2280930e1/LucidaTypewriterOblique.ttf"}}, "executable": false, "type": "file"}, "lib/oblique-fonts/fonts.dir": {"downloads": {"lzma": {"sha1": "067528c789bd713c7c3f34e779aa6e2e8253dcf6", "size": 188, "url": "https://launcher.mojang.com/v1/objects/067528c789bd713c7c3f34e779aa6e2e8253dcf6/fonts.dir"}, "raw": {"sha1": "5aee54ffba9e33de56fd84ef64fa496b898585bb", "size": 2115, "url": "https://launcher.mojang.com/v1/objects/5aee54ffba9e33de56fd84ef64fa496b898585bb/fonts.dir"}}, "executable": false, "type": "file"}, "lib/plugin.jar": {"downloads": {"raw": {"sha1": "3f250842c79112bae5369e372025b166990820e8", "size": 950772, "url": "https://launcher.mojang.com/v1/objects/3f250842c79112bae5369e372025b166990820e8/plugin.jar"}}, "executable": false, "type": "file"}, "lib/psfont.properties.ja": {"downloads": {"lzma": {"sha1": "7ca1cc244ed251cd1eb2347f1eea37d7d18c8ad4", "size": 701, "url": "https://launcher.mojang.com/v1/objects/7ca1cc244ed251cd1eb2347f1eea37d7d18c8ad4/psfont.properties.ja"}, "raw": {"sha1": "56ed1c661eeede17b4fae8c9de7b5edbad387abc", "size": 2796, "url": "https://launcher.mojang.com/v1/objects/56ed1c661eeede17b4fae8c9de7b5edbad387abc/psfont.properties.ja"}}, "executable": false, "type": "file"}, "lib/psfontj2d.properties": {"downloads": {"lzma": {"sha1": "4252fa01af8739a3545e2b705e3383892e22ab40", "size": 2278, "url": "https://launcher.mojang.com/v1/objects/4252fa01af8739a3545e2b705e3383892e22ab40/psfontj2d.properties"}, "raw": {"sha1": "aa327a22a49967f4d74afeee6726f505f209692f", "size": 10393, "url": "https://launcher.mojang.com/v1/objects/aa327a22a49967f4d74afeee6726f505f209692f/psfontj2d.properties"}}, "executable": false, "type": "file"}, "lib/resources.jar": {"downloads": {"lzma": {"sha1": "1b0e08441750dc17efe4b527aa146da6cc14e8a6", "size": 579294, "url": "https://launcher.mojang.com/v1/objects/1b0e08441750dc17efe4b527aa146da6cc14e8a6/resources.jar"}, "raw": {"sha1": "daa021906e4648d4c37e798c11733dc2047f2da1", "size": 3505206, "url": "https://launcher.mojang.com/v1/objects/daa021906e4648d4c37e798c11733dc2047f2da1/resources.jar"}}, "executable": false, "type": "file"}, "lib/rt.jar": {"downloads": {"lzma": {"sha1": "fc4a8681aeda29c2a2a3fd11bad7729543283f3d", "size": 14378994, "url": "https://launcher.mojang.com/v1/objects/fc4a8681aeda29c2a2a3fd11bad7729543283f3d/rt.jar"}, "raw": {"sha1": "5396b0954a20f3210f1f4f1886ead30880d6ebfe", "size": 66334986, "url": "https://launcher.mojang.com/v1/objects/5396b0954a20f3210f1f4f1886ead30880d6ebfe/rt.jar"}}, "executable": false, "type": "file"}, "lib/security": {"type": "directory"}, "lib/security/blacklist": {"downloads": {"lzma": {"sha1": "8206fce6c1d91a39fdf78e8e79e953913994a1cd", "size": 1969, "url": "https://launcher.mojang.com/v1/objects/8206fce6c1d91a39fdf78e8e79e953913994a1cd/blacklist"}, "raw": {"sha1": "d4ffb3857eab403955ce9d156e46d056061e6a5a", "size": 4054, "url": "https://launcher.mojang.com/v1/objects/d4ffb3857eab403955ce9d156e46d056061e6a5a/blacklist"}}, "executable": false, "type": "file"}, "lib/security/blacklisted.certs": {"downloads": {"lzma": {"sha1": "8311bead054caf6cfe678d4b7998de4caaabfa53", "size": 806, "url": "https://launcher.mojang.com/v1/objects/8311bead054caf6cfe678d4b7998de4caaabfa53/blacklisted.certs"}, "raw": {"sha1": "c5c005c29a80493f5c31cd7eb629ac1b9c752404", "size": 1273, "url": "https://launcher.mojang.com/v1/objects/c5c005c29a80493f5c31cd7eb629ac1b9c752404/blacklisted.certs"}}, "executable": false, "type": "file"}, "lib/security/cacerts": {"downloads": {"lzma": {"sha1": "654dd94809655d5b28385cbb5eba8d6ad9f2c1aa", "size": 67802, "url": "https://launcher.mojang.com/v1/objects/654dd94809655d5b28385cbb5eba8d6ad9f2c1aa/cacerts"}, "raw": {"sha1": "2917859c443c68e19f93abcd1315c3c2904cbef9", "size": 104430, "url": "https://launcher.mojang.com/v1/objects/2917859c443c68e19f93abcd1315c3c2904cbef9/cacerts"}}, "executable": false, "type": "file"}, "lib/security/java.policy": {"downloads": {"lzma": {"sha1": "b601c420d02ef3dbd8595453d08fdef91134e8b5", "size": 647, "url": "https://launcher.mojang.com/v1/objects/b601c420d02ef3dbd8595453d08fdef91134e8b5/java.policy"}, "raw": {"sha1": "c0112209a567b3b523cfed7041709f9440227968", "size": 2466, "url": "https://launcher.mojang.com/v1/objects/c0112209a567b3b523cfed7041709f9440227968/java.policy"}}, "executable": false, "type": "file"}, "lib/security/java.security": {"downloads": {"lzma": {"sha1": "531620e82ca0365ce8dc97096bb0ac5a7ace5952", "size": 10959, "url": "https://launcher.mojang.com/v1/objects/531620e82ca0365ce8dc97096bb0ac5a7ace5952/java.security"}, "raw": {"sha1": "5dcc17a168c53d0b366784e520bd4d55aa61ac18", "size": 41528, "url": "https://launcher.mojang.com/v1/objects/5dcc17a168c53d0b366784e520bd4d55aa61ac18/java.security"}}, "executable": false, "type": "file"}, "lib/security/javaws.policy": {"downloads": {"raw": {"sha1": "4384ca5e4d32f7dd86d8baddd1e690730d74e694", "size": 98, "url": "https://launcher.mojang.com/v1/objects/4384ca5e4d32f7dd86d8baddd1e690730d74e694/javaws.policy"}}, "executable": false, "type": "file"}, "lib/security/policy": {"type": "directory"}, "lib/security/policy/limited": {"type": "directory"}, "lib/security/policy/limited/US_export_policy.jar": {"downloads": {"raw": {"sha1": "7d69ea3b385bc067738520f1b5c549e1084be285", "size": 3026, "url": "https://launcher.mojang.com/v1/objects/7d69ea3b385bc067738520f1b5c549e1084be285/US_export_policy.jar"}}, "executable": false, "type": "file"}, "lib/security/policy/limited/local_policy.jar": {"downloads": {"raw": {"sha1": "238b8826e110f58acb2e1959773b0a577cd4d569", "size": 3527, "url": "https://launcher.mojang.com/v1/objects/238b8826e110f58acb2e1959773b0a577cd4d569/local_policy.jar"}}, "executable": false, "type": "file"}, "lib/security/policy/unlimited": {"type": "directory"}, "lib/security/policy/unlimited/US_export_policy.jar": {"downloads": {"raw": {"sha1": "f6fb2af1e87fc622cda194a7d6b5f5f069653ff1", "size": 3023, "url": "https://launcher.mojang.com/v1/objects/f6fb2af1e87fc622cda194a7d6b5f5f069653ff1/US_export_policy.jar"}}, "executable": false, "type": "file"}, "lib/security/policy/unlimited/local_policy.jar": {"downloads": {"raw": {"sha1": "517368ab2cbaf6b42ea0b963f98eeedd996e83e3", "size": 3035, "url": "https://launcher.mojang.com/v1/objects/517368ab2cbaf6b42ea0b963f98eeedd996e83e3/local_policy.jar"}}, "executable": false, "type": "file"}, "lib/security/trusted.libraries": {"downloads": {"raw": {"sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "size": 0, "url": "https://launcher.mojang.com/v1/objects/da39a3ee5e6b4b0d3255bfef95601890afd80709/trusted.libraries"}}, "executable": false, "type": "file"}, "lib/sound.properties": {"downloads": {"lzma": {"sha1": "3b5f7e4ec437d79048af35094290577f483b3fe1", "size": 473, "url": "https://launcher.mojang.com/v1/objects/3b5f7e4ec437d79048af35094290577f483b3fe1/sound.properties"}, "raw": {"sha1": "9afceb218059d981d0fa9f07aad3c5097cf41b0c", "size": 1210, "url": "https://launcher.mojang.com/v1/objects/9afceb218059d981d0fa9f07aad3c5097cf41b0c/sound.properties"}}, "executable": false, "type": "file"}, "lib/tzdb.dat": {"downloads": {"lzma": {"sha1": "39c69339965484afe89c14111baeeb862fdefd97", "size": 32547, "url": "https://launcher.mojang.com/v1/objects/39c69339965484afe89c14111baeeb862fdefd97/tzdb.dat"}, "raw": {"sha1": "b59c07e3619271a3b9861e999f4b138e971baf69", "size": 105734, "url": "https://launcher.mojang.com/v1/objects/b59c07e3619271a3b9861e999f4b138e971baf69/tzdb.dat"}}, "executable": false, "type": "file"}, "man": {"type": "directory"}, "man/ja": {"target": "ja_JP.UTF-8", "type": "link"}, "man/ja_JP.UTF-8": {"type": "directory"}, "man/ja_JP.UTF-8/man1": {"type": "directory"}, "man/ja_JP.UTF-8/man1/java.1": {"downloads": {"lzma": {"sha1": "f9da09710b6c6df23c256e324a0c4df00a0d6ded", "size": 25461, "url": "https://launcher.mojang.com/v1/objects/f9da09710b6c6df23c256e324a0c4df00a0d6ded/java.1"}, "raw": {"sha1": "b0b12a0bb66e6171771ca4b1dfca32fb759bcaec", "size": 148688, "url": "https://launcher.mojang.com/v1/objects/b0b12a0bb66e6171771ca4b1dfca32fb759bcaec/java.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/javaws.1": {"downloads": {"lzma": {"sha1": "6188fae453ca09ccb19be5c9f4d2059926b36267", "size": 2154, "url": "https://launcher.mojang.com/v1/objects/6188fae453ca09ccb19be5c9f4d2059926b36267/javaws.1"}, "raw": {"sha1": "8f39d928870268ace07bedfebd18db1e1d07fc37", "size": 6641, "url": "https://launcher.mojang.com/v1/objects/8f39d928870268ace07bedfebd18db1e1d07fc37/javaws.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/jjs.1": {"downloads": {"lzma": {"sha1": "6e42b989d28b185dc1aab50c0389834e649a37d4", "size": 3452, "url": "https://launcher.mojang.com/v1/objects/6e42b989d28b185dc1aab50c0389834e649a37d4/jjs.1"}, "raw": {"sha1": "e023322a2013912315a2bd1034e6f829a27c76e0", "size": 11365, "url": "https://launcher.mojang.com/v1/objects/e023322a2013912315a2bd1034e6f829a27c76e0/jjs.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/keytool.1": {"downloads": {"lzma": {"sha1": "a78134a4bddd53d684a70aa677e51a215db1c9cb", "size": 20698, "url": "https://launcher.mojang.com/v1/objects/a78134a4bddd53d684a70aa677e51a215db1c9cb/keytool.1"}, "raw": {"sha1": "148583c837eaaf6333ccfd8c9e8df08574e14b0c", "size": 111033, "url": "https://launcher.mojang.com/v1/objects/148583c837eaaf6333ccfd8c9e8df08574e14b0c/keytool.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/orbd.1": {"downloads": {"lzma": {"sha1": "326af0dcbff173ef8aee29163dbe146d7389cc3e", "size": 4225, "url": "https://launcher.mojang.com/v1/objects/326af0dcbff173ef8aee29163dbe146d7389cc3e/orbd.1"}, "raw": {"sha1": "95651622d33c08286858ec337edd3ea72acd93dc", "size": 16092, "url": "https://launcher.mojang.com/v1/objects/95651622d33c08286858ec337edd3ea72acd93dc/orbd.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/pack200.1": {"downloads": {"lzma": {"sha1": "e0eedafa748c61a44e5be4355fe9d44b05048e80", "size": 4293, "url": "https://launcher.mojang.com/v1/objects/e0eedafa748c61a44e5be4355fe9d44b05048e80/pack200.1"}, "raw": {"sha1": "aa21a0ab75707f7fc66e83c7a392e69b37ddf80e", "size": 14482, "url": "https://launcher.mojang.com/v1/objects/aa21a0ab75707f7fc66e83c7a392e69b37ddf80e/pack200.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/policytool.1": {"downloads": {"lzma": {"sha1": "3c766ed12dab58166169d35680c392a6be1814a1", "size": 1380, "url": "https://launcher.mojang.com/v1/objects/3c766ed12dab58166169d35680c392a6be1814a1/policytool.1"}, "raw": {"sha1": "80879c74e072a98fad6f32b3283331aaf9bd002f", "size": 4020, "url": "https://launcher.mojang.com/v1/objects/80879c74e072a98fad6f32b3283331aaf9bd002f/policytool.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/rmid.1": {"downloads": {"lzma": {"sha1": "1e20779d990beacc32a48237777d670fcc47ca14", "size": 4836, "url": "https://launcher.mojang.com/v1/objects/1e20779d990beacc32a48237777d670fcc47ca14/rmid.1"}, "raw": {"sha1": "7e40cb8003d098d6e36f45640b26f979ac94b5c5", "size": 19715, "url": "https://launcher.mojang.com/v1/objects/7e40cb8003d098d6e36f45640b26f979ac94b5c5/rmid.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/rmiregistry.1": {"downloads": {"lzma": {"sha1": "aaf4ffe07e954f8696eef1ecb7a5e244628d0ad9", "size": 1627, "url": "https://launcher.mojang.com/v1/objects/aaf4ffe07e954f8696eef1ecb7a5e244628d0ad9/rmiregistry.1"}, "raw": {"sha1": "c53c52f3ae7a011c135894c9fc51b741e729c33d", "size": 4557, "url": "https://launcher.mojang.com/v1/objects/c53c52f3ae7a011c135894c9fc51b741e729c33d/rmiregistry.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/servertool.1": {"downloads": {"lzma": {"sha1": "3b9e624e9d1cf2959b438a35061162e2100ddecd", "size": 2626, "url": "https://launcher.mojang.com/v1/objects/3b9e624e9d1cf2959b438a35061162e2100ddecd/servertool.1"}, "raw": {"sha1": "50ab8bcd9dd9d0b1a3d81348fbce1c8f82e7189e", "size": 9081, "url": "https://launcher.mojang.com/v1/objects/50ab8bcd9dd9d0b1a3d81348fbce1c8f82e7189e/servertool.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/tnameserv.1": {"downloads": {"lzma": {"sha1": "bb3106ff74c60a76de3d20659b9c2128c70f3bf2", "size": 4478, "url": "https://launcher.mojang.com/v1/objects/bb3106ff74c60a76de3d20659b9c2128c70f3bf2/tnameserv.1"}, "raw": {"sha1": "01e714671ecd1167edcb5310b16a9c59c33c3eaa", "size": 17722, "url": "https://launcher.mojang.com/v1/objects/01e714671ecd1167edcb5310b16a9c59c33c3eaa/tnameserv.1"}}, "executable": false, "type": "file"}, "man/ja_JP.UTF-8/man1/unpack200.1": {"downloads": {"lzma": {"sha1": "c115a881cf800b08df294df55d9f250ae944e33c", "size": 1973, "url": "https://launcher.mojang.com/v1/objects/c115a881cf800b08df294df55d9f250ae944e33c/unpack200.1"}, "raw": {"sha1": "7c882bba0067367a41ad84868d18793b8a7397a3", "size": 5382, "url": "https://launcher.mojang.com/v1/objects/7c882bba0067367a41ad84868d18793b8a7397a3/unpack200.1"}}, "executable": false, "type": "file"}, "man/man1": {"type": "directory"}, "man/man1/java.1": {"downloads": {"lzma": {"sha1": "06a6b0275c202bf698d73ca71f95618d56d81c15", "size": 25796, "url": "https://launcher.mojang.com/v1/objects/06a6b0275c202bf698d73ca71f95618d56d81c15/java.1"}, "raw": {"sha1": "69fec7a341aa91f18dbdcdb95952dede7e1b689a", "size": 124796, "url": "https://launcher.mojang.com/v1/objects/69fec7a341aa91f18dbdcdb95952dede7e1b689a/java.1"}}, "executable": false, "type": "file"}, "man/man1/javaws.1": {"downloads": {"lzma": {"sha1": "4bae251c6dfb5420f56928815cf80d0b6d517a1f", "size": 1759, "url": "https://launcher.mojang.com/v1/objects/4bae251c6dfb5420f56928815cf80d0b6d517a1f/javaws.1"}, "raw": {"sha1": "e61e44e101b1bc119c2d2d4b10320f38b36a8036", "size": 4897, "url": "https://launcher.mojang.com/v1/objects/e61e44e101b1bc119c2d2d4b10320f38b36a8036/javaws.1"}}, "executable": false, "type": "file"}, "man/man1/jjs.1": {"downloads": {"lzma": {"sha1": "29683cf2bd47015c9461b688749ddffd95f6671d", "size": 1881, "url": "https://launcher.mojang.com/v1/objects/29683cf2bd47015c9461b688749ddffd95f6671d/jjs.1"}, "raw": {"sha1": "78d419bd3a7f3e0802d5220e690429194b5d1beb", "size": 4932, "url": "https://launcher.mojang.com/v1/objects/78d419bd3a7f3e0802d5220e690429194b5d1beb/jjs.1"}}, "executable": false, "type": "file"}, "man/man1/keytool.1": {"downloads": {"lzma": {"sha1": "b67e5126d43713ee3675706724b34061578b42db", "size": 19690, "url": "https://launcher.mojang.com/v1/objects/b67e5126d43713ee3675706724b34061578b42db/keytool.1"}, "raw": {"sha1": "4c976f86057ab779763fcfb98f5702ebef47f629", "size": 86925, "url": "https://launcher.mojang.com/v1/objects/4c976f86057ab779763fcfb98f5702ebef47f629/keytool.1"}}, "executable": false, "type": "file"}, "man/man1/orbd.1": {"downloads": {"lzma": {"sha1": "147064d6f7e027002e296bb246ae572d0ce0495b", "size": 3708, "url": "https://launcher.mojang.com/v1/objects/147064d6f7e027002e296bb246ae572d0ce0495b/orbd.1"}, "raw": {"sha1": "64201e1846fcf1dcc45c786ffeab89426d1c7742", "size": 12180, "url": "https://launcher.mojang.com/v1/objects/64201e1846fcf1dcc45c786ffeab89426d1c7742/orbd.1"}}, "executable": false, "type": "file"}, "man/man1/pack200.1": {"downloads": {"lzma": {"sha1": "fe17486bbe9c58cf4182fa056b9cd124e8295607", "size": 3724, "url": "https://launcher.mojang.com/v1/objects/fe17486bbe9c58cf4182fa056b9cd124e8295607/pack200.1"}, "raw": {"sha1": "26826cf52b89924f2d2a60d6cda798891875eae6", "size": 11623, "url": "https://launcher.mojang.com/v1/objects/26826cf52b89924f2d2a60d6cda798891875eae6/pack200.1"}}, "executable": false, "type": "file"}, "man/man1/policytool.1": {"downloads": {"lzma": {"sha1": "bd154e7c39aca71d15b2098c588866f8d95bc743", "size": 1122, "url": "https://launcher.mojang.com/v1/objects/bd154e7c39aca71d15b2098c588866f8d95bc743/policytool.1"}, "raw": {"sha1": "ab296625155d9a2b25ecc2b4feff2f741b3ad136", "size": 3235, "url": "https://launcher.mojang.com/v1/objects/ab296625155d9a2b25ecc2b4feff2f741b3ad136/policytool.1"}}, "executable": false, "type": "file"}, "man/man1/rmid.1": {"downloads": {"lzma": {"sha1": "6a7da234e7f43ebca5c4ba8cd862fda3be62fbaa", "size": 4255, "url": "https://launcher.mojang.com/v1/objects/6a7da234e7f43ebca5c4ba8cd862fda3be62fbaa/rmid.1"}, "raw": {"sha1": "6f10e214d7950a6a8460524e41dc700f112f89e5", "size": 15979, "url": "https://launcher.mojang.com/v1/objects/6f10e214d7950a6a8460524e41dc700f112f89e5/rmid.1"}}, "executable": false, "type": "file"}, "man/man1/rmiregistry.1": {"downloads": {"lzma": {"sha1": "f40dd17e3a734600ad1828b0c42d3a1685c4c520", "size": 1301, "url": "https://launcher.mojang.com/v1/objects/f40dd17e3a734600ad1828b0c42d3a1685c4c520/rmiregistry.1"}, "raw": {"sha1": "d9a3d23fab689df5bb9a792b88f462f939b49f70", "size": 3449, "url": "https://launcher.mojang.com/v1/objects/d9a3d23fab689df5bb9a792b88f462f939b49f70/rmiregistry.1"}}, "executable": false, "type": "file"}, "man/man1/servertool.1": {"downloads": {"lzma": {"sha1": "74f1e10712202cd3ca0ff5833de05b7ee67092e1", "size": 2307, "url": "https://launcher.mojang.com/v1/objects/74f1e10712202cd3ca0ff5833de05b7ee67092e1/servertool.1"}, "raw": {"sha1": "e6c7b510740ac8681a9bfb5f4ee1f0306125b728", "size": 7237, "url": "https://launcher.mojang.com/v1/objects/e6c7b510740ac8681a9bfb5f4ee1f0306125b728/servertool.1"}}, "executable": false, "type": "file"}, "man/man1/tnameserv.1": {"downloads": {"lzma": {"sha1": "4bec7f4e070d023f124f9352a8971d7acd249a15", "size": 3955, "url": "https://launcher.mojang.com/v1/objects/4bec7f4e070d023f124f9352a8971d7acd249a15/tnameserv.1"}, "raw": {"sha1": "a31dbbe800d49cb371fab9a4b73d22c3bf8799ad", "size": 15747, "url": "https://launcher.mojang.com/v1/objects/a31dbbe800d49cb371fab9a4b73d22c3bf8799ad/tnameserv.1"}}, "executable": false, "type": "file"}, "man/man1/unpack200.1": {"downloads": {"lzma": {"sha1": "f8e73863187929debf2ea6dadefb2995ec7917e7", "size": 1672, "url": "https://launcher.mojang.com/v1/objects/f8e73863187929debf2ea6dadefb2995ec7917e7/unpack200.1"}, "raw": {"sha1": "437f7233d738cb9b822e99003127049005663e0f", "size": 4244, "url": "https://launcher.mojang.com/v1/objects/437f7233d738cb9b822e99003127049005663e0f/unpack200.1"}}, "executable": false, "type": "file"}, "plugin": {"type": "directory"}, "plugin/desktop": {"type": "directory"}, "plugin/desktop/sun_java.desktop": {"downloads": {"lzma": {"sha1": "49ab0ccb54c3be68281d05055bc56a88b1281d3c", "size": 447, "url": "https://launcher.mojang.com/v1/objects/49ab0ccb54c3be68281d05055bc56a88b1281d3c/sun_java.desktop"}, "raw": {"sha1": "79120ee8160ad6f3c9b90c2641fb7edf3af96b5d", "size": 624, "url": "https://launcher.mojang.com/v1/objects/79120ee8160ad6f3c9b90c2641fb7edf3af96b5d/sun_java.desktop"}}, "executable": false, "type": "file"}, "plugin/desktop/sun_java.png": {"downloads": {"raw": {"sha1": "699c41e97a35414e72a80327a54d6e14e874e951", "size": 4351, "url": "https://launcher.mojang.com/v1/objects/699c41e97a35414e72a80327a54d6e14e874e951/sun_java.png"}}, "executable": false, "type": "file"}, "release": {"downloads": {"raw": {"sha1": "cb462682644c0275d94a45b759108815f3112064", "size": 424, "url": "https://launcher.mojang.com/v1/objects/cb462682644c0275d94a45b759108815f3112064/release"}}, "executable": false, "type": "file"}}} \ No newline at end of file +{ + "files": { + "COPYRIGHT": { + "downloads": { + "lzma": { + "sha1": "dd860e040807f7e53ae89da5f28dd73d57ac605d", + "size": 1431, + "url": "https://launcher.mojang.com/v1/objects/dd860e040807f7e53ae89da5f28dd73d57ac605d/COPYRIGHT" + }, + "raw": { + "sha1": "c725183c757011e7ba96c83c1e86ee7e8b516a2b", + "size": 3244, + "url": "https://launcher.mojang.com/v1/objects/c725183c757011e7ba96c83c1e86ee7e8b516a2b/COPYRIGHT" + } + }, + "executable": false, + "type": "file" + }, + "LICENSE": { + "downloads": { + "raw": { + "sha1": "3e86865deec0814c958bcf7fb87f790bccc0e8bd", + "size": 40, + "url": "https://launcher.mojang.com/v1/objects/3e86865deec0814c958bcf7fb87f790bccc0e8bd/LICENSE" + } + }, + "executable": false, + "type": "file" + }, + "README": { + "downloads": { + "raw": { + "sha1": "f90331df1e5badeadc501d8dd70714c62a920204", + "size": 46, + "url": "https://launcher.mojang.com/v1/objects/f90331df1e5badeadc501d8dd70714c62a920204/README" + } + }, + "executable": false, + "type": "file" + }, + "THIRDPARTYLICENSEREADME-JAVAFX.txt": { + "downloads": { + "lzma": { + "sha1": "4fee85109d7ff04b982d0576dabd15397f599125", + "size": 15455, + "url": + "https://launcher.mojang.com/v1/objects/4fee85109d7ff04b982d0576dabd15397f599125/THIRDPARTYLICENSEREADME-JAVAFX.txt" + }, + "raw": { + "sha1": "56ff42f87607b997b52ae0ef8bf315e36932e870", + "size": 112724, + "url": + "https://launcher.mojang.com/v1/objects/56ff42f87607b997b52ae0ef8bf315e36932e870/THIRDPARTYLICENSEREADME-JAVAFX.txt" + } + }, + "executable": false, + "type": "file" + }, + "THIRDPARTYLICENSEREADME.txt": { + "downloads": { + "lzma": { + "sha1": "419c1414ba46ae9dbfd38cf4e0601fff61644429", + "size": 32266, + "url": "https://launcher.mojang.com/v1/objects/419c1414ba46ae9dbfd38cf4e0601fff61644429/THIRDPARTYLICENSEREADME.txt" + }, + "raw": { + "sha1": "b83c3f32261de3e48ccd20614a11e066b1ec9027", + "size": 153824, + "url": "https://launcher.mojang.com/v1/objects/b83c3f32261de3e48ccd20614a11e066b1ec9027/THIRDPARTYLICENSEREADME.txt" + } + }, + "executable": false, + "type": "file" + }, + "Welcome.html": { + "downloads": { + "lzma": { + "sha1": "01c21a74b4aafb7cbe0388233c43cbdf77dcaaea", + "size": 528, + "url": "https://launcher.mojang.com/v1/objects/01c21a74b4aafb7cbe0388233c43cbdf77dcaaea/Welcome.html" + }, + "raw": { + "sha1": "d98ae54f03dac87419abc19b97e315830c2da55f", + "size": 955, + "url": "https://launcher.mojang.com/v1/objects/d98ae54f03dac87419abc19b97e315830c2da55f/Welcome.html" + } + }, + "executable": false, + "type": "file" + }, + "bin": { + "type": "directory" + }, + "bin/ControlPanel": { + "target": "jcontrol", + "type": "link" + }, + "bin/java": { + "downloads": { + "lzma": { + "sha1": "3857eea1d59e1bc545c67a753ed2768254807b8a", + "size": 2088, + "url": "https://launcher.mojang.com/v1/objects/3857eea1d59e1bc545c67a753ed2768254807b8a/java" + }, + "raw": { + "sha1": "3d20560fb5d1a49cb689c2226972e92e06d27ba6", + "size": 8464, + "url": "https://launcher.mojang.com/v1/objects/3d20560fb5d1a49cb689c2226972e92e06d27ba6/java" + } + }, + "executable": true, + "type": "file" + }, + "bin/javaws": { + "downloads": { + "lzma": { + "sha1": "a6bec5c049e76c4488294a256a2084ea23ddb440", + "size": 38173, + "url": "https://launcher.mojang.com/v1/objects/a6bec5c049e76c4488294a256a2084ea23ddb440/javaws" + }, + "raw": { + "sha1": "955c0f0066e2f893b0c2b3ccd83e223722e4ab74", + "size": 140296, + "url": "https://launcher.mojang.com/v1/objects/955c0f0066e2f893b0c2b3ccd83e223722e4ab74/javaws" + } + }, + "executable": true, + "type": "file" + }, + "bin/jcontrol": { + "downloads": { + "lzma": { + "sha1": "40c5e33748f252e1d950b579a4185ab2c23fc908", + "size": 2166, + "url": "https://launcher.mojang.com/v1/objects/40c5e33748f252e1d950b579a4185ab2c23fc908/jcontrol" + }, + "raw": { + "sha1": "ed541733c8b51e34349c1f8010b277e58ad73f1e", + "size": 6264, + "url": "https://launcher.mojang.com/v1/objects/ed541733c8b51e34349c1f8010b277e58ad73f1e/jcontrol" + } + }, + "executable": true, + "type": "file" + }, + "bin/jjs": { + "downloads": { + "lzma": { + "sha1": "d44d1ac421979f7671921986214812095a5b0e3b", + "size": 2168, + "url": "https://launcher.mojang.com/v1/objects/d44d1ac421979f7671921986214812095a5b0e3b/jjs" + }, + "raw": { + "sha1": "f00f944c3dbe556793b5dc686aaeee3e5722e99b", + "size": 8584, + "url": "https://launcher.mojang.com/v1/objects/f00f944c3dbe556793b5dc686aaeee3e5722e99b/jjs" + } + }, + "executable": true, + "type": "file" + }, + "bin/keytool": { + "downloads": { + "lzma": { + "sha1": "93c607dce450976667c382f609a367167bdec05c", + "size": 2175, + "url": "https://launcher.mojang.com/v1/objects/93c607dce450976667c382f609a367167bdec05c/keytool" + }, + "raw": { + "sha1": "7114b561546270e441e9ed1bcc24e5188c068a42", + "size": 8584, + "url": "https://launcher.mojang.com/v1/objects/7114b561546270e441e9ed1bcc24e5188c068a42/keytool" + } + }, + "executable": true, + "type": "file" + }, + "bin/orbd": { + "downloads": { + "lzma": { + "sha1": "b27dfded5e2b2f6f02c555971c94e46ca14ac81b", + "size": 2254, + "url": "https://launcher.mojang.com/v1/objects/b27dfded5e2b2f6f02c555971c94e46ca14ac81b/orbd" + }, + "raw": { + "sha1": "7f31217fecb3dbbd89f1dd3783fca58793a66fd2", + "size": 8656, + "url": "https://launcher.mojang.com/v1/objects/7f31217fecb3dbbd89f1dd3783fca58793a66fd2/orbd" + } + }, + "executable": true, + "type": "file" + }, + "bin/pack200": { + "downloads": { + "lzma": { + "sha1": "b52da4497b49b1508b6225a5740857ddb8f52e97", + "size": 2183, + "url": "https://launcher.mojang.com/v1/objects/b52da4497b49b1508b6225a5740857ddb8f52e97/pack200" + }, + "raw": { + "sha1": "16ef3e801efb57e50bc6477a27a9d95d02d0775b", + "size": 8584, + "url": "https://launcher.mojang.com/v1/objects/16ef3e801efb57e50bc6477a27a9d95d02d0775b/pack200" + } + }, + "executable": true, + "type": "file" + }, + "bin/policytool": { + "downloads": { + "lzma": { + "sha1": "87da4c07da45f3d1a1a9d732af197cd39bf69d10", + "size": 2182, + "url": "https://launcher.mojang.com/v1/objects/87da4c07da45f3d1a1a9d732af197cd39bf69d10/policytool" + }, + "raw": { + "sha1": "a52a29424470cb9b8db5c2fb1751d0b697a7ec8e", + "size": 8592, + "url": "https://launcher.mojang.com/v1/objects/a52a29424470cb9b8db5c2fb1751d0b697a7ec8e/policytool" + } + }, + "executable": true, + "type": "file" + }, + "bin/rmid": { + "downloads": { + "lzma": { + "sha1": "1494c1174fde0c0a93ea117bc7edf7eb936c0512", + "size": 2172, + "url": "https://launcher.mojang.com/v1/objects/1494c1174fde0c0a93ea117bc7edf7eb936c0512/rmid" + }, + "raw": { + "sha1": "5c8710e1ab924e5b09a07bcb4c6e106293bbd1a8", + "size": 8584, + "url": "https://launcher.mojang.com/v1/objects/5c8710e1ab924e5b09a07bcb4c6e106293bbd1a8/rmid" + } + }, + "executable": true, + "type": "file" + }, + "bin/rmiregistry": { + "downloads": { + "lzma": { + "sha1": "7070cf2ec5a5e520a880bae699431edf02083e7e", + "size": 2174, + "url": "https://launcher.mojang.com/v1/objects/7070cf2ec5a5e520a880bae699431edf02083e7e/rmiregistry" + }, + "raw": { + "sha1": "5f518daa7050028d5d9d849634c73136f2b23a54", + "size": 8592, + "url": "https://launcher.mojang.com/v1/objects/5f518daa7050028d5d9d849634c73136f2b23a54/rmiregistry" + } + }, + "executable": true, + "type": "file" + }, + "bin/servertool": { + "downloads": { + "lzma": { + "sha1": "1db683a11cc9b7313426c84412f4d95be2fa7ccd", + "size": 2185, + "url": "https://launcher.mojang.com/v1/objects/1db683a11cc9b7313426c84412f4d95be2fa7ccd/servertool" + }, + "raw": { + "sha1": "49d0ebfeb265ce5a8733e1014541ea2525674a60", + "size": 8592, + "url": "https://launcher.mojang.com/v1/objects/49d0ebfeb265ce5a8733e1014541ea2525674a60/servertool" + } + }, + "executable": true, + "type": "file" + }, + "bin/tnameserv": { + "downloads": { + "lzma": { + "sha1": "36da9c9a2c5a8b662a3f8d52ca67339bce1c2714", + "size": 2291, + "url": "https://launcher.mojang.com/v1/objects/36da9c9a2c5a8b662a3f8d52ca67339bce1c2714/tnameserv" + }, + "raw": { + "sha1": "09d998f8efcb6f55d0d87f59e08f8b89662796d9", + "size": 8656, + "url": "https://launcher.mojang.com/v1/objects/09d998f8efcb6f55d0d87f59e08f8b89662796d9/tnameserv" + } + }, + "executable": true, + "type": "file" + }, + "bin/unpack200": { + "downloads": { + "lzma": { + "sha1": "344959e32fc7ee19eebe7b3cf5ab6d1a7d6641f2", + "size": 79721, + "url": "https://launcher.mojang.com/v1/objects/344959e32fc7ee19eebe7b3cf5ab6d1a7d6641f2/unpack200" + }, + "raw": { + "sha1": "5dd933132f1b202e19e0c8e093f7113711cfdfc1", + "size": 182616, + "url": "https://launcher.mojang.com/v1/objects/5dd933132f1b202e19e0c8e093f7113711cfdfc1/unpack200" + } + }, + "executable": true, + "type": "file" + }, + "lib": { + "type": "directory" + }, + "lib/amd64": { + "type": "directory" + }, + "lib/amd64/jli": { + "type": "directory" + }, + "lib/amd64/jli/libjli.so": { + "downloads": { + "lzma": { + "sha1": "372331ee8e375888f798a2e88180a94493e141b0", + "size": 48327, + "url": "https://launcher.mojang.com/v1/objects/372331ee8e375888f798a2e88180a94493e141b0/libjli.so" + }, + "raw": { + "sha1": "73b0cf8b7415686bc40c561ff77ff2740ccf7a44", + "size": 108616, + "url": "https://launcher.mojang.com/v1/objects/73b0cf8b7415686bc40c561ff77ff2740ccf7a44/libjli.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/jvm.cfg": { + "downloads": { + "lzma": { + "sha1": "86bcfebec37b38415525ffd77d3eaf70d0b1b4ca", + "size": 435, + "url": "https://launcher.mojang.com/v1/objects/86bcfebec37b38415525ffd77d3eaf70d0b1b4ca/jvm.cfg" + }, + "raw": { + "sha1": "84b38bdc745de446ba0ca0232ea3aaf2efd721da", + "size": 627, + "url": "https://launcher.mojang.com/v1/objects/84b38bdc745de446ba0ca0232ea3aaf2efd721da/jvm.cfg" + } + }, + "executable": false, + "type": "file" + }, + "lib/amd64/libavplugin-53.so": { + "downloads": { + "lzma": { + "sha1": "a332366762d9efc7b845a682b7edce62db44618c", + "size": 14747, + "url": "https://launcher.mojang.com/v1/objects/a332366762d9efc7b845a682b7edce62db44618c/libavplugin-53.so" + }, + "raw": { + "sha1": "9bd1473dd8a0dc7950c7af1cc69a45548df26eb5", + "size": 51720, + "url": "https://launcher.mojang.com/v1/objects/9bd1473dd8a0dc7950c7af1cc69a45548df26eb5/libavplugin-53.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libavplugin-54.so": { + "downloads": { + "lzma": { + "sha1": "2c615852a0720a275163e00597c1f711f11341da", + "size": 15153, + "url": "https://launcher.mojang.com/v1/objects/2c615852a0720a275163e00597c1f711f11341da/libavplugin-54.so" + }, + "raw": { + "sha1": "8808050c5949c4800b42d1b19b1f8b0d120bcacb", + "size": 51768, + "url": "https://launcher.mojang.com/v1/objects/8808050c5949c4800b42d1b19b1f8b0d120bcacb/libavplugin-54.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libavplugin-55.so": { + "downloads": { + "lzma": { + "sha1": "39ee8e7fe14f0010c78973962800f539c3e4c16b", + "size": 15168, + "url": "https://launcher.mojang.com/v1/objects/39ee8e7fe14f0010c78973962800f539c3e4c16b/libavplugin-55.so" + }, + "raw": { + "sha1": "f10ea4ea3489e96d8d161a96790133c417ec44e1", + "size": 51784, + "url": "https://launcher.mojang.com/v1/objects/f10ea4ea3489e96d8d161a96790133c417ec44e1/libavplugin-55.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libavplugin-56.so": { + "downloads": { + "lzma": { + "sha1": "abe7feced5a559f1bdc868526dc69484e0e591a0", + "size": 15169, + "url": "https://launcher.mojang.com/v1/objects/abe7feced5a559f1bdc868526dc69484e0e591a0/libavplugin-56.so" + }, + "raw": { + "sha1": "e5bfcbff5a5a5a5993a3e689a05ef358c131a3ed", + "size": 51784, + "url": "https://launcher.mojang.com/v1/objects/e5bfcbff5a5a5a5993a3e689a05ef358c131a3ed/libavplugin-56.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libavplugin-57.so": { + "downloads": { + "lzma": { + "sha1": "4dd26b4ef2294b6929dcb2c7546b47eac5cc78a9", + "size": 15174, + "url": "https://launcher.mojang.com/v1/objects/4dd26b4ef2294b6929dcb2c7546b47eac5cc78a9/libavplugin-57.so" + }, + "raw": { + "sha1": "2949e7ff9b0ac90e8943c211cff141ab12eec3f8", + "size": 51784, + "url": "https://launcher.mojang.com/v1/objects/2949e7ff9b0ac90e8943c211cff141ab12eec3f8/libavplugin-57.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libavplugin-ffmpeg-56.so": { + "downloads": { + "lzma": { + "sha1": "c688ba1cfa442bf18bee43b2fa870b4dc1ce3fb6", + "size": 15231, + "url": "https://launcher.mojang.com/v1/objects/c688ba1cfa442bf18bee43b2fa870b4dc1ce3fb6/libavplugin-ffmpeg-56.so" + }, + "raw": { + "sha1": "0d36c971a9ad99fc2292092fdec3a4179b1021b9", + "size": 51920, + "url": "https://launcher.mojang.com/v1/objects/0d36c971a9ad99fc2292092fdec3a4179b1021b9/libavplugin-ffmpeg-56.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libavplugin-ffmpeg-57.so": { + "downloads": { + "lzma": { + "sha1": "087426bdbffebcfa372a438e863785f4ffbe9a6b", + "size": 15180, + "url": "https://launcher.mojang.com/v1/objects/087426bdbffebcfa372a438e863785f4ffbe9a6b/libavplugin-ffmpeg-57.so" + }, + "raw": { + "sha1": "5e9c4eb4b49eb8e57c01003ec73a1eb8d6d8c462", + "size": 51784, + "url": "https://launcher.mojang.com/v1/objects/5e9c4eb4b49eb8e57c01003ec73a1eb8d6d8c462/libavplugin-ffmpeg-57.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libawt.so": { + "downloads": { + "lzma": { + "sha1": "018be58b205b73c842a55df811b70d0e8237216e", + "size": 195720, + "url": "https://launcher.mojang.com/v1/objects/018be58b205b73c842a55df811b70d0e8237216e/libawt.so" + }, + "raw": { + "sha1": "02632cd326e3161c00a7e784599dd7b9ee053dce", + "size": 759184, + "url": "https://launcher.mojang.com/v1/objects/02632cd326e3161c00a7e784599dd7b9ee053dce/libawt.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libawt_headless.so": { + "downloads": { + "lzma": { + "sha1": "7ac2517cff75d4bbb0a0412a9b5f18c74ea188fa", + "size": 11211, + "url": "https://launcher.mojang.com/v1/objects/7ac2517cff75d4bbb0a0412a9b5f18c74ea188fa/libawt_headless.so" + }, + "raw": { + "sha1": "862157ec957008d0911c5daedc004b3a202623a4", + "size": 39176, + "url": "https://launcher.mojang.com/v1/objects/862157ec957008d0911c5daedc004b3a202623a4/libawt_headless.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libawt_xawt.so": { + "downloads": { + "lzma": { + "sha1": "d536a96af27dfe35de6bb2c8759d51c488cdd8d4", + "size": 149598, + "url": "https://launcher.mojang.com/v1/objects/d536a96af27dfe35de6bb2c8759d51c488cdd8d4/libawt_xawt.so" + }, + "raw": { + "sha1": "28232b3e01b6f11bfe098bfc6eafc3a513dcebf1", + "size": 470232, + "url": "https://launcher.mojang.com/v1/objects/28232b3e01b6f11bfe098bfc6eafc3a513dcebf1/libawt_xawt.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libbci.so": { + "downloads": { + "lzma": { + "sha1": "c36fad091d11e64c815d5ca17c0ef7a55b0776b1", + "size": 3509, + "url": "https://launcher.mojang.com/v1/objects/c36fad091d11e64c815d5ca17c0ef7a55b0776b1/libbci.so" + }, + "raw": { + "sha1": "33824051db1ccb6332e22c2b63231055240d0af0", + "size": 12760, + "url": "https://launcher.mojang.com/v1/objects/33824051db1ccb6332e22c2b63231055240d0af0/libbci.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libdcpr.so": { + "downloads": { + "lzma": { + "sha1": "70c6b0933a37f2b1124d6e7c131039241fe796ee", + "size": 75969, + "url": "https://launcher.mojang.com/v1/objects/70c6b0933a37f2b1124d6e7c131039241fe796ee/libdcpr.so" + }, + "raw": { + "sha1": "fa7001bc5d80579e2716590f3eee8027da0beae7", + "size": 204456, + "url": "https://launcher.mojang.com/v1/objects/fa7001bc5d80579e2716590f3eee8027da0beae7/libdcpr.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libdecora_sse.so": { + "downloads": { + "lzma": { + "sha1": "514acc017dfb6cefaf8cc6d18006ce55781cc9bc", + "size": 24397, + "url": "https://launcher.mojang.com/v1/objects/514acc017dfb6cefaf8cc6d18006ce55781cc9bc/libdecora_sse.so" + }, + "raw": { + "sha1": "d0c84233504c916e548e29f513e25f6a7479abfc", + "size": 74912, + "url": "https://launcher.mojang.com/v1/objects/d0c84233504c916e548e29f513e25f6a7479abfc/libdecora_sse.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libdeploy.so": { + "downloads": { + "lzma": { + "sha1": "6cf31fd98301c749ac0d2c7825f6d925a4409760", + "size": 168999, + "url": "https://launcher.mojang.com/v1/objects/6cf31fd98301c749ac0d2c7825f6d925a4409760/libdeploy.so" + }, + "raw": { + "sha1": "b3832e97ed8ca794884b56a591b83d02a2c0c06f", + "size": 642368, + "url": "https://launcher.mojang.com/v1/objects/b3832e97ed8ca794884b56a591b83d02a2c0c06f/libdeploy.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libdt_socket.so": { + "downloads": { + "lzma": { + "sha1": "4cc5c880dbb6fa180436d12d60f0abec8ebb59dc", + "size": 7784, + "url": "https://launcher.mojang.com/v1/objects/4cc5c880dbb6fa180436d12d60f0abec8ebb59dc/libdt_socket.so" + }, + "raw": { + "sha1": "91ce96f252b8139fc12f0f224ed5b1a041767ab7", + "size": 24616, + "url": "https://launcher.mojang.com/v1/objects/91ce96f252b8139fc12f0f224ed5b1a041767ab7/libdt_socket.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libfontmanager.so": { + "downloads": { + "lzma": { + "sha1": "f94e5e94c71c603ff4d3cd1e7e3d9e181fcc145d", + "size": 146951, + "url": "https://launcher.mojang.com/v1/objects/f94e5e94c71c603ff4d3cd1e7e3d9e181fcc145d/libfontmanager.so" + }, + "raw": { + "sha1": "2428e805f2c53d1283a033dfd11a86fbb7bd7159", + "size": 490672, + "url": "https://launcher.mojang.com/v1/objects/2428e805f2c53d1283a033dfd11a86fbb7bd7159/libfontmanager.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libfxplugins.so": { + "downloads": { + "lzma": { + "sha1": "a640143365d382a5ad743a784bc2f3706d9d6d67", + "size": 50048, + "url": "https://launcher.mojang.com/v1/objects/a640143365d382a5ad743a784bc2f3706d9d6d67/libfxplugins.so" + }, + "raw": { + "sha1": "0fd4ac04a84c131f1aaee9e6b0898ff9ea69e3ee", + "size": 151448, + "url": "https://launcher.mojang.com/v1/objects/0fd4ac04a84c131f1aaee9e6b0898ff9ea69e3ee/libfxplugins.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libglass.so": { + "downloads": { + "lzma": { + "sha1": "f1ff517714fa5f2c861f33b32db823fe851541f1", + "size": 2856, + "url": "https://launcher.mojang.com/v1/objects/f1ff517714fa5f2c861f33b32db823fe851541f1/libglass.so" + }, + "raw": { + "sha1": "e7f4fece30ac727be8148d33b8256abd3a41cef9", + "size": 13072, + "url": "https://launcher.mojang.com/v1/objects/e7f4fece30ac727be8148d33b8256abd3a41cef9/libglass.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libglassgtk2.so": { + "downloads": { + "lzma": { + "sha1": "15b90f7a2baacd15e80aa9785d87cf1e4258376d", + "size": 220476, + "url": "https://launcher.mojang.com/v1/objects/15b90f7a2baacd15e80aa9785d87cf1e4258376d/libglassgtk2.so" + }, + "raw": { + "sha1": "e30a634c2ff2143bdee512360553d6e0304f33b2", + "size": 844984, + "url": "https://launcher.mojang.com/v1/objects/e30a634c2ff2143bdee512360553d6e0304f33b2/libglassgtk2.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libglassgtk3.so": { + "downloads": { + "lzma": { + "sha1": "868c231165f8c9043b7f0e7de208ec023f06a6e7", + "size": 220560, + "url": "https://launcher.mojang.com/v1/objects/868c231165f8c9043b7f0e7de208ec023f06a6e7/libglassgtk3.so" + }, + "raw": { + "sha1": "762a11a2b376b7b5a2a7cad780715524fdd176d5", + "size": 845304, + "url": "https://launcher.mojang.com/v1/objects/762a11a2b376b7b5a2a7cad780715524fdd176d5/libglassgtk3.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libglib-lite.so": { + "downloads": { + "lzma": { + "sha1": "61b8871242febe1be262de167dc20ae94bf964b4", + "size": 457046, + "url": "https://launcher.mojang.com/v1/objects/61b8871242febe1be262de167dc20ae94bf964b4/libglib-lite.so" + }, + "raw": { + "sha1": "63afa060fc3f120af76128e51d32603fc4336fa8", + "size": 1538352, + "url": "https://launcher.mojang.com/v1/objects/63afa060fc3f120af76128e51d32603fc4336fa8/libglib-lite.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libgstreamer-lite.so": { + "downloads": { + "lzma": { + "sha1": "2447dc368406ba1b989a29937d41924620e01988", + "size": 673056, + "url": "https://launcher.mojang.com/v1/objects/2447dc368406ba1b989a29937d41924620e01988/libgstreamer-lite.so" + }, + "raw": { + "sha1": "5505e7ca592ac64371d3db8fe53bcb602e9723d3", + "size": 2263872, + "url": "https://launcher.mojang.com/v1/objects/5505e7ca592ac64371d3db8fe53bcb602e9723d3/libgstreamer-lite.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libhprof.so": { + "downloads": { + "lzma": { + "sha1": "94a5589c818db1fb1cf1881e24e217c309fce2e4", + "size": 64471, + "url": "https://launcher.mojang.com/v1/objects/94a5589c818db1fb1cf1881e24e217c309fce2e4/libhprof.so" + }, + "raw": { + "sha1": "4bb9bdeef6133b6dd558d52d691b077c03e9b0ee", + "size": 175504, + "url": "https://launcher.mojang.com/v1/objects/4bb9bdeef6133b6dd558d52d691b077c03e9b0ee/libhprof.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libinstrument.so": { + "downloads": { + "lzma": { + "sha1": "84ffea356caf725b42c86a8ebc9587f477ddde29", + "size": 18603, + "url": "https://launcher.mojang.com/v1/objects/84ffea356caf725b42c86a8ebc9587f477ddde29/libinstrument.so" + }, + "raw": { + "sha1": "cb8009769601e3fecd7ea2b36c344f737b1a9da7", + "size": 51560, + "url": "https://launcher.mojang.com/v1/objects/cb8009769601e3fecd7ea2b36c344f737b1a9da7/libinstrument.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libj2gss.so": { + "downloads": { + "lzma": { + "sha1": "4b2aa699506b126098b585a9617ce1c05707fa29", + "size": 14132, + "url": "https://launcher.mojang.com/v1/objects/4b2aa699506b126098b585a9617ce1c05707fa29/libj2gss.so" + }, + "raw": { + "sha1": "cbce4a302b255d4d1924ef7606f038af766c5e86", + "size": 47688, + "url": "https://launcher.mojang.com/v1/objects/cbce4a302b255d4d1924ef7606f038af766c5e86/libj2gss.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libj2pcsc.so": { + "downloads": { + "lzma": { + "sha1": "2361d3b2e3da48593c391b29b0d2b5409e4c55e5", + "size": 5074, + "url": "https://launcher.mojang.com/v1/objects/2361d3b2e3da48593c391b29b0d2b5409e4c55e5/libj2pcsc.so" + }, + "raw": { + "sha1": "1274178492e7a3e997e12f67794616f7c3d8d0b9", + "size": 18296, + "url": "https://launcher.mojang.com/v1/objects/1274178492e7a3e997e12f67794616f7c3d8d0b9/libj2pcsc.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libj2pkcs11.so": { + "downloads": { + "lzma": { + "sha1": "ef927e2790ba05931d0f0bdd63da3d275a834946", + "size": 21573, + "url": "https://launcher.mojang.com/v1/objects/ef927e2790ba05931d0f0bdd63da3d275a834946/libj2pkcs11.so" + }, + "raw": { + "sha1": "bd4f2af9bfdc6168633d1920c1a1415de06bb45a", + "size": 79472, + "url": "https://launcher.mojang.com/v1/objects/bd4f2af9bfdc6168633d1920c1a1415de06bb45a/libj2pkcs11.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjaas_unix.so": { + "downloads": { + "lzma": { + "sha1": "7f7e843544ee1eb1454a5826bdd4218685b79430", + "size": 2404, + "url": "https://launcher.mojang.com/v1/objects/7f7e843544ee1eb1454a5826bdd4218685b79430/libjaas_unix.so" + }, + "raw": { + "sha1": "4c517925c7d464a5b719898eb0bea1b04df31f1f", + "size": 8192, + "url": "https://launcher.mojang.com/v1/objects/4c517925c7d464a5b719898eb0bea1b04df31f1f/libjaas_unix.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjava.so": { + "downloads": { + "lzma": { + "sha1": "5eee7a42600a44a8bb8d6d7f510fd96a29637ac0", + "size": 63113, + "url": "https://launcher.mojang.com/v1/objects/5eee7a42600a44a8bb8d6d7f510fd96a29637ac0/libjava.so" + }, + "raw": { + "sha1": "e280aeddf3fc0ec664aef7efc0e0e197a54aaf02", + "size": 227672, + "url": "https://launcher.mojang.com/v1/objects/e280aeddf3fc0ec664aef7efc0e0e197a54aaf02/libjava.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjava_crw_demo.so": { + "downloads": { + "lzma": { + "sha1": "b197cf23ae3556eb0b45c663f0a8cb62408b961e", + "size": 10412, + "url": "https://launcher.mojang.com/v1/objects/b197cf23ae3556eb0b45c663f0a8cb62408b961e/libjava_crw_demo.so" + }, + "raw": { + "sha1": "18f20f906977c90d0090b41dbda8dd5cfead5a4c", + "size": 26144, + "url": "https://launcher.mojang.com/v1/objects/18f20f906977c90d0090b41dbda8dd5cfead5a4c/libjava_crw_demo.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjavafx_font.so": { + "downloads": { + "lzma": { + "sha1": "ffbba0e5022f829412b86063d8a90f95f16709b1", + "size": 5608, + "url": "https://launcher.mojang.com/v1/objects/ffbba0e5022f829412b86063d8a90f95f16709b1/libjavafx_font.so" + }, + "raw": { + "sha1": "8634a0aca612fc40420a4a7cc8af4cc46cfc6725", + "size": 17104, + "url": "https://launcher.mojang.com/v1/objects/8634a0aca612fc40420a4a7cc8af4cc46cfc6725/libjavafx_font.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjavafx_font_freetype.so": { + "downloads": { + "lzma": { + "sha1": "310271eda8a2ac264ffc3640a9d847b49438d0bd", + "size": 6942, + "url": "https://launcher.mojang.com/v1/objects/310271eda8a2ac264ffc3640a9d847b49438d0bd/libjavafx_font_freetype.so" + }, + "raw": { + "sha1": "3e7572d047c12ba2bc43acec7f98a67c20af8042", + "size": 27616, + "url": "https://launcher.mojang.com/v1/objects/3e7572d047c12ba2bc43acec7f98a67c20af8042/libjavafx_font_freetype.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjavafx_font_pango.so": { + "downloads": { + "lzma": { + "sha1": "a7bcf0669e70b0f43099a99c81e6b6440cb40ac0", + "size": 5820, + "url": "https://launcher.mojang.com/v1/objects/a7bcf0669e70b0f43099a99c81e6b6440cb40ac0/libjavafx_font_pango.so" + }, + "raw": { + "sha1": "f0b775cc9a514c7ee8b4d6fb300653ce548caf10", + "size": 25560, + "url": "https://launcher.mojang.com/v1/objects/f0b775cc9a514c7ee8b4d6fb300653ce548caf10/libjavafx_font_pango.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjavafx_font_t2k.so": { + "downloads": { + "lzma": { + "sha1": "551c29dc7c7fc83223aa36a6187f7e0c5d650538", + "size": 431450, + "url": "https://launcher.mojang.com/v1/objects/551c29dc7c7fc83223aa36a6187f7e0c5d650538/libjavafx_font_t2k.so" + }, + "raw": { + "sha1": "91e5813057c3b852d411540160f8ad05fb9f1ed3", + "size": 1486128, + "url": "https://launcher.mojang.com/v1/objects/91e5813057c3b852d411540160f8ad05fb9f1ed3/libjavafx_font_t2k.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjavafx_iio.so": { + "downloads": { + "lzma": { + "sha1": "c832998fd5e06ed6dcd6428816194c350785420c", + "size": 101479, + "url": "https://launcher.mojang.com/v1/objects/c832998fd5e06ed6dcd6428816194c350785420c/libjavafx_iio.so" + }, + "raw": { + "sha1": "dcdf68cb25677b76c1cf0bb94294e6e9880a6678", + "size": 256336, + "url": "https://launcher.mojang.com/v1/objects/dcdf68cb25677b76c1cf0bb94294e6e9880a6678/libjavafx_iio.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjawt.so": { + "downloads": { + "lzma": { + "sha1": "c1ced6aad5c69ff444dc67d0fd7e333558953831", + "size": 1872, + "url": "https://launcher.mojang.com/v1/objects/c1ced6aad5c69ff444dc67d0fd7e333558953831/libjawt.so" + }, + "raw": { + "sha1": "c5032f2c6fa40bea24e56605cf76b26a27e87b67", + "size": 8048, + "url": "https://launcher.mojang.com/v1/objects/c5032f2c6fa40bea24e56605cf76b26a27e87b67/libjawt.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjdwp.so": { + "downloads": { + "lzma": { + "sha1": "c1aabbb3f5a624b9ad10ed871a1d83510a99b646", + "size": 94884, + "url": "https://launcher.mojang.com/v1/objects/c1aabbb3f5a624b9ad10ed871a1d83510a99b646/libjdwp.so" + }, + "raw": { + "sha1": "a043e97be47937f6f552e94cf79c76c1c57f9594", + "size": 272248, + "url": "https://launcher.mojang.com/v1/objects/a043e97be47937f6f552e94cf79c76c1c57f9594/libjdwp.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjfr.so": { + "downloads": { + "lzma": { + "sha1": "11b8e6bfffdccbacbf9dd29dea4b90b753f3c1b7", + "size": 8780, + "url": "https://launcher.mojang.com/v1/objects/11b8e6bfffdccbacbf9dd29dea4b90b753f3c1b7/libjfr.so" + }, + "raw": { + "sha1": "312392dd186b11c418183e818f1928e8685a07e5", + "size": 28384, + "url": "https://launcher.mojang.com/v1/objects/312392dd186b11c418183e818f1928e8685a07e5/libjfr.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjfxmedia.so": { + "downloads": { + "lzma": { + "sha1": "a4e7a126eb648ce6e5e6dc151831da37d8334139", + "size": 391897, + "url": "https://launcher.mojang.com/v1/objects/a4e7a126eb648ce6e5e6dc151831da37d8334139/libjfxmedia.so" + }, + "raw": { + "sha1": "5fa54944327a6012c3d34cb5c1c4432762178dc8", + "size": 1636376, + "url": "https://launcher.mojang.com/v1/objects/5fa54944327a6012c3d34cb5c1c4432762178dc8/libjfxmedia.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjfxwebkit.so": { + "downloads": { + "lzma": { + "sha1": "b274debd222cdcc2ee84160ebb95144b3880bc97", + "size": 20492825, + "url": "https://launcher.mojang.com/v1/objects/b274debd222cdcc2ee84160ebb95144b3880bc97/libjfxwebkit.so" + }, + "raw": { + "sha1": "ecee564c3b2f645131b35bb3004abd4caeabd291", + "size": 91014584, + "url": "https://launcher.mojang.com/v1/objects/ecee564c3b2f645131b35bb3004abd4caeabd291/libjfxwebkit.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjpeg.so": { + "downloads": { + "lzma": { + "sha1": "9ad55e370c5eaaa73c3158339db3c368b1aaf0cb", + "size": 113072, + "url": "https://launcher.mojang.com/v1/objects/9ad55e370c5eaaa73c3158339db3c368b1aaf0cb/libjpeg.so" + }, + "raw": { + "sha1": "651e6d53ae67db1f0efbf7f104447a9b49b7e333", + "size": 292520, + "url": "https://launcher.mojang.com/v1/objects/651e6d53ae67db1f0efbf7f104447a9b49b7e333/libjpeg.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjsdt.so": { + "downloads": { + "lzma": { + "sha1": "04b6d1361a34c496b5f652b2477784d69b8b6baf", + "size": 3964, + "url": "https://launcher.mojang.com/v1/objects/04b6d1361a34c496b5f652b2477784d69b8b6baf/libjsdt.so" + }, + "raw": { + "sha1": "82b48a82bf6183d34cf00a0f81661b45c616f31b", + "size": 12904, + "url": "https://launcher.mojang.com/v1/objects/82b48a82bf6183d34cf00a0f81661b45c616f31b/libjsdt.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjsig.so": { + "downloads": { + "lzma": { + "sha1": "37d3b89abde397216cc4ecb1339d8543d99b8428", + "size": 3536, + "url": "https://launcher.mojang.com/v1/objects/37d3b89abde397216cc4ecb1339d8543d99b8428/libjsig.so" + }, + "raw": { + "sha1": "42e52ba1bcbe0362ab24bcf65c93797354db6fb9", + "size": 13336, + "url": "https://launcher.mojang.com/v1/objects/42e52ba1bcbe0362ab24bcf65c93797354db6fb9/libjsig.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjsound.so": { + "downloads": { + "lzma": { + "sha1": "7e3c565d74d8ffae716f32b05544fa4a6f108adc", + "size": 2002, + "url": "https://launcher.mojang.com/v1/objects/7e3c565d74d8ffae716f32b05544fa4a6f108adc/libjsound.so" + }, + "raw": { + "sha1": "0c0fc63b92d7b83c9960fa80d45c80553ea20254", + "size": 8232, + "url": "https://launcher.mojang.com/v1/objects/0c0fc63b92d7b83c9960fa80d45c80553ea20254/libjsound.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libjsoundalsa.so": { + "downloads": { + "lzma": { + "sha1": "b06c51858a25ff776519495f1b9b3d9f604b089f", + "size": 23097, + "url": "https://launcher.mojang.com/v1/objects/b06c51858a25ff776519495f1b9b3d9f604b089f/libjsoundalsa.so" + }, + "raw": { + "sha1": "281d37f0326d4a12dc7ea316ead09c198ff7bdf7", + "size": 83256, + "url": "https://launcher.mojang.com/v1/objects/281d37f0326d4a12dc7ea316ead09c198ff7bdf7/libjsoundalsa.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/liblcms.so": { + "downloads": { + "lzma": { + "sha1": "7a239baba2086cae49114b382b74b971da02f08e", + "size": 176175, + "url": "https://launcher.mojang.com/v1/objects/7a239baba2086cae49114b382b74b971da02f08e/liblcms.so" + }, + "raw": { + "sha1": "c8895cc3c3d023d9e059225969ab67954772c0a1", + "size": 526872, + "url": "https://launcher.mojang.com/v1/objects/c8895cc3c3d023d9e059225969ab67954772c0a1/liblcms.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libmanagement.so": { + "downloads": { + "lzma": { + "sha1": "aed3fdbcefd1716abfc6a306687c8b741cbb318e", + "size": 12838, + "url": "https://launcher.mojang.com/v1/objects/aed3fdbcefd1716abfc6a306687c8b741cbb318e/libmanagement.so" + }, + "raw": { + "sha1": "eba35f61e0d50e30874b7c7b335edf2d52662423", + "size": 51808, + "url": "https://launcher.mojang.com/v1/objects/eba35f61e0d50e30874b7c7b335edf2d52662423/libmanagement.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libmlib_image.so": { + "downloads": { + "lzma": { + "sha1": "1bb181f079492d55c7a458e96488cd17fe0a7b86", + "size": 310272, + "url": "https://launcher.mojang.com/v1/objects/1bb181f079492d55c7a458e96488cd17fe0a7b86/libmlib_image.so" + }, + "raw": { + "sha1": "c973c450d33873675945d4694be484e3427f58f1", + "size": 1048136, + "url": "https://launcher.mojang.com/v1/objects/c973c450d33873675945d4694be484e3427f58f1/libmlib_image.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libnet.so": { + "downloads": { + "lzma": { + "sha1": "9dd79703b6deb86e0321afe01c6ac508263c8312", + "size": 38123, + "url": "https://launcher.mojang.com/v1/objects/9dd79703b6deb86e0321afe01c6ac508263c8312/libnet.so" + }, + "raw": { + "sha1": "b3a17b7d53fcdf1e689e1ec29ce851eee6022ead", + "size": 116920, + "url": "https://launcher.mojang.com/v1/objects/b3a17b7d53fcdf1e689e1ec29ce851eee6022ead/libnet.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libnio.so": { + "downloads": { + "lzma": { + "sha1": "5697c89d5d5d9b74f2e1555fcbba79dd4049e287", + "size": 24445, + "url": "https://launcher.mojang.com/v1/objects/5697c89d5d5d9b74f2e1555fcbba79dd4049e287/libnio.so" + }, + "raw": { + "sha1": "573bf8f64dbcc397f8abd3e1da28f90ab0679f5b", + "size": 93872, + "url": "https://launcher.mojang.com/v1/objects/573bf8f64dbcc397f8abd3e1da28f90ab0679f5b/libnio.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libnpjp2.so": { + "downloads": { + "lzma": { + "sha1": "6fe53b5951ff740e7f2ef7ffe5975af26da06718", + "size": 57892, + "url": "https://launcher.mojang.com/v1/objects/6fe53b5951ff740e7f2ef7ffe5975af26da06718/libnpjp2.so" + }, + "raw": { + "sha1": "2bb13c53a4280379253475e51216b97eed1d4ce3", + "size": 216592, + "url": "https://launcher.mojang.com/v1/objects/2bb13c53a4280379253475e51216b97eed1d4ce3/libnpjp2.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libnpt.so": { + "downloads": { + "lzma": { + "sha1": "1b170b09a32b1b8b6624fa5d1f94ec60b2bf3876", + "size": 5070, + "url": "https://launcher.mojang.com/v1/objects/1b170b09a32b1b8b6624fa5d1f94ec60b2bf3876/libnpt.so" + }, + "raw": { + "sha1": "6b1ff6b9b4624f3cc7801f221c82b8046fb76364", + "size": 17504, + "url": "https://launcher.mojang.com/v1/objects/6b1ff6b9b4624f3cc7801f221c82b8046fb76364/libnpt.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libprism_common.so": { + "downloads": { + "lzma": { + "sha1": "f4aca04c90bc7505851c074a08b2c31cae1f94fa", + "size": 23315, + "url": "https://launcher.mojang.com/v1/objects/f4aca04c90bc7505851c074a08b2c31cae1f94fa/libprism_common.so" + }, + "raw": { + "sha1": "b00866b6ed8646a29a334d46e297267552f27de8", + "size": 59008, + "url": "https://launcher.mojang.com/v1/objects/b00866b6ed8646a29a334d46e297267552f27de8/libprism_common.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libprism_es2.so": { + "downloads": { + "lzma": { + "sha1": "7ff4173c338c7a6f370f231670055737e032da3e", + "size": 18416, + "url": "https://launcher.mojang.com/v1/objects/7ff4173c338c7a6f370f231670055737e032da3e/libprism_es2.so" + }, + "raw": { + "sha1": "1390a1dc14345e5a948148e59195d62f3a83863f", + "size": 63808, + "url": "https://launcher.mojang.com/v1/objects/1390a1dc14345e5a948148e59195d62f3a83863f/libprism_es2.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libprism_sw.so": { + "downloads": { + "lzma": { + "sha1": "6728e8bf7b214067d715be6fe0325910d63c2468", + "size": 29457, + "url": "https://launcher.mojang.com/v1/objects/6728e8bf7b214067d715be6fe0325910d63c2468/libprism_sw.so" + }, + "raw": { + "sha1": "7a6c34cb2bbcde411778d1b3f8677c39e32c3ac4", + "size": 71608, + "url": "https://launcher.mojang.com/v1/objects/7a6c34cb2bbcde411778d1b3f8677c39e32c3ac4/libprism_sw.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libresource.so": { + "downloads": { + "lzma": { + "sha1": "1e35e63f1e74915fba620f1febf420b919d49bc5", + "size": 2633, + "url": "https://launcher.mojang.com/v1/objects/1e35e63f1e74915fba620f1febf420b919d49bc5/libresource.so" + }, + "raw": { + "sha1": "57490353ad0d83ab1930355213dea269795434fe", + "size": 13456, + "url": "https://launcher.mojang.com/v1/objects/57490353ad0d83ab1930355213dea269795434fe/libresource.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libsctp.so": { + "downloads": { + "lzma": { + "sha1": "4340132ed250d7849a016e071be773eaedd33aa8", + "size": 9332, + "url": "https://launcher.mojang.com/v1/objects/4340132ed250d7849a016e071be773eaedd33aa8/libsctp.so" + }, + "raw": { + "sha1": "4a80e743750f127c0d5a359f5cd60b97e7ee12ae", + "size": 29552, + "url": "https://launcher.mojang.com/v1/objects/4a80e743750f127c0d5a359f5cd60b97e7ee12ae/libsctp.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libsplashscreen.so": { + "downloads": { + "lzma": { + "sha1": "b226c8dbd73a548fc2b042ee6db6cc80e727597c", + "size": 190305, + "url": "https://launcher.mojang.com/v1/objects/b226c8dbd73a548fc2b042ee6db6cc80e727597c/libsplashscreen.so" + }, + "raw": { + "sha1": "87d6a491f5ba7e6c4d972264a0c9063afea567a2", + "size": 441376, + "url": "https://launcher.mojang.com/v1/objects/87d6a491f5ba7e6c4d972264a0c9063afea567a2/libsplashscreen.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libsunec.so": { + "downloads": { + "lzma": { + "sha1": "6ebba98fab1e3d872d1363235b76497f6f9babdc", + "size": 88829, + "url": "https://launcher.mojang.com/v1/objects/6ebba98fab1e3d872d1363235b76497f6f9babdc/libsunec.so" + }, + "raw": { + "sha1": "3b262a0a530f6e4e539aed2cd27b4de1d0ed8859", + "size": 283368, + "url": "https://launcher.mojang.com/v1/objects/3b262a0a530f6e4e539aed2cd27b4de1d0ed8859/libsunec.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libt2k.so": { + "downloads": { + "lzma": { + "sha1": "602cb812ef0b350ccf56ce209a260ddbe3743d92", + "size": 190720, + "url": "https://launcher.mojang.com/v1/objects/602cb812ef0b350ccf56ce209a260ddbe3743d92/libt2k.so" + }, + "raw": { + "sha1": "b072c56df997f61e15e6b5a43b8907b0d25c2043", + "size": 504840, + "url": "https://launcher.mojang.com/v1/objects/b072c56df997f61e15e6b5a43b8907b0d25c2043/libt2k.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libunpack.so": { + "downloads": { + "lzma": { + "sha1": "7107b615e941074f0b14c31c88fb67200aacd37f", + "size": 70308, + "url": "https://launcher.mojang.com/v1/objects/7107b615e941074f0b14c31c88fb67200aacd37f/libunpack.so" + }, + "raw": { + "sha1": "b05ff862ed87928ed91e80e5604673c5ea710a53", + "size": 197712, + "url": "https://launcher.mojang.com/v1/objects/b05ff862ed87928ed91e80e5604673c5ea710a53/libunpack.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libverify.so": { + "downloads": { + "lzma": { + "sha1": "ecd98efb8c7da441a8c3580e8f5598f3cb4165b1", + "size": 21885, + "url": "https://launcher.mojang.com/v1/objects/ecd98efb8c7da441a8c3580e8f5598f3cb4165b1/libverify.so" + }, + "raw": { + "sha1": "e2c8d92531c45ab9be69ffb72c87fa12e9e59827", + "size": 66112, + "url": "https://launcher.mojang.com/v1/objects/e2c8d92531c45ab9be69ffb72c87fa12e9e59827/libverify.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/libzip.so": { + "downloads": { + "lzma": { + "sha1": "7c562342e3f7b138dc978495447e3e6a96c2cf45", + "size": 54876, + "url": "https://launcher.mojang.com/v1/objects/7c562342e3f7b138dc978495447e3e6a96c2cf45/libzip.so" + }, + "raw": { + "sha1": "5f4bf35a5c3e8f8c650e891d1031589b8ab6d77f", + "size": 127016, + "url": "https://launcher.mojang.com/v1/objects/5f4bf35a5c3e8f8c650e891d1031589b8ab6d77f/libzip.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/amd64/server": { + "type": "directory" + }, + "lib/amd64/server/Xusage.txt": { + "downloads": { + "lzma": { + "sha1": "acb2da24a4c765887df83985e4c26d6be302a0a3", + "size": 629, + "url": "https://launcher.mojang.com/v1/objects/acb2da24a4c765887df83985e4c26d6be302a0a3/Xusage.txt" + }, + "raw": { + "sha1": "6983727eafe140f9dd793c78aa6f3e007438243a", + "size": 1423, + "url": "https://launcher.mojang.com/v1/objects/6983727eafe140f9dd793c78aa6f3e007438243a/Xusage.txt" + } + }, + "executable": false, + "type": "file" + }, + "lib/amd64/server/libjsig.so": { + "target": "../libjsig.so", + "type": "link" + }, + "lib/amd64/server/libjvm.so": { + "downloads": { + "lzma": { + "sha1": "d5c6f3338aaa6712f79d680ac8c3e31beebaa886", + "size": 4154311, + "url": "https://launcher.mojang.com/v1/objects/d5c6f3338aaa6712f79d680ac8c3e31beebaa886/libjvm.so" + }, + "raw": { + "sha1": "23a98e1eb505cc3fb91bc0cb2adb71ab9270e9ca", + "size": 17045016, + "url": "https://launcher.mojang.com/v1/objects/23a98e1eb505cc3fb91bc0cb2adb71ab9270e9ca/libjvm.so" + } + }, + "executable": true, + "type": "file" + }, + "lib/applet": { + "type": "directory" + }, + "lib/calendars.properties": { + "downloads": { + "lzma": { + "sha1": "4a757c23f2942bd802a4f80235131146d9267750", + "size": 558, + "url": "https://launcher.mojang.com/v1/objects/4a757c23f2942bd802a4f80235131146d9267750/calendars.properties" + }, + "raw": { + "sha1": "42ebb0988124433b8f2a6e5d9a74ed41240bcfc6", + "size": 1378, + "url": "https://launcher.mojang.com/v1/objects/42ebb0988124433b8f2a6e5d9a74ed41240bcfc6/calendars.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/charsets.jar": { + "downloads": { + "lzma": { + "sha1": "2bf44143b2ad9d7d55045a4de4a562330c194dc0", + "size": 412367, + "url": "https://launcher.mojang.com/v1/objects/2bf44143b2ad9d7d55045a4de4a562330c194dc0/charsets.jar" + }, + "raw": { + "sha1": "d73ab9f8de255a7e112ddd13622bf7f6b18c8447", + "size": 3135615, + "url": "https://launcher.mojang.com/v1/objects/d73ab9f8de255a7e112ddd13622bf7f6b18c8447/charsets.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/classlist": { + "downloads": { + "lzma": { + "sha1": "14e7c73d21b8513b0aff8d86e5cb34c52021fbca", + "size": 15024, + "url": "https://launcher.mojang.com/v1/objects/14e7c73d21b8513b0aff8d86e5cb34c52021fbca/classlist" + }, + "raw": { + "sha1": "9c0404b63c87e2fed35e3a6cd137d6cf876c42bd", + "size": 84311, + "url": "https://launcher.mojang.com/v1/objects/9c0404b63c87e2fed35e3a6cd137d6cf876c42bd/classlist" + } + }, + "executable": false, + "type": "file" + }, + "lib/cmm": { + "type": "directory" + }, + "lib/cmm/CIEXYZ.pf": { + "downloads": { + "lzma": { + "sha1": "fcc5ca2fd3f45cac3434b480fa3ce00007e96529", + "size": 8964, + "url": "https://launcher.mojang.com/v1/objects/fcc5ca2fd3f45cac3434b480fa3ce00007e96529/CIEXYZ.pf" + }, + "raw": { + "sha1": "b7779924c70554647b87c2a86159ca7781e929f8", + "size": 51236, + "url": "https://launcher.mojang.com/v1/objects/b7779924c70554647b87c2a86159ca7781e929f8/CIEXYZ.pf" + } + }, + "executable": false, + "type": "file" + }, + "lib/cmm/GRAY.pf": { + "downloads": { + "lzma": { + "sha1": "5388ccfe67d3131d6d02143d8e8895003ab14ff6", + "size": 299, + "url": "https://launcher.mojang.com/v1/objects/5388ccfe67d3131d6d02143d8e8895003ab14ff6/GRAY.pf" + }, + "raw": { + "sha1": "27f93961d66b8230d0cdb8b166bc8b4153d5bc2d", + "size": 632, + "url": "https://launcher.mojang.com/v1/objects/27f93961d66b8230d0cdb8b166bc8b4153d5bc2d/GRAY.pf" + } + }, + "executable": false, + "type": "file" + }, + "lib/cmm/LINEAR_RGB.pf": { + "downloads": { + "lzma": { + "sha1": "2bd90f09c8deb64b1729d6b8173c78f9e9cab27b", + "size": 678, + "url": "https://launcher.mojang.com/v1/objects/2bd90f09c8deb64b1729d6b8173c78f9e9cab27b/LINEAR_RGB.pf" + }, + "raw": { + "sha1": "7913274c2f73bafcf888f09ff60990b100214ede", + "size": 1044, + "url": "https://launcher.mojang.com/v1/objects/7913274c2f73bafcf888f09ff60990b100214ede/LINEAR_RGB.pf" + } + }, + "executable": false, + "type": "file" + }, + "lib/cmm/PYCC.pf": { + "downloads": { + "lzma": { + "sha1": "dbb2197ecff3fcdd142e9006490c8cb5c8d19af8", + "size": 171521, + "url": "https://launcher.mojang.com/v1/objects/dbb2197ecff3fcdd142e9006490c8cb5c8d19af8/PYCC.pf" + }, + "raw": { + "sha1": "4f7eed05b8f0eea7bcdc8f8f7aaeb1925ce7b144", + "size": 274474, + "url": "https://launcher.mojang.com/v1/objects/4f7eed05b8f0eea7bcdc8f8f7aaeb1925ce7b144/PYCC.pf" + } + }, + "executable": false, + "type": "file" + }, + "lib/cmm/sRGB.pf": { + "downloads": { + "raw": { + "sha1": "9eaea0911d89d63e39e95f2e2116eaec7e0bb91e", + "size": 3144, + "url": "https://launcher.mojang.com/v1/objects/9eaea0911d89d63e39e95f2e2116eaec7e0bb91e/sRGB.pf" + } + }, + "executable": false, + "type": "file" + }, + "lib/content-types.properties": { + "downloads": { + "lzma": { + "sha1": "43a23d9a6c637c128b14cfa3feced93cbcf85b1a", + "size": 1617, + "url": "https://launcher.mojang.com/v1/objects/43a23d9a6c637c128b14cfa3feced93cbcf85b1a/content-types.properties" + }, + "raw": { + "sha1": "b21698017c4a2866b5fabe59681b7592e72c83b1", + "size": 5916, + "url": "https://launcher.mojang.com/v1/objects/b21698017c4a2866b5fabe59681b7592e72c83b1/content-types.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/currency.data": { + "downloads": { + "lzma": { + "sha1": "451b3f166ea34ef2aefbb01606ea5adcc0d65b42", + "size": 1184, + "url": "https://launcher.mojang.com/v1/objects/451b3f166ea34ef2aefbb01606ea5adcc0d65b42/currency.data" + }, + "raw": { + "sha1": "bf524381a7a9b9d5bbab48069c583d2936e367a1", + "size": 4134, + "url": "https://launcher.mojang.com/v1/objects/bf524381a7a9b9d5bbab48069c583d2936e367a1/currency.data" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy": { + "type": "directory" + }, + "lib/deploy.jar": { + "downloads": { + "raw": { + "sha1": "fbe1de8fcd9a3d482c59414dce9311e4194766c9", + "size": 2255881, + "url": "https://launcher.mojang.com/v1/objects/fbe1de8fcd9a3d482c59414dce9311e4194766c9/deploy.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/MixedCodeMainDialog.ui": { + "downloads": { + "lzma": { + "sha1": "7d812964343d1e978442f5c847c709784fc18fc0", + "size": 683, + "url": "https://launcher.mojang.com/v1/objects/7d812964343d1e978442f5c847c709784fc18fc0/MixedCodeMainDialog.ui" + }, + "raw": { + "sha1": "c9b1af1c229e54b2d8a3d642d4f0bb31dc15be79", + "size": 4507, + "url": "https://launcher.mojang.com/v1/objects/c9b1af1c229e54b2d8a3d642d4f0bb31dc15be79/MixedCodeMainDialog.ui" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/MixedCodeMainDialogJs.ui": { + "downloads": { + "lzma": { + "sha1": "54fb58dbcc59e35e0ae896d0e266ae0c5bcf85c2", + "size": 792, + "url": "https://launcher.mojang.com/v1/objects/54fb58dbcc59e35e0ae896d0e266ae0c5bcf85c2/MixedCodeMainDialogJs.ui" + }, + "raw": { + "sha1": "ad6337fb6d46750e14c12b439a5856f4b6864d0d", + "size": 6110, + "url": "https://launcher.mojang.com/v1/objects/ad6337fb6d46750e14c12b439a5856f4b6864d0d/MixedCodeMainDialogJs.ui" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/cautionshield.icns": { + "downloads": { + "lzma": { + "sha1": "7cea751dc168605054ec38ce8bfa71812be405c1", + "size": 2333, + "url": "https://launcher.mojang.com/v1/objects/7cea751dc168605054ec38ce8bfa71812be405c1/cautionshield.icns" + }, + "raw": { + "sha1": "1de7ed5d5fc75aa1bcede088c655bee3bde64c38", + "size": 3588, + "url": "https://launcher.mojang.com/v1/objects/1de7ed5d5fc75aa1bcede088c655bee3bde64c38/cautionshield.icns" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/ffjcext.zip": { + "downloads": { + "lzma": { + "sha1": "80bcb9b3794f69d87dba93e90230f288e651e798", + "size": 1809, + "url": "https://launcher.mojang.com/v1/objects/80bcb9b3794f69d87dba93e90230f288e651e798/ffjcext.zip" + }, + "raw": { + "sha1": "76d051ca7d3666ff25ea8eb9957a05574a45287f", + "size": 13454, + "url": "https://launcher.mojang.com/v1/objects/76d051ca7d3666ff25ea8eb9957a05574a45287f/ffjcext.zip" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/java-icon.ico": { + "downloads": { + "lzma": { + "sha1": "2a24f0207d7ab5976a8b0d92b4b381d49e895c9d", + "size": 8468, + "url": "https://launcher.mojang.com/v1/objects/2a24f0207d7ab5976a8b0d92b4b381d49e895c9d/java-icon.ico" + }, + "raw": { + "sha1": "2997ceb26ff49a7d7c5e7a2405b5fb50b62c7914", + "size": 29926, + "url": "https://launcher.mojang.com/v1/objects/2997ceb26ff49a7d7c5e7a2405b5fb50b62c7914/java-icon.ico" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages.properties": { + "downloads": { + "lzma": { + "sha1": "c1e16f80dc0b1f1a591cecf3cbab4ba5e47492f4", + "size": 1225, + "url": "https://launcher.mojang.com/v1/objects/c1e16f80dc0b1f1a591cecf3cbab4ba5e47492f4/messages.properties" + }, + "raw": { + "sha1": "dc52841c708e3c1eb2a044088a43396d1291bb5e", + "size": 2860, + "url": "https://launcher.mojang.com/v1/objects/dc52841c708e3c1eb2a044088a43396d1291bb5e/messages.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_de.properties": { + "downloads": { + "lzma": { + "sha1": "42b42e6e1d2cb2d781f2226bde612ce519b29bc8", + "size": 1394, + "url": "https://launcher.mojang.com/v1/objects/42b42e6e1d2cb2d781f2226bde612ce519b29bc8/messages_de.properties" + }, + "raw": { + "sha1": "d989fe1b8f7904888d5102294ebefd28d932ecdb", + "size": 3306, + "url": "https://launcher.mojang.com/v1/objects/d989fe1b8f7904888d5102294ebefd28d932ecdb/messages_de.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_es.properties": { + "downloads": { + "lzma": { + "sha1": "c4a653e9802ca982e892b45d88c1e259c09e8c8e", + "size": 1404, + "url": "https://launcher.mojang.com/v1/objects/c4a653e9802ca982e892b45d88c1e259c09e8c8e/messages_es.properties" + }, + "raw": { + "sha1": "1b0334b79db481c3a59be6915d5118d760c97baa", + "size": 3600, + "url": "https://launcher.mojang.com/v1/objects/1b0334b79db481c3a59be6915d5118d760c97baa/messages_es.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_fr.properties": { + "downloads": { + "lzma": { + "sha1": "2d8dee07e3f5aab7318a22e169810b216ac44f97", + "size": 1401, + "url": "https://launcher.mojang.com/v1/objects/2d8dee07e3f5aab7318a22e169810b216ac44f97/messages_fr.properties" + }, + "raw": { + "sha1": "69bd2d03c2064f8679de5b4e430ea61b567c69c5", + "size": 3409, + "url": "https://launcher.mojang.com/v1/objects/69bd2d03c2064f8679de5b4e430ea61b567c69c5/messages_fr.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_it.properties": { + "downloads": { + "lzma": { + "sha1": "7c28cdd8d9e34355ba0fc03004c4f64749cae57e", + "size": 1375, + "url": "https://launcher.mojang.com/v1/objects/7c28cdd8d9e34355ba0fc03004c4f64749cae57e/messages_it.properties" + }, + "raw": { + "sha1": "dbe49949308f28540a42ae6cd2ad58afbf615592", + "size": 3223, + "url": "https://launcher.mojang.com/v1/objects/dbe49949308f28540a42ae6cd2ad58afbf615592/messages_it.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_ja.properties": { + "downloads": { + "lzma": { + "sha1": "9a6a4c086e48b9e615b72b6bbebb3c724d178ff4", + "size": 1680, + "url": "https://launcher.mojang.com/v1/objects/9a6a4c086e48b9e615b72b6bbebb3c724d178ff4/messages_ja.properties" + }, + "raw": { + "sha1": "751170a7cdefcb1226604ac3f8196e06a04fd7ac", + "size": 6349, + "url": "https://launcher.mojang.com/v1/objects/751170a7cdefcb1226604ac3f8196e06a04fd7ac/messages_ja.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_ko.properties": { + "downloads": { + "lzma": { + "sha1": "0c57c2ebfa0830f816657a384898487fc492efac", + "size": 1645, + "url": "https://launcher.mojang.com/v1/objects/0c57c2ebfa0830f816657a384898487fc492efac/messages_ko.properties" + }, + "raw": { + "sha1": "bf9e055b5ab138ad6d49769e2b7630b7938848d6", + "size": 5712, + "url": "https://launcher.mojang.com/v1/objects/bf9e055b5ab138ad6d49769e2b7630b7938848d6/messages_ko.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_pt_BR.properties": { + "downloads": { + "lzma": { + "sha1": "f8364dba0aa0a7e445a1a8d0e7ad66b996f70063", + "size": 1388, + "url": "https://launcher.mojang.com/v1/objects/f8364dba0aa0a7e445a1a8d0e7ad66b996f70063/messages_pt_BR.properties" + }, + "raw": { + "sha1": "24e4951743521ab9a11381c77bd0cdb1ed30f5b5", + "size": 3285, + "url": "https://launcher.mojang.com/v1/objects/24e4951743521ab9a11381c77bd0cdb1ed30f5b5/messages_pt_BR.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_sv.properties": { + "downloads": { + "lzma": { + "sha1": "65e5897d552258141aacf02f087c7c9c33ad0727", + "size": 1355, + "url": "https://launcher.mojang.com/v1/objects/65e5897d552258141aacf02f087c7c9c33ad0727/messages_sv.properties" + }, + "raw": { + "sha1": "bb5a4aa0ba499f6b1916a83e3c7922a4583b4adb", + "size": 3384, + "url": "https://launcher.mojang.com/v1/objects/bb5a4aa0ba499f6b1916a83e3c7922a4583b4adb/messages_sv.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_zh_CN.properties": { + "downloads": { + "lzma": { + "sha1": "de7d39a6e6748e9f47e842c9da90f515921c222c", + "size": 1506, + "url": "https://launcher.mojang.com/v1/objects/de7d39a6e6748e9f47e842c9da90f515921c222c/messages_zh_CN.properties" + }, + "raw": { + "sha1": "1c2b96673dddd3596890ef4fc22017d484a1f652", + "size": 4072, + "url": "https://launcher.mojang.com/v1/objects/1c2b96673dddd3596890ef4fc22017d484a1f652/messages_zh_CN.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_zh_HK.properties": { + "downloads": { + "lzma": { + "sha1": "e8d0e3a63caa2535a4f361033941f34dcc170a7e", + "size": 1529, + "url": "https://launcher.mojang.com/v1/objects/e8d0e3a63caa2535a4f361033941f34dcc170a7e/messages_zh_TW.properties" + }, + "raw": { + "sha1": "37a57aad121c14c25e149206179728fa62203bf0", + "size": 3752, + "url": "https://launcher.mojang.com/v1/objects/37a57aad121c14c25e149206179728fa62203bf0/messages_zh_TW.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/messages_zh_TW.properties": { + "downloads": { + "lzma": { + "sha1": "e8d0e3a63caa2535a4f361033941f34dcc170a7e", + "size": 1529, + "url": "https://launcher.mojang.com/v1/objects/e8d0e3a63caa2535a4f361033941f34dcc170a7e/messages_zh_TW.properties" + }, + "raw": { + "sha1": "37a57aad121c14c25e149206179728fa62203bf0", + "size": 3752, + "url": "https://launcher.mojang.com/v1/objects/37a57aad121c14c25e149206179728fa62203bf0/messages_zh_TW.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/mixcode_s.png": { + "downloads": { + "raw": { + "sha1": "4604e9f265eec97bccd0151c3a81afa9e69499e5", + "size": 3115, + "url": "https://launcher.mojang.com/v1/objects/4604e9f265eec97bccd0151c3a81afa9e69499e5/mixcode_s.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/splash.gif": { + "downloads": { + "raw": { + "sha1": "20e7aec75f6d036d504277542e507eb7dc24aae8", + "size": 8590, + "url": "https://launcher.mojang.com/v1/objects/20e7aec75f6d036d504277542e507eb7dc24aae8/splash.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/splash@2x.gif": { + "downloads": { + "raw": { + "sha1": "0ae4a5bda2a6d628fac51462390b503c99509fdc", + "size": 15276, + "url": "https://launcher.mojang.com/v1/objects/0ae4a5bda2a6d628fac51462390b503c99509fdc/splash2x.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/splash_11-lic.gif": { + "downloads": { + "raw": { + "sha1": "8def364e07f40142822df84b5bb4f50846cb5e4e", + "size": 7805, + "url": "https://launcher.mojang.com/v1/objects/8def364e07f40142822df84b5bb4f50846cb5e4e/splash_11-lic.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/deploy/splash_11@2x-lic.gif": { + "downloads": { + "raw": { + "sha1": "d2bff9bbf7920ca743b81a0ee23b0719b4d057ca", + "size": 12250, + "url": "https://launcher.mojang.com/v1/objects/d2bff9bbf7920ca743b81a0ee23b0719b4d057ca/splash_11%402x-lic.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop": { + "type": "directory" + }, + "lib/desktop/applications": { + "type": "directory" + }, + "lib/desktop/applications/sun-java.desktop": { + "downloads": { + "lzma": { + "sha1": "109d1cdf165f38da92da70b403ca940192a7a9a8", + "size": 536, + "url": "https://launcher.mojang.com/v1/objects/109d1cdf165f38da92da70b403ca940192a7a9a8/sun-java.desktop" + }, + "raw": { + "sha1": "d346dfe90505603ce5aff5a3c6c2e4a23d5bd990", + "size": 777, + "url": "https://launcher.mojang.com/v1/objects/d346dfe90505603ce5aff5a3c6c2e4a23d5bd990/sun-java.desktop" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/applications/sun-javaws.desktop": { + "downloads": { + "lzma": { + "sha1": "5e1815e7f83515881e6998584dc6bb02c5bef09a", + "size": 451, + "url": "https://launcher.mojang.com/v1/objects/5e1815e7f83515881e6998584dc6bb02c5bef09a/sun-javaws.desktop" + }, + "raw": { + "sha1": "50ce8e519b836e0f53d58ce1a359d98b6cafdda6", + "size": 619, + "url": "https://launcher.mojang.com/v1/objects/50ce8e519b836e0f53d58ce1a359d98b6cafdda6/sun-javaws.desktop" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/applications/sun_java.desktop": { + "downloads": { + "lzma": { + "sha1": "49ab0ccb54c3be68281d05055bc56a88b1281d3c", + "size": 447, + "url": "https://launcher.mojang.com/v1/objects/49ab0ccb54c3be68281d05055bc56a88b1281d3c/sun_java.desktop" + }, + "raw": { + "sha1": "79120ee8160ad6f3c9b90c2641fb7edf3af96b5d", + "size": 624, + "url": "https://launcher.mojang.com/v1/objects/79120ee8160ad6f3c9b90c2641fb7edf3af96b5d/sun_java.desktop" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/16x16": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/16x16/apps": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/16x16/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "366e7a48e9e4fb92eaeabbcaeb4626122a66cecb", + "size": 417, + "url": "https://launcher.mojang.com/v1/objects/366e7a48e9e4fb92eaeabbcaeb4626122a66cecb/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/16x16/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "366e7a48e9e4fb92eaeabbcaeb4626122a66cecb", + "size": 417, + "url": "https://launcher.mojang.com/v1/objects/366e7a48e9e4fb92eaeabbcaeb4626122a66cecb/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/16x16/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "366e7a48e9e4fb92eaeabbcaeb4626122a66cecb", + "size": 417, + "url": "https://launcher.mojang.com/v1/objects/366e7a48e9e4fb92eaeabbcaeb4626122a66cecb/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/16x16/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/16x16/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "629c48907368ecf32d2395b6459c367f79d84689", + "size": 464, + "url": + "https://launcher.mojang.com/v1/objects/629c48907368ecf32d2395b6459c367f79d84689/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "629c48907368ecf32d2395b6459c367f79d84689", + "size": 464, + "url": + "https://launcher.mojang.com/v1/objects/629c48907368ecf32d2395b6459c367f79d84689/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/16x16/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "629c48907368ecf32d2395b6459c367f79d84689", + "size": 464, + "url": + "https://launcher.mojang.com/v1/objects/629c48907368ecf32d2395b6459c367f79d84689/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/48x48": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/48x48/apps": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/48x48/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "8373482d072684e09830dbdb97a76ea264c9f4e9", + "size": 3451, + "url": "https://launcher.mojang.com/v1/objects/8373482d072684e09830dbdb97a76ea264c9f4e9/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/48x48/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "8373482d072684e09830dbdb97a76ea264c9f4e9", + "size": 3451, + "url": "https://launcher.mojang.com/v1/objects/8373482d072684e09830dbdb97a76ea264c9f4e9/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/48x48/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "8373482d072684e09830dbdb97a76ea264c9f4e9", + "size": 3451, + "url": "https://launcher.mojang.com/v1/objects/8373482d072684e09830dbdb97a76ea264c9f4e9/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/48x48/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/HighContrast/48x48/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "56a4996519f8f3541eba7b7a7a69bcdcd8ed0410", + "size": 2088, + "url": + "https://launcher.mojang.com/v1/objects/56a4996519f8f3541eba7b7a7a69bcdcd8ed0410/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "56a4996519f8f3541eba7b7a7a69bcdcd8ed0410", + "size": 2088, + "url": + "https://launcher.mojang.com/v1/objects/56a4996519f8f3541eba7b7a7a69bcdcd8ed0410/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrast/48x48/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "56a4996519f8f3541eba7b7a7a69bcdcd8ed0410", + "size": 2088, + "url": + "https://launcher.mojang.com/v1/objects/56a4996519f8f3541eba7b7a7a69bcdcd8ed0410/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/16x16": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/16x16/apps": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/16x16/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "bf0995acb94aa794e73c5b971282ff13ffe42793", + "size": 402, + "url": "https://launcher.mojang.com/v1/objects/bf0995acb94aa794e73c5b971282ff13ffe42793/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/16x16/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "bf0995acb94aa794e73c5b971282ff13ffe42793", + "size": 402, + "url": "https://launcher.mojang.com/v1/objects/bf0995acb94aa794e73c5b971282ff13ffe42793/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/16x16/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "bf0995acb94aa794e73c5b971282ff13ffe42793", + "size": 402, + "url": "https://launcher.mojang.com/v1/objects/bf0995acb94aa794e73c5b971282ff13ffe42793/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/16x16/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/16x16/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "1477eceda25e162fcda2e69ee3906091973d8344", + "size": 473, + "url": + "https://launcher.mojang.com/v1/objects/1477eceda25e162fcda2e69ee3906091973d8344/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "1477eceda25e162fcda2e69ee3906091973d8344", + "size": 473, + "url": + "https://launcher.mojang.com/v1/objects/1477eceda25e162fcda2e69ee3906091973d8344/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/16x16/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "1477eceda25e162fcda2e69ee3906091973d8344", + "size": 473, + "url": + "https://launcher.mojang.com/v1/objects/1477eceda25e162fcda2e69ee3906091973d8344/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/48x48": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/48x48/apps": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/48x48/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "413da160dd9899b95f53d4cc11f5ee0550cc6585", + "size": 3410, + "url": "https://launcher.mojang.com/v1/objects/413da160dd9899b95f53d4cc11f5ee0550cc6585/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/48x48/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "413da160dd9899b95f53d4cc11f5ee0550cc6585", + "size": 3410, + "url": "https://launcher.mojang.com/v1/objects/413da160dd9899b95f53d4cc11f5ee0550cc6585/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/48x48/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "413da160dd9899b95f53d4cc11f5ee0550cc6585", + "size": 3410, + "url": "https://launcher.mojang.com/v1/objects/413da160dd9899b95f53d4cc11f5ee0550cc6585/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/48x48/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/HighContrastInverse/48x48/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "d66e04dfa25c196bec2e201547325b79846ab674", + "size": 2085, + "url": + "https://launcher.mojang.com/v1/objects/d66e04dfa25c196bec2e201547325b79846ab674/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "d66e04dfa25c196bec2e201547325b79846ab674", + "size": 2085, + "url": + "https://launcher.mojang.com/v1/objects/d66e04dfa25c196bec2e201547325b79846ab674/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/HighContrastInverse/48x48/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "d66e04dfa25c196bec2e201547325b79846ab674", + "size": 2085, + "url": + "https://launcher.mojang.com/v1/objects/d66e04dfa25c196bec2e201547325b79846ab674/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/16x16": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/16x16/apps": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/16x16/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "f93b7cf0a6d27d664a7f09dab6933b2768536f52", + "size": 519, + "url": "https://launcher.mojang.com/v1/objects/f93b7cf0a6d27d664a7f09dab6933b2768536f52/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/16x16/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "f93b7cf0a6d27d664a7f09dab6933b2768536f52", + "size": 519, + "url": "https://launcher.mojang.com/v1/objects/f93b7cf0a6d27d664a7f09dab6933b2768536f52/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/16x16/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "f93b7cf0a6d27d664a7f09dab6933b2768536f52", + "size": 519, + "url": "https://launcher.mojang.com/v1/objects/f93b7cf0a6d27d664a7f09dab6933b2768536f52/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/16x16/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/16x16/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "0aa1605877280b88de1f1cc3e7e4bdbeed968a73", + "size": 525, + "url": + "https://launcher.mojang.com/v1/objects/0aa1605877280b88de1f1cc3e7e4bdbeed968a73/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "0aa1605877280b88de1f1cc3e7e4bdbeed968a73", + "size": 525, + "url": + "https://launcher.mojang.com/v1/objects/0aa1605877280b88de1f1cc3e7e4bdbeed968a73/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/16x16/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "0aa1605877280b88de1f1cc3e7e4bdbeed968a73", + "size": 525, + "url": + "https://launcher.mojang.com/v1/objects/0aa1605877280b88de1f1cc3e7e4bdbeed968a73/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/48x48": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/48x48/apps": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/48x48/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "1fcf4fd6da61873b5f21b39412da26509734b7cc", + "size": 1507, + "url": "https://launcher.mojang.com/v1/objects/1fcf4fd6da61873b5f21b39412da26509734b7cc/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/48x48/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "1fcf4fd6da61873b5f21b39412da26509734b7cc", + "size": 1507, + "url": "https://launcher.mojang.com/v1/objects/1fcf4fd6da61873b5f21b39412da26509734b7cc/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/48x48/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "1fcf4fd6da61873b5f21b39412da26509734b7cc", + "size": 1507, + "url": "https://launcher.mojang.com/v1/objects/1fcf4fd6da61873b5f21b39412da26509734b7cc/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/48x48/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/LowContrast/48x48/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "e36636b1c04dc283c18adf669b892d54b15d3ee6", + "size": 1948, + "url": + "https://launcher.mojang.com/v1/objects/e36636b1c04dc283c18adf669b892d54b15d3ee6/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "e36636b1c04dc283c18adf669b892d54b15d3ee6", + "size": 1948, + "url": + "https://launcher.mojang.com/v1/objects/e36636b1c04dc283c18adf669b892d54b15d3ee6/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/LowContrast/48x48/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "e36636b1c04dc283c18adf669b892d54b15d3ee6", + "size": 1948, + "url": + "https://launcher.mojang.com/v1/objects/e36636b1c04dc283c18adf669b892d54b15d3ee6/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/16x16": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/16x16/apps": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/16x16/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "e91d05bfe9b889bf8a227908b597cab4630da8f2", + "size": 383, + "url": "https://launcher.mojang.com/v1/objects/e91d05bfe9b889bf8a227908b597cab4630da8f2/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/16x16/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "e91d05bfe9b889bf8a227908b597cab4630da8f2", + "size": 383, + "url": "https://launcher.mojang.com/v1/objects/e91d05bfe9b889bf8a227908b597cab4630da8f2/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/16x16/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "e91d05bfe9b889bf8a227908b597cab4630da8f2", + "size": 383, + "url": "https://launcher.mojang.com/v1/objects/e91d05bfe9b889bf8a227908b597cab4630da8f2/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/16x16/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/16x16/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "d2f6abe8e498aeecb334fb43f63001d34dbf6ea5", + "size": 783, + "url": + "https://launcher.mojang.com/v1/objects/d2f6abe8e498aeecb334fb43f63001d34dbf6ea5/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/16x16/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "d2f6abe8e498aeecb334fb43f63001d34dbf6ea5", + "size": 783, + "url": + "https://launcher.mojang.com/v1/objects/d2f6abe8e498aeecb334fb43f63001d34dbf6ea5/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/16x16/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "d2f6abe8e498aeecb334fb43f63001d34dbf6ea5", + "size": 783, + "url": + "https://launcher.mojang.com/v1/objects/d2f6abe8e498aeecb334fb43f63001d34dbf6ea5/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/48x48": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/48x48/apps": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/48x48/apps/sun-java.png": { + "downloads": { + "raw": { + "sha1": "6c90a38eaada9c32a678a282be18ec5b43a84264", + "size": 1439, + "url": "https://launcher.mojang.com/v1/objects/6c90a38eaada9c32a678a282be18ec5b43a84264/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/48x48/apps/sun-javaws.png": { + "downloads": { + "raw": { + "sha1": "6c90a38eaada9c32a678a282be18ec5b43a84264", + "size": 1439, + "url": "https://launcher.mojang.com/v1/objects/6c90a38eaada9c32a678a282be18ec5b43a84264/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/48x48/apps/sun-jcontrol.png": { + "downloads": { + "raw": { + "sha1": "6c90a38eaada9c32a678a282be18ec5b43a84264", + "size": 1439, + "url": "https://launcher.mojang.com/v1/objects/6c90a38eaada9c32a678a282be18ec5b43a84264/sun-javaws.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/48x48/mimetypes": { + "type": "directory" + }, + "lib/desktop/icons/hicolor/48x48/mimetypes/gnome-mime-application-x-java-archive.png": { + "downloads": { + "raw": { + "sha1": "4d5e6e0c41d1076bc86f3ab157c88a41a5716997", + "size": 3202, + "url": + "https://launcher.mojang.com/v1/objects/4d5e6e0c41d1076bc86f3ab157c88a41a5716997/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/48x48/mimetypes/gnome-mime-application-x-java-jnlp-file.png": { + "downloads": { + "raw": { + "sha1": "4d5e6e0c41d1076bc86f3ab157c88a41a5716997", + "size": 3202, + "url": + "https://launcher.mojang.com/v1/objects/4d5e6e0c41d1076bc86f3ab157c88a41a5716997/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/icons/hicolor/48x48/mimetypes/gnome-mime-text-x-java.png": { + "downloads": { + "raw": { + "sha1": "4d5e6e0c41d1076bc86f3ab157c88a41a5716997", + "size": 3202, + "url": + "https://launcher.mojang.com/v1/objects/4d5e6e0c41d1076bc86f3ab157c88a41a5716997/gnome-mime-application-x-java-archive.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/mime": { + "type": "directory" + }, + "lib/desktop/mime/packages": { + "type": "directory" + }, + "lib/desktop/mime/packages/x-java-archive.xml": { + "downloads": { + "lzma": { + "sha1": "841230729f0a59de2a1071d155d96358232b2ba1", + "size": 591, + "url": "https://launcher.mojang.com/v1/objects/841230729f0a59de2a1071d155d96358232b2ba1/x-java-archive.xml" + }, + "raw": { + "sha1": "b6297fd36efa799312961f95ebf0c85c920d5037", + "size": 1822, + "url": "https://launcher.mojang.com/v1/objects/b6297fd36efa799312961f95ebf0c85c920d5037/x-java-archive.xml" + } + }, + "executable": false, + "type": "file" + }, + "lib/desktop/mime/packages/x-java-jnlp-file.xml": { + "downloads": { + "lzma": { + "sha1": "abf9acbe7c18027c4f036c4e42bb2cf1115525fa", + "size": 302, + "url": "https://launcher.mojang.com/v1/objects/abf9acbe7c18027c4f036c4e42bb2cf1115525fa/x-java-jnlp-file.xml" + }, + "raw": { + "sha1": "72f03da83ddb76c9105f619fcfa4dbdad70e6b30", + "size": 412, + "url": "https://launcher.mojang.com/v1/objects/72f03da83ddb76c9105f619fcfa4dbdad70e6b30/x-java-jnlp-file.xml" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext": { + "type": "directory" + }, + "lib/ext/cldrdata.jar": { + "downloads": { + "raw": { + "sha1": "6cacc961942d3f02a88907aa8f2eaae8e20c95a0", + "size": 3860502, + "url": "https://launcher.mojang.com/v1/objects/6cacc961942d3f02a88907aa8f2eaae8e20c95a0/cldrdata.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/dnsns.jar": { + "downloads": { + "raw": { + "sha1": "93bebdd7514e53ae31d60c5daba673878c8822ec", + "size": 8286, + "url": "https://launcher.mojang.com/v1/objects/93bebdd7514e53ae31d60c5daba673878c8822ec/dnsns.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/jaccess.jar": { + "downloads": { + "raw": { + "sha1": "2f54879df7c29ec67c40d40cfc95c0d4a968bea1", + "size": 44516, + "url": "https://launcher.mojang.com/v1/objects/2f54879df7c29ec67c40d40cfc95c0d4a968bea1/jaccess.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/jfxrt.jar": { + "downloads": { + "lzma": { + "sha1": "a6c5b6a782ba360ada6651f5322dcab88c75711c", + "size": 3374270, + "url": "https://launcher.mojang.com/v1/objects/a6c5b6a782ba360ada6651f5322dcab88c75711c/jfxrt.jar" + }, + "raw": { + "sha1": "1ad7a876f045399c23ee4ab7dee380a04ca2ac08", + "size": 18508094, + "url": "https://launcher.mojang.com/v1/objects/1ad7a876f045399c23ee4ab7dee380a04ca2ac08/jfxrt.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/localedata.jar": { + "downloads": { + "raw": { + "sha1": "0cc9f550d4e410b5aa29dbfd2c1b5c99391c7f70", + "size": 1178926, + "url": "https://launcher.mojang.com/v1/objects/0cc9f550d4e410b5aa29dbfd2c1b5c99391c7f70/localedata.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/meta-index": { + "downloads": { + "lzma": { + "sha1": "1359457529f42bacf495afcb68149ae036442dd9", + "size": 594, + "url": "https://launcher.mojang.com/v1/objects/1359457529f42bacf495afcb68149ae036442dd9/meta-index" + }, + "raw": { + "sha1": "334649c6e2d5d7248211f30855e97cfcb4558851", + "size": 1269, + "url": "https://launcher.mojang.com/v1/objects/334649c6e2d5d7248211f30855e97cfcb4558851/meta-index" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/nashorn.jar": { + "downloads": { + "raw": { + "sha1": "dec5dd17a0f52ae79dfbfb38840bffb8b7a679a5", + "size": 2023869, + "url": "https://launcher.mojang.com/v1/objects/dec5dd17a0f52ae79dfbfb38840bffb8b7a679a5/nashorn.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/sunec.jar": { + "downloads": { + "raw": { + "sha1": "bf1c817820341a246f7130fe046e8310b03d04f6", + "size": 41672, + "url": "https://launcher.mojang.com/v1/objects/bf1c817820341a246f7130fe046e8310b03d04f6/sunec.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/sunjce_provider.jar": { + "downloads": { + "raw": { + "sha1": "bb3494e4b5cb3c3e60da767207731f18b267cb34", + "size": 279326, + "url": "https://launcher.mojang.com/v1/objects/bb3494e4b5cb3c3e60da767207731f18b267cb34/sunjce_provider.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/sunpkcs11.jar": { + "downloads": { + "raw": { + "sha1": "5bb1dedc3344cd3bb86828d4aa8ca82f4a606ed4", + "size": 250218, + "url": "https://launcher.mojang.com/v1/objects/5bb1dedc3344cd3bb86828d4aa8ca82f4a606ed4/sunpkcs11.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/ext/zipfs.jar": { + "downloads": { + "raw": { + "sha1": "37b338f0e8e60d6396f51275130e8110816d7b30", + "size": 68964, + "url": "https://launcher.mojang.com/v1/objects/37b338f0e8e60d6396f51275130e8110816d7b30/zipfs.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/flavormap.properties": { + "downloads": { + "lzma": { + "sha1": "2d5ef19ee77ccfc95c9413eea155cde59a48fadd", + "size": 1541, + "url": "https://launcher.mojang.com/v1/objects/2d5ef19ee77ccfc95c9413eea155cde59a48fadd/flavormap.properties" + }, + "raw": { + "sha1": "4e66e8fe12d7f8b3b0c4e1a1915f329bb1fbf6d2", + "size": 3901, + "url": "https://launcher.mojang.com/v1/objects/4e66e8fe12d7f8b3b0c4e1a1915f329bb1fbf6d2/flavormap.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.RedHat.5.bfc": { + "downloads": { + "lzma": { + "sha1": "5197f6e387f16458b7408134e38b06f20f625e4c", + "size": 795, + "url": "https://launcher.mojang.com/v1/objects/5197f6e387f16458b7408134e38b06f20f625e4c/fontconfig.RedHat.5.bfc" + }, + "raw": { + "sha1": "fb806ada6e68f16a9fe2b726a39d9ef5a835c0c2", + "size": 4532, + "url": "https://launcher.mojang.com/v1/objects/fb806ada6e68f16a9fe2b726a39d9ef5a835c0c2/fontconfig.RedHat.5.bfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.RedHat.5.properties.src": { + "downloads": { + "lzma": { + "sha1": "3897ae198e96e5a687c9c9b218ff5df60c868e0d", + "size": 1089, + "url": + "https://launcher.mojang.com/v1/objects/3897ae198e96e5a687c9c9b218ff5df60c868e0d/fontconfig.RedHat.5.properties.src" + }, + "raw": { + "sha1": "c67d1a06cb37b66e69560c9f5e4be7cf08af0493", + "size": 8841, + "url": + "https://launcher.mojang.com/v1/objects/c67d1a06cb37b66e69560c9f5e4be7cf08af0493/fontconfig.RedHat.5.properties.src" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.RedHat.6.bfc": { + "downloads": { + "lzma": { + "sha1": "ef2f5d1f8d620be9927db45d3a28bd75777245cb", + "size": 818, + "url": "https://launcher.mojang.com/v1/objects/ef2f5d1f8d620be9927db45d3a28bd75777245cb/fontconfig.RedHat.6.bfc" + }, + "raw": { + "sha1": "9ba3b3e2c621c31d0ef1b2053c80f77419a19965", + "size": 4250, + "url": "https://launcher.mojang.com/v1/objects/9ba3b3e2c621c31d0ef1b2053c80f77419a19965/fontconfig.RedHat.6.bfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.RedHat.6.properties.src": { + "downloads": { + "lzma": { + "sha1": "74f4148f9d7ec3d67bbd724834d478a72cfdb0db", + "size": 1111, + "url": + "https://launcher.mojang.com/v1/objects/74f4148f9d7ec3d67bbd724834d478a72cfdb0db/fontconfig.RedHat.6.properties.src" + }, + "raw": { + "sha1": "768e58d4d314621c38daf9fde6d67119f370acd9", + "size": 8735, + "url": + "https://launcher.mojang.com/v1/objects/768e58d4d314621c38daf9fde6d67119f370acd9/fontconfig.RedHat.6.properties.src" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.SuSE.10.bfc": { + "downloads": { + "lzma": { + "sha1": "d8fe9b1d8d02368dcd452de93024c6f60670eb87", + "size": 1083, + "url": "https://launcher.mojang.com/v1/objects/d8fe9b1d8d02368dcd452de93024c6f60670eb87/fontconfig.SuSE.10.bfc" + }, + "raw": { + "sha1": "ffd0dfbd1553e15b11649a73a0b3f48318138e0d", + "size": 6702, + "url": "https://launcher.mojang.com/v1/objects/ffd0dfbd1553e15b11649a73a0b3f48318138e0d/fontconfig.SuSE.10.bfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.SuSE.10.properties.src": { + "downloads": { + "lzma": { + "sha1": "2c382bd741a9e23114be3da82dee8290ebfca8a9", + "size": 1555, + "url": + "https://launcher.mojang.com/v1/objects/2c382bd741a9e23114be3da82dee8290ebfca8a9/fontconfig.SuSE.10.properties.src" + }, + "raw": { + "sha1": "a38dbdbbc514567b8281e1aea726865f37e97894", + "size": 16772, + "url": + "https://launcher.mojang.com/v1/objects/a38dbdbbc514567b8281e1aea726865f37e97894/fontconfig.SuSE.10.properties.src" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.SuSE.11.bfc": { + "downloads": { + "lzma": { + "sha1": "2b78cbf11289c9858951fea7180696ba3b7176d6", + "size": 1092, + "url": "https://launcher.mojang.com/v1/objects/2b78cbf11289c9858951fea7180696ba3b7176d6/fontconfig.SuSE.11.bfc" + }, + "raw": { + "sha1": "a4d8500fcb47f6327460a95851b1368660da8302", + "size": 7032, + "url": "https://launcher.mojang.com/v1/objects/a4d8500fcb47f6327460a95851b1368660da8302/fontconfig.SuSE.11.bfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.SuSE.11.properties.src": { + "downloads": { + "lzma": { + "sha1": "5c1635803906e2c59d36492dec724dd7ae49a5ab", + "size": 1589, + "url": + "https://launcher.mojang.com/v1/objects/5c1635803906e2c59d36492dec724dd7ae49a5ab/fontconfig.SuSE.11.properties.src" + }, + "raw": { + "sha1": "c4b69589e41a7279a71866a9134213be19cdf88d", + "size": 16781, + "url": + "https://launcher.mojang.com/v1/objects/c4b69589e41a7279a71866a9134213be19cdf88d/fontconfig.SuSE.11.properties.src" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.Turbo.bfc": { + "downloads": { + "lzma": { + "sha1": "1c771325d9ee4af209a3db92294451d58962c7a4", + "size": 822, + "url": "https://launcher.mojang.com/v1/objects/1c771325d9ee4af209a3db92294451d58962c7a4/fontconfig.Turbo.bfc" + }, + "raw": { + "sha1": "f24368deeb85cc9d0781083bc56e773518d72219", + "size": 4668, + "url": "https://launcher.mojang.com/v1/objects/f24368deeb85cc9d0781083bc56e773518d72219/fontconfig.Turbo.bfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.Turbo.properties.src": { + "downloads": { + "lzma": { + "sha1": "7748ffa17e2c8a34754138efa963ba39bd1cbbb3", + "size": 1113, + "url": "https://launcher.mojang.com/v1/objects/7748ffa17e2c8a34754138efa963ba39bd1cbbb3/fontconfig.Turbo.properties.src" + }, + "raw": { + "sha1": "2bb7258bed7ccd4f117e4e5f892c9b13424b0c82", + "size": 9192, + "url": "https://launcher.mojang.com/v1/objects/2bb7258bed7ccd4f117e4e5f892c9b13424b0c82/fontconfig.Turbo.properties.src" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.bfc": { + "downloads": { + "lzma": { + "sha1": "be6d49ee8c64f458c4f0e64254963fec48d25150", + "size": 286, + "url": "https://launcher.mojang.com/v1/objects/be6d49ee8c64f458c4f0e64254963fec48d25150/fontconfig.bfc" + }, + "raw": { + "sha1": "de39b0e19637f58d92a0188122514aa7247ebb5b", + "size": 1678, + "url": "https://launcher.mojang.com/v1/objects/de39b0e19637f58d92a0188122514aa7247ebb5b/fontconfig.bfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/fontconfig.properties.src": { + "downloads": { + "lzma": { + "sha1": "9498d5e00e5401200667687e826e28c60fa60ba4", + "size": 417, + "url": "https://launcher.mojang.com/v1/objects/9498d5e00e5401200667687e826e28c60fa60ba4/fontconfig.properties.src" + }, + "raw": { + "sha1": "3617ff1424fd204415242565541facf862b16eb4", + "size": 1938, + "url": "https://launcher.mojang.com/v1/objects/3617ff1424fd204415242565541facf862b16eb4/fontconfig.properties.src" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts": { + "type": "directory" + }, + "lib/fonts/LucidaBrightDemiBold.ttf": { + "downloads": { + "lzma": { + "sha1": "4f748750831a7719440dff5457f4d207d0f24d21", + "size": 42347, + "url": "https://launcher.mojang.com/v1/objects/4f748750831a7719440dff5457f4d207d0f24d21/LucidaBrightDemiBold.ttf" + }, + "raw": { + "sha1": "b5c97f985639e19a3b712193ee48b55dda581fd1", + "size": 75144, + "url": "https://launcher.mojang.com/v1/objects/b5c97f985639e19a3b712193ee48b55dda581fd1/LucidaBrightDemiBold.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaBrightDemiItalic.ttf": { + "downloads": { + "lzma": { + "sha1": "f82e9a688553c100ecb98412b985807ed56dff5d", + "size": 43119, + "url": "https://launcher.mojang.com/v1/objects/f82e9a688553c100ecb98412b985807ed56dff5d/LucidaBrightDemiItalic.ttf" + }, + "raw": { + "sha1": "1fd1f757febf3e5f5fbb7fbf7a56587a40d57de7", + "size": 75124, + "url": "https://launcher.mojang.com/v1/objects/1fd1f757febf3e5f5fbb7fbf7a56587a40d57de7/LucidaBrightDemiItalic.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaBrightItalic.ttf": { + "downloads": { + "lzma": { + "sha1": "6d630df719271319c3d53f90a3d425118b908266", + "size": 46206, + "url": "https://launcher.mojang.com/v1/objects/6d630df719271319c3d53f90a3d425118b908266/LucidaBrightItalic.ttf" + }, + "raw": { + "sha1": "aa5c037865c563726ecd63d61ca26443589be425", + "size": 80856, + "url": "https://launcher.mojang.com/v1/objects/aa5c037865c563726ecd63d61ca26443589be425/LucidaBrightItalic.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaBrightRegular.ttf": { + "downloads": { + "lzma": { + "sha1": "4b2e31aaec2238b6ecf9f845bad0a1c6d09fbbfe", + "size": 181085, + "url": "https://launcher.mojang.com/v1/objects/4b2e31aaec2238b6ecf9f845bad0a1c6d09fbbfe/LucidaBrightRegular.ttf" + }, + "raw": { + "sha1": "5d7ed564791c900a8786936930ba99385653139c", + "size": 344908, + "url": "https://launcher.mojang.com/v1/objects/5d7ed564791c900a8786936930ba99385653139c/LucidaBrightRegular.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaSansDemiBold.ttf": { + "downloads": { + "lzma": { + "sha1": "079b16dc3c4918ab1f4f760b6dc5e6586c219042", + "size": 173229, + "url": "https://launcher.mojang.com/v1/objects/079b16dc3c4918ab1f4f760b6dc5e6586c219042/LucidaSansDemiBold.ttf" + }, + "raw": { + "sha1": "92b79fefc35e96190250c602a8fed85276b32a95", + "size": 317896, + "url": "https://launcher.mojang.com/v1/objects/92b79fefc35e96190250c602a8fed85276b32a95/LucidaSansDemiBold.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaSansRegular.ttf": { + "downloads": { + "lzma": { + "sha1": "64a65d7b94d7153d20957ef6d06bebb4dd0f48e4", + "size": 326062, + "url": "https://launcher.mojang.com/v1/objects/64a65d7b94d7153d20957ef6d06bebb4dd0f48e4/LucidaSansRegular.ttf" + }, + "raw": { + "sha1": "39cc8bcb8d4a71d4657fc92ef0b9f4e3e9e67add", + "size": 698236, + "url": "https://launcher.mojang.com/v1/objects/39cc8bcb8d4a71d4657fc92ef0b9f4e3e9e67add/LucidaSansRegular.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaTypewriterBold.ttf": { + "downloads": { + "lzma": { + "sha1": "cdb017f7c34bea0802bc5ea5583aef721ed99c49", + "size": 130412, + "url": "https://launcher.mojang.com/v1/objects/cdb017f7c34bea0802bc5ea5583aef721ed99c49/LucidaTypewriterBold.ttf" + }, + "raw": { + "sha1": "a5da2eb49448f461470387c939f0e69119310e0b", + "size": 234068, + "url": "https://launcher.mojang.com/v1/objects/a5da2eb49448f461470387c939f0e69119310e0b/LucidaTypewriterBold.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/LucidaTypewriterRegular.ttf": { + "downloads": { + "lzma": { + "sha1": "aeda4a09a53783b0dc97de8e20071bea874cbfe5", + "size": 135184, + "url": "https://launcher.mojang.com/v1/objects/aeda4a09a53783b0dc97de8e20071bea874cbfe5/LucidaTypewriterRegular.ttf" + }, + "raw": { + "sha1": "c144dcafe4faf2e79cfd74d8134a631f30234db1", + "size": 242700, + "url": "https://launcher.mojang.com/v1/objects/c144dcafe4faf2e79cfd74d8134a631f30234db1/LucidaTypewriterRegular.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/fonts/fonts.dir": { + "downloads": { + "lzma": { + "sha1": "68f2dd93b215ec8b8d9409d2b9c825632c6b907d", + "size": 273, + "url": "https://launcher.mojang.com/v1/objects/68f2dd93b215ec8b8d9409d2b9c825632c6b907d/fonts.dir" + }, + "raw": { + "sha1": "97f40cca185c954adf5cc582345a7cb8e4c50578", + "size": 4041, + "url": "https://launcher.mojang.com/v1/objects/97f40cca185c954adf5cc582345a7cb8e4c50578/fonts.dir" + } + }, + "executable": false, + "type": "file" + }, + "lib/hijrah-config-umalqura.properties": { + "downloads": { + "lzma": { + "sha1": "02e8d296e3b18a450f1ed1547cbf2b7275664c9a", + "size": 1969, + "url": + "https://launcher.mojang.com/v1/objects/02e8d296e3b18a450f1ed1547cbf2b7275664c9a/hijrah-config-umalqura.properties" + }, + "raw": { + "sha1": "84aa425100740722e91f4725caf849e7863d12ba", + "size": 13962, + "url": + "https://launcher.mojang.com/v1/objects/84aa425100740722e91f4725caf849e7863d12ba/hijrah-config-umalqura.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/images": { + "type": "directory" + }, + "lib/images/cursors": { + "type": "directory" + }, + "lib/images/cursors/cursors.properties": { + "downloads": { + "lzma": { + "sha1": "612bd0f610ee1023947c4a2a8d3fc7d6f97e7d8f", + "size": 385, + "url": "https://launcher.mojang.com/v1/objects/612bd0f610ee1023947c4a2a8d3fc7d6f97e7d8f/cursors.properties" + }, + "raw": { + "sha1": "f2b9a22ddd0a77869497a64f28f07e89a7d41f48", + "size": 1274, + "url": "https://launcher.mojang.com/v1/objects/f2b9a22ddd0a77869497a64f28f07e89a7d41f48/cursors.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/invalid32x32.gif": { + "downloads": { + "raw": { + "sha1": "259edc45b4569427e8319895a444f4295d54348f", + "size": 153, + "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/motif_CopyDrop32x32.gif": { + "downloads": { + "raw": { + "sha1": "eb7620fae702172aa663a19d170a0b929d3b11d1", + "size": 158, + "url": "https://launcher.mojang.com/v1/objects/eb7620fae702172aa663a19d170a0b929d3b11d1/motif_CopyDrop32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/motif_CopyNoDrop32x32.gif": { + "downloads": { + "raw": { + "sha1": "259edc45b4569427e8319895a444f4295d54348f", + "size": 153, + "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/motif_LinkDrop32x32.gif": { + "downloads": { + "raw": { + "sha1": "9699137f990c240e714481563181069c8f6c17bb", + "size": 162, + "url": "https://launcher.mojang.com/v1/objects/9699137f990c240e714481563181069c8f6c17bb/motif_LinkDrop32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/motif_LinkNoDrop32x32.gif": { + "downloads": { + "raw": { + "sha1": "259edc45b4569427e8319895a444f4295d54348f", + "size": 153, + "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/motif_MoveDrop32x32.gif": { + "downloads": { + "raw": { + "sha1": "03c1617ce3c5ab8af03e46d30a8c8f31ab57fb1b", + "size": 141, + "url": "https://launcher.mojang.com/v1/objects/03c1617ce3c5ab8af03e46d30a8c8f31ab57fb1b/motif_MoveDrop32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/cursors/motif_MoveNoDrop32x32.gif": { + "downloads": { + "raw": { + "sha1": "259edc45b4569427e8319895a444f4295d54348f", + "size": 153, + "url": "https://launcher.mojang.com/v1/objects/259edc45b4569427e8319895a444f4295d54348f/invalid32x32.gif" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/icons": { + "type": "directory" + }, + "lib/images/icons/sun-java.png": { + "downloads": { + "raw": { + "sha1": "d101b693aa054f51097eebdfeed8b8a6ca7b55b8", + "size": 4707, + "url": "https://launcher.mojang.com/v1/objects/d101b693aa054f51097eebdfeed8b8a6ca7b55b8/sun-java.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/icons/sun-java_HighContrast.png": { + "downloads": { + "raw": { + "sha1": "a6b1e418d6b5d03719b96f61f0c5236a60970151", + "size": 3729, + "url": "https://launcher.mojang.com/v1/objects/a6b1e418d6b5d03719b96f61f0c5236a60970151/sun-java_HighContrast.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/icons/sun-java_HighContrastInverse.png": { + "downloads": { + "raw": { + "sha1": "2dda28b9bddc9b5b018e3e8a8b062a99d9b2f887", + "size": 3777, + "url": + "https://launcher.mojang.com/v1/objects/2dda28b9bddc9b5b018e3e8a8b062a99d9b2f887/sun-java_HighContrastInverse.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/images/icons/sun-java_LowContrast.png": { + "downloads": { + "raw": { + "sha1": "7714cc4e894c3626c8da6fe742ed22b2829122d9", + "size": 4012, + "url": "https://launcher.mojang.com/v1/objects/7714cc4e894c3626c8da6fe742ed22b2829122d9/sun-java_LowContrast.png" + } + }, + "executable": false, + "type": "file" + }, + "lib/javafx.properties": { + "downloads": { + "raw": { + "sha1": "49e6b75d109e5fd3f6cbe7cc5fa9a7980796d14d", + "size": 56, + "url": "https://launcher.mojang.com/v1/objects/49e6b75d109e5fd3f6cbe7cc5fa9a7980796d14d/javafx.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/javaws.jar": { + "downloads": { + "raw": { + "sha1": "04fa5ae04ead65b91be5dee575497e49ffd49fe9", + "size": 488118, + "url": "https://launcher.mojang.com/v1/objects/04fa5ae04ead65b91be5dee575497e49ffd49fe9/javaws.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/jce.jar": { + "downloads": { + "raw": { + "sha1": "5460adee09cc5fc8829c0acfc46c34670a7d70a0", + "size": 115646, + "url": "https://launcher.mojang.com/v1/objects/5460adee09cc5fc8829c0acfc46c34670a7d70a0/jce.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/jexec": { + "downloads": { + "lzma": { + "sha1": "2d4323d4e060f8126d026ca6c03b8972aedd2fab", + "size": 3311, + "url": "https://launcher.mojang.com/v1/objects/2d4323d4e060f8126d026ca6c03b8972aedd2fab/jexec" + }, + "raw": { + "sha1": "6aa01f1d8d103974164bcfaea03c04eeeefd7d41", + "size": 13376, + "url": "https://launcher.mojang.com/v1/objects/6aa01f1d8d103974164bcfaea03c04eeeefd7d41/jexec" + } + }, + "executable": true, + "type": "file" + }, + "lib/jfr": { + "type": "directory" + }, + "lib/jfr.jar": { + "downloads": { + "lzma": { + "sha1": "5b9d615c91c72f4fe356d9b4105946679452d1e1", + "size": 137982, + "url": "https://launcher.mojang.com/v1/objects/5b9d615c91c72f4fe356d9b4105946679452d1e1/jfr.jar" + }, + "raw": { + "sha1": "0f3fd66a336703d935bdc22ad8082bc51d34e534", + "size": 560713, + "url": "https://launcher.mojang.com/v1/objects/0f3fd66a336703d935bdc22ad8082bc51d34e534/jfr.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/jfr/default.jfc": { + "downloads": { + "lzma": { + "sha1": "373ddd878146dd8ce8991c2c5115a05a82859bdb", + "size": 2207, + "url": "https://launcher.mojang.com/v1/objects/373ddd878146dd8ce8991c2c5115a05a82859bdb/default.jfc" + }, + "raw": { + "sha1": "1a64b68d0e7d43f8149faba94440be54f4f24527", + "size": 20109, + "url": "https://launcher.mojang.com/v1/objects/1a64b68d0e7d43f8149faba94440be54f4f24527/default.jfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/jfr/profile.jfc": { + "downloads": { + "lzma": { + "sha1": "3dcdc5feee3ccfb66bc8726b666944cd4bdadae3", + "size": 2199, + "url": "https://launcher.mojang.com/v1/objects/3dcdc5feee3ccfb66bc8726b666944cd4bdadae3/profile.jfc" + }, + "raw": { + "sha1": "5d7d08a595f76322c51ae43ea966fbba6b69eebe", + "size": 20065, + "url": "https://launcher.mojang.com/v1/objects/5d7d08a595f76322c51ae43ea966fbba6b69eebe/profile.jfc" + } + }, + "executable": false, + "type": "file" + }, + "lib/jfxswt.jar": { + "downloads": { + "raw": { + "sha1": "99d9a264c898d84c01e1c42565e7fe1a89dcd72d", + "size": 33932, + "url": "https://launcher.mojang.com/v1/objects/99d9a264c898d84c01e1c42565e7fe1a89dcd72d/jfxswt.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/jsse.jar": { + "downloads": { + "lzma": { + "sha1": "94a17dfbc2e76cd12c33970a15341424f875a9ce", + "size": 187549, + "url": "https://launcher.mojang.com/v1/objects/94a17dfbc2e76cd12c33970a15341424f875a9ce/jsse.jar" + }, + "raw": { + "sha1": "92c5c626e8a2d16f41272c0e404d4f992dd8310a", + "size": 675599, + "url": "https://launcher.mojang.com/v1/objects/92c5c626e8a2d16f41272c0e404d4f992dd8310a/jsse.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/jvm.hprof.txt": { + "downloads": { + "lzma": { + "sha1": "eccdb240a815b2a83a502749339b27bb8669965b", + "size": 1863, + "url": "https://launcher.mojang.com/v1/objects/eccdb240a815b2a83a502749339b27bb8669965b/jvm.hprof.txt" + }, + "raw": { + "sha1": "fbd61d52534cdd0c15df332114d469c65d001e33", + "size": 4226, + "url": "https://launcher.mojang.com/v1/objects/fbd61d52534cdd0c15df332114d469c65d001e33/jvm.hprof.txt" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale": { + "type": "directory" + }, + "lib/locale/de": { + "type": "directory" + }, + "lib/locale/de/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/de/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "3061d922907cc557208109088fc6ab81d577ff6f", + "size": 970, + "url": "https://launcher.mojang.com/v1/objects/3061d922907cc557208109088fc6ab81d577ff6f/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "5b223a3d723ac1cfce63623fb109f2868d47d1b7", + "size": 2483, + "url": "https://launcher.mojang.com/v1/objects/5b223a3d723ac1cfce63623fb109f2868d47d1b7/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/es": { + "type": "directory" + }, + "lib/locale/es/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/es/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "24338049a89b323e17182b3a3006b50565d4fa0f", + "size": 979, + "url": "https://launcher.mojang.com/v1/objects/24338049a89b323e17182b3a3006b50565d4fa0f/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "6cc63dc97f2fdb2ed799e48b1dc98c4f37cdecc1", + "size": 2477, + "url": "https://launcher.mojang.com/v1/objects/6cc63dc97f2fdb2ed799e48b1dc98c4f37cdecc1/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/fr": { + "type": "directory" + }, + "lib/locale/fr/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/fr/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "22796a48ef39f57d2d6fa70f41308e493d7f05c1", + "size": 1033, + "url": "https://launcher.mojang.com/v1/objects/22796a48ef39f57d2d6fa70f41308e493d7f05c1/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "d9d5b458db6e83fdf85c3526aeee3f57c4929840", + "size": 2746, + "url": "https://launcher.mojang.com/v1/objects/d9d5b458db6e83fdf85c3526aeee3f57c4929840/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/it": { + "type": "directory" + }, + "lib/locale/it/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/it/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "59a4cae38bfb8927745674d0efc2f284bc277987", + "size": 958, + "url": "https://launcher.mojang.com/v1/objects/59a4cae38bfb8927745674d0efc2f284bc277987/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "f6e72e3b2141ccc3dffab10ae14a754e494577ba", + "size": 2434, + "url": "https://launcher.mojang.com/v1/objects/f6e72e3b2141ccc3dffab10ae14a754e494577ba/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/ja": { + "type": "directory" + }, + "lib/locale/ja/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/ja/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "7d6aeed563e1cefcf0224cf522048468088884a9", + "size": 1036, + "url": "https://launcher.mojang.com/v1/objects/7d6aeed563e1cefcf0224cf522048468088884a9/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "378881a8cb8dd2aebb43eacd0c68519be4f258b1", + "size": 2415, + "url": "https://launcher.mojang.com/v1/objects/378881a8cb8dd2aebb43eacd0c68519be4f258b1/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/ko": { + "type": "directory" + }, + "lib/locale/ko.UTF-8": { + "type": "directory" + }, + "lib/locale/ko.UTF-8/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/ko.UTF-8/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "12ee3b21511e8497d95ea0ba9d6fe519227d0b16", + "size": 1069, + "url": "https://launcher.mojang.com/v1/objects/12ee3b21511e8497d95ea0ba9d6fe519227d0b16/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "cb19df01c59662dbe2f4050b1290d374b82fe1fa", + "size": 2753, + "url": "https://launcher.mojang.com/v1/objects/cb19df01c59662dbe2f4050b1290d374b82fe1fa/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/ko/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/ko/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "6e2e47c64c360517fd436bc79c823b5679a1efe6", + "size": 996, + "url": "https://launcher.mojang.com/v1/objects/6e2e47c64c360517fd436bc79c823b5679a1efe6/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "12c8a118d150c78f719314df6dec49a967af71e9", + "size": 2399, + "url": "https://launcher.mojang.com/v1/objects/12c8a118d150c78f719314df6dec49a967af71e9/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/pt_BR": { + "type": "directory" + }, + "lib/locale/pt_BR/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/pt_BR/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "bcaa7e7916493f071f1bf64bf58c6b038e3569c9", + "size": 940, + "url": "https://launcher.mojang.com/v1/objects/bcaa7e7916493f071f1bf64bf58c6b038e3569c9/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "a3bc0c43994c53c59bba94982cf95f6d36283dd0", + "size": 2420, + "url": "https://launcher.mojang.com/v1/objects/a3bc0c43994c53c59bba94982cf95f6d36283dd0/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/sv": { + "type": "directory" + }, + "lib/locale/sv/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/sv/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "76017835d6261fe2eedbcbe5eb08a7484c3080c5", + "size": 946, + "url": "https://launcher.mojang.com/v1/objects/76017835d6261fe2eedbcbe5eb08a7484c3080c5/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "09a47686edec4bbb34e82fbd08559f8bb6266544", + "size": 2359, + "url": "https://launcher.mojang.com/v1/objects/09a47686edec4bbb34e82fbd08559f8bb6266544/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/zh": { + "type": "directory" + }, + "lib/locale/zh.GBK": { + "type": "directory" + }, + "lib/locale/zh.GBK/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/zh.GBK/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "75fd04045bf5890b8bb822770bfdb90a2e9ea65b", + "size": 902, + "url": "https://launcher.mojang.com/v1/objects/75fd04045bf5890b8bb822770bfdb90a2e9ea65b/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "7006fe7767b8807441a1f359a90509b3e507b0d1", + "size": 2002, + "url": "https://launcher.mojang.com/v1/objects/7006fe7767b8807441a1f359a90509b3e507b0d1/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/zh/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/zh/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "75fd04045bf5890b8bb822770bfdb90a2e9ea65b", + "size": 902, + "url": "https://launcher.mojang.com/v1/objects/75fd04045bf5890b8bb822770bfdb90a2e9ea65b/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "7006fe7767b8807441a1f359a90509b3e507b0d1", + "size": 2002, + "url": "https://launcher.mojang.com/v1/objects/7006fe7767b8807441a1f359a90509b3e507b0d1/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/zh_HK.BIG5HK": { + "type": "directory" + }, + "lib/locale/zh_HK.BIG5HK/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/zh_HK.BIG5HK/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "3a1397bb1b1741697be1479232b6d9599940c851", + "size": 912, + "url": "https://launcher.mojang.com/v1/objects/3a1397bb1b1741697be1479232b6d9599940c851/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "c6023544067278c78599921f1032de353ff7da42", + "size": 2025, + "url": "https://launcher.mojang.com/v1/objects/c6023544067278c78599921f1032de353ff7da42/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/zh_TW": { + "type": "directory" + }, + "lib/locale/zh_TW.BIG5": { + "type": "directory" + }, + "lib/locale/zh_TW.BIG5/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/zh_TW.BIG5/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "3a1397bb1b1741697be1479232b6d9599940c851", + "size": 912, + "url": "https://launcher.mojang.com/v1/objects/3a1397bb1b1741697be1479232b6d9599940c851/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "c6023544067278c78599921f1032de353ff7da42", + "size": 2025, + "url": "https://launcher.mojang.com/v1/objects/c6023544067278c78599921f1032de353ff7da42/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/locale/zh_TW/LC_MESSAGES": { + "type": "directory" + }, + "lib/locale/zh_TW/LC_MESSAGES/sunw_java_plugin.mo": { + "downloads": { + "lzma": { + "sha1": "c05e610e75182f0c4e77f3e7a4d9670ed62bf63c", + "size": 897, + "url": "https://launcher.mojang.com/v1/objects/c05e610e75182f0c4e77f3e7a4d9670ed62bf63c/sunw_java_plugin.mo" + }, + "raw": { + "sha1": "f9b972dd059eae3cd337dfcef6a178e8ed8a7db6", + "size": 2025, + "url": "https://launcher.mojang.com/v1/objects/f9b972dd059eae3cd337dfcef6a178e8ed8a7db6/sunw_java_plugin.mo" + } + }, + "executable": false, + "type": "file" + }, + "lib/logging.properties": { + "downloads": { + "lzma": { + "sha1": "642202a58e5216d086ad37c0b5a633be802edc78", + "size": 896, + "url": "https://launcher.mojang.com/v1/objects/642202a58e5216d086ad37c0b5a633be802edc78/logging.properties" + }, + "raw": { + "sha1": "89da8094484891f9ec1fa40c6c8b61f94c5869d0", + "size": 2455, + "url": "https://launcher.mojang.com/v1/objects/89da8094484891f9ec1fa40c6c8b61f94c5869d0/logging.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/management": { + "type": "directory" + }, + "lib/management-agent.jar": { + "downloads": { + "lzma": { + "sha1": "3ea0bf17e14b3428296a0f4011bf4025fcbfa4bd", + "size": 243, + "url": "https://launcher.mojang.com/v1/objects/3ea0bf17e14b3428296a0f4011bf4025fcbfa4bd/management-agent.jar" + }, + "raw": { + "sha1": "9fbed36522aa3a80bac08a328942cbc5ef39ca8e", + "size": 381, + "url": "https://launcher.mojang.com/v1/objects/9fbed36522aa3a80bac08a328942cbc5ef39ca8e/management-agent.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/management/jmxremote.access": { + "downloads": { + "lzma": { + "sha1": "69042ff1b14165db19c9d728614639dec16d6a31", + "size": 1419, + "url": "https://launcher.mojang.com/v1/objects/69042ff1b14165db19c9d728614639dec16d6a31/jmxremote.access" + }, + "raw": { + "sha1": "21200eaad898ba4a2a8834a032efb6616fabb930", + "size": 3998, + "url": "https://launcher.mojang.com/v1/objects/21200eaad898ba4a2a8834a032efb6616fabb930/jmxremote.access" + } + }, + "executable": false, + "type": "file" + }, + "lib/management/jmxremote.password.template": { + "downloads": { + "lzma": { + "sha1": "556c64b1e920766f8867be3964de6e49f5b81a60", + "size": 1129, + "url": "https://launcher.mojang.com/v1/objects/556c64b1e920766f8867be3964de6e49f5b81a60/jmxremote.password.template" + }, + "raw": { + "sha1": "c1e0f01408bf20fbbb8b4810520c725f70050db5", + "size": 2856, + "url": "https://launcher.mojang.com/v1/objects/c1e0f01408bf20fbbb8b4810520c725f70050db5/jmxremote.password.template" + } + }, + "executable": false, + "type": "file" + }, + "lib/management/management.properties": { + "downloads": { + "lzma": { + "sha1": "3e52f9baa6394ca6956845424c607e5cde5d3c67", + "size": 3176, + "url": "https://launcher.mojang.com/v1/objects/3e52f9baa6394ca6956845424c607e5cde5d3c67/management.properties" + }, + "raw": { + "sha1": "e0451d8d7d9e84d7b1c39ec7d00993307a5cbbf1", + "size": 14630, + "url": "https://launcher.mojang.com/v1/objects/e0451d8d7d9e84d7b1c39ec7d00993307a5cbbf1/management.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/management/snmp.acl.template": { + "downloads": { + "lzma": { + "sha1": "9a4aa6396c3b488b0663bed5e5ecb762985669c9", + "size": 1121, + "url": "https://launcher.mojang.com/v1/objects/9a4aa6396c3b488b0663bed5e5ecb762985669c9/snmp.acl.template" + }, + "raw": { + "sha1": "2e9f9ac287274532eb1f0d1afcefd7f3e97cc794", + "size": 3376, + "url": "https://launcher.mojang.com/v1/objects/2e9f9ac287274532eb1f0d1afcefd7f3e97cc794/snmp.acl.template" + } + }, + "executable": false, + "type": "file" + }, + "lib/meta-index": { + "downloads": { + "lzma": { + "sha1": "1ac60b31362fda4725c665b591c5fbe384cbc8c1", + "size": 788, + "url": "https://launcher.mojang.com/v1/objects/1ac60b31362fda4725c665b591c5fbe384cbc8c1/meta-index" + }, + "raw": { + "sha1": "bf204f09242203e713c31785158a0792f9edb600", + "size": 2034, + "url": "https://launcher.mojang.com/v1/objects/bf204f09242203e713c31785158a0792f9edb600/meta-index" + } + }, + "executable": false, + "type": "file" + }, + "lib/net.properties": { + "downloads": { + "lzma": { + "sha1": "e9ec3981a0797bf55bb87b24d9eb651ce7e6916b", + "size": 1830, + "url": "https://launcher.mojang.com/v1/objects/e9ec3981a0797bf55bb87b24d9eb651ce7e6916b/net.properties" + }, + "raw": { + "sha1": "fd9471742eb759f4478bb1de9a0dc0527265b6ea", + "size": 5352, + "url": "https://launcher.mojang.com/v1/objects/fd9471742eb759f4478bb1de9a0dc0527265b6ea/net.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/oblique-fonts": { + "type": "directory" + }, + "lib/oblique-fonts/LucidaSansDemiOblique.ttf": { + "downloads": { + "lzma": { + "sha1": "49c8980c1b89bbdbab59d0f5bd5bebf0afcb93b2", + "size": 38580, + "url": "https://launcher.mojang.com/v1/objects/49c8980c1b89bbdbab59d0f5bd5bebf0afcb93b2/LucidaSansDemiOblique.ttf" + }, + "raw": { + "sha1": "53e4e12a675ac222469341c3dbc102464a1be4c7", + "size": 91352, + "url": "https://launcher.mojang.com/v1/objects/53e4e12a675ac222469341c3dbc102464a1be4c7/LucidaSansDemiOblique.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/oblique-fonts/LucidaSansOblique.ttf": { + "downloads": { + "lzma": { + "sha1": "553123c0edcd08035dede4ffd92b5b81c9a7538a", + "size": 116575, + "url": "https://launcher.mojang.com/v1/objects/553123c0edcd08035dede4ffd92b5b81c9a7538a/LucidaSansOblique.ttf" + }, + "raw": { + "sha1": "95a195ad4fc520b3e395c85b747fc3024d118dd9", + "size": 253724, + "url": "https://launcher.mojang.com/v1/objects/95a195ad4fc520b3e395c85b747fc3024d118dd9/LucidaSansOblique.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/oblique-fonts/LucidaTypewriterBoldOblique.ttf": { + "downloads": { + "lzma": { + "sha1": "2475b08151556ad4d89bb1d2b6494c6bee9abd82", + "size": 29954, + "url": "https://launcher.mojang.com/v1/objects/2475b08151556ad4d89bb1d2b6494c6bee9abd82/LucidaTypewriterBoldOblique.ttf" + }, + "raw": { + "sha1": "f331fc8b0cc494702bc46b690f2b8eed36469a02", + "size": 63168, + "url": "https://launcher.mojang.com/v1/objects/f331fc8b0cc494702bc46b690f2b8eed36469a02/LucidaTypewriterBoldOblique.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/oblique-fonts/LucidaTypewriterOblique.ttf": { + "downloads": { + "lzma": { + "sha1": "5b970bc3b7abb21dce1aa28ff7f03459d351e552", + "size": 60133, + "url": "https://launcher.mojang.com/v1/objects/5b970bc3b7abb21dce1aa28ff7f03459d351e552/LucidaTypewriterOblique.ttf" + }, + "raw": { + "sha1": "f8ea00db73f8a89a27674d050edc37c2280930e1", + "size": 137484, + "url": "https://launcher.mojang.com/v1/objects/f8ea00db73f8a89a27674d050edc37c2280930e1/LucidaTypewriterOblique.ttf" + } + }, + "executable": false, + "type": "file" + }, + "lib/oblique-fonts/fonts.dir": { + "downloads": { + "lzma": { + "sha1": "067528c789bd713c7c3f34e779aa6e2e8253dcf6", + "size": 188, + "url": "https://launcher.mojang.com/v1/objects/067528c789bd713c7c3f34e779aa6e2e8253dcf6/fonts.dir" + }, + "raw": { + "sha1": "5aee54ffba9e33de56fd84ef64fa496b898585bb", + "size": 2115, + "url": "https://launcher.mojang.com/v1/objects/5aee54ffba9e33de56fd84ef64fa496b898585bb/fonts.dir" + } + }, + "executable": false, + "type": "file" + }, + "lib/plugin.jar": { + "downloads": { + "raw": { + "sha1": "3f250842c79112bae5369e372025b166990820e8", + "size": 950772, + "url": "https://launcher.mojang.com/v1/objects/3f250842c79112bae5369e372025b166990820e8/plugin.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/psfont.properties.ja": { + "downloads": { + "lzma": { + "sha1": "7ca1cc244ed251cd1eb2347f1eea37d7d18c8ad4", + "size": 701, + "url": "https://launcher.mojang.com/v1/objects/7ca1cc244ed251cd1eb2347f1eea37d7d18c8ad4/psfont.properties.ja" + }, + "raw": { + "sha1": "56ed1c661eeede17b4fae8c9de7b5edbad387abc", + "size": 2796, + "url": "https://launcher.mojang.com/v1/objects/56ed1c661eeede17b4fae8c9de7b5edbad387abc/psfont.properties.ja" + } + }, + "executable": false, + "type": "file" + }, + "lib/psfontj2d.properties": { + "downloads": { + "lzma": { + "sha1": "4252fa01af8739a3545e2b705e3383892e22ab40", + "size": 2278, + "url": "https://launcher.mojang.com/v1/objects/4252fa01af8739a3545e2b705e3383892e22ab40/psfontj2d.properties" + }, + "raw": { + "sha1": "aa327a22a49967f4d74afeee6726f505f209692f", + "size": 10393, + "url": "https://launcher.mojang.com/v1/objects/aa327a22a49967f4d74afeee6726f505f209692f/psfontj2d.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/resources.jar": { + "downloads": { + "lzma": { + "sha1": "1b0e08441750dc17efe4b527aa146da6cc14e8a6", + "size": 579294, + "url": "https://launcher.mojang.com/v1/objects/1b0e08441750dc17efe4b527aa146da6cc14e8a6/resources.jar" + }, + "raw": { + "sha1": "daa021906e4648d4c37e798c11733dc2047f2da1", + "size": 3505206, + "url": "https://launcher.mojang.com/v1/objects/daa021906e4648d4c37e798c11733dc2047f2da1/resources.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/rt.jar": { + "downloads": { + "lzma": { + "sha1": "fc4a8681aeda29c2a2a3fd11bad7729543283f3d", + "size": 14378994, + "url": "https://launcher.mojang.com/v1/objects/fc4a8681aeda29c2a2a3fd11bad7729543283f3d/rt.jar" + }, + "raw": { + "sha1": "5396b0954a20f3210f1f4f1886ead30880d6ebfe", + "size": 66334986, + "url": "https://launcher.mojang.com/v1/objects/5396b0954a20f3210f1f4f1886ead30880d6ebfe/rt.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/security": { + "type": "directory" + }, + "lib/security/blacklist": { + "downloads": { + "lzma": { + "sha1": "8206fce6c1d91a39fdf78e8e79e953913994a1cd", + "size": 1969, + "url": "https://launcher.mojang.com/v1/objects/8206fce6c1d91a39fdf78e8e79e953913994a1cd/blacklist" + }, + "raw": { + "sha1": "d4ffb3857eab403955ce9d156e46d056061e6a5a", + "size": 4054, + "url": "https://launcher.mojang.com/v1/objects/d4ffb3857eab403955ce9d156e46d056061e6a5a/blacklist" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/blacklisted.certs": { + "downloads": { + "lzma": { + "sha1": "8311bead054caf6cfe678d4b7998de4caaabfa53", + "size": 806, + "url": "https://launcher.mojang.com/v1/objects/8311bead054caf6cfe678d4b7998de4caaabfa53/blacklisted.certs" + }, + "raw": { + "sha1": "c5c005c29a80493f5c31cd7eb629ac1b9c752404", + "size": 1273, + "url": "https://launcher.mojang.com/v1/objects/c5c005c29a80493f5c31cd7eb629ac1b9c752404/blacklisted.certs" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/cacerts": { + "downloads": { + "lzma": { + "sha1": "654dd94809655d5b28385cbb5eba8d6ad9f2c1aa", + "size": 67802, + "url": "https://launcher.mojang.com/v1/objects/654dd94809655d5b28385cbb5eba8d6ad9f2c1aa/cacerts" + }, + "raw": { + "sha1": "2917859c443c68e19f93abcd1315c3c2904cbef9", + "size": 104430, + "url": "https://launcher.mojang.com/v1/objects/2917859c443c68e19f93abcd1315c3c2904cbef9/cacerts" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/java.policy": { + "downloads": { + "lzma": { + "sha1": "b601c420d02ef3dbd8595453d08fdef91134e8b5", + "size": 647, + "url": "https://launcher.mojang.com/v1/objects/b601c420d02ef3dbd8595453d08fdef91134e8b5/java.policy" + }, + "raw": { + "sha1": "c0112209a567b3b523cfed7041709f9440227968", + "size": 2466, + "url": "https://launcher.mojang.com/v1/objects/c0112209a567b3b523cfed7041709f9440227968/java.policy" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/java.security": { + "downloads": { + "lzma": { + "sha1": "531620e82ca0365ce8dc97096bb0ac5a7ace5952", + "size": 10959, + "url": "https://launcher.mojang.com/v1/objects/531620e82ca0365ce8dc97096bb0ac5a7ace5952/java.security" + }, + "raw": { + "sha1": "5dcc17a168c53d0b366784e520bd4d55aa61ac18", + "size": 41528, + "url": "https://launcher.mojang.com/v1/objects/5dcc17a168c53d0b366784e520bd4d55aa61ac18/java.security" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/javaws.policy": { + "downloads": { + "raw": { + "sha1": "4384ca5e4d32f7dd86d8baddd1e690730d74e694", + "size": 98, + "url": "https://launcher.mojang.com/v1/objects/4384ca5e4d32f7dd86d8baddd1e690730d74e694/javaws.policy" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/policy": { + "type": "directory" + }, + "lib/security/policy/limited": { + "type": "directory" + }, + "lib/security/policy/limited/US_export_policy.jar": { + "downloads": { + "raw": { + "sha1": "7d69ea3b385bc067738520f1b5c549e1084be285", + "size": 3026, + "url": "https://launcher.mojang.com/v1/objects/7d69ea3b385bc067738520f1b5c549e1084be285/US_export_policy.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/policy/limited/local_policy.jar": { + "downloads": { + "raw": { + "sha1": "238b8826e110f58acb2e1959773b0a577cd4d569", + "size": 3527, + "url": "https://launcher.mojang.com/v1/objects/238b8826e110f58acb2e1959773b0a577cd4d569/local_policy.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/policy/unlimited": { + "type": "directory" + }, + "lib/security/policy/unlimited/US_export_policy.jar": { + "downloads": { + "raw": { + "sha1": "f6fb2af1e87fc622cda194a7d6b5f5f069653ff1", + "size": 3023, + "url": "https://launcher.mojang.com/v1/objects/f6fb2af1e87fc622cda194a7d6b5f5f069653ff1/US_export_policy.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/policy/unlimited/local_policy.jar": { + "downloads": { + "raw": { + "sha1": "517368ab2cbaf6b42ea0b963f98eeedd996e83e3", + "size": 3035, + "url": "https://launcher.mojang.com/v1/objects/517368ab2cbaf6b42ea0b963f98eeedd996e83e3/local_policy.jar" + } + }, + "executable": false, + "type": "file" + }, + "lib/security/trusted.libraries": { + "downloads": { + "raw": { + "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "size": 0, + "url": "https://launcher.mojang.com/v1/objects/da39a3ee5e6b4b0d3255bfef95601890afd80709/trusted.libraries" + } + }, + "executable": false, + "type": "file" + }, + "lib/sound.properties": { + "downloads": { + "lzma": { + "sha1": "3b5f7e4ec437d79048af35094290577f483b3fe1", + "size": 473, + "url": "https://launcher.mojang.com/v1/objects/3b5f7e4ec437d79048af35094290577f483b3fe1/sound.properties" + }, + "raw": { + "sha1": "9afceb218059d981d0fa9f07aad3c5097cf41b0c", + "size": 1210, + "url": "https://launcher.mojang.com/v1/objects/9afceb218059d981d0fa9f07aad3c5097cf41b0c/sound.properties" + } + }, + "executable": false, + "type": "file" + }, + "lib/tzdb.dat": { + "downloads": { + "lzma": { + "sha1": "39c69339965484afe89c14111baeeb862fdefd97", + "size": 32547, + "url": "https://launcher.mojang.com/v1/objects/39c69339965484afe89c14111baeeb862fdefd97/tzdb.dat" + }, + "raw": { + "sha1": "b59c07e3619271a3b9861e999f4b138e971baf69", + "size": 105734, + "url": "https://launcher.mojang.com/v1/objects/b59c07e3619271a3b9861e999f4b138e971baf69/tzdb.dat" + } + }, + "executable": false, + "type": "file" + }, + "man": { + "type": "directory" + }, + "man/ja": { + "target": "ja_JP.UTF-8", + "type": "link" + }, + "man/ja_JP.UTF-8": { + "type": "directory" + }, + "man/ja_JP.UTF-8/man1": { + "type": "directory" + }, + "man/ja_JP.UTF-8/man1/java.1": { + "downloads": { + "lzma": { + "sha1": "f9da09710b6c6df23c256e324a0c4df00a0d6ded", + "size": 25461, + "url": "https://launcher.mojang.com/v1/objects/f9da09710b6c6df23c256e324a0c4df00a0d6ded/java.1" + }, + "raw": { + "sha1": "b0b12a0bb66e6171771ca4b1dfca32fb759bcaec", + "size": 148688, + "url": "https://launcher.mojang.com/v1/objects/b0b12a0bb66e6171771ca4b1dfca32fb759bcaec/java.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/javaws.1": { + "downloads": { + "lzma": { + "sha1": "6188fae453ca09ccb19be5c9f4d2059926b36267", + "size": 2154, + "url": "https://launcher.mojang.com/v1/objects/6188fae453ca09ccb19be5c9f4d2059926b36267/javaws.1" + }, + "raw": { + "sha1": "8f39d928870268ace07bedfebd18db1e1d07fc37", + "size": 6641, + "url": "https://launcher.mojang.com/v1/objects/8f39d928870268ace07bedfebd18db1e1d07fc37/javaws.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/jjs.1": { + "downloads": { + "lzma": { + "sha1": "6e42b989d28b185dc1aab50c0389834e649a37d4", + "size": 3452, + "url": "https://launcher.mojang.com/v1/objects/6e42b989d28b185dc1aab50c0389834e649a37d4/jjs.1" + }, + "raw": { + "sha1": "e023322a2013912315a2bd1034e6f829a27c76e0", + "size": 11365, + "url": "https://launcher.mojang.com/v1/objects/e023322a2013912315a2bd1034e6f829a27c76e0/jjs.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/keytool.1": { + "downloads": { + "lzma": { + "sha1": "a78134a4bddd53d684a70aa677e51a215db1c9cb", + "size": 20698, + "url": "https://launcher.mojang.com/v1/objects/a78134a4bddd53d684a70aa677e51a215db1c9cb/keytool.1" + }, + "raw": { + "sha1": "148583c837eaaf6333ccfd8c9e8df08574e14b0c", + "size": 111033, + "url": "https://launcher.mojang.com/v1/objects/148583c837eaaf6333ccfd8c9e8df08574e14b0c/keytool.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/orbd.1": { + "downloads": { + "lzma": { + "sha1": "326af0dcbff173ef8aee29163dbe146d7389cc3e", + "size": 4225, + "url": "https://launcher.mojang.com/v1/objects/326af0dcbff173ef8aee29163dbe146d7389cc3e/orbd.1" + }, + "raw": { + "sha1": "95651622d33c08286858ec337edd3ea72acd93dc", + "size": 16092, + "url": "https://launcher.mojang.com/v1/objects/95651622d33c08286858ec337edd3ea72acd93dc/orbd.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/pack200.1": { + "downloads": { + "lzma": { + "sha1": "e0eedafa748c61a44e5be4355fe9d44b05048e80", + "size": 4293, + "url": "https://launcher.mojang.com/v1/objects/e0eedafa748c61a44e5be4355fe9d44b05048e80/pack200.1" + }, + "raw": { + "sha1": "aa21a0ab75707f7fc66e83c7a392e69b37ddf80e", + "size": 14482, + "url": "https://launcher.mojang.com/v1/objects/aa21a0ab75707f7fc66e83c7a392e69b37ddf80e/pack200.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/policytool.1": { + "downloads": { + "lzma": { + "sha1": "3c766ed12dab58166169d35680c392a6be1814a1", + "size": 1380, + "url": "https://launcher.mojang.com/v1/objects/3c766ed12dab58166169d35680c392a6be1814a1/policytool.1" + }, + "raw": { + "sha1": "80879c74e072a98fad6f32b3283331aaf9bd002f", + "size": 4020, + "url": "https://launcher.mojang.com/v1/objects/80879c74e072a98fad6f32b3283331aaf9bd002f/policytool.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/rmid.1": { + "downloads": { + "lzma": { + "sha1": "1e20779d990beacc32a48237777d670fcc47ca14", + "size": 4836, + "url": "https://launcher.mojang.com/v1/objects/1e20779d990beacc32a48237777d670fcc47ca14/rmid.1" + }, + "raw": { + "sha1": "7e40cb8003d098d6e36f45640b26f979ac94b5c5", + "size": 19715, + "url": "https://launcher.mojang.com/v1/objects/7e40cb8003d098d6e36f45640b26f979ac94b5c5/rmid.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/rmiregistry.1": { + "downloads": { + "lzma": { + "sha1": "aaf4ffe07e954f8696eef1ecb7a5e244628d0ad9", + "size": 1627, + "url": "https://launcher.mojang.com/v1/objects/aaf4ffe07e954f8696eef1ecb7a5e244628d0ad9/rmiregistry.1" + }, + "raw": { + "sha1": "c53c52f3ae7a011c135894c9fc51b741e729c33d", + "size": 4557, + "url": "https://launcher.mojang.com/v1/objects/c53c52f3ae7a011c135894c9fc51b741e729c33d/rmiregistry.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/servertool.1": { + "downloads": { + "lzma": { + "sha1": "3b9e624e9d1cf2959b438a35061162e2100ddecd", + "size": 2626, + "url": "https://launcher.mojang.com/v1/objects/3b9e624e9d1cf2959b438a35061162e2100ddecd/servertool.1" + }, + "raw": { + "sha1": "50ab8bcd9dd9d0b1a3d81348fbce1c8f82e7189e", + "size": 9081, + "url": "https://launcher.mojang.com/v1/objects/50ab8bcd9dd9d0b1a3d81348fbce1c8f82e7189e/servertool.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/tnameserv.1": { + "downloads": { + "lzma": { + "sha1": "bb3106ff74c60a76de3d20659b9c2128c70f3bf2", + "size": 4478, + "url": "https://launcher.mojang.com/v1/objects/bb3106ff74c60a76de3d20659b9c2128c70f3bf2/tnameserv.1" + }, + "raw": { + "sha1": "01e714671ecd1167edcb5310b16a9c59c33c3eaa", + "size": 17722, + "url": "https://launcher.mojang.com/v1/objects/01e714671ecd1167edcb5310b16a9c59c33c3eaa/tnameserv.1" + } + }, + "executable": false, + "type": "file" + }, + "man/ja_JP.UTF-8/man1/unpack200.1": { + "downloads": { + "lzma": { + "sha1": "c115a881cf800b08df294df55d9f250ae944e33c", + "size": 1973, + "url": "https://launcher.mojang.com/v1/objects/c115a881cf800b08df294df55d9f250ae944e33c/unpack200.1" + }, + "raw": { + "sha1": "7c882bba0067367a41ad84868d18793b8a7397a3", + "size": 5382, + "url": "https://launcher.mojang.com/v1/objects/7c882bba0067367a41ad84868d18793b8a7397a3/unpack200.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1": { + "type": "directory" + }, + "man/man1/java.1": { + "downloads": { + "lzma": { + "sha1": "06a6b0275c202bf698d73ca71f95618d56d81c15", + "size": 25796, + "url": "https://launcher.mojang.com/v1/objects/06a6b0275c202bf698d73ca71f95618d56d81c15/java.1" + }, + "raw": { + "sha1": "69fec7a341aa91f18dbdcdb95952dede7e1b689a", + "size": 124796, + "url": "https://launcher.mojang.com/v1/objects/69fec7a341aa91f18dbdcdb95952dede7e1b689a/java.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/javaws.1": { + "downloads": { + "lzma": { + "sha1": "4bae251c6dfb5420f56928815cf80d0b6d517a1f", + "size": 1759, + "url": "https://launcher.mojang.com/v1/objects/4bae251c6dfb5420f56928815cf80d0b6d517a1f/javaws.1" + }, + "raw": { + "sha1": "e61e44e101b1bc119c2d2d4b10320f38b36a8036", + "size": 4897, + "url": "https://launcher.mojang.com/v1/objects/e61e44e101b1bc119c2d2d4b10320f38b36a8036/javaws.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/jjs.1": { + "downloads": { + "lzma": { + "sha1": "29683cf2bd47015c9461b688749ddffd95f6671d", + "size": 1881, + "url": "https://launcher.mojang.com/v1/objects/29683cf2bd47015c9461b688749ddffd95f6671d/jjs.1" + }, + "raw": { + "sha1": "78d419bd3a7f3e0802d5220e690429194b5d1beb", + "size": 4932, + "url": "https://launcher.mojang.com/v1/objects/78d419bd3a7f3e0802d5220e690429194b5d1beb/jjs.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/keytool.1": { + "downloads": { + "lzma": { + "sha1": "b67e5126d43713ee3675706724b34061578b42db", + "size": 19690, + "url": "https://launcher.mojang.com/v1/objects/b67e5126d43713ee3675706724b34061578b42db/keytool.1" + }, + "raw": { + "sha1": "4c976f86057ab779763fcfb98f5702ebef47f629", + "size": 86925, + "url": "https://launcher.mojang.com/v1/objects/4c976f86057ab779763fcfb98f5702ebef47f629/keytool.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/orbd.1": { + "downloads": { + "lzma": { + "sha1": "147064d6f7e027002e296bb246ae572d0ce0495b", + "size": 3708, + "url": "https://launcher.mojang.com/v1/objects/147064d6f7e027002e296bb246ae572d0ce0495b/orbd.1" + }, + "raw": { + "sha1": "64201e1846fcf1dcc45c786ffeab89426d1c7742", + "size": 12180, + "url": "https://launcher.mojang.com/v1/objects/64201e1846fcf1dcc45c786ffeab89426d1c7742/orbd.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/pack200.1": { + "downloads": { + "lzma": { + "sha1": "fe17486bbe9c58cf4182fa056b9cd124e8295607", + "size": 3724, + "url": "https://launcher.mojang.com/v1/objects/fe17486bbe9c58cf4182fa056b9cd124e8295607/pack200.1" + }, + "raw": { + "sha1": "26826cf52b89924f2d2a60d6cda798891875eae6", + "size": 11623, + "url": "https://launcher.mojang.com/v1/objects/26826cf52b89924f2d2a60d6cda798891875eae6/pack200.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/policytool.1": { + "downloads": { + "lzma": { + "sha1": "bd154e7c39aca71d15b2098c588866f8d95bc743", + "size": 1122, + "url": "https://launcher.mojang.com/v1/objects/bd154e7c39aca71d15b2098c588866f8d95bc743/policytool.1" + }, + "raw": { + "sha1": "ab296625155d9a2b25ecc2b4feff2f741b3ad136", + "size": 3235, + "url": "https://launcher.mojang.com/v1/objects/ab296625155d9a2b25ecc2b4feff2f741b3ad136/policytool.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/rmid.1": { + "downloads": { + "lzma": { + "sha1": "6a7da234e7f43ebca5c4ba8cd862fda3be62fbaa", + "size": 4255, + "url": "https://launcher.mojang.com/v1/objects/6a7da234e7f43ebca5c4ba8cd862fda3be62fbaa/rmid.1" + }, + "raw": { + "sha1": "6f10e214d7950a6a8460524e41dc700f112f89e5", + "size": 15979, + "url": "https://launcher.mojang.com/v1/objects/6f10e214d7950a6a8460524e41dc700f112f89e5/rmid.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/rmiregistry.1": { + "downloads": { + "lzma": { + "sha1": "f40dd17e3a734600ad1828b0c42d3a1685c4c520", + "size": 1301, + "url": "https://launcher.mojang.com/v1/objects/f40dd17e3a734600ad1828b0c42d3a1685c4c520/rmiregistry.1" + }, + "raw": { + "sha1": "d9a3d23fab689df5bb9a792b88f462f939b49f70", + "size": 3449, + "url": "https://launcher.mojang.com/v1/objects/d9a3d23fab689df5bb9a792b88f462f939b49f70/rmiregistry.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/servertool.1": { + "downloads": { + "lzma": { + "sha1": "74f1e10712202cd3ca0ff5833de05b7ee67092e1", + "size": 2307, + "url": "https://launcher.mojang.com/v1/objects/74f1e10712202cd3ca0ff5833de05b7ee67092e1/servertool.1" + }, + "raw": { + "sha1": "e6c7b510740ac8681a9bfb5f4ee1f0306125b728", + "size": 7237, + "url": "https://launcher.mojang.com/v1/objects/e6c7b510740ac8681a9bfb5f4ee1f0306125b728/servertool.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/tnameserv.1": { + "downloads": { + "lzma": { + "sha1": "4bec7f4e070d023f124f9352a8971d7acd249a15", + "size": 3955, + "url": "https://launcher.mojang.com/v1/objects/4bec7f4e070d023f124f9352a8971d7acd249a15/tnameserv.1" + }, + "raw": { + "sha1": "a31dbbe800d49cb371fab9a4b73d22c3bf8799ad", + "size": 15747, + "url": "https://launcher.mojang.com/v1/objects/a31dbbe800d49cb371fab9a4b73d22c3bf8799ad/tnameserv.1" + } + }, + "executable": false, + "type": "file" + }, + "man/man1/unpack200.1": { + "downloads": { + "lzma": { + "sha1": "f8e73863187929debf2ea6dadefb2995ec7917e7", + "size": 1672, + "url": "https://launcher.mojang.com/v1/objects/f8e73863187929debf2ea6dadefb2995ec7917e7/unpack200.1" + }, + "raw": { + "sha1": "437f7233d738cb9b822e99003127049005663e0f", + "size": 4244, + "url": "https://launcher.mojang.com/v1/objects/437f7233d738cb9b822e99003127049005663e0f/unpack200.1" + } + }, + "executable": false, + "type": "file" + }, + "plugin": { + "type": "directory" + }, + "plugin/desktop": { + "type": "directory" + }, + "plugin/desktop/sun_java.desktop": { + "downloads": { + "lzma": { + "sha1": "49ab0ccb54c3be68281d05055bc56a88b1281d3c", + "size": 447, + "url": "https://launcher.mojang.com/v1/objects/49ab0ccb54c3be68281d05055bc56a88b1281d3c/sun_java.desktop" + }, + "raw": { + "sha1": "79120ee8160ad6f3c9b90c2641fb7edf3af96b5d", + "size": 624, + "url": "https://launcher.mojang.com/v1/objects/79120ee8160ad6f3c9b90c2641fb7edf3af96b5d/sun_java.desktop" + } + }, + "executable": false, + "type": "file" + }, + "plugin/desktop/sun_java.png": { + "downloads": { + "raw": { + "sha1": "699c41e97a35414e72a80327a54d6e14e874e951", + "size": 4351, + "url": "https://launcher.mojang.com/v1/objects/699c41e97a35414e72a80327a54d6e14e874e951/sun_java.png" + } + }, + "executable": false, + "type": "file" + }, + "release": { + "downloads": { + "raw": { + "sha1": "cb462682644c0275d94a45b759108815f3112064", + "size": 424, + "url": "https://launcher.mojang.com/v1/objects/cb462682644c0275d94a45b759108815f3112064/release" + } + }, + "executable": false, + "type": "file" + } + } +} \ No newline at end of file From 39d4f0df66c2981c20e897416db2e8b551c52f03 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 2 Aug 2023 18:54:52 +0200 Subject: [PATCH 422/429] fix: don't reset meta url on launch Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index fd253dabc..3a09ae28e 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -713,7 +713,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QUrl metaUrl(m_settings->get("MetaURLOverride").toString()); // get rid of invalid meta urls - if (!metaUrl.isValid() || metaUrl.scheme() != "http" || metaUrl.scheme() != "https") + if (!metaUrl.isValid() || (metaUrl.scheme() != "http" && metaUrl.scheme() != "https")) m_settings->reset("MetaURLOverride"); } From b013133cc1a66d777c0c16969302e23fb8cd2e16 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:24:47 +0200 Subject: [PATCH 423/429] chore: update to qt 6.5.2 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 c710d54bd..a7b8f652a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: qt_ver: 6 qt_host: windows qt_arch: '' - qt_version: '6.5.1' + qt_version: '6.5.2' qt_modules: 'qt5compat qtimageformats' qt_tools: '' @@ -80,7 +80,7 @@ jobs: qt_ver: 6 qt_host: windows qt_arch: 'win64_msvc2019_arm64' - qt_version: '6.5.1' + qt_version: '6.5.2' qt_modules: 'qt5compat qtimageformats' qt_tools: '' @@ -90,7 +90,7 @@ jobs: qt_ver: 6 qt_host: mac qt_arch: '' - qt_version: '6.5.0' + qt_version: '6.5.2' qt_modules: 'qt5compat qtimageformats' qt_tools: '' From 1d638e018ac40fbfb35dd117f9a948c0cf35eadd Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 4 Aug 2023 19:41:47 +0200 Subject: [PATCH 424/429] chore: update license headers Signed-off-by: Sefa Eyeoglu --- buildconfig/BuildConfig.cpp.in | 2 +- launcher/ApplicationMessage.cpp | 2 +- launcher/BaseInstance.cpp | 2 +- launcher/BaseInstance.h | 2 +- launcher/BaseVersionList.cpp | 2 +- launcher/Commandline.cpp | 2 +- launcher/DesktopServices.cpp | 2 +- launcher/GZip.cpp | 2 +- launcher/InstanceImportTask.cpp | 2 +- launcher/InstanceImportTask.h | 2 +- launcher/InstanceList.cpp | 2 +- launcher/JavaCommon.cpp | 2 +- launcher/Json.cpp | 2 +- launcher/Json.h | 2 +- launcher/LaunchController.cpp | 2 +- launcher/LaunchController.h | 2 +- launcher/NullInstance.h | 2 +- launcher/RuntimeContext.h | 2 +- launcher/Version.h | 2 +- launcher/icons/IconList.cpp | 2 +- launcher/icons/MMCIcon.cpp | 2 +- launcher/java/JavaChecker.cpp | 2 +- launcher/java/JavaUtils.cpp | 2 +- launcher/launch/LaunchTask.cpp | 2 +- launcher/launch/LaunchTask.h | 2 +- launcher/launch/steps/CheckJava.cpp | 2 +- launcher/launch/steps/PostLaunchCommand.cpp | 2 +- launcher/launch/steps/PreLaunchCommand.cpp | 2 +- launcher/launch/steps/QuitAfterGameStop.cpp | 2 +- launcher/launch/steps/QuitAfterGameStop.h | 2 +- launcher/main.cpp | 2 +- launcher/minecraft/AssetsUtils.cpp | 2 +- launcher/minecraft/Component.cpp | 2 +- launcher/minecraft/GradleSpecifier.h | 2 +- launcher/minecraft/LaunchProfile.cpp | 2 +- launcher/minecraft/LaunchProfile.h | 2 +- launcher/minecraft/Library.cpp | 2 +- launcher/minecraft/Library.h | 2 +- launcher/minecraft/MojangVersionFormat.cpp | 2 +- launcher/minecraft/OneSixVersionFormat.cpp | 2 +- launcher/minecraft/ProfileUtils.cpp | 2 +- launcher/minecraft/ProfileUtils.h | 2 +- launcher/minecraft/Rule.cpp | 2 +- launcher/minecraft/Rule.h | 2 +- launcher/minecraft/VersionFile.cpp | 2 +- launcher/minecraft/VersionFile.h | 2 +- launcher/minecraft/WorldList.cpp | 2 +- launcher/minecraft/auth/AccountData.cpp | 2 +- launcher/minecraft/auth/AccountData.h | 2 +- launcher/minecraft/auth/AccountList.cpp | 2 +- launcher/minecraft/auth/AccountList.h | 2 +- launcher/minecraft/auth/AccountTask.cpp | 2 +- launcher/minecraft/auth/AccountTask.h | 2 +- launcher/minecraft/auth/AuthRequest.cpp | 2 +- launcher/minecraft/auth/MinecraftAccount.cpp | 2 +- launcher/minecraft/auth/MinecraftAccount.h | 2 +- launcher/minecraft/auth/steps/MSAStep.cpp | 2 +- launcher/minecraft/auth/steps/MSAStep.h | 2 +- launcher/minecraft/launch/LauncherPartLaunch.cpp | 2 +- launcher/minecraft/launch/ModMinecraftJar.cpp | 2 +- launcher/minecraft/launch/ScanModFolders.cpp | 2 +- launcher/minecraft/launch/VerifyJavaInstall.cpp | 2 +- launcher/minecraft/launch/VerifyJavaInstall.h | 2 +- launcher/minecraft/mod/MetadataHandler.h | 2 +- launcher/minecraft/mod/Mod.cpp | 2 +- launcher/minecraft/mod/Mod.h | 2 +- launcher/minecraft/mod/ModDetails.h | 2 +- launcher/minecraft/mod/ModFolderModel.cpp | 2 +- launcher/minecraft/mod/ModFolderModel.h | 2 +- launcher/minecraft/mod/ResourcePackFolderModel.cpp | 2 +- launcher/minecraft/mod/TexturePack.cpp | 2 +- launcher/minecraft/mod/TexturePack.h | 2 +- launcher/minecraft/mod/TexturePackFolderModel.cpp | 2 +- launcher/minecraft/mod/TexturePackFolderModel.h | 2 +- launcher/minecraft/mod/tasks/LocalModUpdateTask.h | 2 +- launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp | 2 +- launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h | 2 +- launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp | 2 +- launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h | 2 +- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 2 +- launcher/minecraft/mod/tasks/ModFolderLoadTask.h | 2 +- launcher/minecraft/services/CapeChange.cpp | 2 +- launcher/minecraft/services/SkinDelete.cpp | 2 +- launcher/minecraft/services/SkinUpload.cpp | 2 +- launcher/minecraft/update/FoldersTask.cpp | 2 +- launcher/modplatform/ModIndex.cpp | 2 +- launcher/modplatform/ResourceAPI.h | 2 +- launcher/modplatform/atlauncher/ATLPackInstallTask.cpp | 2 +- launcher/modplatform/atlauncher/ATLPackInstallTask.h | 2 +- launcher/modplatform/atlauncher/ATLPackManifest.cpp | 2 +- launcher/modplatform/atlauncher/ATLPackManifest.h | 2 +- launcher/modplatform/atlauncher/ATLShareCode.cpp | 2 +- launcher/modplatform/atlauncher/ATLShareCode.h | 2 +- launcher/modplatform/flame/PackManifest.h | 2 +- launcher/modplatform/legacy_ftb/PackFetchTask.cpp | 2 +- launcher/modplatform/legacy_ftb/PackInstallTask.cpp | 2 +- launcher/modplatform/legacy_ftb/PrivatePackManager.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackIndex.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackIndex.h | 2 +- launcher/modplatform/modrinth/ModrinthPackManifest.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackManifest.h | 2 +- launcher/modplatform/packwiz/Packwiz.cpp | 2 +- launcher/modplatform/packwiz/Packwiz.h | 2 +- launcher/modplatform/technic/SolderPackInstallTask.cpp | 2 +- launcher/modplatform/technic/SolderPackInstallTask.h | 2 +- launcher/modplatform/technic/SolderPackManifest.cpp | 2 +- launcher/modplatform/technic/SolderPackManifest.h | 2 +- launcher/net/ChecksumValidator.h | 2 +- launcher/net/NetUtils.h | 2 +- launcher/net/Sink.h | 2 +- launcher/net/Validator.h | 2 +- launcher/news/NewsChecker.cpp | 2 +- launcher/screenshots/ImgurAlbumCreation.cpp | 2 +- launcher/screenshots/ImgurAlbumCreation.h | 2 +- launcher/screenshots/ImgurUpload.cpp | 2 +- launcher/screenshots/ImgurUpload.h | 2 +- launcher/tasks/Task.cpp | 2 +- launcher/translations/TranslationsModel.cpp | 2 +- launcher/ui/InstanceWindow.cpp | 2 +- launcher/ui/InstanceWindow.h | 2 +- launcher/ui/dialogs/AboutDialog.cpp | 2 +- launcher/ui/dialogs/CopyInstanceDialog.cpp | 2 +- launcher/ui/dialogs/MSALoginDialog.cpp | 2 +- launcher/ui/dialogs/NewComponentDialog.cpp | 2 +- launcher/ui/dialogs/NewInstanceDialog.cpp | 2 +- launcher/ui/dialogs/NewInstanceDialog.h | 2 +- launcher/ui/dialogs/ProfileSetupDialog.cpp | 2 +- launcher/ui/dialogs/SkinUploadDialog.cpp | 2 +- launcher/ui/instanceview/InstanceDelegate.cpp | 2 +- launcher/ui/instanceview/InstanceView.cpp | 2 +- launcher/ui/instanceview/InstanceView.h | 2 +- launcher/ui/pages/BasePage.h | 2 +- launcher/ui/pages/global/APIPage.h | 2 +- launcher/ui/pages/global/AccountListPage.cpp | 2 +- launcher/ui/pages/global/AccountListPage.h | 2 +- launcher/ui/pages/global/CustomCommandsPage.cpp | 2 +- launcher/ui/pages/global/CustomCommandsPage.h | 2 +- launcher/ui/pages/global/ExternalToolsPage.cpp | 2 +- launcher/ui/pages/global/ExternalToolsPage.h | 2 +- launcher/ui/pages/global/JavaPage.cpp | 2 +- launcher/ui/pages/global/JavaPage.h | 2 +- launcher/ui/pages/global/LanguagePage.cpp | 2 +- launcher/ui/pages/global/LanguagePage.h | 2 +- launcher/ui/pages/global/LauncherPage.h | 2 +- launcher/ui/pages/global/MinecraftPage.cpp | 2 +- launcher/ui/pages/global/MinecraftPage.h | 2 +- launcher/ui/pages/global/ProxyPage.cpp | 2 +- launcher/ui/pages/global/ProxyPage.h | 2 +- launcher/ui/pages/instance/GameOptionsPage.cpp | 2 +- launcher/ui/pages/instance/GameOptionsPage.h | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.h | 2 +- launcher/ui/pages/instance/LogPage.h | 2 +- launcher/ui/pages/instance/NotesPage.cpp | 2 +- launcher/ui/pages/instance/NotesPage.h | 2 +- launcher/ui/pages/instance/OtherLogsPage.h | 2 +- launcher/ui/pages/instance/ScreenshotsPage.h | 2 +- launcher/ui/pages/instance/ServersPage.h | 2 +- launcher/ui/pages/instance/WorldListPage.h | 2 +- launcher/ui/pages/modplatform/CustomPage.cpp | 2 +- launcher/ui/pages/modplatform/CustomPage.h | 2 +- launcher/ui/pages/modplatform/ImportPage.cpp | 2 +- launcher/ui/pages/modplatform/ImportPage.h | 2 +- .../ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp | 2 +- launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h | 2 +- launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp | 2 +- launcher/ui/pages/modplatform/atlauncher/AtlPage.h | 2 +- .../modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp | 2 +- .../modplatform/atlauncher/AtlUserInteractionSupportImpl.h | 2 +- launcher/ui/pages/modplatform/flame/FlamePage.cpp | 2 +- launcher/ui/pages/modplatform/flame/FlamePage.h | 2 +- launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp | 2 +- launcher/ui/pages/modplatform/legacy_ftb/Page.cpp | 2 +- launcher/ui/pages/modplatform/legacy_ftb/Page.h | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthModel.h | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthPage.h | 2 +- .../ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h | 2 +- .../ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h | 2 +- launcher/ui/pages/modplatform/technic/TechnicData.h | 2 +- launcher/ui/pages/modplatform/technic/TechnicModel.cpp | 2 +- launcher/ui/pages/modplatform/technic/TechnicModel.h | 2 +- launcher/ui/pages/modplatform/technic/TechnicPage.cpp | 2 +- launcher/ui/pages/modplatform/technic/TechnicPage.h | 2 +- launcher/ui/widgets/CustomCommands.cpp | 2 +- launcher/ui/widgets/CustomCommands.h | 2 +- launcher/ui/widgets/LabeledToolButton.cpp | 2 +- launcher/ui/widgets/LogView.cpp | 2 +- launcher/ui/widgets/PageContainer.cpp | 2 +- launcher/ui/widgets/PageContainer.h | 2 +- launcher/ui/widgets/VariableSizedImageObject.cpp | 2 +- launcher/ui/widgets/VariableSizedImageObject.h | 2 +- launcher/updater/ExternalUpdater.h | 2 +- launcher/updater/MacSparkleUpdater.h | 2 +- launcher/updater/MacSparkleUpdater.mm | 2 +- tests/Library_test.cpp | 2 +- tests/Packwiz_test.cpp | 2 +- tests/ResourceFolderModel_test.cpp | 2 +- tests/ResourcePackParse_test.cpp | 2 +- tests/TexturePackParse_test.cpp | 2 +- 203 files changed, 203 insertions(+), 203 deletions(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 140731fe0..d7662a7a4 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ApplicationMessage.cpp b/launcher/ApplicationMessage.cpp index 8d75ecc8f..50ac10ccc 100644 --- a/launcher/ApplicationMessage.cpp +++ b/launcher/ApplicationMessage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 67fc150a4..70c6da6b3 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield * diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index f0686942d..4357125f3 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield * diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index d817926ef..e11560d5e 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/Commandline.cpp b/launcher/Commandline.cpp index 4fac024ac..8489fb745 100644 --- a/launcher/Commandline.cpp +++ b/launcher/Commandline.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp index d7d2833e9..710487349 100644 --- a/launcher/DesktopServices.cpp +++ b/launcher/DesktopServices.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 dada513 * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/GZip.cpp b/launcher/GZip.cpp index 292fab294..1c2539e08 100644 --- a/launcher/GZip.cpp +++ b/launcher/GZip.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 5624454a3..97e106ba6 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 flowln * diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index 582a9ded0..4459e440c 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index d808676c1..029384091 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index 73bc96a43..e16ac9255 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/Json.cpp b/launcher/Json.cpp index 8db44f062..f397f89c5 100644 --- a/launcher/Json.cpp +++ b/launcher/Json.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/Json.h b/launcher/Json.h index 5a8504ef9..28891f398 100644 --- a/launcher/Json.h +++ b/launcher/Json.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 720f8b91b..380489e06 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/LaunchController.h b/launcher/LaunchController.h index b4138a062..f1c88afb7 100644 --- a/launcher/LaunchController.h +++ b/launcher/LaunchController.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h index 85d8e65e7..a332d4c49 100644 --- a/launcher/NullInstance.h +++ b/launcher/NullInstance.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/RuntimeContext.h b/launcher/RuntimeContext.h index 70e7d0d16..c57140d28 100644 --- a/launcher/RuntimeContext.h +++ b/launcher/RuntimeContext.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/Version.h b/launcher/Version.h index 51162c073..101a907cb 100644 --- a/launcher/Version.h +++ b/launcher/Version.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2023 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/icons/IconList.cpp b/launcher/icons/IconList.cpp index 2e5e1cadf..30c51caf9 100644 --- a/launcher/icons/IconList.cpp +++ b/launcher/icons/IconList.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/icons/MMCIcon.cpp b/launcher/icons/MMCIcon.cpp index 9c1b366c3..8301b1ba9 100644 --- a/launcher/icons/MMCIcon.cpp +++ b/launcher/icons/MMCIcon.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index f3207fdcf..20caba189 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index a44ebca25..3512c3079 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/LaunchTask.cpp b/launcher/launch/LaunchTask.cpp index 902801a10..06a32bd28 100644 --- a/launcher/launch/LaunchTask.cpp +++ b/launcher/launch/LaunchTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/LaunchTask.h b/launcher/launch/LaunchTask.h index 40a3324ba..e79c43557 100644 --- a/launcher/launch/LaunchTask.h +++ b/launcher/launch/LaunchTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index 7fd8fc331..81337a88e 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/steps/PostLaunchCommand.cpp b/launcher/launch/steps/PostLaunchCommand.cpp index 2e59de630..725101224 100644 --- a/launcher/launch/steps/PostLaunchCommand.cpp +++ b/launcher/launch/steps/PostLaunchCommand.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/steps/PreLaunchCommand.cpp b/launcher/launch/steps/PreLaunchCommand.cpp index a7f36086b..6d071a66e 100644 --- a/launcher/launch/steps/PreLaunchCommand.cpp +++ b/launcher/launch/steps/PreLaunchCommand.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/steps/QuitAfterGameStop.cpp b/launcher/launch/steps/QuitAfterGameStop.cpp index f9eced993..389560461 100644 --- a/launcher/launch/steps/QuitAfterGameStop.cpp +++ b/launcher/launch/steps/QuitAfterGameStop.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 dada513 * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/launch/steps/QuitAfterGameStop.h b/launcher/launch/steps/QuitAfterGameStop.h index 5f5e63048..9326b2a8c 100644 --- a/launcher/launch/steps/QuitAfterGameStop.h +++ b/launcher/launch/steps/QuitAfterGameStop.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 dada513 * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/main.cpp b/launcher/main.cpp index 31551f998..35f545f52 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/AssetsUtils.cpp b/launcher/minecraft/AssetsUtils.cpp index 32b48aed8..4923f0efd 100644 --- a/launcher/minecraft/AssetsUtils.cpp +++ b/launcher/minecraft/AssetsUtils.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/Component.cpp b/launcher/minecraft/Component.cpp index 96d67a057..79ea7a06d 100644 --- a/launcher/minecraft/Component.cpp +++ b/launcher/minecraft/Component.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/GradleSpecifier.h b/launcher/minecraft/GradleSpecifier.h index 53c31e8e0..22db7d641 100644 --- a/launcher/minecraft/GradleSpecifier.h +++ b/launcher/minecraft/GradleSpecifier.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/LaunchProfile.cpp b/launcher/minecraft/LaunchProfile.cpp index 013c78ae3..cf819b411 100644 --- a/launcher/minecraft/LaunchProfile.cpp +++ b/launcher/minecraft/LaunchProfile.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/LaunchProfile.h b/launcher/minecraft/LaunchProfile.h index 797631f37..3acc1f192 100644 --- a/launcher/minecraft/LaunchProfile.h +++ b/launcher/minecraft/LaunchProfile.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/Library.cpp b/launcher/minecraft/Library.cpp index 53c285d86..a9c208450 100644 --- a/launcher/minecraft/Library.cpp +++ b/launcher/minecraft/Library.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/Library.h b/launcher/minecraft/Library.h index a24c11215..f8816a97b 100644 --- a/launcher/minecraft/Library.h +++ b/launcher/minecraft/Library.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/MojangVersionFormat.cpp b/launcher/minecraft/MojangVersionFormat.cpp index d7393cf4a..6ee10ec15 100644 --- a/launcher/minecraft/MojangVersionFormat.cpp +++ b/launcher/minecraft/MojangVersionFormat.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 22c2c997c..e24553252 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/ProfileUtils.cpp b/launcher/minecraft/ProfileUtils.cpp index 666ebcfc1..18a4b7d00 100644 --- a/launcher/minecraft/ProfileUtils.cpp +++ b/launcher/minecraft/ProfileUtils.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/ProfileUtils.h b/launcher/minecraft/ProfileUtils.h index 93cc3da07..98a7ff739 100644 --- a/launcher/minecraft/ProfileUtils.h +++ b/launcher/minecraft/ProfileUtils.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/Rule.cpp b/launcher/minecraft/Rule.cpp index 74c12a0d2..d80aab84d 100644 --- a/launcher/minecraft/Rule.cpp +++ b/launcher/minecraft/Rule.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/Rule.h b/launcher/minecraft/Rule.h index 0ece6ae22..483cd936f 100644 --- a/launcher/minecraft/Rule.h +++ b/launcher/minecraft/Rule.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/VersionFile.cpp b/launcher/minecraft/VersionFile.cpp index b8aaee90f..6632bb8bf 100644 --- a/launcher/minecraft/VersionFile.cpp +++ b/launcher/minecraft/VersionFile.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Jamie Mansfield * diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index d8984a29e..280e35ee3 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/WorldList.cpp b/launcher/minecraft/WorldList.cpp index c55742eb7..a7348e570 100644 --- a/launcher/minecraft/WorldList.cpp +++ b/launcher/minecraft/WorldList.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp index b621a68c8..b56f49cbd 100644 --- a/launcher/minecraft/auth/AccountData.cpp +++ b/launcher/minecraft/auth/AccountData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h index 38e3c3c90..9b626c34e 100644 --- a/launcher/minecraft/auth/AccountData.h +++ b/launcher/minecraft/auth/AccountData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 609eaa550..317af714b 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h index 30926d13f..6a0b01916 100644 --- a/launcher/minecraft/auth/AccountList.h +++ b/launcher/minecraft/auth/AccountList.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AccountTask.cpp b/launcher/minecraft/auth/AccountTask.cpp index 896607197..4c3d6ee19 100644 --- a/launcher/minecraft/auth/AccountTask.cpp +++ b/launcher/minecraft/auth/AccountTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AccountTask.h b/launcher/minecraft/auth/AccountTask.h index 68bbfe5fa..82332c0b9 100644 --- a/launcher/minecraft/auth/AccountTask.h +++ b/launcher/minecraft/auth/AccountTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/AuthRequest.cpp b/launcher/minecraft/auth/AuthRequest.cpp index bd48a059d..189978cc0 100644 --- a/launcher/minecraft/auth/AuthRequest.cpp +++ b/launcher/minecraft/auth/AuthRequest.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index e8422a6f3..1dcea2072 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h index 395ca5498..f04f947fa 100644 --- a/launcher/minecraft/auth/MinecraftAccount.h +++ b/launcher/minecraft/auth/MinecraftAccount.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp index 66a9a0e80..1aa22765d 100644 --- a/launcher/minecraft/auth/steps/MSAStep.cpp +++ b/launcher/minecraft/auth/steps/MSAStep.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/auth/steps/MSAStep.h b/launcher/minecraft/auth/steps/MSAStep.h index fc070ff6a..b6635d4a5 100644 --- a/launcher/minecraft/auth/steps/MSAStep.h +++ b/launcher/minecraft/auth/steps/MSAStep.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/launch/LauncherPartLaunch.cpp b/launcher/minecraft/launch/LauncherPartLaunch.cpp index e5f919d79..05562ef2f 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.cpp +++ b/launcher/minecraft/launch/LauncherPartLaunch.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/launch/ModMinecraftJar.cpp b/launcher/minecraft/launch/ModMinecraftJar.cpp index f858dd740..6e73333b1 100644 --- a/launcher/minecraft/launch/ModMinecraftJar.cpp +++ b/launcher/minecraft/launch/ModMinecraftJar.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/launch/ScanModFolders.cpp b/launcher/minecraft/launch/ScanModFolders.cpp index 04d820668..7e08a4e36 100644 --- a/launcher/minecraft/launch/ScanModFolders.cpp +++ b/launcher/minecraft/launch/ScanModFolders.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 03831d175..cdd1f7fd1 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/launch/VerifyJavaInstall.h b/launcher/minecraft/launch/VerifyJavaInstall.h index edf6015a3..dabbf3b25 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.h +++ b/launcher/minecraft/launch/VerifyJavaInstall.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index ea9078e04..88e9ff2b6 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 46509cde6..ae3dea8d8 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 51c42028c..ca3ee11fa 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/ModDetails.h b/launcher/minecraft/mod/ModDetails.h index 60099496c..6a15219a2 100644 --- a/launcher/minecraft/mod/ModDetails.h +++ b/launcher/minecraft/mod/ModDetails.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 69028199a..8dbe583da 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index f1f40a817..06fd78149 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index 0e2981eff..70206cb00 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/TexturePack.cpp b/launcher/minecraft/mod/TexturePack.cpp index fbc716c42..7d8c67137 100644 --- a/launcher/minecraft/mod/TexturePack.cpp +++ b/launcher/minecraft/mod/TexturePack.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/TexturePack.h b/launcher/minecraft/mod/TexturePack.h index 577005655..bf4b5b6b4 100644 --- a/launcher/minecraft/mod/TexturePack.h +++ b/launcher/minecraft/mod/TexturePack.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index 869fbe2e5..9a9910faf 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/TexturePackFolderModel.h b/launcher/minecraft/mod/TexturePackFolderModel.h index ccc634da7..b975d8641 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.h +++ b/launcher/minecraft/mod/TexturePackFolderModel.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h index 31f919b84..080999294 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp index 7440e6aa3..73cbf891c 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h index 58d90b3b9..5199bf3f0 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp index 817b0ea9c..887a1062e 100644 --- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h index 6b91565ad..1341590f2 100644 --- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 4a19a8eb4..9f79ba098 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h index 7ce13cfaf..4200ef6d9 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/minecraft/services/CapeChange.cpp b/launcher/minecraft/services/CapeChange.cpp index cb6ed1a41..f87da13e8 100644 --- a/launcher/minecraft/services/CapeChange.cpp +++ b/launcher/minecraft/services/CapeChange.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/services/SkinDelete.cpp b/launcher/minecraft/services/SkinDelete.cpp index 3737a5af8..9e9020692 100644 --- a/launcher/minecraft/services/SkinDelete.cpp +++ b/launcher/minecraft/services/SkinDelete.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/services/SkinUpload.cpp b/launcher/minecraft/services/SkinUpload.cpp index 299608815..163b481b1 100644 --- a/launcher/minecraft/services/SkinUpload.cpp +++ b/launcher/minecraft/services/SkinUpload.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/minecraft/update/FoldersTask.cpp b/launcher/minecraft/update/FoldersTask.cpp index 3cbc309d0..c74e8d2ef 100644 --- a/launcher/minecraft/update/FoldersTask.cpp +++ b/launcher/minecraft/update/FoldersTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index ecea0d8ce..350a9f10b 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index d3277761e..ef220977e 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0 /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 1ac527bc9..f01984812 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h index b82f523fe..ffc358fbb 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/atlauncher/ATLPackManifest.cpp b/launcher/modplatform/atlauncher/ATLPackManifest.cpp index 88d728c22..9ff2f339e 100644 --- a/launcher/modplatform/atlauncher/ATLPackManifest.cpp +++ b/launcher/modplatform/atlauncher/ATLPackManifest.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/atlauncher/ATLPackManifest.h b/launcher/modplatform/atlauncher/ATLPackManifest.h index fec4bb576..8db91087d 100644 --- a/launcher/modplatform/atlauncher/ATLPackManifest.h +++ b/launcher/modplatform/atlauncher/ATLPackManifest.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/atlauncher/ATLShareCode.cpp b/launcher/modplatform/atlauncher/ATLShareCode.cpp index b49631024..800eac538 100644 --- a/launcher/modplatform/atlauncher/ATLShareCode.cpp +++ b/launcher/modplatform/atlauncher/ATLShareCode.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/atlauncher/ATLShareCode.h b/launcher/modplatform/atlauncher/ATLShareCode.h index 69a493f85..531945bce 100644 --- a/launcher/modplatform/atlauncher/ATLShareCode.h +++ b/launcher/modplatform/atlauncher/ATLShareCode.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/flame/PackManifest.h b/launcher/modplatform/flame/PackManifest.h index a608263c6..854cdbc41 100644 --- a/launcher/modplatform/flame/PackManifest.h +++ b/launcher/modplatform/flame/PackManifest.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp index c7db4906e..6d27357a9 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index 1afe57830..91c821f0e 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp b/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp index 7ab5e9d6b..2ae351329 100644 --- a/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp +++ b/launcher/modplatform/legacy_ftb/PrivatePackManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index b40373496..96dafe70c 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index a8d986c57..58a0f227c 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * * 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/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index d4565191a..0d07c6361 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.h b/launcher/modplatform/modrinth/ModrinthPackManifest.h index 1af47cbc0..effa1a84a 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.h +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 510c7309d..1be283787 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 6b13f74a9..7edc18cde 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index 1e2716e90..ad564de00 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021-2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/technic/SolderPackInstallTask.h b/launcher/modplatform/technic/SolderPackInstallTask.h index f2c6a83a4..2ea701e23 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.h +++ b/launcher/modplatform/technic/SolderPackInstallTask.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021-2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/technic/SolderPackManifest.cpp b/launcher/modplatform/technic/SolderPackManifest.cpp index 3d9a2ea11..38b668f6b 100644 --- a/launcher/modplatform/technic/SolderPackManifest.cpp +++ b/launcher/modplatform/technic/SolderPackManifest.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/technic/SolderPackManifest.h b/launcher/modplatform/technic/SolderPackManifest.h index 917b4eefa..1a06d7037 100644 --- a/launcher/modplatform/technic/SolderPackManifest.h +++ b/launcher/modplatform/technic/SolderPackManifest.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/net/ChecksumValidator.h b/launcher/net/ChecksumValidator.h index a2ca2c7a4..dfee0aee5 100644 --- a/launcher/net/ChecksumValidator.h +++ b/launcher/net/ChecksumValidator.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/net/NetUtils.h b/launcher/net/NetUtils.h index afaf7b5f3..cd517bcca 100644 --- a/launcher/net/NetUtils.h +++ b/launcher/net/NetUtils.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/net/Sink.h b/launcher/net/Sink.h index 3870f29bc..fcdabf372 100644 --- a/launcher/net/Sink.h +++ b/launcher/net/Sink.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/net/Validator.h b/launcher/net/Validator.h index 105a233c8..33c4cfee1 100644 --- a/launcher/net/Validator.h +++ b/launcher/net/Validator.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * * 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/news/NewsChecker.cpp b/launcher/news/NewsChecker.cpp index 11ba5311b..33fb7eceb 100644 --- a/launcher/news/NewsChecker.cpp +++ b/launcher/news/NewsChecker.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp index 68eb02ac4..d598d77e2 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/screenshots/ImgurAlbumCreation.h b/launcher/screenshots/ImgurAlbumCreation.h index 9efaed4fe..3a82a956a 100644 --- a/launcher/screenshots/ImgurAlbumCreation.h +++ b/launcher/screenshots/ImgurAlbumCreation.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp index 81aa1f749..706af7ba5 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/screenshots/ImgurUpload.h b/launcher/screenshots/ImgurUpload.h index 084349b22..8714e0c04 100644 --- a/launcher/screenshots/ImgurUpload.h +++ b/launcher/screenshots/ImgurUpload.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index a8097ffd6..b17096ca7 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> * diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index aa204cb72..06d5bfd86 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index 4c54ba26e..9c7886fac 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/InstanceWindow.h b/launcher/ui/InstanceWindow.h index ef9cdf4a5..508bcaa14 100644 --- a/launcher/ui/InstanceWindow.h +++ b/launcher/ui/InstanceWindow.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index bac30b010..3c6f6ef16 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index eac5721e0..0e4100279 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp index f8aab34d9..74fff9fd3 100644 --- a/launcher/ui/dialogs/MSALoginDialog.cpp +++ b/launcher/ui/dialogs/MSALoginDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/NewComponentDialog.cpp b/launcher/ui/dialogs/NewComponentDialog.cpp index 0d90b02e3..b47b85ff1 100644 --- a/launcher/ui/dialogs/NewComponentDialog.cpp +++ b/launcher/ui/dialogs/NewComponentDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index 8fe4c38cd..6e5a41efc 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h index de054cf7a..b348649fe 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.h +++ b/launcher/ui/dialogs/NewInstanceDialog.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/ProfileSetupDialog.cpp b/launcher/ui/dialogs/ProfileSetupDialog.cpp index e203269c3..d7758d6d8 100644 --- a/launcher/ui/dialogs/ProfileSetupDialog.cpp +++ b/launcher/ui/dialogs/ProfileSetupDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/dialogs/SkinUploadDialog.cpp b/launcher/ui/dialogs/SkinUploadDialog.cpp index 10d8089e4..8f0c8fa49 100644 --- a/launcher/ui/dialogs/SkinUploadDialog.cpp +++ b/launcher/ui/dialogs/SkinUploadDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/instanceview/InstanceDelegate.cpp b/launcher/ui/instanceview/InstanceDelegate.cpp index 0d3d1f423..915b41d84 100644 --- a/launcher/ui/instanceview/InstanceDelegate.cpp +++ b/launcher/ui/instanceview/InstanceDelegate.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 5a0450e07..a9442546a 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index 11892b227..3d4d56208 100644 --- a/launcher/ui/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/BasePage.h b/launcher/ui/pages/BasePage.h index dc2bde992..d35206a08 100644 --- a/launcher/ui/pages/BasePage.h +++ b/launcher/ui/pages/BasePage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/APIPage.h b/launcher/ui/pages/global/APIPage.h index 8d8f06454..d4ed92900 100644 --- a/launcher/ui/pages/global/APIPage.h +++ b/launcher/ui/pages/global/APIPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield * Copyright (c) 2022 Lenny McLennington diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index 41e78bf4d..1d5ecb8d1 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield * diff --git a/launcher/ui/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h index 483d7924f..add0f4aa0 100644 --- a/launcher/ui/pages/global/AccountListPage.h +++ b/launcher/ui/pages/global/AccountListPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield * diff --git a/launcher/ui/pages/global/CustomCommandsPage.cpp b/launcher/ui/pages/global/CustomCommandsPage.cpp index fad69050b..cc8518c2f 100644 --- a/launcher/ui/pages/global/CustomCommandsPage.cpp +++ b/launcher/ui/pages/global/CustomCommandsPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/global/CustomCommandsPage.h b/launcher/ui/pages/global/CustomCommandsPage.h index c69b02e5a..ec1204ffe 100644 --- a/launcher/ui/pages/global/CustomCommandsPage.h +++ b/launcher/ui/pages/global/CustomCommandsPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/ExternalToolsPage.cpp b/launcher/ui/pages/global/ExternalToolsPage.cpp index abe157f09..33e9c5388 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.cpp +++ b/launcher/ui/pages/global/ExternalToolsPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/ExternalToolsPage.h b/launcher/ui/pages/global/ExternalToolsPage.h index 0b38b80f9..7248f0c99 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.h +++ b/launcher/ui/pages/global/ExternalToolsPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 775638403..a9ede8ed2 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 64f2a296e..1a1bd96e1 100644 --- a/launcher/ui/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/LanguagePage.cpp b/launcher/ui/pages/global/LanguagePage.cpp index 27af91d84..af6fc1727 100644 --- a/launcher/ui/pages/global/LanguagePage.cpp +++ b/launcher/ui/pages/global/LanguagePage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/global/LanguagePage.h b/launcher/ui/pages/global/LanguagePage.h index ea358851a..ff7ce7ddc 100644 --- a/launcher/ui/pages/global/LanguagePage.h +++ b/launcher/ui/pages/global/LanguagePage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index 238e31bb4..e733224d2 100644 --- a/launcher/ui/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/MinecraftPage.cpp b/launcher/ui/pages/global/MinecraftPage.cpp index 55ad12ac8..866a4121c 100644 --- a/launcher/ui/pages/global/MinecraftPage.cpp +++ b/launcher/ui/pages/global/MinecraftPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2023 seth * diff --git a/launcher/ui/pages/global/MinecraftPage.h b/launcher/ui/pages/global/MinecraftPage.h index a9e2e8024..28c31b5d8 100644 --- a/launcher/ui/pages/global/MinecraftPage.h +++ b/launcher/ui/pages/global/MinecraftPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/ProxyPage.cpp b/launcher/ui/pages/global/ProxyPage.cpp index 931adac52..19b2bcea1 100644 --- a/launcher/ui/pages/global/ProxyPage.cpp +++ b/launcher/ui/pages/global/ProxyPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/global/ProxyPage.h b/launcher/ui/pages/global/ProxyPage.h index 092a11d2f..26118f181 100644 --- a/launcher/ui/pages/global/ProxyPage.h +++ b/launcher/ui/pages/global/ProxyPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/instance/GameOptionsPage.cpp b/launcher/ui/pages/instance/GameOptionsPage.cpp index e90041709..8db392b1d 100644 --- a/launcher/ui/pages/instance/GameOptionsPage.cpp +++ b/launcher/ui/pages/instance/GameOptionsPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/GameOptionsPage.h b/launcher/ui/pages/instance/GameOptionsPage.h index 563bd10ae..a132843e7 100644 --- a/launcher/ui/pages/instance/GameOptionsPage.h +++ b/launcher/ui/pages/instance/GameOptionsPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index d25459d5f..687b82d73 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2023 seth diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index 9f1355939..21ecbaf8e 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/LogPage.h b/launcher/ui/pages/instance/LogPage.h index 33b6cc39f..6c259891d 100644 --- a/launcher/ui/pages/instance/LogPage.h +++ b/launcher/ui/pages/instance/LogPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/NotesPage.cpp b/launcher/ui/pages/instance/NotesPage.cpp index 887bad85a..a86369f87 100644 --- a/launcher/ui/pages/instance/NotesPage.cpp +++ b/launcher/ui/pages/instance/NotesPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/NotesPage.h b/launcher/ui/pages/instance/NotesPage.h index aa6083062..3351d25fc 100644 --- a/launcher/ui/pages/instance/NotesPage.h +++ b/launcher/ui/pages/instance/NotesPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/OtherLogsPage.h b/launcher/ui/pages/instance/OtherLogsPage.h index ecb896fca..4b3b122b0 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.h +++ b/launcher/ui/pages/instance/OtherLogsPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/ScreenshotsPage.h b/launcher/ui/pages/instance/ScreenshotsPage.h index 0f824a056..bb127b429 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.h +++ b/launcher/ui/pages/instance/ScreenshotsPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/instance/ServersPage.h b/launcher/ui/pages/instance/ServersPage.h index 96a8dd7d4..a27d1d297 100644 --- a/launcher/ui/pages/instance/ServersPage.h +++ b/launcher/ui/pages/instance/ServersPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/instance/WorldListPage.h b/launcher/ui/pages/instance/WorldListPage.h index df8b512ff..4f83002f4 100644 --- a/launcher/ui/pages/instance/WorldListPage.h +++ b/launcher/ui/pages/instance/WorldListPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/CustomPage.cpp b/launcher/ui/pages/modplatform/CustomPage.cpp index ae5cae30f..4ac21b012 100644 --- a/launcher/ui/pages/modplatform/CustomPage.cpp +++ b/launcher/ui/pages/modplatform/CustomPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/CustomPage.h b/launcher/ui/pages/modplatform/CustomPage.h index 273a60790..c5d6d5af5 100644 --- a/launcher/ui/pages/modplatform/CustomPage.h +++ b/launcher/ui/pages/modplatform/CustomPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index b7f4d1baf..ba53d0330 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/modplatform/ImportPage.h b/launcher/ui/pages/modplatform/ImportPage.h index 66c452b9f..d846d566d 100644 --- a/launcher/ui/pages/modplatform/ImportPage.h +++ b/launcher/ui/pages/modplatform/ImportPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index 9b0206f98..62e406d38 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h index a23b16539..72a946dad 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp index 6e1e16a2f..4c9dec581 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h index ac336ec10..6bc449649 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp index 9ed75bccf..0c7257859 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h index adeb53cbc..52ced2615 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 4a59a0b2a..b676cad9a 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.h b/launcher/ui/pages/modplatform/flame/FlamePage.h index ad54c13a8..ff5c79750 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.h +++ b/launcher/ui/pages/modplatform/flame/FlamePage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index 330dd4fb8..1731ff2cb 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp index e322419ba..ef8e9892c 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.h b/launcher/ui/pages/modplatform/legacy_ftb/Page.h index 32b4a8146..a12b0745d 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.h +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 9c392fcab..761e265d2 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 47c2d55b4..721c69f55 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index c71dd9038..31b05030c 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index db5e1a3d6..b7054c886 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp index 8aa649898..00a0108aa 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h index d7c858f88..15cd58544 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp index ff809c7bb..616c1a815 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h index 26037f0cd..86ba1ccb2 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0 /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/technic/TechnicData.h b/launcher/ui/pages/modplatform/technic/TechnicData.h index 81488811a..fc7fa4d39 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicData.h +++ b/launcher/ui/pages/modplatform/technic/TechnicData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021-2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp index f08eb2897..02d7fd5b9 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.h b/launcher/ui/pages/modplatform/technic/TechnicModel.h index 0f1a814e2..d7a635d41 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicModel.h +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp index 589d3da59..881327547 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021-2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.h b/launcher/ui/pages/modplatform/technic/TechnicPage.h index d33656ebb..91b61eaf2 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicPage.h +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2021-2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/CustomCommands.cpp b/launcher/ui/widgets/CustomCommands.cpp index 98a1b7e86..9b98d7409 100644 --- a/launcher/ui/widgets/CustomCommands.cpp +++ b/launcher/ui/widgets/CustomCommands.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/CustomCommands.h b/launcher/ui/widgets/CustomCommands.h index 96a3fa627..5b410ae9a 100644 --- a/launcher/ui/widgets/CustomCommands.h +++ b/launcher/ui/widgets/CustomCommands.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/LabeledToolButton.cpp b/launcher/ui/widgets/LabeledToolButton.cpp index 7af48b0c9..46114e047 100644 --- a/launcher/ui/widgets/LabeledToolButton.cpp +++ b/launcher/ui/widgets/LabeledToolButton.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/LogView.cpp b/launcher/ui/widgets/LogView.cpp index 8c960ebb1..4096889d3 100644 --- a/launcher/ui/widgets/LogView.cpp +++ b/launcher/ui/widgets/LogView.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index c3b70c447..f132643a0 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield * diff --git a/launcher/ui/widgets/PageContainer.h b/launcher/ui/widgets/PageContainer.h index f5978dbaa..43aa0e7c0 100644 --- a/launcher/ui/widgets/PageContainer.h +++ b/launcher/ui/widgets/PageContainer.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/VariableSizedImageObject.cpp b/launcher/ui/widgets/VariableSizedImageObject.cpp index 991b4a047..4daf513a3 100644 --- a/launcher/ui/widgets/VariableSizedImageObject.cpp +++ b/launcher/ui/widgets/VariableSizedImageObject.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/widgets/VariableSizedImageObject.h b/launcher/ui/widgets/VariableSizedImageObject.h index 137487eee..ca67af0c9 100644 --- a/launcher/ui/widgets/VariableSizedImageObject.h +++ b/launcher/ui/widgets/VariableSizedImageObject.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/updater/ExternalUpdater.h b/launcher/updater/ExternalUpdater.h index 6c0803a7e..daa5b1095 100644 --- a/launcher/updater/ExternalUpdater.h +++ b/launcher/updater/ExternalUpdater.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Kenneth Chew * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/updater/MacSparkleUpdater.h b/launcher/updater/MacSparkleUpdater.h index 3f6b5f4ad..5f9b1a28c 100644 --- a/launcher/updater/MacSparkleUpdater.h +++ b/launcher/updater/MacSparkleUpdater.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Kenneth Chew * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/updater/MacSparkleUpdater.mm b/launcher/updater/MacSparkleUpdater.mm index 1c1f5cd27..b2b631593 100644 --- a/launcher/updater/MacSparkleUpdater.mm +++ b/launcher/updater/MacSparkleUpdater.mm @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Kenneth Chew * * This program is free software: you can redistribute it and/or modify diff --git a/tests/Library_test.cpp b/tests/Library_test.cpp index e8090c097..8b8d4c55c 100644 --- a/tests/Library_test.cpp +++ b/tests/Library_test.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/tests/Packwiz_test.cpp b/tests/Packwiz_test.cpp index 6f4aa5d1b..d1b274d12 100644 --- a/tests/Packwiz_test.cpp +++ b/tests/Packwiz_test.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * diff --git a/tests/ResourceFolderModel_test.cpp b/tests/ResourceFolderModel_test.cpp index 8012d4df0..57c2cbdff 100644 --- a/tests/ResourceFolderModel_test.cpp +++ b/tests/ResourceFolderModel_test.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * * This program is free software: you can redistribute it and/or modify diff --git a/tests/ResourcePackParse_test.cpp b/tests/ResourcePackParse_test.cpp index 1dcce3249..e1092167d 100644 --- a/tests/ResourcePackParse_test.cpp +++ b/tests/ResourcePackParse_test.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * * This program is free software: you can redistribute it and/or modify diff --git a/tests/TexturePackParse_test.cpp b/tests/TexturePackParse_test.cpp index 558529287..85c96b57c 100644 --- a/tests/TexturePackParse_test.cpp +++ b/tests/TexturePackParse_test.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln * Copyright (C) 2022 Sefa Eyeoglu * From 37e5f6af48efc27469856fa04d5417a790eea4d0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 6 Aug 2023 00:17:51 +0000 Subject: [PATCH 425/429] 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 'flake-parts': 'github:hercules-ci/flake-parts/8e8d955c22df93dbe24f19ea04f47a74adbdc5ec' (2023-07-04) → 'github:hercules-ci/flake-parts/59cf3f1447cfc75087e7273b04b31e689a8599fb' (2023-08-01) • Updated input 'flake-parts/nixpkgs-lib': 'github:NixOS/nixpkgs/4bc72cae107788bf3f24f30db2e2f685c9298dc9?dir=lib' (2023-06-29) → 'github:NixOS/nixpkgs/9e1960bc196baf6881340d53dccb203a951745a2?dir=lib' (2023-08-01) • Updated input 'nixpkgs': 'github:nixos/nixpkgs/d2b52322f35597c62abf56de91b0236746b2a03d' (2023-07-29) → 'github:nixos/nixpkgs/0d2fb29f5071a12d7983319c2c2576be6a130582' (2023-08-05) • Updated input 'pre-commit-hooks': 'github:cachix/pre-commit-hooks.nix/1e2443dd3f669eb65433b2fc26a3065e05a7dc9c' (2023-07-29) → 'github:cachix/pre-commit-hooks.nix/3139c4d1f7732cab89f06492bdd4677b877e3785' (2023-08-05) --- flake.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/flake.lock b/flake.lock index af7ecae7c..3f1d7d25c 100644 --- a/flake.lock +++ b/flake.lock @@ -21,11 +21,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1688466019, - "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "lastModified": 1690933134, + "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb", "type": "github" }, "original": { @@ -91,11 +91,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1690630721, - "narHash": "sha256-Y04onHyBQT4Erfr2fc82dbJTfXGYrf4V0ysLUYnPOP8=", + "lastModified": 1691218994, + "narHash": "sha256-46GJ5vLf9H+Oh7Jii2gJI9GATJHGbx2iQpon5nUSFPI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d2b52322f35597c62abf56de91b0236746b2a03d", + "rev": "0d2fb29f5071a12d7983319c2c2576be6a130582", "type": "github" }, "original": { @@ -108,11 +108,11 @@ "nixpkgs-lib": { "locked": { "dir": "lib", - "lastModified": 1688049487, - "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", + "lastModified": 1690881714, + "narHash": "sha256-h/nXluEqdiQHs1oSgkOOWF+j8gcJMWhwnZ9PFabN6q0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", + "rev": "9e1960bc196baf6881340d53dccb203a951745a2", "type": "github" }, "original": { @@ -138,11 +138,11 @@ ] }, "locked": { - "lastModified": 1690628027, - "narHash": "sha256-OTSbA2hM6VmxyZ/4siYPANffMBzIsKu04GLjXcv8ST0=", + "lastModified": 1691256628, + "narHash": "sha256-M0YXHemR3zbyhM7PvJa5lzGhWVf6kM/fpZ4cWe/VIhI=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "1e2443dd3f669eb65433b2fc26a3065e05a7dc9c", + "rev": "3139c4d1f7732cab89f06492bdd4677b877e3785", "type": "github" }, "original": { From d9cd6f9c5016080034e01289773b167a2f23f15b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 18:20:26 +0000 Subject: [PATCH 426/429] chore(deps): update hendrikmuhs/ccache-action action to v1.2.10 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7b8f652a..432f39fb0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -152,7 +152,7 @@ jobs: - name: Setup ccache if: (runner.os != 'Windows' || matrix.msystem == '') && inputs.build_type == 'Debug' - uses: hendrikmuhs/ccache-action@v1.2.9 + uses: hendrikmuhs/ccache-action@v1.2.10 with: key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}-${{ matrix.architecture }} From b3da35be74cc9ed87c5ae5784820b1a521e87289 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 10 Aug 2023 12:19:38 +0300 Subject: [PATCH 427/429] Fixed curseforge import Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index e17cf1c2e..8b6622944 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -353,11 +353,11 @@ bool FlameCreationTask::createInstance() id.remove("forge-"); loaderType = "forge"; loaderUid = "net.minecraftforge"; - } else if (loaderType == "fabric") { + } else if (id.startsWith("fabric-")) { id.remove("fabric-"); loaderType = "fabric"; loaderUid = "net.fabricmc.fabric-loader"; - } else if (loaderType == "quilt") { + } else if (id.startsWith("quilt-")) { id.remove("quilt-"); loaderType = "quilt"; loaderUid = "org.quiltmc.quilt-loader"; From c9d628bf18ee8a2e8d1faf63fb9f8146b47099d6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 11 Aug 2023 19:42:02 +0300 Subject: [PATCH 428/429] revert asan on debug on by default Signed-off-by: Trial97 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 350189c87..60f03640e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0") # set CXXFLAGS for build targets set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}") -option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" on) +option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" off) # If this is a Debug build turn on address sanitiser if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER) From d6e4fe7c1f74222235a8eb4772fc999ba1d63d78 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 12 Aug 2023 10:06:27 +0300 Subject: [PATCH 429/429] Update CMakeLists.txt Co-authored-by: Sefa Eyeoglu Signed-off-by: Alexandru Ionut Tripon --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60f03640e..17f7c3d8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0") # set CXXFLAGS for build targets set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}") -option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" off) +option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" OFF) # If this is a Debug build turn on address sanitiser if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER)