From 783761ca2e6bc00d7025fd296f21f649e9f28f06 Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 12 Dec 2022 13:28:24 -0800 Subject: [PATCH 01/38] Merge pull request #600 from TheLastRar/reset-stylesheet Resolves https://github.com/PrismLauncher/PrismLauncher/issues/510 --- launcher/ui/themes/ITheme.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/launcher/ui/themes/ITheme.cpp b/launcher/ui/themes/ITheme.cpp index 7247b444c..8bfc466d2 100644 --- a/launcher/ui/themes/ITheme.cpp +++ b/launcher/ui/themes/ITheme.cpp @@ -6,19 +6,14 @@ void ITheme::apply(bool) { + APPLICATION->setStyleSheet(QString()); QApplication::setStyle(QStyleFactory::create(qtTheme())); - if(hasColorScheme()) - { + if (hasColorScheme()) { QApplication::setPalette(colorScheme()); } - if(hasStyleSheet()) - { + if (hasStyleSheet()) APPLICATION->setStyleSheet(appStyleSheet()); - } - else - { - APPLICATION->setStyleSheet(QString()); - } + QDir::setSearchPaths("theme", searchPaths()); } From c11575f5f5ca7d95853caf75b0021a70c5ede677 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 13 Dec 2022 08:31:52 +0100 Subject: [PATCH 02/38] Merge pull request #604 from flowln/fix_crash_with_gtk2 fix: crash with GTK2 theme due to QProxyStyle in ManagedPackPage --- launcher/ui/pages/instance/ManagedPackPage.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 7a0d234cf..7a8230430 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -7,6 +7,7 @@ #include #include +#include #include @@ -60,7 +61,10 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi ui->setupUi(this); - ui->versionsComboBox->setStyle(new NoBigComboBoxStyle(ui->versionsComboBox->style())); + // 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")) + ui->versionsComboBox->setStyle(new NoBigComboBoxStyle(ui->versionsComboBox->style())); ui->reloadButton->setVisible(false); connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool){ From 0a6c1238eb095ec12ee7fa3f0922ab3e4f1fa5ae Mon Sep 17 00:00:00 2001 From: flow Date: Tue, 13 Dec 2022 07:01:23 -0800 Subject: [PATCH 03/38] Merge pull request #601 from Scrumplex/fix-translations-3 --- launcher/ui/pages/instance/ManagedPackPage.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 7a8230430..4de80468e 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -227,17 +227,16 @@ void ModrinthManagedPackPage::parseManagedPack() ui->versionsComboBox->blockSignals(false); for (auto version : m_pack.versions) { - QString name; + QString name = version.version; if (!version.name.contains(version.version)) name = QString("%1 — %2").arg(version.name, version.version); - else - name = version.name; // NOTE: the id from version isn't the same id in the modpack format spec... // e.g. HexMC's 4.4.0 has versionId 4.0.0 in the modpack index.............. if (version.version == m_inst->getManagedPackVersionName()) - name.append(tr(" (Current)")); + name = tr("%1 (Current)").arg(name); + ui->versionsComboBox->addItem(name, QVariant(version.id)); } @@ -374,12 +373,10 @@ void FlameManagedPackPage::parseManagedPack() ui->versionsComboBox->blockSignals(false); for (auto version : m_pack.versions) { - QString name; - - name = version.version; + QString name = version.version; if (version.fileId == m_inst->getManagedPackVersionID().toInt()) - name.append(tr(" (Current)")); + name = tr("%1 (Current)").arg(name); ui->versionsComboBox->addItem(name, QVariant(version.fileId)); } From d7223972d84cd990926357f295c209ecb4359b15 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 14 Dec 2022 13:04:41 +0100 Subject: [PATCH 04/38] Merge pull request #612 from DioEgizio/move-cat-right closes https://github.com/PrismLauncher/PrismLauncher/issues/611 --- 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 2f1976cc0..3651aa158 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1683,7 +1683,7 @@ InstanceView background-image: url(:/backgrounds/%1); background-attachment: fixed; background-clip: padding; - background-position: bottom left; + background-position: bottom right; background-repeat: none; background-color:palette(base); })") From 25c63dd1e0bb2fc467a85e5a32401232e1935363 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 15 Dec 2022 04:47:56 -0800 Subject: [PATCH 05/38] Merge pull request #605 from flowln/fix_crash_in_downloader_image Fixes https://github.com/PrismLauncher/PrismLauncher/issues/590 --- launcher/ui/widgets/VariableSizedImageObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/widgets/VariableSizedImageObject.cpp b/launcher/ui/widgets/VariableSizedImageObject.cpp index e57f7e95a..991b4a047 100644 --- a/launcher/ui/widgets/VariableSizedImageObject.cpp +++ b/launcher/ui/widgets/VariableSizedImageObject.cpp @@ -101,7 +101,7 @@ void VariableSizedImageObject::loadImage(QTextDocument* doc, const QUrl& source, auto full_entry_path = entry->getFullPath(); auto source_url = source; - connect(job, &NetJob::succeeded, [this, doc, full_entry_path, source_url, posInDocument] { + connect(job, &NetJob::succeeded, this, [this, doc, full_entry_path, source_url, posInDocument] { qDebug() << "Loaded resource at" << full_entry_path; // If we flushed, don't proceed. From 2a819f1ca029f6dc63f74cdc3d2f46fea8d6e2bb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 15 Dec 2022 16:35:15 +0100 Subject: [PATCH 06/38] Merge pull request #593 from Scrumplex/fix-winget-release-no999999 --- .github/workflows/winget.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index 5c34040f7..b4136df5b 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -11,5 +11,5 @@ jobs: with: identifier: PrismLauncher.PrismLauncher version: ${{ github.event.release.tag_name }} - installers-regex: 'PrismLauncher-Windows-Setup-.+\.exe$' + installers-regex: 'PrismLauncher-Windows-MSVC(:?-arm64)?-Setup-.+\.exe$' token: ${{ secrets.WINGET_TOKEN }} From 94410352f53df622a6b05fb3e651fa032725e56f Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 15 Dec 2022 07:55:28 -0800 Subject: [PATCH 07/38] Merge pull request #625 from Edgars-Cirulis/develop --- launcher/ApplicationMessage.cpp | 8 ++++---- launcher/ApplicationMessage.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/ApplicationMessage.cpp b/launcher/ApplicationMessage.cpp index ca276b89c..700e43ced 100644 --- a/launcher/ApplicationMessage.cpp +++ b/launcher/ApplicationMessage.cpp @@ -47,8 +47,8 @@ void ApplicationMessage::parse(const QByteArray & input) { args.clear(); auto parsedArgs = root.value("args").toObject(); - for(auto iter = parsedArgs.begin(); iter != parsedArgs.end(); iter++) { - args[iter.key()] = iter.value().toString(); + for(auto iter = parsedArgs.constBegin(); iter != parsedArgs.constEnd(); iter++) { + args.insert(iter.key(), iter.value().toString()); } } @@ -56,8 +56,8 @@ QByteArray ApplicationMessage::serialize() { QJsonObject root; root.insert("command", command); QJsonObject outArgs; - for (auto iter = args.begin(); iter != args.end(); iter++) { - outArgs[iter.key()] = iter.value(); + for (auto iter = args.constBegin(); iter != args.constEnd(); iter++) { + outArgs.insert(iter.key(), iter.value()); } root.insert("args", outArgs); diff --git a/launcher/ApplicationMessage.h b/launcher/ApplicationMessage.h index 745bdeadc..d66456ebd 100644 --- a/launcher/ApplicationMessage.h +++ b/launcher/ApplicationMessage.h @@ -1,12 +1,12 @@ #pragma once #include -#include +#include #include struct ApplicationMessage { QString command; - QMap args; + QHash args; QByteArray serialize(); void parse(const QByteArray & input); From 040774d67bbbbe3654558545f98357ee5a5bc50b Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 16 Dec 2022 07:22:22 -0800 Subject: [PATCH 08/38] Merge pull request #607 from flowln/dont_crash_on_zip_import Fixes https://github.com/PrismLauncher/PrismLauncher/issues/609 --- launcher/InstanceImportTask.cpp | 64 ++++++++++++------- .../flame/FlameInstanceCreationTask.cpp | 4 +- .../modrinth/ModrinthInstanceCreationTask.cpp | 4 +- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index b97870da4..6b3fd296f 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -257,20 +257,26 @@ void InstanceImportTask::extractAborted() void InstanceImportTask::processFlame() { - auto pack_id_it = m_extra_info.constFind("pack_id"); - Q_ASSERT(pack_id_it != m_extra_info.constEnd()); - auto pack_id = pack_id_it.value(); + FlameCreationTask* inst_creation_task = nullptr; + if (!m_extra_info.isEmpty()) { + auto pack_id_it = m_extra_info.constFind("pack_id"); + Q_ASSERT(pack_id_it != m_extra_info.constEnd()); + auto pack_id = pack_id_it.value(); - auto pack_version_id_it = m_extra_info.constFind("pack_version_id"); - Q_ASSERT(pack_version_id_it != m_extra_info.constEnd()); - auto pack_version_id = pack_version_id_it.value(); + auto pack_version_id_it = m_extra_info.constFind("pack_version_id"); + Q_ASSERT(pack_version_id_it != m_extra_info.constEnd()); + auto pack_version_id = pack_version_id_it.value(); - QString original_instance_id; - auto original_instance_id_it = m_extra_info.constFind("original_instance_id"); - if (original_instance_id_it != m_extra_info.constEnd()) - original_instance_id = original_instance_id_it.value(); + QString original_instance_id; + auto original_instance_id_it = m_extra_info.constFind("original_instance_id"); + if (original_instance_id_it != m_extra_info.constEnd()) + original_instance_id = original_instance_id_it.value(); - auto* inst_creation_task = new FlameCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); + inst_creation_task = new FlameCreationTask(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 = new FlameCreationTask(m_stagingPath, m_globalSettings, m_parent, {}, {}); + } inst_creation_task->setName(*this); inst_creation_task->setIcon(m_instIcon); @@ -335,21 +341,33 @@ void InstanceImportTask::processMultiMC() void InstanceImportTask::processModrinth() { - auto pack_id_it = m_extra_info.constFind("pack_id"); - Q_ASSERT(pack_id_it != m_extra_info.constEnd()); - auto pack_id = pack_id_it.value(); + ModrinthCreationTask* inst_creation_task = nullptr; + if (!m_extra_info.isEmpty()) { + auto pack_id_it = m_extra_info.constFind("pack_id"); + Q_ASSERT(pack_id_it != m_extra_info.constEnd()); + auto pack_id = pack_id_it.value(); - QString pack_version_id; - auto pack_version_id_it = m_extra_info.constFind("pack_version_id"); - if (pack_version_id_it != m_extra_info.constEnd()) - pack_version_id = pack_version_id_it.value(); + QString pack_version_id; + auto pack_version_id_it = m_extra_info.constFind("pack_version_id"); + if (pack_version_id_it != m_extra_info.constEnd()) + pack_version_id = pack_version_id_it.value(); - QString original_instance_id; - auto original_instance_id_it = m_extra_info.constFind("original_instance_id"); - if (original_instance_id_it != m_extra_info.constEnd()) - original_instance_id = original_instance_id_it.value(); + QString original_instance_id; + auto original_instance_id_it = m_extra_info.constFind("original_instance_id"); + if (original_instance_id_it != m_extra_info.constEnd()) + original_instance_id = original_instance_id_it.value(); - auto* 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()) { + QRegularExpression regex(R"(data\/(.*)\/versions)"); + pack_id = regex.match(m_sourceUrl.toString()).captured(1); + } + + // FIXME: Find a way to get the ID in directly imported ZIPs + inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id); + } inst_creation_task->setName(*this); inst_creation_task->setIcon(m_instIcon); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 729268d7d..1d441f092 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -361,7 +361,9 @@ bool FlameCreationTask::createInstance() FS::deletePath(jarmodsPath); } - instance.setManagedPack("flame", m_managed_id, m_pack.name, m_managed_version_id, m_pack.version); + // Don't add managed info to packs without an ID (most likely imported from ZIP) + if (!m_managed_id.isEmpty()) + instance.setManagedPack("flame", m_managed_id, m_pack.name, m_managed_version_id, m_pack.version); instance.setName(name()); m_mod_id_resolver = new Flame::FileResolvingTask(APPLICATION->network(), m_pack); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 1c0e89798..5632f6a32 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -217,7 +217,9 @@ bool ModrinthCreationTask::createInstance() instance.setIconKey("modrinth"); } - instance.setManagedPack("modrinth", m_managed_id, m_managed_name, m_managed_version_id, version()); + // Don't add managed info to packs without an ID (most likely imported from ZIP) + if (!m_managed_id.isEmpty()) + instance.setManagedPack("modrinth", m_managed_id, m_managed_name, m_managed_version_id, version()); instance.setName(name()); instance.saveNow(); From bcf506488f88a8fa1f386fe5db3efeaf35813767 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 17 Dec 2022 05:53:17 -0800 Subject: [PATCH 09/38] Merge pull request #631 from getchoo/better-msvc-flags --- CMakeLists.txt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bdd4811d..51a47bf10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,19 +28,28 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_STANDARD 11) include(GenerateExportHeader) if(MSVC) - # Use /W4 as /Wall includes unnesserey warnings such as added padding to structs - # /permissive- specify standards-conforming compiler behavior, also enabled by Qt6, default on with std:c++20 # /GS Adds buffer security checks, default on but incuded anyway to mirror gcc's fstack-protector flag - set(CMAKE_CXX_FLAGS "/W4 /permissive- /GS ${CMAKE_CXX_FLAGS}") + # /permissive- specify standards-conforming compiler behavior, also enabled by Qt6, default on with std:c++20 + # Use /W4 as /Wall includes unnesserey warnings such as added padding to structs + set(CMAKE_CXX_FLAGS "/GS /permissive- /W4 ${CMAKE_CXX_FLAGS}") # LINK accepts /SUBSYSTEM whics sets if we are a WINDOWS (gui) or a CONSOLE programs # This implicitly selects an entrypoint specific to the subsystem selected # qtmain/QtEntryPointLib provides the correct entrypoint (wWinMain) for gui programs # Additinaly LINK autodetects we use a GUI so we can omit /SUBSYSTEM # This allows tests to still use have console without using seperate linker flags + # /LTCG allows for linking wholy optimizated programs # /MANIFEST:NO disables generating a manifest file, we instead provide our own # /STACK sets the stack reserve size, ATL's pack list needs 3-4 MiB as of November 2022, provide 8 MiB - set(CMAKE_EXE_LINKER_FLAGS "/MANIFEST:NO /STACK:8388608 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "/LTCG /MANIFEST:NO /STACK:8388608 ${CMAKE_EXE_LINKER_FLAGS}") + + # /GL enables whole program optimizations + # /Gw helps reduce binary size + # /Gy allows the compiler to package individual functions + # /guard:cf enables control flow guard + foreach(lang C CXX) + set("CMAKE_${lang}_FLAGS_RELEASE" "/GL /Gw /Gy /guard:cf") + endforeach() # See https://github.com/ccache/ccache/issues/1040 # Note, CMake 3.25 replaces this with CMAKE_MSVC_DEBUG_INFORMATION_FORMAT From 45870497c613a7eb2d410c29c98815cc7c25d86c Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 17 Dec 2022 08:02:41 -0800 Subject: [PATCH 10/38] Merge pull request #630 from leo78913/yeet-scrollbars --- launcher/ui/dialogs/IconPickerDialog.cpp | 1 - launcher/ui/dialogs/ImportResourcePackDialog.cpp | 1 - launcher/ui/pages/instance/NotesPage.ui | 6 ------ launcher/ui/pages/instance/OtherLogsPage.ui | 3 --- launcher/ui/pages/instance/VersionPage.ui | 3 --- launcher/ui/widgets/ModListView.cpp | 1 - 6 files changed, 15 deletions(-) diff --git a/launcher/ui/dialogs/IconPickerDialog.cpp b/launcher/ui/dialogs/IconPickerDialog.cpp index fcb645db4..6fa265085 100644 --- a/launcher/ui/dialogs/IconPickerDialog.cpp +++ b/launcher/ui/dialogs/IconPickerDialog.cpp @@ -47,7 +47,6 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) contentsWidget->setUniformItemSizes(true); contentsWidget->setTextElideMode(Qt::ElideRight); contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); contentsWidget->setItemDelegate(new ListViewDelegate()); diff --git a/launcher/ui/dialogs/ImportResourcePackDialog.cpp b/launcher/ui/dialogs/ImportResourcePackDialog.cpp index e807e9265..e89026569 100644 --- a/launcher/ui/dialogs/ImportResourcePackDialog.cpp +++ b/launcher/ui/dialogs/ImportResourcePackDialog.cpp @@ -29,7 +29,6 @@ ImportResourcePackDialog::ImportResourcePackDialog(QWidget* parent) : QDialog(pa // NOTE: We can't have uniform sizes because the text may wrap if it's too long. If we set this, it will cut off the wrapped text. contentsWidget->setUniformItemSizes(false); contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); contentsWidget->setItemDelegate(new ListViewDelegate()); diff --git a/launcher/ui/pages/instance/NotesPage.ui b/launcher/ui/pages/instance/NotesPage.ui index 67cb261c1..4b506da70 100644 --- a/launcher/ui/pages/instance/NotesPage.ui +++ b/launcher/ui/pages/instance/NotesPage.ui @@ -17,17 +17,11 @@ 0 - - 0 - 0 - - Qt::ScrollBarAlwaysOn - true diff --git a/launcher/ui/pages/instance/OtherLogsPage.ui b/launcher/ui/pages/instance/OtherLogsPage.ui index 77f3e6477..3fdb023fe 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.ui +++ b/launcher/ui/pages/instance/OtherLogsPage.ui @@ -48,9 +48,6 @@ false - - Qt::ScrollBarAlwaysOn - true diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index 74b9568a4..4cd508853 100644 --- a/launcher/ui/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -28,9 +28,6 @@ - - Qt::ScrollBarAlwaysOn - Qt::ScrollBarAlwaysOff diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index c8ccd2925..d1860f57b 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -31,7 +31,6 @@ ModListView::ModListView ( QWidget* parent ) setSelectionMode ( QAbstractItemView::ExtendedSelection ); setHeaderHidden ( false ); setSelectionBehavior(QAbstractItemView::SelectRows); - setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn ); setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); setDropIndicatorShown(true); setDragEnabled(true); From 3476bbebd96dd5621039229ecad1ee5636d1e543 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 17 Dec 2022 17:26:34 +0100 Subject: [PATCH 11/38] Merge pull request #636 from flowln/fix_component_version_when_updating Correctly set component versions in Modrinth pack updating --- .../modrinth/ModrinthInstanceCreationTask.cpp | 46 ++++++++++--------- .../modrinth/ModrinthInstanceCreationTask.h | 4 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 5632f6a32..c5a27c9dc 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -202,14 +202,14 @@ bool ModrinthCreationTask::createInstance() auto components = instance.getPackProfile(); components->buildingFromScratch(); - components->setComponentVersion("net.minecraft", minecraftVersion, true); + components->setComponentVersion("net.minecraft", m_minecraft_version, true); - if (!fabricVersion.isEmpty()) - components->setComponentVersion("net.fabricmc.fabric-loader", fabricVersion); - if (!quiltVersion.isEmpty()) - components->setComponentVersion("org.quiltmc.quilt-loader", quiltVersion); - if (!forgeVersion.isEmpty()) - components->setComponentVersion("net.minecraftforge", forgeVersion); + if (!m_fabric_version.isEmpty()) + components->setComponentVersion("net.fabricmc.fabric-loader", m_fabric_version); + if (!m_quilt_version.isEmpty()) + components->setComponentVersion("org.quiltmc.quilt-loader", m_quilt_version); + if (!m_forge_version.isEmpty()) + components->setComponentVersion("net.minecraftforge", m_forge_version); if (m_instIcon != "default") { instance.setIconKey(m_instIcon); @@ -279,7 +279,7 @@ bool ModrinthCreationTask::createInstance() return ended_well; } -bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector& files, bool set_managed_info, 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); @@ -291,7 +291,7 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector< throw JSONValidationError("Unknown game: " + game); } - if (set_managed_info) { + if (set_internal_data) { if (m_managed_version_id.isEmpty()) m_managed_version_id = Json::ensureString(obj, "versionId", {}, "Managed ID"); m_managed_name = Json::ensureString(obj, "name", {}, "Managed Name"); @@ -367,19 +367,21 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector< files.push_back(file); } - auto dependencies = Json::requireObject(obj, "dependencies", "modrinth.index.json"); - for (auto it = dependencies.begin(), end = dependencies.end(); it != end; ++it) { - QString name = it.key(); - if (name == "minecraft") { - minecraftVersion = Json::requireString(*it, "Minecraft version"); - } else if (name == "fabric-loader") { - fabricVersion = Json::requireString(*it, "Fabric Loader version"); - } else if (name == "quilt-loader") { - quiltVersion = Json::requireString(*it, "Quilt Loader version"); - } else if (name == "forge") { - forgeVersion = Json::requireString(*it, "Forge version"); - } else { - throw JSONValidationError("Unknown dependency type: " + name); + if (set_internal_data) { + auto dependencies = Json::requireObject(obj, "dependencies", "modrinth.index.json"); + for (auto it = dependencies.begin(), end = dependencies.end(); it != end; ++it) { + QString name = it.key(); + if (name == "minecraft") { + m_minecraft_version = Json::requireString(*it, "Minecraft version"); + } else if (name == "fabric-loader") { + m_fabric_version = Json::requireString(*it, "Fabric Loader version"); + } else if (name == "quilt-loader") { + m_quilt_version = Json::requireString(*it, "Quilt Loader version"); + } else if (name == "forge") { + m_forge_version = Json::requireString(*it, "Forge version"); + } else { + throw JSONValidationError("Unknown dependency type: " + name); + } } } } else { diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h index 122fc5ce3..6de24fd40 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h @@ -37,12 +37,12 @@ class ModrinthCreationTask final : public InstanceCreationTask { bool createInstance() override; private: - bool parseManifest(const QString&, std::vector&, bool set_managed_info = true, bool show_optional_dialog = true); + bool parseManifest(const QString&, std::vector&, bool set_internal_data = true, bool show_optional_dialog = true); private: QWidget* m_parent = nullptr; - QString minecraftVersion, fabricVersion, quiltVersion, forgeVersion; + QString m_minecraft_version, m_fabric_version, m_quilt_version, m_forge_version; QString m_managed_id, m_managed_version_id, m_managed_name; std::vector m_files; From 3b1ab3c9740058e3227a418b3bff9106ab9c034b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 18 Dec 2022 16:27:48 +0100 Subject: [PATCH 12/38] Merge pull request #642 from DioEgizio/dont-ship-unnecessary-tlsbackends fix: exclude unused tls backends --- launcher/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 439feb443..a0d92b6ee 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1166,6 +1166,8 @@ if(INSTALL_BUNDLE STREQUAL "full") CONFIGURATIONS Debug RelWithDebInfo "" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime + PATTERN "*qopensslbackend*" EXCLUDE + PATTERN "*qcertonlybackend*" EXCLUDE ) install( DIRECTORY "${QT_PLUGINS_DIR}/tls" @@ -1175,6 +1177,8 @@ if(INSTALL_BUNDLE STREQUAL "full") REGEX "dd\\." EXCLUDE REGEX "_debug\\." EXCLUDE REGEX "\\.dSYM" EXCLUDE + PATTERN "*qopensslbackend*" EXCLUDE + PATTERN "*qcertonlybackend*" EXCLUDE ) endif() configure_file( From 5203e721996f23c740c4a37b2d5c9db5d901cf42 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 19 Dec 2022 15:35:34 +0100 Subject: [PATCH 13/38] Merge pull request #628 from flowln/fix_multiple_resource_packs_crash Fixes https://github.com/PrismLauncher/PrismLauncher/issues/624 --- .../minecraft/mod/ResourceFolderModel.cpp | 7 +++- launcher/minecraft/mod/ResourceFolderModel.h | 2 ++ launcher/net/NetJob.cpp | 4 +-- launcher/tasks/ConcurrentTask.cpp | 36 +++++++++++++------ launcher/tasks/ConcurrentTask.h | 9 ++++- launcher/tasks/MultipleOptionsTask.cpp | 4 +-- launcher/tasks/SequentialTask.cpp | 4 +-- 7 files changed, 47 insertions(+), 19 deletions(-) diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 0310c8f6e..a52c5db34 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -20,6 +20,7 @@ ResourceFolderModel::ResourceFolderModel(QDir dir, QObject* parent) : QAbstractL m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged); + connect(&m_helper_thread_task, &ConcurrentTask::finished, this, [this]{ m_helper_thread_task.clear(); }); } ResourceFolderModel::~ResourceFolderModel() @@ -275,7 +276,11 @@ void ResourceFolderModel::resolveResource(Resource* res) connect( task, &Task::finished, this, [=] { m_active_parse_tasks.remove(ticket); }, Qt::ConnectionType::QueuedConnection); - QThreadPool::globalInstance()->start(task); + m_helper_thread_task.addTask(task); + + if (!m_helper_thread_task.isRunning()) { + QThreadPool::globalInstance()->start(&m_helper_thread_task); + } } void ResourceFolderModel::onUpdateSucceeded() diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index fe283b043..f1bc2dd78 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -10,6 +10,7 @@ #include "Resource.h" #include "tasks/Task.h" +#include "tasks/ConcurrentTask.h" class QSortFilterProxyModel; @@ -197,6 +198,7 @@ class ResourceFolderModel : public QAbstractListModel { // Represents the relationship between a resource's internal ID and it's row position on the model. QMap m_resources_index; + ConcurrentTask m_helper_thread_task; QMap m_active_parse_tasks; std::atomic m_next_resolution_ticket = 0; }; diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp index 8ced1b7ef..9b5d4f1be 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -123,7 +123,7 @@ auto NetJob::getFailedFiles() -> QList void NetJob::updateState() { - emit progress(m_done.count(), m_total_size); + emit progress(m_done.count(), totalSize()); setStatus(tr("Executing %1 task(s) (%2 out of %3 are done)") - .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(m_total_size))); + .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(totalSize()))); } diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp index ce08a6a29..a890013ef 100644 --- a/launcher/tasks/ConcurrentTask.cpp +++ b/launcher/tasks/ConcurrentTask.cpp @@ -27,18 +27,13 @@ auto ConcurrentTask::getStepTotalProgress() const -> qint64 void ConcurrentTask::addTask(Task::Ptr task) { - if (!isRunning()) - m_queue.append(task); - else - qWarning() << "Tried to add a task to a running concurrent task!"; + m_queue.append(task); } void ConcurrentTask::executeTask() { - m_total_size = m_queue.size(); - // Start the least amount of tasks needed, but at least one - int num_starts = std::max(1, std::min(m_total_max_size, m_total_size)); + int num_starts = qMax(1, qMin(m_total_max_size, m_queue.size())); for (int i = 0; i < num_starts; i++) { QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); } @@ -73,6 +68,20 @@ bool ConcurrentTask::abort() return suceedeed; } +void ConcurrentTask::clear() +{ + Q_ASSERT(!isRunning()); + + m_done.clear(); + m_failed.clear(); + m_queue.clear(); + + m_aborted = false; + + m_progress = 0; + m_stepProgress = 0; +} + void ConcurrentTask::startNext() { if (m_aborted || m_doing.count() > m_total_max_size) @@ -101,9 +110,14 @@ void ConcurrentTask::startNext() setStepStatus(next->isMultiStep() ? next->getStepStatus() : next->getStatus()); updateState(); - QCoreApplication::processEvents(); + QMetaObject::invokeMethod(next.get(), &Task::start, Qt::QueuedConnection); - next->start(); + // Allow going up the number of concurrent tasks in case of tasks being added in the middle of a running task. + int num_starts = m_total_max_size - m_doing.size(); + for (int i = 0; i < num_starts; i++) + QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); + + QCoreApplication::processEvents(); } void ConcurrentTask::subTaskSucceeded(Task::Ptr task) @@ -145,7 +159,7 @@ void ConcurrentTask::subTaskProgress(qint64 current, qint64 total) void ConcurrentTask::updateState() { - setProgress(m_done.count(), m_total_size); + setProgress(m_done.count(), totalSize()); setStatus(tr("Executing %1 task(s) (%2 out of %3 are done)") - .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(m_total_size))); + .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(totalSize()))); } diff --git a/launcher/tasks/ConcurrentTask.h b/launcher/tasks/ConcurrentTask.h index f1279d324..b46919fb4 100644 --- a/launcher/tasks/ConcurrentTask.h +++ b/launcher/tasks/ConcurrentTask.h @@ -24,6 +24,11 @@ public: public slots: bool abort() override; + /** Resets the internal state of the task. + * This allows the same task to be re-used. + */ + void clear(); + protected slots: void executeTask() override; @@ -36,6 +41,9 @@ slots: void subTaskProgress(qint64 current, qint64 total); protected: + // NOTE: This is not thread-safe. + [[nodiscard]] unsigned int totalSize() const { return m_queue.size() + m_doing.size() + m_done.size(); } + void setStepStatus(QString status) { m_step_status = status; emit stepStatus(status); }; virtual void updateState(); @@ -51,7 +59,6 @@ protected: QHash m_failed; int m_total_max_size; - int m_total_size; qint64 m_stepProgress = 0; qint64 m_stepTotalProgress = 100; diff --git a/launcher/tasks/MultipleOptionsTask.cpp b/launcher/tasks/MultipleOptionsTask.cpp index 5ad6181f8..034499dfa 100644 --- a/launcher/tasks/MultipleOptionsTask.cpp +++ b/launcher/tasks/MultipleOptionsTask.cpp @@ -22,6 +22,6 @@ void MultipleOptionsTask::startNext() void MultipleOptionsTask::updateState() { - setProgress(m_done.count(), m_total_size); - setStatus(tr("Attempting task %1 out of %2").arg(QString::number(m_doing.count() + m_done.count()), QString::number(m_total_size))); + setProgress(m_done.count(), totalSize()); + setStatus(tr("Attempting task %1 out of %2").arg(QString::number(m_doing.count() + m_done.count()), QString::number(totalSize()))); } diff --git a/launcher/tasks/SequentialTask.cpp b/launcher/tasks/SequentialTask.cpp index a34137cbf..b2f86328a 100644 --- a/launcher/tasks/SequentialTask.cpp +++ b/launcher/tasks/SequentialTask.cpp @@ -17,6 +17,6 @@ void SequentialTask::startNext() void SequentialTask::updateState() { - setProgress(m_done.count(), m_total_size); - setStatus(tr("Executing task %1 out of %2").arg(QString::number(m_doing.count() + m_done.count()), QString::number(m_total_size))); + setProgress(m_done.count(), totalSize()); + setStatus(tr("Executing task %1 out of %2").arg(QString::number(m_doing.count() + m_done.count()), QString::number(totalSize()))); } From 3751856a4e4a756b84bf03e1ef4811dc81e3992d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 19 Dec 2022 16:09:55 +0100 Subject: [PATCH 14/38] Merge pull request #647 from Scrumplex/update-flake --- flake.lock | 31 +++++++------------------------ flake.nix | 7 +++---- nix/default.nix | 14 +++++--------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/flake.lock b/flake.lock index 7c0bb2f8a..051e1664c 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1650374568, - "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", + "lastModified": 1668681692, + "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=", "owner": "edolstra", "repo": "flake-compat", - "rev": "b4a34015c698c7793d592d66adbab377907a2be8", + "rev": "009399224d5e398d03b22badca40a37ac85412a1", "type": "github" }, "original": { @@ -34,11 +34,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1666057921, - "narHash": "sha256-VpQqtXdj6G7cH//SvoprjR7XT3KS7p+tCVebGK1N6tE=", + "lastModified": 1671417167, + "narHash": "sha256-JkHam6WQOwZN1t2C2sbp1TqMv3TVRjzrdoejqfefwrM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "88eab1e431cabd0ed621428d8b40d425a07af39f", + "rev": "bb31220cca6d044baa6dc2715b07497a2a7c4bc7", "type": "github" }, "original": { @@ -52,24 +52,7 @@ "inputs": { "flake-compat": "flake-compat", "libnbtplusplus": "libnbtplusplus", - "nixpkgs": "nixpkgs", - "tomlplusplus": "tomlplusplus" - } - }, - "tomlplusplus": { - "flake": false, - "locked": { - "lastModified": 1666091090, - "narHash": "sha256-djpMCFPvkJcfynV8WnsYdtwLq+J7jpV1iM4C6TojiyM=", - "owner": "marzer", - "repo": "tomlplusplus", - "rev": "1e4a3833d013aee08f58c5b31c69f709afc69f73", - "type": "github" - }, - "original": { - "owner": "marzer", - "repo": "tomlplusplus", - "type": "github" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index b1e07c910..5615a758f 100644 --- a/flake.nix +++ b/flake.nix @@ -5,10 +5,9 @@ nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; libnbtplusplus = { url = "github:PrismLauncher/libnbtplusplus"; flake = false; }; - tomlplusplus = { url = "github:marzer/tomlplusplus"; flake = false; }; }; - outputs = { self, nixpkgs, libnbtplusplus, tomlplusplus, ... }: + outputs = { self, nixpkgs, libnbtplusplus, ... }: let # User-friendly version number. version = builtins.substring 0 8 self.lastModifiedDate; @@ -23,8 +22,8 @@ pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system}); packagesFn = pkgs: rec { - prismlauncher-qt5 = pkgs.libsForQt5.callPackage ./nix { inherit version self libnbtplusplus tomlplusplus; }; - prismlauncher = pkgs.qt6Packages.callPackage ./nix { inherit version self libnbtplusplus tomlplusplus; }; + prismlauncher-qt5 = pkgs.libsForQt5.callPackage ./nix { inherit version self libnbtplusplus; }; + prismlauncher = pkgs.qt6Packages.callPackage ./nix { inherit version self libnbtplusplus; }; }; in { diff --git a/nix/default.nix b/nix/default.nix index 6050fd37f..82ba9c7d0 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -2,7 +2,7 @@ , stdenv , cmake , jdk8 -, jdk +, jdk17 , zlib , file , wrapQtAppsHook @@ -16,15 +16,15 @@ , glfw , openal , extra-cmake-modules +, tomlplusplus , ghc_filesystem , msaClientID ? "" -, jdks ? [ jdk jdk8 ] +, jdks ? [ jdk17 jdk8 ] # flake , self , version , libnbtplusplus -, tomlplusplus }: stdenv.mkDerivation rec { @@ -33,13 +33,14 @@ stdenv.mkDerivation rec { src = lib.cleanSource self; - nativeBuildInputs = [ extra-cmake-modules cmake file jdk wrapQtAppsHook ]; + nativeBuildInputs = [ extra-cmake-modules cmake file jdk17 wrapQtAppsHook ]; buildInputs = [ qtbase qtsvg zlib quazip ghc_filesystem + tomlplusplus ] ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland; cmakeFlags = lib.optionals (msaClientID != "") [ "-DLauncher_MSA_CLIENT_ID=${msaClientID}" ] @@ -52,11 +53,6 @@ stdenv.mkDerivation rec { ln -s ${libnbtplusplus}/* source/libraries/libnbtplusplus chmod -R +r+w source/libraries/libnbtplusplus chown -R $USER: source/libraries/libnbtplusplus - rm -rf source/libraries/tomlplusplus - mkdir source/libraries/tomlplusplus - ln -s ${tomlplusplus}/* source/libraries/tomlplusplus - chmod -R +r+w source/libraries/tomlplusplus - chown -R $USER: source/libraries/tomlplusplus ''; postInstall = From 6f8e1ccf896541de9a900042d073ba0f71cca336 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 19 Dec 2022 16:11:10 +0100 Subject: [PATCH 15/38] chore: bump to 6.1 Signed-off-by: Sefa Eyeoglu --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51a47bf10..70846fc49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRIN ######## Set version numbers ######## set(Launcher_VERSION_MAJOR 6) -set(Launcher_VERSION_MINOR 0) +set(Launcher_VERSION_MINOR 1) set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}") set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0") From e1e0166c95480ceb755f92c1e4499ebc657332ec Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 19 Dec 2022 16:36:42 +0100 Subject: [PATCH 16/38] Merge pull request #649 from Scrumplex/fix-winget-release-no9999999 --- .github/workflows/winget.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index b4136df5b..ef9561cf1 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -11,5 +11,5 @@ jobs: with: identifier: PrismLauncher.PrismLauncher version: ${{ github.event.release.tag_name }} - installers-regex: 'PrismLauncher-Windows-MSVC(:?-arm64)?-Setup-.+\.exe$' + installers-regex: 'PrismLauncher-Windows-MSVC(:?-arm64|-Legacy)?-Setup-.+\.exe$' token: ${{ secrets.WINGET_TOKEN }} From 1de301752f74e153b18228097708f010877e65cb Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 24 Dec 2022 03:58:49 -0800 Subject: [PATCH 17/38] Merge pull request #665 from flowln/logging_categories --- launcher/Application.cpp | 23 ++++++++++++----------- program_info/prismlauncher.6.scd | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 3f313ee4a..ff34a168d 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -146,19 +146,12 @@ static const QLatin1String liveCheckFile("live.check"); 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) { - const char *levels = "DWCFIS"; - const QString format("%1 %2 %3\n"); - - qint64 msecstotal = APPLICATION->timeSinceStart(); - qint64 seconds = msecstotal / 1000; - qint64 msecs = msecstotal % 1000; - QString foo; - char buf[1025] = {0}; - ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs); - - QString out = format.arg(buf).arg(levels[type]).arg(msg); + QString out = qFormatLogMessage(type, context, msg); + out += QChar::LineFeed; APPLICATION->logFile->write(out.toUtf8()); APPLICATION->logFile->flush(); @@ -431,6 +424,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) return; } 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}"); + qDebug() << "<> Log initialized."; } diff --git a/program_info/prismlauncher.6.scd b/program_info/prismlauncher.6.scd index f979e4571..e1ebfff32 100644 --- a/program_info/prismlauncher.6.scd +++ b/program_info/prismlauncher.6.scd @@ -41,6 +41,24 @@ Here are the current features of Prism Launcher. *-a, --profile*=PROFILE Use the account specified by PROFILE (only valid in combination with --launch). +# ENVIRONMENT + +The behavior of the launcher can be customized by the following environment +variables, besides other common Qt variables: + +*QT_LOGGING_RULES* + Specifies which logging categories are shown in the logs. One can + enable/disable multiple categories by separating them with a semicolon (;). + + The specific syntax, and alternatives to this setting, can be found at + https://doc.qt.io/qt-6/qloggingcategory.html#configuring-categories. + +*QT_MESSAGE_PATTERN* + Specifies the format in which the console output will be shown. + + Available options, as well as syntax, can be viewed at + https://doc.qt.io/qt-6/qtglobal.html#qSetMessagePattern. + # EXIT STATUS *0* From de561e4fd3d7a9a80e2f5cf083a96f5d5f4d80ca Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 24 Dec 2022 06:38:49 -0800 Subject: [PATCH 18/38] Merge pull request #666 from getchoo/pls-scrump scrump heard your pleads, rejoice! --- buildconfig/BuildConfig.cpp.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 1262ce8e4..353731896 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -76,7 +76,9 @@ Config::Config() // Assume that builds outside of Git repos are "stable" if (GIT_REFSPEC == QStringLiteral("GITDIR-NOTFOUND") - || GIT_TAG == QStringLiteral("GITDIR-NOTFOUND")) + || GIT_TAG == QStringLiteral("GITDIR-NOTFOUND") + || GIT_REFSPEC == QStringLiteral("") + || GIT_TAG == QStringLiteral("GIT-NOTFOUND")) { GIT_REFSPEC = "refs/heads/stable"; GIT_TAG = versionString(); From 49060beae7047c4c739e25fc6d61d7fa74c97b01 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 28 Dec 2022 13:48:39 +0100 Subject: [PATCH 19/38] Merge pull request #680 from AshtakaOOf/flathub-screenshots --- ...rismlauncher.PrismLauncher.metainfo.xml.in | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/program_info/org.prismlauncher.PrismLauncher.metainfo.xml.in b/program_info/org.prismlauncher.PrismLauncher.metainfo.xml.in index 13a860d9a..967089603 100644 --- a/program_info/org.prismlauncher.PrismLauncher.metainfo.xml.in +++ b/program_info/org.prismlauncher.PrismLauncher.metainfo.xml.in @@ -19,38 +19,49 @@

