aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/Application.cpp26
-rw-r--r--launcher/Application.h5
-rw-r--r--launcher/BaseInstance.cpp3
-rw-r--r--launcher/BaseInstance.h6
-rw-r--r--launcher/LaunchController.cpp8
-rw-r--r--launcher/MangoHud.cpp43
-rw-r--r--launcher/MangoHud.h4
-rw-r--r--launcher/NullInstance.h2
-rw-r--r--launcher/Version.h20
-rw-r--r--launcher/launch/LogModel.h2
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp84
-rw-r--r--launcher/minecraft/MinecraftInstance.h4
-rw-r--r--launcher/minecraft/PackProfile.cpp3
-rw-r--r--launcher/minecraft/auth/AccountList.cpp5
-rw-r--r--launcher/minecraft/launch/ExtractNatives.cpp12
-rw-r--r--launcher/modplatform/ResourceAPI.h4
-rw-r--r--launcher/modplatform/flame/FlameAPI.h7
-rw-r--r--launcher/modplatform/flame/FlameInstanceCreationTask.cpp8
-rw-r--r--launcher/modplatform/flame/FlamePackExportTask.cpp3
-rw-r--r--launcher/modplatform/import_ftb/PackHelpers.cpp6
-rw-r--r--launcher/modplatform/import_ftb/PackInstallTask.cpp4
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.h9
-rw-r--r--launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp4
-rw-r--r--launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp4
-rw-r--r--launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h2
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackExportTask.cpp3
-rw-r--r--launcher/net/HttpMetaCache.cpp19
-rw-r--r--launcher/resources/multimc/multimc.qrc1
-rw-r--r--launcher/resources/multimc/scalable/instances/neoforged.svg3
-rw-r--r--launcher/ui/InstanceWindow.cpp117
-rw-r--r--launcher/ui/InstanceWindow.h13
-rw-r--r--launcher/ui/MainWindow.cpp119
-rw-r--r--launcher/ui/MainWindow.h13
-rw-r--r--launcher/ui/MainWindow.ui16
-rw-r--r--launcher/ui/dialogs/InstallLoaderDialog.cpp4
-rw-r--r--launcher/ui/dialogs/SkinUploadDialog.ui6
-rw-r--r--launcher/ui/pages/global/AccountListPage.cpp5
-rw-r--r--launcher/ui/pages/global/JavaPage.cpp4
-rw-r--r--launcher/ui/pages/global/MinecraftPage.cpp41
-rw-r--r--launcher/ui/pages/global/MinecraftPage.h3
-rw-r--r--launcher/ui/pages/global/MinecraftPage.ui59
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.cpp1
-rw-r--r--launcher/ui/pages/instance/InstanceSettingsPage.cpp52
-rw-r--r--launcher/ui/pages/instance/InstanceSettingsPage.h3
-rw-r--r--launcher/ui/pages/instance/InstanceSettingsPage.ui69
-rw-r--r--launcher/ui/pages/instance/ServersPage.cpp24
-rw-r--r--launcher/ui/pages/instance/VersionPage.cpp9
-rw-r--r--launcher/ui/pages/modplatform/CustomPage.cpp3
-rw-r--r--launcher/ui/pages/modplatform/CustomPage.ui10
-rw-r--r--launcher/ui/widgets/JavaSettingsWidget.cpp27
50 files changed, 506 insertions, 396 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 4da41142..00010465 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -9,7 +9,6 @@
* Copyright (C) 2022 Tayou <git@tayou.org>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
- * Copyright (C) 2023 seth <getchoo at tuta dot io>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -580,12 +579,11 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_settings->registerSetting("IgnoreJavaCompatibility", false);
m_settings->registerSetting("IgnoreJavaWizard", false);
- // Mod loader settings
- m_settings->registerSetting("DisableQuiltBeacon", false);
-
// Native library workarounds
m_settings->registerSetting("UseNativeOpenAL", false);
+ m_settings->registerSetting("CustomOpenALPath", "");
m_settings->registerSetting("UseNativeGLFW", false);
+ m_settings->registerSetting("CustomGLFWPath", "");
// Peformance related options
m_settings->registerSetting("EnableFeralGamemode", false);
@@ -845,6 +843,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
updateCapabilities();
+ detectLibraries();
+
if (createSetupWizard()) {
return;
}
@@ -964,7 +964,7 @@ void Application::performMainStartupAction()
qDebug() << " Launching with account" << m_profileToUse;
}
- launch(inst, true, false, nullptr, serverToJoin, accountToUse);
+ launch(inst, true, false, serverToJoin, accountToUse);
return;
}
}
@@ -1063,7 +1063,7 @@ void Application::messageReceived(const QByteArray& message)
}
}
- launch(instance, true, false, nullptr, serverObject, accountObject);
+ launch(instance, true, false, serverObject, accountObject);
} else {
qWarning() << "Received invalid message" << message;
}
@@ -1104,7 +1104,6 @@ bool Application::openJsonEditor(const QString& filename)
bool Application::launch(InstancePtr instance,
bool online,
bool demo,
- BaseProfilerFactory* profiler,
MinecraftServerTargetPtr serverToJoin,
MinecraftAccountPtr accountToUse)
{
@@ -1112,7 +1111,7 @@ bool Application::launch(InstancePtr instance,
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
} else if (instance->canLaunch()) {
auto& extras = m_instanceExtras[instance->id()];
- auto& window = extras.window;
+ auto window = extras.window;
if (window) {
if (!window->saveAll()) {
return false;
@@ -1123,7 +1122,7 @@ bool Application::launch(InstancePtr instance,
controller->setInstance(instance);
controller->setOnline(online);
controller->setDemo(demo);
- controller->setProfiler(profiler);
+ controller->setProfiler(profilers().value(instance->settings()->get("Profiler").toString(), nullptr).get());
controller->setServerToJoin(serverToJoin);
controller->setAccountToUse(accountToUse);
if (window) {
@@ -1415,6 +1414,15 @@ void Application::updateCapabilities()
#endif
}
+void Application::detectLibraries()
+{
+#ifdef Q_OS_LINUX
+ m_detectedGLFWPath = MangoHud::findLibrary(BuildConfig.GLFW_LIBRARY_NAME);
+ m_detectedOpenALPath = MangoHud::findLibrary(BuildConfig.OPENAL_LIBRARY_NAME);
+ qDebug() << "Detected native libraries:" << m_detectedGLFWPath << m_detectedOpenALPath;
+#endif
+}
+
QString Application::getJarPath(QString jarFile)
{
QStringList potentialPaths = {
diff --git a/launcher/Application.h b/launcher/Application.h
index 7185886d..b227bb81 100644
--- a/launcher/Application.h
+++ b/launcher/Application.h
@@ -142,6 +142,8 @@ class Application : public QApplication {
void updateCapabilities();
+ void detectLibraries();
+
/*!
* Finds and returns the full path to a jar file.
* Returns a null-string if it could not be found.
@@ -193,7 +195,6 @@ class Application : public QApplication {
bool launch(InstancePtr instance,
bool online = true,
bool demo = false,
- BaseProfilerFactory* profiler = nullptr,
MinecraftServerTargetPtr serverToJoin = nullptr,
MinecraftAccountPtr accountToUse = nullptr);
bool kill(InstancePtr instance);
@@ -277,6 +278,8 @@ class Application : public QApplication {
SetupWizard* m_setupWizard = nullptr;
public:
+ QString m_detectedGLFWPath;
+ QString m_detectedOpenALPath;
QString m_instanceIdToLaunch;
QString m_serverToJoin;
QString m_profileToUse;
diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp
index 70c6da6b..72503639 100644
--- a/launcher/BaseInstance.cpp
+++ b/launcher/BaseInstance.cpp
@@ -3,6 +3,7 @@
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
+ * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -100,6 +101,8 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("ManagedPackName", "");
m_settings->registerSetting("ManagedPackVersionID", "");
m_settings->registerSetting("ManagedPackVersionName", "");
+
+ m_settings->registerSetting("Profiler", "");
}
QString BaseInstance::getPreLaunchCommand()
diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h
index 38dc7c4a..47fff595 100644
--- a/launcher/BaseInstance.h
+++ b/launcher/BaseInstance.h
@@ -3,6 +3,7 @@
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
+ * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,6 +39,7 @@
#include <cassert>
#include <QDateTime>
+#include <QMenu>
#include <QObject>
#include <QProcess>
#include <QSet>
@@ -246,6 +248,8 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
virtual bool canEdit() const = 0;
virtual bool canExport() const = 0;
+ virtual void populateLaunchMenu(QMenu* menu) = 0;
+
bool reloadSettings();
/**
@@ -282,6 +286,8 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
void runningStatusChanged(bool running);
+ void profilerChanged();
+
void statusChanged(Status from, Status to);
protected slots:
diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp
index 380489e0..b21eb281 100644
--- a/launcher/LaunchController.cpp
+++ b/launcher/LaunchController.cpp
@@ -2,6 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -361,22 +362,21 @@ void LaunchController::readyForLaunch()
QString error;
if (!m_profiler->check(&error)) {
m_launcher->abort();
- QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't start profiler: %1").arg(error));
emitFailed("Profiler startup failed!");
+ QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Profiler check for %1 failed: %2").arg(m_profiler->name(), error));
return;
}
BaseProfiler* profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this);
connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString& message) {
- QMessageBox msg;
+ QMessageBox msg(m_parentWidget);
msg.setText(tr("The game launch is delayed until you press the "
"button. This is the right time to setup the profiler, as the "
"profiler server is running now.\n\n%1")
.arg(message));
msg.setWindowTitle(tr("Waiting."));
msg.setIcon(QMessageBox::Information);
- msg.addButton(tr("Launch"), QMessageBox::AcceptRole);
- msg.setModal(true);
+ msg.addButton(tr("&Launch"), QMessageBox::AcceptRole);
msg.exec();
m_launcher->proceed();
});
diff --git a/launcher/MangoHud.cpp b/launcher/MangoHud.cpp
index 5758da3a..ab79f418 100644
--- a/launcher/MangoHud.cpp
+++ b/launcher/MangoHud.cpp
@@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include <QDebug>
#include <QDir>
#include <QString>
#include <QStringList>
@@ -26,6 +27,15 @@
#include "Json.h"
#include "MangoHud.h"
+#ifdef __GLIBC__
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#define UNDEF_GNU_SOURCE
+#endif
+#include <dlfcn.h>
+#include <linux/limits.h>
+#endif
+
namespace MangoHud {
QString getLibraryString()
@@ -106,4 +116,37 @@ QString getLibraryString()
return QString();
}
+
+QString findLibrary(QString libName)
+{
+#ifdef __GLIBC__
+ const char* library = libName.toLocal8Bit().constData();
+
+ void* handle = dlopen(library, RTLD_NOW);
+ if (!handle) {
+ qCritical() << "dlopen() failed:" << dlerror();
+ return {};
+ }
+
+ char path[PATH_MAX];
+ if (dlinfo(handle, RTLD_DI_ORIGIN, path) == -1) {
+ qCritical() << "dlinfo() failed:" << dlerror();
+ dlclose(handle);
+ return {};
+ }
+
+ auto fullPath = FS::PathCombine(QString(path), libName);
+
+ dlclose(handle);
+ return fullPath;
+#else
+ qWarning() << "MangoHud::findLibrary is not implemented on this platform";
+ return {};
+#endif
+}
} // namespace MangoHud
+
+#ifdef UNDEF_GNU_SOURCE
+#undef _GNU_SOURCE
+#undef UNDEF_GNU_SOURCE
+#endif
diff --git a/launcher/MangoHud.h b/launcher/MangoHud.h
index 7b7c2849..5361999b 100644
--- a/launcher/MangoHud.h
+++ b/launcher/MangoHud.h
@@ -24,4 +24,6 @@
namespace MangoHud {
QString getLibraryString();
-}
+
+QString findLibrary(QString libName);
+} // namespace MangoHud
diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h
index ff658c43..c79600e7 100644
--- a/launcher/NullInstance.h
+++ b/launcher/NullInstance.h
@@ -2,6 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,6 +63,7 @@ class NullInstance : public BaseInstance {
bool canExport() const override { return false; }
bool canEdit() const override { return false; }
bool canLaunch() const override { return false; }
+ void populateLaunchMenu(QMenu* menu) override {}
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override
{
QStringList out;
diff --git a/launcher/Version.h b/launcher/Version.h
index 92bff9ba..9c043b01 100644
--- a/launcher/Version.h
+++ b/launcher/Version.h
@@ -103,14 +103,8 @@ class Version {
QString m_fullString;
- [[nodiscard]] inline bool isAppendix() const
- {
- return m_stringPart.startsWith('+');
- }
- [[nodiscard]] inline bool isPreRelease() const
- {
- return m_stringPart.startsWith('-') && m_stringPart.length() > 1;
- }
+ [[nodiscard]] inline bool isAppendix() const { return m_stringPart.startsWith('+'); }
+ [[nodiscard]] inline bool isPreRelease() const { return m_stringPart.startsWith('-') && m_stringPart.length() > 1; }
inline bool operator==(const Section& other) const
{
@@ -156,14 +150,8 @@ class Version {
return m_fullString < other.m_fullString;
}
- inline bool operator!=(const Section& other) const
- {
- return !(*this == other);
- }
- inline bool operator>(const Section& other) const
- {
- return !(*this < other || *this == other);
- }
+ inline bool operator!=(const Section& other) const { return !(*this == other); }
+ inline bool operator>(const Section& other) const { return !(*this < other || *this == other); }
};
private:
diff --git a/launcher/launch/LogModel.h b/launcher/launch/LogModel.h
index ba2e4054..18e51d7e 100644
--- a/launcher/launch/LogModel.h
+++ b/launcher/launch/LogModel.h
@@ -30,7 +30,7 @@ class LogModel : public QAbstractListModel {
enum Roles { LevelRole = Qt::UserRole };
- private /* types */:
+ private /* types */:
struct entry {
MessageLevel::Enum level;
QString line;
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index 305bff67..0da97c14 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -3,8 +3,7 @@
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
- * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
- * Copyright (c) 2023 seth <getchoo at tuta dot io>
+ * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -88,6 +87,10 @@
#include "minecraft/gameoptions/GameOptions.h"
#include "minecraft/update/FoldersTask.h"
+#include "tools/BaseProfiler.h"
+
+#include <QActionGroup>
+
#ifdef Q_OS_LINUX
#include "MangoHud.h"
#endif
@@ -166,7 +169,9 @@ void MinecraftInstance::loadSpecificSettings()
// Native library workarounds
auto nativeLibraryWorkaroundsOverride = m_settings->registerSetting("OverrideNativeWorkarounds", false);
m_settings->registerOverride(global_settings->getSetting("UseNativeOpenAL"), nativeLibraryWorkaroundsOverride);
+ m_settings->registerOverride(global_settings->getSetting("CustomOpenALPath"), nativeLibraryWorkaroundsOverride);
m_settings->registerOverride(global_settings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride);
+ m_settings->registerOverride(global_settings->getSetting("CustomGLFWPath"), nativeLibraryWorkaroundsOverride);
// Peformance related options
auto performanceOverride = m_settings->registerSetting("OverridePerformance", false);
@@ -179,10 +184,6 @@ void MinecraftInstance::loadSpecificSettings()
m_settings->registerOverride(global_settings->getSetting("CloseAfterLaunch"), miscellaneousOverride);
m_settings->registerOverride(global_settings->getSetting("QuitAfterGameStop"), miscellaneousOverride);
- // Mod loader specific options
- auto modLoaderSettings = m_settings->registerSetting("OverrideModLoaderSettings", false);
- m_settings->registerOverride(global_settings->getSetting("DisableQuiltBeacon"), modLoaderSettings);
-
m_settings->set("InstanceType", "OneSix");
}
@@ -229,6 +230,50 @@ QSet<QString> MinecraftInstance::traits() const
return profile->getTraits();
}
+// FIXME: move UI code out of MinecraftInstance
+void MinecraftInstance::populateLaunchMenu(QMenu* menu)
+{
+ QAction* normalLaunch = menu->addAction(tr("&Launch"));
+ normalLaunch->setShortcut(QKeySequence::Open);
+ QAction* normalLaunchOffline = menu->addAction(tr("Launch &Offline"));
+ normalLaunchOffline->setShortcut(QKeySequence(tr("Ctrl+Shift+O")));
+ QAction* normalLaunchDemo = menu->addAction(tr("Launch &Demo"));
+ normalLaunchDemo->setShortcut(QKeySequence(tr("Ctrl+Alt+O")));
+
+ normalLaunchDemo->setEnabled(supportsDemo());
+
+ connect(normalLaunch, &QAction::triggered, [this] { APPLICATION->launch(shared_from_this()); });
+ connect(normalLaunchOffline, &QAction::triggered, [this] { APPLICATION->launch(shared_from_this(), false, false); });
+ connect(normalLaunchDemo, &QAction::triggered, [this] { APPLICATION->launch(shared_from_this(), false, true); });
+
+ QString profilersTitle = tr("Profilers");
+ menu->addSeparator()->setText(profilersTitle);
+
+ auto profilers = new QActionGroup(menu);
+ profilers->setExclusive(true);
+ connect(profilers, &QActionGroup::triggered, [this](QAction* action) {
+ settings()->set("Profiler", action->data());
+ emit profilerChanged();
+ });
+
+ QAction* noProfilerAction = menu->addAction(tr("&No Profiler"));
+ noProfilerAction->setData("");
+ noProfilerAction->setCheckable(true);
+ noProfilerAction->setChecked(true);
+ profilers->addAction(noProfilerAction);
+
+ for (auto profiler = APPLICATION->profilers().begin(); profiler != APPLICATION->profilers().end(); profiler++) {
+ QAction* profilerAction = menu->addAction(profiler.value()->name());
+ profilers->addAction(profilerAction);
+ profilerAction->setData(profiler.key());
+ profilerAction->setCheckable(true);
+ profilerAction->setChecked(settings()->get("Profiler").toString() == profiler.key());
+
+ QString error;
+ profilerAction->setEnabled(profiler.value()->check(&error));
+ }
+}
+
QString MinecraftInstance::gameRoot() const
{
QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
@@ -385,10 +430,31 @@ QStringList MinecraftInstance::extraArguments()
}
{
- const auto loaders = version->getModLoaders();
- if (loaders.has_value() && loaders.value() & ResourceAPI::Quilt && settings()->get("DisableQuiltBeacon").toBool())
- list.append("-Dloader.disable_beacon=true");
+ QString openALPath;
+ QString glfwPath;
+
+ if (settings()->get("UseNativeOpenAL").toBool()) {
+ openALPath = APPLICATION->m_detectedOpenALPath;
+ auto customPath = settings()->get("CustomOpenALPath").toString();
+ if (!customPath.isEmpty())
+ openALPath = customPath;
+ }
+ if (settings()->get("UseNativeGLFW").toBool()) {
+ glfwPath = APPLICATION->m_detectedGLFWPath;
+ auto customPath = settings()->get("CustomGLFWPath").toString();
+ if (!customPath.isEmpty())
+ glfwPath = customPath;
+ }
+
+ QFileInfo openALInfo(openALPath);
+ QFileInfo glfwInfo(glfwPath);
+
+ if (!openALPath.isEmpty() && openALInfo.exists())
+ list.append("-Dorg.lwjgl.openal.libname=" + openALInfo.absoluteFilePath());
+ if (!glfwPath.isEmpty() && glfwInfo.exists())
+ list.append("-Dorg.lwjgl.glfw.libname=" + glfwInfo.absoluteFilePath());
}
+
return list;
}
diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h
index c331cc6f..dabd44ba 100644
--- a/launcher/minecraft/MinecraftInstance.h
+++ b/launcher/minecraft/MinecraftInstance.h
@@ -2,7 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
- * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -70,6 +70,8 @@ class MinecraftInstance : public BaseInstance {
bool canExport() const override { return true; }
+ void populateLaunchMenu(QMenu* menu) override;
+
////// Directories and files //////
QString jarModsDir() const;
QString resourcePacksDir() const;
diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp
index cf8270cd..92988808 100644
--- a/launcher/minecraft/PackProfile.cpp
+++ b/