chore: reformat

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
Sefa Eyeoglu 2023-08-14 18:16:53 +02:00
parent 779f70057b
commit 91ba4cf75e
No known key found for this signature in database
GPG Key ID: E13DFD4B47127951
603 changed files with 15840 additions and 16257 deletions

View File

@ -36,8 +36,8 @@
*/ */
#pragma once #pragma once
#include <QString>
#include <QList> #include <QList>
#include <QString>
/** /**
* \brief The Config class holds all the build-time information passed from the build system. * \brief The Config class holds all the build-time information passed from the build system.

View File

@ -49,27 +49,27 @@
#include "pathmatcher/MultiMatcher.h" #include "pathmatcher/MultiMatcher.h"
#include "pathmatcher/SimplePrefixMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h"
#include "settings/INIFile.h" #include "settings/INIFile.h"
#include "ui/MainWindow.h"
#include "ui/InstanceWindow.h" #include "ui/InstanceWindow.h"
#include "ui/MainWindow.h"
#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/ProgressDialog.h"
#include "ui/instanceview/AccessibleInstanceView.h" #include "ui/instanceview/AccessibleInstanceView.h"
#include "ui/pages/BasePageProvider.h" #include "ui/pages/BasePageProvider.h"
#include "ui/pages/global/LauncherPage.h" #include "ui/pages/global/APIPage.h"
#include "ui/pages/global/MinecraftPage.h" #include "ui/pages/global/AccountListPage.h"
#include "ui/pages/global/CustomCommandsPage.h"
#include "ui/pages/global/ExternalToolsPage.h"
#include "ui/pages/global/JavaPage.h" #include "ui/pages/global/JavaPage.h"
#include "ui/pages/global/LanguagePage.h" #include "ui/pages/global/LanguagePage.h"
#include "ui/pages/global/LauncherPage.h"
#include "ui/pages/global/MinecraftPage.h"
#include "ui/pages/global/ProxyPage.h" #include "ui/pages/global/ProxyPage.h"
#include "ui/pages/global/ExternalToolsPage.h"
#include "ui/pages/global/AccountListPage.h"
#include "ui/pages/global/APIPage.h"
#include "ui/pages/global/CustomCommandsPage.h"
#include "ui/setupwizard/SetupWizard.h"
#include "ui/setupwizard/LanguageWizardPage.h"
#include "ui/setupwizard/JavaWizardPage.h" #include "ui/setupwizard/JavaWizardPage.h"
#include "ui/setupwizard/LanguageWizardPage.h"
#include "ui/setupwizard/PasteWizardPage.h" #include "ui/setupwizard/PasteWizardPage.h"
#include "ui/setupwizard/SetupWizard.h"
#include "ui/setupwizard/ThemeWizardPage.h" #include "ui/setupwizard/ThemeWizardPage.h"
#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/CustomMessageBox.h"
@ -83,20 +83,20 @@
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <QFileOpenEvent>
#include <QAccessible> #include <QAccessible>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QDebug>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QNetworkAccessManager> #include <QFileOpenEvent>
#include <QTranslator> #include <QIcon>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QList> #include <QList>
#include <QNetworkAccessManager>
#include <QStringList> #include <QStringList>
#include <QDebug>
#include <QStyleFactory> #include <QStyleFactory>
#include <QTranslator>
#include <QWindow> #include <QWindow>
#include <QIcon>
#include "InstanceList.h" #include "InstanceList.h"
#include "MTPixmapCache.h" #include "MTPixmapCache.h"
@ -116,19 +116,19 @@
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "settings/Setting.h" #include "settings/Setting.h"
#include "translations/TranslationsModel.h"
#include "meta/Index.h" #include "meta/Index.h"
#include "translations/TranslationsModel.h"
#include <FileSystem.h>
#include <DesktopServices.h> #include <DesktopServices.h>
#include <FileSystem.h>
#include <LocalPeer.h> #include <LocalPeer.h>
#include <sys.h> #include <sys.h>
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
#include <dlfcn.h> #include <dlfcn.h>
#include "gamemode_client.h"
#include "MangoHud.h" #include "MangoHud.h"
#include "gamemode_client.h"
#endif #endif
#if defined(Q_OS_MAC) && defined(SPARKLE_ENABLED) #if defined(Q_OS_MAC) && defined(SPARKLE_ENABLED)
@ -165,8 +165,6 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QSt
} // namespace } // namespace
Application::Application(int& argc, char** argv) : QApplication(argc, argv) Application::Application(int& argc, char** argv) : QApplication(argc, argv)
{ {
#if defined Q_OS_WIN32 #if defined Q_OS_WIN32
@ -190,15 +188,14 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(BuildConfig.LAUNCHER_DISPLAYNAME); parser.setApplicationDescription(BuildConfig.LAUNCHER_DISPLAYNAME);
parser.addOptions({ parser.addOptions(
{{"d", "dir"}, "Use a custom path as application root (use '.' for current directory)", "directory"}, { { { "d", "dir" }, "Use a custom path as application root (use '.' for current directory)", "directory" },
{ { "l", "launch" }, "Launch the specified instance (by instance ID)", "instance" }, { { "l", "launch" }, "Launch the specified instance (by instance ID)", "instance" },
{ { "s", "server" }, "Join the specified server on launch (only valid in combination with --launch)", "address" }, { { "s", "server" }, "Join the specified server on launch (only valid in combination with --launch)", "address" },
{ { "a", "profile" }, "Use the account specified by its profile name (only valid in combination with --launch)", "profile" }, { { "a", "profile" }, "Use the account specified by its profile name (only valid in combination with --launch)", "profile" },
{ "alive", "Write a small '" + liveCheckFile + "' file after the launcher starts" }, { "alive", "Write a small '" + liveCheckFile + "' file after the launcher starts" },
{ { "I", "import" }, "Import instance from specified zip (local path or URL)", "file" }, { { "I", "import" }, "Import instance from specified zip (local path or URL)", "file" },
{"show", "Opens the window for the specified instance (by instance ID)", "show"} { "show", "Opens the window for the specified instance (by instance ID)", "show" } });
});
parser.addHelpOption(); parser.addHelpOption();
parser.addVersionOption(); parser.addVersionOption();
@ -220,10 +217,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath())); m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath()));
} }
// error if --launch is missing with --server or --profile // error if --launch is missing with --server or --profile
if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) if ((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) {
{
std::cerr << "--server and --profile can only be used in combination with --launch!" << std::endl; std::cerr << "--server and --profile can only be used in combination with --launch!" << std::endl;
m_status = Application::Failed; m_status = Application::Failed;
return; return;
@ -251,22 +246,16 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
QString dataPath; QString dataPath;
// change folder // change folder
QString dirParam = parser.value("dir"); QString dirParam = parser.value("dir");
if (!dirParam.isEmpty()) if (!dirParam.isEmpty()) {
{
// the dir param. it makes multimc data path point to whatever the user specified // the dir param. it makes multimc data path point to whatever the user specified
// on command line // on command line
adjustedBy = "Command line"; adjustedBy = "Command line";
dataPath = dirParam; dataPath = dirParam;
} } else {
else
{
QDir foo; QDir foo;
if (DesktopServices::isSnap()) if (DesktopServices::isSnap()) {
{
foo = QDir(getenv("SNAP_USER_COMMON")); foo = QDir(getenv("SNAP_USER_COMMON"));
} } else {
else
{
foo = QDir(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); foo = QDir(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), ".."));
} }
@ -282,34 +271,27 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
#endif #endif
} }
if (!FS::ensureFolderPathExists(dataPath)) if (!FS::ensureFolderPathExists(dataPath)) {
{
showFatalErrorMessage( showFatalErrorMessage(
"The launcher data folder could not be created.", "The launcher data folder could not be created.",
QString( QString("The launcher data folder could not be created.\n"
"The launcher data folder could not be created.\n"
"\n" "\n"
"Make sure you have the right permissions to the launcher data folder and any folder needed to access it.\n" "Make sure you have the right permissions to the launcher data folder and any folder needed to access it.\n"
"(%1)\n" "(%1)\n"
"\n" "\n"
"The launcher cannot continue until you fix this problem." "The launcher cannot continue until you fix this problem.")
).arg(dataPath) .arg(dataPath));
);
return; return;
} }
if (!QDir::setCurrent(dataPath)) if (!QDir::setCurrent(dataPath)) {
{ showFatalErrorMessage("The launcher data folder could not be opened.",
showFatalErrorMessage( QString("The launcher data folder could not be opened.\n"
"The launcher data folder could not be opened.",
QString(
"The launcher data folder could not be opened.\n"
"\n" "\n"
"Make sure you have the right permissions to the launcher data folder.\n" "Make sure you have the right permissions to the launcher data folder.\n"
"(%1)\n" "(%1)\n"
"\n" "\n"
"The launcher cannot continue until you fix this problem." "The launcher cannot continue until you fix this problem.")
).arg(dataPath) .arg(dataPath));
);
return; return;
} }
@ -326,14 +308,12 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
if (m_peerInstance->isClient()) { if (m_peerInstance->isClient()) {
int timeout = 2000; int timeout = 2000;
if(m_instanceIdToLaunch.isEmpty()) if (m_instanceIdToLaunch.isEmpty()) {
{
ApplicationMessage activate; ApplicationMessage activate;
activate.command = "activate"; activate.command = "activate";
m_peerInstance->sendMessage(activate.serialize(), timeout); m_peerInstance->sendMessage(activate.serialize(), timeout);
if(!m_zipsToImport.isEmpty()) if (!m_zipsToImport.isEmpty()) {
{
for (auto zip_url : m_zipsToImport) { for (auto zip_url : m_zipsToImport) {
ApplicationMessage import; ApplicationMessage import;
import.command = "import"; import.command = "import";
@ -341,19 +321,15 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_peerInstance->sendMessage(import.serialize(), timeout); m_peerInstance->sendMessage(import.serialize(), timeout);
} }
} }
} } else {
else
{
ApplicationMessage launch; ApplicationMessage launch;
launch.command = "launch"; launch.command = "launch";
launch.args["id"] = m_instanceIdToLaunch; launch.args["id"] = m_instanceIdToLaunch;
if(!m_serverToJoin.isEmpty()) if (!m_serverToJoin.isEmpty()) {
{
launch.args["server"] = m_serverToJoin; launch.args["server"] = m_serverToJoin;
} }
if(!m_profileToUse.isEmpty()) if (!m_profileToUse.isEmpty()) {
{
launch.args["profile"] = m_profileToUse; launch.args["profile"] = m_profileToUse;
} }
m_peerInstance->sendMessage(launch.serialize(), timeout); m_peerInstance->sendMessage(launch.serialize(), timeout);
@ -397,9 +373,16 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
qInstallMessageHandler(appDebugOutput); qInstallMessageHandler(appDebugOutput);
qSetMessagePattern( qSetMessagePattern(
"%{time process}" " " "%{time process}"
"%{if-debug}D%{endif}" "%{if-info}I%{endif}" "%{if-warning}W%{endif}" "%{if-critical}C%{endif}" "%{if-fatal}F%{endif}" " "
" " "|" " " "%{if-debug}D%{endif}"
"%{if-info}I%{endif}"
"%{if-warning}W%{endif}"
"%{if-critical}C%{endif}"
"%{if-fatal}F%{endif}"
" "
"|"
" "
"%{if-category}[%{category}]: %{endif}" "%{if-category}[%{category}]: %{endif}"
"%{message}"); "%{message}");
@ -455,49 +438,44 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
bool migrated = false; bool migrated = false;
if (!migrated) if (!migrated)
migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../PolyMC"), "PolyMC", "polymc.cfg"); migrated = handleDataMigration(
dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../PolyMC"), "PolyMC",
"polymc.cfg");
if (!migrated) if (!migrated)
migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../multimc"), "MultiMC", "multimc.cfg"); migrated = handleDataMigration(
dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../multimc"), "MultiMC",
"multimc.cfg");
} }
{ {
qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT;
qDebug() << "Version : " << BuildConfig.printableVersionString(); qDebug() << "Version : " << BuildConfig.printableVersionString();
qDebug() << "Platform : " << BuildConfig.BUILD_PLATFORM; qDebug() << "Platform : " << BuildConfig.BUILD_PLATFORM;
qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT;
qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC;
if (adjustedBy.size()) if (adjustedBy.size()) {
{
qDebug() << "Work dir before adjustment : " << origcwdPath; qDebug() << "Work dir before adjustment : " << origcwdPath;
qDebug() << "Work dir after adjustment : " << QDir::currentPath(); qDebug() << "Work dir after adjustment : " << QDir::currentPath();
qDebug() << "Adjusted by : " << adjustedBy; qDebug() << "Adjusted by : " << adjustedBy;
} } else {
else
{
qDebug() << "Work dir : " << QDir::currentPath(); qDebug() << "Work dir : " << QDir::currentPath();
} }
qDebug() << "Binary path : " << binPath; qDebug() << "Binary path : " << binPath;
qDebug() << "Application root path : " << m_rootPath; qDebug() << "Application root path : " << m_rootPath;
if(!m_instanceIdToLaunch.isEmpty()) if (!m_instanceIdToLaunch.isEmpty()) {
{
qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch;
} }
if(!m_serverToJoin.isEmpty()) if (!m_serverToJoin.isEmpty()) {
{
qDebug() << "Address of server to join :" << m_serverToJoin; qDebug() << "Address of server to join :" << m_serverToJoin;
} }
qDebug() << "<> Paths set."; qDebug() << "<> Paths set.";
} }
if(m_liveCheck) if (m_liveCheck) {
{
QFile check(liveCheckFile); QFile check(liveCheckFile);
if(check.open(QIODevice::WriteOnly | QIODevice::Truncate)) if (check.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
{
auto payload = appID.toString().toUtf8(); auto payload = appID.toString().toUtf8();
if(check.write(payload) == payload.size()) if (check.write(payload) == payload.size()) {
{
check.close(); check.close();
} else { } else {
qWarning() << "Could not write into" << liveCheckFile << "!"; qWarning() << "Could not write into" << liveCheckFile << "!";
@ -666,8 +644,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
QString pastebinURL = m_settings->get("PastebinURL").toString(); QString pastebinURL = m_settings->get("PastebinURL").toString();
bool userHadDefaultPastebin = pastebinURL == "https://0x0.st"; bool userHadDefaultPastebin = pastebinURL == "https://0x0.st";
if (!pastebinURL.isEmpty() && !userHadDefaultPastebin) if (!pastebinURL.isEmpty() && !userHadDefaultPastebin) {
{
m_settings->set("PastebinType", PasteUpload::PasteType::NullPointer); m_settings->set("PastebinType", PasteUpload::PasteType::NullPointer);
m_settings->set("PastebinCustomAPIBase", pastebinURL); m_settings->set("PastebinCustomAPIBase", pastebinURL);
m_settings->reset("PastebinURL"); m_settings->reset("PastebinURL");
@ -676,8 +653,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
bool ok; bool ok;
int pasteType = m_settings->get("PastebinType").toInt(&ok); int pasteType = m_settings->get("PastebinType").toInt(&ok);
// If PastebinType is invalid then reset the related settings. // If PastebinType is invalid then reset the related settings.
if (!ok || !(PasteUpload::PasteType::First <= pasteType && pasteType <= PasteUpload::PasteType::Last)) if (!ok || !(PasteUpload::PasteType::First <= pasteType && pasteType <= PasteUpload::PasteType::Last)) {
{
m_settings->reset("PastebinType"); m_settings->reset("PastebinType");
m_settings->reset("PastebinCustomAPIBase"); m_settings->reset("PastebinCustomAPIBase");
} }
@ -758,8 +734,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
} }
// initialize the updater // initialize the updater
if(BuildConfig.UPDATER_ENABLED) if (BuildConfig.UPDATER_ENABLED) {
{
qDebug() << "Initializing updater"; qDebug() << "Initializing updater";
#if defined(Q_OS_MAC) && defined(SPARKLE_ENABLED) #if defined(Q_OS_MAC) && defined(SPARKLE_ENABLED)
m_updater.reset(new MacSparkleUpdater()); m_updater.reset(new MacSparkleUpdater());
@ -770,18 +745,11 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// Instance icons // Instance icons
{ {
auto setting = APPLICATION->settings()->getSetting("IconsDir"); auto setting = APPLICATION->settings()->getSetting("IconsDir");
QStringList instFolders = QStringList instFolders = { ":/icons/multimc/32x32/instances/", ":/icons/multimc/50x50/instances/",
{ ":/icons/multimc/128x128/instances/", ":/icons/multimc/scalable/instances/" };
":/icons/multimc/32x32/instances/",
":/icons/multimc/50x50/instances/",
":/icons/multimc/128x128/instances/",
":/icons/multimc/scalable/instances/"
};
m_icons.reset(new IconList(instFolders, setting->get().toString())); m_icons.reset(new IconList(instFolders, setting->get().toString()));
connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) connect(setting.get(), &Setting::SettingChanged,
{ [&](const Setting&, QVariant value) { m_icons->directoryChanged(value.toString()); });
m_icons->directoryChanged(value.toString());
});
qDebug() << "<> Instance icons intialized."; qDebug() << "<> Instance icons intialized.";
} }
@ -795,8 +763,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// and remember that we have to show him a dialog when the gui starts (if it does so) // and remember that we have to show him a dialog when the gui starts (if it does so)
QString instDir = InstDirSetting->get().toString(); QString instDir = InstDirSetting->get().toString();
qDebug() << "Instance path : " << instDir; qDebug() << "Instance path : " << instDir;
if (FS::checkProblemticPathJava(QDir(instDir))) if (FS::checkProblemticPathJava(QDir(instDir))) {
{
qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!"; qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!";
} }
m_instances.reset(new InstanceList(m_settings, instDir, this)); m_instances.reset(new InstanceList(m_settings, instDir, this));
@ -849,8 +816,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// FIXME: what to do with these? // FIXME: what to do with these?
m_profilers.insert("jprofiler", std::shared_ptr<BaseProfilerFactory>(new JProfilerFactory())); m_profilers.insert("jprofiler", std::shared_ptr<BaseProfilerFactory>(new JProfilerFactory()));
m_profilers.insert("jvisualvm", std::shared_ptr<BaseProfilerFactory>(new JVisualVMFactory())); m_profilers.insert("jvisualvm", std::shared_ptr<BaseProfilerFactory>(new JVisualVMFactory()));
for (auto profiler : m_profilers.values()) for (auto profiler : m_profilers.values()) {
{
profiler->registerSettings(m_settings); profiler->registerSettings(m_settings);
} }
@ -860,19 +826,15 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
} }
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
connect(this, &Application::clickedOnDock, [this]() { connect(this, &Application::clickedOnDock, [this]() { this->showMainWindow(); });
this->showMainWindow();
});
#endif #endif
connect(this, &Application::aboutToQuit, [this]() { connect(this, &Application::aboutToQuit, [this]() {
if(m_instances) if (m_instances) {
{
// save any remaining instance state // save any remaining instance state
m_instances->saveNow(); m_instances->saveNow();
} }
if(logFile) if (logFile) {
{
logFile->flush(); logFile->flush();
logFile->close(); logFile->close();
} }
@ -882,8 +844,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
updateCapabilities(); updateCapabilities();
if(createSetupWizard()) if (createSetupWizard()) {
{
return; return;
} }
@ -892,23 +853,20 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
bool Application::createSetupWizard() bool Application::createSetupWizard()
{ {
bool javaRequired = [&]() bool javaRequired = [&]() {
{
bool ignoreJavaWizard = m_settings->get("IgnoreJavaWizard").toBool(); bool ignoreJavaWizard = m_settings->get("IgnoreJavaWizard").toBool();
if (ignoreJavaWizard) { if (ignoreJavaWizard) {
return false; return false;
} }
QString currentHostName = QHostInfo::localHostName(); QString currentHostName = QHostInfo::localHostName();
QString oldHostName = settings()->get("LastHostname").toString(); QString oldHostName = settings()->get("LastHostname").toString();
if (currentHostName != oldHostName) if (currentHostName != oldHostName) {
{
settings()->set("LastHostname", currentHostName); settings()->set("LastHostname", currentHostName);
return true; return true;
} }
QString currentJavaPath = settings()->get("JavaPath").toString(); QString currentJavaPath = settings()->get("JavaPath").toString();
QString actualPath = FS::ResolveExecutable(currentJavaPath); QString actualPath = FS::ResolveExecutable(currentJavaPath);
if (actualPath.isNull()) if (actualPath.isNull()) {
{
return true; return true;
} }
return false; return false;
@ -918,26 +876,21 @@ bool Application::createSetupWizard()
bool themeInterventionRequired = settings()->get("ApplicationTheme") == ""; bool themeInterventionRequired = settings()->get("ApplicationTheme") == "";
bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired; bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired;
if(wizardRequired) if (wizardRequired) {
{
m_setupWizard = new SetupWizard(nullptr); m_setupWizard = new SetupWizard(nullptr);
if (languageRequired) if (languageRequired) {
{
m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard)); m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard));
} }
if (javaRequired) if (javaRequired) {
{
m_setupWizard->addPage(new JavaWizardPage(m_setupWizard)); m_setupWizard->addPage(new JavaWizardPage(m_setupWizard));
} }
if (pasteInterventionRequired) if (pasteInterventionRequired) {
{
m_setupWizard->addPage(new PasteWizardPage(m_setupWizard)); m_setupWizard->addPage(new PasteWizardPage(m_setupWizard));
} }
if (themeInterventionRequired) if (themeInterventionRequired) {
{
settings()->set("ApplicationTheme", QString("system")); // set default theme after going into theme wizard settings()->set("ApplicationTheme", QString("system")); // set default theme after going into theme wizard
m_setupWizard->addPage(new ThemeWizardPage(m_setupWizard)); m_setupWizard->addPage(new ThemeWizardPage(m_setupWizard));
} }
@ -978,24 +931,20 @@ void Application::setupWizardFinished(int status)
void Application::performMainStartupAction() void Application::performMainStartupAction()
{ {
m_status = Application::Initialized; m_status = Application::Initialized;
if(!m_instanceIdToLaunch.isEmpty()) if (!m_instanceIdToLaunch.isEmpty()) {
{
auto inst = instances()->getInstanceById(m_instanceIdToLaunch); auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
if(inst) if (inst) {
{
MinecraftServerTargetPtr serverToJoin = nullptr; MinecraftServerTargetPtr serverToJoin = nullptr;
MinecraftAccountPtr accountToUse = nullptr; MinecraftAccountPtr accountToUse = nullptr;
qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching";
if(!m_serverToJoin.isEmpty()) if (!m_serverToJoin.isEmpty()) {
{
// FIXME: validate the server string // FIXME: validate the server string
serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin)));
qDebug() << " Launching with server" << m_serverToJoin; qDebug() << " Launching with server" << m_serverToJoin;
} }
if(!m_profileToUse.isEmpty()) if (!m_profileToUse.isEmpty()) {
{
accountToUse = accounts()->getAccountByProfileName(m_profileToUse); accountToUse = accounts()->getAccountByProfileName(m_profileToUse);
if (!accountToUse) { if (!accountToUse) {
return; return;
@ -1007,24 +956,20 @@ void Application::performMainStartupAction()
return; return;
} }
} }
if(!m_instanceIdToShowWindowOf.isEmpty()) if (!m_instanceIdToShowWindowOf.isEmpty()) {
{
auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf); auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf);
if(inst) if (inst) {
{
qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf; qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf;
showInstanceWindow(inst); showInstanceWindow(inst);
return; return;
} }
} }
if(!m_mainWindow) if (!m_mainWindow) {
{
// normal main window // normal main window
showMainWindow(false); showMainWindow(false);
qDebug() << "<> Main window shown."; qDebug() << "<> Main window shown.";
} }
if(!m_zipsToImport.isEmpty()) if (!m_zipsToImport.isEmpty()) {
{
qDebug() << "<> Importing from zip:" << m_zipsToImport; qDebug() << "<> Importing from zip:" << m_zipsToImport;
m_mainWindow->processURLs(m_zipsToImport); m_mainWindow->processURLs(m_zipsToImport);
} }
@ -1044,8 +989,7 @@ Application::~Application()
#if defined Q_OS_WIN32 #if defined Q_OS_WIN32
// Detach from Windows console // Detach from Windows console
if(consoleAttached) if (consoleAttached) {
{
fclose(stdout); fclose(stdout);
fclose(stdin); fclose(stdin);
fclose(stderr); fclose(stderr);
@ -1056,8 +1000,7 @@ Application::~Application()
void Application::messageReceived(const QByteArray& message) void Application::messageReceived(const QByteArray& message)
{ {
if(status() != Initialized) if (status() != Initialized) {
{
qDebug() << "Received message" << message << "while still initializing. It will be ignored."; qDebug() << "Received message" << message << "while still initializing. It will be ignored.";
return; return;
} }
@ -1067,22 +1010,16 @@ void Application::messageReceived(const QByteArray& message)
auto& command = received.command; auto& command = received.command;
if(command == "activate") if (command == "activate") {
{
showMainWindow(); showMainWindow();
} } else if (command == "import") {
else if(command == "import")
{
QString path = received.args["path"]; QString path = received.args["path"];
if(path.isEmpty()) if (path.isEmpty()) {
{
qWarning() << "Received" << command << "message without a zip path/URL."; qWarning() << "Received" << command << "message without a zip path/URL.";
return; return;
} }
m_mainWindow->processURLs({ QUrl::fromLocalFile(QFileInfo(path).absoluteFilePath()) }); m_mainWindow->processURLs({ QUrl::fromLocalFile(QFileInfo(path).absoluteFilePath()) });
} } else if (command == "launch") {
else if(command == "launch")
{
QString id = received.args["id"]; QString id = received.args["id"];
QString server = received.args["server"]; QString server = received.args["server"];
QString profile = received.args["profile"]; QString profile = received.args["profile"];
@ -1094,8 +1031,7 @@ void Application::messageReceived(const QByteArray& message)
qWarning() << "Launch command requires an valid instance ID. " << id << "resolves to nothing."; qWarning() << "Launch command requires an valid instance ID. " << id << "resolves to nothing.";
return; return;
} }
} } else {
else {
qWarning() << "Launch command called without an instance ID..."; qWarning() << "Launch command called without an instance ID...";
return; return;
} }
@ -1109,22 +1045,14 @@ void Application::messageReceived(const QByteArray& message)
if (!profile.isEmpty()) { if (!profile.isEmpty()) {
accountObject = accounts()->getAccountByProfileName(profile); accountObject = accounts()->getAccountByProfileName(profile);
if (!accountObject) { if (!accountObject) {
qWarning() << "Launch command requires the specified profile to be valid. " << profile << "does not resolve to any account."; qWarning() << "Launch command requires the specified profile to be valid. " << profile
<< "does not resolve to any account.";
return; return;
} }
} }
launch( launch(instance, true, false, nullptr, serverObject, accountObject);
instance, } else {
true,
false,
nullptr,
serverObject,
accountObject
);
}
else
{
qWarning() << "Received invalid message" << message; qWarning() << "Received invalid message" << message;
} }
} }
@ -1136,8 +1064,7 @@ std::shared_ptr<TranslationsModel> Application::translations()
std::shared_ptr<JavaInstallList> Application::javalist() std::shared_ptr<JavaInstallList> Application::javalist()
{ {
if (!m_javalist) if (!m_javalist) {
{
m_javalist.reset(new JavaInstallList()); m_javalist.reset(new JavaInstallList());
} }
return m_javalist; return m_javalist;
@ -1184,37 +1111,28 @@ QString Application::getCatPack(QString catName)
bool Application::openJsonEditor(const QString& filename) bool Application::openJsonEditor(const QString& filename)
{ {
const QString file = QDir::current().absoluteFilePath(filename); const QString file = QDir::current().absoluteFilePath(filename);
if (m_settings->get("JsonEditor").toString().isEmpty()) if (m_settings->get("JsonEditor").toString().isEmpty()) {
{
return DesktopServices::openUrl(QUrl::fromLocalFile(file)); return DesktopServices::openUrl(QUrl::fromLocalFile(file));
} } else {
else
{
// return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); // return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file);
return DesktopServices::run(m_settings->get("JsonEditor").toString(), { file }); return DesktopServices::run(m_settings->get("JsonEditor").toString(), { file });
} }
} }
bool Application::launch( bool Application::launch(InstancePtr instance,
InstancePtr instance,
bool online, bool online,
bool demo, bool demo,
BaseProfilerFactory* profiler, BaseProfilerFactory* profiler,
MinecraftServerTargetPtr serverToJoin, MinecraftServerTargetPtr serverToJoin,
MinecraftAccountPtr accountToUse MinecraftAccountPtr accountToUse)
) {
if(m_updateRunning)
{ {
if (m_updateRunning) {
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
} } else if (instance->canLaunch()) {
else if(instance->canLaunch())
{
auto& extras = m_instanceExtras[instance->id()]; auto& extras = m_instanceExtras[instance->id()];
auto& window = extras.window; auto& window = extras.window;
if(window) if (window) {
{ if (!window->saveAll()) {
if(!window->saveAll())
{
return false; return false;
} }
} }
@ -1226,30 +1144,21 @@ bool Application::launch(
controller->setProfiler(profiler); controller->setProfiler(profiler);
controller->setServerToJoin(serverToJoin); controller->setServerToJoin(serverToJoin);
controller->setAccountToUse(accountToUse); controller->setAccountToUse(accountToUse);
if(window) if (window) {
{
controller->setParentWidget(window); controller->setParentWidget(window);
} } else if (m_mainWindow) {
else if(m_mainWindow)
{
controller->setParentWidget(m_mainWindow); controller->setParentWidget(m_mainWindow);
} }
connect(controller.get(), &LaunchController::succeeded, this, &Application::controllerSucceeded); connect(controller.get(), &LaunchController::succeeded, this, &Application::controllerSucceeded);
connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed); connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed);
connect(controller.get(), &LaunchController::aborted, this, [this] { connect(controller.get(), &LaunchController::aborted, this, [this] { controllerFailed(tr("Aborted")); });
controllerFailed(tr("Aborted"));
});
addRunningInstance(); addRunningInstance();
controller->start(); controller->start();
return true; return true;
} } else if (instance->isRunning()) {
else if (instance->isRunning())
{
showInstanceWindow(instance, "console"); showInstanceWindow(instance, "console");
return true; return true;
} } else if (instance->canEdit()) {
else if (instance->canEdit())
{
showInstanceWindow(instance); showInstanceWindow(instance);
return true; return true;
} }
@ -1258,16 +1167,14 @@ bool Application::launch(
bool Application::kill(InstancePtr instance) bool Application::kill(InstancePtr instance)
{ {
if (!instance->isRunning()) if (!instance->isRunning()) {
{
qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running.";
return false; return false;
} }
auto& extras = m_instanceExtras[instance->id()]; auto& extras = m_instanceExtras[instance->id()];
// NOTE: copy of the shared pointer keeps it alive // NOTE: copy of the shared pointer keeps it alive
auto controller = extras.controller; auto controller = extras.controller;
if(controller) if (controller) {
{
return controller->abort(); return controller->abort();
} }
return true; return true;
@ -1282,22 +1189,19 @@ void Application::closeCurrentWindow()
void Application::addRunningInstance() void Application::addRunningInstance()
{ {
m_runningInstances++; m_runningInstances++;
if(m_runningInstances == 1) if (m_runningInstances == 1) {
{
emit updateAllowedChanged(false); emit updateAllowedChanged(false);
} }
} }
void Application::subRunningInstance() void Application::subRunningInstance()
{ {
if(m_runningInstances == 0) if (m_runningInstances == 0) {
{
qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF"; qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF";
return; return;
} }
m_runningInstances--; m_runningInstances--;
if(m_runningInstances == 0) if (m_runningInstances == 0) {
{
emit updateAllowedChanged(true); emit updateAllowedChanged(true);
} }
} }
@ -1317,7 +1221,6 @@ void Application::updateIsRunning(bool running)
m_updateRunning = running; m_updateRunning = running;
} }
void Application::controllerSucceeded() void Application::controllerSucceeded()
{ {
auto controller = qobject_cast<LaunchController*>(QObject::sender()); auto controller = qobject_cast<LaunchController*>(QObject::sender());
@ -1327,10 +1230,8 @@ void Application::controllerSucceeded()
auto& extras = m_instanceExtras[id]; auto& extras = m_instanceExtras[id];
// on success, do... // on success, do...
if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) {
{ if (extras.window) {
if(extras.window)
{
extras.window->close(); extras.window->close();
} }
} }
@ -1338,8 +1239,7 @@ void Application::controllerSucceeded()
subRunningInstance(); subRunningInstance();
// quit when there are no more windows. // quit when there are no more windows.
if(shouldExitNow()) if (shouldExitNow()) {
{
m_status = Status::Succeeded; m_status = Status::Succeeded;
exit(0); exit(0);
} }
@ -1359,8 +1259,7 @@ void Application::controllerFailed(const QString& error)
subRunningInstance(); subRunningInstance();
// quit when there are no more windows. // quit when there are no more windows.
if(shouldExitNow()) if (shouldExitNow()) {
{
m_status = Status::Failed; m_status = Status::Failed;
exit(1); exit(1);
} }
@ -1382,24 +1281,18 @@ void Application::ShowGlobalSettings(class QWidget* parent, QString open_page)
MainWindow* Application::showMainWindow(bool minimized) MainWindow* Application::showMainWindow(bool minimized)
{ {
if(m_mainWindow) if (m_mainWindow) {
{
m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized); m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized);
m_mainWindow->raise(); m_mainWindow->raise();
m_mainWindow->activateWindow(); m_mainWindow->activateWindow();
} } else {
else
{
m_mainWindow = new MainWindow(); m_mainWindow = new MainWindow();
m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray()));
m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray()));
if(minimized) if (minimized) {
{
m_mainWindow->showMinimized(); m_mainWindow->showMinimized();
} } else {
else
{
m_mainWindow->show(); m_mainWindow->show();
} }
@ -1419,23 +1312,18 @@ InstanceWindow *Application::showInstanceWindow(InstancePtr instance, QString pa
auto& extras = m_instanceExtras[id]; auto& extras = m_instanceExtras[id];
auto& window = extras.window; auto& window = extras.window;
if(window) if (window) {
{
window->raise(); window->raise();
window->activateWindow(); window->activateWindow();
} } else {
else
{
window = new InstanceWindow(instance); window = new InstanceWindow(instance);
m_openWindows++; m_openWindows++;
connect(window, &InstanceWindow::isClosing, this, &Application::on_windowClose); connect(window, &InstanceWindow::isClosing, this, &Application::on_windowClose);
} }
if(!page.isEmpty()) if (!page.isEmpty()) {
{
window->selectPage(page); window->selectPage(page);
} }
if(extras.controller) if (extras.controller) {
{
extras.controller->setParentWidget(window); extras.controller->setParentWidget(window);
} }
return window; return window;
@ -1445,23 +1333,19 @@ void Application::on_windowClose()
{ {
m_openWindows--; m_openWindows--;
auto instWindow = qobject_cast<InstanceWindow*>(QObject::sender()); auto instWindow = qobject_cast<InstanceWindow*>(QObject::sender());
if(instWindow) if (instWindow) {
{
auto& extras = m_instanceExtras[instWindow->instanceId()]; auto& extras = m_instanceExtras[instWindow->instanceId()];
extras.window = nullptr; extras.window = nullptr;
if(extras.controller) if (extras.controller) {
{
extras.controller->setParentWidget(m_mainWindow); extras.controller->setParentWidget(m_mainWindow);
} }
} }
auto mainWindow = qobject_cast<MainWindow*>(QObject::sender()); auto mainWindow = qobject_cast<MainWindow*>(QObject::sender());
if(mainWindow) if (mainWindow) {
{
m_mainWindow = nullptr; m_mainWindow = nullptr;
} }
// quit when there are no more windows. // quit when there are no more windows.
if(shouldExitNow()) if (shouldExitNow()) {
{
exit(0); exit(0);
} }
} }
@ -1469,23 +1353,14 @@ void Application::on_windowClose()
void Application::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password) void Application::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password)
{ {
// Set the application proxy settings. // Set the application proxy settings.
if (proxyTypeStr == "SOCKS5") if (proxyTypeStr == "SOCKS5") {
{ QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password));
QNetworkProxy::setApplicationProxy( } else if (proxyTypeStr == "HTTP") {
QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password)); QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password));
} } else if (proxyTypeStr == "None") {
else if (proxyTypeStr == "HTTP")
{
QNetworkProxy::setApplicationProxy(
QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password));
}
else if (proxyTypeStr == "None")
{
// If we have no proxy set, set no proxy and return. // If we have no proxy set, set no proxy and return.
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
} } else {
else
{
// If we have "Default" selected, set Qt to use the system proxy settings. // If we have "Default" selected, set Qt to use the system proxy settings.
QNetworkProxyFactory::setUseSystemConfiguration(true); QNetworkProxyFactory::setUseSystemConfiguration(true);
} }
@ -1495,13 +1370,11 @@ void Application::updateProxySettings(QString proxyTypeStr, QString addr, int po
m_network->setProxy(proxy); m_network->setProxy(proxy);
QString proxyDesc; QString proxyDesc;
if (proxy.type() == QNetworkProxy::NoProxy) if (proxy.type() == QNetworkProxy::NoProxy) {
{
qDebug() << "Using no proxy is an option!"; qDebug() << "Using no proxy is an option!";
return; return;
} }
switch (proxy.type()) switch (proxy.type()) {
{
case QNetworkProxy::DefaultProxy: case QNetworkProxy::DefaultProxy:
proxyDesc = "Default proxy: "; proxyDesc = "Default proxy: ";
break; break;
@ -1521,9 +1394,7 @@ void Application::updateProxySettings(QString proxyTypeStr, QString addr, int po
proxyDesc = "DERP proxy: "; proxyDesc = "DERP proxy: ";
break; break;
} }
proxyDesc += QString("%1:%2") proxyDesc += QString("%1:%2").arg(proxy.hostName()).arg(proxy.port());
.arg(proxy.hostName())
.arg(proxy.port());
qDebug() << proxyDesc; qDebug() << proxyDesc;
} }
@ -1539,8 +1410,7 @@ shared_qobject_ptr<QNetworkAccessManager> Application::network()
shared_qobject_ptr<Meta::Index> Application::metadataIndex() shared_qobject_ptr<Meta::Index> Application::metadataIndex()
{ {
if (!m_metadataIndex) if (!m_metadataIndex) {
{
m_metadataIndex.reset(new Meta::Index()); m_metadataIndex.reset(new Meta::Index());
} }
return m_metadataIndex; return m_metadataIndex;
@ -1573,8 +1443,7 @@ QString Application::getJarPath(QString jarFile)
FS::PathCombine(applicationDirPath(), "jars"), FS::PathCombine(applicationDirPath(), "jars"),
FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging
}; };
for(QString p : potentialPaths) for (QString p : potentialPaths) {
{
QString jarPath = FS::PathCombine(p, jarFile); QString jarPath = FS::PathCombine(p, jarFile);
if (QFileInfo(jarPath).isFile()) if (QFileInfo(jarPath).isFile())
return jarPath; return jarPath;

View File

@ -38,12 +38,12 @@
#pragma once #pragma once
#include <QApplication> #include <QApplication>
#include <memory> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QFlag> #include <QFlag>
#include <QIcon> #include <QIcon>
#include <QDateTime>
#include <QUrl> #include <QUrl>
#include <memory>
#include <BaseInstance.h> #include <BaseInstance.h>
@ -81,17 +81,11 @@ namespace Meta {
#endif #endif
#define APPLICATION (static_cast<Application*>(QCoreApplication::instance())) #define APPLICATION (static_cast<Application*>(QCoreApplication::instance()))
class Application : public QApplication class Application : public QApplication {
{
// friends for the purpose of limiting access to deprecated stuff // friends for the purpose of limiting access to deprecated stuff
Q_OBJECT Q_OBJECT
public: public:
enum Status { enum Status { StartingUp, Failed, Succeeded, Initialized };
StartingUp,
Failed,
Succeeded,
Initialized
};
enum Capability { enum Capability {
None = 0, None = 0,
@ -109,13 +103,9 @@ public:
bool event(QEvent* event) override; bool event(QEvent* event) override;
std::shared_ptr<SettingsObject> settings() const { std::shared_ptr<SettingsObject> settings() const { return m_settings; }
return m_settings;
}
qint64 timeSinceStart() const { qint64 timeSinceStart() const { return startTime.msecsTo(QDateTime::currentDateTime()); }
return startTime.msecsTo(QDateTime::currentDateTime());
}
QIcon getThemedIcon(const QString& name); QIcon getThemedIcon(const QString& name);
@ -139,29 +129,17 @@ public:
std::shared_ptr<JavaInstallList> javalist(); std::shared_ptr<JavaInstallList> javalist();
std::shared_ptr<InstanceList> instances() const { std::shared_ptr<InstanceList> instances() const { return m_instances; }
return m_instances;
}
std::shared_ptr<IconList> icons() const { std::shared_ptr<IconList> icons() const { return m_icons; }
return m_icons;
}
MCEditTool *mcedit() const { MCEditTool* mcedit() const { return m_mcedit.get(); }
return m_mcedit.get();
}
shared_qobject_ptr<AccountList> accounts() const { shared_qobject_ptr<AccountList> accounts() const { return m_accounts; }
return m_accounts;
}
Status status() const { Status status() const { return m_status; }
return m_status;
}
const QMap<QString, std::shared_ptr<BaseProfilerFactory>> &profilers() const { const QMap<QString, std::shared_ptr<BaseProfilerFactory>>& profilers() const { return m_profilers; }
return m_profilers;
}
void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password); void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password);
@ -186,17 +164,11 @@ public:
QString getUserAgentUncached(); QString getUserAgentUncached();
/// this is the root of the 'installation'. Used for automatic updates /// this is the root of the 'installation'. Used for automatic updates
const QString &root() { const QString& root() { return m_rootPath; }
return m_rootPath;
}
bool isPortable() { bool isPortable() { return m_portable; }
return m_portable;
}
const Capabilities capabilities() { const Capabilities capabilities() { return m_capabilities; }
return m_capabilities;
}
/*! /*!
* Opens a json file using either a system default editor, or, if not empty, the editor * Opens a json file using either a system default editor, or, if not empty, the editor
@ -225,14 +197,12 @@ signals:
#endif #endif
public slots: public slots:
bool launch( bool launch(InstancePtr instance,
InstancePtr instance,
bool online = true, bool online = true,
bool demo = false, bool demo = false,
BaseProfilerFactory* profiler = nullptr, BaseProfilerFactory* profiler = nullptr,
MinecraftServerTargetPtr serverToJoin = nullptr, MinecraftServerTargetPtr serverToJoin = nullptr,
MinecraftAccountPtr accountToUse = nullptr MinecraftAccountPtr accountToUse = nullptr);
);
bool kill(InstancePtr instance); bool kill(InstancePtr instance);
void closeCurrentWindow(); void closeCurrentWindow();
@ -312,6 +282,7 @@ private:
LocalPeer* m_peerInstance = nullptr; LocalPeer* m_peerInstance = nullptr;
SetupWizard* m_setupWizard = nullptr; SetupWizard* m_setupWizard = nullptr;
public: public:
QString m_instanceIdToLaunch; QString m_instanceIdToLaunch;
QString m_serverToJoin; QString m_serverToJoin;

View File

@ -39,7 +39,8 @@
#include <QJsonObject> #include <QJsonObject>
#include "Json.h" #include "Json.h"
void ApplicationMessage::parse(const QByteArray & input) { void ApplicationMessage::parse(const QByteArray& input)
{
auto doc = Json::requireDocument(input, "ApplicationMessage"); auto doc = Json::requireDocument(input, "ApplicationMessage");
auto root = Json::requireObject(doc, "ApplicationMessage"); auto root = Json::requireObject(doc, "ApplicationMessage");
@ -52,7 +53,8 @@ void ApplicationMessage::parse(const QByteArray & input) {
} }
} }
QByteArray ApplicationMessage::serialize() { QByteArray ApplicationMessage::serialize()
{
QJsonObject root; QJsonObject root;
root.insert("command", command); root.insert("command", command);
QJsonObject outArgs; QJsonObject outArgs;

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <QString>
#include <QHash>
#include <QByteArray> #include <QByteArray>
#include <QHash>
#include <QString>
struct ApplicationMessage { struct ApplicationMessage {
QString command; QString command;

View File

@ -18,10 +18,7 @@
#include "BaseInstaller.h" #include "BaseInstaller.h"
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
BaseInstaller::BaseInstaller() BaseInstaller::BaseInstaller() {}
{
}
bool BaseInstaller::isApplied(MinecraftInstance* on) bool BaseInstaller::isApplied(MinecraftInstance* on)
{ {
@ -30,15 +27,12 @@ bool BaseInstaller::isApplied(MinecraftInstance *on)
bool BaseInstaller::add(MinecraftInstance* to) bool BaseInstaller::add(MinecraftInstance* to)
{ {
if (!patchesDir(to->instanceRoot()).exists()) if (!patchesDir(to->instanceRoot()).exists()) {
{
QDir(to->instanceRoot()).mkdir("patches"); QDir(to->instanceRoot()).mkdir("patches");
} }
if (isApplied(to)) if (isApplied(to)) {
{ if (!remove(to)) {
if (!remove(to))
{
return false; return false;
} }
} }

View File

@ -26,8 +26,7 @@ class QObject;
class Task; class Task;
class BaseVersion; class BaseVersion;
class BaseInstaller class BaseInstaller {
{
public: public:
BaseInstaller(); BaseInstaller();
virtual ~BaseInstaller(){}; virtual ~BaseInstaller(){};

View File

@ -36,23 +36,22 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include <QFileInfo>
#include <QDir>
#include <QDebug> #include <QDebug>
#include <QRegularExpression> #include <QDir>
#include <QFileInfo>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QRegularExpression>
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "settings/Setting.h"
#include "settings/OverrideSetting.h" #include "settings/OverrideSetting.h"
#include "settings/Setting.h"
#include "FileSystem.h"
#include "Commandline.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "Commandline.h"
#include "FileSystem.h"
BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) : QObject()
: QObject()
{ {
m_settings = settings; m_settings = settings;
m_global_settings = globalSettings; m_global_settings = globalSettings;
@ -148,7 +147,11 @@ QString BaseInstance::getManagedPackVersionName() const
return m_settings->get("ManagedPackVersionName").toString(); return m_settings->get("ManagedPackVersionName").toString();
} }
void BaseInstance::setManagedPack(const QString& type, const QString& id, const QString& name, const QString& versionId, const QString& version) void BaseInstance::setManagedPack(const QString& type,
const QString& id,
const QString& name,
const QString& versionId,
const QString& version)
{ {
m_settings->set("ManagedPack", true); m_settings->set("ManagedPack", true);
m_settings->set("ManagedPackType", type); m_settings->set("ManagedPackType", type);
@ -173,8 +176,7 @@ int BaseInstance::getConsoleMaxLines() const
auto lineSetting = m_settings->getSetting("ConsoleMaxLines"); auto lineSetting = m_settings->getSetting("ConsoleMaxLines");
bool conversionOk = false; bool conversionOk = false;
int maxLines = lineSetting->get().toInt(&conversionOk); int maxLines = lineSetting->get().toInt(&conversionOk);
if(!conversionOk) if (!conversionOk) {
{
maxLines = lineSetting->defValue().toInt(); maxLines = lineSetting->defValue().toInt();
qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines; qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines;
} }
@ -220,8 +222,7 @@ bool BaseInstance::isLinkedToInstanceId(const QString& id) const
void BaseInstance::iconUpdated(QString key) void BaseInstance::iconUpdated(QString key)
{ {
if(iconKey() == key) if (iconKey() == key) {
{
emit propertiesChanged(this); emit propertiesChanged(this);
} }
} }
@ -235,8 +236,7 @@ void BaseInstance::invalidate()
void BaseInstance::changeStatus(BaseInstance::Status newStatus) void BaseInstance::changeStatus(BaseInstance::Status newStatus)
{ {
Status status = currentStatus(); Status status = currentStatus();
if(status != newStatus) if (status != newStatus) {
{
m_status = newStatus; m_status = newStatus;
emit statusChanged(status, newStatus); emit statusChanged(status, newStatus);
} }
@ -264,18 +264,14 @@ void BaseInstance::setRunning(bool running)
m_isRunning = running; m_isRunning = running;
if(!m_settings->get("RecordGameTime").toBool()) if (!m_settings->get("RecordGameTime").toBool()) {
{
emit runningStatusChanged(running); emit runningStatusChanged(running);
return; return;
} }
if(running) if (running) {
{
m_timeStarted = QDateTime::currentDateTime(); m_timeStarted = QDateTime::currentDateTime();
} } else {
else
{
QDateTime timeEnded = QDateTime::currentDateTime(); QDateTime timeEnded = QDateTime::currentDateTime();
qint64 current = settings()->get("totalTimePlayed").toLongLong(); qint64 current = settings()->get("totalTimePlayed").toLongLong();
@ -291,8 +287,7 @@ void BaseInstance::setRunning(bool running)
int64_t BaseInstance::totalTimePlayed() const int64_t BaseInstance::totalTimePlayed() const
{ {
qint64 current = m_settings->get("totalTimePlayed").toLongLong(); qint64 current = m_settings->get("totalTimePlayed").toLongLong();
if(m_isRunning) if (m_isRunning) {
{
QDateTime timeNow = QDateTime::currentDateTime(); QDateTime timeNow = QDateTime::currentDateTime();
return current + m_timeStarted.secsTo(timeNow); return current + m_timeStarted.secsTo(timeNow);
} }
@ -301,8 +296,7 @@ int64_t BaseInstance::totalTimePlayed() const
int64_t BaseInstance::lastTimePlayed() const int64_t BaseInstance::lastTimePlayed() const
{ {
if(m_isRunning) if (m_isRunning) {
{
QDateTime timeNow = QDateTime::currentDateTime(); QDateTime timeNow = QDateTime::currentDateTime();
return m_timeStarted.secsTo(timeNow); return m_timeStarted.secsTo(timeNow);
} }

View File

@ -37,24 +37,24 @@
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <QObject>
#include "QObjectPtr.h"
#include <QDateTime> #include <QDateTime>
#include <QSet> #include <QObject>
#include <QProcess> #include <QProcess>
#include <QSet>
#include "QObjectPtr.h"
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
#include "settings/INIFile.h"
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "minecraft/auth/MinecraftAccount.h"
#include "MessageLevel.h" #include "MessageLevel.h"
#include "minecraft/auth/MinecraftAccount.h"
#include "pathmatcher/IPathMatcher.h" #include "pathmatcher/IPathMatcher.h"
#include "settings/INIFile.h"
#include "net/Mode.h" #include "net/Mode.h"
#include "minecraft/launch/MinecraftServerTarget.h"
#include "RuntimeContext.h" #include "RuntimeContext.h"
#include "minecraft/launch/MinecraftServerTarget.h"
class QDir; class QDir;
class Task; class Task;
@ -72,16 +72,14 @@ typedef std::shared_ptr<BaseInstance> InstancePtr;
* To create a new instance type, create a new class inheriting from this class * To create a new instance type, create a new class inheriting from this class
* and implement the pure virtual functions. * and implement the pure virtual functions.
*/ */
class BaseInstance : public QObject, public std::enable_shared_from_this<BaseInstance> class BaseInstance : public QObject, public std::enable_shared_from_this<BaseInstance> {
{
Q_OBJECT Q_OBJECT
protected: protected:
/// no-touchy! /// no-touchy!
BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir); BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir);
public: /* types */ public: /* types */
enum class Status enum class Status {
{
Present, Present,
Gone // either nuked or invalidated Gone // either nuked or invalidated
}; };
@ -117,10 +115,7 @@ public:
QString instanceRoot() const; QString instanceRoot() const;
/// Path to the instance's game root directory. /// Path to the instance's game root directory.
virtual QString gameRoot() const virtual QString gameRoot() const { return instanceRoot(); }
{
return instanceRoot();
}
/// Path to the instance's mods directory. /// Path to the instance's mods directory.
virtual QString modsRoot() const = 0; virtual QString modsRoot() const = 0;
@ -151,10 +146,7 @@ public:
void copyManagedPack(BaseInstance& other); void copyManagedPack(BaseInstance& other);
/// guess log level from a line of game log /// guess log level from a line of game log
virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString &line, MessageLevel::Enum level) virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString& line, MessageLevel::Enum level) { return level; }
{
return level;
}
virtual QStringList extraArguments(); virtual QStringList extraArguments();
@ -189,8 +181,7 @@ public:
virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0; virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0;
/// returns a valid launcher (task container) /// returns a valid launcher (task container)
virtual shared_qobject_ptr<LaunchTask> createLaunchTask( virtual shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0;
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0;
/// returns the current launch task (if any) /// returns the current launch task (if any)
shared_qobject_ptr<LaunchTask> getLaunchTask(); shared_qobject_ptr<LaunchTask> getLaunchTask();
@ -222,45 +213,30 @@ public:
virtual QString typeName() const = 0; virtual QString typeName() const = 0;
void updateRuntimeContext(); void updateRuntimeContext();
RuntimeContext runtimeContext() const RuntimeContext runtimeContext() const { return m_runtimeContext; }
{
return m_runtimeContext;
}
bool hasVersionBroken() const bool hasVersionBroken() const { return m_hasBrokenVersion; }
{
return m_hasBrokenVersion;
}
void setVersionBroken(bool value) void setVersionBroken(bool value)
{ {
if(m_hasBrokenVersion != value) if (m_hasBrokenVersion != value) {
{
m_hasBrokenVersion = value; m_hasBrokenVersion = value;
emit propertiesChanged(this); emit propertiesChanged(this);
} }
} }
bool hasUpdateAvailable() const bool hasUpdateAvailable() const { return m_hasUpdate; }
{
return m_hasUpdate;
}
void setUpdateAvailable(bool value) void setUpdateAvailable(bool value)
{ {
if(m_hasUpdate != value) if (m_hasUpdate != value) {
{
m_hasUpdate = value; m_hasUpdate = value;
emit propertiesChanged(this); emit propertiesChanged(this);
} }
} }
bool hasCrashed() const bool hasCrashed() const { return m_crashed; }
{
return m_crashed;
}
void setCrashed(bool value) void setCrashed(bool value)
{ {
if(m_crashed != value) if (m_crashed != value) {
{
m_crashed = value; m_crashed = value;
emit propertiesChanged(this); emit propertiesChanged(this);
} }
@ -328,7 +304,6 @@ private: /* data */
SettingsObjectWeakPtr m_global_settings; SettingsObjectWeakPtr m_global_settings;
bool m_specific_settings_loaded = false; bool m_specific_settings_loaded = false;
}; };
Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>) Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>)

