aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/CMakeLists.txt1
-rw-r--r--launcher/InstancePageProvider.h2
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp16
-rw-r--r--launcher/minecraft/MinecraftInstance.h3
-rw-r--r--launcher/minecraft/WorldList.cpp3
-rw-r--r--launcher/minecraft/auth/flows/AuthContext.cpp33
-rw-r--r--launcher/minecraft/legacy/LegacyModList.cpp2
-rw-r--r--launcher/minecraft/mod/ModFolderModel.cpp2
-rw-r--r--launcher/modplatform/modpacksch/FTBPackInstallTask.cpp4
-rwxr-xr-xlauncher/package/ubuntu/multimc/opt/multimc/run.sh2
-rw-r--r--launcher/pages/instance/ShaderPackPage.h22
-rw-r--r--launcher/resources/OSX/OSX.qrc1
-rw-r--r--launcher/resources/OSX/scalable/custom-commands.svg71
-rw-r--r--launcher/resources/iOS/iOS.qrc1
-rw-r--r--launcher/resources/iOS/scalable/custom-commands.svg63
-rw-r--r--launcher/resources/pe_blue/pe_blue.qrc1
-rw-r--r--launcher/resources/pe_blue/scalable/custom-commands.svg336
-rw-r--r--launcher/resources/pe_colored/pe_colored.qrc2
-rw-r--r--launcher/resources/pe_colored/scalable/custom-commands.svg345
-rw-r--r--launcher/resources/pe_colored/scalable/shaderpacks.svg83
-rw-r--r--launcher/resources/pe_dark/pe_dark.qrc1
-rw-r--r--launcher/resources/pe_dark/scalable/custom-commands.svg335
-rw-r--r--launcher/resources/pe_light/pe_light.qrc1
-rw-r--r--launcher/resources/pe_light/scalable/custom-commands.svg336
24 files changed, 1644 insertions, 22 deletions
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index c29ee3e1..14704905 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -653,6 +653,7 @@ SET(MULTIMC_SOURCES
pages/instance/VersionPage.h
pages/instance/TexturePackPage.h
pages/instance/ResourcePackPage.h
+ pages/instance/ShaderPackPage.h
pages/instance/ModFolderPage.cpp
pages/instance/ModFolderPage.h
pages/instance/NotesPage.cpp
diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h
index 3cb723c4..d45b3f2e 100644
--- a/launcher/InstancePageProvider.h
+++ b/launcher/InstancePageProvider.h
@@ -9,6 +9,7 @@
#include "pages/instance/ModFolderPage.h"
#include "pages/instance/ResourcePackPage.h"
#include "pages/instance/TexturePackPage.h"
+#include "pages/instance/ShaderPackPage.h"
#include "pages/instance/NotesPage.h"
#include "pages/instance/ScreenshotsPage.h"
#include "pages/instance/InstanceSettingsPage.h"
@@ -44,6 +45,7 @@ public:
values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods"));
values.append(new ResourcePackPage(onesix.get()));
values.append(new TexturePackPage(onesix.get()));
+ values.append(new ShaderPackPage(onesix.get()));
values.append(new NotesPage(onesix.get()));
values.append(new WorldListPage(onesix.get(), onesix->worldList()));
values.append(new ServersPage(onesix));
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index 5f3c7244..f86269f0 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -222,6 +222,11 @@ QString MinecraftInstance::texturePacksDir() const
return FS::PathCombine(gameRoot(), "texturepacks");
}
+QString MinecraftInstance::shaderPacksDir() const
+{
+ return FS::PathCombine(gameRoot(), "shaderpacks");
+}
+
QString MinecraftInstance::instanceConfigFolder() const
{
return FS::PathCombine(gameRoot(), "config");
@@ -1010,6 +1015,17 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::texturePackList() const
return m_texture_pack_list;
}
+std::shared_ptr<ModFolderModel> MinecraftInstance::shaderPackList() const
+{
+ if (!m_shader_pack_list)
+ {
+ m_shader_pack_list.reset(new ResourcePackFolderModel(shaderPacksDir()));
+ m_shader_pack_list->disableInteraction(isRunning());
+ connect(this, &BaseInstance::runningStatusChanged, m_shader_pack_list.get(), &ModFolderModel::disableInteraction);
+ }
+ return m_shader_pack_list;
+}
+
std::shared_ptr<WorldList> MinecraftInstance::worldList() const
{
if (!m_world_list)
diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h
index b55a2776..cdfd350b 100644
--- a/launcher/minecraft/MinecraftInstance.h
+++ b/launcher/minecraft/MinecraftInstance.h
@@ -39,6 +39,7 @@ public:
QString jarModsDir() const;
QString resourcePacksDir() const;
QString texturePacksDir() const;
+ QString shaderPacksDir() const;
QString loaderModsDir() const;
QString coreModsDir() const;
QString modsCacheLocation() const;
@@ -71,6 +72,7 @@ public:
std::shared_ptr<ModFolderModel> coreModList() const;
std::shared_ptr<ModFolderModel> resourcePackList() const;
std::shared_ptr<ModFolderModel> texturePackList() const;
+ std::shared_ptr<ModFolderModel> shaderPackList() const;
std::shared_ptr<WorldList> worldList() const;
std::shared_ptr<GameOptions> gameOptionsModel() const;
@@ -124,6 +126,7 @@ protected: // data
mutable std::shared_ptr<ModFolderModel> m_loader_mod_list;
mutable std::shared_ptr<ModFolderModel> m_core_mod_list;
mutable std::shared_ptr<ModFolderModel> m_resource_pack_list;
+ mutable std::shared_ptr<ModFolderModel> m_shader_pack_list;
mutable std::shared_ptr<ModFolderModel> m_texture_pack_list;
mutable std::shared_ptr<WorldList> m_world_list;
mutable std::shared_ptr<GameOptions> m_game_options;
diff --git a/launcher/minecraft/WorldList.cpp b/launcher/minecraft/WorldList.cpp
index f6309dbd..dcdbc321 100644
--- a/launcher/minecraft/WorldList.cpp
+++ b/launcher/minecraft/WorldList.cpp
@@ -26,8 +26,7 @@ WorldList::WorldList(const QString &dir)
: QAbstractListModel(), m_dir(dir)
{
FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
m_watcher = new QFileSystemWatcher(this);
is_watching = false;
diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp
index b4db6c2d..47908b70 100644
--- a/launcher/minecraft/auth/flows/AuthContext.cpp
+++ b/launcher/minecraft/auth/flows/AuthContext.cpp
@@ -23,7 +23,6 @@
#include "Env.h"
using OAuth2 = Katabasis::OAuth2;
-using Requestor = AuthRequest;
using Activity = Katabasis::Activity;
AuthContext::AuthContext(AccountData * data, QObject *parent) :
@@ -164,8 +163,8 @@ void AuthContext::doUserAuth() {
QNetworkRequest request = QNetworkRequest(QUrl("https://user.auth.xboxlive.com/user/authenticate"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Accept", "application/json");
- auto *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onUserAuthDone);
+ auto *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onUserAuthDone);
requestor->post(request, xbox_auth_data.toUtf8());
qDebug() << "First layer of XBox auth ... commencing.";
}
@@ -358,8 +357,8 @@ void AuthContext::doSTSAuthMinecraft() {
QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Accept", "application/json");
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onSTSAuthMinecraftDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onSTSAuthMinecraftDone);
requestor->post(request, xbox_auth_data.toUtf8());
qDebug() << "Getting Minecraft services STS token...";
}
@@ -428,8 +427,8 @@ void AuthContext::doMinecraftAuth() {
QNetworkRequest request = QNetworkRequest(QUrl("https://api.minecraftservices.com/authentication/login_with_xbox"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Accept", "application/json");
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onMinecraftAuthDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftAuthDone);
requestor->post(request, data.toUtf8());
qDebug() << "Getting Minecraft access token...";
}
@@ -518,8 +517,8 @@ void AuthContext::doSTSAuthGeneric() {
QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Accept", "application/json");
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onSTSAuthGenericDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onSTSAuthGenericDone);
requestor->post(request, xbox_auth_data.toUtf8());
qDebug() << "Getting generic STS token...";
}
@@ -574,8 +573,8 @@ void AuthContext::doXBoxProfile() {
request.setRawHeader("Accept", "application/json");
request.setRawHeader("x-xbl-contract-version", "3");
request.setRawHeader("Authorization", QString("XBL3.0 x=%1;%2").arg(m_data->userToken.extra["uhs"].toString(), m_data->xboxApiToken.token).toUtf8());
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onXBoxProfileDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onXBoxProfileDone);
requestor->get(request);
qDebug() << "Getting Xbox profile...";
}
@@ -753,8 +752,8 @@ void AuthContext::doMinecraftProfile() {
// request.setRawHeader("Accept", "application/json");
request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8());
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onMinecraftProfileDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftProfileDone);
requestor->get(request);
}
@@ -801,8 +800,8 @@ void AuthContext::doMigrationEligibilityCheck() {
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8());
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onMigrationEligibilityCheckDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onMigrationEligibilityCheckDone);
requestor->get(request);
}
@@ -853,8 +852,8 @@ void AuthContext::doGetSkin() {
auto url = QUrl(m_data->minecraftProfile.skin.url);
QNetworkRequest request = QNetworkRequest(url);
- Requestor *requestor = new Requestor(this);
- connect(requestor, &Requestor::finished, this, &AuthContext::onSkinDone);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &AuthContext::onSkinDone);
requestor->get(request);
}
diff --git a/launcher/minecraft/legacy/LegacyModList.cpp b/launcher/minecraft/legacy/LegacyModList.cpp
index 7301eb8c..e9948ab1 100644
--- a/launcher/minecraft/legacy/LegacyModList.cpp
+++ b/launcher/minecraft/legacy/LegacyModList.cpp
@@ -22,7 +22,7 @@ LegacyModList::LegacyModList(const QString &dir, const QString &list_file)
: m_dir(dir), m_list_file(list_file)
{
FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs | QDir::NoSymLinks);
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
}
diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp
index 031eebe5..f0c53c39 100644
--- a/launcher/minecraft/mod/ModFolderModel.cpp
+++ b/launcher/minecraft/mod/ModFolderModel.cpp
@@ -29,7 +29,7 @@
ModFolderModel::ModFolderModel(const QString &dir) : QAbstractListModel(), m_dir(dir)
{
FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs | QDir::NoSymLinks);
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
m_watcher = new QFileSystemWatcher(this);
connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
index f22373bc..2e87a754 100644
--- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
@@ -108,6 +108,10 @@ void PackInstallTask::downloadPack()
auto relpath = FS::PathCombine("minecraft", file.path, file.name);
auto path = FS::PathCombine(m_stagingPath, relpath);
+ if (filesToCopy.contains(entry->getFullPath())) {
+ qWarning() << "Ignoring" << file.url << "as a file of that path is already downloading.";
+ continue;
+ }
qDebug() << "Will download" << file.url << "to" << path;
filesToCopy[entry->getFullPath()] = path;
diff --git a/launcher/package/ubuntu/multimc/opt/multimc/run.sh b/launcher/package/ubuntu/multimc/opt/multimc/run.sh
index c493a513..12a9b45c 100755
--- a/launcher/package/ubuntu/multimc/opt/multimc/run.sh
+++ b/launcher/package/ubuntu/multimc/opt/multimc/run.sh
@@ -22,7 +22,7 @@ deploy() {
runmmc() {
cd ${INSTDIR}
- ./MultiMC "$@"
+ exec ./MultiMC "$@"
}
if [[ ! -f ${INSTDIR}/MultiMC ]]; then
diff --git a/launcher/pages/instance/ShaderPackPage.h b/launcher/pages/instance/ShaderPackPage.h
new file mode 100644
index 00000000..36724992
--- /dev/null
+++ b/launcher/pages/instance/ShaderPackPage.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "ModFolderPage.h"
+#include "ui_ModFolderPage.h"
+
+class ShaderPackPage : public ModFolderPage
+{
+ Q_OBJECT
+public:
+ explicit ShaderPackPage(MinecraftInstance *instance, QWidget *parent = 0)
+ : ModFolderPage(instance, instance->shaderPackList(), "shaderpacks",
+ "shaderpacks", tr("Shader packs"), "Resource-packs", parent)
+ {
+ ui->actionView_configs->setVisible(false);
+ }
+ virtual ~ShaderPackPage() {}
+
+ virtual bool shouldDisplay() const override
+ {
+ return true;
+ }
+};
diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc
index 19fd4b6a..1a6ec0dc 100644
--- a/launcher/resources/OSX/OSX.qrc
+++ b/launcher/resources/OSX/OSX.qrc
@@ -9,6 +9,7 @@
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
diff --git a/launcher/resources/OSX/scalable/custom-commands.svg b/launcher/resources/OSX/scalable/custom-commands.svg
new file mode 100644
index 00000000..e663452b
--- /dev/null
+++ b/launcher/resources/OSX/scalable/custom-commands.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 24 24"
+ enable-background="new 0 0 24 24"
+ xml:space="preserve"
+ sodipodi:docname="custom_commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ 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"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
+ id="namedview12"
+ pagecolor="#505050"
+ bordercolor="#eeeeee"
+ borderopacity="1"
+ inkscape:pageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="33.791667"
+ inkscape:cx="12.014797"
+ inkscape:cy="16.734895"
+ inkscape:window-width="3440"
+ inkscape:window-height="1382"
+ inkscape:window-x="0"
+ inkscape:window-y="32"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Calque_1" /><metadata
+ id="metadata22"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs20" /><path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ fill="#E6E6E6"
+ d="M21,20H9c-1.1,0-2-0.9-2-2V6c0-1.1,0.9-2,2-2h12c1.1,0,2,0.9,2,2 v12C23,19.1,22.1,20,21,20z"
+ id="path2" /><rect
+ fill="none"
+ width="24"
+ height="24"
+ id="rect4" /><g
+ id="_x36__8_"><g
+ id="g8"><path
+ d="M 21,4 H 9 C 7.9,4 7,4.9 7,6 v 12 c 0,1.1 0.9,2 2,2 h 12 c 1.1,0 2,-0.9 2,-2 V 6 C 23,4.9 22.1,4 21,4 Z m 1,14 -1,1 H 9 L 8,18 V 6 C 8,5.4 8.4,5 9,5 h 12 c 0.6,0 1,0.4 1,1 z"
+ id="path6"
+ style="fill:#585858" /></g></g><circle
+ cx="-3.8492424"
+ cy="11.559504"
+ r="1"
+ id="circle11"
+ style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd" /><g
+ id="g856"
+ style="fill:#585858;fill-opacity:1"
+ transform="matrix(0.01889997,0,0,0.01889997,10.039419,7.0394194)"><g
+ id="g854"
+ style="fill:#585858;fill-opacity:1"><path
+ inkscape:connector-curvature="0"
+ id="path850"
+ d="m 226.434,249.503 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 L 61.8,74.165 c -5.128,-5.141 -11.554,-7.852 -18.568,-7.852 -7.026,0 -13.452,2.717 -18.556,7.846 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 L 129.267,249.503 7.84,370.936 C 2.711,376.071 0,382.491 0,389.486 c 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
+ style="fill:#585858;fill-opacity:1" /><path
+ inkscape:connector-curvature="0"
+ id="path852"
+ d="m 498.866,384.951 h -323.02 c -7.203,0 -13.611,2.583 -18.581,7.528 -4.896,4.92 -7.484,11.327 -7.484,18.531 v 21.536 c 0,7.252 2.607,13.672 7.491,18.543 4.915,4.927 11.34,7.528 18.574,7.528 h 323.02 c 7.239,0 13.659,-2.607 18.531,-7.497 4.927,-4.908 7.533,-11.334 7.533,-18.58 v -21.537 c 0,-7.209 -2.589,-13.616 -7.54,-18.592 -4.913,-4.877 -11.321,-7.46 -18.524,-7.46 z"
+ style="fill:#585858;fill-opacity:1" /></g></g></svg>
diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc
index 511e390b..75c88bb0 100644
--- a/launcher/resources/iOS/iOS.qrc
+++ b/launcher/resources/iOS/iOS.qrc
@@ -9,6 +9,7 @@
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
diff --git a/launcher/resources/iOS/scalable/custom-commands.svg b/launcher/resources/iOS/scalable/custom-commands.svg
new file mode 100644
index 00000000..f44e2bfe
--- /dev/null
+++ b/launcher/resources/iOS/scalable/custom-commands.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xml:space="preserve"
+ enable-background="new 0 0 32 32"
+ viewBox="0 0 32 32"
+ y="0px"
+ x="0px"
+ id="Calque_1"
+ version="1.1"
+ sodipodi:docname="custom-commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ 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"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
+ id="namedview8"
+ pagecolor="#505050"
+ bordercolor="#eeeeee"
+ borderopacity="1"
+ inkscape:pageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="25.34375"
+ inkscape:cx="15.980271"
+ inkscape:cy="16"
+ inkscape:window-width="1720"
+ inkscape:window-height="1382"
+ inkscape:window-x="0"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Calque_1" /><metadata
+ id="metadata15"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs13" />
+<g
+ id="g8">
+
+ <path
+ id="path6"
+ d="M28,32H4c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h24c2.2,0,4,1.8,4,4 v24C32,30.2,30.2,32,28,32z M30,4c0-1.1-0.9-2-2-2H4C2.9,2,2,2.9,2,4v24c0,1.1,0.9,2,2,2h24c1.1,0,2-0.9,2-2V4z"
+ fill="#3366CC"
+ clip-rule="evenodd"
+ fill-rule="evenodd" />
+</g>
+<g
+ id="g856"
+ style="fill:#3366cc;fill-opacity:1"
+ transform="matrix(0.03343306,0,0,0.03343306,7.2249919,7.2249919)"><g
+ id="g854"
+ style="fill:#3366cc;fill-opacity:1"><path
+ inkscape:connector-curvature="0"
+ id="path850"
+ d="m 226.434,249.503 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 L 61.8,74.165 c -5.128,-5.141 -11.554,-7.852 -18.568,-7.852 -7.026,0 -13.452,2.717 -18.556,7.846 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 L 129.267,249.503 7.84,370.936 C 2.711,376.071 0,382.491 0,389.486 c 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
+ style="fill:#3366cc;fill-opacity:1" /><path
+ inkscape:connector-curvature="0"
+ id="path852"
+ d="m 498.866,384.951 h -323.02 c -7.203,0 -13.611,2.583 -18.581,7.528 -4.896,4.92 -7.484,11.327 -7.484,18.531 v 21.536 c 0,7.252 2.607,13.672 7.491,18.543 4.915,4.927 11.34,7.528 18.574,7.528 h 323.02 c 7.239,0 13.659,-2.607 18.531,-7.497 4.927,-4.908 7.533,-11.334 7.533,-18.58 v -21.537 c 0,-7.209 -2.589,-13.616 -7.54,-18.592 -4.913,-4.877 -11.321,-7.46 -18.524,-7.46 z"
+ style="fill:#3366cc;fill-opacity:1" /></g></g></svg>
diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc
index 98445d88..2a685979 100644
--- a/launcher/resources/pe_blue/pe_blue.qrc
+++ b/launcher/resources/pe_blue/pe_blue.qrc
@@ -9,6 +9,7 @@
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
diff --git a/launcher/resources/pe_blue/scalable/custom-commands.svg b/launcher/resources/pe_blue/scalable/custom-commands.svg
new file mode 100644
index 00000000..be76ece9
--- /dev/null
+++ b/launcher/resources/pe_blue/scalable/custom-commands.svg
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ id="svg2"
+ height="32"
+ width="32"
+ version="1.1"
+ sodipodi:docname="custom-commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <sodipodi:namedview
+ pagecolor="#505050"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1720"
+ inkscape:window-height="1382"
+ id="namedview52"
+ showgrid="false"
+ inkscape:zoom="20.85965"
+ inkscape:cx="20.901597"
+ inkscape:cy="20.829688"
+ inkscape:window-x="1720"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:bbox-nodes="true"
+ inkscape:pagecheckerboard="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid858" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3931">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3933" />
+ <stop
+ offset="0.69999987"
+ style="stop-color:#ffffff;stop-opacity:0.10396039"
+ id="stop3939" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0.14356436"
+ id="stop3935" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3900">
+ <stop
+ offset="0"
+ style="stop-color:#f6f6f6;stop-opacity:1"
+ id="stop3902" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#494949;stop-opacity:1"
+ id="stop3904" />
+ <stop
+ offset="1"
+ style="stop-color:#2c2c2c;stop-opacity:1"
+ id="stop3906" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3808">
+ <stop
+ offset="0"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3810" />
+ <stop
+ offset="1"
+ style="stop-color:#c8c8c8;stop-opacity:1"
+ id="stop3812" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3030">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3032" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3038" />
+ <stop
+ offset="1"
+ style="stop-color:#4d4d4d;stop-opacity:1"
+ id="stop3034" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3030"
+ id="radialGradient3036"
+ fy="14.242621"
+ fx="29.381905"
+ r="16.375"
+ cy="14.242621"
+ cx="29.381905" />
+ <linearGradient
+ gradientTransform="matrix(1.5,0,0,1,-16,4)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3824"
+ y2="1033.8622"
+ x2="34"
+ y1="1033.8622"
+ x1="30" />
+ <linearGradient
+ gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3834"
+ y2="1039.3622"
+ x2="32"
+ y1="1043.3622"
+ x1="32" />
+ <radialGradient
+ gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3844"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3852"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3857"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3937"
+ fy="21.976955"
+ fx="31.946348"
+ r="19.25"
+ cy="21.976955"
+ cx="31.946348" />
+ </defs>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ fill="#3366cc"
+ d="M 26,32 H 6.0000001 C 2.7000001,32 -5.0000001e-8,29.3 -5.0000001e-8,26 V 6.0000001 C -5.0000001e-8,2.7000001 2.7000001,-4.9999999e-8 6.0000001,-4.9999999e-8 H 26 C 29.3,-4.9999999e-8 32,2.7000001 32,6.0000001 V 26 c 0,3.3 -2.7,6 -6,6 z"
+ id="path2" />
+ <path
+ fill="#daeeff"
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M 28,6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 20 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
+ id="path4" />
+ <g
+ style="fill:#008000"
+ id="g869"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g871"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g873"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g875"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g877"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g879"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g881"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g883"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g885"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g887"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g889"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g891"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g893"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g895"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g897"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ id="g856"
+ style="fill:#c1272d;fill-opacity:1"
+ transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
+ <g
+ id="g854"
+ style="fill:#c1272d;fill-opacity:1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path850"
+ d="m 226.434,249.503 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 L 61.8,74.165 c -5.128,-5.141 -11.554,-7.852 -18.568,-7.852 -7.026,0 -13.452,2.717 -18.556,7.846 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 L 129.267,249.503 7.84,370.936 C 2.711,376.071 0,382.491 0,389.486 c 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
+ style="fill:#c1272d;fill-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path852"
+ d="m 498.866,384.951 h -323.02 c -7.203,0 -13.611,2.583 -18.581,7.528 -4.896,4.92 -7.484,11.327 -7.484,18.531 v 21.536 c 0,7.252 2.607,13.672 7.491,18.543 4.915,4.927 11.34,7.528 18.574,7.528 h 323.02 c 7.239,0 13.659,-2.607 18.531,-7.497 4.927,-4.908 7.533,-11.334 7.533,-18.58 v -21.537 c 0,-7.209 -2.589,-13.616 -7.54,-18.592 -4.913,-4.877 -11.321,-7.46 -18.524,-7.46 z"
+ style="fill:#c1272d;fill-opacity:1" />
+ </g>
+ </g>
+ <g
+ id="g858"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g860"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g862"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g864"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g866"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g868"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g870"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g872"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g874"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g876"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g878"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g880"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g882"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g884"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g886"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+</svg>
diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc
index fbaaf9e4..e95d6579 100644
--- a/launcher/resources/pe_colored/pe_colored.qrc
+++ b/launcher/resources/pe_colored/pe_colored.qrc
@@ -9,6 +9,7 @@
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
@@ -29,6 +30,7 @@
<file>scalable/resourcepacks.svg</file>
<file>scalable/screenshots.svg</file>
<file>scalable/settings.svg</file>
+ <file>scalable/shaderpacks.svg</file>
<file>scalable/status-bad.svg</file>
<file>scalable/status-good.svg</file>
<file>scalable/status-yellow.svg</file>
diff --git a/launcher/resources/pe_colored/scalable/custom-commands.svg b/launcher/resources/pe_colored/scalable/custom-commands.svg
new file mode 100644
index 00000000..44dd1992
--- /dev/null
+++ b/launcher/resources/pe_colored/scalable/custom-commands.svg
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ id="svg2"
+ height="32"
+ width="32"
+ version="1.1"
+ sodipodi:docname="custom-commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <sodipodi:namedview
+ pagecolor="#505050"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1720"
+ inkscape:window-height="1382"
+ id="namedview52"
+ showgrid="false"
+ inkscape:zoom="20.85965"
+ inkscape:cx="20.853658"
+ inkscape:cy="20.829688"
+ inkscape:window-x="1720"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:bbox-nodes="true"
+ inkscape:pagecheckerboard="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid858" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3931">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3933" />
+ <stop
+ offset="0.69999987"
+ style="stop-color:#ffffff;stop-opacity:0.10396039"
+ id="stop3939" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0.14356436"
+ id="stop3935" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3900">
+ <stop
+ offset="0"
+ style="stop-color:#f6f6f6;stop-opacity:1"
+ id="stop3902" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#494949;stop-opacity:1"
+ id="stop3904" />
+ <stop
+ offset="1"
+ style="stop-color:#2c2c2c;stop-opacity:1"
+ id="stop3906" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3808">
+ <stop
+ offset="0"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3810" />
+ <stop
+ offset="1"
+ style="stop-color:#c8c8c8;stop-opacity:1"
+ id="stop3812" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3030">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3032" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3038" />
+ <stop
+ offset="1"
+ style="stop-color:#4d4d4d;stop-opacity:1"
+ id="stop3034" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3030"
+ id="radialGradient3036"
+ fy="14.242621"
+ fx="29.381905"
+ r="16.375"
+ cy="14.242621"
+ cx="29.381905" />
+ <linearGradient
+ gradientTransform="matrix(1.5,0,0,1,-16,4)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3824"
+ y2="1033.8622"
+ x2="34"
+ y1="1033.8622"
+ x1="30" />
+ <linearGradient
+ gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3834"
+ y2="1039.3622"
+ x2="32"
+ y1="1043.3622"
+ x1="32" />
+ <radialGradient
+ gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3844"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3852"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3857"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3937"
+ fy="21.976955"
+ fx="31.946348"
+ r="19.25"
+ cy="21.976955"
+ cx="31.946348" />
+ </defs>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ id="path2"
+ d="M 28,6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 20 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
+ fill="#f2f2f2"
+ clip-rule="evenodd"
+ fill-rule="evenodd" />
+ <g
+ style="fill:#008000"
+ id="g869"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g871"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g873"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g875"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g877"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g879"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g881"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g883"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g885"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g887"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g889"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g891"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g893"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g895"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g897"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ id="g856"
+ style="fill:#c1272d;fill-opacity:1"
+ transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
+ <g
+ id="g854"
+ style="fill:#c1272d;fill-opacity:1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path850"
+ d="m 226.434,249.503 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 L 61.8,74.165 c -5.128,-5.141 -11.554,-7.852 -18.568,-7.852 -7.026,0 -13.452,2.717 -18.556,7.846 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 L 129.267,249.503 7.84,370.936 C 2.711,376.071 0,382.491 0,389.486 c 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
+ style="fill:#c1272d;fill-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path852"
+ d="m 498.866,384.951 h -323.02 c -7.203,0 -13.611,2.583 -18.581,7.528 -4.896,4.92 -7.484,11.327 -7.484,18.531 v 21.536 c 0,7.252 2.607,13.672 7.491,18.543 4.915,4.927 11.34,7.528 18.574,7.528 h 323.02 c 7.239,0 13.659,-2.607 18.531,-7.497 4.927,-4.908 7.533,-11.334 7.533,-18.58 v -21.537 c 0,-7.209 -2.589,-13.616 -7.54,-18.592 -4.913,-4.877 -11.321,-7.46 -18.524,-7.46 z"
+ style="fill:#c1272d;fill-opacity:1" />
+ </g>
+ </g>
+ <g
+ id="g858"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g860"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g862"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g864"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g866"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g868"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g870"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g872"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g874"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g876"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g878"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g880"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g882"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g884"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g886"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g12">
+ <path
+ id="path6"
+ d="m 6,28 h 20 c 1.1,0 2,-0.9 2,-2 V 9 6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 3 17 c 0,1.1 0.9,2 2,2 z"
+ fill="none" />
+ <path
+ id="path8"
+ d="M 26,0 H 6 C 2.7,0 0,2.7 0,6 V 9 H 4 V 6 C 4,4.9 4.9,4 6,4 h 20 c 1.1,0 2,0.9 2,2 v 3 h 4 V 6 C 32,2.7 29.3,0 26,0 Z"
+ fill="#39b54a" />
+ <path
+ id="path10"
+ d="m 28,26 c 0,1.1 -0.9,2 -2,2 H 6 C 4.9,28 4,27.1 4,26 V 9 H 0 v 17 c 0,3.3 2.7,6 6,6 h 20 c 3.3,0 6,-2.7 6,-6 V 9 h -4 z"
+ fill="#8c6239" />
+ </g>
+</svg>
diff --git a/launcher/resources/pe_colored/scalable/shaderpacks.svg b/launcher/resources/pe_colored/scalable/shaderpacks.svg
new file mode 100644
index 00000000..9400b933
--- /dev/null
+++ b/launcher/resources/pe_colored/scalable/shaderpacks.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xml:space="preserve"
+ enable-background="new 0 0 32 32"
+ viewBox="0 0 32 32"
+ y="0px"
+ x="0px"
+ id="Calque_1"
+ version="1.1"
+ sodipodi:docname="shaderpacks.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ 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"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
+ id="namedview14"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="14.584077"
+ inkscape:cx="24.478752"
+ inkscape:cy="13.165043"
+ inkscape:window-width="2399"
+ inkscape:window-height="1183"
+ inkscape:window-x="2321"
+ inkscape:window-y="798"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Calque_1" /><metadata
+ id="metadata19"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs17"><linearGradient
+ id="linearGradient3249"
+ inkscape:swatch="solid"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3247" /></linearGradient>
+
+
+
+
+
+ </defs><g
+ id="g6"><path
+ id="path2"
+ d="M26,0H6C2.7,0,0,2.7,0,6v3h32V6C32,2.7,29.3,0,26,0z"
+ fill="#39B54A" /><path
+ id="path4"
+ d="M0,26c0,3.3,2.7,6,6,6h20c3.3,0,6-2.7,6-6V9H0V26z"
+ fill="#8C6239" /></g><path
+ fill="#F2F2F2"
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ id="path8"
+ d="M28,6c0-1.1-0.9-2-2-2H6C4.9,4,4,4.9,4,6v20c0,1.1,0.9,2,2,2h20 c1.1,0,2-0.9,2-2V6z" /><rect
+ x="6.0678372"
+ y="6.0678444"
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ fill="none"
+ width="19.864313"
+ height="19.864313"
+ id="rect838"
+ style="stroke-width:1.98049" /><path
+ id="polygon840"
+ style="clip-rule:evenodd;fill:#294eab;fill-rule:evenodd;stroke-width:3.19043"
+ transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)"
+ d="m -433,272.1 v 17.8 l -14,7.1 v -17.8 z" /><path
+ id="polygon842"
+ style="clip-rule:evenodd;fill:#39b54a;fill-rule:evenodd;stroke-width:3.19043"
+ transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)"
+ d="m -461,272.1 v 17.8 l 14,7.1 v -17.8 z" /><path
+ id="polygon844"
+ style="clip-rule:evenodd;fill:#ed4c31;fill-rule:evenodd;stroke-width:3.19043"
+ transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)"
+ d="m -447,265 -14,7.1 14,7.1 14,-7.1 z" /></svg>
diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc
index a57b6a14..a138abc4 100644
--- a/launcher/resources/pe_dark/pe_dark.qrc
+++ b/launcher/resources/pe_dark/pe_dark.qrc
@@ -9,6 +9,7 @@
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
diff --git a/launcher/resources/pe_dark/scalable/custom-commands.svg b/launcher/resources/pe_dark/scalable/custom-commands.svg
new file mode 100644
index 00000000..42185e37
--- /dev/null
+++ b/launcher/resources/pe_dark/scalable/custom-commands.svg
@@ -0,0 +1,335 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ id="svg2"
+ height="32"
+ width="32"
+ version="1.1"
+ sodipodi:docname="custom-commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <sodipodi:namedview
+ pagecolor="#505050"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1720"
+ inkscape:window-height="1382"
+ id="namedview52"
+ showgrid="false"
+ inkscape:zoom="20.85965"
+ inkscape:cx="20.901597"
+ inkscape:cy="20.829688"
+ inkscape:window-x="1720"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="g856"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:bbox-nodes="true"
+ inkscape:pagecheckerboard="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid858" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3931">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3933" />
+ <stop
+ offset="0.69999987"
+ style="stop-color:#ffffff;stop-opacity:0.10396039"
+ id="stop3939" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0.14356436"
+ id="stop3935" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3900">
+ <stop
+ offset="0"
+ style="stop-color:#f6f6f6;stop-opacity:1"
+ id="stop3902" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#494949;stop-opacity:1"
+ id="stop3904" />
+ <stop
+ offset="1"
+ style="stop-color:#2c2c2c;stop-opacity:1"
+ id="stop3906" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3808">
+ <stop
+ offset="0"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3810" />
+ <stop
+ offset="1"
+ style="stop-color:#c8c8c8;stop-opacity:1"
+ id="stop3812" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3030">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3032" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3038" />
+ <stop
+ offset="1"
+ style="stop-color:#4d4d4d;stop-opacity:1"
+ id="stop3034" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3030"
+ id="radialGradient3036"
+ fy="14.242621"
+ fx="29.381905"
+ r="16.375"
+ cy="14.242621"
+ cx="29.381905" />
+ <linearGradient
+ gradientTransform="matrix(1.5,0,0,1,-16,4)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3824"
+ y2="1033.8622"
+ x2="34"
+ y1="1033.8622"
+ x1="30" />
+ <linearGradient
+ gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3834"
+ y2="1039.3622"
+ x2="32"
+ y1="1043.3622"
+ x1="32" />
+ <radialGradient
+ gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3844"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3852"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3857"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3937"
+ fy="21.976955"
+ fx="31.946348"
+ r="19.25"
+ cy="21.976955"
+ cx="31.946348" />
+ </defs>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M 26,32 H 5.9999999 C 2.6999999,32 -5.0000001e-8,29.3 -5.0000001e-8,26 V 6 C -5.0000001e-8,2.7 2.6999999,-4.9999999e-8 5.9999999,-4.9999999e-8 H 26 C 29.3,-4.9999999e-8 32,2.7 32,6 v 20 c 0,3.3 -2.7,6 -6,6 z"
+ id="path2" />
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ fill="#f2f2f2"
+ d="M 28,6 C 28,4.9 27.1,4 26,4 H 5.9999999 c -1.1,0 -2,0.9 -2,2 v 20 c 0,1.1 0.9,2 2,2 H 26 c 1.1,0 2,-0.9 2,-2 z"
+ id="path4" />
+ <g
+ style="fill:#008000"
+ id="g869"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g871"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g873"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g875"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g877"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g879"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g881"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g883"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g885"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g887"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g889"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g891"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g893"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g895"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g897"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ id="g856"
+ style="fill:#c1272d;fill-opacity:1"
+ transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
+ <g
+ id="g854"
+ style="fill:#666666;fill-opacity:1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path850"
+ d="m 226.434,249.503 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 L 61.8,74.165 c -5.128,-5.141 -11.554,-7.852 -18.568,-7.852 -7.026,0 -13.452,2.717 -18.556,7.846 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 L 129.267,249.503 7.84,370.936 C 2.711,376.071 0,382.491 0,389.486 c 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
+ style="fill:#666666;fill-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path852"
+ d="m 498.866,384.951 h -323.02 c -7.203,0 -13.611,2.583 -18.581,7.528 -4.896,4.92 -7.484,11.327 -7.484,18.531 v 21.536 c 0,7.252 2.607,13.672 7.491,18.543 4.915,4.927 11.34,7.528 18.574,7.528 h 323.02 c 7.239,0 13.659,-2.607 18.531,-7.497 4.927,-4.908 7.533,-11.334 7.533,-18.58 v -21.537 c 0,-7.209 -2.589,-13.616 -7.54,-18.592 -4.913,-4.877 -11.321,-7.46 -18.524,-7.46 z"
+ style="fill:#666666;fill-opacity:1" />
+ </g>
+ </g>
+ <g
+ id="g858"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g860"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g862"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g864"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g866"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g868"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g870"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g872"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g874"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g876"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g878"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g880"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g882"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g884"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g886"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+</svg>
diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc
index 6d77c835..f518b650 100644
--- a/launcher/resources/pe_light/pe_light.qrc
+++ b/launcher/resources/pe_light/pe_light.qrc
@@ -9,6 +9,7 @@
<file>scalable/checkupdate.svg</file>
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
diff --git a/launcher/resources/pe_light/scalable/custom-commands.svg b/launcher/resources/pe_light/scalable/custom-commands.svg
new file mode 100644
index 00000000..b3dfe12a
--- /dev/null
+++ b/launcher/resources/pe_light/scalable/custom-commands.svg
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ id="svg2"
+ height="32"
+ width="32"
+ version="1.1"
+ sodipodi:docname="custom-commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <sodipodi:namedview
+ pagecolor="#505050"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1720"
+ inkscape:window-height="1382"
+ id="namedview52"
+ showgrid="false"
+ inkscape:zoom="20.85965"
+ inkscape:cx="20.901597"
+ inkscape:cy="20.829688"
+ inkscape:window-x="1720"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:bbox-nodes="true"
+ inkscape:pagecheckerboard="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid858" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3931">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3933" />
+ <stop
+ offset="0.69999987"
+ style="stop-color:#ffffff;stop-opacity:0.10396039"
+ id="stop3939" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0.14356436"
+ id="stop3935" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3900">
+ <stop
+ offset="0"
+ style="stop-color:#f6f6f6;stop-opacity:1"
+ id="stop3902" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#494949;stop-opacity:1"
+ id="stop3904" />
+ <stop
+ offset="1"
+ style="stop-color:#2c2c2c;stop-opacity:1"
+ id="stop3906" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3808">
+ <stop
+ offset="0"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3810" />
+ <stop
+ offset="1"
+ style="stop-color:#c8c8c8;stop-opacity:1"
+ id="stop3812" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3030">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3032" />
+ <stop
+ offset="0.75714284"
+ style="stop-color:#333333;stop-opacity:1"
+ id="stop3038" />
+ <stop
+ offset="1"
+ style="stop-color:#4d4d4d;stop-opacity:1"
+ id="stop3034" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3030"
+ id="radialGradient3036"
+ fy="14.242621"
+ fx="29.381905"
+ r="16.375"
+ cy="14.242621"
+ cx="29.381905" />
+ <linearGradient
+ gradientTransform="matrix(1.5,0,0,1,-16,4)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3824"
+ y2="1033.8622"
+ x2="34"
+ y1="1033.8622"
+ x1="30" />
+ <linearGradient
+ gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3808"
+ id="linearGradient3834"
+ y2="1039.3622"
+ x2="32"
+ y1="1043.3622"
+ x1="32" />
+ <radialGradient
+ gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3844"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3852"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3857"
+ fy="1039.813"
+ fx="30.724609"
+ r="3"
+ cy="1039.813"
+ cx="30.724609" />
+ <radialGradient
+ gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3900"
+ id="radialGradient3937"
+ fy="21.976955"
+ fx="31.946348"
+ r="19.25"
+ cy="21.976955"
+ cx="31.946348" />
+ </defs>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ id="path2"
+ d="m 28,5.9999998 c 0,-1.1 -0.9,-2 -2,-2 H 6 c -1.1,0 -2,0.9 -2,2 V 26 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
+ fill="#4d4d4d"
+ clip-rule="evenodd"
+ fill-rule="evenodd" />
+ <path
+ id="path6"
+ d="M 26,32 H 6 C 2.7,32 4.9999998e-8,29.3 4.9999998e-8,26 V 5.9999998 C 4.9999998e-8,2.6999998 2.7,-2e-7 6,-2e-7 h 20 c 3.3,0 6,2.7 6,6 V 26 c 0,3.3 -2.7,6 -6,6 z M 28,5.9999998 c 0,-1.1 -0.9,-2 -2,-2 H 6 c -1.1,0 -2,0.9 -2,2 V 26 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
+ fill="#f2f2f2"
+ clip-rule="evenodd"
+ fill-rule="evenodd" />
+ <g
+ style="fill:#008000"
+ id="g869"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g871"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g873"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g875"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g877"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g879"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g881"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g883"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g885"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g887"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g889"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g891"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g893"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g895"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ style="fill:#008000"
+ id="g897"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
+ <g
+ id="g856"
+ style="fill:#ffffff;fill-opacity:1"
+ transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
+ <g
+ id="g854"
+ style="fill:#ffffff;fill-opacity:1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path850"
+ d="m 226.434,249.503 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 L 61.8,74.165 c -5.128,-5.141 -11.554,-7.852 -18.568,-7.852 -7.026,0 -13.452,2.717 -18.556,7.846 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 L 129.267,249.503 7.84,370.936 C 2.711,376.071 0,382.491 0,389.486 c 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
+ style="fill:#ffffff;fill-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path852"
+ d="m 498.866,384.951 h -323.02 c -7.203,0 -13.611,2.583 -18.581,7.528 -4.896,4.92 -7.484,11.327 -7.484,18.531 v 21.536 c 0,7.252 2.607,13.672 7.491,18.543 4.915,4.927 11.34,7.528 18.574,7.528 h 323.02 c 7.239,0 13.659,-2.607 18.531,-7.497 4.927,-4.908 7.533,-11.334 7.533,-18.58 v -21.537 c 0,-7.209 -2.589,-13.616 -7.54,-18.592 -4.913,-4.877 -11.321,-7.46 -18.524,-7.46 z"
+ style="fill:#ffffff;fill-opacity:1" />
+ </g>
+ </g>
+ <g
+ id="g858"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g860"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g862"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g864"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g866"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g868"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g870"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g872"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g874"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g876"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g878"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g880"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g882"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g884"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+ <g
+ id="g886"
+ style="fill:#00ff00"
+ transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
+</svg>