aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/winget.yml2
-rw-r--r--CMakeLists.txt19
-rw-r--r--launcher/ApplicationMessage.cpp8
-rw-r--r--launcher/ApplicationMessage.h4
-rw-r--r--launcher/InstanceImportTask.cpp74
-rw-r--r--launcher/icons/IconList.cpp19
-rw-r--r--launcher/icons/IconList.h1
-rw-r--r--launcher/modplatform/flame/FlameInstanceCreationTask.cpp4
-rw-r--r--launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp4
-rw-r--r--launcher/ui/MainWindow.cpp2
-rw-r--r--launcher/ui/dialogs/IconPickerDialog.cpp6
-rw-r--r--launcher/ui/dialogs/IconPickerDialog.h1
-rw-r--r--launcher/ui/pages/instance/ManagedPackPage.cpp19
-rw-r--r--launcher/ui/widgets/VariableSizedImageObject.cpp2
14 files changed, 103 insertions, 62 deletions
diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml
index 5c34040f..b4136df5 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 }}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2bdd4811..de9b6fe1 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
@@ -129,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 6)
+set(Launcher_VERSION_MAJOR 7)
set(Launcher_VERSION_MINOR 0)
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
diff --git a/launcher/ApplicationMessage.cpp b/launcher/ApplicationMessage.cpp
index ca276b89..700e43ce 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 745bdead..d66456eb 100644
--- a/launcher/ApplicationMessage.h
+++ b/launcher/ApplicationMessage.h
@@ -1,12 +1,12 @@
#pragma once
#include <QString>
-#include <QMap>
+#include <QHash>
#include <QByteArray>
struct ApplicationMessage {
QString command;
- QMap<QString, QString> args;
+ QHash<QString, QString> args;
QByteArray serialize();
void parse(const QByteArray & input);
diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp
index b97870da..6b3fd296 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();
-
- 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();
-
- auto* inst_creation_task = new FlameCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
+ 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();
+
+ 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();
+
+ 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();
-
- 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();
+ 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 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();
+
+ 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);
+ }
- auto* inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
+ // 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/icons/IconList.cpp b/launcher/icons/IconList.cpp
index 01043ad2..1dfc6432 100644
--- a/launcher/icons/IconList.cpp
+++ b/launcher/icons/IconList.cpp
@@ -354,15 +354,18 @@ const MMCIcon *IconList::icon(const QString &key) const
bool IconList::deleteIcon(const QString &key)
{
- int iconIdx = getIconIndex(key);
- if (iconIdx == -1)
+ if (!iconFileExists(key))
return false;
- auto &iconEntry = icons[iconIdx];
- if (iconEntry.has(IconType::FileBased))
- {
- return QFile::remove(iconEntry.m_images[IconType::FileBased].filename);
- }
- return false;
+
+ return QFile::remove(icon(key)->getFilePath());
+}
+
+bool IconList::trashIcon(const QString &key)
+{
+ if (!iconFileExists(key))
+ return false;
+
+ return FS::trash(icon(key)->getFilePath(), nullptr);
}
bool IconList::addThemeIcon(const QString& key)
diff --git a/launcher/icons/IconList.h b/launcher/icons/IconList.h
index f9f49e7f..97141e4a 100644
--- a/launcher/icons/IconList.h
+++ b/launcher/icons/IconList.h
@@ -52,6 +52,7 @@ public:
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);
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 729268d7..1d441f09 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 1c0e8979..5632f6a3 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();
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 2f1976cc..3651aa15 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);
})")
diff --git a/launcher/ui/dialogs/IconPickerDialog.cpp b/launcher/ui/dialogs/IconPickerDialog.cpp
index 6fa26508..5131686a 100644
--- a/launcher/ui/dialogs/IconPickerDialog.cpp
+++ b/launcher/ui/dialogs/IconPickerDialog.cpp
@@ -62,7 +62,7 @@ IconPickerDialog::IconPickerDialog(QWidget *parent)
// NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win.
auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole);
- auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole);
+ buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole);
connect(buttonAdd, SIGNAL(clicked(bool)), SLOT(addNewIcon()));
connect(buttonRemove, SIGNAL(clicked(bool)), SLOT(removeSelectedIcon()));
@@ -110,6 +110,9 @@ void IconPickerDialog::addNewIcon()
void IconPickerDialog::removeSelectedIcon()
{
+ if (APPLICATION->icons()->trashIcon(selectedIconKey))
+ return;
+
APPLICATION->icons()->deleteIcon(selectedIconKey);
}
@@ -128,6 +131,7 @@ void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection
if (!key.isEmpty()) {
selectedIconKey = key;
}
+ buttonRemove->setEnabled(APPLICATION->icons()->iconFileExists(selectedIconKey));
}
int IconPickerDialog::execWithSelection(QString selection)
diff --git a/launcher/ui/dialogs/IconPickerDialog.h b/launcher/ui/dialogs/IconPickerDialog.h
index 9af6a678..c93f565f 100644
--- a/launcher/ui/dialogs/IconPickerDialog.h
+++ b/launcher/ui/dialogs/IconPickerDialog.h
@@ -37,6 +37,7 @@ protected:
private:
Ui::IconPickerDialog *ui;
+ QPushButton *buttonRemove;
private
slots:
diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp
index 7a0d234c..4de80468 100644
--- a/launcher/ui/pages/instance/ManagedPackPage.cpp
+++ b/launcher/ui/pages/instance/ManagedPackPage.cpp
@@ -7,6 +7,7 @@
#include <QListView>
#include <QProxyStyle>
+#include <QStyleFactory>
#include <HoeDown.h>
@@ -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){
@@ -223,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));
}
@@ -370,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));
}
diff --git a/launcher/ui/widgets/VariableSizedImageObject.cpp b/launcher/ui/widgets/VariableSizedImageObject.cpp
index e57f7e95..991b4a04 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.