Features:

  • Easily install game modifications, such as Fabric, Forge and Quilt
  • -
  • Control your Java settings
  • +
  • Easily install and update modpacks from the Launcher
  • +
  • Control your Java settings, and enable Mangohud or Gamemode with a toggle
  • Manage worlds and resource packs from the launcher
  • -
  • See logs and other details easily
  • +
  • See logs and other details easily through a dashboard
  • Kill Minecraft in case of a crash/freeze
  • Isolate Minecraft instances to keep everything clean
  • Install and update mods directly from the launcher
  • +
  • Customize the launcher with themes, and more
  • +
  • And cat :3
The main Prism Launcher window - https://prismlauncher.org/img/screenshots/LauncherDark.png + https://prismlauncher.org/img/screenshots/LauncherDark.png Modpack installation - https://prismlauncher.org/img/screenshots/ModpackInstallDark.png + https://prismlauncher.org/img/screenshots/ModpackInstallDark.png + + + Modpack updating + https://prismlauncher.org/img/screenshots/ModpackUpdateDark.png Mod installation - https://prismlauncher.org/img/screenshots/ModInstallDark.png + https://prismlauncher.org/img/screenshots/ModInstallDark.png Mod updating - https://prismlauncher.org/img/screenshots/ModUpdateDark.png + https://prismlauncher.org/img/screenshots/ModUpdateDark.png Instance management - https://prismlauncher.org/img/screenshots/PropertiesDark.png + https://prismlauncher.org/img/screenshots/PropertiesDark.png - Cat :) - https://prismlauncher.org/img/screenshots/LauncherCatDark.png + Cat :3 + https://prismlauncher.org/img/screenshots/LauncherCatDark.png + + + Customization + https://prismlauncher.org/img/screenshots/CustomizeDark.png From 699fce44827f00d5eb8ae0eb8c13d42d7e953a6d Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 28 Dec 2022 09:54:23 -0800 Subject: [PATCH 20/38] Merge pull request #684 from Scrumplex/logging-categories Prevents private credentials from leaking in the logs of general users --- CMakeLists.txt | 2 ++ launcher/CMakeLists.txt | 18 +++++++++++++ launcher/minecraft/auth/Parsers.cpp | 25 ++++++------------- .../minecraft/auth/steps/EntitlementsStep.cpp | 5 ++-- .../auth/steps/LauncherLoginStep.cpp | 15 ++++------- launcher/minecraft/auth/steps/MSAStep.cpp | 7 +++--- .../auth/steps/MinecraftProfileStep.cpp | 5 ++-- .../auth/steps/MinecraftProfileStepMojang.cpp | 5 ++-- .../auth/steps/XboxAuthorizationStep.cpp | 5 ++-- .../minecraft/auth/steps/XboxProfileStep.cpp | 10 +++----- libraries/katabasis/CMakeLists.txt | 9 +++++++ .../katabasis/include/katabasis/DeviceFlow.h | 1 + libraries/katabasis/src/DeviceFlow.cpp | 6 ++--- 13 files changed, 59 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70846fc49..6d2f3c4fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,6 +268,8 @@ if(NOT Launcher_FORCE_BUNDLED_LIBS) find_package(ghc_filesystem QUIET) endif() +include(ECMQtDeclareLoggingCategory) + ####################################### Program Info ####################################### set(Launcher_APP_BINARY_NAME "prismlauncher" CACHE STRING "Name of the Launcher binary") diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index a0d92b6ee..6ca88ec60 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -551,6 +551,24 @@ set(ATLAUNCHER_SOURCES modplatform/atlauncher/ATLShareCode.h ) +######## Logging categories ######## + +ecm_qt_declare_logging_category(CORE_SOURCES + HEADER Logging.h + IDENTIFIER authCredentials + CATEGORY_NAME "launcher.auth.credentials" + DEFAULT_SEVERITY Warning + DESCRIPTION "Secrets and credentials for debugging purposes" + EXPORT "${Launcher_Name}" +) + +if(KDE_INSTALL_LOGGINGCATEGORIESDIR) # only install if there is a standard path for this + ecm_qt_install_logging_categories( + EXPORT "${Launcher_Name}" + DESTINATION "${KDE_INSTALL_LOGGINGCATEGORIESDIR}" + ) +endif() + ################################ COMPILE ################################ set(LOGIC_SOURCES diff --git a/launcher/minecraft/auth/Parsers.cpp b/launcher/minecraft/auth/Parsers.cpp index 47473899b..f3d9ad56b 100644 --- a/launcher/minecraft/auth/Parsers.cpp +++ b/launcher/minecraft/auth/Parsers.cpp @@ -1,5 +1,6 @@ #include "Parsers.h" #include "Json.h" +#include "Logging.h" #include #include @@ -75,9 +76,7 @@ bool getBool(QJsonValue value, bool & out) { bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString name) { qDebug() << "Parsing" << name <<":"; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error) { @@ -137,9 +136,7 @@ bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString na bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { qDebug() << "Parsing Minecraft profile..."; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); @@ -275,9 +272,7 @@ decoded base64 "value": bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { qDebug() << "Parsing Minecraft profile..."; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); @@ -389,9 +384,7 @@ bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) { bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) { qDebug() << "Parsing Minecraft entitlements..."; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); @@ -424,9 +417,7 @@ bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) bool parseRolloutResponse(QByteArray & data, bool& result) { qDebug() << "Parsing Rollout response..."; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); @@ -455,9 +446,7 @@ bool parseRolloutResponse(QByteArray & data, bool& result) { bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) { QJsonParseError jsonError; qDebug() << "Parsing Mojang response..."; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error) { qWarning() << "Failed to parse response from api.minecraftservices.com/launcher/login as JSON: " << jsonError.errorString(); diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.cpp b/launcher/minecraft/auth/steps/EntitlementsStep.cpp index f726244fa..bd6042926 100644 --- a/launcher/minecraft/auth/steps/EntitlementsStep.cpp +++ b/launcher/minecraft/auth/steps/EntitlementsStep.cpp @@ -3,6 +3,7 @@ #include #include +#include "Logging.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" @@ -41,9 +42,7 @@ void EntitlementsStep::onRequestDone( auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; // TODO: check presence of same entitlementsRequestId? // TODO: validate JWTs? diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp index 8c53f037f..8a26cbe77 100644 --- a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp +++ b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp @@ -2,9 +2,10 @@ #include +#include "Logging.h" +#include "minecraft/auth/AccountTask.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" -#include "minecraft/auth/AccountTask.h" #include "net/NetUtils.h" LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) { @@ -51,14 +52,10 @@ void LauncherLoginStep::onRequestDone( auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; if (Net::isApplicationError(error)) { emit finished( AccountTaskState::STATE_FAILED_SOFT, @@ -76,9 +73,7 @@ void LauncherLoginStep::onRequestDone( if(!Parsers::parseMojangResponse(data, m_data->yggdrasilToken)) { qWarning() << "Could not parse login_with_xbox response..."; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; emit finished( AccountTaskState::STATE_FAILED_SOFT, tr("Failed to parse the Minecraft access token response.") diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp index 16afcb427..6fc8d468e 100644 --- a/launcher/minecraft/auth/steps/MSAStep.cpp +++ b/launcher/minecraft/auth/steps/MSAStep.cpp @@ -42,6 +42,7 @@ #include "minecraft/auth/Parsers.h" #include "Application.h" +#include "Logging.h" using OAuth2 = Katabasis::DeviceFlow; using Activity = Katabasis::Activity; @@ -117,14 +118,12 @@ void MSAStep::onOAuthActivityChanged(Katabasis::Activity activity) { // Succeeded or did not invalidate tokens emit hideVerificationUriAndCode(); QVariantMap extraTokens = m_oauth2->extraTokens(); -#ifndef NDEBUG if (!extraTokens.isEmpty()) { - qDebug() << "Extra tokens in response:"; + qCDebug(authCredentials()) << "Extra tokens in response:"; foreach (QString key, extraTokens.keys()) { - qDebug() << "\t" << key << ":" << extraTokens.value(key); + qCDebug(authCredentials()) << "\t" << key << ":" << extraTokens.value(key); } } -#endif emit finished(AccountTaskState::STATE_WORKING, tr("Got ")); return; } diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp index b39b93266..6cfa7c1cf 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp +++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp @@ -2,6 +2,7 @@ #include +#include "Logging.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" @@ -40,9 +41,7 @@ void MinecraftProfileStep::onRequestDone( auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); -#ifndef NDEBUG - qDebug() << data; -#endif + 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) { diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp index 6a1eb7a0d..8c3785882 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp +++ b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp @@ -2,6 +2,7 @@ #include +#include "Logging.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" @@ -43,9 +44,7 @@ void MinecraftProfileStepMojang::onRequestDone( auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); -#ifndef NDEBUG - qDebug() << data; -#endif + 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) { diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp index 14bde47e0..b397b7349 100644 --- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp +++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp @@ -4,6 +4,7 @@ #include #include +#include "Logging.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" @@ -58,9 +59,7 @@ void XboxAuthorizationStep::onRequestDone( auto requestor = qobject_cast(QObject::sender()); requestor->deleteLater(); -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; if (Net::isApplicationError(error)) { diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.cpp b/launcher/minecraft/auth/steps/XboxProfileStep.cpp index 738fe1dbe..644c419b1 100644 --- a/launcher/minecraft/auth/steps/XboxProfileStep.cpp +++ b/launcher/minecraft/auth/steps/XboxProfileStep.cpp @@ -3,7 +3,7 @@ #include #include - +#include "Logging.h" #include "minecraft/auth/AuthRequest.h" #include "minecraft/auth/Parsers.h" #include "net/NetUtils.h" @@ -56,9 +56,7 @@ void XboxProfileStep::onRequestDone( if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; -#ifndef NDEBUG - qDebug() << data; -#endif + qCDebug(authCredentials()) << data; if (Net::isApplicationError(error)) { emit finished( AccountTaskState::STATE_FAILED_SOFT, @@ -74,9 +72,7 @@ void XboxProfileStep::onRequestDone( return; } -#ifndef NDEBUG - qDebug() << "XBox profile: " << data; -#endif + qCDebug(authCredentials()) << "XBox profile: " << data; emit finished(AccountTaskState::STATE_WORKING, tr("Got Xbox profile")); } diff --git a/libraries/katabasis/CMakeLists.txt b/libraries/katabasis/CMakeLists.txt index f764feb6a..643244ede 100644 --- a/libraries/katabasis/CMakeLists.txt +++ b/libraries/katabasis/CMakeLists.txt @@ -38,6 +38,15 @@ set( katabasis_PUBLIC include/katabasis/RequestParameter.h ) +ecm_qt_declare_logging_category(katabasis_PRIVATE + HEADER KatabasisLogging.h # NOTE: this won't be in src/, but CMAKE_BINARY_DIR/src isn't included by default so this should be fine + IDENTIFIER katabasisCredentials + CATEGORY_NAME "katabasis.credentials" + DEFAULT_SEVERITY Warning + DESCRIPTION "Secrets and credentials from Katabasis" + EXPORT "Katabasis" +) + add_library( Katabasis STATIC ${katabasis_PRIVATE} ${katabasis_PUBLIC} ) target_link_libraries(Katabasis Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Network) diff --git a/libraries/katabasis/include/katabasis/DeviceFlow.h b/libraries/katabasis/include/katabasis/DeviceFlow.h index b68c92e03..0401df3c0 100644 --- a/libraries/katabasis/include/katabasis/DeviceFlow.h +++ b/libraries/katabasis/include/katabasis/DeviceFlow.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/libraries/katabasis/src/DeviceFlow.cpp b/libraries/katabasis/src/DeviceFlow.cpp index f78fd6200..f49fcb7d7 100644 --- a/libraries/katabasis/src/DeviceFlow.cpp +++ b/libraries/katabasis/src/DeviceFlow.cpp @@ -19,9 +19,11 @@ #include "katabasis/PollServer.h" #include "katabasis/Globals.h" +#include "KatabasisLogging.h" #include "JsonResponse.h" namespace { + // ref: https://tools.ietf.org/html/rfc8628#section-3.2 // Exception: Google sign-in uses "verification_url" instead of "*_uri" - we'll accept both. bool hasMandatoryDeviceAuthParams(const QVariantMap& params) @@ -333,9 +335,7 @@ QString DeviceFlow::refreshToken() { } void DeviceFlow::setRefreshToken(const QString &v) { -#ifndef NDEBUG - qDebug() << "DeviceFlow::setRefreshToken" << v << "..."; -#endif + qCDebug(katabasisCredentials) << "new refresh token:" << v; token_.refresh_token = v; } From 4438684ce6e3ffc51f21bb33f4c2d77ac206ac7f Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 7 Jan 2023 12:57:35 -0300 Subject: [PATCH 21/38] Merge pull request #713 from redstrate/fix-html-rendering --- launcher/ui/pages/modplatform/ModPage.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 677bc4d66..75be25b2d 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -428,6 +428,10 @@ void ModPage::updateUi() text += "
"; HoeDown h; + + // hoedown bug: it doesn't handle markdown surrounded by block tags (like center, div) so strip them + current.extraData.body.remove(QRegularExpression("<[^>]*(?:center|div)\\W*>")); + ui->packDescription->setHtml(text + (current.extraData.body.isEmpty() ? current.description : h.process(current.extraData.body.toUtf8()))); ui->packDescription->flush(); } From 3fc63fa196f02475ecf3687356f1e24a30c9bd7f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 7 Jan 2023 17:18:10 +0100 Subject: [PATCH 22/38] Merge pull request #710 from byquanton/develop Fixes https://github.com/PrismLauncher/PrismLauncher/issues/708 --- launcher/modplatform/technic/TechnicPackProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/modplatform/technic/TechnicPackProcessor.cpp b/launcher/modplatform/technic/TechnicPackProcessor.cpp index 95feb4b28..df713a725 100644 --- a/launcher/modplatform/technic/TechnicPackProcessor.cpp +++ b/launcher/modplatform/technic/TechnicPackProcessor.cpp @@ -172,7 +172,7 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const auto libraryObject = Json::ensureObject(library, {}, ""); auto libraryName = Json::ensureString(libraryObject, "name", "", ""); - if (libraryName.startsWith("net.minecraftforge:forge:") && 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-")) From c3d64aa98407586c19b073ccff1709853a4c2417 Mon Sep 17 00:00:00 2001 From: flow Date: Sun, 8 Jan 2023 11:33:13 -0300 Subject: [PATCH 23/38] Merge pull request #716 from DioEgizio/qt6.4.2-winmsvc closes https://github.com/PrismLauncher/PrismLauncher/issues/288 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ba5d0e48..324ad08ce 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: qt_ver: 6 qt_host: windows qt_arch: '' - qt_version: '6.4.0' + qt_version: '6.4.2' qt_modules: 'qt5compat qtimageformats' qt_tools: '' @@ -73,7 +73,7 @@ jobs: qt_ver: 6 qt_host: windows qt_arch: 'win64_msvc2019_arm64' - qt_version: '6.4.0' + qt_version: '6.4.2' qt_modules: 'qt5compat qtimageformats' qt_tools: '' From a8611a56fcdae153c05e3f11678d464435c40adf Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 10 Jan 2023 08:48:17 +0100 Subject: [PATCH 24/38] Merge pull request #726 from TheLastRar/qt6-win-darkmode Closes https://github.com/PrismLauncher/PrismLauncher/issues/158 --- launcher/Application.cpp | 16 +------- launcher/CMakeLists.txt | 10 ----- launcher/ui/WinDarkmode.cpp | 32 --------------- launcher/ui/WinDarkmode.h | 60 ----------------------------- launcher/ui/themes/ThemeManager.cpp | 17 -------- 5 files changed, 1 insertion(+), 134 deletions(-) delete mode 100644 launcher/ui/WinDarkmode.cpp delete mode 100644 launcher/ui/WinDarkmode.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index ff34a168d..9d528d7a5 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -62,11 +62,6 @@ #include "ui/pages/global/APIPage.h" #include "ui/pages/global/CustomCommandsPage.h" -#ifdef Q_OS_WIN -#include "ui/WinDarkmode.h" -#include -#endif - #include "ui/setupwizard/SetupWizard.h" #include "ui/setupwizard/LanguageWizardPage.h" #include "ui/setupwizard/JavaWizardPage.h" @@ -1353,16 +1348,7 @@ MainWindow* Application::showMainWindow(bool minimized) m_mainWindow = new MainWindow(); m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); -#ifdef Q_OS_WIN - if (IsWindows10OrGreater()) - { - if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); - } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); - } - } -#endif + if(minimized) { m_mainWindow->showMinimized(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 6ca88ec60..b6e3872ef 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -923,16 +923,6 @@ SET(LAUNCHER_SOURCES ui/instanceview/VisualGroup.h ) -if(WIN32) - set(LAUNCHER_SOURCES - ${LAUNCHER_SOURCES} - - # GUI - dark titlebar for Windows 10/11 - ui/WinDarkmode.h - ui/WinDarkmode.cpp - ) -endif() - qt_wrap_ui(LAUNCHER_UI ui/setupwizard/PasteWizardPage.ui ui/pages/global/AccountListPage.ui diff --git a/launcher/ui/WinDarkmode.cpp b/launcher/ui/WinDarkmode.cpp deleted file mode 100644 index eac68e4f6..000000000 --- a/launcher/ui/WinDarkmode.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -#include "WinDarkmode.h" - -namespace WinDarkmode { - -/* See https://github.com/statiolake/neovim-qt/commit/da8eaba7f0e38b6b51f3bacd02a8cc2d1f7a34d8 */ -void setDarkWinTitlebar(WId winid, bool darkmode) -{ - HWND hwnd = reinterpret_cast(winid); - BOOL dark = (BOOL) darkmode; - - HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - HMODULE hUser32 = GetModuleHandleW(L"user32.dll"); - fnAllowDarkModeForWindow AllowDarkModeForWindow - = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133))); - fnSetPreferredAppMode SetPreferredAppMode - = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135))); - fnSetWindowCompositionAttribute SetWindowCompositionAttribute - = reinterpret_cast(GetProcAddress(hUser32, "SetWindowCompositionAttribute")); - - SetPreferredAppMode(AllowDark); - AllowDarkModeForWindow(hwnd, dark); - WINDOWCOMPOSITIONATTRIBDATA data = { - WCA_USEDARKMODECOLORS, - &dark, - sizeof(dark) - }; - SetWindowCompositionAttribute(hwnd, &data); -} - -} diff --git a/launcher/ui/WinDarkmode.h b/launcher/ui/WinDarkmode.h deleted file mode 100644 index 5b567c6b0..000000000 --- a/launcher/ui/WinDarkmode.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include -#include - - -namespace WinDarkmode { - -void setDarkWinTitlebar(WId winid, bool darkmode); - -enum PreferredAppMode { - Default, - AllowDark, - ForceDark, - ForceLight, - Max -}; - -enum WINDOWCOMPOSITIONATTRIB { - WCA_UNDEFINED = 0, - WCA_NCRENDERING_ENABLED = 1, - WCA_NCRENDERING_POLICY = 2, - WCA_TRANSITIONS_FORCEDISABLED = 3, - WCA_ALLOW_NCPAINT = 4, - WCA_CAPTION_BUTTON_BOUNDS = 5, - WCA_NONCLIENT_RTL_LAYOUT = 6, - WCA_FORCE_ICONIC_REPRESENTATION = 7, - WCA_EXTENDED_FRAME_BOUNDS = 8, - WCA_HAS_ICONIC_BITMAP = 9, - WCA_THEME_ATTRIBUTES = 10, - WCA_NCRENDERING_EXILED = 11, - WCA_NCADORNMENTINFO = 12, - WCA_EXCLUDED_FROM_LIVEPREVIEW = 13, - WCA_VIDEO_OVERLAY_ACTIVE = 14, - WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15, - WCA_DISALLOW_PEEK = 16, - WCA_CLOAK = 17, - WCA_CLOAKED = 18, - WCA_ACCENT_POLICY = 19, - WCA_FREEZE_REPRESENTATION = 20, - WCA_EVER_UNCLOAKED = 21, - WCA_VISUAL_OWNER = 22, - WCA_HOLOGRAPHIC = 23, - WCA_EXCLUDED_FROM_DDA = 24, - WCA_PASSIVEUPDATEMODE = 25, - WCA_USEDARKMODECOLORS = 26, - WCA_LAST = 27 -}; - -struct WINDOWCOMPOSITIONATTRIBDATA { - WINDOWCOMPOSITIONATTRIB Attrib; - PVOID pvData; - SIZE_T cbData; -}; - -using fnAllowDarkModeForWindow = BOOL (WINAPI *)(HWND hWnd, BOOL allow); -using fnSetPreferredAppMode = PreferredAppMode (WINAPI *)(PreferredAppMode appMode); -using fnSetWindowCompositionAttribute = BOOL (WINAPI *)(HWND hwnd, WINDOWCOMPOSITIONATTRIBDATA *); - -} diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 01a38a864..5a6124727 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -28,14 +28,6 @@ #include "Application.h" -#ifdef Q_OS_WIN -#include -// this is needed for versionhelpers.h, it is also included in WinDarkmode, but we can't rely on that. -// Ultimately this should be included in versionhelpers, but that is outside of the project. -#include "ui/WinDarkmode.h" -#include -#endif - ThemeManager::ThemeManager(MainWindow* mainWindow) { m_mainWindow = mainWindow; @@ -140,15 +132,6 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial) auto& theme = themeIter->second; themeDebugLog() << "applying theme" << theme->name(); theme->apply(initial); -#ifdef Q_OS_WIN - if (m_mainWindow && IsWindows10OrGreater()) { - if (QString::compare(theme->id(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); - } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); - } - } -#endif } else { themeWarningLog() << "Tried to set invalid theme:" << name; } From 4539d58d7d81879678cf959fa46302acaa9a686e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 11 Jan 2023 09:49:20 +0100 Subject: [PATCH 25/38] Merge pull request #731 from flowln/windows_server_trash --- launcher/FileSystem.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 3e8e10a51..e3111f4ee 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -234,6 +235,10 @@ bool trash(QString path, QString *pathInTrash = nullptr) // FIXME: Figure out trash in Flatpak. Qt seemingly doesn't use the Trash portal if (DesktopServices::isFlatpak()) return false; +#if defined Q_OS_WIN32 + if (IsWindowsServer()) + return false; +#endif return QFile::moveToTrash(path, pathInTrash); #endif } From d16b6fe634d9302da22f4acde8e1b521ea204339 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 12 Jan 2023 16:31:03 +0100 Subject: [PATCH 26/38] Merge pull request #732 from DioEgizio/actually-fix-openssl3-mac-failures --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 324ad08ce..c46e0153f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,6 +105,7 @@ jobs: INSTALL_APPIMAGE_DIR: "install-appdir" BUILD_DIR: "build" CCACHE_VAR: "" + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 steps: ## From bf9885dd7e2e7bcda900b2259b9591902deada4e Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 14 Jan 2023 12:19:12 -0300 Subject: [PATCH 27/38] Merge pull request #743 from flowln/fix_mods_with_wrong_modListVersion --- launcher/minecraft/mod/tasks/LocalModParseTask.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 774f61145..2ef76dceb 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -16,7 +16,7 @@ namespace { // NEW format -// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/6f62b37cea040daf350dc253eae6326dd9c822c3 +// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/c8d8f1929aff9979e322af79a59ce81f3e02db6a // OLD format: // https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc @@ -73,10 +73,11 @@ ModDetails ReadMCModInfo(QByteArray contents) version = Json::ensureString(val, "").toInt(); if (version != 2) { - qCritical() << "BAD stuff happened to mod json:"; - qCritical() << contents; - return {}; + qWarning() << QString(R"(The value of 'modListVersion' is "%1" (expected "2")! The file may be corrupted.)").arg(version); + qWarning() << "The contents of 'mcmod.info' are as follows:"; + qWarning() << contents; } + auto arrVal = jsonDoc.object().value("modlist"); if (arrVal.isUndefined()) { arrVal = jsonDoc.object().value("modList"); From 642908847252eaa13d3f4733500c0f4b00ab1f0f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 14 Jan 2023 17:17:49 +0100 Subject: [PATCH 28/38] Merge pull request #746 from RaptaG/patch-1 --- COPYING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING.md b/COPYING.md index 75a5c0eb3..544b9591a 100644 --- a/COPYING.md +++ b/COPYING.md @@ -1,7 +1,7 @@ ## Prism Launcher Prism Launcher - Minecraft Launcher - Copyright (C) 2022 Prism Launcher Contributors + Copyright (C) 2022-2023 Prism Launcher Contributors 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 c5ce8bfb3eee8b5bc8b85a3f9be96de1f64ddf96 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 23 Jan 2023 00:07:34 +0100 Subject: [PATCH 29/38] Merge pull request #772 from TheLastRar/zlib-fallback-bundled-fix Fix: zlib fallback not working --- CMakeLists.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d2f3c4fe..fec3848e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,9 +208,15 @@ set(Launcher_BUILD_TIMESTAMP "${TODAY}") ################################ 3rd Party Libs ################################ -if(NOT Launcher_FORCE_BUNDLED_LIBS) +# Successive configurations of cmake without cleaning the build dir will cause zlib fallback to fail due to cached values +# Record when fallback triggered and skip this find_package +if(NOT Launcher_FORCE_BUNDLED_LIBS AND NOT FORCE_BUNDLED_ZLIB) find_package(ZLIB QUIET) endif() +if(NOT ZLIB_FOUND) + set(FORCE_BUNDLED_ZLIB TRUE CACHE BOOL "") + mark_as_advanced(FORCE_BUNDLED_ZLIB) +endif() # Find the required Qt parts include(QtVersionlessBackport) @@ -377,13 +383,14 @@ add_subdirectory(libraries/systeminfo) # system information library add_subdirectory(libraries/hoedown) # markdown parser add_subdirectory(libraries/launcher) # java based launcher part for Minecraft add_subdirectory(libraries/javacheck) # java compatibility checker -if(NOT ZLIB_FOUND) +if(FORCE_BUNDLED_ZLIB) message(STATUS "Using bundled zlib") + set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) # Suppress cmake warnings and allow INTERPROCEDURAL_OPTIMIZATION for zlib set(SKIP_INSTALL_ALL ON) add_subdirectory(libraries/zlib EXCLUDE_FROM_ALL) - set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib" "${CMAKE_CURRENT_BINARY_DIR}/libraries/zlib" CACHE STRING "") + set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib" "${CMAKE_CURRENT_BINARY_DIR}/libraries/zlib" CACHE STRING "" FORCE) set_target_properties(zlibstatic PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIR}") add_library(ZLIB::ZLIB ALIAS zlibstatic) set(ZLIB_LIBRARY ZLIB::ZLIB CACHE STRING "zlib library name") From 92f6a34624ffb7635482c09a24a80983bb9c8043 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 23 Jan 2023 23:58:41 +0100 Subject: [PATCH 30/38] Merge pull request #758 from flowln/fix_process_events_backstab --- launcher/tasks/ConcurrentTask.cpp | 4 +-- tests/Task_test.cpp | 60 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp index a890013ef..190d48d8f 100644 --- a/launcher/tasks/ConcurrentTask.cpp +++ b/launcher/tasks/ConcurrentTask.cpp @@ -110,14 +110,14 @@ void ConcurrentTask::startNext() setStepStatus(next->isMultiStep() ? next->getStepStatus() : next->getStatus()); updateState(); + 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 = m_total_max_size - m_doing.size(); for (int i = 0; i < num_starts; i++) QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); - - QCoreApplication::processEvents(); } void ConcurrentTask::subTaskSucceeded(Task::Ptr task) diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index 80bba02fc..6649b7248 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -11,6 +13,9 @@ class BasicTask : public Task { friend class TaskTest; + public: + BasicTask(bool show_debug_log = true) : Task(nullptr, show_debug_log) {} + private: void executeTask() override { @@ -30,6 +35,42 @@ class BasicTask_MultiStep : public Task { void executeTask() override {}; }; +class BigConcurrentTask : public QThread { + Q_OBJECT + + ConcurrentTask big_task; + + void run() override + { + QTimer deadline; + deadline.setInterval(10000); + 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. + static const unsigned s_num_tasks = 1 << 14; + auto sub_tasks = new BasicTask*[s_num_tasks]; + + for (unsigned i = 0; i < s_num_tasks; i++) { + sub_tasks[i] = new BasicTask(false); + big_task.addTask(sub_tasks[i]); + } + + big_task.run(); + + while (!big_task.isFinished() && !passed_the_deadline) + QCoreApplication::processEvents(); + + emit finished(); + } + + public: + bool passed_the_deadline = false; + + signals: + void finished(); +}; + class TaskTest : public QObject { Q_OBJECT @@ -183,6 +224,25 @@ class TaskTest : public QObject { return t.isFinished(); }, 1000), "Task didn't finish as it should."); } + + void test_stackOverflowInConcurrentTask() + { + QEventLoop loop; + + auto thread = new BigConcurrentTask; + // NOTE: This is an arbitrary value, big enough to not cause problems on normal execution, but low enough + // so that the number of tasks that needs to get ran to potentially cause a problem isn't too big. + thread->setStackSize(32 * 1024); + + connect(thread, &BigConcurrentTask::finished, &loop, &QEventLoop::quit); + + thread->start(); + + loop.exec(); + + QVERIFY(!thread->passed_the_deadline); + thread->deleteLater(); + } }; QTEST_GUILESS_MAIN(TaskTest) From 4827f7e3179fa72ab63f5333f934e763af6653b5 Mon Sep 17 00:00:00 2001 From: flow Date: Tue, 24 Jan 2023 11:15:33 -0800 Subject: [PATCH 31/38] Merge pull request #781 from Ryex/patch-1 --- launcher/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 9d528d7a5..e38a7ff59 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1525,7 +1525,8 @@ QString Application::getJarPath(QString jarFile) FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_APP_BINARY_NAME), #endif FS::PathCombine(m_rootPath, "jars"), - FS::PathCombine(applicationDirPath(), "jars") + FS::PathCombine(applicationDirPath(), "jars"), + FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging }; for(QString p : potentialPaths) { From 16b48866f4e2c06584851271897ad6ef7d96ef7e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 25 Jan 2023 10:33:01 +0100 Subject: [PATCH 32/38] Merge pull request #784 from flowln/fix_resource_folder_double_smart_ptrs --- launcher/minecraft/mod/ResourceFolderModel.cpp | 8 ++++---- launcher/tasks/ConcurrentTask.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index a52c5db34..fdfb434bb 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -260,7 +260,7 @@ void ResourceFolderModel::resolveResource(Resource* res) return; } - auto task = createParseTask(*res); + Task::Ptr task{ createParseTask(*res) }; if (!task) return; @@ -270,11 +270,11 @@ void ResourceFolderModel::resolveResource(Resource* res) m_active_parse_tasks.insert(ticket, task); connect( - task, &Task::succeeded, this, [=] { onParseSucceeded(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); + task.get(), &Task::succeeded, this, [=] { onParseSucceeded(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); connect( - task, &Task::failed, this, [=] { onParseFailed(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); + task.get(), &Task::failed, this, [=] { onParseFailed(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection); connect( - task, &Task::finished, this, [=] { m_active_parse_tasks.remove(ticket); }, Qt::ConnectionType::QueuedConnection); + task.get(), &Task::finished, this, [=] { m_active_parse_tasks.remove(ticket); }, Qt::ConnectionType::QueuedConnection); m_helper_thread_task.addTask(task); diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp index 190d48d8f..3cc37b2a2 100644 --- a/launcher/tasks/ConcurrentTask.cpp +++ b/launcher/tasks/ConcurrentTask.cpp @@ -115,7 +115,7 @@ void ConcurrentTask::startNext() 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 = m_total_max_size - m_doing.size(); + 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); } From b7e96bdf62edcffc9ecc35fb2036cc8be36d2ef1 Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 25 Jan 2023 11:53:51 -0800 Subject: [PATCH 33/38] Merge pull request #779 from TheLastRar/zlib-undo-rename --- CMakeLists.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fec3848e9..2bb1dc531 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -389,8 +389,18 @@ if(FORCE_BUNDLED_ZLIB) set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) # Suppress cmake warnings and allow INTERPROCEDURAL_OPTIMIZATION for zlib set(SKIP_INSTALL_ALL ON) add_subdirectory(libraries/zlib EXCLUDE_FROM_ALL) - - set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib" "${CMAKE_CURRENT_BINARY_DIR}/libraries/zlib" CACHE STRING "" FORCE) + + # On OS where unistd.h exists, zlib's generated header defines `Z_HAVE_UNISTD_H`, while the included header does not. + # We cannot safely undo the rename on those systems, and they generally have packages for zlib anyway. + check_include_file(unistd.h NEED_GENERATED_ZCONF) + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib/zconf.h.included" AND NOT NEED_GENERATED_ZCONF) + # zlib's cmake script renames a file, dirtying the submodule, see https://github.com/madler/zlib/issues/162 + message(STATUS "Undoing Rename") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib/zconf.h") + file(RENAME "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib/zconf.h.included" "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib/zconf.h") + endif() + + set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/libraries/zlib" "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib" CACHE STRING "" FORCE) set_target_properties(zlibstatic PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIR}") add_library(ZLIB::ZLIB ALIAS zlibstatic) set(ZLIB_LIBRARY ZLIB::ZLIB CACHE STRING "zlib library name") From 68c884f20d03f917211165d89e0c39069b5976e1 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 2 Feb 2023 13:47:36 -0800 Subject: [PATCH 34/38] Merge pull request #810 from flowln/error_on_bad_file_paths_as_we_should_catquake --- launcher/minecraft/OneSixVersionFormat.cpp | 11 +++++++++++ .../modrinth/ModrinthInstanceCreationTask.cpp | 19 ++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 280f6b269..c2e33f4b2 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -39,6 +39,8 @@ #include "minecraft/ParseUtils.h" #include +#include + using namespace Json; static void readString(const QJsonObject &root, const QString &key, QString &variable) @@ -121,6 +123,15 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc out->uid = root.value("fileId").toString(); } + const QRegularExpression valid_uid_regex{ QRegularExpression::anchoredPattern(QStringLiteral(R"(\w+(?:\.\w+)*)")) }; + 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->version = root.value("version").toString(); MojangVersionFormat::readVersionProperties(root, out.get()); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index c5a27c9dc..153d05742 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -225,10 +225,19 @@ bool ModrinthCreationTask::createInstance() m_files_job = new NetJob(tr("Mod download"), APPLICATION->network()); + auto root_modpack_path = FS::PathCombine(m_stagingPath, ".minecraft"); + auto root_modpack_url = QUrl::fromLocalFile(root_modpack_path); + for (auto file : m_files) { - auto path = FS::PathCombine(m_stagingPath, ".minecraft", file.path); - qDebug() << "Will try to download" << file.downloads.front() << "to" << path; - auto dl = Net::Download::makeFile(file.downloads.dequeue(), path); + 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)); + return false; + } + + qDebug() << "Will try to download" << file.downloads.front() << "to" << file_path; + auto dl = Net::Download::makeFile(file.downloads.dequeue(), file_path); dl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash)); m_files_job->addNetAction(dl); @@ -236,8 +245,8 @@ bool ModrinthCreationTask::createInstance() // FIXME: This really needs to be put into a ConcurrentTask of // MultipleOptionsTask's , once those exist :) auto param = dl.toWeakRef(); - connect(dl.get(), &NetAction::failed, [this, &file, path, param] { - auto ndl = Net::Download::makeFile(file.downloads.dequeue(), path); + connect(dl.get(), &NetAction::failed, [this, &file, file_path, param] { + 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(); From a7ff74365d76257168b04f7dbf991930554f5dad Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 2 Feb 2023 13:47:51 -0800 Subject: [PATCH 35/38] Merge pull request #804 from flowln/improve_big_concurrent_task_test --- tests/Task_test.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/tests/Task_test.cpp b/tests/Task_test.cpp index 6649b7248..fdf407257 100644 --- a/tests/Task_test.cpp +++ b/tests/Task_test.cpp @@ -7,6 +7,8 @@ #include #include +#include + /* Does nothing. Only used for testing. */ class BasicTask : public Task { Q_OBJECT @@ -35,10 +37,23 @@ class BasicTask_MultiStep : public Task { void executeTask() override {}; }; -class BigConcurrentTask : public QThread { +class BigConcurrentTask : public ConcurrentTask { Q_OBJECT - ConcurrentTask big_task; + void startNext() override + { + // 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 {}; + + ConcurrentTask::startNext(); + } +}; + +class BigConcurrentTaskThread : public QThread { + Q_OBJECT + + BigConcurrentTask big_task; void run() override { @@ -48,8 +63,10 @@ class BigConcurrentTask : public QThread { deadline.start(); // NOTE: Arbitrary value that manages to trigger a problem when there is one. - static const unsigned s_num_tasks = 1 << 14; - auto sub_tasks = new BasicTask*[s_num_tasks]; + // 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]; for (unsigned i = 0; i < s_num_tasks; i++) { sub_tasks[i] = new BasicTask(false); @@ -229,12 +246,9 @@ class TaskTest : public QObject { { QEventLoop loop; - auto thread = new BigConcurrentTask; - // NOTE: This is an arbitrary value, big enough to not cause problems on normal execution, but low enough - // so that the number of tasks that needs to get ran to potentially cause a problem isn't too big. - thread->setStackSize(32 * 1024); + auto thread = new BigConcurrentTaskThread; - connect(thread, &BigConcurrentTask::finished, &loop, &QEventLoop::quit); + connect(thread, &BigConcurrentTaskThread::finished, &loop, &QEventLoop::quit); thread->start(); From d8a84d2aa3e40072a0049b112f174a25b7af8a1f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 3 Feb 2023 10:58:17 +0100 Subject: [PATCH 36/38] chore: bump to 6.2 Signed-off-by: Sefa Eyeoglu --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bb1dc531..3e046f67a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRIN ######## Set version numbers ######## set(Launcher_VERSION_MAJOR 6) -set(Launcher_VERSION_MINOR 1) +set(Launcher_VERSION_MINOR 2) set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}") set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0") From bc376b22c72902847855facecb18887a4762ba39 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 3 Feb 2023 18:40:10 +0100 Subject: [PATCH 37/38] chore: bump to 6.3 Signed-off-by: Sefa Eyeoglu --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e046f67a..6ad6b9040 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRIN ######## Set version numbers ######## set(Launcher_VERSION_MAJOR 6) -set(Launcher_VERSION_MINOR 2) +set(Launcher_VERSION_MINOR 3) set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}") set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0") From 39bba9cbfadc0aac3ef571a80e78a9fa3f5a0028 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 3 Feb 2023 18:44:07 +0100 Subject: [PATCH 38/38] Merge pull request #815 from Scrumplex/fix-funny --- launcher/minecraft/OneSixVersionFormat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index c2e33f4b2..888b68609 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -123,7 +123,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc out->uid = root.value("fileId").toString(); } - const QRegularExpression valid_uid_regex{ QRegularExpression::anchoredPattern(QStringLiteral(R"(\w+(?:\.\w+)*)")) }; + 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(