View File

@ -36,14 +36,11 @@
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "BaseVersion.h" #include "BaseVersion.h"
BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent) BaseVersionList::BaseVersionList(QObject* parent) : QAbstractListModel(parent) {}
{
}
BaseVersion::Ptr BaseVersionList::findVersion(const QString& descriptor) BaseVersion::Ptr BaseVersionList::findVersion(const QString& descriptor)
{ {
for (int i = 0; i < count(); i++) for (int i = 0; i < count(); i++) {
{
if (at(i)->descriptor() == descriptor) if (at(i)->descriptor() == descriptor)
return at(i); return at(i);
} }
@ -68,8 +65,7 @@ QVariant BaseVersionList::data(const QModelIndex &index, int role) const
BaseVersion::Ptr version = at(index.row()); BaseVersion::Ptr version = at(index.row());
switch (role) switch (role) {
{
case VersionPointerRole: case VersionPointerRole:
return QVariant::fromValue(version); return QVariant::fromValue(version);

View File

@ -15,13 +15,13 @@
#pragma once #pragma once
#include <QAbstractListModel>
#include <QObject> #include <QObject>
#include <QVariant> #include <QVariant>
#include <QAbstractListModel>
#include "BaseVersion.h" #include "BaseVersion.h"
#include "tasks/Task.h"
#include "QObjectPtr.h" #include "QObjectPtr.h"
#include "tasks/Task.h"
/*! /*!
* \brief Class that each instance type's version list derives from. * \brief Class that each instance type's version list derives from.
@ -35,12 +35,10 @@
* all have a default implementation, but they can be overridden by plugins to * all have a default implementation, but they can be overridden by plugins to
* change the behavior of the list. * change the behavior of the list.
*/ */
class BaseVersionList : public QAbstractListModel class BaseVersionList : public QAbstractListModel {
{
Q_OBJECT Q_OBJECT
public: public:
enum ModelRoles enum ModelRoles {
{
VersionPointerRole = Qt::UserRole, VersionPointerRole = Qt::UserRole,
VersionRole, VersionRole,
VersionIdRole, VersionIdRole,
@ -103,8 +101,7 @@ public:
*/ */
virtual void sortVersions() = 0; virtual void sortVersions() = 0;
protected protected slots:
slots:
/*! /*!
* Updates this list with the given list of versions. * Updates this list with the given list of versions.
* This is done by copying each version in the given list and inserting it * This is done by copying each version in the given list and inserting it

View File

@ -41,8 +41,7 @@
* @file libutil/src/cmdutils.cpp * @file libutil/src/cmdutils.cpp
*/ */
namespace Commandline namespace Commandline {
{
// commandline splitter // commandline splitter
QStringList splitArgs(QString args) QStringList splitArgs(QString args)
@ -51,19 +50,15 @@ QStringList splitArgs(QString args)
QString current; QString current;
bool escape = false; bool escape = false;
QChar inquotes; QChar inquotes;
for (int i = 0; i < args.length(); i++) for (int i = 0; i < args.length(); i++) {
{
QChar cchar = args.at(i); QChar cchar = args.at(i);
// \ escaped // \ escaped
if (escape) if (escape) {
{
current += cchar; current += cchar;
escape = false; escape = false;
// in "quotes" // in "quotes"
} } else if (!inquotes.isNull()) {
else if (!inquotes.isNull())
{
if (cchar == '\\') if (cchar == '\\')
escape = true; escape = true;
else if (cchar == inquotes) else if (cchar == inquotes)
@ -71,18 +66,13 @@ QStringList splitArgs(QString args)
else else
current += cchar; current += cchar;
// otherwise // otherwise
} } else {
else if (cchar == ' ') {
{ if (!current.isEmpty()) {
if (cchar == ' ')
{
if (!current.isEmpty())
{
argv << current; argv << current;
current.clear(); current.clear();
} }
} } else if (cchar == '"' || cchar == '\'')
else if (cchar == '"' || cchar == '\'')
inquotes = cchar; inquotes = cchar;
else else
current += cchar; current += cchar;
@ -92,4 +82,4 @@ QStringList splitArgs(QString args)
argv << current; argv << current;
return argv; return argv;
} }
} } // namespace Commandline

View File

@ -25,8 +25,7 @@
* @brief commandline parsing and processing utilities * @brief commandline parsing and processing utilities
*/ */
namespace Commandline namespace Commandline {
{
/** /**
* @brief split a string into argv items like a shell would do * @brief split a string into argv items like a shell would do
@ -34,4 +33,4 @@ namespace Commandline
* @return a QStringList containing all arguments * @return a QStringList containing all arguments
*/ */
QStringList splitArgs(QString args); QStringList splitArgs(QString args);
} } // namespace Commandline

View File

@ -1,13 +1,9 @@
#pragma once #pragma once
template <typename T> template <typename T>
class DefaultVariable class DefaultVariable {
{
public: public:
DefaultVariable(const T & value) DefaultVariable(const T& value) { defaultValue = value; }
{
defaultValue = value;
}
DefaultVariable<T>& operator=(const T& value) DefaultVariable<T>& operator=(const T& value)
{ {
currentValue = value; currentValue = value;
@ -15,18 +11,10 @@ public:
is_explicit = true; is_explicit = true;
return *this; return *this;
} }
operator const T &() const operator const T&() const { return is_default ? defaultValue : currentValue; }
{ bool isDefault() const { return is_default; }
return is_default ? defaultValue : currentValue; bool isExplicit() const { return is_explicit; }
}
bool isDefault() const
{
return is_default;
}
bool isExplicit() const
{
return is_explicit;
}
private: private:
T currentValue; T currentValue;
T defaultValue; T defaultValue;

View File

@ -33,40 +33,37 @@
* limitations under the License. * limitations under the License.
*/ */
#include "DesktopServices.h" #include "DesktopServices.h"
#include <QDir>
#include <QDesktopServices>
#include <QProcess>
#include <QDebug> #include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QProcess>
/** /**
* This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing. * This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing.
*/ */
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h>
template <typename T> template <typename T>
bool IndirectOpen(T callable, qint64* pid_forked = nullptr) bool IndirectOpen(T callable, qint64* pid_forked = nullptr)
{ {
auto pid = fork(); auto pid = fork();
if(pid_forked) if (pid_forked) {
{
if (pid > 0) if (pid > 0)
*pid_forked = pid; *pid_forked = pid;
else else
*pid_forked = 0; *pid_forked = 0;
} }
if(pid == -1) if (pid == -1) {
{
qWarning() << "IndirectOpen failed to fork: " << errno; qWarning() << "IndirectOpen failed to fork: " << errno;
return false; return false;
} }
// child - do the stuff // child - do the stuff
if(pid == 0) if (pid == 0) {
{
// unset all this garbage so it doesn't get passed to the child process // unset all this garbage so it doesn't get passed to the child process
qunsetenv("LD_PRELOAD"); qunsetenv("LD_PRELOAD");
qunsetenv("LD_LIBRARY_PATH"); qunsetenv("LD_LIBRARY_PATH");
@ -82,19 +79,14 @@ bool IndirectOpen(T callable, qint64 *pid_forked = nullptr)
// die. now. do not clean up anything, it would just hang forever. // die. now. do not clean up anything, it would just hang forever.
_exit(status ? 0 : 1); _exit(status ? 0 : 1);
} } else {
else
{
// parent - assume it worked. // parent - assume it worked.
int status; int status;
while (waitpid(pid, &status, 0)) while (waitpid(pid, &status, 0)) {
{ if (WIFEXITED(status)) {
if(WIFEXITED(status))
{
return WEXITSTATUS(status) == 0; return WEXITSTATUS(status) == 0;
} }
if(WIFSIGNALED(status)) if (WIFSIGNALED(status)) {
{
return false; return false;
} }
} }
@ -109,21 +101,14 @@ bool openDirectory(const QString &path, [[maybe_unused]] bool ensureExists)
qDebug() << "Opening directory" << path; qDebug() << "Opening directory" << path;
QDir parentPath; QDir parentPath;
QDir dir(path); QDir dir(path);
if (!dir.exists()) if (!dir.exists()) {
{
parentPath.mkpath(dir.absolutePath()); parentPath.mkpath(dir.absolutePath());
} }
auto f = [&]() auto f = [&]() { return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); };
{
return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!isSandbox()) if (!isSandbox()) {
{
return IndirectOpen(f); return IndirectOpen(f);
} } else {
else
{
return f(); return f();
} }
#else #else
@ -134,17 +119,11 @@ bool openDirectory(const QString &path, [[maybe_unused]] bool ensureExists)
bool openFile(const QString& path) bool openFile(const QString& path)
{ {
qDebug() << "Opening file" << path; qDebug() << "Opening file" << path;
auto f = [&]() auto f = [&]() { return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); };
{
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!isSandbox()) if (!isSandbox()) {
{
return IndirectOpen(f); return IndirectOpen(f);
} } else {
else
{
return f(); return f();
} }
#else #else
@ -157,15 +136,9 @@ bool openFile(const QString &application, const QString &path, const QString &wo
qDebug() << "Opening file" << path << "using" << application; qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
if(!isSandbox()) if (!isSandbox()) {
{ return IndirectOpen([&]() { return QProcess::startDetached(application, QStringList() << path, workingDirectory); }, pid);
return IndirectOpen([&]() } else {
{
return QProcess::startDetached(application, QStringList() << path, workingDirectory);
}, pid);
}
else
{
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid); return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
} }
#else #else
@ -177,16 +150,10 @@ bool run(const QString &application, const QStringList &args, const QString &wor
{ {
qDebug() << "Running" << application << "with args" << args.join(' '); qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!isSandbox()) if (!isSandbox()) {
{
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]() return IndirectOpen([&]() { return QProcess::startDetached(application, args, workingDirectory); }, pid);
{ } else {
return QProcess::startDetached(application, args, workingDirectory);
}, pid);
}
else
{
return QProcess::startDetached(application, args, workingDirectory, pid); return QProcess::startDetached(application, args, workingDirectory, pid);
} }
#else #else
@ -197,17 +164,11 @@ bool run(const QString &application, const QStringList &args, const QString &wor
bool openUrl(const QUrl& url) bool openUrl(const QUrl& url)
{ {
qDebug() << "Opening URL" << url.toString(); qDebug() << "Opening URL" << url.toString();
auto f = [&]() auto f = [&]() { return QDesktopServices::openUrl(url); };
{
return QDesktopServices::openUrl(url);
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if(!isSandbox()) if (!isSandbox()) {
{
return IndirectOpen(f); return IndirectOpen(f);
} } else {
else
{
return f(); return f();
} }
#else #else
@ -238,4 +199,4 @@ bool isSandbox()
return isSnap() || isFlatpak(); return isSnap() || isFlatpak();
} }
} } // namespace DesktopServices

View File

@ -1,14 +1,13 @@
#pragma once #pragma once
#include <QUrl>
#include <QString> #include <QString>
#include <QUrl>
/** /**
* This wraps around QDesktopServices and adds workarounds where needed * This wraps around QDesktopServices and adds workarounds where needed
* Use this instead of QDesktopServices! * Use this instead of QDesktopServices!
*/ */
namespace DesktopServices namespace DesktopServices {
{
/** /**
* Open a file in whatever application is applicable * Open a file in whatever application is applicable
*/ */
@ -48,4 +47,4 @@ namespace DesktopServices
* Determine whether the launcher is running in a sandboxed (Flatpak or Snap) environment * Determine whether the launcher is running in a sandboxed (Flatpak or Snap) environment
*/ */
bool isSandbox(); bool isSandbox();
} } // namespace DesktopServices

View File

@ -2,30 +2,17 @@
#pragma once #pragma once
#include <QString>
#include <QDebug> #include <QDebug>
#include <QString>
#include <exception> #include <exception>
class Exception : public std::exception class Exception : public std::exception {
{
public: public:
Exception(const QString &message) : std::exception(), m_message(message) Exception(const QString& message) : std::exception(), m_message(message) { qCritical() << "Exception:" << message; }
{ Exception(const Exception& other) : std::exception(), m_message(other.cause()) {}
qCritical() << "Exception:" << message;
}
Exception(const Exception &other)
: std::exception(), m_message(other.cause())
{
}
virtual ~Exception() noexcept {} virtual ~Exception() noexcept {}
const char *what() const noexcept const char* what() const noexcept { return m_message.toLatin1().constData(); }
{ QString cause() const { return m_message; }
return m_message.toLatin1().constData();
}
QString cause() const
{
return m_message;
}
private: private:
QString m_message; QString m_message;

View File

@ -4,20 +4,16 @@
template <typename T> template <typename T>
inline void clamp(T& current, T min, T max) inline void clamp(T& current, T min, T max)
{ {
if (current < min) if (current < min) {
{
current = min; current = min;
} } else if (current > max) {
else if(current > max)
{
current = max; current = max;
} }
} }
// List of numbers from min to max. Next is exponent times bigger than previous. // List of numbers from min to max. Next is exponent times bigger than previous.
class ExponentialSeries class ExponentialSeries {
{
public: public:
ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2) ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2)
{ {
@ -25,10 +21,7 @@ public:
m_max = max; m_max = max;
m_exponent = exponent; m_exponent = exponent;
} }
void reset() void reset() { m_current = m_min; }
{
m_current = m_min;
}
unsigned operator()() unsigned operator()()
{ {
unsigned retval = m_current; unsigned retval = m_current;

View File

@ -779,7 +779,8 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
} }
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
// Create the Application // Create the Application
QDir applicationDirectory = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/"; QDir applicationDirectory =
QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/";
if (!applicationDirectory.mkpath(".")) { if (!applicationDirectory.mkpath(".")) {
qWarning() << "Couldn't create application directory"; qWarning() << "Couldn't create application directory";
@ -843,7 +844,9 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
" <key>CFBundleIconFile</key>\n" " <key>CFBundleIconFile</key>\n"
" <string>Icon.icns</string>\n" " <string>Icon.icns</string>\n"
" <key>CFBundleName</key>\n" " <key>CFBundleName</key>\n"
" <string>" << name << "</string>\n" // Name of the application " <string>"
<< name
<< "</string>\n" // Name of the application
" <key>CFBundlePackageType</key>\n" " <key>CFBundlePackageType</key>\n"
" <string>APPL</string>\n" " <string>APPL</string>\n"
" <key>CFBundleShortVersionString</key>\n" " <key>CFBundleShortVersionString</key>\n"

View File

@ -43,10 +43,10 @@
#include <system_error> #include <system_error>
#include <QDir> #include <QDir>
#include <QPair>
#include <QFlags> #include <QFlags>
#include <QLocalServer> #include <QLocalServer>
#include <QObject> #include <QObject>
#include <QPair>
#include <QThread> #include <QThread>
namespace FS { namespace FS {
@ -365,12 +365,12 @@ enum class FilesystemType {
* QMap is ordered * QMap is ordered
* *
*/ */
static const QMap<FilesystemType, QStringList> s_filesystem_type_names = { static const QMap<FilesystemType, QStringList> s_filesystem_type_names = { { FilesystemType::FAT, { "FAT" } },
{FilesystemType::FAT, { "FAT" }},
{ FilesystemType::NTFS, { "NTFS" } }, { FilesystemType::NTFS, { "NTFS" } },
{ FilesystemType::REFS, { "REFS" } }, { FilesystemType::REFS, { "REFS" } },
{ FilesystemType::EXT_2_OLD, { "EXT_2_OLD", "EXT2_OLD" } }, { FilesystemType::EXT_2_OLD, { "EXT_2_OLD", "EXT2_OLD" } },
{FilesystemType::EXT_2_3_4, { "EXT2/3/4", "EXT_2_3_4", "EXT2", "EXT3", "EXT4" }}, { FilesystemType::EXT_2_3_4,
{ "EXT2/3/4", "EXT_2_3_4", "EXT2", "EXT3", "EXT4" } },
{ FilesystemType::EXT, { "EXT" } }, { FilesystemType::EXT, { "EXT" } },
{ FilesystemType::XFS, { "XFS" } }, { FilesystemType::XFS, { "XFS" } },
{ FilesystemType::BTRFS, { "BTRFS" } }, { FilesystemType::BTRFS, { "BTRFS" } },
@ -382,8 +382,7 @@ static const QMap<FilesystemType, QStringList> s_filesystem_type_names = {
{ FilesystemType::HFSX, { "HFSX" } }, { FilesystemType::HFSX, { "HFSX" } },
{ FilesystemType::FUSEBLK, { "FUSEBLK" } }, { FilesystemType::FUSEBLK, { "FUSEBLK" } },
{ FilesystemType::F2FS, { "F2FS" } }, { FilesystemType::F2FS, { "F2FS" } },
{FilesystemType::UNKNOWN, { "UNKNOWN" }} { FilesystemType::UNKNOWN, { "UNKNOWN" } } };
};
/** /**
* @brief Get the string name of Filesystem enum object * @brief Get the string name of Filesystem enum object

View File

@ -22,8 +22,7 @@ bool ExactIfPresentFilter::accepts(const QString& value)
return value.isEmpty() || value == pattern; return value.isEmpty() || value == pattern;
} }
RegexpFilter::RegexpFilter(const QString& regexp, bool invert) RegexpFilter::RegexpFilter(const QString& regexp, bool invert) : invert(invert)
:invert(invert)
{ {
pattern.setPattern(regexp); pattern.setPattern(regexp);
pattern.optimize(); pattern.optimize();

View File

@ -1,51 +1,50 @@
#pragma once #pragma once
#include <QString>
#include <QRegularExpression> #include <QRegularExpression>
#include <QString>
class Filter class Filter {
{
public: public:
virtual ~Filter(); virtual ~Filter();
virtual bool accepts(const QString& value) = 0; virtual bool accepts(const QString& value) = 0;
}; };
class ContainsFilter: public Filter class ContainsFilter : public Filter {
{
public: public:
ContainsFilter(const QString& pattern); ContainsFilter(const QString& pattern);
virtual ~ContainsFilter(); virtual ~ContainsFilter();
bool accepts(const QString& value) override; bool accepts(const QString& value) override;
private: private:
QString pattern; QString pattern;
}; };
class ExactFilter: public Filter class ExactFilter : public Filter {
{
public: public:
ExactFilter(const QString& pattern); ExactFilter(const QString& pattern);
virtual ~ExactFilter(); virtual ~ExactFilter();
bool accepts(const QString& value) override; bool accepts(const QString& value) override;
private: private:
QString pattern; QString pattern;
}; };
class ExactIfPresentFilter: public Filter class ExactIfPresentFilter : public Filter {
{
public: public:
ExactIfPresentFilter(const QString& pattern); ExactIfPresentFilter(const QString& pattern);
~ExactIfPresentFilter() override = default; ~ExactIfPresentFilter() override = default;
bool accepts(const QString& value) override; bool accepts(const QString& value) override;
private: private:
QString pattern; QString pattern;
}; };
class RegexpFilter: public Filter class RegexpFilter : public Filter {
{
public: public:
RegexpFilter(const QString& regexp, bool invert); RegexpFilter(const QString& regexp, bool invert);
virtual ~RegexpFilter(); virtual ~RegexpFilter();
bool accepts(const QString& value) override; bool accepts(const QString& value) override;
private: private:
QRegularExpression pattern; QRegularExpression pattern;
bool invert = false; bool invert = false;

View File

@ -39,8 +39,7 @@
bool GZip::unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes) bool GZip::unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes)
{ {
if (compressedBytes.size() == 0) if (compressedBytes.size() == 0) {
{
uncompressedBytes = compressedBytes; uncompressedBytes = compressedBytes;
return true; return true;
} }
@ -56,18 +55,15 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
bool done = false; bool done = false;
if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
{
return false; return false;
} }
int err = Z_OK; int err = Z_OK;
while (!done) while (!done) {
{
// If our output buffer is too small // If our output buffer is too small
if (strm.total_out >= uncompLength) if (strm.total_out >= uncompLength) {
{
uncompressedBytes.resize(uncompLength * 2); uncompressedBytes.resize(uncompLength * 2);
uncompLength *= 2; uncompLength *= 2;
} }
@ -79,14 +75,12 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
err = inflate(&strm, Z_SYNC_FLUSH); err = inflate(&strm, Z_SYNC_FLUSH);
if (err == Z_STREAM_END) if (err == Z_STREAM_END)
done = true; done = true;
else if (err != Z_OK) else if (err != Z_OK) {
{
break; break;
} }
} }
if (inflateEnd(&strm) != Z_OK || !done) if (inflateEnd(&strm) != Z_OK || !done) {
{
return false; return false;
} }
@ -96,8 +90,7 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
bool GZip::zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes) bool GZip::zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes)
{ {
if (uncompressedBytes.size() == 0) if (uncompressedBytes.size() == 0) {
{
compressedBytes = uncompressedBytes; compressedBytes = uncompressedBytes;
return true; return true;
} }
@ -109,8 +102,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
z_stream zs; z_stream zs;
memset(&zs, 0, sizeof(zs)); memset(&zs, 0, sizeof(zs));
if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) {
{
return false; return false;
} }
@ -122,11 +114,9 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
unsigned offset = 0; unsigned offset = 0;
unsigned temp = 0; unsigned temp = 0;
do do {
{
auto remaining = compressedBytes.size() - offset; auto remaining = compressedBytes.size() - offset;
if(remaining < 1) if (remaining < 1) {
{
compressedBytes.resize(compressedBytes.size() * 2); compressedBytes.resize(compressedBytes.size() * 2);
} }
zs.next_out = reinterpret_cast<Bytef*>((compressedBytes.data() + offset)); zs.next_out = reinterpret_cast<Bytef*>((compressedBytes.data() + offset));
@ -137,13 +127,11 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
compressedBytes.resize(offset); compressedBytes.resize(offset);
if (deflateEnd(&zs) != Z_OK) if (deflateEnd(&zs) != Z_OK) {
{
return false; return false;
} }
if (ret != Z_STREAM_END) if (ret != Z_STREAM_END) {
{
return false; return false;
} }
return true; return true;

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <QByteArray> #include <QByteArray>
class GZip class GZip {
{
public: public:
static bool unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes); static bool unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes);
static bool zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes); static bool zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes);
}; };

View File

@ -6,17 +6,10 @@
bool InstanceCopyPrefs::allTrue() const bool InstanceCopyPrefs::allTrue() const
{ {
return copySaves && return copySaves && keepPlaytime && copyGameOptions && copyResourcePacks && copyShaderPacks && copyServers && copyMods &&
keepPlaytime &&
copyGameOptions &&
copyResourcePacks &&
copyShaderPacks &&
copyServers &&
copyMods &&
copyScreenshots; copyScreenshots;
} }
// Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat") // Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat")
QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const
{ {
@ -33,16 +26,21 @@ QString InstanceCopyPrefs::getSelectedFiltersAsRegex(const QStringList& addition
filters << "options.txt"; filters << "options.txt";
if (!copyResourcePacks) if (!copyResourcePacks)
filters << "resourcepacks" << "texturepacks"; filters << "resourcepacks"
<< "texturepacks";
if (!copyShaderPacks) if (!copyShaderPacks)
filters << "shaderpacks"; filters << "shaderpacks";
if (!copyServers) if (!copyServers)
filters << "servers.dat" << "servers.dat_old" << "server-resource-packs"; filters << "servers.dat"
<< "servers.dat_old"
<< "server-resource-packs";
if (!copyMods) if (!copyMods)
filters << "coremods" << "mods" << "config"; filters << "coremods"
<< "mods"
<< "config";
if (!copyScreenshots) if (!copyScreenshots)
filters << "screenshots"; filters << "screenshots";

View File

@ -156,7 +156,8 @@ void InstanceCopyTask::copyFinished()
allowed_symlinks.append(m_origInstance->gameRoot().toUtf8()); allowed_symlinks.append(m_origInstance->gameRoot().toUtf8());
allowed_symlinks.append("\n"); allowed_symlinks.append("\n");
if (allowed_symlinks_file.isSymLink()) if (allowed_symlinks_file.isSymLink())
FS::deletePath(allowed_symlinks_file FS::deletePath(
allowed_symlinks_file
.filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link. .filePath()); // we dont want to modify the original. also make sure the resulting file is not itself a link.
FS::write(allowed_symlinks_file.filePath(), allowed_symlinks); FS::write(allowed_symlinks_file.filePath(), allowed_symlinks);

View File

@ -11,8 +11,7 @@
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
#include "tasks/Task.h" #include "tasks/Task.h"
class InstanceCopyTask : public InstanceTask class InstanceCopyTask : public InstanceTask {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs); explicit InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs);

View File

@ -45,9 +45,9 @@
#include "icons/IconList.h" #include "icons/IconList.h"
#include "icons/IconUtils.h" #include "icons/IconUtils.h"
#include "modplatform/technic/TechnicPackProcessor.h"
#include "modplatform/modrinth/ModrinthInstanceCreationTask.h"
#include "modplatform/flame/FlameInstanceCreationTask.h" #include "modplatform/flame/FlameInstanceCreationTask.h"
#include "modplatform/modrinth/ModrinthInstanceCreationTask.h"
#include "modplatform/technic/TechnicPackProcessor.h"
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
@ -140,8 +140,7 @@ void InstanceImportTask::processZipPack()
// open the zip and find relevant files in it // open the zip and find relevant files in it
m_packZip.reset(new QuaZip(m_archivePath)); m_packZip.reset(new QuaZip(m_archivePath));
if (!m_packZip->open(QuaZip::mdUnzip)) if (!m_packZip->open(QuaZip::mdUnzip)) {
{
emitFailed(tr("Unable to open supplied modpack zip file.")); emitFailed(tr("Unable to open supplied modpack zip file."));
return; return;
} }
@ -155,22 +154,17 @@ void InstanceImportTask::processZipPack()
// NOTE: Prioritize modpack platforms that aren't searched for recursively. // NOTE: Prioritize modpack platforms that aren't searched for recursively.
// Especially Flame has a very common filename for its manifest, which may appear inside overrides for example // Especially Flame has a very common filename for its manifest, which may appear inside overrides for example
if(modrinthFound) if (modrinthFound) {
{
// process as Modrinth pack // process as Modrinth pack
qDebug() << "Modrinth:" << modrinthFound; qDebug() << "Modrinth:" << modrinthFound;
m_modpackType = ModpackType::Modrinth; m_modpackType = ModpackType::Modrinth;
} } else if (technicFound) {
else if (technicFound)
{
// process as Technic pack // process as Technic pack
qDebug() << "Technic:" << technicFound; qDebug() << "Technic:" << technicFound;
extractDir.mkpath(".minecraft"); extractDir.mkpath(".minecraft");
extractDir.cd(".minecraft"); extractDir.cd(".minecraft");
m_modpackType = ModpackType::Technic; m_modpackType = ModpackType::Technic;
} } else {
else
{
QStringList paths_to_ignore{ "overrides/" }; QStringList paths_to_ignore{ "overrides/" };
if (QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg", paths_to_ignore); !mmcRoot.isNull()) { if (QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg", paths_to_ignore); !mmcRoot.isNull()) {
@ -178,21 +172,22 @@ void InstanceImportTask::processZipPack()
qDebug() << "MultiMC:" << mmcRoot; qDebug() << "MultiMC:" << mmcRoot;
root = mmcRoot; root = mmcRoot;
m_modpackType = ModpackType::MultiMC; m_modpackType = ModpackType::MultiMC;
} else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore); !flameRoot.isNull()) { } else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore);
!flameRoot.isNull()) {
// process as Flame pack // process as Flame pack
qDebug() << "Flame:" << flameRoot; qDebug() << "Flame:" << flameRoot;
root = flameRoot; root = flameRoot;
m_modpackType = ModpackType::Flame; m_modpackType = ModpackType::Flame;
} }
} }
if(m_modpackType == ModpackType::Unknown) if (m_modpackType == ModpackType::Unknown) {
{
emitFailed(tr("Archive does not contain a recognized modpack type.")); emitFailed(tr("Archive does not contain a recognized modpack type."));
return; return;
} }
// make sure we extract just the pack // make sure we extract just the pack
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath()); m_extractFuture =
QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath());
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &InstanceImportTask::extractFinished); connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &InstanceImportTask::extractFinished);
m_extractFutureWatcher.setFuture(m_extractFuture); m_extractFutureWatcher.setFuture(m_extractFuture);
} }
@ -212,37 +207,28 @@ void InstanceImportTask::extractFinished()
qDebug() << "Fixing permissions for extracted pack files..."; qDebug() << "Fixing permissions for extracted pack files...";
QDirIterator it(extractDir, QDirIterator::Subdirectories); QDirIterator it(extractDir, QDirIterator::Subdirectories);
while (it.hasNext()) while (it.hasNext()) {
{
auto filepath = it.next(); auto filepath = it.next();
QFileInfo file(filepath); QFileInfo file(filepath);
auto permissions = QFile::permissions(filepath); auto permissions = QFile::permissions(filepath);
auto origPermissions = permissions; auto origPermissions = permissions;
if(file.isDir()) if (file.isDir()) {
{
// Folder +rwx for current user // Folder +rwx for current user
permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser; permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
} } else {
else
{
// File +rw for current user // File +rw for current user
permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser; permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
} }
if(origPermissions != permissions) if (origPermissions != permissions) {
{ if (!QFile::setPermissions(filepath, permissions)) {
if(!QFile::setPermissions(filepath, permissions))
{
logWarning(tr("Could not fix permissions for %1").arg(filepath)); logWarning(tr("Could not fix permissions for %1").arg(filepath));
} } else {
else
{
qDebug() << "Fixed" << filepath; qDebug() << "Fixed" << filepath;
} }
} }
} }
switch(m_modpackType) switch (m_modpackType) {
{
case ModpackType::MultiMC: case ModpackType::MultiMC:
processMultiMC(); processMultiMC();
return; return;
@ -278,7 +264,8 @@ void InstanceImportTask::processFlame()
if (original_instance_id_it != m_extra_info.constEnd()) if (original_instance_id_it != m_extra_info.constEnd())
original_instance_id = original_instance_id_it.value(); original_instance_id = original_instance_id_it.value();
inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); inst_creation_task =
makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
} else { } else {
// FIXME: Find a way to get IDs in directly imported ZIPs // FIXME: Find a way to get IDs in directly imported ZIPs
inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, QString(), QString()); inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, QString(), QString());
@ -364,7 +351,8 @@ void InstanceImportTask::processModrinth()
if (original_instance_id_it != m_extra_info.constEnd()) if (original_instance_id_it != m_extra_info.constEnd())
original_instance_id = original_instance_id_it.value(); original_instance_id = original_instance_id_it.value();
inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); inst_creation_task =
new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
} else { } else {
QString pack_id; QString pack_id;
if (!m_sourceUrl.isEmpty()) { if (!m_sourceUrl.isEmpty()) {

View File

@ -35,34 +35,29 @@
#pragma once #pragma once
#include "InstanceTask.h"
#include "net/NetJob.h"
#include <QUrl>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher> #include <QFutureWatcher>
#include "settings/SettingsObject.h" #include <QUrl>
#include "InstanceTask.h"
#include "QObjectPtr.h" #include "QObjectPtr.h"
#include "modplatform/flame/PackManifest.h" #include "modplatform/flame/PackManifest.h"
#include "net/NetJob.h"
#include "settings/SettingsObject.h"
#include <optional> #include <optional>
class QuaZip; class QuaZip;
namespace Flame namespace Flame {
{
class FileResolvingTask; class FileResolvingTask;
} }
class InstanceImportTask : public InstanceTask class InstanceImportTask : public InstanceTask {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {}); explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {});
bool abort() override; bool abort() override;
const QVector<Flame::File> &getBlockedFiles() const const QVector<Flame::File>& getBlockedFiles() const { return m_blockedMods; }
{
return m_blockedMods;
}
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.

View File

@ -15,12 +15,12 @@
#pragma once #pragma once
#include <QObject>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QSet>
#include <QList> #include <QList>
#include <QStack> #include <QObject>
#include <QPair> #include <QPair>
#include <QSet>
#include <QStack>
#include "BaseInstance.h" #include "BaseInstance.h"
@ -32,21 +32,9 @@ using InstanceId = QString;
using GroupId = QString; using GroupId = QString;
using InstanceLocator = std::pair<InstancePtr, int>; using InstanceLocator = std::pair<InstancePtr, int>;
enum class InstCreateError enum class InstCreateError { NoCreateError = 0, NoSuchVersion, UnknownCreateError, InstExists, CantCreateDir };
{
NoCreateError = 0,
NoSuchVersion,
UnknownCreateError,
InstExists,
CantCreateDir
};
enum class GroupsState enum class GroupsState { NotLoaded, Steady, Dirty };
{
NotLoaded,
Steady,
Dirty
};
struct TrashHistoryItem { struct TrashHistoryItem {
QString id; QString id;
@ -55,8 +43,7 @@ struct TrashHistoryItem {
QString groupName; QString groupName;
}; };
class InstanceList : public QAbstractListModel class InstanceList : public QAbstractListModel {
{
Q_OBJECT Q_OBJECT
public: public:
@ -71,8 +58,7 @@ public:
bool setData(const QModelIndex& index, const QVariant& value, int role) override; bool setData(const QModelIndex& index, const QVariant& value, int role) override;
enum AdditionalRoles enum AdditionalRoles {
{
GroupRole = Qt::UserRole, GroupRole = Qt::UserRole,
InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance
InstanceIDRole = 0x34B1CB49 ///< Return id if the instance InstanceIDRole = 0x34B1CB49 ///< Return id if the instance
@ -82,21 +68,11 @@ public:
* NoError Indicates that no error occurred. * NoError Indicates that no error occurred.
* UnknownError indicates that an unspecified error occurred. * UnknownError indicates that an unspecified error occurred.
*/ */
enum InstListError enum InstListError { NoError = 0, UnknownError };
{
NoError = 0,
UnknownError
};
InstancePtr at(int i) const InstancePtr at(int i) const { return m_instances.at(i); }
{
return m_instances.at(i);
}
int count() const int count() const { return m_instances.count(); }
{
return m_instances.count();
}
InstListError loadList(); InstListError loadList();
void saveNow(); void saveNow();

View File

@ -1,30 +1,26 @@
#pragma once #pragma once
#include "minecraft/MinecraftInstance.h"
#include <FileSystem.h> #include <FileSystem.h>
#include "minecraft/MinecraftInstance.h"
#include "ui/pages/BasePage.h" #include "ui/pages/BasePage.h"
#include "ui/pages/BasePageProvider.h" #include "ui/pages/BasePageProvider.h"
#include "ui/pages/instance/InstanceSettingsPage.h"
#include "ui/pages/instance/LogPage.h" #include "ui/pages/instance/LogPage.h"
#include "ui/pages/instance/VersionPage.h"
#include "ui/pages/instance/ManagedPackPage.h" #include "ui/pages/instance/ManagedPackPage.h"
#include "ui/pages/instance/ModFolderPage.h" #include "ui/pages/instance/ModFolderPage.h"
#include "ui/pages/instance/ResourcePackPage.h"
#include "ui/pages/instance/TexturePackPage.h"
#include "ui/pages/instance/ShaderPackPage.h"
#include "ui/pages/instance/NotesPage.h" #include "ui/pages/instance/NotesPage.h"
#include "ui/pages/instance/ScreenshotsPage.h"
#include "ui/pages/instance/InstanceSettingsPage.h"
#include "ui/pages/instance/OtherLogsPage.h" #include "ui/pages/instance/OtherLogsPage.h"
#include "ui/pages/instance/WorldListPage.h" #include "ui/pages/instance/ResourcePackPage.h"
#include "ui/pages/instance/ScreenshotsPage.h"
#include "ui/pages/instance/ServersPage.h" #include "ui/pages/instance/ServersPage.h"
#include "ui/pages/instance/ShaderPackPage.h"
#include "ui/pages/instance/TexturePackPage.h"
#include "ui/pages/instance/VersionPage.h"
#include "ui/pages/instance/WorldListPage.h"
class InstancePageProvider : protected QObject, public BasePageProvider class InstancePageProvider : protected QObject, public BasePageProvider {
{
Q_OBJECT Q_OBJECT
public: public:
explicit InstancePageProvider(InstancePtr parent) explicit InstancePageProvider(InstancePtr parent) { inst = parent; }
{
inst = parent;
}
virtual ~InstancePageProvider(){}; virtual ~InstancePageProvider(){};
virtual QList<BasePage*> getPages() override virtual QList<BasePage*> getPages() override
@ -49,18 +45,14 @@ public:
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots"))); values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix.get())); values.append(new InstanceSettingsPage(onesix.get()));
auto logMatcher = inst->getLogFileMatcher(); auto logMatcher = inst->getLogFileMatcher();
if(logMatcher) if (logMatcher) {
{
values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher)); values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher));
} }
return values; return values;
} }
virtual QString dialogTitle() override virtual QString dialogTitle() override { return tr("Edit Instance (%1)").arg(inst->name()); }
{
return tr("Edit Instance (%1)").arg(inst->name());
}
protected: protected:
InstancePtr inst; InstancePtr inst;
}; };

View File

@ -22,7 +22,8 @@ ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name)
{ {
auto info = CustomMessageBox::selectable( auto info = CustomMessageBox::selectable(
parent, QObject::tr("Similar modpack was found!"), parent, QObject::tr("Similar modpack was found!"),
QObject::tr("One or more of your instances are from this same modpack%1. Do you want to create a " QObject::tr(
"One or more of your instances are from this same modpack%1. Do you want to create a "
"separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before "
"updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).")
.arg(original_version_name), .arg(original_version_name),
@ -38,7 +39,6 @@ ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name)
if (info->clickedButton() == info->button(QMessageBox::Abort)) if (info->clickedButton() == info->button(QMessageBox::Abort))
return ShouldUpdate::SkipUpdating; return ShouldUpdate::SkipUpdating;
return ShouldUpdate::Cancel; return ShouldUpdate::Cancel;
} }
QString InstanceName::name() const QString InstanceName::name() const

View File

@ -41,28 +41,23 @@
bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget* parent) bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget* parent)
{ {
if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegularExpression("-Xm[sx]")) if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegularExpression("-Xm[sx]")) || jvmargs.contains("-XX-MaxHeapSize") ||
|| jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize")) jvmargs.contains("-XX:InitialHeapSize")) {
{
auto warnStr = QObject::tr( auto warnStr = QObject::tr(
"You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" or \"-Xms\").\n" "You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" "
"or \"-Xms\").\n"
"There are dedicated boxes for these in the settings (Java tab, in the Memory group at the top).\n" "There are dedicated boxes for these in the settings (Java tab, in the Memory group at the top).\n"
"This message will be displayed until you remove them from the JVM arguments."); "This message will be displayed until you remove them from the JVM arguments.");
CustomMessageBox::selectable( CustomMessageBox::selectable(parent, QObject::tr("JVM arguments warning"), warnStr, QMessageBox::Warning)->exec();
parent, QObject::tr("JVM arguments warning"),
warnStr,
QMessageBox::Warning)->exec();
return false; return false;
} }
// block lunacy with passing required version to the JVM // block lunacy with passing required version to the JVM
if (jvmargs.contains(QRegularExpression("-version:.*"))) { if (jvmargs.contains(QRegularExpression("-version:.*"))) {
auto warnStr = QObject::tr( auto warnStr = QObject::tr(
"You tried to pass required Java version argument to the JVM (using \"-version:xxx\"). This is not safe and will not be allowed.\n" "You tried to pass required Java version argument to the JVM (using \"-version:xxx\"). This is not safe and will not be "
"allowed.\n"
"This message will be displayed until you remove this from the JVM arguments."); "This message will be displayed until you remove this from the JVM arguments.");
CustomMessageBox::selectable( CustomMessageBox::selectable(parent, QObject::tr("JVM arguments warning"), warnStr, QMessageBox::Warning)->exec();
parent, QObject::tr("JVM arguments warning"),
warnStr,
QMessageBox::Warning)->exec();
return false; return false;
} }
return true; return true;
@ -71,11 +66,12 @@ bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent)
void JavaCommon::javaWasOk(QWidget* parent, const JavaCheckResult& result) void JavaCommon::javaWasOk(QWidget* parent, const JavaCheckResult& result)
{ {
QString text; QString text;
text += QObject::tr("Java test succeeded!<br />Platform reported: %1<br />Java version " text += QObject::tr(
"Java test succeeded!<br />Platform reported: %1<br />Java version "
"reported: %2<br />Java vendor " "reported: %2<br />Java vendor "
"reported: %3<br />").arg(result.realPlatform, result.javaVersion.toString(), result.javaVendor); "reported: %3<br />")
if (result.errorLog.size()) .arg(result.realPlatform, result.javaVersion.toString(), result.javaVendor);
{ if (result.errorLog.size()) {
auto htmlError = result.errorLog; auto htmlError = result.errorLog;
htmlError.replace('\n', "<br />"); htmlError.replace('\n', "<br />");
text += QObject::tr("<br />Warnings:<br /><font color=\"orange\">%1</font>").arg(htmlError); text += QObject::tr("<br />Warnings:<br /><font color=\"orange\">%1</font>").arg(htmlError);
@ -111,8 +107,7 @@ void JavaCommon::javaCheckNotFound(QWidget *parent)
void JavaCommon::TestCheck::run() void JavaCommon::TestCheck::run()
{ {
if (!JavaCommon::checkJVMArgs(m_args, m_parent)) if (!JavaCommon::checkJVMArgs(m_args, m_parent)) {
{
emit finished(); emit finished();
return; return;
} }
@ -129,8 +124,7 @@ void JavaCommon::TestCheck::run()
void JavaCommon::TestCheck::checkFinished(JavaCheckResult result) void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
{ {
if (result.validity != JavaCheckResult::Validity::Valid) if (result.validity != JavaCheckResult::Validity::Valid) {
{
javaBinaryWasBad(m_parent, result); javaBinaryWasBad(m_parent, result);
emit finished(); emit finished();
return; return;
@ -141,8 +135,7 @@ void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
checker->m_args = m_args; checker->m_args = m_args;
checker->m_minMem = m_minMem; checker->m_minMem = m_minMem;
checker->m_maxMem = m_maxMem; checker->m_maxMem = m_maxMem;
if (result.javaVersion.requiresPermGen()) if (result.javaVersion.requiresPermGen()) {
{
checker->m_permGen = m_permGen; checker->m_permGen = m_permGen;
} }
checker->performCheck(); checker->performCheck();
@ -150,8 +143,7 @@ void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result) void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result)
{ {
if (result.validity == JavaCheckResult::Validity::Valid) if (result.validity == JavaCheckResult::Validity::Valid) {
{
javaWasOk(m_parent, result); javaWasOk(m_parent, result);
emit finished(); emit finished();
return; return;
@ -159,4 +151,3 @@ void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result)
javaArgsWereBad(m_parent, result); javaArgsWereBad(m_parent, result);
emit finished(); emit finished();
} }

View File

@ -6,8 +6,7 @@ class QWidget;
/** /**
* Common UI bits for the java pages to use. * Common UI bits for the java pages to use.
*/ */
namespace JavaCommon namespace JavaCommon {
{
bool checkJVMArgs(QString args, QWidget* parent); bool checkJVMArgs(QString args, QWidget* parent);
// Show a dialog saying that the Java binary was usable // Show a dialog saying that the Java binary was usable
@ -19,14 +18,12 @@ namespace JavaCommon
// Show a dialog if we couldn't find Java Checker // Show a dialog if we couldn't find Java Checker
void javaCheckNotFound(QWidget* parent); void javaCheckNotFound(QWidget* parent);
class TestCheck : public QObject class TestCheck : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
TestCheck(QWidget* parent, QString path, QString args, int minMem, int maxMem, int permGen) TestCheck(QWidget* parent, QString path, QString args, int minMem, int maxMem, int permGen)
: m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen) : m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen)
{ {}
}
virtual ~TestCheck(){}; virtual ~TestCheck(){};
void run(); void run();
@ -47,4 +44,4 @@ namespace JavaCommon
int m_maxMem = 0; int m_maxMem = 0;
int m_permGen = 64; int m_permGen = 64;
}; };
} } // namespace JavaCommon

View File

@ -37,11 +37,10 @@
#include <QFile> #include <QFile>
#include "FileSystem.h"
#include <math.h> #include <math.h>
#include "FileSystem.h"
namespace Json namespace Json {
{
void write(const QJsonDocument& doc, const QString& filename) void write(const QJsonDocument& doc, const QString& filename)
{ {
FS::write(filename, doc.toJson()); FS::write(filename, doc.toJson());
@ -71,17 +70,13 @@ static bool isBinaryJson(const QByteArray &data)
} }
QJsonDocument requireDocument(const QByteArray& data, const QString& what) QJsonDocument requireDocument(const QByteArray& data, const QString& what)
{ {
if (isBinaryJson(data)) if (isBinaryJson(data)) {
{
// FIXME: Is this needed? // FIXME: Is this needed?
throw JsonException(what + ": Invalid JSON. Binary JSON unsupported"); throw JsonException(what + ": Invalid JSON. Binary JSON unsupported");
} } else {
else
{
QJsonParseError error; QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(data, &error); QJsonDocument doc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) if (error.error != QJsonParseError::NoError) {
{
throw JsonException(what + ": Error parsing JSON: " + error.errorString()); throw JsonException(what + ": Error parsing JSON: " + error.errorString());
} }
return doc; return doc;
@ -93,16 +88,14 @@ QJsonDocument requireDocument(const QString &filename, const QString &what)
} }
QJsonObject requireObject(const QJsonDocument& doc, const QString& what) QJsonObject requireObject(const QJsonDocument& doc, const QString& what)
{ {
if (!doc.isObject()) if (!doc.isObject()) {
{
throw JsonException(what + " is not an object"); throw JsonException(what + " is not an object");
} }
return doc.object(); return doc.object();
} }
QJsonArray requireArray(const QJsonDocument& doc, const QString& what) QJsonArray requireArray(const QJsonDocument& doc, const QString& what)
{ {
if (!doc.isArray()) if (!doc.isArray()) {
{
throw JsonException(what + " is not an array"); throw JsonException(what + " is not an array");
} }
return doc.array(); return doc.array();
@ -110,19 +103,16 @@ QJsonArray requireArray(const QJsonDocument &doc, const QString &what)
void writeString(QJsonObject& to, const QString& key, const QString& value) void writeString(QJsonObject& to, const QString& key, const QString& value)
{ {
if (!value.isEmpty()) if (!value.isEmpty()) {
{
to.insert(key, value); to.insert(key, value);
} }
} }
void writeStringList(QJsonObject& to, const QString& key, const QStringList& values) void writeStringList(QJsonObject& to, const QString& key, const QStringList& values)
{ {
if (!values.isEmpty()) if (!values.isEmpty()) {
{
QJsonArray array; QJsonArray array;
for(auto value: values) for (auto value : values) {
{
array.append(value); array.append(value);
} }
to.insert(key, array); to.insert(key, array);
@ -160,99 +150,98 @@ QJsonValue toJson<QVariant>(const QVariant &variant)
return QJsonValue::fromVariant(variant); return QJsonValue::fromVariant(variant);
} }
template <>
template<> QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what) QByteArray requireIsType<QByteArray>(const QJsonValue& value, const QString& what)
{ {
const QString string = ensureIsType<QString>(value, what); const QString string = ensureIsType<QString>(value, what);
// ensure that the string can be safely cast to Latin1 // ensure that the string can be safely cast to Latin1
if (string != QString::fromLatin1(string.toLatin1())) if (string != QString::fromLatin1(string.toLatin1())) {
{
throw JsonException(what + " is not encodable as Latin1"); throw JsonException(what + " is not encodable as Latin1");
} }
return QByteArray::fromHex(string.toLatin1()); return QByteArray::fromHex(string.toLatin1());
} }
template<> QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what) template <>
{ QJsonArray requireIsType<QJsonArray>(const QJsonValue& value, const QString& what)
if (!value.isArray())
{ {
if (!value.isArray()) {
throw JsonException(what + " is not an array"); throw JsonException(what + " is not an array");
} }
return value.toArray(); return value.toArray();
} }
template <>
template<> QString requireIsType<QString>(const QJsonValue &value, const QString &what) QString requireIsType<QString>(const QJsonValue& value, const QString& what)
{
if (!value.isString())
{ {
if (!value.isString()) {
throw JsonException(what + " is not a string"); throw JsonException(what + " is not a string");
} }
return value.toString(); return value.toString();
} }
template<> bool requireIsType<bool>(const QJsonValue &value, const QString &what) template <>
{ bool requireIsType<bool>(const QJsonValue& value, const QString& what)
if (!value.isBool())
{ {
if (!value.isBool()) {
throw JsonException(what + " is not a bool"); throw JsonException(what + " is not a bool");
} }
return value.toBool(); return value.toBool();
} }
template<> double requireIsType<double>(const QJsonValue &value, const QString &what) template <>
{ double requireIsType<double>(const QJsonValue& value, const QString& what)
if (!value.isDouble())
{ {
if (!value.isDouble()) {
throw JsonException(what + " is not a double"); throw JsonException(what + " is not a double");
} }
return value.toDouble(); return value.toDouble();
} }
template<> int requireIsType<int>(const QJsonValue &value, const QString &what) template <>
int requireIsType<int>(const QJsonValue& value, const QString& what)
{ {
const double doubl = requireIsType<double>(value, what); const double doubl = requireIsType<double>(value, what);
if (fmod(doubl, 1) != 0) if (fmod(doubl, 1) != 0) {
{
throw JsonException(what + " is not an integer"); throw JsonException(what + " is not an integer");
} }
return int(doubl); return int(doubl);
} }
template<> QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what) template <>
QDateTime requireIsType<QDateTime>(const QJsonValue& value, const QString& what)
{ {
const QString string = requireIsType<QString>(value, what); const QString string = requireIsType<QString>(value, what);
const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate); const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate);
if (!datetime.isValid()) if (!datetime.isValid()) {
{
throw JsonException(what + " is not a ISO formatted date/time value"); throw JsonException(what + " is not a ISO formatted date/time value");
} }
return datetime; return datetime;
} }
template<> QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what) template <>
QUrl requireIsType<QUrl>(const QJsonValue& value, const QString& what)
{ {
const QString string = ensureIsType<QString>(value, what); const QString string = ensureIsType<QString>(value, what);
if (string.isEmpty()) if (string.isEmpty()) {
{
return QUrl(); return QUrl();
} }
const QUrl url = QUrl(string, QUrl::StrictMode); const QUrl url = QUrl(string, QUrl::StrictMode);
if (!url.isValid()) if (!url.isValid()) {
{
throw JsonException(what + " is not a correctly formatted URL"); throw JsonException(what + " is not a correctly formatted URL");
} }
return url; return url;
} }
template<> QDir requireIsType<QDir>(const QJsonValue &value, const QString &what) template <>
QDir requireIsType<QDir>(const QJsonValue& value, const QString& what)
{ {
const QString string = requireIsType<QString>(value, what); const QString string = requireIsType<QString>(value, what);
// FIXME: does not handle invalid characters! // FIXME: does not handle invalid characters!
return QDir::current().absoluteFilePath(string); return QDir::current().absoluteFilePath(string);
} }
template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what) template <>
QUuid requireIsType<QUuid>(const QJsonValue& value, const QString& what)
{ {
const QString string = requireIsType<QString>(value, what); const QString string = requireIsType<QString>(value, what);
const QUuid uuid = QUuid(string); const QUuid uuid = QUuid(string);
@ -263,31 +252,31 @@ template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &wh
return uuid; return uuid;
} }
template<> QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what) template <>
{ QJsonObject requireIsType<QJsonObject>(const QJsonValue& value, const QString& what)
if (!value.isObject())
{ {
if (!value.isObject()) {
throw JsonException(what + " is not an object"); throw JsonException(what + " is not an object");
} }
return value.toObject(); return value.toObject();
} }
template<> QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what) template <>
{ QVariant requireIsType<QVariant>(const QJsonValue& value, const QString& what)
if (value.isNull() || value.isUndefined())
{ {
if (value.isNull() || value.isUndefined()) {
throw JsonException(what + " is null or undefined"); throw JsonException(what + " is null or undefined");
} }
return value.toVariant(); return value.toVariant();
} }
template<> QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what) template <>
{ QJsonValue requireIsType<QJsonValue>(const QJsonValue& value, const QString& what)
if (value.isNull() || value.isUndefined())
{ {
if (value.isNull() || value.isUndefined()) {
throw JsonException(what + " is null or undefined"); throw JsonException(what + " is null or undefined");
} }
return value; return value;
} }
} } // namespace Json

View File

@ -35,22 +35,20 @@
#pragma once #pragma once
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDateTime> #include <QDateTime>
#include <QUrl>
#include <QDir> #include <QDir>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QUrl>
#include <QUuid> #include <QUuid>
#include <QVariant> #include <QVariant>
#include <memory> #include <memory>
#include "Exception.h" #include "Exception.h"
namespace Json namespace Json {
{ class JsonException : public ::Exception {
class JsonException : public ::Exception
{
public: public:
JsonException(const QString& message) : Exception(message) {} JsonException(const QString& message) : Exception(message) {}
}; };
@ -101,8 +99,7 @@ template<typename T>
QJsonArray toJsonArray(const QList<T>& container) QJsonArray toJsonArray(const QList<T>& container)
{ {
QJsonArray array; QJsonArray array;
for (const T item : container) for (const T item : container) {
{
array.append(toJson<T>(item)); array.append(toJson<T>(item));
} }
return array; return array;
@ -115,47 +112,56 @@ template <typename T>
T requireIsType(const QJsonValue& value, const QString& what = "Value"); T requireIsType(const QJsonValue& value, const QString& what = "Value");
/// @throw JsonException /// @throw JsonException
template<> double requireIsType<double>(const QJsonValue &value, const QString &what); template <>
double requireIsType<double>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> bool requireIsType<bool>(const QJsonValue &value, const QString &what); template <>
bool requireIsType<bool>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> int requireIsType<int>(const QJsonValue &value, const QString &what); template <>
int requireIsType<int>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what); template <>
QJsonObject requireIsType<QJsonObject>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what); template <>
QJsonArray requireIsType<QJsonArray>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what); template <>
QJsonValue requireIsType<QJsonValue>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what); template <>
QByteArray requireIsType<QByteArray>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what); template <>
QDateTime requireIsType<QDateTime>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what); template <>
QVariant requireIsType<QVariant>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QString requireIsType<QString>(const QJsonValue &value, const QString &what); template <>
QString requireIsType<QString>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what); template <>
QUuid requireIsType<QUuid>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QDir requireIsType<QDir>(const QJsonValue &value, const QString &what); template <>
QDir requireIsType<QDir>(const QJsonValue& value, const QString& what);
/// @throw JsonException /// @throw JsonException
template<> QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what); template <>
QUrl requireIsType<QUrl>(const QJsonValue& value, const QString& what);
// the following functions are higher level functions, that make use of the above functions for // the following functions are higher level functions, that make use of the above functions for
// type conversion // type conversion
template <typename T> template <typename T>
T ensureIsType(const QJsonValue& value, const T default_ = T(), const QString& what = "Value") T ensureIsType(const QJsonValue& value, const T default_ = T(), const QString& what = "Value")
{ {
if (value.isUndefined() || value.isNull()) if (value.isUndefined() || value.isNull()) {
{
return default_; return default_;
} }
try try {
{
return requireIsType<T>(value, what); return requireIsType<T>(value, what);
} } catch (const JsonException&) {
catch (const JsonException &)
{
return default_; return default_;
} }
} }
@ -165,8 +171,7 @@ template <typename T>
T requireIsType(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__") T requireIsType(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
throw JsonException(localWhat + "s parent does not contain " + localWhat); throw JsonException(localWhat + "s parent does not contain " + localWhat);
} }
return requireIsType<T>(parent.value(key), localWhat); return requireIsType<T>(parent.value(key), localWhat);
@ -176,8 +181,7 @@ template <typename T>
T ensureIsType(const QJsonObject& parent, const QString& key, const T default_ = T(), const QString& what = "__placeholder__") T ensureIsType(const QJsonObject& parent, const QString& key, const T default_ = T(), const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
return default_; return default_;
} }
return ensureIsType<T>(parent.value(key), default_, localWhat); return ensureIsType<T>(parent.value(key), default_, localWhat);
@ -188,8 +192,7 @@ QVector<T> requireIsArrayOf(const QJsonDocument &doc)
{ {
const QJsonArray array = requireArray(doc); const QJsonArray array = requireArray(doc);
QVector<T> out; QVector<T> out;
for (const QJsonValue val : array) for (const QJsonValue val : array) {
{
out.append(requireIsType<T>(val, "Document")); out.append(requireIsType<T>(val, "Document"));
} }
return out; return out;
@ -200,8 +203,7 @@ QVector<T> ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value
{ {
const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what); const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what);
QVector<T> out; QVector<T> out;
for (const QJsonValue val : array) for (const QJsonValue val : array) {
{
out.append(requireIsType<T>(val, what)); out.append(requireIsType<T>(val, what));
} }
return out; return out;
@ -210,8 +212,7 @@ QVector<T> ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value
template <typename T> template <typename T>
QVector<T> ensureIsArrayOf(const QJsonValue& value, const QVector<T> default_, const QString& what = "Value") QVector<T> ensureIsArrayOf(const QJsonValue& value, const QVector<T> default_, const QString& what = "Value")
{ {
if (value.isUndefined()) if (value.isUndefined()) {
{
return default_; return default_;
} }
return ensureIsArrayOf<T>(value, what); return ensureIsArrayOf<T>(value, what);
@ -222,20 +223,20 @@ template <typename T>
QVector<T> requireIsArrayOf(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__") QVector<T> requireIsArrayOf(const QJsonObject& parent, const QString& key, const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
throw JsonException(localWhat + "s parent does not contain " + localWhat); throw JsonException(localWhat + "s parent does not contain " + localWhat);
} }
return ensureIsArrayOf<T>(parent.value(key), localWhat); return ensureIsArrayOf<T>(parent.value(key), localWhat);
} }
template <typename T> template <typename T>
QVector<T> ensureIsArrayOf(const QJsonObject &parent, const QString &key, QVector<T> ensureIsArrayOf(const QJsonObject& parent,
const QVector<T> &default_ = QVector<T>(), const QString &what = "__placeholder__") const QString& key,
const QVector<T>& default_ = QVector<T>(),
const QString& what = "__placeholder__")
{ {
const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
if (!parent.contains(key)) if (!parent.contains(key)) {
{
return default_; return default_;
} }
return ensureIsArrayOf<T>(parent.value(key), default_, localWhat); return ensureIsArrayOf<T>(parent.value(key), default_, localWhat);
@ -255,7 +256,8 @@ QVector<T> ensureIsArrayOf(const QJsonObject &parent, const QString &key,
{ \ { \
return requireIsType<TYPE>(parent, key, what); \ return requireIsType<TYPE>(parent, key, what); \
} \ } \
inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_ = TYPE(), const QString &what = "__placeholder") \ inline TYPE ensure##NAME(const QJsonObject& parent, const QString& key, const TYPE default_ = TYPE(), \
const QString& what = "__placeholder") \
{ \ { \
return ensureIsType<TYPE>(parent, key, default_, what); \ return ensureIsType<TYPE>(parent, key, default_, what); \
} }
@ -276,5 +278,5 @@ JSON_HELPERFUNCTIONS(Variant, QVariant)
#undef JSON_HELPERFUNCTIONS #undef JSON_HELPERFUNCTIONS
} } // namespace Json
using JSONValidationError = Json::JsonException; using JSONValidationError = Json::JsonException;

View File

@ -1,42 +1,26 @@
#include "KonamiCode.h" #include "KonamiCode.h"
#include <array>
#include <QDebug> #include <QDebug>
#include <array>
namespace { namespace {
const std::array<Qt::Key, 10> konamiCode = const std::array<Qt::Key, 10> konamiCode = { { Qt::Key_Up, Qt::Key_Up, Qt::Key_Down, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right,
{ Qt::Key_Left, Qt::Key_Right, Qt::Key_B, Qt::Key_A } };
{
Qt::Key_Up, Qt::Key_Up,
Qt::Key_Down, Qt::Key_Down,
Qt::Key_Left, Qt::Key_Right,
Qt::Key_Left, Qt::Key_Right,
Qt::Key_B, Qt::Key_A
}
};
}
KonamiCode::KonamiCode(QObject* parent) : QObject(parent)
{
} }
KonamiCode::KonamiCode(QObject* parent) : QObject(parent) {}
void KonamiCode::input(QEvent* event) void KonamiCode::input(QEvent* event)
{ {
if( event->type() == QEvent::KeyPress ) if (event->type() == QEvent::KeyPress) {
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
auto key = Qt::Key(keyEvent->key()); auto key = Qt::Key(keyEvent->key());
if(key == konamiCode[m_progress]) if (key == konamiCode[m_progress]) {
{
m_progress++; m_progress++;
} } else {
else
{
m_progress = 0; m_progress = 0;
} }
if(m_progress == static_cast<int>(konamiCode.size())) if (m_progress == static_cast<int>(konamiCode.size())) {
{
m_progress = 0; m_progress = 0;
emit triggered(); emit triggered();
} }

View File

@ -2,8 +2,7 @@
#include <QKeyEvent> #include <QKeyEvent>
class KonamiCode : public QObject class KonamiCode : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
KonamiCode(QObject* parent = 0); KonamiCode(QObject* parent = 0);

View File

@ -34,39 +34,36 @@
*/ */
#include "LaunchController.h" #include "LaunchController.h"
#include "minecraft/auth/AccountList.h"
#include "Application.h" #include "Application.h"
#include "minecraft/auth/AccountList.h"
#include "ui/MainWindow.h"
#include "ui/InstanceWindow.h" #include "ui/InstanceWindow.h"
#include "ui/MainWindow.h"
#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/ProfileSelectDialog.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/dialogs/EditAccountDialog.h" #include "ui/dialogs/EditAccountDialog.h"
#include "ui/dialogs/ProfileSelectDialog.h"
#include "ui/dialogs/ProfileSetupDialog.h" #include "ui/dialogs/ProfileSetupDialog.h"
#include "ui/dialogs/ProgressDialog.h"
#include <QLineEdit>
#include <QInputDialog>
#include <QStringList>
#include <QHostInfo>
#include <QList>
#include <QHostAddress> #include <QHostAddress>
#include <QHostInfo>
#include <QInputDialog>
#include <QLineEdit>
#include <QList>
#include <QPushButton> #include <QPushButton>
#include <QStringList>
#include "BuildConfig.h" #include "BuildConfig.h"
#include "JavaCommon.h" #include "JavaCommon.h"
#include "tasks/Task.h"
#include "minecraft/auth/AccountTask.h"
#include "launch/steps/TextPrint.h" #include "launch/steps/TextPrint.h"
#include "minecraft/auth/AccountTask.h"
#include "tasks/Task.h"
LaunchController::LaunchController(QObject *parent) : Task(parent) LaunchController::LaunchController(QObject* parent) : Task(parent) {}
{
}
void LaunchController::executeTask() void LaunchController::executeTask()
{ {
if (!m_instance) if (!m_instance) {
{
emitFailed(tr("No instance specified!")); emitFailed(tr("No instance specified!"));
return; return;
} }
@ -87,26 +84,19 @@ void LaunchController::decideAccount()
// Find an account to use. // Find an account to use.
auto accounts = APPLICATION->accounts(); auto accounts = APPLICATION->accounts();
if (accounts->count() <= 0) if (accounts->count() <= 0) {
{
// Tell the user they need to log in at least one account in order to play. // Tell the user they need to log in at least one account in order to play.
auto reply = CustomMessageBox::selectable( auto reply = CustomMessageBox::selectable(m_parentWidget, tr("No Accounts"),
m_parentWidget,
tr("No Accounts"),
tr("In order to play Minecraft, you must have at least one Microsoft or Mojang " tr("In order to play Minecraft, you must have at least one Microsoft or Mojang "
"account logged in. Mojang accounts can only be used offline. " "account logged in. Mojang accounts can only be used offline. "
"Would you like to open the account manager to add an account now?"), "Would you like to open the account manager to add an account now?"),
QMessageBox::Information, QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)
QMessageBox::Yes | QMessageBox::No ->exec();
)->exec();
if (reply == QMessageBox::Yes) if (reply == QMessageBox::Yes) {
{
// Open the account manager. // Open the account manager.
APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts"); APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts");
} } else if (reply == QMessageBox::No) {
else if (reply == QMessageBox::No)
{
// Do not open "profile select" dialog. // Do not open "profile select" dialog.
return; return;
} }
@ -121,14 +111,10 @@ void LaunchController::decideAccount()
m_accountToUse = accounts->at(instanceAccountIndex); m_accountToUse = accounts->at(instanceAccountIndex);
} }
if (!m_accountToUse) if (!m_accountToUse) {
{
// If no default account is set, ask the user which one to use. // If no default account is set, ask the user which one to use.
ProfileSelectDialog selectDialog( ProfileSelectDialog selectDialog(tr("Which account would you like to use?"), ProfileSelectDialog::GlobalDefaultCheckbox,
tr("Which account would you like to use?"), m_parentWidget);
ProfileSelectDialog::GlobalDefaultCheckbox,
m_parentWidget
);
selectDialog.exec(); selectDialog.exec();
@ -142,13 +128,12 @@ void LaunchController::decideAccount()
} }
} }
void LaunchController::login()
void LaunchController::login() { {
decideAccount(); decideAccount();
// if no account is selected, we bail // if no account is selected, we bail
if (!m_accountToUse) if (!m_accountToUse) {
{
emitFailed(tr("No account selected for launch.")); emitFailed(tr("No account selected for launch."));
return; return;
} }
@ -157,15 +142,11 @@ void LaunchController::login() {
bool tryagain = true; bool tryagain = true;
unsigned int tries = 0; unsigned int tries = 0;
while (tryagain) while (tryagain) {
{
if (tries > 0 && tries % 3 == 0) { if (tries > 0 && tries % 3 == 0) {
auto result = QMessageBox::question( auto result =
m_parentWidget, QMessageBox::question(m_parentWidget, tr("Continue launch?"),
tr("Continue launch?"), tr("It looks like we couldn't launch after %1 tries. Do you want to continue trying?").arg(tries));
tr("It looks like we couldn't launch after %1 tries. Do you want to continue trying?")
.arg(tries)
);
if (result == QMessageBox::No) { if (result == QMessageBox::No) {
emitAborted(); emitAborted();
@ -201,21 +182,12 @@ void LaunchController::login() {
QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString(); QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString();
QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName; QString usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName;
QString name = QInputDialog::getText( QString name = QInputDialog::getText(m_parentWidget, tr("Player name"), message, QLineEdit::Normal, usedname, &ok);
m_parentWidget, if (!ok) {
tr("Player name"),
message,
QLineEdit::Normal,
usedname,
&ok
);
if (!ok)
{
tryagain = false; tryagain = false;
break; break;
} }
if (name.length()) if (name.length()) {
{
usedname = name; usedname = name;
APPLICATION->settings()->set("LastOfflinePlayerName", usedname); APPLICATION->settings()->set("LastOfflinePlayerName", usedname);
} }
@ -226,13 +198,10 @@ void LaunchController::login() {
if (!m_accountToUse->hasProfile()) { if (!m_accountToUse->hasProfile()) {
// Now handle setting up a profile name here... // Now handle setting up a profile name here...
ProfileSetupDialog dialog(m_accountToUse, m_parentWidget); ProfileSetupDialog dialog(m_accountToUse, m_parentWidget);
if (dialog.exec() == QDialog::Accepted) if (dialog.exec() == QDialog::Accepted) {
{
tryagain = true; tryagain = true;
continue; continue;
} } else {
else
{
emitFailed(tr("Received undetermined session status during login.")); emitFailed(tr("Received undetermined session status during login."));
return; return;
} }
@ -240,12 +209,13 @@ void LaunchController::login() {
// we own Minecraft, there is a profile, it's all ready to go! // we own Minecraft, there is a profile, it's all ready to go!
launchInstance(); launchInstance();
return; return;
} } else {
else {
// play demo ? // play demo ?
QMessageBox box(m_parentWidget); QMessageBox box(m_parentWidget);
box.setWindowTitle(tr("Play demo?")); box.setWindowTitle(tr("Play demo?"));
box.setText(tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play the demo?")); box.setText(
tr("This account does not own Minecraft.\nYou need to purchase the game first to play it.\n\nDo you want to play "
"the demo?"));
box.setIcon(QMessageBox::Warning); box.setIcon(QMessageBox::Warning);
auto demoButton = box.addButton(tr("Play Demo"), QMessageBox::ButtonRole::YesRole); auto demoButton = box.addButton(tr("Play Demo"), QMessageBox::ButtonRole::YesRole);
auto cancelButton = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::NoRole); auto cancelButton = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::NoRole);
@ -256,8 +226,7 @@ void LaunchController::login() {
// play demo here // play demo here
m_session->MakeDemo(); m_session->MakeDemo();
launchInstance(); launchInstance();
} } else {
else {
emitFailed(tr("Launch cancelled - account does not own Minecraft.")); emitFailed(tr("Launch cancelled - account does not own Minecraft."));
} }
} }
@ -272,8 +241,7 @@ void LaunchController::login() {
case AccountState::Working: { case AccountState::Working: {
// refresh is in progress, we need to wait for it to finish to proceed. // refresh is in progress, we need to wait for it to finish to proceed.
ProgressDialog progDialog(m_parentWidget); ProgressDialog progDialog(m_parentWidget);
if (m_online) if (m_online) {
{
progDialog.setSkipButton(true, tr("Play Offline")); progDialog.setSkipButton(true, tr("Play Offline"));
} }
auto task = m_accountToUse->currentTask(); auto task = m_accountToUse->currentTask();
@ -288,37 +256,24 @@ void LaunchController::login() {
*/ */
case AccountState::Expired: { case AccountState::Expired: {
auto errorString = tr("The account has expired and needs to be logged into manually again."); auto errorString = tr("The account has expired and needs to be logged into manually again.");
QMessageBox::warning( QMessageBox::warning(m_parentWidget, tr("Account refresh failed"), errorString, QMessageBox::StandardButton::Ok,
m_parentWidget, QMessageBox::StandardButton::Ok);
tr("Account refresh failed"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString); emitFailed(errorString);
return; return;
} }
case AccountState::Disabled: { case AccountState::Disabled: {
auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again."); auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again.");
QMessageBox::warning( QMessageBox::warning(m_parentWidget, tr("Client identification changed"), errorString, QMessageBox::StandardButton::Ok,
m_parentWidget, QMessageBox::StandardButton::Ok);
tr("Client identification changed"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString); emitFailed(errorString);
return; return;
} }
case AccountState::Gone: { case AccountState::Gone: {
auto errorString = tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account you migrated this one to."); auto errorString =
QMessageBox::warning( tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account "
m_parentWidget, "you migrated this one to.");
tr("Account gone"), QMessageBox::warning(m_parentWidget, tr("Account gone"), errorString, QMessageBox::StandardButton::Ok,
errorString, QMessageBox::StandardButton::Ok);
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
emitFailed(errorString); emitFailed(errorString);
return; return;
} }
@ -332,24 +287,21 @@ void LaunchController::launchInstance()
Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL"); Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL");
Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL"); Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL");
if(!m_instance->reloadSettings()) if (!m_instance->reloadSettings()) {
{
QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't load the instance profile.")); QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't load the instance profile."));
emitFailed(tr("Couldn't load the instance profile.")); emitFailed(tr("Couldn't load the instance profile."));
return; return;
} }
m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin); m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin);
if (!m_launcher) if (!m_launcher) {
{
emitFailed(tr("Couldn't instantiate a launcher.")); emitFailed(tr("Couldn't instantiate a launcher."));
return; return;
} }
auto console = qobject_cast<InstanceWindow*>(m_parentWidget); auto console = qobject_cast<InstanceWindow*>(m_parentWidget);
auto showConsole = m_instance->settings()->get("ShowConsole").toBool(); auto showConsole = m_instance->settings()->get("ShowConsole").toBool();
if(!console && showConsole) if (!console && showConsole) {
{
APPLICATION->showInstanceWindow(m_instance); APPLICATION->showInstanceWindow(m_instance);
} }
connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch);
@ -387,11 +339,13 @@ void LaunchController::launchInstance()
online_mode = m_demo ? "demo" : "offline"; online_mode = m_demo ? "demo" : "offline";
} }
m_launcher->prependStep(makeShared<TextPrint>(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher)); m_launcher->prependStep(
makeShared<TextPrint>(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher));
// Prepend Version // Prepend Version
{ {
auto versionString = QString("%1 version: %2 (%3)").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM); auto versionString = QString("%1 version: %2 (%3)")
.arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM);
m_launcher->prependStep(makeShared<TextPrint>(m_launcher.get(), versionString + "\n\n", MessageLevel::Launcher)); m_launcher->prependStep(makeShared<TextPrint>(m_launcher.get(), versionString + "\n\n", MessageLevel::Launcher));
} }
m_launcher->start(); m_launcher->start();
@ -399,15 +353,13 @@ void LaunchController::launchInstance()
void LaunchController::readyForLaunch() void LaunchController::readyForLaunch()
{ {
if (!m_profiler) if (!m_profiler) {
{
m_launcher->proceed(); m_launcher->proceed();
return; return;
} }
QString error; QString error;
if (!m_profiler->check(&error)) if (!m_profiler->check(&error)) {
{
m_launcher->abort(); m_launcher->abort();
QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't start profiler: %1").arg(error)); QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't start profiler: %1").arg(error));
emitFailed("Profiler startup failed!"); emitFailed("Profiler startup failed!");
@ -415,12 +367,12 @@ void LaunchController::readyForLaunch()
} }
BaseProfiler* profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this); BaseProfiler* profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this);
connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString & message) connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString& message) {
{
QMessageBox msg; QMessageBox msg;
msg.setText(tr("The game launch is delayed until you press the " msg.setText(tr("The game launch is delayed until you press the "
"button. This is the right time to setup the profiler, as the " "button. This is the right time to setup the profiler, as the "
"profiler server is running now.\n\n%1").arg(message)); "profiler server is running now.\n\n%1")
.arg(message));
msg.setWindowTitle(tr("Waiting.")); msg.setWindowTitle(tr("Waiting."));
msg.setIcon(QMessageBox::Information); msg.setIcon(QMessageBox::Information);
msg.addButton(tr("Launch"), QMessageBox::AcceptRole); msg.addButton(tr("Launch"), QMessageBox::AcceptRole);
@ -428,8 +380,7 @@ void LaunchController::readyForLaunch()
msg.exec(); msg.exec();
m_launcher->proceed(); m_launcher->proceed();
}); });
connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString & message) connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString& message) {
{
QMessageBox msg; QMessageBox msg;
msg.setText(tr("Couldn't start the profiler: %1").arg(message)); msg.setText(tr("Couldn't start the profiler: %1").arg(message));
msg.setWindowTitle(tr("Error")); msg.setWindowTitle(tr("Error"));
@ -450,8 +401,7 @@ void LaunchController::onSucceeded()
void LaunchController::onFailed(QString reason) void LaunchController::onFailed(QString reason)
{ {
if(m_instance->settings()->get("ShowConsoleOnError").toBool()) if (m_instance->settings()->get("ShowConsoleOnError").toBool()) {
{
APPLICATION->showInstanceWindow(m_instance, "console"); APPLICATION->showInstanceWindow(m_instance, "console");
} }
emitFailed(reason); emitFailed(reason);
@ -467,21 +417,18 @@ void LaunchController::onProgressRequested(Task* task)
bool LaunchController::abort() bool LaunchController::abort()
{ {
if(!m_launcher) if (!m_launcher) {
{
return true; return true;
} }
if(!m_launcher->canAbort()) if (!m_launcher->canAbort()) {
{
return false; return false;
} }
auto response = CustomMessageBox::selectable( auto response = CustomMessageBox::selectable(m_parentWidget, tr("Kill Minecraft?"),
m_parentWidget, tr("Kill Minecraft?"),
tr("This can cause the instance to get corrupted and should only be used if Minecraft " tr("This can cause the instance to get corrupted and should only be used if Minecraft "
"is frozen for some reason"), "is frozen for some reason"),
QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec(); QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)
if (response == QMessageBox::Yes) ->exec();
{ if (response == QMessageBox::Yes) {
return m_launcher->abort(); return m_launcher->abort();
} }
return false; return false;

View File

@ -34,16 +34,15 @@
*/ */
#pragma once #pragma once
#include <QObject>
#include <BaseInstance.h> #include <BaseInstance.h>
#include <tools/BaseProfiler.h> #include <tools/BaseProfiler.h>
#include <QObject>
#include "minecraft/launch/MinecraftServerTarget.h"
#include "minecraft/auth/MinecraftAccount.h" #include "minecraft/auth/MinecraftAccount.h"
#include "minecraft/launch/MinecraftServerTarget.h"
class InstanceWindow; class InstanceWindow;
class LaunchController: public Task class LaunchController : public Task {
{
Q_OBJECT Q_OBJECT
public: public:
void executeTask() override; void executeTask() override;
@ -51,42 +50,23 @@ public:
LaunchController(QObject* parent = nullptr); LaunchController(QObject* parent = nullptr);
virtual ~LaunchController(){}; virtual ~LaunchController(){};
void setInstance(InstancePtr instance) { void setInstance(InstancePtr instance) { m_instance = instance; }
m_instance = instance;
}
InstancePtr instance() { InstancePtr instance() { return m_instance; }
return m_instance;
}
void setOnline(bool online) { void setOnline(bool online) { m_online = online; }
m_online = online;
}
void setDemo(bool demo) { void setDemo(bool demo) { m_demo = demo; }
m_demo = demo;
}
void setProfiler(BaseProfilerFactory *profiler) { void setProfiler(BaseProfilerFactory* profiler) { m_profiler = profiler; }
m_profiler = profiler;
}
void setParentWidget(QWidget * widget) { void setParentWidget(QWidget* widget) { m_parentWidget = widget; }
m_parentWidget = widget;
}
void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { m_serverToJoin = std::move(serverToJoin); }
m_serverToJoin = std::move(serverToJoin);
}
void setAccountToUse(MinecraftAccountPtr accountToUse) { void setAccountToUse(MinecraftAccountPtr accountToUse) { m_accountToUse = std::move(accountToUse); }
m_accountToUse = std::move(accountToUse);
}
QString id() QString id() { return m_instance->id(); }
{
return m_instance->id();
}
bool abort() override; bool abort() override;

View File

@ -51,8 +51,7 @@ LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent)
LoggedProcess::~LoggedProcess() LoggedProcess::~LoggedProcess()
{ {
if(m_is_detachable) if (m_is_detachable) {
{
setProcessState(QProcess::NotRunning); setProcessState(QProcess::NotRunning);
} }
} }
@ -95,16 +94,12 @@ void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
m_exit_code = exit_code; m_exit_code = exit_code;
// based on state, send signals // based on state, send signals
if (!m_is_aborting) if (!m_is_aborting) {
{ if (status == QProcess::NormalExit) {
if (status == QProcess::NormalExit)
{
//: Message displayed on instance exit //: Message displayed on instance exit
emit log({ tr("Process exited with code %1.").arg(exit_code) }, MessageLevel::Launcher); emit log({ tr("Process exited with code %1.").arg(exit_code) }, MessageLevel::Launcher);
changeState(LoggedProcess::Finished); changeState(LoggedProcess::Finished);
} } else {
else
{
//: Message displayed on instance crashed //: Message displayed on instance crashed
if (exit_code == -1) if (exit_code == -1)
emit log({ tr("Process crashed.") }, MessageLevel::Launcher); emit log({ tr("Process crashed.") }, MessageLevel::Launcher);
@ -112,9 +107,7 @@ void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
emit log({ tr("Process crashed with exitcode %1.").arg(exit_code) }, MessageLevel::Launcher); emit log({ tr("Process crashed with exitcode %1.").arg(exit_code) }, MessageLevel::Launcher);
changeState(LoggedProcess::Crashed); changeState(LoggedProcess::Crashed);
} }
} } else {
else
{
//: Message displayed after the instance exits due to kill request //: Message displayed after the instance exits due to kill request
emit log({ tr("Process was killed by user.") }, MessageLevel::Error); emit log({ tr("Process was killed by user.") }, MessageLevel::Error);
changeState(LoggedProcess::Aborted); changeState(LoggedProcess::Aborted);
@ -123,10 +116,8 @@ void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
void LoggedProcess::on_error(QProcess::ProcessError error) void LoggedProcess::on_error(QProcess::ProcessError error)
{ {
switch(error) switch (error) {
{ case QProcess::FailedToStart: {
case QProcess::FailedToStart:
{
emit log({ tr("The process failed to start.") }, MessageLevel::Fatal); emit log({ tr("The process failed to start.") }, MessageLevel::Fatal);
changeState(LoggedProcess::FailedToStart); changeState(LoggedProcess::FailedToStart);
break; break;
@ -167,23 +158,18 @@ LoggedProcess::State LoggedProcess::state() const
void LoggedProcess::on_stateChange(QProcess::ProcessState state) void LoggedProcess::on_stateChange(QProcess::ProcessState state)
{ {
switch(state) switch (state) {
{
case QProcess::NotRunning: case QProcess::NotRunning:
break; // let's not - there are too many that handle this already. break; // let's not - there are too many that handle this already.
case QProcess::Starting: case QProcess::Starting: {
{ if (m_state != LoggedProcess::NotRunning) {
if(m_state != LoggedProcess::NotRunning)
{
qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Starting; qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Starting;
} }
changeState(LoggedProcess::Starting); changeState(LoggedProcess::Starting);
return; return;
} }
case QProcess::Running: case QProcess::Running: {
{ if (m_state != LoggedProcess::Starting) {
if(m_state != LoggedProcess::Starting)
{
qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Running; qWarning() << "Wrong state change for process from state" << m_state << "to" << (int)LoggedProcess::Running;
} }
changeState(LoggedProcess::Running); changeState(LoggedProcess::Running);

View File

@ -43,20 +43,10 @@
* This is a basic process. * This is a basic process.
* It has line-based logging support and hides some of the nasty bits. * It has line-based logging support and hides some of the nasty bits.
*/ */
class LoggedProcess : public QProcess class LoggedProcess : public QProcess {
{
Q_OBJECT Q_OBJECT
public: public:
enum State enum State { NotRunning, Starting, FailedToStart, Running, Finished, Crashed, Aborted };
{
NotRunning,
Starting,
FailedToStart,
Running,
Finished,
Crashed,
Aborted
};
public: public:
explicit LoggedProcess(QObject* parent = 0); explicit LoggedProcess(QObject* parent = 0);
@ -77,7 +67,6 @@ public slots:
*/ */
void kill(); void kill();
private slots: private slots:
void on_stdErr(); void on_stdErr();
void on_stdOut(); void on_stdOut();

View File

@ -17,30 +17,29 @@
#include <MMCTime.h> #include <MMCTime.h>
#include <QObject>
#include <QDateTime> #include <QDateTime>
#include <QObject>
#include <QTextStream> #include <QTextStream>
QString Time::prettifyDuration(int64_t duration) { QString Time::prettifyDuration(int64_t duration)
{
int seconds = (int)(duration % 60); int seconds = (int)(duration % 60);
duration /= 60; duration /= 60;
int minutes = (int)(duration % 60); int minutes = (int)(duration % 60);
duration /= 60; duration /= 60;
int hours = (int)(duration % 24); int hours = (int)(duration % 24);
int days = (int)(duration / 24); int days = (int)(duration / 24);
if((hours == 0)&&(days == 0)) if ((hours == 0) && (days == 0)) {
{
return QObject::tr("%1min %2s").arg(minutes).arg(seconds); return QObject::tr("%1min %2s").arg(minutes).arg(seconds);
} }
if (days == 0) if (days == 0) {
{
return QObject::tr("%1h %2min").arg(hours).arg(minutes); return QObject::tr("%1h %2min").arg(hours).arg(minutes);
} }
return QObject::tr("%1d %2h %3min").arg(days).arg(hours).arg(minutes); return QObject::tr("%1d %2h %3min").arg(days).arg(hours).arg(minutes);
} }
QString Time::humanReadableDuration(double duration, int precision) { QString Time::humanReadableDuration(double duration, int precision)
{
using days = std::chrono::duration<int, std::ratio<86400>>; using days = std::chrono::duration<int, std::ratio<86400>>;
QString outStr; QString outStr;

View File

@ -31,4 +31,4 @@ QString prettifyDuration(int64_t duration);
* @return QString * @return QString
*/ */
QString humanReadableDuration(double duration, int precision = 0); QString humanReadableDuration(double duration, int precision = 0);
} } // namespace Time

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug>
#include <QPixmapCache> #include <QPixmapCache>
#include <QThread> #include <QThread>
#include <QTime> #include <QTime>
#include <QDebug>
#define GET_TYPE() \ #define GET_TYPE() \
Qt::ConnectionType type; \ Qt::ConnectionType type; \

View File

@ -16,15 +16,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <QStringList>
#include <QDir> #include <QDir>
#include <QString> #include <QString>
#include <QStringList>
#include <QSysInfo> #include <QSysInfo>
#include <QtGlobal> #include <QtGlobal>
#include "MangoHud.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "Json.h" #include "Json.h"
#include "MangoHud.h"
namespace MangoHud { namespace MangoHud {

View File

@ -18,7 +18,7 @@
#pragma once #pragma once
#include <QString>
#include <cmark.h> #include <cmark.h>
#include <QString>
QString markdownToHTML(const QString& markdown); QString markdownToHTML(const QString& markdown);

View File

@ -26,8 +26,7 @@ MessageLevel::Enum MessageLevel::fromLine(QString &line)
{ {
// Level prefix // Level prefix
int endmark = line.indexOf("]!"); int endmark = line.indexOf("]!");
if (line.startsWith("!![") && endmark != -1) if (line.startsWith("!![") && endmark != -1) {
{
auto level = MessageLevel::getLevel(line.left(endmark).mid(3)); auto level = MessageLevel::getLevel(line.left(endmark).mid(3));
line = line.mid(endmark + 2); line = line.mid(endmark + 2);
return level; return level;

View File

@ -6,10 +6,8 @@
* @brief the MessageLevel Enum * @brief the MessageLevel Enum
* defines what level a log message is * defines what level a log message is
*/ */
namespace MessageLevel namespace MessageLevel {
{ enum Enum {
enum Enum
{
Unknown, /**< No idea what this is or where it came from */ Unknown, /**< No idea what this is or where it came from */
StdOut, /**< Undetermined stderr messages */ StdOut, /**< Undetermined stderr messages */
StdErr, /**< Undetermined stdout messages */ StdErr, /**< Undetermined stdout messages */
@ -25,4 +23,4 @@ MessageLevel::Enum getLevel(const QString &levelName);
/* Get message level from a line. Line is modified if it was successful. */ /* Get message level from a line. Line is modified if it was successful. */
MessageLevel::Enum fromLine(QString& line); MessageLevel::Enum fromLine(QString& line);
} } // namespace MessageLevel

View File

@ -37,8 +37,7 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
class NullInstance: public BaseInstance class NullInstance : public BaseInstance {
{
Q_OBJECT Q_OBJECT
public: public:
NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir)
@ -47,78 +46,29 @@ public:
setVersionBroken(true); setVersionBroken(true);
} }
virtual ~NullInstance(){}; virtual ~NullInstance(){};
void saveNow() override void saveNow() override {}
{ void loadSpecificSettings() override { setSpecificSettingsLoaded(true); }
} QString getStatusbarDescription() override { return tr("Unknown instance type"); };
void loadSpecificSettings() override QSet<QString> traits() const override { return {}; };
{ QString instanceConfigFolder() const override { return instanceRoot(); };
setSpecificSettingsLoaded(true); shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override { return nullptr; }
} shared_qobject_ptr<Task> createUpdateTask([[maybe_unused]] Net::Mode mode) override { return nullptr; }
QString getStatusbarDescription() override QProcessEnvironment createEnvironment() override { return QProcessEnvironment(); }
{ QProcessEnvironment createLaunchEnvironment() override { return QProcessEnvironment(); }
return tr("Unknown instance type"); QMap<QString, QString> getVariables() override { return QMap<QString, QString>(); }
}; IPathMatcher::Ptr getLogFileMatcher() override { return nullptr; }
QSet< QString > traits() const override QString getLogFileRoot() override { return instanceRoot(); }
{ QString typeName() const override { return "Null"; }
return {}; bool canExport() const override { return false; }
}; bool canEdit() const override { return false; }
QString instanceConfigFolder() const override bool canLaunch() const override { return false; }
{
return instanceRoot();
};
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override
{
return nullptr;
}
shared_qobject_ptr< Task > createUpdateTask([[maybe_unused]] Net::Mode mode) override
{
return nullptr;
}
QProcessEnvironment createEnvironment() override
{
return QProcessEnvironment();
}
QProcessEnvironment createLaunchEnvironment() override
{
return QProcessEnvironment();
}
QMap<QString, QString> getVariables() override
{
return QMap<QString, QString>();
}
IPathMatcher::Ptr getLogFileMatcher() override
{
return nullptr;
}
QString getLogFileRoot() override
{
return instanceRoot();
}
QString typeName() const override
{
return "Null";
}
bool canExport() const override
{
return false;
}
bool canEdit() const override
{
return false;
}
bool canLaunch() const override
{
return false;
}
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override
{ {
QStringList out; QStringList out;
out << "Null instance - placeholder."; out << "Null instance - placeholder.";
return out; return out;
} }
QString modsRoot() const override { QString modsRoot() const override { return QString(); }
return QString();
}
void updateRuntimeContext() void updateRuntimeContext()
{ {
// NOOP // NOOP

View File

@ -3,42 +3,27 @@
#include <QList> #include <QList>
#include <QString> #include <QString>
enum class ProblemSeverity enum class ProblemSeverity { None, Warning, Error };
{
None,
Warning,
Error
};
struct PatchProblem struct PatchProblem {
{
ProblemSeverity m_severity; ProblemSeverity m_severity;
QString m_description; QString m_description;
}; };
class ProblemProvider class ProblemProvider {
{
public: public:
virtual ~ProblemProvider() {} virtual ~ProblemProvider() {}
virtual const QList<PatchProblem> getProblems() const = 0; virtual const QList<PatchProblem> getProblems() const = 0;
virtual ProblemSeverity getProblemSeverity() const = 0; virtual ProblemSeverity getProblemSeverity() const = 0;
}; };
class ProblemContainer : public ProblemProvider class ProblemContainer : public ProblemProvider {
{
public: public:
const QList<PatchProblem> getProblems() const override const QList<PatchProblem> getProblems() const override { return m_problems; }
{ ProblemSeverity getProblemSeverity() const override { return m_problemSeverity; }
return m_problems;
}
ProblemSeverity getProblemSeverity() const override
{
return m_problemSeverity;
}
virtual void addProblem(ProblemSeverity severity, const QString& description) virtual void addProblem(ProblemSeverity severity, const QString& description)
{ {
if(severity > m_problemSeverity) if (severity > m_problemSeverity) {
{
m_problemSeverity = severity; m_problemSeverity = severity;
} }
m_problems.append({ severity, description }); m_problems.append({ severity, description });

View File

@ -36,35 +36,34 @@
#pragma once #pragma once
#include <QVariant>
#include <QList> #include <QList>
#include <QVariant>
namespace QVariantUtils { namespace QVariantUtils {
template <typename T> template <typename T>
inline QList<T> toList(QVariant src) { inline QList<T> toList(QVariant src)
{
QVariantList variantList = src.toList(); QVariantList variantList = src.toList();
QList<T> list_t; QList<T> list_t;
list_t.reserve(variantList.size()); list_t.reserve(variantList.size());
for (const QVariant& v : variantList) for (const QVariant& v : variantList) {
{
list_t.append(v.value<T>()); list_t.append(v.value<T>());
} }
return list_t; return list_t;
} }
template <typename T> template <typename T>
inline QVariant fromList(QList<T> val) { inline QVariant fromList(QList<T> val)
{
QVariantList variantList; QVariantList variantList;
variantList.reserve(val.size()); variantList.reserve(val.size());
for (const T& v : val) for (const T& v : val) {
{
variantList.append(v); variantList.append(v);
} }
return variantList; return variantList;
} }
} } // namespace QVariantUtils

View File

@ -1,12 +1,11 @@
#pragma once #pragma once
#include <QWriteLocker>
#include <QReadLocker>
#include <QMap> #include <QMap>
#include <QReadLocker>
#include <QSet> #include <QSet>
#include <QWriteLocker>
template <typename K, typename V> template <typename K, typename V>
class RWStorage class RWStorage {
{
public: public:
void add(K key, V value) void add(K key, V value)
{ {
@ -17,21 +16,19 @@ public:
V get(K key) V get(K key)
{ {
QReadLocker l(&lock); QReadLocker l(&lock);
if(cache.contains(key)) if (cache.contains(key)) {
{
return cache[key]; return cache[key];
} } else
else return V(); return V();
} }
bool get(K key, V& value) bool get(K key, V& value)
{ {
QReadLocker l(&lock); QReadLocker l(&lock);
if(cache.contains(key)) if (cache.contains(key)) {
{
value = cache[key]; value = cache[key];
return true; return true;
} } else
else return false; return false;
} }
bool has(K key) bool has(K key)
{ {
@ -48,8 +45,7 @@ public:
void setStale(K key) void setStale(K key)
{ {
QWriteLocker l(&lock); QWriteLocker l(&lock);
if(cache.contains(key)) if (cache.contains(key)) {
{
stale_entries.insert(key); stale_entries.insert(key);
} }
} }
@ -59,6 +55,7 @@ public:
cache.clear(); cache.clear();
stale_entries.clear(); stale_entries.clear();
} }
private: private:
QReadWriteLock lock; QReadWriteLock lock;
QMap<K, V> cache; QMap<K, V> cache;

View File

@ -1,15 +1,12 @@
#include "RecursiveFileSystemWatcher.h" #include "RecursiveFileSystemWatcher.h"
#include <QRegularExpression>
#include <QDebug> #include <QDebug>
#include <QRegularExpression>
RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent) RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject* parent) : QObject(parent), m_watcher(new QFileSystemWatcher(this))
: QObject(parent), m_watcher(new QFileSystemWatcher(this))
{ {
connect(m_watcher, &QFileSystemWatcher::fileChanged, this, connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &RecursiveFileSystemWatcher::fileChange);
&RecursiveFileSystemWatcher::fileChange); connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &RecursiveFileSystemWatcher::directoryChange);
connect(m_watcher, &QFileSystemWatcher::directoryChanged, this,
&RecursiveFileSystemWatcher::directoryChange);
} }
void RecursiveFileSystemWatcher::setRootDir(const QDir& root) void RecursiveFileSystemWatcher::setRootDir(const QDir& root)
@ -18,8 +15,7 @@ void RecursiveFileSystemWatcher::setRootDir(const QDir &root)
disable(); disable();
m_root = root; m_root = root;
setFiles(scanRecursive(m_root)); setFiles(scanRecursive(m_root));
if (wasEnabled) if (wasEnabled) {
{
enable(); enable();
} }
} }
@ -28,16 +24,14 @@ void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles)
bool wasEnabled = m_isEnabled; bool wasEnabled = m_isEnabled;
disable(); disable();
m_watchFiles = watchFiles; m_watchFiles = watchFiles;
if (wasEnabled) if (wasEnabled) {
{
enable(); enable();
} }
} }
void RecursiveFileSystemWatcher::enable() void RecursiveFileSystemWatcher::enable()
{ {
if (m_isEnabled) if (m_isEnabled) {
{
return; return;
} }
Q_ASSERT(m_root != QDir::root()); Q_ASSERT(m_root != QDir::root());
@ -46,8 +40,7 @@ void RecursiveFileSystemWatcher::enable()
} }
void RecursiveFileSystemWatcher::disable() void RecursiveFileSystemWatcher::disable()
{ {
if (!m_isEnabled) if (!m_isEnabled) {
{
return; return;
} }
m_isEnabled = false; m_isEnabled = false;
@ -57,8 +50,7 @@ void RecursiveFileSystemWatcher::disable()
void RecursiveFileSystemWatcher::setFiles(const QStringList& files) void RecursiveFileSystemWatcher::setFiles(const QStringList& files)
{ {
if (files != m_files) if (files != m_files) {
{
m_files = files; m_files = files;
emit filesChanged(); emit filesChanged();
} }
@ -67,14 +59,11 @@ void RecursiveFileSystemWatcher::setFiles(const QStringList &files)
void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir& dir) void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir& dir)
{ {
m_watcher->addPath(dir.absolutePath()); m_watcher->addPath(dir.absolutePath());
for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) for (const QString& directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
{
addFilesToWatcherRecursive(dir.absoluteFilePath(directory)); addFilesToWatcherRecursive(dir.absoluteFilePath(directory));
} }
if (m_watchFiles) if (m_watchFiles) {
{ for (const QFileInfo& info : dir.entryInfoList(QDir::Files)) {
for (const QFileInfo &info : dir.entryInfoList(QDir::Files))
{
m_watcher->addPath(info.absoluteFilePath()); m_watcher->addPath(info.absoluteFilePath());
} }
} }
@ -82,19 +71,15 @@ void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir)
QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory) QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory)
{ {
QStringList ret; QStringList ret;
if(!m_matcher) if (!m_matcher) {
{
return {}; return {};
} }
for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden)) for (const QString& dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden)) {
{
ret.append(scanRecursive(directory.absoluteFilePath(dir))); ret.append(scanRecursive(directory.absoluteFilePath(dir)));
} }
for (const QString &file : directory.entryList(QDir::Files | QDir::Hidden)) for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) {
{
auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file)); auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
if (m_matcher->matches(relPath)) if (m_matcher->matches(relPath)) {
{
ret.append(relPath); ret.append(relPath);
} }
} }

View File

@ -1,37 +1,24 @@
#pragma once #pragma once
#include <QFileSystemWatcher>
#include <QDir> #include <QDir>
#include <QFileSystemWatcher>
#include "pathmatcher/IPathMatcher.h" #include "pathmatcher/IPathMatcher.h"
class RecursiveFileSystemWatcher : public QObject class RecursiveFileSystemWatcher : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
RecursiveFileSystemWatcher(QObject* parent); RecursiveFileSystemWatcher(QObject* parent);
void setRootDir(const QDir& root); void setRootDir(const QDir& root);
QDir rootDir() const QDir rootDir() const { return m_root; }
{
return m_root;
}
// WARNING: setting this to true may be bad for performance // WARNING: setting this to true may be bad for performance
void setWatchFiles(const bool watchFiles); void setWatchFiles(const bool watchFiles);
bool watchFiles() const bool watchFiles() const { return m_watchFiles; }
{
return m_watchFiles;
}
void setMatcher(IPathMatcher::Ptr matcher) void setMatcher(IPathMatcher::Ptr matcher) { m_matcher = matcher; }
{
m_matcher = matcher;
}
QStringList files() const QStringList files() const { return m_files; }
{
return m_files;
}
signals: signals:
void filesChanged(); void filesChanged();

View File

@ -1,26 +1,18 @@
#pragma once #pragma once
#include <QString>
#include <QMap> #include <QMap>
#include <QString>
#include <QStringList> #include <QStringList>
template <char Tseparator> template <char Tseparator>
class SeparatorPrefixTree class SeparatorPrefixTree {
{
public: public:
SeparatorPrefixTree(QStringList paths) SeparatorPrefixTree(QStringList paths) { insert(paths); }
{
insert(paths);
}
SeparatorPrefixTree(bool contained = false) SeparatorPrefixTree(bool contained = false) { m_contained = contained; }
{
m_contained = contained;
}
void insert(QStringList paths) void insert(QStringList paths)
{ {
for(auto &path: paths) for (auto& path : paths) {
{
insert(path); insert(path);
} }
} }
@ -29,16 +21,12 @@ public:
SeparatorPrefixTree& insert(QString path) SeparatorPrefixTree& insert(QString path)
{ {
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
children[path] = SeparatorPrefixTree(true); children[path] = SeparatorPrefixTree(true);
return children[path]; return children[path];
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
if(!children.contains(prefix)) if (!children.contains(prefix)) {
{
children[prefix] = SeparatorPrefixTree(false); children[prefix] = SeparatorPrefixTree(false);
} }
return children[prefix].insert(path.mid(sepIndex + 1)); return children[prefix].insert(path.mid(sepIndex + 1));
@ -56,26 +44,20 @@ public:
bool covers(QString path) const bool covers(QString path) const
{ {
// if we found some valid node, it's good enough. the tree covers the path // if we found some valid node, it's good enough. the tree covers the path
if(m_contained) if (m_contained) {
{
return true; return true;
} }
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return (*found).covers(QString()); return (*found).covers(QString());
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return (*found).covers(path.mid(sepIndex + 1)); return (*found).covers(path.mid(sepIndex + 1));
@ -86,38 +68,30 @@ public:
QString cover(QString path) const QString cover(QString path) const
{ {
// if we found some valid node, it's good enough. the tree covers the path // if we found some valid node, it's good enough. the tree covers the path
if(m_contained) if (m_contained) {
{
return QString(""); return QString("");
} }
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return QString(); return QString();
} }
auto nested = (*found).cover(QString()); auto nested = (*found).cover(QString());
if(nested.isNull()) if (nested.isNull()) {
{
return nested; return nested;
} }
if (nested.isEmpty()) if (nested.isEmpty())
return path; return path;
return path + Tseparator + nested; return path + Tseparator + nested;
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return QString(); return QString();
} }
auto nested = (*found).cover(path.mid(sepIndex + 1)); auto nested = (*found).cover(path.mid(sepIndex + 1));
if(nested.isNull()) if (nested.isNull()) {
{
return nested; return nested;
} }
if (nested.isEmpty()) if (nested.isEmpty())
@ -130,21 +104,16 @@ public:
bool exists(QString path) const bool exists(QString path) const
{ {
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return true; return true;
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return false; return false;
} }
return (*found).exists(path.mid(sepIndex + 1)); return (*found).exists(path.mid(sepIndex + 1));
@ -155,21 +124,16 @@ public:
const SeparatorPrefixTree* find(QString path) const const SeparatorPrefixTree* find(QString path) const
{ {
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
auto found = children.find(path); auto found = children.find(path);
if(found == children.end()) if (found == children.end()) {
{
return nullptr; return nullptr;
} }
return &(*found); return &(*found);
} } else {
else
{
auto prefix = path.left(sepIndex); auto prefix = path.left(sepIndex);
auto found = children.find(prefix); auto found = children.find(prefix);
if(found == children.end()) if (found == children.end()) {
{
return nullptr; return nullptr;
} }
return (*found).find(path.mid(sepIndex + 1)); return (*found).find(path.mid(sepIndex + 1));
@ -177,70 +141,48 @@ public:
} }
/// is this a leaf node? /// is this a leaf node?
bool leaf() const bool leaf() const { return children.isEmpty(); }
{
return children.isEmpty();
}
/// is this node actually contained in the tree, or is it purely structural? /// is this node actually contained in the tree, or is it purely structural?
bool contained() const bool contained() const { return m_contained; }
{
return m_contained;
}
/// Remove a path from the tree /// Remove a path from the tree
bool remove(QString path) bool remove(QString path) { return removeInternal(path) != Failed; }
{
return removeInternal(path) != Failed;
}
/// Clear all children of this node tree node /// Clear all children of this node tree node
void clear() void clear() { children.clear(); }
{
children.clear();
}
QStringList toStringList() const QStringList toStringList() const
{ {
QStringList collected; QStringList collected;
// collecting these is more expensive. // collecting these is more expensive.
auto iter = children.begin(); auto iter = children.begin();
while(iter != children.end()) while (iter != children.end()) {
{
QStringList list = iter.value().toStringList(); QStringList list = iter.value().toStringList();
for(int i = 0; i < list.size(); i++) for (int i = 0; i < list.size(); i++) {
{
list[i] = iter.key() + Tseparator + list[i]; list[i] = iter.key() + Tseparator + list[i];
} }
collected.append(list); collected.append(list);
if((*iter).m_contained) if ((*iter).m_contained) {
{
collected.append(iter.key()); collected.append(iter.key());
} }
iter++; iter++;
} }
return collected; return collected;
} }
private: private:
enum Removal enum Removal { Failed, Succeeded, HasChildren };
{
Failed,
Succeeded,
HasChildren
};
Removal removeInternal(QString path = QString()) Removal removeInternal(QString path = QString())
{ {
if(path.isEmpty()) if (path.isEmpty()) {
{ if (!m_contained) {
if(!m_contained)
{
// remove all children - we are removing a prefix // remove all children - we are removing a prefix
clear(); clear();
return Succeeded; return Succeeded;
} }
m_contained = false; m_contained = false;
if(children.size()) if (children.size()) {
{
return HasChildren; return HasChildren;
} }
return Succeeded; return Succeeded;
@ -248,42 +190,32 @@ private:
Removal remStatus = Failed; Removal remStatus = Failed;
QString childToRemove; QString childToRemove;
auto sepIndex = path.indexOf(Tseparator); auto sepIndex = path.indexOf(Tseparator);
if(sepIndex == -1) if (sepIndex == -1) {
{
childToRemove = path; childToRemove = path;
auto found = children.find(childToRemove); auto found = children.find(childToRemove);
if(found == children.end()) if (found == children.end()) {
{
return Failed; return Failed;
} }
remStatus = (*found).removeInternal(); remStatus = (*found).removeInternal();
} } else {
else
{
childToRemove = path.left(sepIndex); childToRemove = path.left(sepIndex);
auto found = children.find(childToRemove); auto found = children.find(childToRemove);
if(found == children.end()) if (found == children.end()) {
{
return Failed; return Failed;
} }
remStatus = (*found).removeInternal(path.mid(sepIndex + 1)); remStatus = (*found).removeInternal(path.mid(sepIndex + 1));
} }
switch (remStatus) switch (remStatus) {
{
case Failed: case Failed:
case HasChildren: case HasChildren: {
{
return remStatus; return remStatus;
} }
case Succeeded: case Succeeded: {
{
children.remove(childToRemove); children.remove(childToRemove);
if(m_contained) if (m_contained) {
{
return HasChildren; return HasChildren;
} }
if(children.size()) if (children.size()) {
{
return HasChildren; return HasChildren;
} }
return Succeeded; return Succeeded;

View File

@ -14,17 +14,16 @@
*/ */
#include "SkinUtils.h" #include "SkinUtils.h"
#include "net/HttpMetaCache.h"
#include "Application.h" #include "Application.h"
#include "net/HttpMetaCache.h"
#include <QFile> #include <QFile>
#include <QPainter> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QPainter>
namespace SkinUtils namespace SkinUtils {
{
/* /*
* Given a username, return a pixmap of the cached skin (if it exists), QPixmap() otherwise * Given a username, return a pixmap of the cached skin (if it exists), QPixmap() otherwise
*/ */
@ -32,11 +31,9 @@ QPixmap getFaceFromCache(QString username, int height, int width)
{ {
QFile fskin(APPLICATION->metacache()->resolveEntry("skins", username + ".png")->getFullPath()); QFile fskin(APPLICATION->metacache()->resolveEntry("skins", username + ".png")->getFullPath());
if (fskin.exists()) if (fskin.exists()) {
{
QPixmap skinTexture(fskin.fileName()); QPixmap skinTexture(fskin.fileName());
if(!skinTexture.isNull()) if (!skinTexture.isNull()) {
{
QPixmap skin = QPixmap(8, 8); QPixmap skin = QPixmap(8, 8);
QPainter painter(&skin); QPainter painter(&skin);
painter.drawPixmap(0, 0, skinTexture.copy(8, 8, 8, 8)); painter.drawPixmap(0, 0, skinTexture.copy(8, 8, 8, 8));
@ -47,4 +44,4 @@ QPixmap getFaceFromCache(QString username, int height, int width)
return QPixmap(); return QPixmap();
} }
} } // namespace SkinUtils

View File

@ -17,7 +17,6 @@
#include <QPixmap> #include <QPixmap>
namespace SkinUtils namespace SkinUtils {
{
QPixmap getFaceFromCache(QString id, int height = 64, int width = 64); QPixmap getFaceFromCache(QString id, int height = 64, int width = 64);
} }

View File

@ -77,6 +77,5 @@ QString truncateUrlHumanFriendly(QUrl &url, int max_len, bool hard_limit = false
QString humanReadableFileSize(double bytes, bool use_si = false, int decimal_points = 1); QString humanReadableFileSize(double bytes, bool use_si = false, int decimal_points = 1);
QString getRandomAlphaNumeric(); QString getRandomAlphaNumeric();
} // namespace StringUtils } // namespace StringUtils

View File

@ -34,19 +34,15 @@ class Usable {
* *
* @see Usable * @see Usable
*/ */
class UseLock class UseLock {
{
public: public:
UseLock(shared_qobject_ptr<Usable> usable) UseLock(shared_qobject_ptr<Usable> usable) : m_usable(usable)
: m_usable(usable)
{ {
// this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate. // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate.
m_usable->incrementUses(); m_usable->incrementUses();
} }
~UseLock() ~UseLock() { m_usable->decrementUses(); }
{
m_usable->decrementUses();
}
private: private:
shared_qobject_ptr<Usable> m_usable; shared_qobject_ptr<Usable> m_usable;
}; };

View File

@ -117,12 +117,14 @@ QDebug operator<<(QDebug debug, const Version& v)
bool first = true; bool first = true;
for (auto s : v.m_sections) { for (auto s : v.m_sections) {
if (!first) debug.nospace() << ", "; if (!first)
debug.nospace() << ", ";
debug.nospace() << s.m_fullString; debug.nospace() << s.m_fullString;
first = false; first = false;
} }
debug.nospace() << " ]" << " }"; debug.nospace() << " ]"
<< " }";
return debug; return debug;
} }

View File

@ -103,8 +103,14 @@ class Version {
QString m_fullString; QString m_fullString;
[[nodiscard]] inline bool isAppendix() const { return m_stringPart.startsWith('+'); } [[nodiscard]] inline bool isAppendix() const
[[nodiscard]] inline bool isPreRelease() const { return m_stringPart.startsWith('-') && m_stringPart.length() > 1; } {
return m_stringPart.startsWith('+');
}
[[nodiscard]] inline bool isPreRelease() const
{
return m_stringPart.startsWith('-') && m_stringPart.length() > 1;
}
inline bool operator==(const Section& other) const inline bool operator==(const Section& other) const
{ {
@ -166,5 +172,3 @@ class Version {
void parse(); void parse();
}; };

View File

@ -35,14 +35,13 @@
*/ */
#include "VersionProxyModel.h" #include "VersionProxyModel.h"
#include "Application.h"
#include <QSortFilterProxyModel>
#include <QPixmapCache>
#include <Version.h> #include <Version.h>
#include <meta/VersionList.h> #include <meta/VersionList.h>
#include <QPixmapCache>
#include <QSortFilterProxyModel>
#include "Application.h"
class VersionFilterModel : public QSortFilterProxyModel class VersionFilterModel : public QSortFilterProxyModel {
{
Q_OBJECT Q_OBJECT
public: public:
VersionFilterModel(VersionProxyModel* parent) : QSortFilterProxyModel(parent) VersionFilterModel(VersionProxyModel* parent) : QSortFilterProxyModel(parent)
@ -61,22 +60,18 @@ public:
if (!search.isEmpty() && !sourceModel()->data(idx, BaseVersionList::VersionRole).toString().contains(search, Qt::CaseInsensitive)) if (!search.isEmpty() && !sourceModel()->data(idx, BaseVersionList::VersionRole).toString().contains(search, Qt::CaseInsensitive))
return false; return false;
for (auto it = filters.begin(); it != filters.end(); ++it) for (auto it = filters.begin(); it != filters.end(); ++it) {
{
auto data = sourceModel()->data(idx, it.key()); auto data = sourceModel()->data(idx, it.key());
auto match = data.toString(); auto match = data.toString();
if(!it.value()->accepts(match)) if (!it.value()->accepts(match)) {
{
return false; return false;
} }
} }
return true; return true;
} }
void filterChanged() void filterChanged() { invalidateFilter(); }
{
invalidateFilter();
}
private: private:
VersionProxyModel* m_parent; VersionProxyModel* m_parent;
}; };
@ -109,10 +104,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation,
if (orientation != Qt::Horizontal) if (orientation != Qt::Horizontal)
return QVariant(); return QVariant();
auto column = m_columns[section]; auto column = m_columns[section];
if(role == Qt::DisplayRole) if (role == Qt::DisplayRole) {
{ switch (column) {
switch(column)
{
case Name: case Name:
return tr("Version"); return tr("Version");
case ParentVersion: case ParentVersion:
@ -128,11 +121,8 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation,
case Time: case Time:
return tr("Released"); return tr("Released");
} }
} } else if (role == Qt::ToolTipRole) {
else if(role == Qt::ToolTipRole) switch (column) {
{
switch(column)
{
case Name: case Name:
return tr("The name of the version."); return tr("The name of the version.");
case ParentVersion: case ParentVersion:
@ -154,23 +144,17 @@ QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation,
QVariant VersionProxyModel::data(const QModelIndex& index, int role) const QVariant VersionProxyModel::data(const QModelIndex& index, int role) const
{ {
if(!index.isValid()) if (!index.isValid()) {
{
return QVariant(); return QVariant();
} }
auto column = m_columns[index.column()]; auto column = m_columns[index.column()];
auto parentIndex = mapToSource(index); auto parentIndex = mapToSource(index);
switch(role) switch (role) {
{ case Qt::DisplayRole: {
case Qt::DisplayRole: switch (column) {
{ case Name: {
switch(column)
{
case Name:
{
QString version = sourceModel()->data(parentIndex, BaseVersionList::VersionRole).toString(); QString version = sourceModel()->data(parentIndex, BaseVersionList::VersionRole).toString();
if(version == m_currentVersion) if (version == m_currentVersion) {
{
return tr("%1 (installed)").arg(version); return tr("%1 (installed)").arg(version);
} }
return version; return version;
@ -191,18 +175,14 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
} }
case Qt::ToolTipRole: case Qt::ToolTipRole: {
{ if (column == Name && hasRecommended) {
if(column == Name && hasRecommended)
{
auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
if(value.toBool()) if (value.toBool()) {
{
return tr("Recommended"); return tr("Recommended");
} else if (hasLatest) { } else if (hasLatest) {
auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole);
if(value.toBool()) if (value.toBool()) {
{
return tr("Latest"); return tr("Latest");
} }
} }
@ -210,14 +190,10 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const
return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole);
} }
} }
case Qt::DecorationRole: case Qt::DecorationRole: {
{ switch (column) {
switch(column) case Name: {
{ if (hasRecommended) {
case Name:
{
if(hasRecommended)
{
auto recommenced = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); auto recommenced = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
if (recommenced.toBool()) { if (recommenced.toBool()) {
return APPLICATION->getThemedIcon("star"); return APPLICATION->getThemedIcon("star");
@ -229,8 +205,7 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const
} }
QPixmap pixmap; QPixmap pixmap;
QPixmapCache::find("placeholder", &pixmap); QPixmapCache::find("placeholder", &pixmap);
if(!pixmap) if (!pixmap) {
{
QPixmap px(16, 16); QPixmap px(16, 16);
px.fill(Qt::transparent); px.fill(Qt::transparent);
QPixmapCache::insert("placeholder", px); QPixmapCache::insert("placeholder", px);
@ -239,16 +214,13 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const
return pixmap; return pixmap;
} }
} }
default: default: {
{
return QVariant(); return QVariant();
} }
} }
} }
default: default: {
{ if (roles.contains((BaseVersionList::ModelRoles)role)) {
if(roles.contains((BaseVersionList::ModelRoles)role))
{
return sourceModel()->data(parentIndex, role); return sourceModel()->data(parentIndex, role);
} }
return QVariant(); return QVariant();
@ -263,8 +235,7 @@ QModelIndex VersionProxyModel::parent([[maybe_unused]] const QModelIndex& child)
QModelIndex VersionProxyModel::mapFromSource(const QModelIndex& sourceIndex) const QModelIndex VersionProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
{ {
if(sourceIndex.isValid()) if (sourceIndex.isValid()) {
{
return index(sourceIndex.row(), 0); return index(sourceIndex.row(), 0);
} }
return QModelIndex(); return QModelIndex();
@ -272,8 +243,7 @@ QModelIndex VersionProxyModel::mapFromSource(const QModelIndex &sourceIndex) con
QModelIndex VersionProxyModel::mapToSource(const QModelIndex& proxyIndex) const QModelIndex VersionProxyModel::mapToSource(const QModelIndex& proxyIndex) const
{ {
if(proxyIndex.isValid()) if (proxyIndex.isValid()) {
{
return sourceModel()->index(proxyIndex.row(), 0); return sourceModel()->index(proxyIndex.row(), 0);
} }
return QModelIndex(); return QModelIndex();
@ -282,8 +252,7 @@ QModelIndex VersionProxyModel::mapToSource(const QModelIndex &proxyIndex) const
QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex& parent) const QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex& parent) const
{ {
// no trees here... shoo // no trees here... shoo
if(parent.isValid()) if (parent.isValid()) {
{
return QModelIndex(); return QModelIndex();
} }
if (row < 0 || row >= sourceModel()->rowCount()) if (row < 0 || row >= sourceModel()->rowCount())
@ -300,15 +269,13 @@ int VersionProxyModel::columnCount(const QModelIndex &parent) const
int VersionProxyModel::rowCount(const QModelIndex& parent) const int VersionProxyModel::rowCount(const QModelIndex& parent) const
{ {
if(sourceModel()) if (sourceModel()) {
{
return sourceModel()->rowCount(parent); return sourceModel()->rowCount(parent);
} }
return 0; return 0;
} }
void VersionProxyModel::sourceDataChanged(const QModelIndex &source_top_left, void VersionProxyModel::sourceDataChanged(const QModelIndex& source_top_left, const QModelIndex& source_bottom_right)
const QModelIndex &source_bottom_right)
{ {
if (source_top_left.parent() != source_bottom_right.parent()) if (source_top_left.parent() != source_bottom_right.parent())
return; return;
@ -325,16 +292,14 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw)
beginResetModel(); beginResetModel();
m_columns.clear(); m_columns.clear();
if(!replacing) if (!replacing) {
{
roles.clear(); roles.clear();
filterModel->setSourceModel(replacing); filterModel->setSourceModel(replacing);
return; return;
} }
roles = replacing->providesRoles(); roles = replacing->providesRoles();
if(roles.contains(BaseVersionList::VersionRole)) if (roles.contains(BaseVersionList::VersionRole)) {
{
m_columns.push_back(Name); m_columns.push_back(Name);
} }
/* /*
@ -343,32 +308,25 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw)
m_columns.push_back(ParentVersion); m_columns.push_back(ParentVersion);
} }
*/ */
if(roles.contains(BaseVersionList::ArchitectureRole)) if (roles.contains(BaseVersionList::ArchitectureRole)) {
{
m_columns.push_back(Architecture); m_columns.push_back(Architecture);
} }
if(roles.contains(BaseVersionList::PathRole)) if (roles.contains(BaseVersionList::PathRole)) {
{
m_columns.push_back(Path); m_columns.push_back(Path);
} }
if(roles.contains(Meta::VersionList::TimeRole)) if (roles.contains(Meta::VersionList::TimeRole)) {
{
m_columns.push_back(Time); m_columns.push_back(Time);
} }
if(roles.contains(BaseVersionList::BranchRole)) if (roles.contains(BaseVersionList::BranchRole)) {
{
m_columns.push_back(Branch); m_columns.push_back(Branch);
} }
if(roles.contains(BaseVersionList::TypeRole)) if (roles.contains(BaseVersionList::TypeRole)) {
{
m_columns.push_back(Type); m_columns.push_back(Type);
} }
if(roles.contains(BaseVersionList::RecommendedRole)) if (roles.contains(BaseVersionList::RecommendedRole)) {
{
hasRecommended = true; hasRecommended = true;
} }
if(roles.contains(BaseVersionList::LatestRole)) if (roles.contains(BaseVersionList::LatestRole)) {
{
hasLatest = true; hasLatest = true;
} }
filterModel->setSourceModel(replacing); filterModel->setSourceModel(replacing);
@ -378,16 +336,13 @@ void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw)
QModelIndex VersionProxyModel::getRecommended() const QModelIndex VersionProxyModel::getRecommended() const
{ {
if(!roles.contains(BaseVersionList::RecommendedRole)) if (!roles.contains(BaseVersionList::RecommendedRole)) {
{
return index(0, 0); return index(0, 0);
} }
int recommended = 0; int recommended = 0;
for (int i = 0; i < rowCount(); i++) for (int i = 0; i < rowCount(); i++) {
{
auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::RecommendedRole); auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::RecommendedRole);
if (value.toBool()) if (value.toBool()) {
{
recommended = i; recommended = i;
} }
} }
@ -397,16 +352,13 @@ QModelIndex VersionProxyModel::getRecommended() const
QModelIndex VersionProxyModel::getVersion(const QString& version) const QModelIndex VersionProxyModel::getVersion(const QString& version) const
{ {
int found = -1; int found = -1;
for (int i = 0; i < rowCount(); i++) for (int i = 0; i < rowCount(); i++) {
{
auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::VersionRole); auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::VersionRole);
if (value.toString() == version) if (value.toString() == version) {
{
found = i; found = i;
} }
} }
if(found == -1) if (found == -1) {
{
return QModelIndex(); return QModelIndex();
} }
return index(found, 0); return index(found, 0);
@ -425,7 +377,8 @@ void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filt
filterModel->filterChanged(); filterModel->filterChanged();
} }
void VersionProxyModel::setSearch(const QString &search) { void VersionProxyModel::setSearch(const QString& search)
{
m_search = search; m_search = search;
filterModel->filterChanged(); filterModel->filterChanged();
} }

View File

@ -6,21 +6,10 @@
class VersionFilterModel; class VersionFilterModel;
class VersionProxyModel: public QAbstractProxyModel class VersionProxyModel : public QAbstractProxyModel {
{
Q_OBJECT Q_OBJECT
public: public:
enum Column { Name, ParentVersion, Branch, Type, Architecture, Path, Time };
enum Column
{
Name,
ParentVersion,
Branch,
Type,
Architecture,
Path,
Time
};
typedef QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>> FilterMap; typedef QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>> FilterMap;
public: public:

View File

@ -1,20 +1,15 @@
#pragma once #pragma once
#include <QString>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include <QString>
struct WatchLock struct WatchLock {
{ WatchLock(QFileSystemWatcher* watcher, const QString& directory) : m_watcher(watcher), m_directory(directory)
WatchLock(QFileSystemWatcher * watcher, const QString& directory)
: m_watcher(watcher), m_directory(directory)
{ {
m_watcher->removePath(m_directory); m_watcher->removePath(m_directory);
} }
~WatchLock() ~WatchLock() { m_watcher->addPath(m_directory); }
{
m_watcher->addPath(m_directory);
}
QFileSystemWatcher* m_watcher; QFileSystemWatcher* m_watcher;
QString m_directory; QString m_directory;
}; };

View File

@ -16,7 +16,6 @@
* *
*/ */
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
@ -26,8 +25,8 @@
#include <windows.h> #include <windows.h>
#include <iostream> #include <iostream>
void RedirectHandle(DWORD handle, FILE* stream, const char* mode ) { void RedirectHandle(DWORD handle, FILE* stream, const char* mode)
{
HANDLE stdHandle = GetStdHandle(handle); HANDLE stdHandle = GetStdHandle(handle);
if (stdHandle != INVALID_HANDLE_VALUE) { if (stdHandle != INVALID_HANDLE_VALUE) {
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT); int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
@ -41,7 +40,6 @@ void RedirectHandle(DWORD handle, FILE* stream, const char* mode ) {
} }
} }
} }
} }
// taken from https://stackoverflow.com/a/25927081 // taken from https://stackoverflow.com/a/25927081
@ -101,8 +99,8 @@ void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr
} }
} }
bool AttachWindowsConsole()
bool AttachWindowsConsole() { {
auto stdinType = GetFileType(GetStdHandle(STD_INPUT_HANDLE)); auto stdinType = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
auto stdoutType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)); auto stdoutType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
auto stderrType = GetFileType(GetStdHandle(STD_ERROR_HANDLE)); auto stderrType = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
@ -128,5 +126,3 @@ bool AttachWindowsConsole() {
return false; return false;
} }

View File

@ -35,26 +35,23 @@
#include "JavaChecker.h" #include "JavaChecker.h"
#include <QFile>
#include <QProcess>
#include <QMap>
#include <QDebug> #include <QDebug>
#include <QFile>
#include <QMap>
#include <QProcess>
#include "JavaUtils.h"
#include "FileSystem.h"
#include "Commandline.h"
#include "Application.h" #include "Application.h"
#include "Commandline.h"
#include "FileSystem.h"
#include "JavaUtils.h"
JavaChecker::JavaChecker(QObject *parent) : QObject(parent) JavaChecker::JavaChecker(QObject* parent) : QObject(parent) {}
{
}
void JavaChecker::performCheck() void JavaChecker::performCheck()
{ {
QString checkerJar = JavaUtils::getJavaCheckPath(); QString checkerJar = JavaUtils::getJavaCheckPath();
if (checkerJar.isEmpty()) if (checkerJar.isEmpty()) {
{
qDebug() << "Java checker library could not be found. Please check your installation."; qDebug() << "Java checker library could not be found. Please check your installation.";
return; return;
} }
@ -62,21 +59,17 @@ void JavaChecker::performCheck()
QStringList args; QStringList args;
process.reset(new QProcess()); process.reset(new QProcess());
if(m_args.size()) if (m_args.size()) {
{
auto extraArgs = Commandline::splitArgs(m_args); auto extraArgs = Commandline::splitArgs(m_args);
args.append(extraArgs); args.append(extraArgs);
} }
if(m_minMem != 0) if (m_minMem != 0) {
{
args << QString("-Xms%1m").arg(m_minMem); args << QString("-Xms%1m").arg(m_minMem);
} }
if(m_maxMem != 0) if (m_maxMem != 0) {
{
args << QString("-Xmx%1m").arg(m_maxMem); args << QString("-Xmx%1m").arg(m_maxMem);
} }
if(m_permGen != 64) if (m_permGen != 64) {
{
args << QString("-XX:PermSize=%1m").arg(m_permGen); args << QString("-XX:PermSize=%1m").arg(m_permGen);
} }
@ -130,8 +123,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
qWarning() << "STDERR" << m_stderr; qWarning() << "STDERR" << m_stderr;
qDebug() << "Java checker finished with status" << status << "exit code" << exitcode; qDebug() << "Java checker finished with status" << status << "exit code" << exitcode;
if (status == QProcess::CrashExit || exitcode == 1) if (status == QProcess::CrashExit || exitcode == 1) {
{
result.validity = JavaCheckResult::Validity::Errored; result.validity = JavaCheckResult::Validity::Errored;
emit checkFinished(result); emit checkFinished(result);
return; return;
@ -146,8 +138,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
#else #else
QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts); QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
#endif #endif
for(QString line : lines) for (QString line : lines) {
{
line = line.trimmed(); line = line.trimmed();
// NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux // NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux
if (line.contains("/bedrock/strata")) { if (line.contains("/bedrock/strata")) {
@ -159,18 +150,14 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
#else #else
auto parts = line.split('=', QString::SkipEmptyParts); auto parts = line.split('=', QString::SkipEmptyParts);
#endif #endif
if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) if (parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) {
{
continue; continue;
} } else {
else
{
results.insert(parts[0], parts[1]); results.insert(parts[0], parts[1]);
} }
} }
if(!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor") || !success) if (!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor") || !success) {
{
result.validity = JavaCheckResult::Validity::ReturnedInvalidData; result.validity = JavaCheckResult::Validity::ReturnedInvalidData;
emit checkFinished(result); emit checkFinished(result);
return; return;
@ -181,7 +168,6 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
auto java_vendor = results["java.vendor"]; auto java_vendor = results["java.vendor"];
bool is_64 = os_arch == "x86_64" || os_arch == "amd64" || os_arch == "aarch64" || os_arch == "arm64"; bool is_64 = os_arch == "x86_64" || os_arch == "amd64" || os_arch == "aarch64" || os_arch == "arm64";
result.validity = JavaCheckResult::Validity::Valid; result.validity = JavaCheckResult::Validity::Valid;
result.is_64bit = is_64; result.is_64bit = is_64;
result.mojangPlatform = is_64 ? "64" : "32"; result.mojangPlatform = is_64 ? "64" : "32";
@ -194,8 +180,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
void JavaChecker::error(QProcess::ProcessError err) void JavaChecker::error(QProcess::ProcessError err)
{ {
if(err == QProcess::FailedToStart) if (err == QProcess::FailedToStart) {
{
qDebug() << "Java checker has failed to start."; qDebug() << "Java checker has failed to start.";
qDebug() << "Process environment:"; qDebug() << "Process environment:";
qDebug() << process->environment(); qDebug() << process->environment();
@ -216,8 +201,7 @@ void JavaChecker::error(QProcess::ProcessError err)
void JavaChecker::timeout() void JavaChecker::timeout()
{ {
// NO MERCY. NO ABUSE. // NO MERCY. NO ABUSE.
if(process) if (process) {
{
qDebug() << "Java checker has been killed by timeout."; qDebug() << "Java checker has been killed by timeout.";
process->kill(); process->kill();
} }

View File

@ -9,8 +9,7 @@
class JavaChecker; class JavaChecker;
struct JavaCheckResult struct JavaCheckResult {
{
QString path; QString path;
QString mojangPlatform; QString mojangPlatform;
QString realPlatform; QString realPlatform;
@ -20,18 +19,12 @@ struct JavaCheckResult
QString errorLog; QString errorLog;
bool is_64bit = false; bool is_64bit = false;
int id; int id;
enum class Validity enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored;
{
Errored,
ReturnedInvalidData,
Valid
} validity = Validity::Errored;
}; };
typedef shared_qobject_ptr<QProcess> QProcessPtr; typedef shared_qobject_ptr<QProcess> QProcessPtr;
typedef shared_qobject_ptr<JavaChecker> JavaCheckerPtr; typedef shared_qobject_ptr<JavaChecker> JavaCheckerPtr;
class JavaChecker : public QObject class JavaChecker : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
explicit JavaChecker(QObject* parent = 0); explicit JavaChecker(QObject* parent = 0);
@ -46,13 +39,13 @@ public:
signals: signals:
void checkFinished(JavaCheckResult result); void checkFinished(JavaCheckResult result);
private: private:
QProcessPtr process; QProcessPtr process;
QTimer killTimer; QTimer killTimer;
QString m_stdout; QString m_stdout;
QString m_stderr; QString m_stderr;
public public slots:
slots:
void timeout(); void timeout();
void finished(int exitcode, QProcess::ExitStatus); void finished(int exitcode, QProcess::ExitStatus);
void error(QProcess::ProcessError); void error(QProcess::ProcessError);

View File

@ -20,14 +20,12 @@
void JavaCheckerJob::partFinished(JavaCheckResult result) void JavaCheckerJob::partFinished(JavaCheckResult result)
{ {
num_finished++; num_finished++;
qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/" qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/" << javacheckers.size();
<< javacheckers.size();
setProgress(num_finished, javacheckers.size()); setProgress(num_finished, javacheckers.size());
javaresults.replace(result.id, result); javaresults.replace(result.id, result);
if (num_finished == javacheckers.size()) if (num_finished == javacheckers.size()) {
{
emitSucceeded(); emitSucceeded();
} }
} }
@ -35,8 +33,7 @@ void JavaCheckerJob::partFinished(JavaCheckResult result)
void JavaCheckerJob::executeTask() void JavaCheckerJob::executeTask()
{ {
qDebug() << m_job_name.toLocal8Bit() << " started."; qDebug() << m_job_name.toLocal8Bit() << " started.";
for (auto iter : javacheckers) for (auto iter : javacheckers) {
{
javaresults.append(JavaCheckResult()); javaresults.append(JavaCheckResult());
connect(iter.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished); connect(iter.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished);
iter->performCheck(); iter->performCheck();

View File

@ -23,8 +23,7 @@ class JavaCheckerJob;
typedef shared_qobject_ptr<JavaCheckerJob> JavaCheckerJobPtr; typedef shared_qobject_ptr<JavaCheckerJob> JavaCheckerJobPtr;
// FIXME: this just seems horribly redundant // FIXME: this just seems horribly redundant
class JavaCheckerJob : public Task class JavaCheckerJob : public Task {
{
Q_OBJECT Q_OBJECT
public: public:
explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name){}; explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name){};
@ -34,18 +33,14 @@ public:
{ {
javacheckers.append(base); javacheckers.append(base);
// if this is already running, the action needs to be started right away! // if this is already running, the action needs to be started right away!
if (isRunning()) if (isRunning()) {
{
setProgress(num_finished, javacheckers.size()); setProgress(num_finished, javacheckers.size());
connect(base.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished); connect(base.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished);
base->performCheck(); base->performCheck();
} }
return true; return true;
} }
QList<JavaCheckResult> getResults() QList<JavaCheckResult> getResults() { return javaresults; }
{
return javaresults;
}
private slots: private slots:
void partFinished(JavaCheckResult result); void partFinished(JavaCheckResult result);

View File

@ -39,14 +39,12 @@
#include <QDebug> #include <QDebug>
#include "java/JavaInstallList.h"
#include "java/JavaCheckerJob.h" #include "java/JavaCheckerJob.h"
#include "java/JavaInstallList.h"
#include "java/JavaUtils.h" #include "java/JavaUtils.h"
#include "minecraft/VersionFilterData.h" #include "minecraft/VersionFilterData.h"
JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent) JavaInstallList::JavaInstallList(QObject* parent) : BaseVersionList(parent) {}
{
}
Task::Ptr JavaInstallList::getLoadTask() Task::Ptr JavaInstallList::getLoadTask()
{ {
@ -56,8 +54,7 @@ Task::Ptr JavaInstallList::getLoadTask()
Task::Ptr JavaInstallList::getCurrentTask() Task::Ptr JavaInstallList::getCurrentTask()
{ {
if(m_status == Status::InProgress) if (m_status == Status::InProgress) {
{
return m_loadTask; return m_loadTask;
} }
return nullptr; return nullptr;
@ -65,8 +62,7 @@ Task::Ptr JavaInstallList::getCurrentTask()
void JavaInstallList::load() void JavaInstallList::load()
{ {
if(m_status != Status::InProgress) if (m_status != Status::InProgress) {
{
m_status = Status::InProgress; m_status = Status::InProgress;
m_loadTask.reset(new JavaListLoadTask(this)); m_loadTask.reset(new JavaListLoadTask(this));
m_loadTask->start(); m_loadTask->start();
@ -97,8 +93,7 @@ QVariant JavaInstallList::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
auto version = std::dynamic_pointer_cast<JavaInstall>(m_vlist[index.row()]); auto version = std::dynamic_pointer_cast<JavaInstall>(m_vlist[index.row()]);
switch (role) switch (role) {
{
case SortRole: case SortRole:
return -index.row(); return -index.row();
case VersionPointerRole: case VersionPointerRole:
@ -123,14 +118,12 @@ BaseVersionList::RoleList JavaInstallList::providesRoles() const
return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole }; return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole };
} }
void JavaInstallList::updateListData(QList<BaseVersion::Ptr> versions) void JavaInstallList::updateListData(QList<BaseVersion::Ptr> versions)
{ {
beginResetModel(); beginResetModel();
m_vlist = versions; m_vlist = versions;
sortVersions(); sortVersions();
if(m_vlist.size()) if (m_vlist.size()) {
{
auto best = std::dynamic_pointer_cast<JavaInstall>(m_vlist[0]); auto best = std::dynamic_pointer_cast<JavaInstall>(m_vlist[0]);
best->recommended = true; best->recommended = true;
} }
@ -159,9 +152,7 @@ JavaListLoadTask::JavaListLoadTask(JavaInstallList *vlist) : Task()
m_currentRecommended = NULL; m_currentRecommended = NULL;
} }
JavaListLoadTask::~JavaListLoadTask() JavaListLoadTask::~JavaListLoadTask() {}
{
}
void JavaListLoadTask::executeTask() void JavaListLoadTask::executeTask()
{ {
@ -176,8 +167,7 @@ void JavaListLoadTask::executeTask()
qDebug() << "Probing the following Java paths: "; qDebug() << "Probing the following Java paths: ";
int id = 0; int id = 0;
for(QString candidate : candidate_paths) for (QString candidate : candidate_paths) {
{
qDebug() << " " << candidate; qDebug() << " " << candidate;
auto candidate_checker = new JavaChecker(); auto candidate_checker = new JavaChecker();
@ -197,10 +187,8 @@ void JavaListLoadTask::javaCheckerFinished()
auto results = m_job->getResults(); auto results = m_job->getResults();
qDebug() << "Found the following valid Java installations:"; qDebug() << "Found the following valid Java installations:";
for(JavaCheckResult result : results) for (JavaCheckResult result : results) {
{ if (result.validity == JavaCheckResult::Validity::Valid) {
if(result.validity == JavaCheckResult::Validity::Valid)
{
JavaInstallPtr javaVersion(new JavaInstall()); JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = result.javaVersion; javaVersion->id = result.javaVersion;
@ -213,13 +201,11 @@ void JavaListLoadTask::javaCheckerFinished()
} }
QList<BaseVersion::Ptr> javas_bvp; QList<BaseVersion::Ptr> javas_bvp;
for (auto java : candidates) for (auto java : candidates) {
{
// qDebug() << java->id << java->arch << " at " << java->path; // qDebug() << java->id << java->arch << " at " << java->path;
BaseVersion::Ptr bp_java = std::dynamic_pointer_cast<BaseVersion>(java); BaseVersion::Ptr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
if (bp_java) if (bp_java) {
{
javas_bvp.append(java); javas_bvp.append(java);
} }
} }

View File

@ -15,8 +15,8 @@
#pragma once #pragma once
#include <QObject>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QObject>
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "tasks/Task.h" #include "tasks/Task.h"
@ -28,15 +28,10 @@
class JavaListLoadTask; class JavaListLoadTask;
class JavaInstallList : public BaseVersionList class JavaInstallList : public BaseVersionList {
{
Q_OBJECT Q_OBJECT
enum class Status enum class Status { NotDone, InProgress, Done };
{
NotDone,
InProgress,
Done
};
public: public:
explicit JavaInstallList(QObject* parent = 0); explicit JavaInstallList(QObject* parent = 0);
@ -62,8 +57,7 @@ protected:
QList<BaseVersion::Ptr> m_vlist; QList<BaseVersion::Ptr> m_vlist;
}; };
class JavaListLoadTask : public Task class JavaListLoadTask : public Task {
{
Q_OBJECT Q_OBJECT
public: public:

View File

@ -33,24 +33,21 @@
* limitations under the License. * limitations under the License.
*/ */
#include <QStringList>
#include <QString>
#include <QDir> #include <QDir>
#include <QString>
#include <QStringList> #include <QStringList>
#include <settings/Setting.h> #include <settings/Setting.h>
#include <QDebug> #include <QDebug>
#include "java/JavaUtils.h"
#include "java/JavaInstallList.h"
#include "FileSystem.h"
#include "Application.h" #include "Application.h"
#include "FileSystem.h"
#include "java/JavaInstallList.h"
#include "java/JavaUtils.h"
#define IBUS "@im=ibus" #define IBUS "@im=ibus"
JavaUtils::JavaUtils() JavaUtils::JavaUtils() {}
{
}
QString stripVariableEntries(QString name, QString target, QString remove) QString stripVariableEntries(QString name, QString target, QString remove)
{ {
@ -65,8 +62,7 @@ QString stripVariableEntries(QString name, QString target, QString remove)
for (QString item : toRemove) { for (QString item : toRemove) {
bool removed = targetItems.removeOne(item); bool removed = targetItems.removeOne(item);
if (!removed) if (!removed)
qWarning() << "Entry" << item qWarning() << "Entry" << item << "could not be stripped from variable" << name;
<< "could not be stripped from variable" << name;
} }
return targetItems.join(delimiter); return targetItems.join(delimiter);
} }
@ -77,20 +73,10 @@ QProcessEnvironment CleanEnviroment()
QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment(); QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
QProcessEnvironment env; QProcessEnvironment env;
QStringList ignored = QStringList ignored = { "JAVA_ARGS", "CLASSPATH", "CONFIGPATH", "JAVA_HOME",
{ "JRE_HOME", "_JAVA_OPTIONS", "JAVA_OPTIONS", "JAVA_TOOL_OPTIONS" };
"JAVA_ARGS",
"CLASSPATH",
"CONFIGPATH",
"JAVA_HOME",
"JRE_HOME",
"_JAVA_OPTIONS",
"JAVA_OPTIONS",
"JAVA_TOOL_OPTIONS"
};
QStringList stripped = QStringList stripped = {
{
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
"LD_LIBRARY_PATH", "LD_LIBRARY_PATH",
"LD_PRELOAD", "LD_PRELOAD",
@ -98,12 +84,10 @@ QProcessEnvironment CleanEnviroment()
"QT_PLUGIN_PATH", "QT_PLUGIN_PATH",
"QT_FONTPATH" "QT_FONTPATH"
}; };
for(auto key: rawenv.keys()) for (auto key : rawenv.keys()) {
{
auto value = rawenv.value(key); auto value = rawenv.value(key);
// filter out dangerous java crap // filter out dangerous java crap
if(ignored.contains(key)) if (ignored.contains(key)) {
{
qDebug() << "Env: ignoring" << key << value; qDebug() << "Env: ignoring" << key << value;
continue; continue;
} }
@ -111,13 +95,11 @@ QProcessEnvironment CleanEnviroment()
// These are used to strip the original variables // These are used to strip the original variables
// If there is "LD_LIBRARY_PATH" and "LAUNCHER_LD_LIBRARY_PATH", we want to // If there is "LD_LIBRARY_PATH" and "LAUNCHER_LD_LIBRARY_PATH", we want to
// remove all values in "LAUNCHER_LD_LIBRARY_PATH" from "LD_LIBRARY_PATH" // remove all values in "LAUNCHER_LD_LIBRARY_PATH" from "LD_LIBRARY_PATH"
if(key.startsWith("LAUNCHER_")) if (key.startsWith("LAUNCHER_")) {
{
qDebug() << "Env: ignoring" << key << value; qDebug() << "Env: ignoring" << key << value;
continue; continue;
} }
if(stripped.contains(key)) if (stripped.contains(key)) {
{
QString newValue = stripVariableEntries(key, value, rawenv.value("LAUNCHER_" + key)); QString newValue = stripVariableEntries(key, value, rawenv.value("LAUNCHER_" + key));
qDebug() << "Env: stripped" << key << value << "to" << newValue; qDebug() << "Env: stripped" << key << value << "to" << newValue;
@ -125,8 +107,7 @@ QProcessEnvironment CleanEnviroment()
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
// Strip IBus // Strip IBus
// IBus is a Linux IME framework. For some reason, it breaks MC? // IBus is a Linux IME framework. For some reason, it breaks MC?
if (key == "XMODIFIERS" && value.contains(IBUS)) if (key == "XMODIFIERS" && value.contains(IBUS)) {
{
QString save = value; QString save = value;
value.replace(IBUS, ""); value.replace(IBUS, "");
qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value; qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
@ -137,8 +118,7 @@ QProcessEnvironment CleanEnviroment()
} }
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
// HACK: Workaround for QTBUG-42500 // HACK: Workaround for QTBUG-42500
if(!env.contains("LD_LIBRARY_PATH")) if (!env.contains("LD_LIBRARY_PATH")) {
{
env.insert("LD_LIBRARY_PATH", ""); env.insert("LD_LIBRARY_PATH", "");
} }
#endif #endif
@ -186,8 +166,7 @@ QStringList addJavasFromEnv(QList<QString> javas)
#else #else
QList<QString> javaPaths = env.split(QLatin1String(":")); QList<QString> javaPaths = env.split(QLatin1String(":"));
#endif #endif
for(QString i : javaPaths) for (QString i : javaPaths) {
{
javas.append(i); javas.append(i);
}; };
return javas; return javas;
@ -205,9 +184,8 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString
archType = "32"; archType = "32";
HKEY jreKey; HKEY jreKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.toStdWString().c_str(), 0, if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.toStdWString().c_str(), 0, KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) ==
KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS) ERROR_SUCCESS) {
{
// Read the current type version from the registry. // Read the current type version from the registry.
// This will be used to find any key that contains the JavaHome value. // This will be used to find any key that contains the JavaHome value.
@ -215,35 +193,26 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString
DWORD subKeyNameSize, numSubKeys, retCode; DWORD subKeyNameSize, numSubKeys, retCode;
// Get the number of subkeys // Get the number of subkeys
RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
NULL, NULL);
// Iterate until RegEnumKeyEx fails // Iterate until RegEnumKeyEx fails
if (numSubKeys > 0) if (numSubKeys > 0) {
{ for (DWORD i = 0; i < numSubKeys; i++) {
for (DWORD i = 0; i < numSubKeys; i++)
{
subKeyNameSize = 255; subKeyNameSize = 255;
retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, NULL);
NULL);
QString newSubkeyName = QString::fromWCharArray(subKeyName); QString newSubkeyName = QString::fromWCharArray(subKeyName);
if (retCode == ERROR_SUCCESS) if (retCode == ERROR_SUCCESS) {
{
// Now open the registry key for the version that we just got. // Now open the registry key for the version that we just got.
QString newKeyName = keyName + "\\" + newSubkeyName + subkeySuffix; QString newKeyName = keyName + "\\" + newSubkeyName + subkeySuffix;
HKEY newKey; HKEY newKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, newKeyName.toStdWString().c_str(), 0, if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, newKeyName.toStdWString().c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &newKey) ==
KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS) ERROR_SUCCESS) {
{
// Read the JavaHome value to find where Java is installed. // Read the JavaHome value to find where Java is installed.
DWORD valueSz = 0; DWORD valueSz = 0;
if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, &valueSz) == ERROR_SUCCESS) {
&valueSz) == ERROR_SUCCESS)
{
WCHAR* value = new WCHAR[valueSz]; WCHAR* value = new WCHAR[valueSz];
RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE *)value, RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE*)value, &valueSz);
&valueSz);
QString newValue = QString::fromWCharArray(value); QString newValue = QString::fromWCharArray(value);
delete[] value; delete[] value;
@ -253,8 +222,7 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString
javaVersion->id = newSubkeyName; javaVersion->id = newSubkeyName;
javaVersion->arch = archType; javaVersion->arch = archType;
javaVersion->path = javaVersion->path = QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe");
QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe");
javas.append(javaVersion); javas.append(javaVersion);
} }
@ -275,66 +243,56 @@ QList<QString> JavaUtils::FindJavaPaths()
QList<JavaInstallPtr> java_candidates; QList<JavaInstallPtr> java_candidates;
// Oracle // Oracle
QList<JavaInstallPtr> JRE64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> JRE64s =
KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome");
QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome");
KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome"); QList<JavaInstallPtr> JRE32s =
QList<JavaInstallPtr> JRE32s = this->FindJavaFromRegistryKey( this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome");
KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment", "JavaHome"); QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome");
QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit", "JavaHome");
// Oracle for Java 9 and newer // Oracle for Java 9 and newer
QList<JavaInstallPtr> NEWJRE64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> NEWJRE64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome");
KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome"); QList<JavaInstallPtr> NEWJDK64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome");
QList<JavaInstallPtr> NEWJDK64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> NEWJRE32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome");
KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome"); QList<JavaInstallPtr> NEWJDK32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome");
QList<JavaInstallPtr> NEWJRE32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JRE", "JavaHome");
QList<JavaInstallPtr> NEWJDK32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\JDK", "JavaHome");
// AdoptOpenJDK // AdoptOpenJDK
QList<JavaInstallPtr> ADOPTOPENJRE32s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTOPENJRE32s =
KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> ADOPTOPENJRE64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTOPENJRE64s =
KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JRE", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> ADOPTOPENJDK32s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTOPENJDK32s =
KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> ADOPTOPENJDK64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTOPENJDK64s =
KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI");
// Eclipse Foundation // Eclipse Foundation
QList<JavaInstallPtr> FOUNDATIONJDK32s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> FOUNDATIONJDK32s =
KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> FOUNDATIONJDK64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> FOUNDATIONJDK64s =
KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI");
// Eclipse Adoptium // Eclipse Adoptium
QList<JavaInstallPtr> ADOPTIUMJRE32s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTIUMJRE32s =
KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> ADOPTIUMJRE64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTIUMJRE64s =
KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JRE", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> ADOPTIUMJDK32s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTIUMJDK32s =
KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI");
QList<JavaInstallPtr> ADOPTIUMJDK64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ADOPTIUMJDK64s =
KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI");
// Microsoft // Microsoft
QList<JavaInstallPtr> MICROSOFTJDK64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> MICROSOFTJDK64s =
KEY_WOW64_64KEY, "SOFTWARE\\Microsoft\\JDK", "Path", "\\hotspot\\MSI"); this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Microsoft\\JDK", "Path", "\\hotspot\\MSI");
// Azul Zulu // Azul Zulu
QList<JavaInstallPtr> ZULU64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> ZULU64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath");
KEY_WOW64_64KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath"); QList<JavaInstallPtr> ZULU32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath");
QList<JavaInstallPtr> ZULU32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\Azul Systems\\Zulu", "InstallationPath");
// BellSoft Liberica // BellSoft Liberica
QList<JavaInstallPtr> LIBERICA64s = this->FindJavaFromRegistryKey( QList<JavaInstallPtr> LIBERICA64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath");
KEY_WOW64_64KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath"); QList<JavaInstallPtr> LIBERICA32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath");
QList<JavaInstallPtr> LIBERICA32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\BellSoft\\Liberica", "InstallationPath");
// List x64 before x86 // List x64 before x86
java_candidates.append(JRE64s); java_candidates.append(JRE64s);
@ -371,10 +329,8 @@ QList<QString> JavaUtils::FindJavaPaths()
java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path)); java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path));
QList<QString> candidates; QList<QString> candidates;
for(JavaInstallPtr java_candidate : java_candidates) for (JavaInstallPtr java_candidate : java_candidates) {
{ if (!candidates.contains(java_candidate->path)) {
if(!candidates.contains(java_candidate->path))
{
candidates.append(java_candidate->path); candidates.append(java_candidate->path);
} }
} }
@ -414,14 +370,12 @@ QList<QString> JavaUtils::FindJavaPaths()
{ {
QList<QString> javas; QList<QString> javas;
javas.append(this->GetDefaultJava()->path); javas.append(this->GetDefaultJava()->path);
auto scanJavaDir = [&](const QString & dirPath) auto scanJavaDir = [&](const QString& dirPath) {
{
QDir dir(dirPath); QDir dir(dirPath);
if (!dir.exists()) if (!dir.exists())
return; return;
auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for(auto & entry: entries) for (auto& entry : entries) {
{
QString prefix; QString prefix;
prefix = entry.canonicalFilePath(); prefix = entry.canonicalFilePath();
javas.append(FS::PathCombine(prefix, "jre/bin/java")); javas.append(FS::PathCombine(prefix, "jre/bin/java"));
@ -430,8 +384,7 @@ QList<QString> JavaUtils::FindJavaPaths()
}; };
// java installed in a snap is installed in the standard directory, but underneath $SNAP // java installed in a snap is installed in the standard directory, but underneath $SNAP
auto snap = qEnvironmentVariable("SNAP"); auto snap = qEnvironmentVariable("SNAP");
auto scanJavaDirs = [&](const QString & dirPath) auto scanJavaDirs = [&](const QString& dirPath) {
{
scanJavaDir(dirPath); scanJavaDir(dirPath);
if (!snap.isNull()) { if (!snap.isNull()) {
scanJavaDir(snap + dirPath); scanJavaDir(snap + dirPath);

View File

@ -27,8 +27,7 @@
QString stripVariableEntries(QString name, QString target, QString remove); QString stripVariableEntries(QString name, QString target, QString remove);
QProcessEnvironment CleanEnviroment(); QProcessEnvironment CleanEnviroment();
class JavaUtils : public QObject class JavaUtils : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
JavaUtils(); JavaUtils();

View File

@ -9,23 +9,18 @@ JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
{ {
m_string = javaVersionString; m_string = javaVersionString;
auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int auto getCapturedInteger = [](const QRegularExpressionMatch& match, const QString& what) -> int {
{
auto str = match.captured(what); auto str = match.captured(what);
if(str.isEmpty()) if (str.isEmpty()) {
{
return 0; return 0;
} }
return str.toInt(); return str.toInt();
}; };
QRegularExpression pattern; QRegularExpression pattern;
if(javaVersionString.startsWith("1.")) if (javaVersionString.startsWith("1.")) {
{
pattern = QRegularExpression("1[.](?<major>[0-9]+)([.](?<minor>[0-9]+))?(_(?<security>[0-9]+)?)?(-(?<prerelease>[a-zA-Z0-9]+))?"); pattern = QRegularExpression("1[.](?<major>[0-9]+)([.](?<minor>[0-9]+))?(_(?<security>[0-9]+)?)?(-(?<prerelease>[a-zA-Z0-9]+))?");
} } else {
else
{
pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?"); pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
} }
@ -50,8 +45,7 @@ QString JavaVersion::toString() const
bool JavaVersion::requiresPermGen() bool JavaVersion::requiresPermGen()
{ {
if(m_parseable) if (m_parseable) {
{
return m_major < 8; return m_major < 8;
} }
return true; return true;
@ -59,8 +53,7 @@ bool JavaVersion::requiresPermGen()
bool JavaVersion::operator<(const JavaVersion& rhs) bool JavaVersion::operator<(const JavaVersion& rhs)
{ {
if(m_parseable && rhs.m_parseable) if (m_parseable && rhs.m_parseable) {
{
auto major = m_major; auto major = m_major;
auto rmajor = rhs.m_major; auto rmajor = rhs.m_major;
@ -86,31 +79,25 @@ bool JavaVersion::operator<(const JavaVersion &rhs)
// everything else being equal, consider prerelease status // everything else being equal, consider prerelease status
bool thisPre = !m_prerelease.isEmpty(); bool thisPre = !m_prerelease.isEmpty();
bool rhsPre = !rhs.m_prerelease.isEmpty(); bool rhsPre = !rhs.m_prerelease.isEmpty();
if(thisPre && !rhsPre) if (thisPre && !rhsPre) {
{
// this is a prerelease and the other one isn't -> lesser // this is a prerelease and the other one isn't -> lesser
return true; return true;
} } else if (!thisPre && rhsPre) {
else if(!thisPre && rhsPre)
{
// this isn't a prerelease and the other one is -> greater // this isn't a prerelease and the other one is -> greater
return false; return false;
} } else if (thisPre && rhsPre) {
else if(thisPre && rhsPre)
{
// both are prereleases - use natural compare... // both are prereleases - use natural compare...
return StringUtils::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0; return StringUtils::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0;
} }
// neither is prerelease, so they are the same -> this cannot be less than rhs // neither is prerelease, so they are the same -> this cannot be less than rhs
return false; return false;
} } else
else return StringUtils::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0; return StringUtils::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0;
} }
bool JavaVersion::operator==(const JavaVersion& rhs) bool JavaVersion::operator==(const JavaVersion& rhs)
{ {
if(m_parseable && rhs.m_parseable) if (m_parseable && rhs.m_parseable) {
{
return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease; return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease;
} }
return m_string == rhs.m_string; return m_string == rhs.m_string;

View File

@ -10,9 +10,9 @@
#undef minor #undef minor
#endif #endif
class JavaVersion class JavaVersion {
{
friend class JavaVersionTest; friend class JavaVersionTest;
public: public:
JavaVersion() {} JavaVersion() {}
JavaVersion(const QString& rhs); JavaVersion(const QString& rhs);
@ -27,18 +27,10 @@ public:
QString toString() const; QString toString() const;
int major() int major() { return m_major; }
{ int minor() { return m_minor; }
return m_major; int security() { return m_security; }
}
int minor()
{
return m_minor;
}
int security()
{
return m_security;
}
private: private:
QString m_string; QString m_string;
int m_major = 0; int m_major = 0;

View File

@ -15,20 +15,16 @@
#pragma once #pragma once
#include "tasks/Task.h"
#include "MessageLevel.h" #include "MessageLevel.h"
#include "tasks/Task.h"
#include <QStringList> #include <QStringList>
class LaunchTask; class LaunchTask;
class LaunchStep: public Task class LaunchStep : public Task {
{
Q_OBJECT Q_OBJECT
public: /* methods */ public: /* methods */
explicit LaunchStep(LaunchTask *parent):Task(nullptr), m_parent(parent) explicit LaunchStep(LaunchTask* parent) : Task(nullptr), m_parent(parent) { bind(parent); };
{
bind(parent);
};
virtual ~LaunchStep(){}; virtual ~LaunchStep(){};
private: /* methods */ private: /* methods */

View File

@ -36,16 +36,16 @@
*/ */
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
#include "MessageLevel.h" #include <assert.h>
#include "java/JavaChecker.h" #include <QCoreApplication>
#include "tasks/Task.h"
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QEventLoop> #include <QEventLoop>
#include <QRegularExpression> #include <QRegularExpression>
#include <QCoreApplication>
#include <QStandardPaths> #include <QStandardPaths>
#include <assert.h> #include "MessageLevel.h"
#include "java/JavaChecker.h"
#include "tasks/Task.h"
void LaunchTask::init() void LaunchTask::init()
{ {
@ -59,9 +59,7 @@ shared_qobject_ptr<LaunchTask> LaunchTask::create(InstancePtr inst)
return proc; return proc;
} }
LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance) LaunchTask::LaunchTask(InstancePtr instance) : m_instance(instance) {}
{
}
void LaunchTask::appendStep(shared_qobject_ptr<LaunchStep> step) void LaunchTask::appendStep(shared_qobject_ptr<LaunchStep> step)
{ {
@ -76,8 +74,7 @@ void LaunchTask::prependStep(shared_qobject_ptr<LaunchStep> step)
void LaunchTask::executeTask() void LaunchTask::executeTask()
{ {
m_instance->setCrashed(false); m_instance->setCrashed(false);
if(!m_steps.size()) if (!m_steps.size()) {
{
state = LaunchTask::Finished; state = LaunchTask::Finished;
emitSucceeded(); emitSucceeded();
} }
@ -94,46 +91,35 @@ void LaunchTask::onReadyForLaunch()
void LaunchTask::onStepFinished() void LaunchTask::onStepFinished()
{ {
// initial -> just start the first step // initial -> just start the first step
if(currentStep == -1) if (currentStep == -1) {
{
currentStep++; currentStep++;
m_steps[currentStep]->start(); m_steps[currentStep]->start();
return; return;
} }
auto step = m_steps[currentStep]; auto step = m_steps[currentStep];
if(step->wasSuccessful()) if (step->wasSuccessful()) {
{
// end? // end?
if(currentStep == m_steps.size() - 1) if (currentStep == m_steps.size() - 1) {
{
finalizeSteps(true, QString()); finalizeSteps(true, QString());
} } else {
else
{
currentStep++; currentStep++;
step = m_steps[currentStep]; step = m_steps[currentStep];
step->start(); step->start();
} }
} } else {
else
{
finalizeSteps(false, step->failReason()); finalizeSteps(false, step->failReason());
} }
} }
void LaunchTask::finalizeSteps(bool successful, const QString& error) void LaunchTask::finalizeSteps(bool successful, const QString& error)
{ {
for(auto step = currentStep; step >= 0; step--) for (auto step = currentStep; step >= 0; step--) {
{
m_steps[step]->finalize(); m_steps[step]->finalize();
} }
if(successful) if (successful) {
{
emitSucceeded(); emitSucceeded();
} } else {
else
{
emitFailed(error); emitFailed(error);
} }
} }
@ -152,8 +138,7 @@ void LaunchTask::setCensorFilter(QMap<QString, QString> filter)
QString LaunchTask::censorPrivateInfo(QString in) QString LaunchTask::censorPrivateInfo(QString in)
{ {
auto iter = m_censorFilter.begin(); auto iter = m_censorFilter.begin();
while (iter != m_censorFilter.end()) while (iter != m_censorFilter.end()) {
{
in.replace(iter.key(), iter.value()); in.replace(iter.key(), iter.value());
iter++; iter++;
} }
@ -162,8 +147,7 @@ QString LaunchTask::censorPrivateInfo(QString in)
void LaunchTask::proceed() void LaunchTask::proceed()
{ {
if(state != LaunchTask::Waiting) if (state != LaunchTask::Waiting) {
{
return; return;
} }
m_steps[currentStep]->proceed(); m_steps[currentStep]->proceed();
@ -171,8 +155,7 @@ void LaunchTask::proceed()
bool LaunchTask::canAbort() const bool LaunchTask::canAbort() const
{ {
switch(state) switch (state) {
{
case LaunchTask::Aborted: case LaunchTask::Aborted:
case LaunchTask::Failed: case LaunchTask::Failed:
case LaunchTask::Finished: case LaunchTask::Finished:
@ -180,8 +163,7 @@ bool LaunchTask::canAbort() const
case LaunchTask::NotStarted: case LaunchTask::NotStarted:
return true; return true;
case LaunchTask::Running: case LaunchTask::Running:
case LaunchTask::Waiting: case LaunchTask::Waiting: {
{
auto step = m_steps[currentStep]; auto step = m_steps[currentStep];
return step->canAbort(); return step->canAbort();
} }
@ -191,28 +173,23 @@ bool LaunchTask::canAbort() const
bool LaunchTask::abort() bool LaunchTask::abort()
{ {
switch(state) switch (state) {
{
case LaunchTask::Aborted: case LaunchTask::Aborted:
case LaunchTask::Failed: case LaunchTask::Failed:
case LaunchTask::Finished: case LaunchTask::Finished:
return true; return true;
case LaunchTask::NotStarted: case LaunchTask::NotStarted: {
{
state = LaunchTask::Aborted; state = LaunchTask::Aborted;
emitFailed("Aborted"); emitFailed("Aborted");
return true; return true;
} }
case LaunchTask::Running: case LaunchTask::Running:
case LaunchTask::Waiting: case LaunchTask::Waiting: {
{
auto step = m_steps[currentStep]; auto step = m_steps[currentStep];
if(!step->canAbort()) if (!step->canAbort()) {
{
return false; return false;
} }
if(step->abort()) if (step->abort()) {
{
state = LaunchTask::Aborted; state = LaunchTask::Aborted;
return true; return true;
} }
@ -225,23 +202,22 @@ bool LaunchTask::abort()
shared_qobject_ptr<LogModel> LaunchTask::getLogModel() shared_qobject_ptr<LogModel> LaunchTask::getLogModel()
{ {
if(!m_logModel) if (!m_logModel) {
{
m_logModel.reset(new LogModel()); m_logModel.reset(new LogModel());
m_logModel->setMaxLines(m_instance->getConsoleMaxLines()); m_logModel->setMaxLines(m_instance->getConsoleMaxLines());
m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow()); m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
// FIXME: should this really be here? // FIXME: should this really be here?
m_logModel->setOverflowMessage(tr("Stopped watching the game log because the log length surpassed %1 lines.\n" m_logModel->setOverflowMessage(tr("Stopped watching the game log because the log length surpassed %1 lines.\n"
"You may have to fix your mods because the game is still logging to files and" "You may have to fix your mods because the game is still logging to files and"
" likely wasting harddrive space at an alarming rate!").arg(m_logModel->getMaxLines())); " likely wasting harddrive space at an alarming rate!")
.arg(m_logModel->getMaxLines()));
} }
return m_logModel; return m_logModel;
} }
void LaunchTask::onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel) void LaunchTask::onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel)
{ {
for (auto & line: lines) for (auto& line : lines) {
{
onLogLine(line, defaultLevel); onLogLine(line, defaultLevel);
} }
} }
@ -250,14 +226,12 @@ void LaunchTask::onLogLine(QString line, MessageLevel::Enum level)
{ {
// if the launcher part set a log level, use it // if the launcher part set a log level, use it
auto innerLevel = MessageLevel::fromLine(line); auto innerLevel = MessageLevel::fromLine(line);
if(innerLevel != MessageLevel::Unknown) if (innerLevel != MessageLevel::Unknown) {
{
level = innerLevel; level = innerLevel;
} }
// If the level is still undetermined, guess level // If the level is still undetermined, guess level
if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) {
{
level = m_instance->guessLevel(line, level); level = m_instance->guessLevel(line, level);
} }
@ -285,8 +259,7 @@ void LaunchTask::substituteVariables(QStringList &args) const
{ {
auto env = m_instance->createEnvironment(); auto env = m_instance->createEnvironment();
for (auto key : env.keys()) for (auto key : env.keys()) {
{
args.replaceInStrings("$" + key, env.value(key)); args.replaceInStrings("$" + key, env.value(key));
} }
} }
@ -295,8 +268,7 @@ void LaunchTask::substituteVariables(QString &cmd) const
{ {
auto env = m_instance->createEnvironment(); auto env = m_instance->createEnvironment();
for (auto key : env.keys()) for (auto key : env.keys()) {
{
cmd.replace("$" + key, env.value(key)); cmd.replace("$" + key, env.value(key));
} }
} }

View File

@ -36,31 +36,22 @@
*/ */
#pragma once #pragma once
#include <QProcess>
#include <QObjectPtr.h> #include <QObjectPtr.h>
#include "LogModel.h" #include <QProcess>
#include "BaseInstance.h" #include "BaseInstance.h"
#include "MessageLevel.h"
#include "LoggedProcess.h"
#include "LaunchStep.h" #include "LaunchStep.h"
#include "LogModel.h"
#include "LoggedProcess.h"
#include "MessageLevel.h"
class LaunchTask: public Task class LaunchTask : public Task {
{
Q_OBJECT Q_OBJECT
protected: protected:
explicit LaunchTask(InstancePtr instance); explicit LaunchTask(InstancePtr instance);
void init(); void init();
public: public:
enum State enum State { NotStarted, Running, Waiting, Failed, Aborted, Finished };
{
NotStarted,
Running,
Waiting,
Failed,
Aborted,
Finished
};
public: /* methods */ public: /* methods */
static shared_qobject_ptr<LaunchTask> create(InstancePtr inst); static shared_qobject_ptr<LaunchTask> create(InstancePtr inst);
@ -70,20 +61,11 @@ public: /* methods */
void prependStep(shared_qobject_ptr<LaunchStep> step); void prependStep(shared_qobject_ptr<LaunchStep> step);
void setCensorFilter(QMap<QString, QString> filter); void setCensorFilter(QMap<QString, QString> filter);
InstancePtr instance() InstancePtr instance() { return m_instance; }
{
return m_instance;
}
void setPid(qint64 pid) void setPid(qint64 pid) { m_pid = pid; }
{
m_pid = pid;
}
qint64 pid() qint64 pid() { return m_pid; }
{
return m_pid;
}
/** /**
* @brief prepare the process for launch (for multi-stage launch) * @brief prepare the process for launch (for multi-stage launch)

View File

@ -20,12 +20,10 @@ QVariant LogModel::data(const QModelIndex &index, int role) const
auto row = index.row(); auto row = index.row();
auto realRow = (row + m_firstLine) % m_maxLines; auto realRow = (row + m_firstLine) % m_maxLines;
if (role == Qt::DisplayRole || role == Qt::EditRole) if (role == Qt::DisplayRole || role == Qt::EditRole) {
{
return m_content[realRow].line; return m_content[realRow].line;
} }
if(role == LevelRole) if (role == LevelRole) {
{
return m_content[realRow].level; return m_content[realRow].level;
} }
@ -34,16 +32,13 @@ QVariant LogModel::data(const QModelIndex &index, int role) const
void LogModel::append(MessageLevel::Enum level, QString line) void LogModel::append(MessageLevel::Enum level, QString line)
{ {
if(m_suspended) if (m_suspended) {
{
return; return;
} }
int lineNum = (m_firstLine + m_numLines) % m_maxLines; int lineNum = (m_firstLine + m_numLines) % m_maxLines;
// overflow // overflow
if(m_numLines == m_maxLines) if (m_numLines == m_maxLines) {
{ if (m_stopOnOverflow) {
if(m_stopOnOverflow)
{
// nothing more to do, the buffer is full // nothing more to do, the buffer is full
return; return;
} }
@ -51,9 +46,7 @@ void LogModel::append(MessageLevel::Enum level, QString line)
m_firstLine = (m_firstLine + 1) % m_maxLines; m_firstLine = (m_firstLine + 1) % m_maxLines;
m_numLines--; m_numLines--;
endRemoveRows(); endRemoveRows();
} } else if (m_numLines == m_maxLines - 1 && m_stopOnOverflow) {
else if (m_numLines == m_maxLines - 1 && m_stopOnOverflow)
{
level = MessageLevel::Fatal; level = MessageLevel::Fatal;
line = m_overflowMessage; line = m_overflowMessage;
} }
@ -86,8 +79,7 @@ QString LogModel::toPlainText()
{ {
QString out; QString out;
out.reserve(m_numLines * 80); out.reserve(m_numLines * 80);
for(int i = 0; i < m_numLines; i++) for (int i = 0; i < m_numLines; i++) {
{
QString& line = m_content[(m_firstLine + i) % m_maxLines].line; QString& line = m_content[(m_firstLine + i) % m_maxLines].line;
out.append(line + '\n'); out.append(line + '\n');
} }
@ -98,13 +90,11 @@ QString LogModel::toPlainText()
void LogModel::setMaxLines(int maxLines) void LogModel::setMaxLines(int maxLines)
{ {
// no-op // no-op
if(maxLines == m_maxLines) if (maxLines == m_maxLines) {
{
return; return;
} }
// if it all still fits in the buffer, just resize it // if it all still fits in the buffer, just resize it
if(m_firstLine + m_numLines < m_maxLines) if (m_firstLine + m_numLines < m_maxLines) {
{
m_maxLines = maxLines; m_maxLines = maxLines;
m_content.resize(maxLines); m_content.resize(maxLines);
return; return;
@ -112,22 +102,17 @@ void LogModel::setMaxLines(int maxLines)
// otherwise, we need to reorganize the data because it crosses the wrap boundary // otherwise, we need to reorganize the data because it crosses the wrap boundary
QVector<entry> newContent; QVector<entry> newContent;
newContent.resize(maxLines); newContent.resize(maxLines);
if(m_numLines <= maxLines) if (m_numLines <= maxLines) {
{
// if it all fits in the new buffer, just copy it over // if it all fits in the new buffer, just copy it over
for(int i = 0; i < m_numLines; i++) for (int i = 0; i < m_numLines; i++) {
{
newContent[i] = m_content[(m_firstLine + i) % m_maxLines]; newContent[i] = m_content[(m_firstLine + i) % m_maxLines];
} }
m_content.swap(newContent); m_content.swap(newContent);
} } else {
else
{
// if it doesn't fit, part of the data needs to be thrown away (the oldest log messages) // if it doesn't fit, part of the data needs to be thrown away (the oldest log messages)
int lead = m_numLines - maxLines; int lead = m_numLines - maxLines;
beginRemoveRows(QModelIndex(), 0, lead - 1); beginRemoveRows(QModelIndex(), 0, lead - 1);
for(int i = 0; i < maxLines; i++) for (int i = 0; i < maxLines; i++) {
{
newContent[i] = m_content[(m_firstLine + lead + i) % m_maxLines]; newContent[i] = m_content[(m_firstLine + lead + i) % m_maxLines];
} }
m_numLines = m_maxLines; m_numLines = m_maxLines;
@ -155,8 +140,7 @@ void LogModel::setOverflowMessage(const QString& overflowMessage)
void LogModel::setLineWrap(bool state) void LogModel::setLineWrap(bool state)
{ {
if(m_lineWrap != state) if (m_lineWrap != state) {
{
m_lineWrap = state; m_lineWrap = state;
} }
} }

View File

@ -4,8 +4,7 @@
#include <QString> #include <QString>
#include "MessageLevel.h" #include "MessageLevel.h"
class LogModel : public QAbstractListModel class LogModel : public QAbstractListModel {
{
Q_OBJECT Q_OBJECT
public: public:
explicit LogModel(QObject* parent = 0); explicit LogModel(QObject* parent = 0);
@ -29,14 +28,10 @@ public:
void setLineWrap(bool state); void setLineWrap(bool state);
bool wrapLines() const; bool wrapLines() const;
enum Roles enum Roles { LevelRole = Qt::UserRole };
{
LevelRole = Qt::UserRole
};
private /* types */: private /* types */:
struct entry struct entry {
{
MessageLevel::Enum level; MessageLevel::Enum level;
QString line; QString line;
}; };

View File

@ -34,12 +34,12 @@
*/ */
#include "CheckJava.h" #include "CheckJava.h"
#include "java/JavaUtils.h"
#include <launch/LaunchTask.h>
#include <FileSystem.h> #include <FileSystem.h>
#include <QStandardPaths> #include <launch/LaunchTask.h>
#include <QFileInfo>
#include <sys.h> #include <sys.h>
#include <QFileInfo>
#include <QStandardPaths>
#include "java/JavaUtils.h"
void CheckJava::executeTask() void CheckJava::executeTask()
{ {
@ -49,31 +49,25 @@ void CheckJava::executeTask()
bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool(); bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool();
auto realJavaPath = QStandardPaths::findExecutable(m_javaPath); auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
if (realJavaPath.isEmpty()) if (realJavaPath.isEmpty()) {
{ if (perInstance) {
if (perInstance) emit logLine(QString("The java binary \"%1\" couldn't be found. Please fix the java path "
{ "override in the instance's settings or disable it.")
emit logLine( .arg(m_javaPath),
QString("The java binary \"%1\" couldn't be found. Please fix the java path "
"override in the instance's settings or disable it.").arg(m_javaPath),
MessageLevel::Warning); MessageLevel::Warning);
} } else {
else
{
emit logLine(QString("The java binary \"%1\" couldn't be found. Please set up java in " emit logLine(QString("The java binary \"%1\" couldn't be found. Please set up java in "
"the settings.").arg(m_javaPath), "the settings.")
.arg(m_javaPath),
MessageLevel::Warning); MessageLevel::Warning);
} }
emitFailed(QString("Java path is not valid.")); emitFailed(QString("Java path is not valid."));
return; return;
} } else {
else
{
emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::Launcher); emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::Launcher);
} }
if (JavaUtils::getJavaCheckPath().isEmpty()) if (JavaUtils::getJavaCheckPath().isEmpty()) {
{
const char* reason = QT_TR_NOOP("Java checker library could not be found. Please check your installation."); const char* reason = QT_TR_NOOP("Java checker library could not be found. Please check your installation.");
emit logLine(tr(reason), MessageLevel::Fatal); emit logLine(tr(reason), MessageLevel::Fatal);
emitFailed(tr(reason)); emitFailed(tr(reason));
@ -94,19 +88,15 @@ void CheckJava::executeTask()
m_javaSignature = hash.result().toHex(); m_javaSignature = hash.result().toHex();
// if timestamps are not the same, or something is missing, check! // if timestamps are not the same, or something is missing, check!
if (m_javaSignature != storedSignature || storedVersion.size() == 0 if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 ||
|| storedArchitecture.size() == 0 || storedRealArchitecture.size() == 0 storedRealArchitecture.size() == 0 || storedVendor.size() == 0) {
|| storedVendor.size() == 0)
{
m_JavaChecker.reset(new JavaChecker); m_JavaChecker.reset(new JavaChecker);
emit logLine(QString("Checking Java version..."), MessageLevel::Launcher); emit logLine(QString("Checking Java version..."), MessageLevel::Launcher);
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished); connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
m_JavaChecker->m_path = realJavaPath; m_JavaChecker->m_path = realJavaPath;
m_JavaChecker->performCheck(); m_JavaChecker->performCheck();
return; return;
} } else {
else
{
auto verString = instance->settings()->get("JavaVersion").toString(); auto verString = instance->settings()->get("JavaVersion").toString();
auto archString = instance->settings()->get("JavaArchitecture").toString(); auto archString = instance->settings()->get("JavaArchitecture").toString();
auto realArchString = settings->get("JavaRealArchitecture").toString(); auto realArchString = settings->get("JavaRealArchitecture").toString();
@ -118,10 +108,8 @@ void CheckJava::executeTask()
void CheckJava::checkJavaFinished(JavaCheckResult result) void CheckJava::checkJavaFinished(JavaCheckResult result)
{ {
switch (result.validity) switch (result.validity) {
{ case JavaCheckResult::Validity::Errored: {
case JavaCheckResult::Validity::Errored:
{
// Error message displayed if java can't start // Error message displayed if java can't start
emit logLine(QString("Could not start java:"), MessageLevel::Error); emit logLine(QString("Could not start java:"), MessageLevel::Error);
emit logLines(result.errorLog.split('\n'), MessageLevel::Error); emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
@ -129,16 +117,14 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
emitFailed(QString("Could not start java!")); emitFailed(QString("Could not start java!"));
return; return;
} }
case JavaCheckResult::Validity::ReturnedInvalidData: case JavaCheckResult::Validity::ReturnedInvalidData: {
{
emit logLine(QString("Java checker returned some invalid data we don't understand:"), MessageLevel::Error); emit logLine(QString("Java checker returned some invalid data we don't understand:"), MessageLevel::Error);
emit logLines(result.outLog.split('\n'), MessageLevel::Warning); emit logLines(result.outLog.split('\n'), MessageLevel::Warning);
emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher); emit logLine("\nMinecraft might not start properly.", MessageLevel::Launcher);
emitSucceeded(); emitSucceeded();
return; return;
} }
case JavaCheckResult::Validity::Valid: case JavaCheckResult::Validity::Valid: {
{
auto instance = m_parent->instance(); auto instance = m_parent->instance();
printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, result.realPlatform, result.javaVendor); printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, result.realPlatform, result.javaVendor);
instance->settings()->set("JavaVersion", result.javaVersion.toString()); instance->settings()->set("JavaVersion", result.javaVersion.toString());
@ -154,6 +140,7 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString& vendor) void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString& vendor)
{ {
emit logLine(QString("Java is version %1, using %2 (%3) architecture, from %4.\n\n") emit logLine(
.arg(version, architecture, realArchitecture, vendor), MessageLevel::Launcher); QString("Java is version %1, using %2 (%3) architecture, from %4.\n\n").arg(version, architecture, realArchitecture, vendor),
MessageLevel::Launcher);
} }

View File

@ -15,22 +15,18 @@
#pragma once #pragma once
#include <launch/LaunchStep.h>
#include <LoggedProcess.h> #include <LoggedProcess.h>
#include <java/JavaChecker.h> #include <java/JavaChecker.h>
#include <launch/LaunchStep.h>
class CheckJava: public LaunchStep class CheckJava : public LaunchStep {
{
Q_OBJECT Q_OBJECT
public: public:
explicit CheckJava(LaunchTask* parent) : LaunchStep(parent){}; explicit CheckJava(LaunchTask* parent) : LaunchStep(parent){};
virtual ~CheckJava(){}; virtual ~CheckJava(){};
virtual void executeTask(); virtual void executeTask();
virtual bool canAbort() const virtual bool canAbort() const { return false; }
{
return false;
}
private slots: private slots:
void checkJavaFinished(JavaCheckResult result); void checkJavaFinished(JavaCheckResult result);

View File

@ -13,13 +13,11 @@
* limitations under the License. * limitations under the License.
*/ */
#include "LookupServerAddress.h" #include "LookupServerAddress.h"
#include <launch/LaunchTask.h> #include <launch/LaunchTask.h>
LookupServerAddress::LookupServerAddress(LaunchTask *parent) : LookupServerAddress::LookupServerAddress(LaunchTask* parent) : LaunchStep(parent), m_dnsLookup(new QDnsLookup(this))
LaunchStep(parent), m_dnsLookup(new QDnsLookup(this))
{ {
connect(m_dnsLookup, &QDnsLookup::finished, this, &LookupServerAddress::on_dnsLookupFinished); connect(m_dnsLookup, &QDnsLookup::finished, this, &LookupServerAddress::on_dnsLookupFinished);
@ -51,27 +49,25 @@ void LookupServerAddress::executeTask()
void LookupServerAddress::on_dnsLookupFinished() void LookupServerAddress::on_dnsLookupFinished()
{ {
if (isFinished()) if (isFinished()) {
{
// Aborted // Aborted
return; return;
} }
if (m_dnsLookup->error() != QDnsLookup::NoError) if (m_dnsLookup->error() != QDnsLookup::NoError) {
{
emit logLine(QString("Failed to resolve server address (this is NOT an error!) %1: %2\n") emit logLine(QString("Failed to resolve server address (this is NOT an error!) %1: %2\n")
.arg(m_dnsLookup->name(), m_dnsLookup->errorString()), MessageLevel::Launcher); .arg(m_dnsLookup->name(), m_dnsLookup->errorString()),
MessageLevel::Launcher);
resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch
// and leave it up to minecraft to fail (or maybe not) when connecting // and leave it up to minecraft to fail (or maybe not) when connecting
return; return;
} }
const auto records = m_dnsLookup->serviceRecords(); const auto records = m_dnsLookup->serviceRecords();
if (records.empty()) if (records.empty()) {
{ emit logLine(QString("Failed to resolve server address %1: the DNS lookup succeeded, but no records were returned.\n")
emit logLine( .arg(m_dnsLookup->name()),
QString("Failed to resolve server address %1: the DNS lookup succeeded, but no records were returned.\n") MessageLevel::Warning);
.arg(m_dnsLookup->name()), MessageLevel::Warning);
resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch resolve(m_lookupAddress, 25565); // Technically the task failed, however, we don't abort the launch
// and leave it up to minecraft to fail (or maybe not) when connecting // and leave it up to minecraft to fail (or maybe not) when connecting
return; return;
@ -80,8 +76,9 @@ void LookupServerAddress::on_dnsLookupFinished()
const auto& firstRecord = records.at(0); const auto& firstRecord = records.at(0);
quint16 port = firstRecord.port(); quint16 port = firstRecord.port();
emit logLine(QString("Resolved server address %1 to %2 with port %3\n").arg( emit logLine(
m_dnsLookup->name(), firstRecord.target(), QString::number(port)),MessageLevel::Launcher); QString("Resolved server address %1 to %2 with port %3\n").arg(m_dnsLookup->name(), firstRecord.target(), QString::number(port)),
MessageLevel::Launcher);
resolve(firstRecord.target(), port); resolve(firstRecord.target(), port);
} }

View File

@ -15,8 +15,8 @@
#pragma once #pragma once
#include <launch/LaunchStep.h>
#include <QObjectPtr.h> #include <QObjectPtr.h>
#include <launch/LaunchStep.h>
#include <QDnsLookup> #include <QDnsLookup>
#include "minecraft/launch/MinecraftServerTarget.h" #include "minecraft/launch/MinecraftServerTarget.h"
@ -29,10 +29,7 @@ public:
virtual void executeTask(); virtual void executeTask();
virtual bool abort(); virtual bool abort();
virtual bool canAbort() const virtual bool canAbort() const { return true; }
{
return true;
}
void setLookupAddress(const QString& lookupAddress); void setLookupAddress(const QString& lookupAddress);
void setOutputAddressPtr(MinecraftServerTargetPtr output); void setOutputAddressPtr(MinecraftServerTargetPtr output);

View File

@ -65,31 +65,22 @@ void PostLaunchCommand::executeTask()
void PostLaunchCommand::on_state(LoggedProcess::State state) void PostLaunchCommand::on_state(LoggedProcess::State state)
{ {
auto getError = [&]() auto getError = [&]() { return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode()); };
{ switch (state) {
return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
};
switch(state)
{
case LoggedProcess::Aborted: case LoggedProcess::Aborted:
case LoggedProcess::Crashed: case LoggedProcess::Crashed:
case LoggedProcess::FailedToStart: case LoggedProcess::FailedToStart: {
{
auto error = getError(); auto error = getError();
emit logLine(error, MessageLevel::Fatal); emit logLine(error, MessageLevel::Fatal);
emitFailed(error); emitFailed(error);
return; return;
} }
case LoggedProcess::Finished: case LoggedProcess::Finished: {
{ if (m_process.exitCode() != 0) {
if(m_process.exitCode() != 0)
{
auto error = getError(); auto error = getError();
emit logLine(error, MessageLevel::Fatal); emit logLine(error, MessageLevel::Fatal);
emitFailed(error); emitFailed(error);
} } else {
else
{
emit logLine(tr("Post-Launch command ran successfully.\n\n"), MessageLevel::Launcher); emit logLine(tr("Post-Launch command ran successfully.\n\n"), MessageLevel::Launcher);
emitSucceeded(); emitSucceeded();
} }
@ -107,8 +98,7 @@ void PostLaunchCommand::setWorkingDirectory(const QString &wd)
bool PostLaunchCommand::abort() bool PostLaunchCommand::abort()
{ {
auto state = m_process.state(); auto state = m_process.state();
if (state == LoggedProcess::Running || state == LoggedProcess::Starting) if (state == LoggedProcess::Running || state == LoggedProcess::Starting) {
{
m_process.kill(); m_process.kill();
} }
return true; return true;

View File

@ -15,11 +15,10 @@
#pragma once #pragma once
#include <launch/LaunchStep.h>
#include <LoggedProcess.h> #include <LoggedProcess.h>
#include <launch/LaunchStep.h>
class PostLaunchCommand: public LaunchStep class PostLaunchCommand : public LaunchStep {
{
Q_OBJECT Q_OBJECT
public: public:
explicit PostLaunchCommand(LaunchTask* parent); explicit PostLaunchCommand(LaunchTask* parent);
@ -27,10 +26,7 @@ public:
virtual void executeTask(); virtual void executeTask();
virtual bool abort(); virtual bool abort();
virtual bool canAbort() const virtual bool canAbort() const { return true; }
{
return true;
}
void setWorkingDirectory(const QString& wd); void setWorkingDirectory(const QString& wd);
private slots: private slots:
void on_state(LoggedProcess::State state); void on_state(LoggedProcess::State state);

View File

@ -65,31 +65,22 @@ void PreLaunchCommand::executeTask()
void PreLaunchCommand::on_state(LoggedProcess::State state) void PreLaunchCommand::on_state(LoggedProcess::State state)
{ {
auto getError = [&]() auto getError = [&]() { return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode()); };
{ switch (state) {
return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
};
switch(state)
{
case LoggedProcess::Aborted: case LoggedProcess::Aborted:
case LoggedProcess::Crashed: case LoggedProcess::Crashed:
case LoggedProcess::FailedToStart: case LoggedProcess::FailedToStart: {
{
auto error = getError(); auto error = getError();
emit logLine(error, MessageLevel::Fatal); emit logLine(error, MessageLevel::Fatal);
emitFailed(error); emitFailed(error);
return; return;
} }
case LoggedProcess::Finished: case LoggedProcess::Finished: {
{ if (m_process.exitCode() != 0) {
if(m_process.exitCode() != 0)
{
auto error = getError(); auto error = getError();
emit logLine(error, MessageLevel::Fatal); emit logLine(error, MessageLevel::Fatal);
emitFailed(error); emitFailed(error);
} } else {
else
{
emit logLine(tr("Pre-Launch command ran successfully.\n\n"), MessageLevel::Launcher); emit logLine(tr("Pre-Launch command ran successfully.\n\n"), MessageLevel::Launcher);
emitSucceeded(); emitSucceeded();
} }
@ -107,8 +98,7 @@ void PreLaunchCommand::setWorkingDirectory(const QString &wd)
bool PreLaunchCommand::abort() bool PreLaunchCommand::abort()
{ {
auto state = m_process.state(); auto state = m_process.state();
if (state == LoggedProcess::Running || state == LoggedProcess::Starting) if (state == LoggedProcess::Running || state == LoggedProcess::Starting) {
{
m_process.kill(); m_process.kill();
} }
return true; return true;

View File

@ -15,11 +15,10 @@
#pragma once #pragma once
#include "launch/LaunchStep.h"
#include "LoggedProcess.h" #include "LoggedProcess.h"
#include "launch/LaunchStep.h"
class PreLaunchCommand: public LaunchStep class PreLaunchCommand : public LaunchStep {
{
Q_OBJECT Q_OBJECT
public: public:
explicit PreLaunchCommand(LaunchTask* parent); explicit PreLaunchCommand(LaunchTask* parent);
@ -27,10 +26,7 @@ public:
virtual void executeTask(); virtual void executeTask();
virtual bool abort(); virtual bool abort();
virtual bool canAbort() const virtual bool canAbort() const { return true; }
{
return true;
}
void setWorkingDirectory(const QString& wd); void setWorkingDirectory(const QString& wd);
private slots: private slots:
void on_state(LoggedProcess::State state); void on_state(LoggedProcess::State state);

View File

@ -20,16 +20,12 @@
#include <launch/LaunchStep.h> #include <launch/LaunchStep.h>
class QuitAfterGameStop: public LaunchStep class QuitAfterGameStop : public LaunchStep {
{
Q_OBJECT Q_OBJECT
public: public:
explicit QuitAfterGameStop(LaunchTask* parent) : LaunchStep(parent){}; explicit QuitAfterGameStop(LaunchTask* parent) : LaunchStep(parent){};
virtual ~QuitAfterGameStop(){}; virtual ~QuitAfterGameStop(){};
virtual void executeTask(); virtual void executeTask();
virtual bool canAbort() const virtual bool canAbort() const { return false; }
{
return false;
}
}; };

View File

@ -15,16 +15,15 @@
#pragma once #pragma once
#include <launch/LaunchStep.h>
#include <LoggedProcess.h> #include <LoggedProcess.h>
#include <java/JavaChecker.h> #include <java/JavaChecker.h>
#include <launch/LaunchStep.h>
/* /*
* FIXME: maybe do not export * FIXME: maybe do not export
*/ */
class TextPrint: public LaunchStep class TextPrint : public LaunchStep {
{
Q_OBJECT Q_OBJECT
public: public:
explicit TextPrint(LaunchTask* parent, const QStringList& lines, MessageLevel::Enum level); explicit TextPrint(LaunchTask* parent, const QStringList& lines, MessageLevel::Enum level);

View File

@ -18,14 +18,12 @@
void Update::executeTask() void Update::executeTask()
{ {
if(m_aborted) if (m_aborted) {
{
emitFailed(tr("Task aborted.")); emitFailed(tr("Task aborted."));
return; return;
} }
m_updateTask.reset(m_parent->instance()->createUpdateTask(m_mode)); m_updateTask.reset(m_parent->instance()->createUpdateTask(m_mode));
if(m_updateTask) if (m_updateTask) {
{
connect(m_updateTask.get(), &Task::finished, this, &Update::updateFinished); connect(m_updateTask.get(), &Task::finished, this, &Update::updateFinished);
connect(m_updateTask.get(), &Task::progress, this, &Update::setProgress); connect(m_updateTask.get(), &Task::progress, this, &Update::setProgress);
connect(m_updateTask.get(), &Task::stepProgress, this, &Update::propagateStepProgress); connect(m_updateTask.get(), &Task::stepProgress, this, &Update::propagateStepProgress);
@ -44,13 +42,10 @@ void Update::proceed()
void Update::updateFinished() void Update::updateFinished()
{ {
if(m_updateTask->wasSuccessful()) if (m_updateTask->wasSuccessful()) {
{
m_updateTask.reset(); m_updateTask.reset();
emitSucceeded(); emitSucceeded();
} } else {
else
{
QString reason = tr("Instance update failed because: %1\n\n").arg(m_updateTask->failReason()); QString reason = tr("Instance update failed because: %1\n\n").arg(m_updateTask->failReason());
m_updateTask.reset(); m_updateTask.reset();
emit logLine(reason, MessageLevel::Fatal); emit logLine(reason, MessageLevel::Fatal);
@ -60,21 +55,17 @@ void Update::updateFinished()
bool Update::canAbort() const bool Update::canAbort() const
{ {
if(m_updateTask) if (m_updateTask) {
{
return m_updateTask->canAbort(); return m_updateTask->canAbort();
} }
return true; return true;
} }
bool Update::abort() bool Update::abort()
{ {
m_aborted = true; m_aborted = true;
if(m_updateTask) if (m_updateTask) {
{ if (m_updateTask->canAbort()) {
if(m_updateTask->canAbort())
{
return m_updateTask->abort(); return m_updateTask->abort();
} }
} }

View File

@ -15,15 +15,14 @@
#pragma once #pragma once
#include <launch/LaunchStep.h>
#include <QObjectPtr.h>
#include <LoggedProcess.h> #include <LoggedProcess.h>
#include <QObjectPtr.h>
#include <java/JavaChecker.h> #include <java/JavaChecker.h>
#include <launch/LaunchStep.h>
#include <net/Mode.h> #include <net/Mode.h>
// FIXME: stupid. should be defined by the instance type? or even completely abstracted away... // FIXME: stupid. should be defined by the instance type? or even completely abstracted away...
class Update: public LaunchStep class Update : public LaunchStep {
{
Q_OBJECT Q_OBJECT
public: public:
explicit Update(LaunchTask* parent, Net::Mode mode) : LaunchStep(parent), m_mode(mode){}; explicit Update(LaunchTask* parent, Net::Mode mode) : LaunchStep(parent), m_mode(mode){};

View File

@ -40,15 +40,14 @@
// #define BREAK_RETURN // #define BREAK_RETURN
#ifdef BREAK_INFINITE_LOOP #ifdef BREAK_INFINITE_LOOP
#include <thread>
#include <chrono> #include <chrono>
#include <thread>
#endif #endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#ifdef BREAK_INFINITE_LOOP #ifdef BREAK_INFINITE_LOOP
while(true) while (true) {
{
std::this_thread::sleep_for(std::chrono::milliseconds(250)); std::this_thread::sleep_for(std::chrono::milliseconds(250));
} }
#endif #endif
@ -67,11 +66,9 @@ int main(int argc, char *argv[])
// initialize Qt // initialize Qt
Application app(argc, argv); Application app(argc, argv);
switch (app.status()) switch (app.status()) {
{
case Application::StartingUp: case Application::StartingUp:
case Application::Initialized: case Application::Initialized: {
{
Q_INIT_RESOURCE(multimc); Q_INIT_RESOURCE(multimc);
Q_INIT_RESOURCE(backgrounds); Q_INIT_RESOURCE(backgrounds);
Q_INIT_RESOURCE(documents); Q_INIT_RESOURCE(documents);

View File

@ -15,50 +15,36 @@
#include "BaseEntity.h" #include "BaseEntity.h"
#include "Json.h"
#include "net/ApiDownload.h" #include "net/ApiDownload.h"
#include "net/HttpMetaCache.h" #include "net/HttpMetaCache.h"
#include "net/NetJob.h" #include "net/NetJob.h"
#include "Json.h"
#include "BuildConfig.h"
#include "Application.h" #include "Application.h"
#include "BuildConfig.h"
class ParsingValidator : public Net::Validator class ParsingValidator : public Net::Validator {
{
public: /* con/des */ public: /* con/des */
ParsingValidator(Meta::BaseEntity *entity) : m_entity(entity) ParsingValidator(Meta::BaseEntity* entity) : m_entity(entity){};
{ virtual ~ParsingValidator(){};
};
virtual ~ParsingValidator()
{
};
public: /* methods */ public: /* methods */
bool init(QNetworkRequest &) override bool init(QNetworkRequest&) override { return true; }
{
return true;
}
bool write(QByteArray& data) override bool write(QByteArray& data) override
{ {
this->m_data.append(data); this->m_data.append(data);
return true; return true;
} }
bool abort() override bool abort() override { return true; }
{
return true;
}
bool validate(QNetworkReply&) override bool validate(QNetworkReply&) override
{ {
auto fname = m_entity->localFilename(); auto fname = m_entity->localFilename();
try try {
{
auto doc = Json::requireDocument(m_data, fname); auto doc = Json::requireDocument(m_data, fname);
auto obj = Json::requireObject(doc, fname); auto obj = Json::requireObject(doc, fname);
m_entity->parse(obj); m_entity->parse(obj);
return true; return true;
} } catch (const Exception& e) {
catch (const Exception &e)
{
qWarning() << "Unable to parse response:" << e.cause(); qWarning() << "Unable to parse response:" << e.cause();
return false; return false;
} }
@ -69,20 +55,15 @@ private: /* data */
Meta::BaseEntity* m_entity; Meta::BaseEntity* m_entity;
}; };
Meta::BaseEntity::~BaseEntity() Meta::BaseEntity::~BaseEntity() {}
{
}
QUrl Meta::BaseEntity::url() const QUrl Meta::BaseEntity::url() const
{ {
auto s = APPLICATION->settings(); auto s = APPLICATION->settings();
QString metaOverride = s->get("MetaURLOverride").toString(); QString metaOverride = s->get("MetaURLOverride").toString();
if(metaOverride.isEmpty()) if (metaOverride.isEmpty()) {
{
return QUrl(BuildConfig.META_URL).resolved(localFilename()); return QUrl(BuildConfig.META_URL).resolved(localFilename());
} } else {
else
{
return QUrl(metaOverride).resolved(localFilename()); return QUrl(metaOverride).resolved(localFilename());
} }
} }
@ -90,20 +71,16 @@ QUrl Meta::BaseEntity::url() const
bool Meta::BaseEntity::loadLocalFile() bool Meta::BaseEntity::loadLocalFile()
{ {
const QString fname = QDir("meta").absoluteFilePath(localFilename()); const QString fname = QDir("meta").absoluteFilePath(localFilename());
if (!QFile::exists(fname)) if (!QFile::exists(fname)) {
{
return false; return false;
} }
// TODO: check if the file has the expected checksum // TODO: check if the file has the expected checksum
try try {
{
auto doc = Json::requireDocument(fname, fname); auto doc = Json::requireDocument(fname, fname);
auto obj = Json::requireObject(doc, fname); auto obj = Json::requireObject(doc, fname);
parse(obj); parse(obj);
return true; return true;
} } catch (const Exception& e) {
catch (const Exception &e)
{
qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause()); qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause());
// just make sure it's gone and we never consider it again. // just make sure it's gone and we never consider it again.
QFile::remove(fname); QFile::remove(fname);
@ -114,16 +91,13 @@ bool Meta::BaseEntity::loadLocalFile()
void Meta::BaseEntity::load(Net::Mode loadType) void Meta::BaseEntity::load(Net::Mode loadType)
{ {
// load local file if nothing is loaded yet // load local file if nothing is loaded yet
if(!isLoaded()) if (!isLoaded()) {
{ if (loadLocalFile()) {
if(loadLocalFile())
{
m_loadStatus = LoadStatus::Local; m_loadStatus = LoadStatus::Local;
} }
} }
// if we need remote update, run the update task // if we need remote update, run the update task
if(loadType == Net::Mode::Offline || !shouldStartRemoteUpdate()) if (loadType == Net::Mode::Offline || !shouldStartRemoteUpdate()) {
{
return; return;
} }
m_updateTask.reset(new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()), APPLICATION->network())); m_updateTask.reset(new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()), APPLICATION->network()));
@ -138,14 +112,12 @@ void Meta::BaseEntity::load(Net::Mode loadType)
dl->addValidator(new ParsingValidator(this)); dl->addValidator(new ParsingValidator(this));
m_updateTask->addNetAction(dl); m_updateTask->addNetAction(dl);
m_updateStatus = UpdateStatus::InProgress; m_updateStatus = UpdateStatus::InProgress;
QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]() QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]() {
{
m_loadStatus = LoadStatus::Remote; m_loadStatus = LoadStatus::Remote;
m_updateStatus = UpdateStatus::Succeeded; m_updateStatus = UpdateStatus::Succeeded;
m_updateTask.reset(); m_updateTask.reset();
}); });
QObject::connect(m_updateTask.get(), &NetJob::failed, [&]() QObject::connect(m_updateTask.get(), &NetJob::failed, [&]() {
{
m_updateStatus = UpdateStatus::Failed; m_updateStatus = UpdateStatus::Failed;
m_updateTask.reset(); m_updateTask.reset();
}); });
@ -165,8 +137,7 @@ bool Meta::BaseEntity::shouldStartRemoteUpdate() const
Task::Ptr Meta::BaseEntity::getCurrentTask() Task::Ptr Meta::BaseEntity::getCurrentTask()
{ {
if(m_updateStatus == UpdateStatus::InProgress) if (m_updateStatus == UpdateStatus::InProgress) {
{
return m_updateTask; return m_updateTask;
} }
return nullptr; return nullptr;

View File

@ -22,25 +22,12 @@
#include "net/Mode.h" #include "net/Mode.h"
#include "net/NetJob.h" #include "net/NetJob.h"
namespace Meta namespace Meta {
{ class BaseEntity {
class BaseEntity
{
public: /* types */ public: /* types */
using Ptr = std::shared_ptr<BaseEntity>; using Ptr = std::shared_ptr<BaseEntity>;
enum class LoadStatus enum class LoadStatus { NotLoaded, Local, Remote };
{ enum class UpdateStatus { NotDone, InProgress, Failed, Succeeded };
NotLoaded,
Local,
Remote
};
enum class UpdateStatus
{
NotDone,
InProgress,
Failed,
Succeeded
};
public: public:
virtual ~BaseEntity(); virtual ~BaseEntity();
@ -64,4 +51,4 @@ private:
UpdateStatus m_updateStatus = UpdateStatus::NotDone; UpdateStatus m_updateStatus = UpdateStatus::NotDone;
NetJob::Ptr m_updateTask; NetJob::Ptr m_updateTask;
}; };
} } // namespace Meta

View File

@ -15,20 +15,14 @@
#include "Index.h" #include "Index.h"
#include "VersionList.h"
#include "JsonFormat.h" #include "JsonFormat.h"
#include "VersionList.h"
namespace Meta namespace Meta {
{ Index::Index(QObject* parent) : QAbstractListModel(parent) {}
Index::Index(QObject *parent) Index::Index(const QVector<VersionList::Ptr>& lists, QObject* parent) : QAbstractListModel(parent), m_lists(lists)
: QAbstractListModel(parent)
{
}
Index::Index(const QVector<VersionList::Ptr> &lists, QObject *parent)
: QAbstractListModel(parent), m_lists(lists)
{
for (int i = 0; i < m_lists.size(); ++i)
{ {
for (int i = 0; i < m_lists.size(); ++i) {
m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i)); m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
connectVersionList(i, m_lists.at(i)); connectVersionList(i, m_lists.at(i));
} }
@ -36,23 +30,24 @@ Index::Index(const QVector<VersionList::Ptr> &lists, QObject *parent)
QVariant Index::data(const QModelIndex& index, int role) const QVariant Index::data(const QModelIndex& index, int role) const
{ {
if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size()) if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size()) {
{
return QVariant(); return QVariant();
} }
VersionList::Ptr list = m_lists.at(index.row()); VersionList::Ptr list = m_lists.at(index.row());
switch (role) switch (role) {
{
case Qt::DisplayRole: case Qt::DisplayRole:
if (index.column() == 0) { if (index.column() == 0) {
return list->humanReadable(); return list->humanReadable();
} else { } else {
break; break;
} }
case UidRole: return list->uid(); case UidRole:
case NameRole: return list->name(); return list->uid();
case ListPtrRole: return QVariant::fromValue(list); case NameRole:
return list->name();
case ListPtrRole:
return QVariant::fromValue(list);
} }
return QVariant(); return QVariant();
} }
@ -66,12 +61,9 @@ int Index::columnCount(const QModelIndex &parent) const
} }
QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
{ {
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) {
{
return tr("Name"); return tr("Name");
} } else {
else
{
return QVariant(); return QVariant();
} }
} }
@ -84,8 +76,7 @@ bool Index::hasUid(const QString &uid) const
VersionList::Ptr Index::get(const QString& uid) VersionList::Ptr Index::get(const QString& uid)
{ {
VersionList::Ptr out = m_uids.value(uid, nullptr); VersionList::Ptr out = m_uids.value(uid, nullptr);
if(!out) if (!out) {
{
out = std::make_shared<VersionList>(uid); out = std::make_shared<VersionList>(uid);
m_uids[uid] = out; m_uids[uid] = out;
} }
@ -107,27 +98,19 @@ void Index::merge(const std::shared_ptr<Index> &other)
{ {
const QVector<VersionList::Ptr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists; const QVector<VersionList::Ptr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
// initial load, no need to merge // initial load, no need to merge
if (m_lists.isEmpty()) if (m_lists.isEmpty()) {
{
beginResetModel(); beginResetModel();
m_lists = lists; m_lists = lists;
for (int i = 0; i < lists.size(); ++i) for (int i = 0; i < lists.size(); ++i) {
{
m_uids.insert(lists.at(i)->uid(), lists.at(i)); m_uids.insert(lists.at(i)->uid(), lists.at(i));
connectVersionList(i, lists.at(i)); connectVersionList(i, lists.at(i));
} }
endResetModel(); endResetModel();
} } else {
else for (const VersionList::Ptr& list : lists) {
{ if (m_uids.contains(list->uid())) {
for (const VersionList::Ptr &list : lists)
{
if (m_uids.contains(list->uid()))
{
m_uids[list->uid()]->mergeFromIndex(list); m_uids[list->uid()]->mergeFromIndex(list);
} } else {
else
{
beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size()); beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size());
connectVersionList(m_lists.size(), list); connectVersionList(m_lists.size(), list);
m_lists.append(list); m_lists.append(list);
@ -140,9 +123,7 @@ void Index::merge(const std::shared_ptr<Index> &other)
void Index::connectVersionList(const int row, const VersionList::Ptr& list) void Index::connectVersionList(const int row, const VersionList::Ptr& list)
{ {
connect(list.get(), &VersionList::nameChanged, this, [this, row]() connect(list.get(), &VersionList::nameChanged, this,
{ [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole); });
emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole);
});
}
} }
} // namespace Meta

View File

@ -23,22 +23,15 @@
class Task; class Task;
namespace Meta namespace Meta {
{
class Index : public QAbstractListModel, public BaseEntity class Index : public QAbstractListModel, public BaseEntity {
{
Q_OBJECT Q_OBJECT
public: public:
explicit Index(QObject* parent = nullptr); explicit Index(QObject* parent = nullptr);
explicit Index(const QVector<VersionList::Ptr>& lists, QObject* parent = nullptr); explicit Index(const QVector<VersionList::Ptr>& lists, QObject* parent = nullptr);
enum enum { UidRole = Qt::UserRole, NameRole, ListPtrRole };
{
UidRole = Qt::UserRole,
NameRole,
ListPtrRole
};
QVariant data(const QModelIndex& index, int role) const override; QVariant data(const QModelIndex& index, int role) const override;
int rowCount(const QModelIndex& parent) const override; int rowCount(const QModelIndex& parent) const override;
@ -64,5 +57,4 @@ private:
void connectVersionList(const int row, const VersionList::Ptr& list); void connectVersionList(const int row, const VersionList::Ptr& list);
}; };
} } // namespace Meta

View File

@ -16,8 +16,8 @@
#include "JsonFormat.h" #include "JsonFormat.h"
// FIXME: remove this from here... somehow // FIXME: remove this from here... somehow
#include "minecraft/OneSixVersionFormat.h"
#include "Json.h" #include "Json.h"
#include "minecraft/OneSixVersionFormat.h"
#include "Index.h" #include "Index.h"
#include "Version.h" #include "Version.h"
@ -25,8 +25,7 @@
using namespace Json; using namespace Json;
namespace Meta namespace Meta {
{
MetadataVersion currentFormatVersion() MetadataVersion currentFormatVersion()
{ {
@ -39,8 +38,7 @@ static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages"); const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
QVector<VersionList::Ptr> lists; QVector<VersionList::Ptr> lists;
lists.reserve(objects.size()); lists.reserve(objects.size());
std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj) std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject& obj) {
{
VersionList::Ptr list = std::make_shared<VersionList>(requireString(obj, "uid")); VersionList::Ptr list = std::make_shared<VersionList>(requireString(obj, "uid"));
list->setName(ensureString(obj, "name", QString())); list->setName(ensureString(obj, "name", QString()));
return list; return list;
@ -67,9 +65,8 @@ static Version::Ptr parseVersionInternal(const QJsonObject &obj)
{ {
Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj); Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj);
version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj), version->setData(OneSixVersionFormat::versionFileFromJson(
QString("%1/%2.json").arg(version->uid(), version->version()), QJsonDocument(obj), QString("%1/%2.json").arg(version->uid(), version->version()), obj.contains("order")));
obj.contains("order")));
return version; return version;
} }
@ -81,8 +78,7 @@ static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj)
const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions"); const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
QVector<Version::Ptr> versions; QVector<Version::Ptr> versions;
versions.reserve(versionsRaw.size()); versions.reserve(versionsRaw.size());
std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj) std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject& vObj) {
{
auto version = parseCommonVersion(uid, vObj); auto version = parseCommonVersion(uid, vObj);
version->setProvidesRecommendations(); version->setProvidesRecommendations();
return version; return version;
@ -94,23 +90,18 @@ static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj)
return list; return list;
} }
MetadataVersion parseFormatVersion(const QJsonObject& obj, bool required) MetadataVersion parseFormatVersion(const QJsonObject& obj, bool required)
{ {
if (!obj.contains("formatVersion")) if (!obj.contains("formatVersion")) {
{ if (required) {
if(required)
{
return MetadataVersion::Invalid; return MetadataVersion::Invalid;
} }
return MetadataVersion::InitialRelease; return MetadataVersion::InitialRelease;
} }
if (!obj.value("formatVersion").isDouble()) if (!obj.value("formatVersion").isDouble()) {
{
return MetadataVersion::Invalid; return MetadataVersion::Invalid;
} }
switch(obj.value("formatVersion").toInt()) switch (obj.value("formatVersion").toInt()) {
{
case 0: case 0:
case 1: case 1:
return MetadataVersion::InitialRelease; return MetadataVersion::InitialRelease;
@ -121,8 +112,7 @@ MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required)
void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version) void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version)
{ {
if(version == MetadataVersion::Invalid) if (version == MetadataVersion::Invalid) {
{
return; return;
} }
obj.insert("formatVersion", int(version)); obj.insert("formatVersion", int(version));
@ -131,8 +121,7 @@ void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version)
void parseIndex(const QJsonObject& obj, Index* ptr) void parseIndex(const QJsonObject& obj, Index* ptr)
{ {
const MetadataVersion version = parseFormatVersion(obj); const MetadataVersion version = parseFormatVersion(obj);
switch (version) switch (version) {
{
case MetadataVersion::InitialRelease: case MetadataVersion::InitialRelease:
ptr->merge(parseIndexInternal(obj)); ptr->merge(parseIndexInternal(obj));
break; break;
@ -144,8 +133,7 @@ void parseIndex(const QJsonObject &obj, Index *ptr)
void parseVersionList(const QJsonObject& obj, VersionList* ptr) void parseVersionList(const QJsonObject& obj, VersionList* ptr)
{ {
const MetadataVersion version = parseFormatVersion(obj); const MetadataVersion version = parseFormatVersion(obj);
switch (version) switch (version) {
{
case MetadataVersion::InitialRelease: case MetadataVersion::InitialRelease:
ptr->merge(parseVersionListInternal(obj)); ptr->merge(parseVersionListInternal(obj));
break; break;
@ -157,8 +145,7 @@ void parseVersionList(const QJsonObject &obj, VersionList *ptr)
void parseVersion(const QJsonObject& obj, Version* ptr) void parseVersion(const QJsonObject& obj, Version* ptr)
{ {
const MetadataVersion version = parseFormatVersion(obj); const MetadataVersion version = parseFormatVersion(obj);
switch (version) switch (version) {
{
case MetadataVersion::InitialRelease: case MetadataVersion::InitialRelease:
ptr->merge(parseVersionInternal(obj)); ptr->merge(parseVersionInternal(obj));
break; break;
@ -174,12 +161,10 @@ void parseVersion(const QJsonObject &obj, Version *ptr)
*/ */
void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName) void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName)
{ {
if(obj.contains(keyName)) if (obj.contains(keyName)) {
{
auto reqArray = requireArray(obj, keyName); auto reqArray = requireArray(obj, keyName);
auto iter = reqArray.begin(); auto iter = reqArray.begin();
while(iter != reqArray.end()) while (iter != reqArray.end()) {
{
auto reqObject = requireObject(*iter); auto reqObject = requireObject(*iter);
auto uid = requireString(reqObject, "uid"); auto uid = requireString(reqObject, "uid");
auto equals = ensureString(reqObject, "equals", QString()); auto equals = ensureString(reqObject, "equals", QString());
@ -191,21 +176,17 @@ void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char * keyName
} }
void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char* keyName) void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char* keyName)
{ {
if(!ptr || ptr->empty()) if (!ptr || ptr->empty()) {
{
return; return;
} }
QJsonArray arrOut; QJsonArray arrOut;
for(auto &iter: *ptr) for (auto& iter : *ptr) {
{
QJsonObject reqOut; QJsonObject reqOut;
reqOut.insert("uid", iter.uid); reqOut.insert("uid", iter.uid);
if(!iter.equalsVersion.isEmpty()) if (!iter.equalsVersion.isEmpty()) {
{
reqOut.insert("equals", iter.equalsVersion); reqOut.insert("equals", iter.equalsVersion);
} }
if(!iter.suggests.isEmpty()) if (!iter.suggests.isEmpty()) {
{
reqOut.insert("suggests", iter.suggests); reqOut.insert("suggests", iter.suggests);
} }
arrOut.append(reqOut); arrOut.append(reqOut);
@ -213,5 +194,4 @@ void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName)
obj.insert(keyName, arrOut); obj.insert(keyName, arrOut);
} }
} } // namespace Meta

View File

@ -18,43 +18,25 @@
#include <QJsonObject> #include <QJsonObject>
#include <memory> #include <memory>
#include <set>
#include "Exception.h" #include "Exception.h"
#include "meta/BaseEntity.h" #include "meta/BaseEntity.h"
#include <set>
namespace Meta namespace Meta {
{
class Index; class Index;
class Version; class Version;
class VersionList; class VersionList;
enum class MetadataVersion enum class MetadataVersion { Invalid = -1, InitialRelease = 1 };
{
Invalid = -1,
InitialRelease = 1
};
class ParseException : public Exception class ParseException : public Exception {
{
public: public:
using Exception::Exception; using Exception::Exception;
}; };
struct Require struct Require {
{ bool operator==(const Require& rhs) const { return uid == rhs.uid; }
bool operator==(const Require & rhs) const bool operator<(const Require& rhs) const { return uid < rhs.uid; }
{ bool deepEquals(const Require& rhs) const { return uid == rhs.uid && equalsVersion == rhs.equalsVersion && suggests == rhs.suggests; }
return uid == rhs.uid;
}
bool operator<(const Require & rhs) const
{
return uid < rhs.uid;
}
bool deepEquals(const Require & rhs) const
{
return uid == rhs.uid
&& equalsVersion == rhs.equalsVersion
&& suggests == rhs.suggests;
}
QString uid; QString uid;
QString equalsVersion; QString equalsVersion;
QString suggests; QString suggests;
@ -73,6 +55,6 @@ void serializeFormatVersion(QJsonObject &obj, MetadataVersion version);
void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName = "requires"); void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName = "requires");
void serializeRequires(QJsonObject& objOut, RequireSet* ptr, const char* keyName = "requires"); void serializeRequires(QJsonObject& objOut, RequireSet* ptr, const char* keyName = "requires");
MetadataVersion currentFormatVersion(); MetadataVersion currentFormatVersion();
} } // namespace Meta
Q_DECLARE_METATYPE(std::set<Meta::Require>) Q_DECLARE_METATYPE(std::set<Meta::Require>)

Some files were not shown because too many files have changed in this diff Show More