aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml56
-rw-r--r--.github/workflows/trigger_release.yml9
-rw-r--r--CMakeLists.txt2
-rw-r--r--launcher/CMakeLists.txt2
-rw-r--r--launcher/Filter.cpp6
-rw-r--r--launcher/Filter.h10
-rw-r--r--launcher/minecraft/mod/ModFolderModel.cpp1
-rw-r--r--launcher/minecraft/mod/ResourceFolderModel.cpp2
-rw-r--r--launcher/minecraft/mod/ResourceFolderModel.h1
-rw-r--r--launcher/minecraft/mod/ResourcePackFolderModel.cpp2
-rw-r--r--launcher/minecraft/mod/TexturePackFolderModel.cpp1
-rw-r--r--launcher/resources/multimc/128x128/instances/forge.pngbin0 -> 3229 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/liteloader.pngbin0 -> 7619 bytes
-rw-r--r--launcher/resources/multimc/multimc.qrc5
-rw-r--r--launcher/resources/multimc/scalable/instances/fabricmc.svg71
-rw-r--r--launcher/resources/multimc/scalable/instances/quiltmc.svg98
-rw-r--r--launcher/ui/InstanceWindow.cpp8
-rw-r--r--launcher/ui/InstanceWindow.h4
-rw-r--r--launcher/ui/dialogs/InstallLoaderDialog.cpp164
-rw-r--r--launcher/ui/dialogs/InstallLoaderDialog.h45
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp28
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.h5
-rw-r--r--launcher/ui/dialogs/SkinUploadDialog.ui2
-rw-r--r--launcher/ui/dialogs/VersionSelectDialog.cpp12
-rw-r--r--launcher/ui/dialogs/VersionSelectDialog.h1
-rw-r--r--launcher/ui/pages/BasePageContainer.h1
-rw-r--r--launcher/ui/pages/global/ExternalToolsPage.ui8
-rw-r--r--launcher/ui/pages/global/JavaPage.ui150
-rw-r--r--launcher/ui/pages/global/LauncherPage.ui8
-rw-r--r--launcher/ui/pages/instance/InstanceSettingsPage.ui62
-rw-r--r--launcher/ui/pages/instance/VersionPage.cpp130
-rw-r--r--launcher/ui/pages/instance/VersionPage.h5
-rw-r--r--launcher/ui/pages/instance/VersionPage.ui62
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.cpp4
-rw-r--r--launcher/ui/widgets/JavaSettingsWidget.cpp3
-rw-r--r--launcher/ui/widgets/PageContainer.cpp10
-rw-r--r--launcher/ui/widgets/PageContainer.h8
-rw-r--r--launcher/ui/widgets/PageContainer_p.h2
-rw-r--r--launcher/ui/widgets/VersionSelectWidget.cpp28
-rw-r--r--launcher/ui/widgets/VersionSelectWidget.h6
-rw-r--r--launcher/ui/widgets/WideBar.cpp4
41 files changed, 680 insertions, 346 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a7b8f652..fc223a07 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -24,6 +24,12 @@ on:
CACHIX_AUTH_TOKEN:
description: Private token for authenticating against Cachix cache
required: false
+ GPG_PRIVATE_KEY:
+ description: Private key for AppImage signing
+ required: false
+ GPG_PRIVATE_KEY_ID:
+ description: ID for the GPG_PRIVATE_KEY, to select the signing key
+ required: false
jobs:
build:
@@ -249,6 +255,8 @@ jobs:
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage"
wget "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage"
+ wget "https://github.com/AppImageCommunity/AppImageUpdate/releases/download/continuous/AppImageUpdate-x86_64.AppImage"
+
${{ github.workspace }}/.github/scripts/prepare_JREs.sh
sudo apt install libopengl0
@@ -387,8 +395,8 @@ jobs:
cd ${{ env.INSTALL_DIR }}
if ("${{ matrix.qt_ver }}" -eq "5")
{
- Copy-Item D:/a/PrismLauncher/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll -Destination libcrypto-1_1.dll
- Copy-Item D:/a/PrismLauncher/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll -Destination libssl-1_1.dll
+ Copy-Item ${{ runner.workspace }}/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll -Destination libcrypto-1_1.dll
+ Copy-Item ${{ runner.workspace }}/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll -Destination libssl-1_1.dll
}
cd ${{ github.workspace }}
@@ -425,7 +433,7 @@ jobs:
run: |
cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }} # cmake install on Windows is slow, let's just copy instead
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
-
+
Get-ChildItem ${{ env.INSTALL_PORTABLE_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_PORTABLE_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt
- name: Package (Windows, installer)
@@ -466,11 +474,15 @@ jobs:
- name: Package AppImage (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5
shell: bash
+ env:
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
run: |
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr
+
mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.appdata.xml
export "NO_APPSTREAM=1" # we have to skip appstream checking because appstream on ubuntu 20.04 is outdated
- export OUTPUT="PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage"
+
+ export OUTPUT="PrismLauncher-Linux-x86_64.AppImage"
chmod +x linuxdeploy-*.AppImage
@@ -481,8 +493,8 @@ jobs:
cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk
- cp -r /home/runner/work/PrismLauncher/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
-
+ cp -r ${{ runner.workspace }}/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
+
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
@@ -494,8 +506,33 @@ jobs:
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib"
export LD_LIBRARY_PATH
+ chmod +x AppImageUpdate-x86_64.AppImage
+ ./AppImageUpdate-x86_64.AppImage --appimage-extract
+
+ mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/optional
+ mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins
+
+ cp -r squashfs-root/usr/bin/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin
+ cp -r squashfs-root/usr/lib/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib
+ cp -r squashfs-root/usr/optional/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/optional
+ cp -r squashfs-root/usr/optional/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins
+
+ export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|PrismLauncher-Linux-x86_64.AppImage.zsync"
+
+ if [ '${{ secrets.GPG_PRIVATE_KEY_ID }}' != '' ]; then
+ export SIGN=1
+ export SIGN_KEY=${{ secrets.GPG_PRIVATE_KEY_ID }}
+ mkdir -p ~/.gnupg/
+ printf "$GPG_PRIVATE_KEY" | base64 --decode > ~/.gnupg/private.key
+ gpg --import ~/.gnupg/private.key
+ else
+ echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY
+ fi
+
./linuxdeploy-x86_64.AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.prismlauncher.PrismLauncher.svg
+ mv "PrismLauncher-Linux-x86_64.AppImage" "PrismLauncher-Linux-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage"
+
##
# UPLOAD BUILDS
##
@@ -562,6 +599,13 @@ jobs:
with:
name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
path: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
+
+ - name: Upload AppImage Zsync (Linux)
+ if: runner.os == 'Linux' && matrix.qt_ver != 5
+ uses: actions/upload-artifact@v3
+ with:
+ name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage.zsync
+ path: PrismLauncher-Linux-x86_64.AppImage.zsync
- name: ccache stats (Windows MinGW-w64)
if: runner.os == 'Windows' && matrix.msystem != ''
diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml
index f19b8398..2a46ff5e 100644
--- a/.github/workflows/trigger_release.yml
+++ b/.github/workflows/trigger_release.yml
@@ -43,7 +43,8 @@ jobs:
mv PrismLauncher-Linux-Qt6*/PrismLauncher.tar.gz PrismLauncher-Linux-Qt6-${{ env.VERSION }}.tar.gz
mv PrismLauncher-Linux-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Portable-${{ env.VERSION }}.tar.gz
mv PrismLauncher-Linux*/PrismLauncher.tar.gz PrismLauncher-Linux-${{ env.VERSION }}.tar.gz
- mv PrismLauncher-*.AppImage/PrismLauncher-*.AppImage PrismLauncher-Linux-${{ env.VERSION }}-x86_64.AppImage
+ mv PrismLauncher-*.AppImage/PrismLauncher-*.AppImage PrismLauncher-Linux-x86_64.AppImage
+ mv PrismLauncher-*.AppImage.zsync/PrismLauncher-*.AppImage.zsync PrismLauncher-Linux-x86_64.AppImage.zsync
mv PrismLauncher-macOS-Legacy*/PrismLauncher.tar.gz PrismLauncher-macOS-Legacy-${{ env.VERSION }}.tar.gz
mv PrismLauncher-macOS*/PrismLauncher.tar.gz PrismLauncher-macOS-${{ env.VERSION }}.tar.gz
@@ -78,9 +79,8 @@ jobs:
- name: Create release
id: create_release
uses: softprops/action-gh-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
+ token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ github.ref }}
name: Prism Launcher ${{ env.VERSION }}
draft: true
@@ -88,7 +88,8 @@ jobs:
files: |
PrismLauncher-Linux-${{ env.VERSION }}.tar.gz
PrismLauncher-Linux-Portable-${{ env.VERSION }}.tar.gz
- PrismLauncher-Linux-${{ env.VERSION }}-x86_64.AppImage
+ PrismLauncher-Linux-x86_64.AppImage
+ PrismLauncher-Linux-x86_64.AppImage.zsync
PrismLauncher-Linux-Qt6-${{ env.VERSION }}.tar.gz
PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
PrismLauncher-Windows-MinGW-w64-${{ env.VERSION }}.zip
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 350189c8..17f7c3d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -85,7 +85,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0")
# set CXXFLAGS for build targets
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}")
-option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" on)
+option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" OFF)
# If this is a Debug build turn on address sanitiser
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER)
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index a01c5ef0..5255f9d3 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -974,6 +974,8 @@ SET(LAUNCHER_SOURCES
ui/dialogs/ChooseProviderDialog.cpp
ui/dialogs/ModUpdateDialog.cpp
ui/dialogs/ModUpdateDialog.h
+ ui/dialogs/InstallLoaderDialog.cpp
+ ui/dialogs/InstallLoaderDialog.h
# GUI - widgets
ui/widgets/Common.cpp
diff --git a/launcher/Filter.cpp b/launcher/Filter.cpp
index c65ca0ce..f9530597 100644
--- a/launcher/Filter.cpp
+++ b/launcher/Filter.cpp
@@ -16,6 +16,12 @@ bool ExactFilter::accepts(const QString& value)
return value == pattern;
}
+ExactIfPresentFilter::ExactIfPresentFilter(const QString& pattern) : pattern(pattern) {}
+bool ExactIfPresentFilter::accepts(const QString& value)
+{
+ return value.isEmpty() || value == pattern;
+}
+
RegexpFilter::RegexpFilter(const QString& regexp, bool invert)
:invert(invert)
{
diff --git a/launcher/Filter.h b/launcher/Filter.h
index b55067ac..d3cee2d8 100644
--- a/launcher/Filter.h
+++ b/launcher/Filter.h
@@ -30,6 +30,16 @@ private:
QString pattern;
};
+class ExactIfPresentFilter: public Filter
+{
+ public:
+ ExactIfPresentFilter(const QString& pattern);
+ ~ExactIfPresentFilter() override = default;
+ bool accepts(const QString& value) override;
+ private:
+ QString pattern;
+};
+
class RegexpFilter: public Filter
{
public:
diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp
index 51383edf..4300ce50 100644
--- a/launcher/minecraft/mod/ModFolderModel.cpp
+++ b/launcher/minecraft/mod/ModFolderModel.cpp
@@ -61,6 +61,7 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME , SortType::VERSION, SortType::DATE, SortType::PROVIDER};
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents};
+ m_columnsHideable = { false, true, false, true, true, true };
}
QVariant ModFolderModel::data(const QModelIndex &index, int role) const
diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp
index 39a61067..d834c359 100644
--- a/launcher/minecraft/mod/ResourceFolderModel.cpp
+++ b/launcher/minecraft/mod/ResourceFolderModel.cpp
@@ -552,6 +552,8 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree)
menu->addSeparator()->setText(tr("Show / Hide Columns"));
for (int col = 0; col < columnCount(); ++col) {
+ // Skip creating actions for columns that should not be hidden
+ if (!m_columnsHideable.at(col)) continue;
auto act = new QAction(menu);
setupHeaderAction(act, col);
diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h
index 454b84c3..ec334a08 100644
--- a/launcher/minecraft/mod/ResourceFolderModel.h
+++ b/launcher/minecraft/mod/ResourceFolderModel.h
@@ -202,6 +202,7 @@ class ResourceFolderModel : public QAbstractListModel {
QStringList m_column_names = {"Enable", "Name", "Last Modified"};
QStringList m_column_names_translated = {tr("Enable"), tr("Name"), tr("Last Modified")};
QList<QHeaderView::ResizeMode> m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch, QHeaderView::ResizeToContents };
+ QList<bool> m_columnsHideable = { false, false, true };
QDir m_dir;
BaseInstance* m_instance;
diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp
index 41455599..c8770d54 100644
--- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp
+++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp
@@ -54,7 +54,7 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE};
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents };
-
+ m_columnsHideable = { false, true, false, true, true };
}
QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const
diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp
index 531a7023..28fe0a46 100644
--- a/launcher/minecraft/mod/TexturePackFolderModel.cpp
+++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp
@@ -49,6 +49,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance*
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents};
+ m_columnsHideable = { false, true, false, true };
}
diff --git a/launcher/resources/multimc/128x128/instances/forge.png b/launcher/resources/multimc/128x128/instances/forge.png
new file mode 100644
index 00000000..d8ff79a5
--- /dev/null
+++ b/launcher/resources/multimc/128x128/instances/forge.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/liteloader.png b/launcher/resources/multimc/128x128/instances/liteloader.png
new file mode 100644
index 00000000..646217de
--- /dev/null
+++ b/launcher/resources/multimc/128x128/instances/liteloader.png
Binary files differ
diff --git a/launcher/resources/multimc/multimc.qrc b/launcher/resources/multimc/multimc.qrc
index 2c00f28f..8f079bb3 100644
--- a/launcher/resources/multimc/multimc.qrc
+++ b/launcher/resources/multimc/multimc.qrc
@@ -347,5 +347,10 @@
<file>scalable/export.svg</file>
<file>scalable/launch.svg</file>
<file>scalable/server.svg</file>
+
+ <file>scalable/instances/quiltmc.svg</file> <!-- CC0 QuiltMC -->
+ <file>scalable/instances/fabricmc.svg</file> <!-- CC0 unascribed, https://github.com/FabricMC/community/blob/main/media/unascribed/README.md -->
+ <file>128x128/instances/forge.png</file> <!-- LGPL3 Forge Development LLC -->
+ <file>128x128/instances/liteloader.png</file> <!-- CC-BY-SA 4.0 LiteLoader -->
</qresource>
</RCC>
diff --git a/launcher/resources/multimc/scalable/instances/fabricmc.svg b/launcher/resources/multimc/scalable/instances/fabricmc.svg
new file mode 100644
index 00000000..7bfc7548
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/fabricmc.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="128"
+ height="128"
+ version="1.1"
+ viewBox="0 0 33.867 33.867"
+ xml:space="preserve"
+ id="svg252"
+ sodipodi:docname="fabricmc.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs256" /><sodipodi:namedview
+ id="namedview254"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="2.8284271"
+ inkscape:cx="39.421203"
+ inkscape:cy="132.22897"
+ inkscape:window-width="2560"
+ inkscape:window-height="1386"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g2166" /><g
+ id="g2166"><path
+ style="fill:#38342a;fill-opacity:1;stroke-width:0;stroke-linejoin:round"
+ d="m 16.9336,2.1165994 c 0.705567,0 1.411134,0 2.116701,0 0,0.7055667 0,1.4111333 0,2.1167 0.705566,0 1.411132,0 2.116698,0 0,0.7055665 0,1.4111331 0,2.1166996 0.705567,0 1.411134,0 2.116701,0 0,0.7055667 0,1.4111333 0,2.1167 0.705567,0 1.411133,0 2.1167,0 0,0.705567 0,1.411134 0,2.116701 0.705567,0 1.411133,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 0.705567,0 1.411133,0 2.1167,0 0,1.4111 0,2.8222 0,4.2333 -0.7056,-3.3e-5 -1.4112,-6.7e-5 -2.1168,-10e-5 0,0.705567 0,1.411133 0,2.1167 -1.4111,0 -2.8222,0 -4.2333,0 0,0.705567 0,1.411133 0,2.1167 -0.705567,0 -1.411134,0 -2.116701,0 0,0.705567 0,1.411133 0,2.1167 -0.705566,0 -1.411132,0 -2.116698,0 0,0.705567 0,1.411134 0,2.116701 -0.705567,0 -1.411134,0 -2.116701,0 -3.4e-5,1.411133 -6.7e-5,2.822266 -1.01e-4,4.233399 -0.705567,0 -1.411133,0 -2.1167,0 0,0.705567 0,1.411134 0,2.116701 -1.4111,0 -2.822199,0 -4.233299,0 3.4e-5,-0.705567 6.7e-5,-1.411134 1.01e-4,-2.116701 -0.705567,0 -1.411134,0 -2.116701,0 0,-0.705567 0,-1.411134 0,-2.116701 -0.705567,0 -1.411134,0 -2.116701,0 0,-0.705566 0,-1.411132 0,-2.116698 -0.705567,0 -1.411134,0 -2.116701,0 0,-0.705567 0,-1.411134 0,-2.116701 -0.705566,0 -1.411132,0 -2.116698,0 0,-1.4111 0,-2.8222 0,-4.2333 0.705566,0 1.411132,0 2.116698,0 0,-0.705567 0,-1.411133 0,-2.1167 0.705567,0 1.411134,0 2.116701,0 0,-0.705567 0,-1.411133 0,-2.1167 0.705567,0 1.411134,0 2.116701,0 0,-0.705567 0,-1.411133 0,-2.1167 0.705567,0 1.411134,0 2.116701,0 0,-0.705567 0,-1.411133 0,-2.1167 0.705566,0 1.411132,0 2.116698,0 0,-0.705567 0,-1.411134 0,-2.116701 0.705567,0 1.411134,0 2.116701,0 -3.4e-5,-1.4110999 -6.7e-5,-2.8221997 -1.01e-4,-4.2332996 0.705567,0 1.411134,0 2.116701,0 0,-0.7055667 0,-1.4111333 0,-2.1167 z"
+ id="path1587-0" /><rect
+ x="25.400299"
+ y="14.8166"
+ width="2.1166999"
+ height="2.1166999"
+ fill="#807a6d"
+ id="rect246-7"
+ style="stroke-width:0" /><path
+ id="path1670"
+ style="fill:#dbd0b4;fill-opacity:1;stroke-width:0;stroke-linejoin:round"
+ d="m 4.233501,21.166701 2.1167,-2.117 6.09e-4,-2.1165 2.1161,-10e-5 6.09e-4,-2.1166 2.116099,-10e-5 6.09e-4,-2.1166 h 2.115899 l 2.1168,-2.117 6.72e-4,-2.1164 2.1159,-10e-5 v 2.1167 l 2.1171,10e-5 -3.97e-4,2.1166 2.1171,1e-4 v 2.1167 l 2.1167,2.11665 -11.642055,11.642008"
+ sodipodi:nodetypes="cccccccccccccccccc" /><path
+ style="fill:#dbd0b4;fill-opacity:1;stroke-width:0;stroke-linejoin:round"
+ d="m 16.9336,4.2332985 c 0.705333,-6.65e-5 1.410667,-1.329e-4 2.116,-1.994e-4 0,0.7055666 0,1.4111333 0,2.1166999 0.7058,6.67e-5 1.411599,1.333e-4 2.117399,2e-4 -2.29e-4,0.7055 -4.59e-4,1.411 -6.88e-4,2.1165 0.7058,6.63e-5 1.4116,1.327e-4 2.1174,1.99e-4 -2.29e-4,0.7055003 -4.59e-4,1.4110007 -6.88e-4,2.116501 0.705567,0 1.411133,0 2.1167,0 -0.0492,0.747877 0.09844,1.542199 -0.07194,2.26148 -0.32867,0.65734 -0.65734,1.31468 -0.98601,1.97202 -0.429296,-0.748959 -0.696496,-1.614758 -1.230307,-2.288382 -2.059217,-2.059636 -4.118734,-4.1189729 -6.178143,-6.178418 9.3e-5,-0.7055335 1.87e-4,-1.411067 2.8e-4,-2.1166005 z"
+ id="path2115" /><path
+ d="m 12.700401,25.400025 h 2.1167 v 2.1167 h -2.1167 z m 2.1167,-4.2333 v 4.2333 h 2.1167 v -2.1167 h 2.1167 v -2.1167 c -1.411133,-1.9e-5 -2.822267,1.4e-5 -4.2334,10e-5 z m 6.35,-6.35 v 2.1167 h -2.1167 v 4.2333 h 2.1167 v -2.1167 h 2.1167 v -4.2333 z m 2.1167,-2.1167 h 2.1167 v 2.1167 h -2.1167 z m -2.1167,-2.1167 h 2.1167 v 2.1167 h -2.1167 z m -2.1167,-2.1167 h 2.1167 v 2.1167 h -2.1167 z m -2.1167,-2.1167 h 2.1167 v 2.1167 h -2.1167 z"
+ fill="#bcb29c"
+ id="path238-2"
+ style="stroke-width:0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccc" /><path
+ d="m 10.583601,27.516801 c 0.705567,0 1.411133,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.705567,0 -1.411133,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z m -2.1167,-2.1167 c 0.7055667,0 1.4111333,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.7055667,0 -1.4111333,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z m -2.1167,-2.1167 c 0.7055667,0 1.4111333,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.7055667,0 -1.4111333,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z m -2.1167,-2.1167 c 0.7055667,0 1.4111333,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.7055667,0 -1.4111333,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z"
+ fill="#9a927e"
+ id="path240-6"
+ style="stroke-width:0" /><path
+ d="m 10.583701,25.400025 c 0.705567,0 1.411133,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.705567,0 -1.411133,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z m -2.1167,-2.1167 c 0.7055667,0 1.4111333,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.7055667,0 -1.4111333,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z m -2.1167,-2.1167 c 0.7055667,0 1.4111333,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.7055667,0 -1.4111333,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z m -2.1167,-2.1167 c 0.7055667,0 1.4111333,0 2.1167,0 0,0.705567 0,1.411133 0,2.1167 -0.7055667,0 -1.4111333,0 -2.1167,0 0,-0.705567 0,-1.411133 0,-2.1167 z"
+ fill="#aea694"
+ id="path244-1"
+ style="stroke-width:0" /><path
+ d="m 10.583751,16.933325 h 2.1167 v 2.1167 h -2.1167 z m 2.1167,2.1167 v 2.1167 h 4.2333 v -2.1167 z m 4.2333,-4.2333 v 2.1167 h 4.2333 v -2.1167 z m -2.1167,-2.1167 h 2.1167 v 2.1167 h -2.1167 z m -2.1167,-2.1167 h 2.1167 v 2.1167 h -2.1167 z"
+ fill="#c6bca5"
+ id="path248-8"
+ style="stroke-width:0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/quiltmc.svg b/launcher/resources/multimc/scalable/instances/quiltmc.svg
new file mode 100644
index 00000000..a7aaca53
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/quiltmc.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ id="Layer_1"
+ data-name="Layer 1"
+ viewBox="0 0 23.999999 23.999999"
+ version="1.1"
+ sodipodi:docname="quiltmc.svg"
+ width="24"
+ height="24"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview27"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="10.390684"
+ inkscape:cx="24.685575"
+ inkscape:cy="9.5277659"
+ inkscape:window-width="1499"
+ inkscape:window-height="749"
+ inkscape:window-x="100"
+ inkscape:window-y="118"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Layer_1" />
+ <defs
+ id="defs4">
+ <style
+ id="style2">.cls-1{fill:#1b112b;}.cls-2{fill:#9722ff;}.cls-3{fill:#dc29dd;}.cls-4{fill:#27a2fd;}.cls-5{fill:#34f;}</style>
+ </defs>
+ <rect
+ class="cls-1"
+ width="24"
+ height="24"
+ rx="5.9670944"
+ id="rect6"
+ x="0"
+ y="0"
+ style="stroke-width:0.0262717" />
+ <path
+ class="cls-2"
+ d="M 8.53568,6.3874419 A 0.27217496,0.27217496 0 0 0 8.8075922,6.6593542 H 9.2699744 V 7.6928834 H 8.8075922 a 0.27191225,0.27191225 0 0 0 0,0.5438245 H 9.2699744 V 9.0293255 A 0.24091162,0.24091162 0 0 1 9.0290628,9.2702371 H 8.2364452 V 8.807855 a 0.27191225,0.27191225 0 0 0 -0.5438245,0 V 9.2702371 H 6.6590914 V 8.807855 a 0.27191224,0.27191224 0 0 0 -0.5438244,0 V 9.2702371 H 5.3226493 A 0.24117434,0.24117434 0 0 1 5.0817377,9.0293255 V 5.322912 A 0.24091162,0.24091162 0 0 1 5.3226493,5.0820004 H 9.0290628 A 0.2406489,0.2406489 0 0 1 9.2699744,5.322912 V 6.115267 H 8.8075922 A 0.27217496,0.27217496 0 0 0 8.53568,6.3874419 Z"
+ id="path8"
+ style="stroke-width:0.0262717" />
+ <path
+ class="cls-3"
+ d="m 13.267216,6.3874419 a 0.27191224,0.27191224 0 0 0 0.271912,0.2719123 h 0.463696 v 1.0335292 h -0.462382 a 0.27191225,0.27191225 0 0 0 0,0.5438245 h 0.462382 V 9.0293255 A 0.24117434,0.24117434 0 0 1 13.761912,9.2702371 H 10.054973 A 0.24091162,0.24091162 0 0 1 9.8140616,9.0293255 V 8.2367079 h 0.4621194 a 0.27191225,0.27191225 0 1 0 0,-0.5438245 H 9.8140616 V 6.6593542 h 0.4621194 a 0.27217496,0.27217496 0 1 0 0,-0.5440872 H 9.8140616 V 5.322912 A 0.2406489,0.2406489 0 0 1 10.054973,5.0820004 h 3.706414 a 0.24091162,0.24091162 0 0 1 0.240911,0.2409116 v 0.792355 h -0.462382 a 0.27191224,0.27191224 0 0 0 -0.2727,0.2721749 z"
+ id="path10"
+ style="stroke-width:0.0262717" />
+ <path
+ class="cls-4"
+ d="M 18.73436,5.322912 V 9.0293255 A 0.24091162,0.24091162 0 0 1 18.493448,9.2702371 H 17.70083 V 8.807855 a 0.27191224,0.27191224 0 0 0 -0.543824,0 V 9.2702371 H 16.123477 V 8.807855 a 0.27191251,0.27191251 0 0 0 -0.543825,0 V 9.2702371 H 14.787034 A 0.24117434,0.24117434 0 0 1 14.546123,9.0293255 V 8.2367079 h 0.462382 a 0.27191225,0.27191225 0 1 0 0,-0.5438245 H 14.546123 V 6.6593542 h 0.462382 a 0.27217496,0.27217496 0 0 0 0,-0.5440872 H 14.546123 V 5.322912 a 0.24091162,0.24091162 0 0 1 0.240911,-0.2409116 h 3.706414 A 0.2406489,0.2406489 0 0 1 18.73436,5.322912 Z"
+ id="path12"
+ style="stroke-width:0.0262717" />
+ <path
+ class="cls-3"
+ d="m 9.2699744,10.054973 v 3.706414 A 0.2406489,0.2406489 0 0 1 9.0290628,14.002298 H 8.2364452 v -0.462382 a 0.27191225,0.27191225 0 1 0 -0.5438245,0 v 0.462908 H 6.6590914 v -0.462382 a 0.27191224,0.27191224 0 0 0 -0.5438244,0 v 0.462382 H 5.3226493 A 0.24091162,0.24091162 0 0 1 5.0817377,13.761912 V 10.054973 A 0.24117434,0.24117434 0 0 1 5.3226493,9.8140616 H 6.115267 v 0.4623824 a 0.27191224,0.27191224 0 0 0 0.5438244,0 V 9.81406