From 0c861db7a201c813530e703257f286257f39872f Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Sat, 20 Nov 2021 16:22:22 +0100 Subject: NOISSUE Some happy little refactors --- launcher/Application.cpp | 1537 ++++++++++++++++++++ launcher/Application.h | 239 +++ launcher/ApplicationMessage.cpp | 31 + launcher/ApplicationMessage.h | 13 + launcher/CMakeLists.txt | 8 +- launcher/Env.cpp | 4 +- launcher/Env.h | 4 +- launcher/GuiUtil.cpp | 4 +- launcher/InstanceImportTask.cpp | 4 +- launcher/InstanceWindow.cpp | 18 +- launcher/LaunchController.cpp | 18 +- launcher/Launcher.cpp | 1532 ------------------- launcher/Launcher.h | 237 --- launcher/LauncherMessage.cpp | 31 - launcher/LauncherMessage.h | 13 - launcher/MainWindow.cpp | 236 +-- launcher/MainWindow.h | 2 +- launcher/SkinUtils.cpp | 2 +- launcher/Usable.h | 10 +- launcher/VersionProxyModel.cpp | 8 +- launcher/dialogs/AboutDialog.cpp | 4 +- launcher/dialogs/CopyInstanceDialog.cpp | 10 +- launcher/dialogs/ExportInstanceDialog.cpp | 4 +- launcher/dialogs/IconPickerDialog.cpp | 12 +- launcher/dialogs/LoginDialog.h | 2 +- launcher/dialogs/MSALoginDialog.h | 2 +- launcher/dialogs/NewComponentDialog.cpp | 4 +- launcher/dialogs/NewInstanceDialog.cpp | 24 +- launcher/dialogs/ProfileSelectDialog.cpp | 4 +- launcher/dialogs/ProfileSelectDialog.h | 2 +- launcher/dialogs/ProfileSetupDialog.cpp | 10 +- launcher/dialogs/SkinUploadDialog.cpp | 9 +- launcher/dialogs/UpdateDialog.cpp | 12 +- launcher/dialogs/VersionSelectDialog.cpp | 2 +- launcher/instanceview/InstanceProxyModel.cpp | 6 +- launcher/instanceview/InstanceView.cpp | 4 +- launcher/java/JavaChecker.cpp | 2 +- launcher/main.cpp | 12 +- launcher/meta/BaseEntity.cpp | 2 +- launcher/meta/Index_test.cpp | 4 +- launcher/minecraft/Component.cpp | 10 +- launcher/minecraft/ComponentUpdateTask.cpp | 10 +- launcher/minecraft/MinecraftInstance.cpp | 2 +- launcher/minecraft/PackProfile.cpp | 4 +- launcher/minecraft/auth/AccountList.cpp | 129 +- launcher/minecraft/auth/AccountList.h | 21 +- launcher/minecraft/auth/AccountTask.cpp | 4 - launcher/minecraft/auth/AuthSession.h | 3 +- launcher/minecraft/auth/MinecraftAccount.cpp | 58 +- launcher/minecraft/auth/MinecraftAccount.h | 20 +- launcher/minecraft/auth/flows/AuthContext.cpp | 22 +- launcher/minecraft/auth/flows/AuthRequest.cpp | 13 +- launcher/minecraft/auth/flows/AuthRequest.h | 3 +- launcher/minecraft/auth/flows/MSAInteractive.cpp | 5 +- launcher/minecraft/auth/flows/MSAInteractive.h | 5 +- launcher/minecraft/auth/flows/MSASilent.h | 5 +- launcher/minecraft/auth/flows/MojangLogin.cpp | 6 +- launcher/minecraft/auth/flows/MojangLogin.h | 6 +- launcher/minecraft/auth/flows/MojangRefresh.cpp | 5 +- launcher/minecraft/auth/flows/MojangRefresh.h | 2 +- launcher/minecraft/auth/flows/Parsers.h | 2 +- launcher/minecraft/auth/flows/Yggdrasil.cpp | 72 +- launcher/minecraft/auth/flows/Yggdrasil.h | 6 +- launcher/minecraft/launch/ClaimAccount.cpp | 6 +- launcher/minecraft/launch/LauncherPartLaunch.cpp | 2 +- launcher/minecraft/services/CapeChange.cpp | 4 +- launcher/minecraft/services/SkinDelete.cpp | 2 +- launcher/minecraft/services/SkinUpload.cpp | 2 +- launcher/minecraft/update/AssetUpdateTask.cpp | 4 +- launcher/minecraft/update/FMLLibrariesTask.cpp | 4 +- launcher/minecraft/update/LibrariesTask.cpp | 2 +- .../modplatform/atlauncher/ATLPackInstallTask.cpp | 14 +- .../modplatform/legacy_ftb/PackInstallTask.cpp | 2 +- .../modplatform/modpacksch/FTBPackInstallTask.cpp | 2 +- .../technic/SingleZipPackInstallTask.cpp | 2 +- launcher/net/Download.cpp | 2 +- launcher/net/MetaCacheSink.cpp | 2 +- launcher/net/PasteUpload.cpp | 2 +- launcher/notifications/NotificationChecker.cpp | 2 +- launcher/pagedialog/PageDialog.cpp | 6 +- launcher/pages/global/AccountListPage.cpp | 41 +- launcher/pages/global/AccountListPage.h | 8 +- launcher/pages/global/CustomCommandsPage.cpp | 4 +- launcher/pages/global/CustomCommandsPage.h | 4 +- launcher/pages/global/ExternalToolsPage.cpp | 18 +- launcher/pages/global/ExternalToolsPage.h | 6 +- launcher/pages/global/JavaPage.cpp | 8 +- launcher/pages/global/JavaPage.h | 4 +- launcher/pages/global/LanguagePage.cpp | 2 +- launcher/pages/global/LanguagePage.h | 4 +- launcher/pages/global/LauncherPage.cpp | 28 +- launcher/pages/global/LauncherPage.h | 4 +- launcher/pages/global/MinecraftPage.cpp | 6 +- launcher/pages/global/MinecraftPage.h | 4 +- launcher/pages/global/PasteEEPage.cpp | 6 +- launcher/pages/global/PasteEEPage.h | 4 +- launcher/pages/global/ProxyPage.cpp | 8 +- launcher/pages/global/ProxyPage.h | 4 +- launcher/pages/instance/GameOptionsPage.h | 4 +- launcher/pages/instance/InstanceSettingsPage.cpp | 14 +- launcher/pages/instance/InstanceSettingsPage.h | 4 +- launcher/pages/instance/LegacyUpgradePage.cpp | 6 +- launcher/pages/instance/LegacyUpgradePage.h | 4 +- launcher/pages/instance/LogPage.cpp | 6 +- launcher/pages/instance/LogPage.h | 4 +- launcher/pages/instance/ModFolderPage.cpp | 4 +- launcher/pages/instance/ModFolderPage.h | 4 +- launcher/pages/instance/NotesPage.h | 6 +- launcher/pages/instance/OtherLogsPage.cpp | 4 +- launcher/pages/instance/OtherLogsPage.h | 4 +- launcher/pages/instance/ScreenshotsPage.cpp | 4 +- launcher/pages/instance/ScreenshotsPage.h | 4 +- launcher/pages/instance/ServersPage.cpp | 4 +- launcher/pages/instance/ServersPage.h | 4 +- launcher/pages/instance/VersionPage.cpp | 24 +- launcher/pages/instance/WorldListPage.cpp | 8 +- launcher/pages/instance/WorldListPage.h | 4 +- launcher/pages/modplatform/ImportPage.cpp | 2 +- launcher/pages/modplatform/ImportPage.h | 4 +- launcher/pages/modplatform/VanillaPage.cpp | 4 +- launcher/pages/modplatform/VanillaPage.h | 4 +- .../pages/modplatform/atlauncher/AtlListModel.cpp | 8 +- launcher/pages/modplatform/atlauncher/AtlPage.cpp | 2 +- launcher/pages/modplatform/atlauncher/AtlPage.h | 4 +- launcher/pages/modplatform/flame/FlameModel.cpp | 8 +- launcher/pages/modplatform/flame/FlamePage.cpp | 2 +- launcher/pages/modplatform/flame/FlamePage.h | 4 +- launcher/pages/modplatform/ftb/FtbListModel.cpp | 8 +- launcher/pages/modplatform/ftb/FtbPage.h | 4 +- .../pages/modplatform/legacy_ftb/ListModel.cpp | 8 +- launcher/pages/modplatform/legacy_ftb/Page.cpp | 2 +- launcher/pages/modplatform/legacy_ftb/Page.h | 4 +- .../pages/modplatform/technic/TechnicModel.cpp | 8 +- launcher/pages/modplatform/technic/TechnicPage.cpp | 2 +- launcher/pages/modplatform/technic/TechnicPage.h | 4 +- launcher/screenshots/ImgurAlbumCreation.cpp | 2 +- launcher/screenshots/ImgurUpload.cpp | 2 +- launcher/setupwizard/AnalyticsWizardPage.cpp | 6 +- launcher/setupwizard/JavaWizardPage.cpp | 6 +- launcher/setupwizard/LanguageWizardPage.cpp | 6 +- launcher/setupwizard/SetupWizard.cpp | 2 +- launcher/themes/ITheme.cpp | 6 +- launcher/translations/TranslationsModel.cpp | 4 +- launcher/widgets/JavaSettingsWidget.cpp | 12 +- launcher/widgets/LanguageSelectionWidget.cpp | 8 +- launcher/widgets/PageContainer.cpp | 10 +- 146 files changed, 2549 insertions(+), 2431 deletions(-) create mode 100644 launcher/Application.cpp create mode 100644 launcher/Application.h create mode 100644 launcher/ApplicationMessage.cpp create mode 100644 launcher/ApplicationMessage.h delete mode 100644 launcher/Launcher.cpp delete mode 100644 launcher/Launcher.h delete mode 100644 launcher/LauncherMessage.cpp delete mode 100644 launcher/LauncherMessage.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp new file mode 100644 index 00000000..8789d096 --- /dev/null +++ b/launcher/Application.cpp @@ -0,0 +1,1537 @@ +#include "Application.h" +#include "BuildConfig.h" +#include "MainWindow.h" +#include "InstanceWindow.h" + +#include "instanceview/AccessibleInstanceView.h" +#include + +#include "pages/BasePageProvider.h" +#include "pages/global/LauncherPage.h" +#include "pages/global/MinecraftPage.h" +#include "pages/global/JavaPage.h" +#include "pages/global/LanguagePage.h" +#include "pages/global/ProxyPage.h" +#include "pages/global/ExternalToolsPage.h" +#include "pages/global/AccountListPage.h" +#include "pages/global/PasteEEPage.h" +#include "pages/global/CustomCommandsPage.h" + +#include "themes/ITheme.h" +#include "themes/SystemTheme.h" +#include "themes/DarkTheme.h" +#include "themes/BrightTheme.h" +#include "themes/CustomTheme.h" + +#include "ApplicationMessage.h" + +#include "setupwizard/SetupWizard.h" +#include "setupwizard/LanguageWizardPage.h" +#include "setupwizard/JavaWizardPage.h" +#include "setupwizard/AnalyticsWizardPage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialogs/CustomMessageBox.h" +#include "InstanceList.h" + +#include +#include "icons/IconList.h" +#include "net/HttpMetaCache.h" +#include "Env.h" + +#include "java/JavaUtils.h" + +#include "updater/UpdateChecker.h" + +#include "tools/JProfiler.h" +#include "tools/JVisualVM.h" +#include "tools/MCEditTool.h" + +#include +#include "settings/INISettingsObject.h" +#include "settings/Setting.h" + +#include "translations/TranslationsModel.h" + +#include +#include +#include +#include + +#include +#include + +#include "pagedialog/PageDialog.h" +#include + + +#if defined Q_OS_WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#endif + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +static const QLatin1String liveCheckFile("live.check"); + +using namespace Commandline; + +#define MACOS_HINT "If you are on macOS Sierra, you might have to move the app to your /Applications or ~/Applications folder. "\ + "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ + "\n" + +namespace { +void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + const char *levels = "DWCFIS"; + const QString format("%1 %2 %3\n"); + + qint64 msecstotal = APPLICATION->timeSinceStart(); + qint64 seconds = msecstotal / 1000; + qint64 msecs = msecstotal % 1000; + QString foo; + char buf[1025] = {0}; + ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs); + + QString out = format.arg(buf).arg(levels[type]).arg(msg); + + APPLICATION->logFile->write(out.toUtf8()); + APPLICATION->logFile->flush(); + QTextStream(stderr) << out.toLocal8Bit(); + fflush(stderr); +} + +QString getIdealPlatform(QString currentPlatform) { + auto info = Sys::getKernelInfo(); + switch(info.kernelType) { + case Sys::KernelType::Darwin: { + if(info.kernelMajor >= 17) { + // macOS 10.13 or newer + return "osx64-5.15.2"; + } + else { + // macOS 10.12 or older + return "osx64"; + } + } + case Sys::KernelType::Windows: { + // FIXME: 5.15.2 is not stable on Windows, due to a large number of completely unpredictable and hard to reproduce issues + break; +/* + if(info.kernelMajor == 6 && info.kernelMinor >= 1) { + // Windows 7 + return "win32-5.15.2"; + } + else if (info.kernelMajor > 6) { + // Above Windows 7 + return "win32-5.15.2"; + } + else { + // Below Windows 7 + return "win32"; + } +*/ + } + case Sys::KernelType::Undetermined: + case Sys::KernelType::Linux: { + break; + } + } + return currentPlatform; +} + +} + +Application::Application(int &argc, char **argv) : QApplication(argc, argv) +{ +#if defined Q_OS_WIN32 + // attach the parent console + if(AttachConsole(ATTACH_PARENT_PROCESS)) + { + // if attach succeeds, reopen and sync all the i/o + if(freopen("CON", "w", stdout)) + { + std::cout.sync_with_stdio(); + } + if(freopen("CON", "w", stderr)) + { + std::cerr.sync_with_stdio(); + } + if(freopen("CON", "r", stdin)) + { + std::cin.sync_with_stdio(); + } + auto out = GetStdHandle (STD_OUTPUT_HANDLE); + DWORD written; + const char * endline = "\n"; + WriteConsole(out, endline, strlen(endline), &written, NULL); + consoleAttached = true; + } +#endif + setOrganizationName(BuildConfig.LAUNCHER_NAME); + setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN); + setApplicationName(BuildConfig.LAUNCHER_NAME); + setApplicationDisplayName(BuildConfig.LAUNCHER_DISPLAYNAME); + setApplicationVersion(BuildConfig.printableVersionString()); + + startTime = QDateTime::currentDateTime(); + +#ifdef Q_OS_LINUX + { + QFile osrelease("/proc/sys/kernel/osrelease"); + if (osrelease.open(QFile::ReadOnly | QFile::Text)) { + QTextStream in(&osrelease); + auto contents = in.readAll(); + if( + contents.contains("WSL", Qt::CaseInsensitive) || + contents.contains("Microsoft", Qt::CaseInsensitive) + ) { + showFatalErrorMessage( + "Unsupported system detected!", + "Linux-on-Windows distributions are not supported.\n\n" + "Please use the Windows binary when playing on Windows." + ); + return; + } + } + } +#endif + + // Don't quit on hiding the last window + this->setQuitOnLastWindowClosed(false); + + // Commandline parsing + QHash args; + { + Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals); + + // --help + parser.addSwitch("help"); + parser.addShortOpt("help", 'h'); + parser.addDocumentation("help", "Display this help and exit."); + // --version + parser.addSwitch("version"); + parser.addShortOpt("version", 'V'); + parser.addDocumentation("version", "Display program version and exit."); + // --dir + parser.addOption("dir"); + parser.addShortOpt("dir", 'd'); + parser.addDocumentation("dir", "Use the supplied folder as application root instead of the binary location (use '.' for current)"); + // --launch + parser.addOption("launch"); + parser.addShortOpt("launch", 'l'); + parser.addDocumentation("launch", "Launch the specified instance (by instance ID)"); + // --server + parser.addOption("server"); + parser.addShortOpt("server", 's'); + parser.addDocumentation("server", "Join the specified server on launch (only valid in combination with --launch)"); + // --profile + parser.addOption("profile"); + parser.addShortOpt("profile", 'a'); + parser.addDocumentation("profile", "Use the account specified by its profile name (only valid in combination with --launch)"); + // --alive + parser.addSwitch("alive"); + parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"); + // --import + parser.addOption("import"); + parser.addShortOpt("import", 'I'); + parser.addDocumentation("import", "Import instance from specified zip (local path or URL)"); + + // parse the arguments + try + { + args = parser.parse(arguments()); + } + catch (const ParsingError &e) + { + std::cerr << "CommandLineError: " << e.what() << std::endl; + if(argc > 0) + std::cerr << "Try '" << argv[0] << " -h' to get help on command line parameters." + << std::endl; + m_status = Application::Failed; + return; + } + + // display help and exit + if (args["help"].toBool()) + { + std::cout << qPrintable(parser.compileHelp(arguments()[0])); + m_status = Application::Succeeded; + return; + } + + // display version and exit + if (args["version"].toBool()) + { + std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl; + std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl; + m_status = Application::Succeeded; + return; + } + } + m_instanceIdToLaunch = args["launch"].toString(); + m_serverToJoin = args["server"].toString(); + m_profileToUse = args["profile"].toString(); + m_liveCheck = args["alive"].toBool(); + m_zipToImport = args["import"].toUrl(); + + QString origcwdPath = QDir::currentPath(); + QString binPath = applicationDirPath(); + QString adjustedBy; + QString dataPath; + // change folder + QString dirParam = args["dir"].toString(); + if (!dirParam.isEmpty()) + { + // the dir param. it makes multimc data path point to whatever the user specified + // on command line + adjustedBy += "Command line " + dirParam; + dataPath = dirParam; + } + else + { +#if defined(Q_OS_MAC) + QDir foo(FS::PathCombine(applicationDirPath(), "../../Data")); + dataPath = foo.absolutePath(); + adjustedBy += "Fallback to special Mac location " + dataPath; +#else + dataPath = applicationDirPath(); + adjustedBy += "Fallback to binary path " + dataPath; +#endif + } + + if (!FS::ensureFolderPathExists(dataPath)) + { + showFatalErrorMessage( + "The launcher data folder could not be created.", + "The launcher data folder could not be created.\n" + "\n" +#if defined(Q_OS_MAC) + MACOS_HINT +#endif + "Make sure you have the right permissions to the launcher data folder and any folder needed to access it.\n" + "\n" + "The launcher cannot continue until you fix this problem." + ); + return; + } + if (!QDir::setCurrent(dataPath)) + { + showFatalErrorMessage( + "The launcher data folder could not be opened.", + "The launcher data folder could not be opened.\n" + "\n" +#if defined(Q_OS_MAC) + MACOS_HINT +#endif + "Make sure you have the right permissions to the launcher data folder.\n" + "\n" + "The launcher cannot continue until you fix this problem." + ); + return; + } + + if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty()) + { + std::cerr << "--server can only be used in combination with --launch!" << std::endl; + m_status = Application::Failed; + return; + } + + if(m_instanceIdToLaunch.isEmpty() && !m_profileToUse.isEmpty()) + { + std::cerr << "--account can only be used in combination with --launch!" << std::endl; + m_status = Application::Failed; + return; + } + +#if defined(Q_OS_MAC) + // move user data to new location if on macOS and it still exists in Contents/MacOS + QDir fi(applicationDirPath()); + QString originalData = fi.absolutePath(); + // if the config file exists in Contents/MacOS, then user data is still there and needs to moved + if (QFileInfo::exists(FS::PathCombine(originalData, BuildConfig.LAUNCHER_CONFIGFILE))) + { + if (!QFileInfo::exists(FS::PathCombine(originalData, "dontmovemacdata"))) + { + QMessageBox::StandardButton askMoveDialogue; + askMoveDialogue = QMessageBox::question( + nullptr, + BuildConfig.LAUNCHER_DISPLAYNAME, + "Would you like to move application data to a new data location? It will improve the launcher's performance, but if you switch to older versions it will look like instances have disappeared. If you select no, you can migrate later in settings. You should select yes unless you're commonly switching between different versions (eg. develop and stable).", + QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes + ); + if (askMoveDialogue == QMessageBox::Yes) + { + qDebug() << "On macOS and found config file in old location, moving user data..."; + QDir dir; + QStringList dataFiles { + "*.log", // Launcher log files: ${Launcher_Name}-@.log + "accounts.json", + "accounts", + "assets", + "cache", + "icons", + "instances", + "libraries", + "meta", + "metacache", + "mods", + BuildConfig.LAUNCHER_CONFIGFILE, + "themes", + "translations" + }; + QDirIterator files(originalData, dataFiles); + while (files.hasNext()) { + QString filePath(files.next()); + QString fileName(files.fileName()); + if (!dir.rename(filePath, FS::PathCombine(dataPath, fileName))) + { + qWarning() << "Failed to move " << fileName; + } + } + } + else + { + dataPath = originalData; + QDir::setCurrent(dataPath); + QFile file(originalData + "/dontmovemacdata"); + file.open(QIODevice::WriteOnly); + } + } + else + { + dataPath = originalData; + QDir::setCurrent(dataPath); + } + } +#endif + + /* + * Establish the mechanism for communication with an already running MultiMC that uses the same data path. + * If there is one, tell it what the user actually wanted to do and exit. + * We want to initialize this before logging to avoid messing with the log of a potential already running copy. + */ + auto appID = ApplicationId::fromPathAndVersion(QDir::currentPath(), BuildConfig.printableVersionString()); + { + // FIXME: you can run the same binaries with multiple data dirs and they won't clash. This could cause issues for updates. + m_peerInstance = new LocalPeer(this, appID); + connect(m_peerInstance, &LocalPeer::messageReceived, this, &Application::messageReceived); + if(m_peerInstance->isClient()) { + int timeout = 2000; + + if(m_instanceIdToLaunch.isEmpty()) + { + ApplicationMessage activate; + activate.command = "activate"; + m_peerInstance->sendMessage(activate.serialize(), timeout); + + if(!m_zipToImport.isEmpty()) + { + ApplicationMessage import; + import.command = "import"; + import.args.insert("path", m_zipToImport.toString()); + m_peerInstance->sendMessage(import.serialize(), timeout); + } + } + else + { + ApplicationMessage launch; + launch.command = "launch"; + launch.args["id"] = m_instanceIdToLaunch; + + if(!m_serverToJoin.isEmpty()) + { + launch.args["server"] = m_serverToJoin; + } + if(!m_profileToUse.isEmpty()) + { + launch.args["profile"] = m_profileToUse; + } + m_peerInstance->sendMessage(launch.serialize(), timeout); + } + m_status = Application::Succeeded; + return; + } + } + + // init the logger + { + static const QString logBase = BuildConfig.LAUNCHER_NAME + "-%0.log"; + auto moveFile = [](const QString &oldName, const QString &newName) + { + QFile::remove(newName); + QFile::copy(oldName, newName); + QFile::remove(oldName); + }; + + moveFile(logBase.arg(3), logBase.arg(4)); + moveFile(logBase.arg(2), logBase.arg(3)); + moveFile(logBase.arg(1), logBase.arg(2)); + moveFile(logBase.arg(0), logBase.arg(1)); + + logFile = std::unique_ptr(new QFile(logBase.arg(0))); + if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) + { + showFatalErrorMessage( + "The launcher data folder is not writable!", + "The launcher couldn't create a log file - the data folder is not writable.\n" + "\n" + #if defined(Q_OS_MAC) + MACOS_HINT + #endif + "Make sure you have write permissions to the data folder.\n" + "\n" + "The launcher cannot continue until you fix this problem." + ); + return; + } + qInstallMessageHandler(appDebugOutput); + qDebug() << "<> Log initialized."; + } + + // Set up paths + { + // Root path is used for updates. +#ifdef Q_OS_LINUX + QDir foo(FS::PathCombine(binPath, "..")); + m_rootPath = foo.absolutePath(); +#elif defined(Q_OS_WIN32) + m_rootPath = binPath; +#elif defined(Q_OS_MAC) + QDir foo(FS::PathCombine(binPath, "../..")); + m_rootPath = foo.absolutePath(); + // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues) + FS::updateTimestamp(m_rootPath); +#endif + +#ifdef MULTIMC_JARS_LOCATION + ENV->setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); +#endif + + qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; + qDebug() << "Version : " << BuildConfig.printableVersionString(); + qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; + qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; + if (adjustedBy.size()) + { + qDebug() << "Work dir before adjustment : " << origcwdPath; + qDebug() << "Work dir after adjustment : " << QDir::currentPath(); + qDebug() << "Adjusted by : " << adjustedBy; + } + else + { + qDebug() << "Work dir : " << QDir::currentPath(); + } + qDebug() << "Binary path : " << binPath; + qDebug() << "Application root path : " << m_rootPath; + if(!m_instanceIdToLaunch.isEmpty()) + { + qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; + } + if(!m_serverToJoin.isEmpty()) + { + qDebug() << "Address of server to join :" << m_serverToJoin; + } + qDebug() << "<> Paths set."; + } + + do // once + { + if(m_liveCheck) + { + QFile check(liveCheckFile); + if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qWarning() << "Could not open" << liveCheckFile << "for writing!"; + break; + } + auto payload = appID.toString().toUtf8(); + if(check.write(payload) != payload.size()) + { + qWarning() << "Could not write into" << liveCheckFile << "!"; + check.remove(); + break; + } + check.close(); + } + } while(false); + + // Initialize application settings + { + m_settings.reset(new INISettingsObject(BuildConfig.LAUNCHER_CONFIGFILE, this)); + // Updates + m_settings->registerSetting("UpdateChannel", BuildConfig.VERSION_CHANNEL); + m_settings->registerSetting("AutoUpdate", true); + + // Theming + m_settings->registerSetting("IconTheme", QString("multimc")); + m_settings->registerSetting("ApplicationTheme", QString("system")); + + // Notifications + m_settings->registerSetting("ShownNotifications", QString()); + + // Remembered state + m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); + + QString defaultMonospace; + int defaultSize = 11; +#ifdef Q_OS_WIN32 + defaultMonospace = "Courier"; + defaultSize = 10; +#elif defined(Q_OS_MAC) + defaultMonospace = "Menlo"; +#else + defaultMonospace = "Monospace"; +#endif + + // resolve the font so the default actually matches + QFont consoleFont; + consoleFont.setFamily(defaultMonospace); + consoleFont.setStyleHint(QFont::Monospace); + consoleFont.setFixedPitch(true); + QFontInfo consoleFontInfo(consoleFont); + QString resolvedDefaultMonospace = consoleFontInfo.family(); + QFont resolvedFont(resolvedDefaultMonospace); + qDebug() << "Detected default console font:" << resolvedDefaultMonospace + << ", substitutions:" << resolvedFont.substitutions().join(','); + + m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace); + m_settings->registerSetting("ConsoleFontSize", defaultSize); + m_settings->registerSetting("ConsoleMaxLines", 100000); + m_settings->registerSetting("ConsoleOverflowStop", true); + + // Folders + m_settings->registerSetting("InstanceDir", "instances"); + m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods"); + m_settings->registerSetting("IconsDir", "icons"); + + // Editors + m_settings->registerSetting("JsonEditor", QString()); + + // Language + m_settings->registerSetting("Language", QString()); + + // Console + m_settings->registerSetting("ShowConsole", false); + m_settings->registerSetting("AutoCloseConsole", false); + m_settings->registerSetting("ShowConsoleOnError", true); + m_settings->registerSetting("LogPrePostOutput", true); + + // Window Size + m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false); + m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854); + m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480); + + // Proxy Settings + m_settings->registerSetting("ProxyType", "None"); + m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1"); + m_settings->registerSetting("ProxyPort", 8080); + m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, ""); + m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, ""); + + // Memory + m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); + m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024); + m_settings->registerSetting("PermGen", 128); + + // Java Settings + m_settings->registerSetting("JavaPath", ""); + m_settings->registerSetting("JavaTimestamp", 0); + m_settings->registerSetting("JavaArchitecture", ""); + m_settings->registerSetting("JavaVersion", ""); + m_settings->registerSetting("JavaVendor", ""); + m_settings->registerSetting("LastHostname", ""); + m_settings->registerSetting("JvmArgs", ""); + + // Native library workarounds + m_settings->registerSetting("UseNativeOpenAL", false); + m_settings->registerSetting("UseNativeGLFW", false); + + // Game time + m_settings->registerSetting("ShowGameTime", true); + m_settings->registerSetting("ShowGlobalGameTime", true); + m_settings->registerSetting("RecordGameTime", true); + + // Minecraft launch method + m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); + + // Wrapper command for launch + m_settings->registerSetting("WrapperCommand", ""); + + // Custom Commands + m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, ""); + m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, ""); + + // The cat + m_settings->registerSetting("TheCat", false); + + m_settings->registerSetting("InstSortMode", "Name"); + m_settings->registerSetting("SelectedInstance", QString()); + + // Window state and geometry + m_settings->registerSetting("MainWindowState", ""); + m_settings->registerSetting("MainWindowGeometry", ""); + + m_settings->registerSetting("ConsoleWindowState", ""); + m_settings->registerSetting("ConsoleWindowGeometry", ""); + + m_settings->registerSetting("SettingsGeometry", ""); + + m_settings->registerSetting("PagedGeometry", ""); + + m_settings->registerSetting("NewInstanceGeometry", ""); + + m_settings->registerSetting("UpdateDialogGeometry", ""); + + // paste.ee API key + m_settings->registerSetting("PasteEEAPIKey", "multimc"); + + if(!BuildConfig.ANALYTICS_ID.isEmpty()) + { + // Analytics + m_settings->registerSetting("Analytics", true); + m_settings->registerSetting("AnalyticsSeen", 0); + m_settings->registerSetting("AnalyticsClientID", QString()); + } + + // Init page provider + { + m_globalSettingsProvider = std::make_shared(tr("Settings")); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + } + qDebug() << "<> Settings loaded."; + } + +#ifndef QT_NO_ACCESSIBILITY + QAccessible::installFactory(groupViewAccessibleFactory); +#endif /* !QT_NO_ACCESSIBILITY */ + + // load translations + { + m_translations.reset(new TranslationsModel("translations")); + auto bcp47Name = m_settings->get("Language").toString(); + m_translations->selectLanguage(bcp47Name); + qDebug() << "Your language is" << bcp47Name; + qDebug() << "<> Translations loaded."; + } + + // initialize the updater + if(BuildConfig.UPDATER_ENABLED) + { + auto platform = getIdealPlatform(BuildConfig.BUILD_PLATFORM); + auto channelUrl = BuildConfig.UPDATER_BASE + platform + "/channels.json"; + qDebug() << "Initializing updater with platform: " << platform << " -- " << channelUrl; + m_updateChecker.reset(new UpdateChecker(channelUrl, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); + qDebug() << "<> Updater started."; + } + + // Instance icons + { + auto setting = APPLICATION->settings()->getSetting("IconsDir"); + QStringList instFolders = + { + ":/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())); + connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) + { + m_icons->directoryChanged(value.toString()); + }); + ENV->registerIconList(m_icons); + qDebug() << "<> Instance icons intialized."; + } + + // Icon themes + { + // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! + // set icon theme search path! + auto searchPaths = QIcon::themeSearchPaths(); + searchPaths.append("iconthemes"); + QIcon::setThemeSearchPaths(searchPaths); + qDebug() << "<> Icon themes initialized."; + } + + // Initialize widget themes + { + auto insertTheme = [this](ITheme * theme) + { + m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); + }; + auto darkTheme = new DarkTheme(); + insertTheme(new SystemTheme()); + insertTheme(darkTheme); + insertTheme(new BrightTheme()); + insertTheme(new CustomTheme(darkTheme, "custom")); + qDebug() << "<> Widget themes initialized."; + } + + // initialize and load all instances + { + auto InstDirSetting = m_settings->getSetting("InstanceDir"); + // instance path: check for problems with '!' in instance path and warn the user in the log + // and remember that we have to show him a dialog when the gui starts (if it does so) + QString instDir = InstDirSetting->get().toString(); + qDebug() << "Instance path : " << instDir; + if (FS::checkProblemticPathJava(QDir(instDir))) + { + qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!"; + } + m_instances.reset(new InstanceList(m_settings, instDir, this)); + connect(InstDirSetting.get(), &Setting::SettingChanged, m_instances.get(), &InstanceList::on_InstFolderChanged); + qDebug() << "Loading Instances..."; + m_instances->loadList(); + qDebug() << "<> Instances loaded."; + } + + // and accounts + { + m_accounts.reset(new AccountList(this)); + qDebug() << "Loading accounts..."; + m_accounts->setListFilePath("accounts.json", true); + m_accounts->loadList(); + qDebug() << "<> Accounts loaded."; + } + + // init the http meta cache + { + ENV->initHttpMetaCache(); + qDebug() << "<> Cache initialized."; + } + + // init proxy settings + { + QString proxyTypeStr = settings()->get("ProxyType").toString(); + QString addr = settings()->get("ProxyAddr").toString(); + int port = settings()->get("ProxyPort").value(); + QString user = settings()->get("ProxyUser").toString(); + QString pass = settings()->get("ProxyPass").toString(); + ENV->updateProxySettings(proxyTypeStr, addr, port, user, pass); + qDebug() << "<> Proxy settings done."; + } + + // now we have network, download translation updates + m_translations->downloadIndex(); + + //FIXME: what to do with these? + m_profilers.insert("jprofiler", std::shared_ptr(new JProfilerFactory())); + m_profilers.insert("jvisualvm", std::shared_ptr(new JVisualVMFactory())); + for (auto profiler : m_profilers.values()) + { + profiler->registerSettings(m_settings); + } + + // Create the MCEdit thing... why is this here? + { + m_mcedit.reset(new MCEditTool(m_settings)); + } + + connect(this, &Application::aboutToQuit, [this](){ + if(m_instances) + { + // save any remaining instance state + m_instances->saveNow(); + } + if(logFile) + { + logFile->flush(); + logFile->close(); + } + }); + + { + setIconTheme(settings()->get("IconTheme").toString()); + qDebug() << "<> Icon theme set."; + setApplicationTheme(settings()->get("ApplicationTheme").toString(), true); + qDebug() << "<> Application theme set."; + } + + // Initialize analytics + [this]() + { + const int analyticsVersion = 2; + if(BuildConfig.ANALYTICS_ID.isEmpty()) + { + return; + } + + auto analyticsSetting = m_settings->getSetting("Analytics"); + connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Application::analyticsSettingChanged); + QString clientID = m_settings->get("AnalyticsClientID").toString(); + if(clientID.isEmpty()) + { + clientID = QUuid::createUuid().toString(); + clientID.remove(QLatin1Char('{')); + clientID.remove(QLatin1Char('}')); + m_settings->set("AnalyticsClientID", clientID); + } + m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this); + m_analytics->setLogLevel(GAnalytics::Debug); + m_analytics->setAnonymizeIPs(true); + m_analytics->setNetworkAccessManager(&ENV->network()); + + if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version()) + { + qDebug() << "Analytics info not seen by user yet (or old version)."; + return; + } + if(!m_settings->get("Analytics").toBool()) + { + qDebug() << "Analytics disabled by user."; + return; + } + + m_analytics->enable(); + qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID; + }(); + + if(createSetupWizard()) + { + return; + } + performMainStartupAction(); +} + +bool Application::createSetupWizard() +{ + bool javaRequired = [&]() + { + QString currentHostName = QHostInfo::localHostName(); + QString oldHostName = settings()->get("LastHostname").toString(); + if (currentHostName != oldHostName) + { + settings()->set("LastHostname", currentHostName); + return true; + } + QString currentJavaPath = settings()->get("JavaPath").toString(); + QString actualPath = FS::ResolveExecutable(currentJavaPath); + if (actualPath.isNull()) + { + return true; + } + return false; + }(); + bool analyticsRequired = [&]() + { + if(BuildConfig.ANALYTICS_ID.isEmpty()) + { + return false; + } + if (!settings()->get("Analytics").toBool()) + { + return false; + } + if (settings()->get("AnalyticsSeen").toInt() < analytics()->version()) + { + return true; + } + return false; + }(); + bool languageRequired = [&]() + { + if (settings()->get("Language").toString().isEmpty()) + return true; + return false; + }(); + bool wizardRequired = javaRequired || analyticsRequired || languageRequired; + + if(wizardRequired) + { + m_setupWizard = new SetupWizard(nullptr); + if (languageRequired) + { + m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard)); + } + if (javaRequired) + { + m_setupWizard->addPage(new JavaWizardPage(m_setupWizard)); + } + if(analyticsRequired) + { + m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard)); + } + connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished); + m_setupWizard->show(); + return true; + } + return false; +} + +void Application::setupWizardFinished(int status) +{ + qDebug() << "Wizard result =" << status; + performMainStartupAction(); +} + +void Application::performMainStartupAction() +{ + m_status = Application::Initialized; + if(!m_instanceIdToLaunch.isEmpty()) + { + auto inst = instances()->getInstanceById(m_instanceIdToLaunch); + if(inst) + { + MinecraftServerTargetPtr serverToJoin = nullptr; + MinecraftAccountPtr accountToUse = nullptr; + + qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; + if(!m_serverToJoin.isEmpty()) + { + // FIXME: validate the server string + serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); + qDebug() << " Launching with server" << m_serverToJoin; + } + + if(!m_profileToUse.isEmpty()) + { + accountToUse = accounts()->getAccountByProfileName(m_profileToUse); + if(!accountToUse) { + return; + } + qDebug() << " Launching with account" << m_profileToUse; + } + + launch(inst, true, nullptr, serverToJoin, accountToUse); + return; + } + } + if(!m_mainWindow) + { + // normal main window + showMainWindow(false); + qDebug() << "<> Main window shown."; + } + if(!m_zipToImport.isEmpty()) + { + qDebug() << "<> Importing instance from zip:" << m_zipToImport; + m_mainWindow->droppedURLs({ m_zipToImport }); + } +} + +void Application::showFatalErrorMessage(const QString& title, const QString& content) +{ + m_status = Application::Failed; + auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); + dialog->exec(); +} + +Application::~Application() +{ + // kill the other globals. + Env::dispose(); + + // Shut down logger by setting the logger function to nothing + qInstallMessageHandler(nullptr); + +#if defined Q_OS_WIN32 + // Detach from Windows console + if(consoleAttached) + { + fclose(stdout); + fclose(stdin); + fclose(stderr); + FreeConsole(); + } +#endif +} + +void Application::messageReceived(const QByteArray& message) +{ + if(status() != Initialized) + { + qDebug() << "Received message" << message << "while still initializing. It will be ignored."; + return; + } + + ApplicationMessage received; + received.parse(message); + + auto & command = received.command; + + if(command == "activate") + { + showMainWindow(); + } + else if(command == "import") + { + QString path = received.args["path"]; + if(path.isEmpty()) + { + qWarning() << "Received" << command << "message without a zip path/URL."; + return; + } + m_mainWindow->droppedURLs({ QUrl(path) }); + } + else if(command == "launch") + { + QString id = received.args["id"]; + QString server = received.args["server"]; + QString profile = received.args["profile"]; + + InstancePtr instance; + if(!id.isEmpty()) { + instance = instances()->getInstanceById(id); + if(!instance) { + qWarning() << "Launch command requires an valid instance ID. " << id << "resolves to nothing."; + return; + } + } + else { + qWarning() << "Launch command called without an instance ID..."; + return; + } + + MinecraftServerTargetPtr serverObject = nullptr; + if(!server.isEmpty()) { + serverObject = std::make_shared(MinecraftServerTarget::parse(server)); + } + + MinecraftAccountPtr accountObject; + if(!profile.isEmpty()) { + accountObject = accounts()->getAccountByProfileName(profile); + if(!accountObject) { + qWarning() << "Launch command requires the specified profile to be valid. " << profile << "does not resolve to any account."; + return; + } + } + + launch( + instance, + true, + nullptr, + serverObject, + accountObject + ); + } + else + { + qWarning() << "Received invalid message" << message; + } +} + +void Application::analyticsSettingChanged(const Setting&, QVariant value) +{ + if(!m_analytics) + return; + bool enabled = value.toBool(); + if(enabled) + { + qDebug() << "Analytics enabled by user."; + } + else + { + qDebug() << "Analytics disabled by user."; + } + m_analytics->enable(enabled); +} + +std::shared_ptr Application::translations() +{ + return m_translations; +} + +std::shared_ptr Application::javalist() +{ + if (!m_javalist) + { + m_javalist.reset(new JavaInstallList()); + } + return m_javalist; +} + +std::vector Application::getValidApplicationThemes() +{ + std::vector ret; + auto iter = m_themes.cbegin(); + while (iter != m_themes.cend()) + { + ret.push_back((*iter).second.get()); + iter++; + } + return ret; +} + +void Application::setApplicationTheme(const QString& name, bool initial) +{ + auto systemPalette = qApp->palette(); + auto themeIter = m_themes.find(name); + if(themeIter != m_themes.end()) + { + auto & theme = (*themeIter).second; + theme->apply(initial); + } + else + { + qWarning() << "Tried to set invalid theme:" << name; + } +} + +void Application::setIconTheme(const QString& name) +{ + XdgIcon::setThemeName(name); +} + +QIcon Application::getThemedIcon(const QString& name) +{ + if(name == "logo") { + return QIcon(":/logo.svg"); + } + return XdgIcon::fromTheme(name); +} + +bool Application::openJsonEditor(const QString &filename) +{ + const QString file = QDir::current().absoluteFilePath(filename); + if (m_settings->get("JsonEditor").toString().isEmpty()) + { + return DesktopServices::openUrl(QUrl::fromLocalFile(file)); + } + else + { + //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); + return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file}); + } +} + +bool Application::launch( + InstancePtr instance, + bool online, + BaseProfilerFactory *profiler, + MinecraftServerTargetPtr serverToJoin, + MinecraftAccountPtr accountToUse +) { + if(m_updateRunning) + { + qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; + } + else if(instance->canLaunch()) + { + auto & extras = m_instanceExtras[instance->id()]; + auto & window = extras.window; + if(window) + { + if(!window->saveAll()) + { + return false; + } + } + auto & controller = extras.controller; + controller.reset(new LaunchController()); + controller->setInstance(instance); + controller->setOnline(online); + controller->setProfiler(profiler); + controller->setServerToJoin(serverToJoin); + controller->setAccountToUse(accountToUse); + if(window) + { + controller->setParentWidget(window); + } + else if(m_mainWindow) + { + controller->setParentWidget(m_mainWindow); + } + connect(controller.get(), &LaunchController::succeeded, this, &Application::controllerSucceeded); + connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed); + addRunningInstance(); + controller->start(); + return true; + } + else if (instance->isRunning()) + { + showInstanceWindow(instance, "console"); + return true; + } + else if (instance->canEdit()) + { + showInstanceWindow(instance); + return true; + } + return false; +} + +bool Application::kill(InstancePtr instance) +{ + if (!instance->isRunning()) + { + qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; + return false; + } + auto & extras = m_instanceExtras[instance->id()]; + // NOTE: copy of the shared pointer keeps it alive + auto controller = extras.controller; + if(controller) + { + return controller->abort(); + } + return true; +} + +void Application::addRunningInstance() +{ + m_runningInstances ++; + if(m_runningInstances == 1) + { + emit updateAllowedChanged(false); + } +} + +void Application::subRunningInstance() +{ + if(m_runningInstances == 0) + { + qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF"; + return; + } + m_runningInstances --; + if(m_runningInstances == 0) + { + emit updateAllowedChanged(true); + } +} + +bool Application::shouldExitNow() const +{ + return m_runningInstances == 0 && m_openWindows == 0; +} + +bool Application::updatesAreAllowed() +{ + return m_runningInstances == 0; +} + +void Application::updateIsRunning(bool running) +{ + m_updateRunning = running; +} + + +void Application::controllerSucceeded() +{ + auto controller = qobject_cast(QObject::sender()); + if(!controller) + return; + auto id = controller->id(); + auto & extras = m_instanceExtras[id]; + + // on success, do... + if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) + { + if(extras.window) + { + extras.window->close(); + } + } + extras.controller.reset(); + subRunningInstance(); + + // quit when there are no more windows. + if(shouldExitNow()) + { + m_status = Status::Succeeded; + exit(0); + } +} + +void Application::controllerFailed(const QString& error) +{ + Q_UNUSED(error); + auto controller = qobject_cast(QObject::sender()); + if(!controller) + return; + auto id = controller->id(); + auto & extras = m_instanceExtras[id]; + + // on failure, do... nothing + extras.controller.reset(); + subRunningInstance(); + + // quit when there are no more windows. + if(shouldExitNow()) + { + m_status = Status::Failed; + exit(1); + } +} + +void Application::ShowGlobalSettings(class QWidget* parent, QString open_page) +{ + if(!m_globalSettingsProvider) { + return; + } + emit globalSettingsAboutToOpen(); + { + SettingsObject::Lock lock(APPLICATION->settings()); + PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); + dlg.exec(); + } + emit globalSettingsClosed(); +} + +MainWindow* Application::showMainWindow(bool minimized) +{ + if(m_mainWindow) + { + m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized); + m_mainWindow->raise(); + m_mainWindow->activateWindow(); + } + else + { + m_mainWindow = new MainWindow(); + m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); + m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); + if(minimized) + { + m_mainWindow->showMinimized(); + } + else + { + m_mainWindow->show(); + } + + m_mainWindow->checkInstancePathForProblems(); + connect(this, &Application::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); + connect(m_mainWindow, &MainWindow::isClosing, this, &Application::on_windowClose); + m_openWindows++; + } + // FIXME: move this somewhere else... + if(m_analytics) + { + auto windowSize = m_mainWindow->size(); + auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height()); + qDebug() << "Viewport size" << sizeString; + m_analytics->setViewportSize(sizeString); + /* + * cm1 = java min heap [MB] + * cm2 = java max heap [MB] + * cm3 = system RAM [MB] + * + * cd1 = java version + * cd2 = java architecture + * cd3 = system architecture + * cd4 = CPU architecture + */ + QVariantMap customValues; + int min = m_settings->get("MinMemAlloc").toInt(); + int max = m_settings->get("MaxMemAlloc").toInt(); + if(min < max) + { + customValues["cm1"] = min; + customValues["cm2"] = max; + } + else + { + customValues["cm1"] = max; + customValues["cm2"] = min; + } + + constexpr uint64_t Mega = 1024ull * 1024ull; + int ramSize = int(Sys::getSystemRam() / Mega); + qDebug() << "RAM size is" << ramSize << "MB"; + customValues["cm3"] = ramSize; + + customValues["cd1"] = m_settings->get("JavaVersion"); + customValues["cd2"] = m_settings->get("JavaArchitecture"); + customValues["cd3"] = Sys::isSystem64bit() ? "64":"32"; + customValues["cd4"] = Sys::isCPU64bit() ? "64":"32"; + auto kernelInfo = Sys::getKernelInfo(); + customValues["cd5"] = kernelInfo.kernelName; + customValues["cd6"] = kernelInfo.kernelVersion; + auto distInfo = Sys::getDistributionInfo(); + if(!distInfo.distributionName.isEmpty()) + { + customValues["cd7"] = distInfo.distributionName; + } + if(!distInfo.distributionVersion.isEmpty()) + { + customValues["cd8"] = distInfo.distributionVersion; + } + m_analytics->sendScreenView("Main Window", customValues); + } + return m_mainWindow; +} + +InstanceWindow *Application::showInstanceWindow(InstancePtr instance, QString page) +{ + if(!instance) + return nullptr; + auto id = instance->id(); + auto & extras = m_instanceExtras[id]; + auto & window = extras.window; + + if(window) + { + window->raise(); + window->activateWindow(); + } + else + { + window = new InstanceWindow(instance); + m_openWindows ++; + connect(window, &InstanceWindow::isClosing, this, &Application::on_windowClose); + } + if(!page.isEmpty()) + { + window->selectPage(page); + } + if(extras.controller) + { + extras.controller->setParentWidget(window); + } + return window; +} + +void Application::on_windowClose() +{ + m_openWindows--; + auto instWindow = qobject_cast(QObject::sender()); + if(instWindow) + { + auto & extras = m_instanceExtras[instWindow->instanceId()]; + extras.window = nullptr; + if(extras.controller) + { + extras.controller->setParentWidget(m_mainWindow); + } + } + auto mainWindow = qobject_cast(QObject::sender()); + if(mainWindow) + { + m_mainWindow = nullptr; + } + // quit when there are no more windows. + if(shouldExitNow()) + { + exit(0); + } +} + +QString Application::msaClientId() const { + return Secrets::getMSAClientID('-'); +} diff --git a/launcher/Application.h b/launcher/Application.h new file mode 100644 index 00000000..ce22a2e8 --- /dev/null +++ b/launcher/Application.h @@ -0,0 +1,239 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "minecraft/launch/MinecraftServerTarget.h" + +class LaunchController; +class LocalPeer; +class InstanceWindow; +class MainWindow; +class SetupWizard; +class FolderInstanceProvider; +class GenericPageProvider; +class QFile; +class HttpMetaCache; +class SettingsObject; +class InstanceList; +class AccountList; +class IconList; +class QNetworkAccessManager; +class JavaInstallList; +class UpdateChecker; +class BaseProfilerFactory; +class BaseDetachedToolFactory; +class TranslationsModel; +class ITheme; +class MCEditTool; +class GAnalytics; + +#if defined(APPLICATION) +#undef APPLICATION +#endif +#define APPLICATION (static_cast(QCoreApplication::instance())) + +class Application : public QApplication +{ + // friends for the purpose of limiting access to deprecated stuff + Q_OBJECT +public: + enum Status + { + StartingUp, + Failed, + Succeeded, + Initialized + }; + +public: + Application(int &argc, char **argv); + virtual ~Application(); + + GAnalytics *analytics() const + { + return m_analytics; + } + + std::shared_ptr settings() const + { + return m_settings; + } + + qint64 timeSinceStart() const + { + return startTime.msecsTo(QDateTime::currentDateTime()); + } + + QIcon getThemedIcon(const QString& name); + + void setIconTheme(const QString& name); + + std::vector getValidApplicationThemes(); + + void setApplicationTheme(const QString& name, bool initial); + + // DownloadUpdateTask + std::shared_ptr updateChecker() + { + return m_updateChecker; + } + + std::shared_ptr translations(); + + std::shared_ptr javalist(); + + std::shared_ptr instances() const + { + return m_instances; + } + + FolderInstanceProvider * folderProvider() const + { + return m_instanceFolder; + } + + std::shared_ptr icons() const + { + return m_icons; + } + + MCEditTool *mcedit() const + { + return m_mcedit.get(); + } + + shared_qobject_ptr accounts() const + { + return m_accounts; + } + + QString msaClientId() const; + + Status status() const + { + return m_status; + } + + const QMap> &profilers() const + { + return m_profilers; + } + + /// this is the root of the 'installation'. Used for automatic updates + const QString &root() + { + return m_rootPath; + } + + /*! + * Opens a json file using either a system default editor, or, if not empty, the editor + * specified in the settings + */ + bool openJsonEditor(const QString &filename); + + InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString()); + MainWindow *showMainWindow(bool minimized = false); + + void updateIsRunning(bool running); + bool updatesAreAllowed(); + + void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); + +signals: + void updateAllowedChanged(bool status); + void globalSettingsAboutToOpen(); + void globalSettingsClosed(); + +public slots: + bool launch( + InstancePtr instance, + bool online = true, + BaseProfilerFactory *profiler = nullptr, + MinecraftServerTargetPtr serverToJoin = nullptr, + MinecraftAccountPtr accountToUse = nullptr + ); + bool kill(InstancePtr instance); + +private slots: + void on_windowClose(); + void messageReceived(const QByteArray & message); + void controllerSucceeded(); + void controllerFailed(const QString & error); + void analyticsSettingChanged(const Setting &setting, QVariant value); + void setupWizardFinished(int status); + +private: + bool createSetupWizard(); + void performMainStartupAction(); + + // sets the fatal error message and m_status to Failed. + void showFatalErrorMessage(const QString & title, const QString & content); + +private: + void addRunningInstance(); + void subRunningInstance(); + bool shouldExitNow() const; + +private: + QDateTime startTime; + + std::shared_ptr m_settings; + std::shared_ptr m_instances; + FolderInstanceProvider * m_instanceFolder = nullptr; + std::shared_ptr m_icons; + std::shared_ptr m_updateChecker; + shared_qobject_ptr m_accounts; + std::shared_ptr m_javalist; + std::shared_ptr m_translations; + std::shared_ptr m_globalSettingsProvider; + std::map> m_themes; + std::unique_ptr m_mcedit; + + QMap> m_profilers; + + QString m_rootPath; + Status m_status = Application::StartingUp; + +#if defined Q_OS_WIN32 + // used on Windows to attach the standard IO streams + bool consoleAttached = false; +#endif + + // FIXME: attach to instances instead. + struct InstanceXtras + { + InstanceWindow * window = nullptr; + shared_qobject_ptr controller; + }; + std::map m_instanceExtras; + + // main state variables + size_t m_openWindows = 0; + size_t m_runningInstances = 0; + bool m_updateRunning = false; + + // main window, if any + MainWindow * m_mainWindow = nullptr; + + // peer launcher instance connector - used to implement single instance launcher and signalling + LocalPeer * m_peerInstance = nullptr; + + GAnalytics * m_analytics = nullptr; + SetupWizard * m_setupWizard = nullptr; +public: + QString m_instanceIdToLaunch; + QString m_serverToJoin; + QString m_profileToUse; + bool m_liveCheck = false; + QUrl m_zipToImport; + std::unique_ptr logFile; +}; diff --git a/launcher/ApplicationMessage.cpp b/launcher/ApplicationMessage.cpp new file mode 100644 index 00000000..e22bf13c --- /dev/null +++ b/launcher/ApplicationMessage.cpp @@ -0,0 +1,31 @@ +#include "ApplicationMessage.h" + +#include +#include + +void ApplicationMessage::parse(const QByteArray & input) { + auto doc = QJsonDocument::fromBinaryData(input); + auto root = doc.object(); + + command = root.value("command").toString(); + args.clear(); + + auto parsedArgs = root.value("args").toObject(); + for(auto iter = parsedArgs.begin(); iter != parsedArgs.end(); iter++) { + args[iter.key()] = iter.value().toString(); + } +} + +QByteArray ApplicationMessage::serialize() { + QJsonObject root; + root.insert("command", command); + QJsonObject outArgs; + for (auto iter = args.begin(); iter != args.end(); iter++) { + outArgs[iter.key()] = iter.value(); + } + root.insert("args", outArgs); + + QJsonDocument out; + out.setObject(root); + return out.toBinaryData(); +} diff --git a/launcher/ApplicationMessage.h b/launcher/ApplicationMessage.h new file mode 100644 index 00000000..745bdead --- /dev/null +++ b/launcher/ApplicationMessage.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include + +struct ApplicationMessage { + QString command; + QMap args; + + QByteArray serialize(); + void parse(const QByteArray & input); +}; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 0aeadd51..f9a4327d 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -564,12 +564,12 @@ set(LOGIC_SOURCES SET(LAUNCHER_SOURCES # Application base - Launcher.h - Launcher.cpp + Application.h + Application.cpp UpdateController.cpp UpdateController.h - LauncherMessage.h - LauncherMessage.cpp + ApplicationMessage.h + ApplicationMessage.cpp # GUI - general utilities DesktopServices.h diff --git a/launcher/Env.cpp b/launcher/Env.cpp index 630ba534..1ca82e4b 100644 --- a/launcher/Env.cpp +++ b/launcher/Env.cpp @@ -39,13 +39,13 @@ Env::~Env() delete d; } -Env& Env::Env::getInstance() +Env* Env::Env::getInstance() { if(!instance) { instance = new Env(); } - return *instance; + return instance; } void Env::dispose() diff --git a/launcher/Env.h b/launcher/Env.h index 8002a183..cbf31732 100644 --- a/launcher/Env.h +++ b/launcher/Env.h @@ -25,14 +25,14 @@ class Index; class Env { - friend class Launcher; + friend class Application; private: struct Private; Env(); ~Env(); static void dispose(); public: - static Env& getInstance(); + static Env* getInstance(); QNetworkAccessManager &network() const; diff --git a/launcher/GuiUtil.cpp b/launcher/GuiUtil.cpp index 3dd31c7a..7988bbf8 100644 --- a/launcher/GuiUtil.cpp +++ b/launcher/GuiUtil.cpp @@ -8,7 +8,7 @@ #include "net/PasteUpload.h" #include "dialogs/CustomMessageBox.h" -#include "Launcher.h" +#include "Application.h" #include #include #include @@ -16,7 +16,7 @@ QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget) { ProgressDialog dialog(parentWidget); - auto APIKeySetting = LAUNCHER->settings()->get("PasteEEAPIKey").toString(); + auto APIKeySetting = APPLICATION->settings()->get("PasteEEAPIKey").toString(); if(APIKeySetting == "multimc") { APIKeySetting = BuildConfig.PASTE_EE_KEY; diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 3eac4d57..77beda66 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -51,7 +51,7 @@ void InstanceImportTask::executeTask() m_downloadRequired = true; const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path(); - auto entry = ENV.metacache()->resolveEntry("general", path); + auto entry = ENV->metacache()->resolveEntry("general", path); entry->setStale(true); m_filesNetJob.reset(new NetJob(tr("Modpack download"))); m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry)); @@ -444,7 +444,7 @@ void InstanceImportTask::processMultiMC() if (!importIconPath.isNull() && QFile::exists(importIconPath)) { // import icon - auto iconList = ENV.icons(); + auto iconList = ENV->icons(); if (iconList->iconFileExists(m_instIcon)) { iconList->deleteIcon(m_instIcon); diff --git a/launcher/InstanceWindow.cpp b/launcher/InstanceWindow.cpp index 8f73671b..de870839 100644 --- a/launcher/InstanceWindow.cpp +++ b/launcher/InstanceWindow.cpp @@ -14,7 +14,7 @@ */ #include "InstanceWindow.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -35,7 +35,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) { setAttribute(Qt::WA_DeleteOnClose); - auto icon = LAUNCHER->icons()->getIcon(m_instance->iconKey()); + auto icon = APPLICATION->icons()->getIcon(m_instance->iconKey()); QString windowTitle = tr("Console window for ") + m_instance->name(); // Set window properties @@ -87,9 +87,9 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) // restore window state { - auto base64State = LAUNCHER->settings()->get("ConsoleWindowState").toByteArray(); + auto base64State = APPLICATION->settings()->get("ConsoleWindowState").toByteArray(); restoreState(QByteArray::fromBase64(base64State)); - auto base64Geometry = LAUNCHER->settings()->get("ConsoleWindowGeometry").toByteArray(); + auto base64Geometry = APPLICATION->settings()->get("ConsoleWindowGeometry").toByteArray(); restoreGeometry(QByteArray::fromBase64(base64Geometry)); } @@ -148,7 +148,7 @@ void InstanceWindow::updateLaunchButtons() void InstanceWindow::on_btnLaunchMinecraftOffline_clicked() { - LAUNCHER->launch(m_instance, false, nullptr); + APPLICATION->launch(m_instance, false, nullptr); } void InstanceWindow::on_InstanceLaunchTask_changed(shared_qobject_ptr proc) @@ -183,8 +183,8 @@ void InstanceWindow::closeEvent(QCloseEvent *event) return; } - LAUNCHER->settings()->set("ConsoleWindowState", saveState().toBase64()); - LAUNCHER->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("ConsoleWindowState", saveState().toBase64()); + APPLICATION->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); emit isClosing(); event->accept(); } @@ -198,11 +198,11 @@ void InstanceWindow::on_btnKillMinecraft_clicked() { if(m_instance->isRunning()) { - LAUNCHER->kill(m_instance); + APPLICATION->kill(m_instance); } else { - LAUNCHER->launch(m_instance, true, nullptr); + APPLICATION->launch(m_instance, true, nullptr); } } diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 9edccaf2..3ecb0134 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -1,7 +1,7 @@ #include "LaunchController.h" #include "MainWindow.h" #include -#include "Launcher.h" +#include "Application.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/ProfileSelectDialog.h" #include "dialogs/ProgressDialog.h" @@ -42,7 +42,7 @@ void LaunchController::decideAccount() } // Find an account to use. - std::shared_ptr accounts = LAUNCHER->accounts(); + auto accounts = APPLICATION->accounts(); if (accounts->count() <= 0) { // Tell the user they need to log in at least one account in order to play. @@ -59,12 +59,12 @@ void LaunchController::decideAccount() if (reply == QMessageBox::Yes) { // Open the account manager. - LAUNCHER->ShowGlobalSettings(m_parentWidget, "accounts"); + APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts"); } } - m_accountToUse = accounts->activeAccount(); - if (m_accountToUse == nullptr) + m_accountToUse = accounts->defaultAccount(); + if (!m_accountToUse) { // If no default account is set, ask the user which one to use. ProfileSelectDialog selectDialog( @@ -80,7 +80,7 @@ void LaunchController::decideAccount() // If the user said to use the account as default, do that. if (selectDialog.useAsGlobalDefault() && m_accountToUse) { - accounts->setActiveAccount(m_accountToUse); + accounts->setDefaultAccount(m_accountToUse); } } } @@ -110,7 +110,7 @@ void LaunchController::login() { { m_session = std::make_shared(); m_session->wants_online = m_online; - std::shared_ptr task; + shared_qobject_ptr task; if(!password.isNull()) { task = m_accountToUse->login(m_session, password); } @@ -294,7 +294,7 @@ void LaunchController::launchInstance() auto showConsole = m_instance->settings()->get("ShowConsole").toBool(); if(!console && showConsole) { - LAUNCHER->showInstanceWindow(m_instance); + APPLICATION->showInstanceWindow(m_instance); } connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded); @@ -400,7 +400,7 @@ void LaunchController::onFailed(QString reason) { if(m_instance->settings()->get("ShowConsoleOnError").toBool()) { - LAUNCHER->showInstanceWindow(m_instance, "console"); + APPLICATION->showInstanceWindow(m_instance, "console"); } emitFailed(reason); } diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp deleted file mode 100644 index 429683a4..00000000 --- a/launcher/Launcher.cpp +++ /dev/null @@ -1,1532 +0,0 @@ -#include "Launcher.h" -#include "BuildConfig.h" -#include "MainWindow.h" -#include "InstanceWindow.h" - -#include "instanceview/AccessibleInstanceView.h" -#include - -#include "pages/BasePageProvider.h" -#include "pages/global/LauncherPage.h" -#include "pages/global/MinecraftPage.h" -#include "pages/global/JavaPage.h" -#include "pages/global/LanguagePage.h" -#include "pages/global/ProxyPage.h" -#include "pages/global/ExternalToolsPage.h" -#include "pages/global/AccountListPage.h" -#include "pages/global/PasteEEPage.h" -#include "pages/global/CustomCommandsPage.h" - -#include "themes/ITheme.h" -#include "themes/SystemTheme.h" -#include "themes/DarkTheme.h" -#include "themes/BrightTheme.h" -#include "themes/CustomTheme.h" - -#include "LauncherMessage.h" - -#include "setupwizard/SetupWizard.h" -#include "setupwizard/LanguageWizardPage.h" -#include "setupwizard/JavaWizardPage.h" -#include "setupwizard/AnalyticsWizardPage.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialogs/CustomMessageBox.h" -#include "InstanceList.h" - -#include -#include "icons/IconList.h" -#include "net/HttpMetaCache.h" -#include "Env.h" - -#include "java/JavaUtils.h" - -#include "updater/UpdateChecker.h" - -#include "tools/JProfiler.h" -#include "tools/JVisualVM.h" -#include "tools/MCEditTool.h" - -#include -#include "settings/INISettingsObject.h" -#include "settings/Setting.h" - -#include "translations/TranslationsModel.h" - -#include -#include -#include -#include - -#include -#include - -#include "pagedialog/PageDialog.h" - - -#if defined Q_OS_WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#endif - -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - -static const QLatin1String liveCheckFile("live.check"); - -using namespace Commandline; - -#define MACOS_HINT "If you are on macOS Sierra, you might have to move the app to your /Applications or ~/Applications folder. "\ - "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ - "\n" - -namespace { -void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) -{ - const char *levels = "DWCFIS"; - const QString format("%1 %2 %3\n"); - - qint64 msecstotal = LAUNCHER->timeSinceStart(); - qint64 seconds = msecstotal / 1000; - qint64 msecs = msecstotal % 1000; - QString foo; - char buf[1025] = {0}; - ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs); - - QString out = format.arg(buf).arg(levels[type]).arg(msg); - - LAUNCHER->logFile->write(out.toUtf8()); - LAUNCHER->logFile->flush(); - QTextStream(stderr) << out.toLocal8Bit(); - fflush(stderr); -} - -QString getIdealPlatform(QString currentPlatform) { - auto info = Sys::getKernelInfo(); - switch(info.kernelType) { - case Sys::KernelType::Darwin: { - if(info.kernelMajor >= 17) { - // macOS 10.13 or newer - return "osx64-5.15.2"; - } - else { - // macOS 10.12 or older - return "osx64"; - } - } - case Sys::KernelType::Windows: { - // FIXME: 5.15.2 is not stable on Windows, due to a large number of completely unpredictable and hard to reproduce issues - break; -/* - if(info.kernelMajor == 6 && info.kernelMinor >= 1) { - // Windows 7 - return "win32-5.15.2"; - } - else if (info.kernelMajor > 6) { - // Above Windows 7 - return "win32-5.15.2"; - } - else { - // Below Windows 7 - return "win32"; - } -*/ - } - case Sys::KernelType::Undetermined: - case Sys::KernelType::Linux: { - break; - } - } - return currentPlatform; -} - -} - -Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) -{ -#if defined Q_OS_WIN32 - // attach the parent console - if(AttachConsole(ATTACH_PARENT_PROCESS)) - { - // if attach succeeds, reopen and sync all the i/o - if(freopen("CON", "w", stdout)) - { - std::cout.sync_with_stdio(); - } - if(freopen("CON", "w", stderr)) - { - std::cerr.sync_with_stdio(); - } - if(freopen("CON", "r", stdin)) - { - std::cin.sync_with_stdio(); - } - auto out = GetStdHandle (STD_OUTPUT_HANDLE); - DWORD written; - const char * endline = "\n"; - WriteConsole(out, endline, strlen(endline), &written, NULL); - consoleAttached = true; - } -#endif - setOrganizationName(BuildConfig.LAUNCHER_NAME); - setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN); - setApplicationName(BuildConfig.LAUNCHER_NAME); - setApplicationDisplayName(BuildConfig.LAUNCHER_DISPLAYNAME); - setApplicationVersion(BuildConfig.printableVersionString()); - - startTime = QDateTime::currentDateTime(); - -#ifdef Q_OS_LINUX - { - QFile osrelease("/proc/sys/kernel/osrelease"); - if (osrelease.open(QFile::ReadOnly | QFile::Text)) { - QTextStream in(&osrelease); - auto contents = in.readAll(); - if( - contents.contains("WSL", Qt::CaseInsensitive) || - contents.contains("Microsoft", Qt::CaseInsensitive) - ) { - showFatalErrorMessage( - "Unsupported system detected!", - "Linux-on-Windows distributions are not supported.\n\n" - "Please use the Windows binary when playing on Windows." - ); - return; - } - } - } -#endif - - // Don't quit on hiding the last window - this->setQuitOnLastWindowClosed(false); - - // Commandline parsing - QHash args; - { - Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals); - - // --help - parser.addSwitch("help"); - parser.addShortOpt("help", 'h'); - parser.addDocumentation("help", "Display this help and exit."); - // --version - parser.addSwitch("version"); - parser.addShortOpt("version", 'V'); - parser.addDocumentation("version", "Display program version and exit."); - // --dir - parser.addOption("dir"); - parser.addShortOpt("dir", 'd'); - parser.addDocumentation("dir", "Use the supplied folder as application root instead of the binary location (use '.' for current)"); - // --launch - parser.addOption("launch"); - parser.addShortOpt("launch", 'l'); - parser.addDocumentation("launch", "Launch the specified instance (by instance ID)"); - // --server - parser.addOption("server"); - parser.addShortOpt("server", 's'); - parser.addDocumentation("server", "Join the specified server on launch (only valid in combination with --launch)"); - // --profile - parser.addOption("profile"); - parser.addShortOpt("profile", 'a'); - parser.addDocumentation("profile", "Use the account specified by its profile name (only valid in combination with --launch)"); - // --alive - parser.addSwitch("alive"); - parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"); - // --import - parser.addOption("import"); - parser.addShortOpt("import", 'I'); - parser.addDocumentation("import", "Import instance from specified zip (local path or URL)"); - - // parse the arguments - try - { - args = parser.parse(arguments()); - } - catch (const ParsingError &e) - { - std::cerr << "CommandLineError: " << e.what() << std::endl; - if(argc > 0) - std::cerr << "Try '" << argv[0] << " -h' to get help on command line parameters." - << std::endl; - m_status = Launcher::Failed; - return; - } - - // display help and exit - if (args["help"].toBool()) - { - std::cout << qPrintable(parser.compileHelp(arguments()[0])); - m_status = Launcher::Succeeded; - return; - } - - // display version and exit - if (args["version"].toBool()) - { - std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl; - std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl; - m_status = Launcher::Succeeded; - return; - } - } - m_instanceIdToLaunch = args["launch"].toString(); - m_serverToJoin = args["server"].toString(); - m_profileToUse = args["profile"].toString(); - m_liveCheck = args["alive"].toBool(); - m_zipToImport = args["import"].toUrl(); - - QString origcwdPath = QDir::currentPath(); - QString binPath = applicationDirPath(); - QString adjustedBy; - QString dataPath; - // change folder - QString dirParam = args["dir"].toString(); - if (!dirParam.isEmpty()) - { - // the dir param. it makes multimc data path point to whatever the user specified - // on command line - adjustedBy += "Command line " + dirParam; - dataPath = dirParam; - } - else - { -#if defined(Q_OS_MAC) - QDir foo(FS::PathCombine(applicationDirPath(), "../../Data")); - dataPath = foo.absolutePath(); - adjustedBy += "Fallback to special Mac location " + dataPath; -#else - dataPath = applicationDirPath(); - adjustedBy += "Fallback to binary path " + dataPath; -#endif - } - - if (!FS::ensureFolderPathExists(dataPath)) - { - showFatalErrorMessage( - "The launcher data folder could not be created.", - "The launcher data folder could not be created.\n" - "\n" -#if defined(Q_OS_MAC) - MACOS_HINT -#endif - "Make sure you have the right permissions to the launcher data folder and any folder needed to access it.\n" - "\n" - "The launcher cannot continue until you fix this problem." - ); - return; - } - if (!QDir::setCurrent(dataPath)) - { - showFatalErrorMessage( - "The launcher data folder could not be opened.", - "The launcher data folder could not be opened.\n" - "\n" -#if defined(Q_OS_MAC) - MACOS_HINT -#endif - "Make sure you have the right permissions to the launcher data folder.\n" - "\n" - "The launcher cannot continue until you fix this problem." - ); - return; - } - - if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty()) - { - std::cerr << "--server can only be used in combination with --launch!" << std::endl; - m_status = Launcher::Failed; - return; - } - - if(m_instanceIdToLaunch.isEmpty() && !m_profileToUse.isEmpty()) - { - std::cerr << "--account can only be used in combination with --launch!" << std::endl; - m_status = Launcher::Failed; - return; - } - -#if defined(Q_OS_MAC) - // move user data to new location if on macOS and it still exists in Contents/MacOS - QDir fi(applicationDirPath()); - QString originalData = fi.absolutePath(); - // if the config file exists in Contents/MacOS, then user data is still there and needs to moved - if (QFileInfo::exists(FS::PathCombine(originalData, BuildConfig.LAUNCHER_CONFIGFILE))) - { - if (!QFileInfo::exists(FS::PathCombine(originalData, "dontmovemacdata"))) - { - QMessageBox::StandardButton askMoveDialogue; - askMoveDialogue = QMessageBox::question( - nullptr, - BuildConfig.LAUNCHER_DISPLAYNAME, - "Would you like to move application data to a new data location? It will improve the launcher's performance, but if you switch to older versions it will look like instances have disappeared. If you select no, you can migrate later in settings. You should select yes unless you're commonly switching between different versions (eg. develop and stable).", - QMessageBox::Yes | QMessageBox::No, - QMessageBox::Yes - ); - if (askMoveDialogue == QMessageBox::Yes) - { - qDebug() << "On macOS and found config file in old location, moving user data..."; - QDir dir; - QStringList dataFiles { - "*.log", // Launcher log files: ${Launcher_Name}-@.log - "accounts.json", - "accounts", - "assets", - "cache", - "icons", - "instances", - "libraries", - "meta", - "metacache", - "mods", - BuildConfig.LAUNCHER_CONFIGFILE, - "themes", - "translations" - }; - QDirIterator files(originalData, dataFiles); - while (files.hasNext()) { - QString filePath(files.next()); - QString fileName(files.fileName()); - if (!dir.rename(filePath, FS::PathCombine(dataPath, fileName))) - { - qWarning() << "Failed to move " << fileName; - } - } - } - else - { - dataPath = originalData; - QDir::setCurrent(dataPath); - QFile file(originalData + "/dontmovemacdata"); - file.open(QIODevice::WriteOnly); - } - } - else - { - dataPath = originalData; - QDir::setCurrent(dataPath); - } - } -#endif - - /* - * Establish the mechanism for communication with an already running MultiMC that uses the same data path. - * If there is one, tell it what the user actually wanted to do and exit. - * We want to initialize this before logging to avoid messing with the log of a potential already running copy. - */ - auto appID = ApplicationId::fromPathAndVersion(QDir::currentPath(), BuildConfig.printableVersionString()); - { - // FIXME: you can run the same binaries with multiple data dirs and they won't clash. This could cause issues for updates. - m_peerInstance = new LocalPeer(this, appID); - connect(m_peerInstance, &LocalPeer::messageReceived, this, &Launcher::messageReceived); - if(m_peerInstance->isClient()) { - int timeout = 2000; - - if(m_instanceIdToLaunch.isEmpty()) - { - LauncherMessage activate; - activate.command = "activate"; - m_peerInstance->sendMessage(activate.serialize(), timeout); - - if(!m_zipToImport.isEmpty()) - { - LauncherMessage import; - import.command = "import"; - import.args.insert("path", m_zipToImport.toString()); - m_peerInstance->sendMessage(import.serialize(), timeout); - } - } - else - { - LauncherMessage launch; - launch.command = "launch"; - launch.args["id"] = m_instanceIdToLaunch; - - if(!m_serverToJoin.isEmpty()) - { - launch.args["server"] = m_serverToJoin; - } - if(!m_profileToUse.isEmpty()) - { - launch.args["profile"] = m_profileToUse; - } - m_peerInstance->sendMessage(launch.serialize(), timeout); - } - m_status = Launcher::Succeeded; - return; - } - } - - // init the logger - { - static const QString logBase = BuildConfig.LAUNCHER_NAME + "-%0.log"; - auto moveFile = [](const QString &oldName, const QString &newName) - { - QFile::remove(newName); - QFile::copy(oldName, newName); - QFile::remove(oldName); - }; - - moveFile(logBase.arg(3), logBase.arg(4)); - moveFile(logBase.arg(2), logBase.arg(3)); - moveFile(logBase.arg(1), logBase.arg(2)); - moveFile(logBase.arg(0), logBase.arg(1)); - - logFile = std::unique_ptr(new QFile(logBase.arg(0))); - if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) - { - showFatalErrorMessage( - "The launcher data folder is not writable!", - "The launcher couldn't create a log file - the data folder is not writable.\n" - "\n" - #if defined(Q_OS_MAC) - MACOS_HINT - #endif - "Make sure you have write permissions to the data folder.\n" - "\n" - "The launcher cannot continue until you fix this problem." - ); - return; - } - qInstallMessageHandler(appDebugOutput); - qDebug() << "<> Log initialized."; - } - - // Set up paths - { - // Root path is used for updates. -#ifdef Q_OS_LINUX - QDir foo(FS::PathCombine(binPath, "..")); - m_rootPath = foo.absolutePath(); -#elif defined(Q_OS_WIN32) - m_rootPath = binPath; -#elif defined(Q_OS_MAC) - QDir foo(FS::PathCombine(binPath, "../..")); - m_rootPath = foo.absolutePath(); - // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues) - FS::updateTimestamp(m_rootPath); -#endif - -#ifdef MULTIMC_JARS_LOCATION - ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); -#endif - - qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; - qDebug() << "Version : " << BuildConfig.printableVersionString(); - qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; - qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; - if (adjustedBy.size()) - { - qDebug() << "Work dir before adjustment : " << origcwdPath; - qDebug() << "Work dir after adjustment : " << QDir::currentPath(); - qDebug() << "Adjusted by : " << adjustedBy; - } - else - { - qDebug() << "Work dir : " << QDir::currentPath(); - } - qDebug() << "Binary path : " << binPath; - qDebug() << "Application root path : " << m_rootPath; - if(!m_instanceIdToLaunch.isEmpty()) - { - qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; - } - if(!m_serverToJoin.isEmpty()) - { - qDebug() << "Address of server to join :" << m_serverToJoin; - } - qDebug() << "<> Paths set."; - } - - do // once - { - if(m_liveCheck) - { - QFile check(liveCheckFile); - if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - qWarning() << "Could not open" << liveCheckFile << "for writing!"; - break; - } - auto payload = appID.toString().toUtf8(); - if(check.write(payload) != payload.size()) - { - qWarning() << "Could not write into" << liveCheckFile << "!"; - check.remove(); - break; - } - check.close(); - } - } while(false); - - // Initialize application settings - { - m_settings.reset(new INISettingsObject(BuildConfig.LAUNCHER_CONFIGFILE, this)); - // Updates - m_settings->registerSetting("UpdateChannel", BuildConfig.VERSION_CHANNEL); - m_settings->registerSetting("AutoUpdate", true); - - // Theming - m_settings->registerSetting("IconTheme", QString("multimc")); - m_settings->registerSetting("ApplicationTheme", QString("system")); - - // Notifications - m_settings->registerSetting("ShownNotifications", QString()); - - // Remembered state - m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); - - QString defaultMonospace; - int defaultSize = 11; -#ifdef Q_OS_WIN32 - defaultMonospace = "Courier"; - defaultSize = 10; -#elif defined(Q_OS_MAC) - defaultMonospace = "Menlo"; -#else - defaultMonospace = "Monospace"; -#endif - - // resolve the font so the default actually matches - QFont consoleFont; - consoleFont.setFamily(defaultMonospace); - consoleFont.setStyleHint(QFont::Monospace); - consoleFont.setFixedPitch(true); - QFontInfo consoleFontInfo(consoleFont); - QString resolvedDefaultMonospace = consoleFontInfo.family(); - QFont resolvedFont(resolvedDefaultMonospace); - qDebug() << "Detected default console font:" << resolvedDefaultMonospace - << ", substitutions:" << resolvedFont.substitutions().join(','); - - m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace); - m_settings->registerSetting("ConsoleFontSize", defaultSize); - m_settings->registerSetting("ConsoleMaxLines", 100000); - m_settings->registerSetting("ConsoleOverflowStop", true); - - // Folders - m_settings->registerSetting("InstanceDir", "instances"); - m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods"); - m_settings->registerSetting("IconsDir", "icons"); - - // Editors - m_settings->registerSetting("JsonEditor", QString()); - - // Language - m_settings->registerSetting("Language", QString()); - - // Console - m_settings->registerSetting("ShowConsole", false); - m_settings->registerSetting("AutoCloseConsole", false); - m_settings->registerSetting("ShowConsoleOnError", true); - m_settings->registerSetting("LogPrePostOutput", true); - - // Window Size - m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false); - m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854); - m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480); - - // Proxy Settings - m_settings->registerSetting("ProxyType", "None"); - m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1"); - m_settings->registerSetting("ProxyPort", 8080); - m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, ""); - m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, ""); - - // Memory - m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); - m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024); - m_settings->registerSetting("PermGen", 128); - - // Java Settings - m_settings->registerSetting("JavaPath", ""); - m_settings->registerSetting("JavaTimestamp", 0); - m_settings->registerSetting("JavaArchitecture", ""); - m_settings->registerSetting("JavaVersion", ""); - m_settings->registerSetting("JavaVendor", ""); - m_settings->registerSetting("LastHostname", ""); - m_settings->registerSetting("JvmArgs", ""); - - // Native library workarounds - m_settings->registerSetting("UseNativeOpenAL", false); - m_settings->registerSetting("UseNativeGLFW", false); - - // Game time - m_settings->registerSetting("ShowGameTime", true); - m_settings->registerSetting("ShowGlobalGameTime", true); - m_settings->registerSetting("RecordGameTime", true); - - // Minecraft launch method - m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); - - // Wrapper command for launch - m_settings->registerSetting("WrapperCommand", ""); - - // Custom Commands - m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, ""); - m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, ""); - - // The cat - m_settings->registerSetting("TheCat", false); - - m_settings->registerSetting("InstSortMode", "Name"); - m_settings->registerSetting("SelectedInstance", QString()); - - // Window state and geometry - m_settings->registerSetting("MainWindowState", ""); - m_settings->registerSetting("MainWindowGeometry", ""); - - m_settings->registerSetting("ConsoleWindowState", ""); - m_settings->registerSetting("ConsoleWindowGeometry", ""); - - m_settings->registerSetting("SettingsGeometry", ""); - - m_settings->registerSetting("PagedGeometry", ""); - - m_settings->registerSetting("NewInstanceGeometry", ""); - - m_settings->registerSetting("UpdateDialogGeometry", ""); - - // paste.ee API key - m_settings->registerSetting("PasteEEAPIKey", "multimc"); - - if(!BuildConfig.ANALYTICS_ID.isEmpty()) - { - // Analytics - m_settings->registerSetting("Analytics", true); - m_settings->registerSetting("AnalyticsSeen", 0); - m_settings->registerSetting("AnalyticsClientID", QString()); - } - - // Init page provider - { - m_globalSettingsProvider = std::make_shared(tr("Settings")); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - } - qDebug() << "<> Settings loaded."; - } - -#ifndef QT_NO_ACCESSIBILITY - QAccessible::installFactory(groupViewAccessibleFactory); -#endif /* !QT_NO_ACCESSIBILITY */ - - // load translations - { - m_translations.reset(new TranslationsModel("translations")); - auto bcp47Name = m_settings->get("Language").toString(); - m_translations->selectLanguage(bcp47Name); - qDebug() << "Your language is" << bcp47Name; - qDebug() << "<> Translations loaded."; - } - - // initialize the updater - if(BuildConfig.UPDATER_ENABLED) - { - auto platform = getIdealPlatform(BuildConfig.BUILD_PLATFORM); - auto channelUrl = BuildConfig.UPDATER_BASE + platform + "/channels.json"; - qDebug() << "Initializing updater with platform: " << platform << " -- " << channelUrl; - m_updateChecker.reset(new UpdateChecker(channelUrl, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); - qDebug() << "<> Updater started."; - } - - // Instance icons - { - auto setting = LAUNCHER->settings()->getSetting("IconsDir"); - QStringList instFolders = - { - ":/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())); - connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) - { - m_icons->directoryChanged(value.toString()); - }); - ENV.registerIconList(m_icons); - qDebug() << "<> Instance icons intialized."; - } - - // Icon themes - { - // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! - // set icon theme search path! - auto searchPaths = QIcon::themeSearchPaths(); - searchPaths.append("iconthemes"); - QIcon::setThemeSearchPaths(searchPaths); - qDebug() << "<> Icon themes initialized."; - } - - // Initialize widget themes - { - auto insertTheme = [this](ITheme * theme) - { - m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); - }; - auto darkTheme = new DarkTheme(); - insertTheme(new SystemTheme()); - insertTheme(darkTheme); - insertTheme(new BrightTheme()); - insertTheme(new CustomTheme(darkTheme, "custom")); - qDebug() << "<> Widget themes initialized."; - } - - // initialize and load all instances - { - auto InstDirSetting = m_settings->getSetting("InstanceDir"); - // instance path: check for problems with '!' in instance path and warn the user in the log - // and remember that we have to show him a dialog when the gui starts (if it does so) - QString instDir = InstDirSetting->get().toString(); - qDebug() << "Instance path : " << instDir; - if (FS::checkProblemticPathJava(QDir(instDir))) - { - qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!"; - } - m_instances.reset(new InstanceList(m_settings, instDir, this)); - connect(InstDirSetting.get(), &Setting::SettingChanged, m_instances.get(), &InstanceList::on_InstFolderChanged); - qDebug() << "Loading Instances..."; - m_instances->loadList(); - qDebug() << "<> Instances loaded."; - } - - // and accounts - { - m_accounts.reset(new AccountList(this)); - qDebug() << "Loading accounts..."; - m_accounts->setListFilePath("accounts.json", true); - m_accounts->loadList(); - qDebug() << "<> Accounts loaded."; - } - - // init the http meta cache - { - ENV.initHttpMetaCache(); - qDebug() << "<> Cache initialized."; - } - - // init proxy settings - { - QString proxyTypeStr = settings()->get("ProxyType").toString(); - QString addr = settings()->get("ProxyAddr").toString(); - int port = settings()->get("ProxyPort").value(); - QString user = settings()->get("ProxyUser").toString(); - QString pass = settings()->get("ProxyPass").toString(); - ENV.updateProxySettings(proxyTypeStr, addr, port, user, pass); - qDebug() << "<> Proxy settings done."; - } - - // now we have network, download translation updates - m_translations->downloadIndex(); - - //FIXME: what to do with these? - m_profilers.insert("jprofiler", std::shared_ptr(new JProfilerFactory())); - m_profilers.insert("jvisualvm", std::shared_ptr(new JVisualVMFactory())); - for (auto profiler : m_profilers.values()) - { - profiler->registerSettings(m_settings); - } - - // Create the MCEdit thing... why is this here? - { - m_mcedit.reset(new MCEditTool(m_settings)); - } - - connect(this, &Launcher::aboutToQuit, [this](){ - if(m_instances) - { - // save any remaining instance state - m_instances->saveNow(); - } - if(logFile) - { - logFile->flush(); - logFile->close(); - } - }); - - { - setIconTheme(settings()->get("IconTheme").toString()); - qDebug() << "<> Icon theme set."; - setApplicationTheme(settings()->get("ApplicationTheme").toString(), true); - qDebug() << "<> Application theme set."; - } - - // Initialize analytics - [this]() - { - const int analyticsVersion = 2; - if(BuildConfig.ANALYTICS_ID.isEmpty()) - { - return; - } - - auto analyticsSetting = m_settings->getSetting("Analytics"); - connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Launcher::analyticsSettingChanged); - QString clientID = m_settings->get("AnalyticsClientID").toString(); - if(clientID.isEmpty()) - { - clientID = QUuid::createUuid().toString(); - clientID.remove(QLatin1Char('{')); - clientID.remove(QLatin1Char('}')); - m_settings->set("AnalyticsClientID", clientID); - } - m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this); - m_analytics->setLogLevel(GAnalytics::Debug); - m_analytics->setAnonymizeIPs(true); - m_analytics->setNetworkAccessManager(&ENV.network()); - - if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version()) - { - qDebug() << "Analytics info not seen by user yet (or old version)."; - return; - } - if(!m_settings->get("Analytics").toBool()) - { - qDebug() << "Analytics disabled by user."; - return; - } - - m_analytics->enable(); - qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID; - }(); - - if(createSetupWizard()) - { - return; - } - performMainStartupAction(); -} - -bool Launcher::createSetupWizard() -{ - bool javaRequired = [&]() - { - QString currentHostName = QHostInfo::localHostName(); - QString oldHostName = settings()->get("LastHostname").toString(); - if (currentHostName != oldHostName) - { - settings()->set("LastHostname", currentHostName); - return true; - } - QString currentJavaPath = settings()->get("JavaPath").toString(); - QString actualPath = FS::ResolveExecutable(currentJavaPath); - if (actualPath.isNull()) - { - return true; - } - return false; - }(); - bool analyticsRequired = [&]() - { - if(BuildConfig.ANALYTICS_ID.isEmpty()) - { - return false; - } - if (!settings()->get("Analytics").toBool()) - { - return false; - } - if (settings()->get("AnalyticsSeen").toInt() < analytics()->version()) - { - return true; - } - return false; - }(); - bool languageRequired = [&]() - { - if (settings()->get("Language").toString().isEmpty()) - return true; - return false; - }(); - bool wizardRequired = javaRequired || analyticsRequired || languageRequired; - - if(wizardRequired) - { - m_setupWizard = new SetupWizard(nullptr); - if (languageRequired) - { - m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard)); - } - if (javaRequired) - { - m_setupWizard->addPage(new JavaWizardPage(m_setupWizard)); - } - if(analyticsRequired) - { - m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard)); - } - connect(m_setupWizard, &QDialog::finished, this, &Launcher::setupWizardFinished); - m_setupWizard->show(); - return true; - } - return false; -} - -void Launcher::setupWizardFinished(int status) -{ - qDebug() << "Wizard result =" << status; - performMainStartupAction(); -} - -void Launcher::performMainStartupAction() -{ - m_status = Launcher::Initialized; - if(!m_instanceIdToLaunch.isEmpty()) - { - auto inst = instances()->getInstanceById(m_instanceIdToLaunch); - if(inst) - { - MinecraftServerTargetPtr serverToJoin = nullptr; - MinecraftAccountPtr accountToUse = nullptr; - - qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; - if(!m_serverToJoin.isEmpty()) - { - // FIXME: validate the server string - serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); - qDebug() << " Launching with server" << m_serverToJoin; - } - - if(!m_profileToUse.isEmpty()) - { - accountToUse = accounts()->getAccountByProfileName(m_profileToUse); - if(!accountToUse) { - return; - } - qDebug() << " Launching with account" << m_profileToUse; - } - - launch(inst, true, nullptr, serverToJoin, accountToUse); - return; - } - } - if(!m_mainWindow) - { - // normal main window - showMainWindow(false); - qDebug() << "<> Main window shown."; - } - if(!m_zipToImport.isEmpty()) - { - qDebug() << "<> Importing instance from zip:" << m_zipToImport; - m_mainWindow->droppedURLs({ m_zipToImport }); - } -} - -void Launcher::showFatalErrorMessage(const QString& title, const QString& content) -{ - m_status = Launcher::Failed; - auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); - dialog->exec(); -} - -Launcher::~Launcher() -{ - // kill the other globals. - Env::dispose(); - - // Shut down logger by setting the logger function to nothing - qInstallMessageHandler(nullptr); - -#if defined Q_OS_WIN32 - // Detach from Windows console - if(consoleAttached) - { - fclose(stdout); - fclose(stdin); - fclose(stderr); - FreeConsole(); - } -#endif -} - -void Launcher::messageReceived(const QByteArray& message) -{ - if(status() != Initialized) - { - qDebug() << "Received message" << message << "while still initializing. It will be ignored."; - return; - } - - LauncherMessage received; - received.parse(message); - - auto & command = received.command; - - if(command == "activate") - { - showMainWindow(); - } - else if(command == "import") - { - QString path = received.args["path"]; - if(path.isEmpty()) - { - qWarning() << "Received" << command << "message without a zip path/URL."; - return; - } - m_mainWindow->droppedURLs({ QUrl(path) }); - } - else if(command == "launch") - { - QString id = received.args["id"]; - QString server = received.args["server"]; - QString profile = received.args["profile"]; - - InstancePtr instance; - if(!id.isEmpty()) { - instance = instances()->getInstanceById(id); - if(!instance) { - qWarning() << "Launch command requires an valid instance ID. " << id << "resolves to nothing."; - return; - } - } - else { - qWarning() << "Launch command called without an instance ID..."; - return; - } - - MinecraftServerTargetPtr serverObject = nullptr; - if(!server.isEmpty()) { - serverObject = std::make_shared(MinecraftServerTarget::parse(server)); - } - - MinecraftAccountPtr accountObject; - if(!profile.isEmpty()) { - accountObject = accounts()->getAccountByProfileName(profile); - if(!accountObject) { - qWarning() << "Launch command requires the specified profile to be valid. " << profile << "does not resolve to any account."; - return; - } - } - - launch( - instance, - true, - nullptr, - serverObject, - accountObject - ); - } - else - { - qWarning() << "Received invalid message" << message; - } -} - -void Launcher::analyticsSettingChanged(const Setting&, QVariant value) -{ - if(!m_analytics) - return; - bool enabled = value.toBool(); - if(enabled) - { - qDebug() << "Analytics enabled by user."; - } - else - { - qDebug() << "Analytics disabled by user."; - } - m_analytics->enable(enabled); -} - -std::shared_ptr Launcher::translations() -{ - return m_translations; -} - -std::shared_ptr Launcher::javalist() -{ - if (!m_javalist) - { - m_javalist.reset(new JavaInstallList()); - } - return m_javalist; -} - -std::vector Launcher::getValidApplicationThemes() -{ - std::vector ret; - auto iter = m_themes.cbegin(); - while (iter != m_themes.cend()) - { - ret.push_back((*iter).second.get()); - iter++; - } - return ret; -} - -void Launcher::setApplicationTheme(const QString& name, bool initial) -{ - auto systemPalette = qApp->palette(); - auto themeIter = m_themes.find(name); - if(themeIter != m_themes.end()) - { - auto & theme = (*themeIter).second; - theme->apply(initial); - } - else - { - qWarning() << "Tried to set invalid theme:" << name; - } -} - -void Launcher::setIconTheme(const QString& name) -{ - XdgIcon::setThemeName(name); -} - -QIcon Launcher::getThemedIcon(const QString& name) -{ - if(name == "logo") { - return QIcon(":/logo.svg"); - } - return XdgIcon::fromTheme(name); -} - -bool Launcher::openJsonEditor(const QString &filename) -{ - const QString file = QDir::current().absoluteFilePath(filename); - if (m_settings->get("JsonEditor").toString().isEmpty()) - { - return DesktopServices::openUrl(QUrl::fromLocalFile(file)); - } - else - { - //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); - return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file}); - } -} - -bool Launcher::launch( - InstancePtr instance, - bool online, - BaseProfilerFactory *profiler, - MinecraftServerTargetPtr serverToJoin, - MinecraftAccountPtr accountToUse -) { - if(m_updateRunning) - { - qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; - } - else if(instance->canLaunch()) - { - auto & extras = m_instanceExtras[instance->id()]; - auto & window = extras.window; - if(window) - { - if(!window->saveAll()) - { - return false; - } - } - auto & controller = extras.controller; - controller.reset(new LaunchController()); - controller->setInstance(instance); - controller->setOnline(online); - controller->setProfiler(profiler); - controller->setServerToJoin(serverToJoin); - controller->setAccountToUse(accountToUse); - if(window) - { - controller->setParentWidget(window); - } - else if(m_mainWindow) - { - controller->setParentWidget(m_mainWindow); - } - connect(controller.get(), &LaunchController::succeeded, this, &Launcher::controllerSucceeded); - connect(controller.get(), &LaunchController::failed, this, &Launcher::controllerFailed); - addRunningInstance(); - controller->start(); - return true; - } - else if (instance->isRunning()) - { - showInstanceWindow(instance, "console"); - return true; - } - else if (instance->canEdit()) - { - showInstanceWindow(instance); - return true; - } - return false; -} - -bool Launcher::kill(InstancePtr instance) -{ - if (!instance->isRunning()) - { - qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; - return false; - } - auto & extras = m_instanceExtras[instance->id()]; - // NOTE: copy of the shared pointer keeps it alive - auto controller = extras.controller; - if(controller) - { - return controller->abort(); - } - return true; -} - -void Launcher::addRunningInstance() -{ - m_runningInstances ++; - if(m_runningInstances == 1) - { - emit updateAllowedChanged(false); - } -} - -void Launcher::subRunningInstance() -{ - if(m_runningInstances == 0) - { - qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF"; - return; - } - m_runningInstances --; - if(m_runningInstances == 0) - { - emit updateAllowedChanged(true); - } -} - -bool Launcher::shouldExitNow() const -{ - return m_runningInstances == 0 && m_openWindows == 0; -} - -bool Launcher::updatesAreAllowed() -{ - return m_runningInstances == 0; -} - -void Launcher::updateIsRunning(bool running) -{ - m_updateRunning = running; -} - - -void Launcher::controllerSucceeded() -{ - auto controller = qobject_cast(QObject::sender()); - if(!controller) - return; - auto id = controller->id(); - auto & extras = m_instanceExtras[id]; - - // on success, do... - if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) - { - if(extras.window) - { - extras.window->close(); - } - } - extras.controller.reset(); - subRunningInstance(); - - // quit when there are no more windows. - if(shouldExitNow()) - { - m_status = Status::Succeeded; - exit(0); - } -} - -void Launcher::controllerFailed(const QString& error) -{ - Q_UNUSED(error); - auto controller = qobject_cast(QObject::sender()); - if(!controller) - return; - auto id = controller->id(); - auto & extras = m_instanceExtras[id]; - - // on failure, do... nothing - extras.controller.reset(); - subRunningInstance(); - - // quit when there are no more windows. - if(shouldExitNow()) - { - m_status = Status::Failed; - exit(1); - } -} - -void Launcher::ShowGlobalSettings(class QWidget* parent, QString open_page) -{ - if(!m_globalSettingsProvider) { - return; - } - emit globalSettingsAboutToOpen(); - { - SettingsObject::Lock lock(LAUNCHER->settings()); - PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); - dlg.exec(); - } - emit globalSettingsClosed(); -} - -MainWindow* Launcher::showMainWindow(bool minimized) -{ - if(m_mainWindow) - { - m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized); - m_mainWindow->raise(); - m_mainWindow->activateWindow(); - } - else - { - m_mainWindow = new MainWindow(); - m_mainWindow->restoreState(QByteArray::fromBase64(LAUNCHER->settings()->get("MainWindowState").toByteArray())); - m_mainWindow->restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("MainWindowGeometry").toByteArray())); - if(minimized) - { - m_mainWindow->showMinimized(); - } - else - { - m_mainWindow->show(); - } - - m_mainWindow->checkInstancePathForProblems(); - connect(this, &Launcher::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); - connect(m_mainWindow, &MainWindow::isClosing, this, &Launcher::on_windowClose); - m_openWindows++; - } - // FIXME: move this somewhere else... - if(m_analytics) - { - auto windowSize = m_mainWindow->size(); - auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height()); - qDebug() << "Viewport size" << sizeString; - m_analytics->setViewportSize(sizeString); - /* - * cm1 = java min heap [MB] - * cm2 = java max heap [MB] - * cm3 = system RAM [MB] - * - * cd1 = java version - * cd2 = java architecture - * cd3 = system architecture - * cd4 = CPU architecture - */ - QVariantMap customValues; - int min = m_settings->get("MinMemAlloc").toInt(); - int max = m_settings->get("MaxMemAlloc").toInt(); - if(min < max) - { - customValues["cm1"] = min; - customValues["cm2"] = max; - } - else - { - customValues["cm1"] = max; - customValues["cm2"] = min; - } - - constexpr uint64_t Mega = 1024ull * 1024ull; - int ramSize = int(Sys::getSystemRam() / Mega); - qDebug() << "RAM size is" << ramSize << "MB"; - customValues["cm3"] = ramSize; - - customValues["cd1"] = m_settings->get("JavaVersion"); - customValues["cd2"] = m_settings->get("JavaArchitecture"); - customValues["cd3"] = Sys::isSystem64bit() ? "64":"32"; - customValues["cd4"] = Sys::isCPU64bit() ? "64":"32"; - auto kernelInfo = Sys::getKernelInfo(); - customValues["cd5"] = kernelInfo.kernelName; - customValues["cd6"] = kernelInfo.kernelVersion; - auto distInfo = Sys::getDistributionInfo(); - if(!distInfo.distributionName.isEmpty()) - { - customValues["cd7"] = distInfo.distributionName; - } - if(!distInfo.distributionVersion.isEmpty()) - { - customValues["cd8"] = distInfo.distributionVersion; - } - m_analytics->sendScreenView("Main Window", customValues); - } - return m_mainWindow; -} - -InstanceWindow *Launcher::showInstanceWindow(InstancePtr instance, QString page) -{ - if(!instance) - return nullptr; - auto id = instance->id(); - auto & extras = m_instanceExtras[id]; - auto & window = extras.window; - - if(window) - { - window->raise(); - window->activateWindow(); - } - else - { - window = new InstanceWindow(instance); - m_openWindows ++; - connect(window, &InstanceWindow::isClosing, this, &Launcher::on_windowClose); - } - if(!page.isEmpty()) - { - window->selectPage(page); - } - if(extras.controller) - { - extras.controller->setParentWidget(window); - } - return window; -} - -void Launcher::on_windowClose() -{ - m_openWindows--; - auto instWindow = qobject_cast(QObject::sender()); - if(instWindow) - { - auto & extras = m_instanceExtras[instWindow->instanceId()]; - extras.window = nullptr; - if(extras.controller) - { - extras.controller->setParentWidget(m_mainWindow); - } - } - auto mainWindow = qobject_cast(QObject::sender()); - if(mainWindow) - { - m_mainWindow = nullptr; - } - // quit when there are no more windows. - if(shouldExitNow()) - { - exit(0); - } -} diff --git a/launcher/Launcher.h b/launcher/Launcher.h deleted file mode 100644 index 8d97525f..00000000 --- a/launcher/Launcher.h +++ /dev/null @@ -1,237 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "minecraft/launch/MinecraftServerTarget.h" - -class LaunchController; -class LocalPeer; -class InstanceWindow; -class MainWindow; -class SetupWizard; -class FolderInstanceProvider; -class GenericPageProvider; -class QFile; -class HttpMetaCache; -class SettingsObject; -class InstanceList; -class AccountList; -class IconList; -class QNetworkAccessManager; -class JavaInstallList; -class UpdateChecker; -class BaseProfilerFactory; -class BaseDetachedToolFactory; -class TranslationsModel; -class ITheme; -class MCEditTool; -class GAnalytics; - -#if defined(LAUNCHER) -#undef LAUNCHER -#endif -#define LAUNCHER (static_cast(QCoreApplication::instance())) - -class Launcher : public QApplication -{ - // friends for the purpose of limiting access to deprecated stuff - Q_OBJECT -public: - enum Status - { - StartingUp, - Failed, - Succeeded, - Initialized - }; - -public: - Launcher(int &argc, char **argv); - virtual ~Launcher(); - - GAnalytics *analytics() const - { - return m_analytics; - } - - std::shared_ptr settings() const - { - return m_settings; - } - - qint64 timeSinceStart() const - { - return startTime.msecsTo(QDateTime::currentDateTime()); - } - - QIcon getThemedIcon(const QString& name); - - void setIconTheme(const QString& name); - - std::vector getValidApplicationThemes(); - - void setApplicationTheme(const QString& name, bool initial); - - // DownloadUpdateTask - std::shared_ptr updateChecker() - { - return m_updateChecker; - } - - std::shared_ptr translations(); - - std::shared_ptr javalist(); - - std::shared_ptr instances() const - { - return m_instances; - } - - FolderInstanceProvider * folderProvider() const - { - return m_instanceFolder; - } - - std::shared_ptr icons() const - { - return m_icons; - } - - MCEditTool *mcedit() const - { - return m_mcedit.get(); - } - - std::shared_ptr accounts() const - { - return m_accounts; - } - - Status status() const - { - return m_status; - } - - const QMap> &profilers() const - { - return m_profilers; - } - - /// this is the root of the 'installation'. Used for automatic updates - const QString &root() - { - return m_rootPath; - } - - /*! - * Opens a json file using either a system default editor, or, if not empty, the editor - * specified in the settings - */ - bool openJsonEditor(const QString &filename); - - InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString()); - MainWindow *showMainWindow(bool minimized = false); - - void updateIsRunning(bool running); - bool updatesAreAllowed(); - - void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); - -signals: - void updateAllowedChanged(bool status); - void globalSettingsAboutToOpen(); - void globalSettingsClosed(); - -public slots: - bool launch( - InstancePtr instance, - bool online = true, - BaseProfilerFactory *profiler = nullptr, - MinecraftServerTargetPtr serverToJoin = nullptr, - MinecraftAccountPtr accountToUse = nullptr - ); - bool kill(InstancePtr instance); - -private slots: - void on_windowClose(); - void messageReceived(const QByteArray & message); - void controllerSucceeded(); - void controllerFailed(const QString & error); - void analyticsSettingChanged(const Setting &setting, QVariant value); - void setupWizardFinished(int status); - -private: - bool createSetupWizard(); - void performMainStartupAction(); - - // sets the fatal error message and m_status to Failed. - void showFatalErrorMessage(const QString & title, const QString & content); - -private: - void addRunningInstance(); - void subRunningInstance(); - bool shouldExitNow() const; - -private: - QDateTime startTime; - - std::shared_ptr m_settings; - std::shared_ptr m_instances; - FolderInstanceProvider * m_instanceFolder = nullptr; - std::shared_ptr m_icons; - std::shared_ptr m_updateChecker; - std::shared_ptr m_accounts; - std::shared_ptr m_javalist; - std::shared_ptr m_translations; - std::shared_ptr m_globalSettingsProvider; - std::map> m_themes; - std::unique_ptr m_mcedit; - - QMap> m_profilers; - - QString m_rootPath; - Status m_status = Launcher::StartingUp; - -#if defined Q_OS_WIN32 - // used on Windows to attach the standard IO streams - bool consoleAttached = false; -#endif - - // FIXME: attach to instances instead. - struct InstanceXtras - { - InstanceWindow * window = nullptr; - shared_qobject_ptr controller; - }; - std::map m_instanceExtras; - - // main state variables - size_t m_openWindows = 0; - size_t m_runningInstances = 0; - bool m_updateRunning = false; - - // main window, if any - MainWindow * m_mainWindow = nullptr; - - // peer launcher instance connector - used to implement single instance launcher and signalling - LocalPeer * m_peerInstance = nullptr; - - GAnalytics * m_analytics = nullptr; - SetupWizard * m_setupWizard = nullptr; -public: - QString m_instanceIdToLaunch; - QString m_serverToJoin; - QString m_profileToUse; - bool m_liveCheck = false; - QUrl m_zipToImport; - std::unique_ptr logFile; -}; diff --git a/launcher/LauncherMessage.cpp b/launcher/LauncherMessage.cpp deleted file mode 100644 index 4cc56e22..00000000 --- a/launcher/LauncherMessage.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "LauncherMessage.h" - -#include -#include - -void LauncherMessage::parse(const QByteArray & input) { - auto doc = QJsonDocument::fromBinaryData(input); - auto root = doc.object(); - - command = root.value("command").toString(); - args.clear(); - - auto parsedArgs = root.value("args").toObject(); - for(auto iter = parsedArgs.begin(); iter != parsedArgs.end(); iter++) { - args[iter.key()] = iter.value().toString(); - } -} - -QByteArray LauncherMessage::serialize() { - QJsonObject root; - root.insert("command", command); - QJsonObject outArgs; - for (auto iter = args.begin(); iter != args.end(); iter++) { - outArgs[iter.key()] = iter.value(); - } - root.insert("args", outArgs); - - QJsonDocument out; - out.setObject(root); - return out.toBinaryData(); -} diff --git a/launcher/LauncherMessage.h b/launcher/LauncherMessage.h deleted file mode 100644 index 024b16a5..00000000 --- a/launcher/LauncherMessage.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include -#include - -struct LauncherMessage { - QString command; - QMap args; - - QByteArray serialize(); - void parse(const QByteArray & input); -}; diff --git a/launcher/MainWindow.cpp b/launcher/MainWindow.cpp index 7df3e717..f50f092e 100644 --- a/launcher/MainWindow.cpp +++ b/launcher/MainWindow.cpp @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" #include "MainWindow.h" @@ -278,7 +278,7 @@ public: actionAddInstance = TranslatedAction(MainWindow); actionAddInstance->setObjectName(QStringLiteral("actionAddInstance")); - actionAddInstance->setIcon(LAUNCHER->getThemedIcon("new")); + actionAddInstance->setIcon(APPLICATION->getThemedIcon("new")); actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instance")); actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance.")); all_actions.append(&actionAddInstance); @@ -291,7 +291,7 @@ public: actionViewInstanceFolder = TranslatedAction(MainWindow); actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder")); - actionViewInstanceFolder->setIcon(LAUNCHER->getThemedIcon("viewfolder")); + actionViewInstanceFolder->setIcon(APPLICATION->getThemedIcon("viewfolder")); actionViewInstanceFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Instance Folder")); actionViewInstanceFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance folder in a file browser.")); all_actions.append(&actionViewInstanceFolder); @@ -299,7 +299,7 @@ public: actionViewCentralModsFolder = TranslatedAction(MainWindow); actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder")); - actionViewCentralModsFolder->setIcon(LAUNCHER->getThemedIcon("centralmods")); + actionViewCentralModsFolder->setIcon(APPLICATION->getThemedIcon("centralmods")); actionViewCentralModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Central Mods Folder")); actionViewCentralModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the central mods folder in a file browser.")); all_actions.append(&actionViewCentralModsFolder); @@ -311,7 +311,7 @@ public: foldersMenuButton->setMenu(foldersMenu); foldersMenuButton->setPopupMode(QToolButton::InstantPopup); foldersMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - foldersMenuButton->setIcon(LAUNCHER->getThemedIcon("viewfolder")); + foldersMenuButton->setIcon(APPLICATION->getThemedIcon("viewfolder")); foldersMenuButton->setFocusPolicy(Qt::NoFocus); all_toolbuttons.append(&foldersMenuButton); QWidgetAction* foldersButtonAction = new QWidgetAction(MainWindow); @@ -320,7 +320,7 @@ public: actionSettings = TranslatedAction(MainWindow); actionSettings->setObjectName(QStringLiteral("actionSettings")); - actionSettings->setIcon(LAUNCHER->getThemedIcon("settings")); + actionSettings->setIcon(APPLICATION->getThemedIcon("settings")); actionSettings->setMenuRole(QAction::PreferencesRole); actionSettings.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Settings")); actionSettings.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change settings.")); @@ -333,7 +333,7 @@ public: if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) { actionReportBug = TranslatedAction(MainWindow); actionReportBug->setObjectName(QStringLiteral("actionReportBug")); - actionReportBug->setIcon(LAUNCHER->getThemedIcon("bug")); + actionReportBug->setIcon(APPLICATION->getThemedIcon("bug")); actionReportBug.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Report a Bug")); actionReportBug.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the bug tracker to report a bug with %1.")); all_actions.append(&actionReportBug); @@ -343,7 +343,7 @@ public: if (!BuildConfig.DISCORD_URL.isEmpty()) { actionDISCORD = TranslatedAction(MainWindow); actionDISCORD->setObjectName(QStringLiteral("actionDISCORD")); - actionDISCORD->setIcon(LAUNCHER->getThemedIcon("discord")); + actionDISCORD->setIcon(APPLICATION->getThemedIcon("discord")); actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Discord")); actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 discord voice chat.")); all_actions.append(&actionDISCORD); @@ -353,7 +353,7 @@ public: if (!BuildConfig.SUBREDDIT_URL.isEmpty()) { actionREDDIT = TranslatedAction(MainWindow); actionREDDIT->setObjectName(QStringLiteral("actionREDDIT")); - actionREDDIT->setIcon(LAUNCHER->getThemedIcon("reddit-alien")); + actionREDDIT->setIcon(APPLICATION->getThemedIcon("reddit-alien")); actionREDDIT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Reddit")); actionREDDIT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 subreddit.")); all_actions.append(&actionREDDIT); @@ -362,7 +362,7 @@ public: actionAbout = TranslatedAction(MainWindow); actionAbout->setObjectName(QStringLiteral("actionAbout")); - actionAbout->setIcon(LAUNCHER->getThemedIcon("about")); + actionAbout->setIcon(APPLICATION->getThemedIcon("about")); actionAbout->setMenuRole(QAction::AboutRole); actionAbout.setTextId(QT_TRANSLATE_NOOP("MainWindow", "About %1")); actionAbout.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View information about %1.")); @@ -375,7 +375,7 @@ public: helpMenuButton->setMenu(helpMenu); helpMenuButton->setPopupMode(QToolButton::InstantPopup); helpMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - helpMenuButton->setIcon(LAUNCHER->getThemedIcon("help")); + helpMenuButton->setIcon(APPLICATION->getThemedIcon("help")); helpMenuButton->setFocusPolicy(Qt::NoFocus); all_toolbuttons.append(&helpMenuButton); QWidgetAction* helpButtonAction = new QWidgetAction(MainWindow); @@ -386,7 +386,7 @@ public: { actionCheckUpdate = TranslatedAction(MainWindow); actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); - actionCheckUpdate->setIcon(LAUNCHER->getThemedIcon("checkupdate")); + actionCheckUpdate->setIcon(APPLICATION->getThemedIcon("checkupdate")); actionCheckUpdate.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Update")); actionCheckUpdate.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Check for new updates for %1.")); all_actions.append(&actionCheckUpdate); @@ -397,7 +397,7 @@ public: actionPatreon = TranslatedAction(MainWindow); actionPatreon->setObjectName(QStringLiteral("actionPatreon")); - actionPatreon->setIcon(LAUNCHER->getThemedIcon("patreon")); + actionPatreon->setIcon(APPLICATION->getThemedIcon("patreon")); actionPatreon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Support %1")); actionPatreon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the %1 Patreon page.")); all_actions.append(&actionPatreon); @@ -406,7 +406,7 @@ public: actionCAT = TranslatedAction(MainWindow); actionCAT->setObjectName(QStringLiteral("actionCAT")); actionCAT->setCheckable(true); - actionCAT->setIcon(LAUNCHER->getThemedIcon("cat")); + actionCAT->setIcon(APPLICATION->getThemedIcon("cat")); actionCAT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Meow")); actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a fluffy kitty :3")); actionCAT->setPriority(QAction::LowPriority); @@ -419,7 +419,7 @@ public: actionManageAccounts.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Accounts")); // FIXME: no tooltip! actionManageAccounts->setCheckable(false); - actionManageAccounts->setIcon(LAUNCHER->getThemedIcon("accounts")); + actionManageAccounts->setIcon(APPLICATION->getThemedIcon("accounts")); all_actions.append(&actionManageAccounts); all_toolbars.append(&mainToolBar); @@ -446,7 +446,7 @@ public: actionMoreNews = TranslatedAction(MainWindow); actionMoreNews->setObjectName(QStringLiteral("actionMoreNews")); - actionMoreNews->setIcon(LAUNCHER->getThemedIcon("news")); + actionMoreNews->setIcon(APPLICATION->getThemedIcon("news")); actionMoreNews.setTextId(QT_TRANSLATE_NOOP("MainWindow", "More news...")); actionMoreNews.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the development blog to read more news about %1.")); all_actions.append(&actionMoreNews); @@ -478,7 +478,7 @@ public: changeIconButton = new LabeledToolButton(MainWindow); changeIconButton->setObjectName(QStringLiteral("changeIconButton")); - changeIconButton->setIcon(LAUNCHER->getThemedIcon("news")); + changeIconButton->setIcon(APPLICATION->getThemedIcon("news")); changeIconButton->setToolTip(actionChangeInstIcon->toolTip()); changeIconButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); instanceToolBar->addWidget(changeIconButton); @@ -589,7 +589,7 @@ public: actionCopyInstance = TranslatedAction(MainWindow); actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance")); - actionCopyInstance->setIcon(LAUNCHER->getThemedIcon("copy")); + actionCopyInstance->setIcon(APPLICATION->getThemedIcon("copy")); actionCopyInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Copy Instance")); actionCopyInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Copy the selected instance.")); all_actions.append(&actionCopyInstance); @@ -606,7 +606,7 @@ public: MainWindow->setObjectName(QStringLiteral("MainWindow")); } MainWindow->resize(800, 600); - MainWindow->setWindowIcon(LAUNCHER->getThemedIcon("logo")); + MainWindow->setWindowIcon(APPLICATION->getThemedIcon("logo")); MainWindow->setWindowTitle(BuildConfig.LAUNCHER_DISPLAYNAME); #ifndef QT_NO_ACCESSIBILITY MainWindow->setAccessibleName(BuildConfig.LAUNCHER_NAME); @@ -683,7 +683,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow { m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL)); newsLabel = new QToolButton(); - newsLabel->setIcon(LAUNCHER->getThemedIcon("news")); + newsLabel->setIcon(APPLICATION->getThemedIcon("news")); newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); newsLabel->setFocusPolicy(Qt::NoFocus); @@ -710,20 +710,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(view, &InstanceView::droppedURLs, this, &MainWindow::droppedURLs, Qt::QueuedConnection); proxymodel = new InstanceProxyModel(this); - proxymodel->setSourceModel(LAUNCHER->instances().get()); + proxymodel->setSourceModel(APPLICATION->instances().get()); proxymodel->sort(0); connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged); view->setModel(proxymodel); view->setSourceOfGroupCollapseStatus([](const QString & groupName)->bool { - return LAUNCHER->instances()->isGroupCollapsed(groupName); + return APPLICATION->instances()->isGroupCollapsed(groupName); }); - connect(view, &InstanceView::groupStateChanged, LAUNCHER->instances().get(), &InstanceList::on_GroupStateChanged); + connect(view, &InstanceView::groupStateChanged, APPLICATION->instances().get(), &InstanceList::on_GroupStateChanged); ui->horizontalLayout->addWidget(view); } // The cat background { - bool cat_enable = LAUNCHER->settings()->get("TheCat").toBool(); + bool cat_enable = APPLICATION->settings()->get("TheCat").toBool(); ui->actionCAT->setChecked(cat_enable); // NOTE: calling the operator like that is an ugly hack to appease ancient gcc... connect(ui->actionCAT.operator->(), SIGNAL(toggled(bool)), SLOT(onCatToggled(bool))); @@ -736,16 +736,16 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(view->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::instanceChanged); // track icon changes and update the toolbar! - connect(LAUNCHER->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); + connect(APPLICATION->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); // model reset -> selection is invalid. All the instance pointers are wrong. - connect(LAUNCHER->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); + connect(APPLICATION->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); // handle newly added instances - connect(LAUNCHER->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); + connect(APPLICATION->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); // When the global settings page closes, we want to know about it and update our state - connect(LAUNCHER, &Launcher::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); + connect(APPLICATION, &Application::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); m_statusLeft = new QLabel(tr("No instance selected"), this); m_statusCenter = new QLabel(tr("Total playtime: 0s"), this); @@ -765,7 +765,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow accountMenuButton->setMenu(accountMenu); accountMenuButton->setPopupMode(QToolButton::InstantPopup); accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); + accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); QWidgetAction *accountMenuButtonAction = new QWidgetAction(this); accountMenuButtonAction->setDefaultWidget(accountMenuButton); @@ -776,14 +776,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow // Shouldn't have to use lambdas here like this, but if I don't, the compiler throws a fit. // Template hell sucks... connect( - LAUNCHER->accounts().get(), - &AccountList::activeAccountChanged, + APPLICATION->accounts().get(), + &AccountList::defaultAccountChanged, [this] { - activeAccountChanged(); + defaultAccountChanged(); } ); connect( - LAUNCHER->accounts().get(), + APPLICATION->accounts().get(), &AccountList::listChanged, [this] { @@ -792,10 +792,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow ); // Show initial account - activeAccountChanged(); + defaultAccountChanged(); // TODO: refresh accounts here? - // auto accounts = LAUNCHER->accounts(); + // auto accounts = APPLICATION->accounts(); // load the news { @@ -806,20 +806,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow if(BuildConfig.UPDATER_ENABLED) { - bool updatesAllowed = LAUNCHER->updatesAreAllowed(); + bool updatesAllowed = APPLICATION->updatesAreAllowed(); updatesAllowedChanged(updatesAllowed); // NOTE: calling the operator like that is an ugly hack to appease ancient gcc... connect(ui->actionCheckUpdate.operator->(), &QAction::triggered, this, &MainWindow::checkForUpdates); // set up the updater object. - auto updater = LAUNCHER->updateChecker(); + auto updater = APPLICATION->updateChecker(); connect(updater.get(), &UpdateChecker::updateAvailable, this, &MainWindow::updateAvailable); connect(updater.get(), &UpdateChecker::noUpdateFound, this, &MainWindow::updateNotAvailable); // if automatic update checks are allowed, start one. - if (LAUNCHER->settings()->get("AutoUpdate").toBool() && updatesAllowed) + if (APPLICATION->settings()->get("AutoUpdate").toBool() && updatesAllowed) { - updater->checkForUpdate(LAUNCHER->settings()->get("UpdateChannel").toString(), false); + updater->checkForUpdate(APPLICATION->settings()->get("UpdateChannel").toString(), false); } } @@ -834,7 +834,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow checker->checkForNotifications(); } - setSelectedInstanceById(LAUNCHER->settings()->get("SelectedInstance").toString()); + setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); // removing this looks stupid view->setFocus(); @@ -844,10 +844,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow void MainWindow::retranslateUi() { - std::shared_ptr accounts = LAUNCHER->accounts(); - MinecraftAccountPtr active_account = accounts->activeAccount(); - if(active_account) { - auto profileLabel = profileInUseFilter(active_account->profileName(), active_account->isInUse()); + auto accounts = APPLICATION->accounts(); + MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); + if(defaultAccount) { + auto profileLabel = profileInUseFilter(defaultAccount->profileName(), defaultAccount->isInUse()); accountMenuButton->setText(profileLabel); } else { @@ -876,7 +876,7 @@ QMenu * MainWindow::createPopupMenu() void MainWindow::konamiTriggered() { - // ENV.enableFeature("NewModsPage"); + // ENV->enableFeature("NewModsPage"); qDebug() << "Super Secret Mode ACTIVATED!"; } @@ -982,16 +982,16 @@ void MainWindow::updateToolsMenu() QAction *normalLaunchOffline = launchOfflineMenu->addAction(tr("Launch Offline")); connect(normalLaunch, &QAction::triggered, [this]() { - LAUNCHER->launch(m_selectedInstance, true); + APPLICATION->launch(m_selectedInstance, true); }); connect(normalLaunchOffline, &QAction::triggered, [this]() { - LAUNCHER->launch(m_selectedInstance, false); + APPLICATION->launch(m_selectedInstance, false); }); QString profilersTitle = tr("Profilers"); launchMenu->addSeparator()->setText(profilersTitle); launchOfflineMenu->addSeparator()->setText(profilersTitle); - for (auto profiler : LAUNCHER->profilers().values()) + for (auto profiler : APPLICATION->profilers().values()) { QAction *profilerAction = launchMenu->addAction(profiler->name()); QAction *profilerOfflineAction = launchOfflineMenu->addAction(profiler->name()); @@ -1008,11 +1008,11 @@ void MainWindow::updateToolsMenu() { connect(profilerAction, &QAction::triggered, [this, profiler]() { - LAUNCHER->launch(m_selectedInstance, true, profiler.get()); + APPLICATION->launch(m_selectedInstance, true, profiler.get()); }); connect(profilerOfflineAction, &QAction::triggered, [this, profiler]() { - LAUNCHER->launch(m_selectedInstance, false, profiler.get()); + APPLICATION->launch(m_selectedInstance, false, profiler.get()); }); } } @@ -1024,16 +1024,16 @@ void MainWindow::repopulateAccountsMenu() { accountMenu->clear(); - std::shared_ptr accounts = LAUNCHER->accounts(); - MinecraftAccountPtr active_account = accounts->activeAccount(); + auto accounts = APPLICATION->accounts(); + MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); QString active_profileId = ""; - if (active_account != nullptr) + if (defaultAccount) { // this can be called before accountMenuButton exists if (accountMenuButton) { - auto profileLabel = profileInUseFilter(active_account->profileName(), active_account->isInUse()); + auto profileLabel = profileInUseFilter(defaultAccount->profileName(), defaultAccount->isInUse()); accountMenuButton->setText(profileLabel); } } @@ -1054,7 +1054,7 @@ void MainWindow::repopulateAccountsMenu() QAction *action = new QAction(profileLabel, this); action->setData(i); action->setCheckable(true); - if (active_account == account) + if (defaultAccount == account) { action->setChecked(true); } @@ -1064,7 +1064,7 @@ void MainWindow::repopulateAccountsMenu() action->setIcon(face); } else { - action->setIcon(LAUNCHER->getThemedIcon("noaccount")); + action->setIcon(APPLICATION->getThemedIcon("noaccount")); } accountMenu->addAction(action); connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount())); @@ -1075,9 +1075,9 @@ void MainWindow::repopulateAccountsMenu() QAction *action = new QAction(tr("No Default Account"), this); action->setCheckable(true); - action->setIcon(LAUNCHER->getThemedIcon("noaccount")); + action->setIcon(APPLICATION->getThemedIcon("noaccount")); action->setData(-1); - if (active_account == nullptr) { + if (!defaultAccount) { action->setChecked(true); } @@ -1114,25 +1114,25 @@ void MainWindow::changeActiveAccount() if(!valid) { index = -1; } - std::shared_ptr accounts = LAUNCHER->accounts(); - accounts->setActiveAccount(index == -1 ? nullptr : accounts->at(index)); - activeAccountChanged(); + auto accounts = APPLICATION->accounts(); + accounts->setDefaultAccount(index == -1 ? nullptr : accounts->at(index)); + defaultAccountChanged(); } -void MainWindow::activeAccountChanged() +void MainWindow::defaultAccountChanged() { repopulateAccountsMenu(); - MinecraftAccountPtr account = LAUNCHER->accounts()->activeAccount(); + MinecraftAccountPtr account = APPLICATION->accounts()->defaultAccount(); // FIXME: this needs adjustment for MSA - if (account != nullptr && account->profileName() != "") + if (account && account->profileName() != "") { auto profileLabel = profileInUseFilter(account->profileName(), account->isInUse()); accountMenuButton->setText(profileLabel); auto face = account->getFace(); if(face.isNull()) { - accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); + accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); } else { accountMenuButton->setIcon(face); @@ -1141,7 +1141,7 @@ void MainWindow::activeAccountChanged() } // Set the icon to the "no account" icon. - accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); + accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); accountMenuButton->setText(tr("Profiles")); } @@ -1203,7 +1203,7 @@ void MainWindow::updateNewsLabel() void MainWindow::updateAvailable(GoUpdate::Status status) { - if(!LAUNCHER->updatesAreAllowed()) + if(!APPLICATION->updatesAreAllowed()) { updateNotAvailable(); return; @@ -1249,7 +1249,7 @@ QString intListToString(const QList &list) void MainWindow::notificationsChanged() { QList entries = m_notificationChecker->notificationEntries(); - QList shownNotifications = stringToIntList(LAUNCHER->settings()->get("ShownNotifications").toString()); + QList shownNotifications = stringToIntList(APPLICATION->settings()->get("ShownNotifications").toString()); for (auto it = entries.begin(); it != entries.end(); ++it) { NotificationChecker::NotificationEntry entry = *it; @@ -1262,20 +1262,20 @@ void MainWindow::notificationsChanged() } } } - LAUNCHER->settings()->set("ShownNotifications", intListToString(shownNotifications)); + APPLICATION->settings()->set("ShownNotifications", intListToString(shownNotifications)); } void MainWindow::downloadUpdates(GoUpdate::Status status) { - if(!LAUNCHER->updatesAreAllowed()) + if(!APPLICATION->updatesAreAllowed()) { return; } qDebug() << "Downloading updates."; ProgressDialog updateDlg(this); - status.rootPath = LAUNCHER->root(); + status.rootPath = APPLICATION->root(); - auto dlPath = FS::PathCombine(LAUNCHER->root(), "update", "XXXXXX"); + auto dlPath = FS::PathCombine(APPLICATION->root(), "update", "XXXXXX"); if (!FS::ensureFilePathExists(dlPath)) { CustomMessageBox::selectable(this, tr("Error"), tr("Couldn't create folder for update downloads:\n%1").arg(dlPath), QMessageBox::Warning)->show(); @@ -1288,10 +1288,10 @@ void MainWindow::downloadUpdates(GoUpdate::Status status) * NOTE: This disables launching instances until the update either succeeds (and this process exits) * or the update fails (and the control leaves this scope). */ - LAUNCHER->updateIsRunning(true); - UpdateController update(this, LAUNCHER->root(), updateTask.updateFilesDir(), updateTask.operations()); + APPLICATION->updateIsRunning(true); + UpdateController update(this, APPLICATION->root(), updateTask.updateFilesDir(), updateTask.operations()); update.installUpdates(); - LAUNCHER->updateIsRunning(false); + APPLICATION->updateIsRunning(false); } else { @@ -1302,7 +1302,7 @@ void MainWindow::downloadUpdates(GoUpdate::Status status) void MainWindow::onCatToggled(bool state) { setCatBackground(state); - LAUNCHER->settings()->set("TheCat", state); + APPLICATION->settings()->set("TheCat", state); } namespace { @@ -1360,7 +1360,7 @@ void MainWindow::runModalTask(Task *task) void MainWindow::instanceFromInstanceTask(InstanceTask *rawTask) { - unique_qobject_ptr task(LAUNCHER->instances()->wrapInstanceTask(rawTask)); + unique_qobject_ptr task(APPLICATION->instances()->wrapInstanceTask(rawTask)); runModalTask(task.get()); } @@ -1377,7 +1377,7 @@ void MainWindow::on_actionCopyInstance_triggered() copyTask->setName(copyInstDlg.instName()); copyTask->setGroup(copyInstDlg.instGroup()); copyTask->setIcon(copyInstDlg.iconKey()); - unique_qobject_ptr task(LAUNCHER->instances()->wrapInstanceTask(copyTask)); + unique_qobject_ptr task(APPLICATION->instances()->wrapInstanceTask(copyTask)); runModalTask(task.get()); } @@ -1385,7 +1385,7 @@ void MainWindow::finalizeInstance(InstancePtr inst) { view->updateGeometries(); setSelectedInstanceById(inst->id()); - if (LAUNCHER->accounts()->anyAccountIsValid()) + if (APPLICATION->accounts()->anyAccountIsValid()) { ProgressDialog loadDialog(this); auto update = inst->createUpdateTask(Net::Mode::Online); @@ -1431,14 +1431,14 @@ void MainWindow::addInstance(QString url) if(groupName.isEmpty()) { - groupName = LAUNCHER->settings()->get("LastUsedGroupForNewInstance").toString(); + groupName = APPLICATION->settings()->get("LastUsedGroupForNewInstance").toString(); } NewInstanceDialog newInstDlg(groupName, url, this); if (!newInstDlg.exec()) return; - LAUNCHER->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); + APPLICATION->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); InstanceTask * creationTask = newInstDlg.extractTask(); if(creationTask) @@ -1489,7 +1489,7 @@ void MainWindow::on_actionChangeInstIcon_triggered() if (dlg.result() == QDialog::Accepted) { m_selectedInstance->setIconKey(dlg.selectedIconKey); - auto icon = LAUNCHER->icons()->getIcon(dlg.selectedIconKey); + auto icon = APPLICATION->icons()->getIcon(dlg.selectedIconKey); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1499,7 +1499,7 @@ void MainWindow::iconUpdated(QString icon) { if (icon == m_currentInstIcon) { - auto icon = LAUNCHER->icons()->getIcon(m_currentInstIcon); + auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1508,7 +1508,7 @@ void MainWindow::iconUpdated(QString icon) void MainWindow::updateInstanceToolIcon(QString new_icon) { m_currentInstIcon = new_icon; - auto icon = LAUNCHER->icons()->getIcon(m_currentInstIcon); + auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1517,7 +1517,7 @@ void MainWindow::setSelectedInstanceById(const QString &id) { if (id.isNull()) return; - const QModelIndex index = LAUNCHER->instances()->getInstanceIndexById(id); + const QModelIndex index = APPLICATION->instances()->getInstanceIndexById(id); if (index.isValid()) { QModelIndex selectionIndex = proxymodel->mapFromSource(index); @@ -1533,8 +1533,8 @@ void MainWindow::on_actionChangeInstGroup_triggered() bool ok = false; InstanceId instId = m_selectedInstance->id(); - QString name(LAUNCHER->instances()->getInstanceGroup(instId)); - auto groups = LAUNCHER->instances()->getGroups(); + QString name(APPLICATION->instances()->getInstanceGroup(instId)); + auto groups = APPLICATION->instances()->getGroups(); groups.insert(0, ""); groups.sort(Qt::CaseInsensitive); int foo = groups.indexOf(name); @@ -1543,7 +1543,7 @@ void MainWindow::on_actionChangeInstGroup_triggered() name = name.simplified(); if (ok) { - LAUNCHER->instances()->setInstanceGroup(instId, name); + APPLICATION->instances()->setInstanceGroup(instId, name); } } @@ -1565,25 +1565,25 @@ void MainWindow::deleteGroup() .arg(groupName), QMessageBox::Yes | QMessageBox::No); if(reply == QMessageBox::Yes) { - LAUNCHER->instances()->deleteGroup(groupName); + APPLICATION->instances()->deleteGroup(groupName); } } } void MainWindow::on_actionViewInstanceFolder_triggered() { - QString str = LAUNCHER->settings()->get("InstanceDir").toString(); + QString str = APPLICATION->settings()->get("InstanceDir").toString(); DesktopServices::openDirectory(str); } void MainWindow::refreshInstances() { - LAUNCHER->instances()->loadList(); + APPLICATION->instances()->loadList(); } void MainWindow::on_actionViewCentralModsFolder_triggered() { - DesktopServices::openDirectory(LAUNCHER->settings()->get("CentralModsDir").toString(), true); + DesktopServices::openDirectory(APPLICATION->settings()->get("CentralModsDir").toString(), true); } void MainWindow::on_actionConfig_Folder_triggered() @@ -1599,8 +1599,8 @@ void MainWindow::checkForUpdates() { if(BuildConfig.UPDATER_ENABLED) { - auto updater = LAUNCHER->updateChecker(); - updater->checkForUpdate(LAUNCHER->settings()->get("UpdateChannel").toString(), true); + auto updater = APPLICATION->updateChecker(); + updater->checkForUpdate(APPLICATION->settings()->get("UpdateChannel").toString(), true); } else { @@ -1610,13 +1610,13 @@ void MainWindow::checkForUpdates() void MainWindow::on_actionSettings_triggered() { - LAUNCHER->ShowGlobalSettings(this, "global-settings"); + APPLICATION->ShowGlobalSettings(this, "global-settings"); } void MainWindow::globalSettingsClosed() { // FIXME: quick HACK to make this work. improve, optimize. - LAUNCHER->instances()->loadList(); + APPLICATION->instances()->loadList(); proxymodel->invalidate(); proxymodel->sort(0); updateToolsMenu(); @@ -1626,32 +1626,32 @@ void MainWindow::globalSettingsClosed() void MainWindow::on_actionInstanceSettings_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "settings"); + APPLICATION->showInstanceWindow(m_selectedInstance, "settings"); } void MainWindow::on_actionEditInstNotes_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "notes"); + APPLICATION->showInstanceWindow(m_selectedInstance, "notes"); } void MainWindow::on_actionWorlds_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "worlds"); + APPLICATION->showInstanceWindow(m_selectedInstance, "worlds"); } void MainWindow::on_actionEditInstance_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance); + APPLICATION->showInstanceWindow(m_selectedInstance); } void MainWindow::on_actionScreenshots_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "screenshots"); + APPLICATION->showInstanceWindow(m_selectedInstance, "screenshots"); } void MainWindow::on_actionManageAccounts_triggered() { - LAUNCHER->ShowGlobalSettings(this, "accounts"); + APPLICATION->ShowGlobalSettings(this, "accounts"); } void MainWindow::on_actionReportBug_triggered() @@ -1705,7 +1705,7 @@ void MainWindow::on_actionDeleteInstance_triggered() )->exec(); if (response == QMessageBox::Yes) { - LAUNCHER->instances()->deleteInstance(id); + APPLICATION->instances()->deleteInstance(id); } } @@ -1753,8 +1753,8 @@ void MainWindow::on_actionViewSelectedMCFolder_triggered() void MainWindow::closeEvent(QCloseEvent *event) { // Save the window state and geometry. - LAUNCHER->settings()->set("MainWindowState", saveState().toBase64()); - LAUNCHER->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("MainWindowState", saveState().toBase64()); + APPLICATION->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); event->accept(); emit isClosing(); } @@ -1773,7 +1773,7 @@ void MainWindow::instanceActivated(QModelIndex index) if (!index.isValid()) return; QString id = index.data(InstanceList::InstanceIDRole).toString(); - InstancePtr inst = LAUNCHER->instances()->getInstanceById(id); + InstancePtr inst = APPLICATION->instances()->getInstanceById(id); if (!inst) return; @@ -1788,24 +1788,24 @@ void MainWindow::on_actionLaunchInstance_triggered() } if(m_selectedInstance->isRunning()) { - LAUNCHER->kill(m_selectedInstance); + APPLICATION->kill(m_selectedInstance); } else { - LAUNCHER->launch(m_selectedInstance); + APPLICATION->launch(m_selectedInstance); } } void MainWindow::activateInstance(InstancePtr instance) { - LAUNCHER->launch(instance); + APPLICATION->launch(instance); } void MainWindow::on_actionLaunchInstanceOffline_triggered() { if (m_selectedInstance) { - LAUNCHER->launch(m_selectedInstance, false); + APPLICATION->launch(m_selectedInstance, false); } } @@ -1829,12 +1829,12 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & { if (!current.isValid()) { - LAUNCHER->settings()->set("SelectedInstance", QString()); + APPLICATION->settings()->set("SelectedInstance", QString()); selectionBad(); return; } QString id = current.data(InstanceList::InstanceIDRole).toString(); - m_selectedInstance = LAUNCHER->instances()->getInstanceById(id); + m_selectedInstance = APPLICATION->instances()->getInstanceById(id); if (m_selectedInstance) { ui->instanceToolBar->setEnabled(true); @@ -1857,12 +1857,12 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & updateToolsMenu(); - LAUNCHER->settings()->set("SelectedInstance", m_selectedInstance->id()); + APPLICATION->settings()->set("SelectedInstance", m_selectedInstance->id()); } else { ui->instanceToolBar->setEnabled(false); - LAUNCHER->settings()->set("SelectedInstance", QString()); + APPLICATION->settings()->set("SelectedInstance", QString()); selectionBad(); return; } @@ -1894,12 +1894,12 @@ void MainWindow::selectionBad() updateInstanceToolIcon("grass"); // ...and then see if we can enable the previously selected instance - setSelectedInstanceById(LAUNCHER->settings()->get("SelectedInstance").toString()); + setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); } void MainWindow::checkInstancePathForProblems() { - QString instanceFolder = LAUNCHER->settings()->get("InstanceDir").toString(); + QString instanceFolder = APPLICATION->settings()->get("InstanceDir").toString(); if (FS::checkProblemticPathJava(QDir(instanceFolder))) { QMessageBox warning(this); @@ -1938,9 +1938,9 @@ void MainWindow::checkInstancePathForProblems() void MainWindow::updateStatusCenter() { - m_statusCenter->setVisible(LAUNCHER->settings()->get("ShowGlobalGameTime").toBool()); + m_statusCenter->setVisible(APPLICATION->settings()->get("ShowGlobalGameTime").toBool()); - int timePlayed = LAUNCHER->instances()->getTotalPlayTime(); + int timePlayed = APPLICATION->instances()->getTotalPlayTime(); if (timePlayed > 0) { m_statusCenter->setText(tr("Total playtime: %1").arg(Time::prettifyDuration(timePlayed))); } diff --git a/launcher/MainWindow.h b/launcher/MainWindow.h index c2ad46ea..7e1256cc 100644 --- a/launcher/MainWindow.h +++ b/launcher/MainWindow.h @@ -166,7 +166,7 @@ private slots: void notificationsChanged(); - void activeAccountChanged(); + void defaultAccountChanged(); void changeActiveAccount(); diff --git a/launcher/SkinUtils.cpp b/launcher/SkinUtils.cpp index a196173e..159116d8 100644 --- a/launcher/SkinUtils.cpp +++ b/launcher/SkinUtils.cpp @@ -30,7 +30,7 @@ namespace SkinUtils */ QPixmap getFaceFromCache(QString username, int height, int width) { - QFile fskin(ENV.metacache()->resolveEntry("skins", username + ".png")->getFullPath()); + QFile fskin(ENV->metacache()->resolveEntry("skins", username + ".png")->getFullPath()); if (fskin.exists()) { diff --git a/launcher/Usable.h b/launcher/Usable.h index 83dd083d..a3e880f3 100644 --- a/launcher/Usable.h +++ b/launcher/Usable.h @@ -3,6 +3,8 @@ #include #include +#include "QObjectPtr.h" + class Usable; /** @@ -14,11 +16,11 @@ class Usable { friend class UseLock; public: - std::size_t useCount() + std::size_t useCount() const { return m_useCount; } - bool isInUse() + bool isInUse() const { return m_useCount > 0; } @@ -43,7 +45,7 @@ private: class UseLock { public: - UseLock(std::shared_ptr usable) + UseLock(shared_qobject_ptr usable) : m_usable(usable) { // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate. @@ -54,5 +56,5 @@ public: m_usable->decrementUses(); } private: - std::shared_ptr m_usable; + shared_qobject_ptr m_usable; }; diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 12f9bdd8..b9a87c9c 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -1,5 +1,5 @@ #include "VersionProxyModel.h" -#include "Launcher.h" +#include "Application.h" #include #include #include @@ -194,19 +194,19 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); if(value.toBool()) { - return LAUNCHER->getThemedIcon("star"); + return APPLICATION->getThemedIcon("star"); } else if(hasLatest) { auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); if(value.toBool()) { - return LAUNCHER->getThemedIcon("bug"); + return APPLICATION->getThemedIcon("bug"); } } else if(index.row() == 0) { - return LAUNCHER->getThemedIcon("bug"); + return APPLICATION->getThemedIcon("bug"); } auto pixmap = QPixmapCache::find("placeholder"); if(!pixmap) diff --git a/launcher/dialogs/AboutDialog.cpp b/launcher/dialogs/AboutDialog.cpp index 0c3f07db..6921bf63 100644 --- a/launcher/dialogs/AboutDialog.cpp +++ b/launcher/dialogs/AboutDialog.cpp @@ -16,7 +16,7 @@ #include "AboutDialog.h" #include "ui_AboutDialog.h" #include -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" #include @@ -88,7 +88,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->urlLabel->setOpenExternalLinks(true); - ui->icon->setPixmap(LAUNCHER->getThemedIcon("logo").pixmap(64)); + ui->icon->setPixmap(APPLICATION->getThemedIcon("logo").pixmap(64)); ui->title->setText(launcherName); ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); diff --git a/launcher/dialogs/CopyInstanceDialog.cpp b/launcher/dialogs/CopyInstanceDialog.cpp index 802016d9..1c8d6711 100644 --- a/launcher/dialogs/CopyInstanceDialog.cpp +++ b/launcher/dialogs/CopyInstanceDialog.cpp @@ -16,7 +16,7 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include "CopyInstanceDialog.h" #include "ui_CopyInstanceDialog.h" @@ -36,16 +36,16 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) layout()->setSizeConstraint(QLayout::SetFixedSize); InstIconKey = original->iconKey(); - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); ui->instNameTextBox->setText(original->name()); ui->instNameTextBox->setFocus(); - auto groups = LAUNCHER->instances()->getGroups().toSet(); + auto groups = APPLICATION->instances()->getGroups().toSet(); auto groupList = QStringList(groups.toList()); groupList.sort(Qt::CaseInsensitive); groupList.removeOne(""); groupList.push_front(""); ui->groupBox->addItems(groupList); - int index = groupList.indexOf(LAUNCHER->instances()->getInstanceGroup(m_original->id())); + int index = groupList.indexOf(APPLICATION->instances()->getInstanceGroup(m_original->id())); if(index == -1) { index = 0; @@ -99,7 +99,7 @@ void CopyInstanceDialog::on_iconButton_clicked() if (dlg.result() == QDialog::Accepted) { InstIconKey = dlg.selectedIconKey; - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); } } diff --git a/launcher/dialogs/ExportInstanceDialog.cpp b/launcher/dialogs/ExportInstanceDialog.cpp index 639b7043..1a164875 100644 --- a/launcher/dialogs/ExportInstanceDialog.cpp +++ b/launcher/dialogs/ExportInstanceDialog.cpp @@ -27,7 +27,7 @@ #include #include "MMCStrings.h" #include "SeparatorPrefixTree.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -341,7 +341,7 @@ ExportInstanceDialog::~ExportInstanceDialog() void SaveIcon(InstancePtr m_instance) { auto iconKey = m_instance->iconKey(); - auto iconList = LAUNCHER->icons(); + auto iconList = APPLICATION->icons(); auto mmcIcon = iconList->icon(iconKey); if(!mmcIcon || mmcIcon->isBuiltIn()) { return; diff --git a/launcher/dialogs/IconPickerDialog.cpp b/launcher/dialogs/IconPickerDialog.cpp index a1c432a8..af9d0683 100644 --- a/launcher/dialogs/IconPickerDialog.cpp +++ b/launcher/dialogs/IconPickerDialog.cpp @@ -17,7 +17,7 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include "IconPickerDialog.h" #include "ui_IconPickerDialog.h" @@ -59,7 +59,7 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) contentsWidget->installEventFilter(this); - contentsWidget->setModel(LAUNCHER->icons().get()); + contentsWidget->setModel(APPLICATION->icons().get()); // NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win. auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole); @@ -106,12 +106,12 @@ void IconPickerDialog::addNewIcon() //: The type of icon files auto filter = IconUtils::getIconFilter(); QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), tr("Icons %1").arg(filter)); - LAUNCHER->icons()->installIcons(fileNames); + APPLICATION->icons()->installIcons(fileNames); } void IconPickerDialog::removeSelectedIcon() { - LAUNCHER->icons()->deleteIcon(selectedIconKey); + APPLICATION->icons()->deleteIcon(selectedIconKey); } void IconPickerDialog::activated(QModelIndex index) @@ -133,7 +133,7 @@ void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection int IconPickerDialog::execWithSelection(QString selection) { - auto list = LAUNCHER->icons(); + auto list = APPLICATION->icons(); auto contentsWidget = ui->iconView; selectedIconKey = selection; @@ -159,5 +159,5 @@ IconPickerDialog::~IconPickerDialog() void IconPickerDialog::openFolder() { - DesktopServices::openDirectory(LAUNCHER->icons()->getDirectory(), true); + DesktopServices::openDirectory(APPLICATION->icons()->getDirectory(), true); } diff --git a/launcher/dialogs/LoginDialog.h b/launcher/dialogs/LoginDialog.h index 13463640..833cb570 100644 --- a/launcher/dialogs/LoginDialog.h +++ b/launcher/dialogs/LoginDialog.h @@ -54,5 +54,5 @@ slots: private: Ui::LoginDialog *ui; MinecraftAccountPtr m_account; - std::shared_ptr m_loginTask; + shared_qobject_ptr m_loginTask; }; diff --git a/launcher/dialogs/MSALoginDialog.h b/launcher/dialogs/MSALoginDialog.h index 3d26a0dd..4cf146ab 100644 --- a/launcher/dialogs/MSALoginDialog.h +++ b/launcher/dialogs/MSALoginDialog.h @@ -55,7 +55,7 @@ slots: private: Ui::MSALoginDialog *ui; MinecraftAccountPtr m_account; - std::shared_ptr m_loginTask; + shared_qobject_ptr m_loginTask; QTimer m_externalLoginTimer; int m_externalLoginElapsed = 0; int m_externalLoginTimeout = 0; diff --git a/launcher/dialogs/NewComponentDialog.cpp b/launcher/dialogs/NewComponentDialog.cpp index 1cea54f4..1bbafb0c 100644 --- a/launcher/dialogs/NewComponentDialog.cpp +++ b/launcher/dialogs/NewComponentDialog.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include "NewComponentDialog.h" #include "ui_NewComponentDialog.h" @@ -46,7 +46,7 @@ NewComponentDialog::NewComponentDialog(const QString & initialName, const QStrin connect(ui->nameTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); connect(ui->uidTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); - auto groups = LAUNCHER->instances()->getGroups().toSet(); + auto groups = APPLICATION->instances()->getGroups().toSet(); ui->nameTextBox->setFocus(); originalPlaceholderText = ui->uidTextBox->placeholderText(); diff --git a/launcher/dialogs/NewInstanceDialog.cpp b/launcher/dialogs/NewInstanceDialog.cpp index d18eb3d5..a19f91b7 100644 --- a/launcher/dialogs/NewInstanceDialog.cpp +++ b/launcher/dialogs/NewInstanceDialog.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include "NewInstanceDialog.h" #include "ui_NewInstanceDialog.h" @@ -48,12 +48,12 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString { ui->setupUi(this); - setWindowIcon(LAUNCHER->getThemedIcon("new")); + setWindowIcon(APPLICATION->getThemedIcon("new")); InstIconKey = "default"; - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); - auto groups = LAUNCHER->instances()->getGroups().toSet(); + auto groups = APPLICATION->instances()->getGroups().toSet(); auto groupList = QStringList(groups.toList()); groupList.sort(Qt::CaseInsensitive); groupList.removeOne(""); @@ -105,18 +105,18 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString updateDialogState(); - restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("NewInstanceGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("NewInstanceGeometry").toByteArray())); } void NewInstanceDialog::reject() { - LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); QDialog::reject(); } void NewInstanceDialog::accept() { - LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); importIconNow(); QDialog::accept(); } @@ -155,7 +155,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task if(!task) { - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon("default")); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default")); importIcon = false; } @@ -175,7 +175,7 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QStr void NewInstanceDialog::setSuggestedIcon(const QString &key) { - auto icon = LAUNCHER->icons()->getIcon(key); + auto icon = APPLICATION->icons()->getIcon(key); importIcon = false; ui->iconButton->setIcon(icon); @@ -234,7 +234,7 @@ void NewInstanceDialog::on_iconButton_clicked() if (dlg.result() == QDialog::Accepted) { InstIconKey = dlg.selectedIconKey; - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); importIcon = false; } } @@ -247,9 +247,9 @@ void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) void NewInstanceDialog::importIconNow() { if(importIcon) { - LAUNCHER->icons()->installIcon(importIconPath, importIconName); + APPLICATION->icons()->installIcon(importIconPath, importIconName); InstIconKey = importIconName; importIcon = false; } - LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); } diff --git a/launcher/dialogs/ProfileSelectDialog.cpp b/launcher/dialogs/ProfileSelectDialog.cpp index 1082748f..0e3e493c 100644 --- a/launcher/dialogs/ProfileSelectDialog.cpp +++ b/launcher/dialogs/ProfileSelectDialog.cpp @@ -23,14 +23,14 @@ #include -#include +#include ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent) : QDialog(parent), ui(new Ui::ProfileSelectDialog) { ui->setupUi(this); - m_accounts = LAUNCHER->accounts(); + m_accounts = APPLICATION->accounts(); auto view = ui->listView; //view->setModel(m_accounts.get()); //view->hideColumn(AccountList::ActiveColumn); diff --git a/launcher/dialogs/ProfileSelectDialog.h b/launcher/dialogs/ProfileSelectDialog.h index a4acd9a1..38aa4249 100644 --- a/launcher/dialogs/ProfileSelectDialog.h +++ b/launcher/dialogs/ProfileSelectDialog.h @@ -80,7 +80,7 @@ slots: void on_buttonBox_rejected(); protected: - std::shared_ptr m_accounts; + shared_qobject_ptr m_accounts; //! The account that was selected when the user clicked OK. MinecraftAccountPtr m_selected; diff --git a/launcher/dialogs/ProfileSetupDialog.cpp b/launcher/dialogs/ProfileSetupDialog.cpp index e3d7aec2..51c20202 100644 --- a/launcher/dialogs/ProfileSetupDialog.cpp +++ b/launcher/dialogs/ProfileSetupDialog.cpp @@ -23,19 +23,21 @@ #include -#include +#include #include #include +#include + ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent) : QDialog(parent), m_accountToSetup(accountToSetup), ui(new Ui::ProfileSetupDialog) { ui->setupUi(this); ui->errorLabel->setVisible(false); - goodIcon = LAUNCHER->getThemedIcon("status-good"); - yellowIcon = LAUNCHER->getThemedIcon("status-yellow"); - badIcon = LAUNCHER->getThemedIcon("status-bad"); + goodIcon = APPLICATION->getThemedIcon("status-good"); + yellowIcon = APPLICATION->getThemedIcon("status-yellow"); + badIcon = APPLICATION->getThemedIcon("status-bad"); QRegExp permittedNames("[a-zA-Z0-9_]{3,16}"); auto nameEdit = ui->nameEdit; diff --git a/launcher/dialogs/SkinUploadDialog.cpp b/launcher/dialogs/SkinUploadDialog.cpp index 97478f4b..4e6142fa 100644 --- a/launcher/dialogs/SkinUploadDialog.cpp +++ b/launcher/dialogs/SkinUploadDialog.cpp @@ -3,14 +3,15 @@ #include #include + #include +#include #include #include "SkinUploadDialog.h" #include "ui_SkinUploadDialog.h" #include "ProgressDialog.h" #include "CustomMessageBox.h" -#include void SkinUploadDialog::on_buttonBox_rejected() { @@ -91,10 +92,10 @@ void SkinUploadDialog::on_buttonBox_accepted() model = SkinUpload::ALEX; } SequentialTask skinUpload; - skinUpload.addTask(std::make_shared(this, session, FS::read(fileName), model)); + skinUpload.addTask(shared_qobject_ptr(new SkinUpload(this, session, FS::read(fileName), model))); auto selectedCape = ui->capeCombo->currentData().toString(); - if(selectedCape != session->m_accountPtr->accountData()->minecraftProfile.currentCape) { - skinUpload.addTask(std::make_shared(this, session, selectedCape)); + if(selectedCape != m_acct->accountData()->minecraftProfile.currentCape) { + skinUpload.addTask(shared_qobject_ptr(new CapeChange(this, session, selectedCape))); } if (prog.execWithTask(&skinUpload) != QDialog::Accepted) { diff --git a/launcher/dialogs/UpdateDialog.cpp b/launcher/dialogs/UpdateDialog.cpp index ca3bd915..f3701546 100644 --- a/launcher/dialogs/UpdateDialog.cpp +++ b/launcher/dialogs/UpdateDialog.cpp @@ -1,7 +1,7 @@ #include "UpdateDialog.h" #include "ui_UpdateDialog.h" #include -#include "Launcher.h" +#include "Application.h" #include #include @@ -11,7 +11,7 @@ UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) { ui->setupUi(this); - auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); + auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); if(hasUpdate) { ui->label->setText(tr("A new %1 update is available!").arg(channel)); @@ -24,7 +24,7 @@ UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), u } ui->changelogBrowser->setHtml(tr("

Loading changelog...

")); loadChangelog(); - restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("UpdateDialogGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("UpdateDialogGeometry").toByteArray())); } UpdateDialog::~UpdateDialog() @@ -33,7 +33,7 @@ UpdateDialog::~UpdateDialog() void UpdateDialog::loadChangelog() { - auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); + auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); dljob.reset(new NetJob("Changelog")); QString url; if(channel == "stable") @@ -65,7 +65,7 @@ QString reprocessMarkdown(QByteArray markdown) QString reprocessCommits(QByteArray json) { - auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); + auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); try { QString result; @@ -177,6 +177,6 @@ void UpdateDialog::on_btnUpdateNow_clicked() void UpdateDialog::closeEvent(QCloseEvent* evt) { - LAUNCHER->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); QDialog::closeEvent(evt); } diff --git a/launcher/dialogs/VersionSelectDialog.cpp b/launcher/dialogs/VersionSelectDialog.cpp index 82eb70f4..a920f6b7 100644 --- a/launcher/dialogs/VersionSelectDialog.cpp +++ b/launcher/dialogs/VersionSelectDialog.cpp @@ -28,7 +28,7 @@ #include #include #include -#include "Launcher.h" +#include "Application.h" #include #include diff --git a/launcher/instanceview/InstanceProxyModel.cpp b/launcher/instanceview/InstanceProxyModel.cpp index 76434bd4..d8de93ed 100644 --- a/launcher/instanceview/InstanceProxyModel.cpp +++ b/launcher/instanceview/InstanceProxyModel.cpp @@ -16,7 +16,7 @@ #include "InstanceProxyModel.h" #include "InstanceView.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -34,7 +34,7 @@ QVariant InstanceProxyModel::data(const QModelIndex & index, int role) const QVariant data = QSortFilterProxyModel::data(index, role); if(role == Qt::DecorationRole) { - return QVariant(LAUNCHER->icons()->getIcon(data.toString())); + return QVariant(APPLICATION->icons()->getIcon(data.toString())); } return data; } @@ -59,7 +59,7 @@ bool InstanceProxyModel::subSortLessThan(const QModelIndex &left, const QModelIn { BaseInstance *pdataLeft = static_cast(left.internalPointer()); BaseInstance *pdataRight = static_cast(right.internalPointer()); - QString sortMode = LAUNCHER->settings()->get("InstSortMode").toString(); + QString sortMode = APPLICATION->settings()->get("InstSortMode").toString(); if (sortMode == "LastLaunch") { return pdataLeft->lastLaunch() > pdataRight->lastLaunch(); diff --git a/launcher/instanceview/InstanceView.cpp b/launcher/instanceview/InstanceView.cpp index 80dfb6f2..1f044866 100644 --- a/launcher/instanceview/InstanceView.cpp +++ b/launcher/instanceview/InstanceView.cpp @@ -30,7 +30,7 @@ #include "VisualGroup.h" #include -#include +#include #include @@ -628,7 +628,7 @@ void InstanceView::dropEvent(QDropEvent *event) return; } auto instanceId = QString::fromUtf8(mimedata->data("application/x-instanceid")); - auto instanceList = LAUNCHER->instances().get(); + auto instanceList = APPLICATION->instances().get(); instanceList->setInstanceGroup(instanceId, group->text); event->setDropAction(Qt::MoveAction); event->accept(); diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 81c61ab0..6d73ebfb 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -16,7 +16,7 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent) void JavaChecker::performCheck() { - QString checkerJar = FS::PathCombine(ENV.getJarsPath(), "JavaCheck.jar"); + QString checkerJar = FS::PathCombine(ENV->getJarsPath(), "JavaCheck.jar"); QStringList args; diff --git a/launcher/main.cpp b/launcher/main.cpp index 3c2b9445..3138e7af 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -1,4 +1,4 @@ -#include "Launcher.h" +#include "Application.h" #include "MainWindow.h" #include "LaunchController.h" #include @@ -34,12 +34,12 @@ int main(int argc, char *argv[]) #endif // initialize Qt - Launcher app(argc, argv); + Application app(argc, argv); switch (app.status()) { - case Launcher::StartingUp: - case Launcher::Initialized: + case Application::StartingUp: + case Application::Initialized: { Q_INIT_RESOURCE(multimc); Q_INIT_RESOURCE(backgrounds); @@ -55,9 +55,9 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(flat); return app.exec(); } - case Launcher::Failed: + case Application::Failed: return 1; - case Launcher::Succeeded: + case Application::Succeeded: return 0; } } diff --git a/launcher/meta/BaseEntity.cpp b/launcher/meta/BaseEntity.cpp index 5ff7a59a..1618c999 100644 --- a/launcher/meta/BaseEntity.cpp +++ b/launcher/meta/BaseEntity.cpp @@ -122,7 +122,7 @@ void Meta::BaseEntity::load(Net::Mode loadType) } NetJob *job = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename())); auto url = this->url(); - auto entry = ENV.metacache()->resolveEntry("meta", localFilename()); + auto entry = ENV->metacache()->resolveEntry("meta", localFilename()); entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); /* diff --git a/launcher/meta/Index_test.cpp b/launcher/meta/Index_test.cpp index b0892070..d5d477e8 100644 --- a/launcher/meta/Index_test.cpp +++ b/launcher/meta/Index_test.cpp @@ -12,8 +12,8 @@ private slots: void test_isProvidedByEnv() { - QVERIFY(ENV.metadataIndex()); - QCOMPARE(ENV.metadataIndex(), ENV.metadataIndex()); + QVERIFY(ENV->metadataIndex()); + QCOMPARE(ENV->metadataIndex(), ENV->metadataIndex()); } void test_hasUid_and_getList() diff --git a/launcher/minecraft/Component.cpp b/launcher/minecraft/Component.cpp index 92821065..385688d4 100644 --- a/launcher/minecraft/Component.cpp +++ b/launcher/minecraft/Component.cpp @@ -85,9 +85,9 @@ std::shared_ptr Component::getVersionFile() const std::shared_ptr Component::getVersionList() const { // FIXME: what if the metadata index isn't loaded yet? - if(ENV.metadataIndex()->hasUid(m_uid)) + if(ENV->metadataIndex()->hasUid(m_uid)) { - return ENV.metadataIndex()->get(m_uid); + return ENV->metadataIndex()->get(m_uid); } return nullptr; } @@ -192,7 +192,7 @@ bool Component::isRevertible() { if (isCustom()) { - if(ENV.metadataIndex()->hasUid(m_uid)) + if(ENV->metadataIndex()->hasUid(m_uid)) { return true; } @@ -266,7 +266,7 @@ void Component::setVersion(const QString& version) // we don't have a file, therefore we are loaded with metadata m_cachedVersion = version; // see if the meta version is loaded - auto metaVersion = ENV.metadataIndex()->get(m_uid, version); + auto metaVersion = ENV->metadataIndex()->get(m_uid, version); if(metaVersion->isLoaded()) { // if yes, we can continue with that. @@ -350,7 +350,7 @@ bool Component::revert() m_file.reset(); // check local cache for metadata... - auto version = ENV.metadataIndex()->get(m_uid, m_version); + auto version = ENV->metadataIndex()->get(m_uid, m_version); if(version->isLoaded()) { m_metaVersion = version; diff --git a/launcher/minecraft/ComponentUpdateTask.cpp b/launcher/minecraft/ComponentUpdateTask.cpp index 241d9a49..92ba1640 100644 --- a/launcher/minecraft/ComponentUpdateTask.cpp +++ b/launcher/minecraft/ComponentUpdateTask.cpp @@ -102,7 +102,7 @@ static LoadResult loadComponent(ComponentPtr component, shared_qobject_ptr } else { - auto metaVersion = ENV.metadataIndex()->get(component->m_uid, component->m_version); + auto metaVersion = ENV->metadataIndex()->get(component->m_uid, component->m_version); component->m_metaVersion = metaVersion; if(metaVersion->isLoaded()) { @@ -135,7 +135,7 @@ static LoadResult loadPackProfile(ComponentPtr component, shared_qobject_ptrget(component->m_uid); + auto metaList = ENV->metadataIndex()->get(component->m_uid); if(metaList->isLoaded()) { component->m_loaded = true; @@ -154,13 +154,13 @@ static LoadResult loadPackProfile(ComponentPtr component, shared_qobject_ptr& loadTask, Net::Mode netmode) { // FIXME: DECIDE. do we want to run the update task anyway? - if(ENV.metadataIndex()->isLoaded()) + if(ENV->metadataIndex()->isLoaded()) { qDebug() << "Index is already loaded"; return LoadResult::LoadedLocal; } - ENV.metadataIndex()->load(netmode); - loadTask = ENV.metadataIndex()->getCurrentTask(); + ENV->metadataIndex()->load(netmode); + loadTask = ENV->metadataIndex()->getCurrentTask(); if(loadTask) { return LoadResult::RequiresRemote; diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 2982a340..f755fa6e 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -816,7 +816,7 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt auto process = LaunchTask::create(std::dynamic_pointer_cast(shared_from_this())); auto pptr = process.get(); - ENV.icons()->saveIcon(iconKey(), FS::PathCombine(gameRoot(), "icon.png"), "PNG"); + ENV->icons()->saveIcon(iconKey(), FS::PathCombine(gameRoot(), "icon.png"), "PNG"); // print a header { diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index f6918116..f7612719 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -481,7 +481,7 @@ bool PackProfile::migratePreComponentConfig() } else if(!intendedVersion.isEmpty()) { - auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion); + auto metaVersion = ENV->metadataIndex()->get(uid, intendedVersion); component = new Component(this, metaVersion); } else @@ -546,7 +546,7 @@ bool PackProfile::migratePreComponentConfig() auto patchVersion = d->getOldConfigVersion(uid); if(!patchVersion.isEmpty() && !loadedComponents.contains(uid)) { - auto patch = new Component(this, ENV.metadataIndex()->get(uid, patchVersion)); + auto patch = new Component(this, ENV->metadataIndex()->get(uid, patchVersion)); patch->setOrder(order); loadedComponents[uid] = patch; } diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 5589cfe9..97ba48f4 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -37,6 +37,8 @@ enum AccountListVersion { AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) { } +AccountList::~AccountList() noexcept {} + int AccountList::findAccountByProfileId(const QString& profileId) const { for (int i = 0; i < count(); i++) { MinecraftAccountPtr account = at(i); @@ -62,6 +64,18 @@ const MinecraftAccountPtr AccountList::at(int i) const return MinecraftAccountPtr(m_accounts.at(i)); } +QStringList AccountList::profileNames() const { + QStringList out; + for(auto & account: m_accounts) { + auto profileName = account->profileName(); + if(profileName.isEmpty()) { + continue; + } + out.append(profileName); + } + return out; +} + void AccountList::addAccount(const MinecraftAccountPtr account) { auto profileId = account->profileId(); @@ -71,8 +85,8 @@ void AccountList::addAccount(const MinecraftAccountPtr account) if(existingAccount != -1) { MinecraftAccountPtr existingAccountPtr = m_accounts[existingAccount]; m_accounts[existingAccount] = account; - if(m_activeAccount == existingAccountPtr) { - m_activeAccount = account; + if(m_defaultAccount == existingAccountPtr) { + m_defaultAccount = account; } emit dataChanged(index(existingAccount), index(existingAccount, columnCount(QModelIndex()) - 1)); onListChanged(); @@ -80,10 +94,11 @@ void AccountList::addAccount(const MinecraftAccountPtr account) } } - // if we don't have this porfileId yet, add the account to the end + // if we don't have this profileId yet, add the account to the end int row = m_accounts.count(); beginInsertRows(QModelIndex(), row, row); - connect(account.get(), SIGNAL(changed()), SLOT(accountChanged())); + connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); + connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); endInsertRows(); onListChanged(); @@ -95,10 +110,10 @@ void AccountList::removeAccount(QModelIndex index) if(index.isValid() && row >= 0 && row < m_accounts.size()) { auto & account = m_accounts[row]; - if(account == m_activeAccount) + if(account == m_defaultAccount) { - m_activeAccount = nullptr; - onActiveChanged(); + m_defaultAccount = nullptr; + onDefaultAccountChanged(); } beginRemoveRows(QModelIndex(), row, row); m_accounts.removeAt(index.row()); @@ -107,54 +122,54 @@ void AccountList::removeAccount(QModelIndex index) } } -MinecraftAccountPtr AccountList::activeAccount() const +MinecraftAccountPtr AccountList::defaultAccount() const { - return m_activeAccount; + return m_defaultAccount; } -void AccountList::setActiveAccount(MinecraftAccountPtr newAccount) +void AccountList::setDefaultAccount(MinecraftAccountPtr newAccount) { - if (!newAccount && m_activeAccount) + if (!newAccount && m_defaultAccount) { int idx = 0; - auto prevActiveAcc = m_activeAccount; - m_activeAccount = nullptr; + auto previousDefaultAccount = m_defaultAccount; + m_defaultAccount = nullptr; for (MinecraftAccountPtr account : m_accounts) { - if (account == prevActiveAcc) + if (account == previousDefaultAccount) { - emit dataChanged(index(idx), index(idx)); + emit dataChanged(index(idx), index(idx, columnCount(QModelIndex()) - 1)); } idx ++; } - onActiveChanged(); + onDefaultAccountChanged(); } else { - auto currentActiveAccount = m_activeAccount; - int currentActiveAccountIdx = -1; - auto newActiveAccount = m_activeAccount; - int newActiveAccountIdx = -1; + auto currentDefaultAccount = m_defaultAccount; + int currentDefaultAccountIdx = -1; + auto newDefaultAccount = m_defaultAccount; + int newDefaultAccountIdx = -1; int idx = 0; for (MinecraftAccountPtr account : m_accounts) { if (account == newAccount) { - newActiveAccount = account; - newActiveAccountIdx = idx; + newDefaultAccount = account; + newDefaultAccountIdx = idx; } - if(currentActiveAccount == account) + if(currentDefaultAccount == account) { - currentActiveAccountIdx = idx; + currentDefaultAccountIdx = idx; } idx++; } - if(currentActiveAccount != newActiveAccount) + if(currentDefaultAccount != newDefaultAccount) { - emit dataChanged(index(currentActiveAccountIdx), index(currentActiveAccountIdx)); - emit dataChanged(index(newActiveAccountIdx), index(newActiveAccountIdx)); - m_activeAccount = newActiveAccount; - onActiveChanged(); + emit dataChanged(index(currentDefaultAccountIdx), index(currentDefaultAccountIdx, columnCount(QModelIndex()) - 1)); + emit dataChanged(index(newDefaultAccountIdx), index(newDefaultAccountIdx, columnCount(QModelIndex()) - 1)); + m_defaultAccount = newDefaultAccount; + onDefaultAccountChanged(); } } } @@ -165,6 +180,23 @@ void AccountList::accountChanged() onListChanged(); } +void AccountList::accountActivityChanged(bool active) +{ + MinecraftAccount *account = qobject_cast(sender()); + bool found = false; + for (int i = 0; i < count(); i++) { + if (at(i).get() == account) { + emit dataChanged(index(i), index(i, columnCount(QModelIndex()) - 1)); + found = true; + break; + } + } + if(found) { + emit listActivityChanged(); + } +} + + void AccountList::onListChanged() { if (m_autosave) @@ -174,12 +206,12 @@ void AccountList::onListChanged() emit listChanged(); } -void AccountList::onActiveChanged() +void AccountList::onDefaultAccountChanged() { if (m_autosave) saveList(); - emit activeAccountChanged(); + emit defaultAccountChanged(); } int AccountList::count() const @@ -211,6 +243,11 @@ QVariant AccountList::data(const QModelIndex &index, int role) const return typeStr; } + case StatusColumn: { + auto isActive = account->isActive(); + return isActive ? "Working" : "Ready"; + } + case ProfileNameColumn: { return account->profileName(); } @@ -235,13 +272,13 @@ QVariant AccountList::data(const QModelIndex &index, int role) const return account->accountDisplayString(); case PointerRole: - return qVariantFromValue(account); + return QVariant::fromValue(account); case Qt::CheckStateRole: switch (index.column()) { case NameColumn: - return account == m_activeAccount ? Qt::Checked : Qt::Unchecked; + return account == m_defaultAccount ? Qt::Checked : Qt::Unchecked; } default: @@ -260,6 +297,8 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r return tr("Account"); case TypeColumn: return tr("Type"); + case StatusColumn: + return tr("Status"); case MigrationColumn: return tr("Can Migrate?"); case ProfileNameColumn: @@ -275,6 +314,8 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r return tr("User name of the account."); case TypeColumn: return tr("Type of the account - Mojang or MSA."); + case StatusColumn: + return tr("Current status of the account."); case MigrationColumn: return tr("Can this account migrate to Microsoft account?"); case ProfileNameColumn: @@ -309,9 +350,9 @@ Qt::ItemFlags AccountList::flags(const QModelIndex &index) const return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -bool AccountList::setData(const QModelIndex &index, const QVariant &value, int role) +bool AccountList::setData(const QModelIndex &idx, const QVariant &value, int role) { - if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid()) + if (idx.row() < 0 || idx.row() >= rowCount(idx) || !idx.isValid()) { return false; } @@ -320,12 +361,12 @@ bool AccountList::setData(const QModelIndex &index, const QVariant &value, int r { if(value == Qt::Checked) { - MinecraftAccountPtr account = at(index.row()); - setActiveAccount(account); + MinecraftAccountPtr account = at(idx.row()); + setDefaultAccount(account); } } - emit dataChanged(index, index); + emit dataChanged(idx, index(idx.row(), columnCount(QModelIndex()) - 1)); return true; } @@ -395,7 +436,7 @@ bool AccountList::loadList() bool AccountList::loadV2(QJsonObject& root) { beginResetModel(); - auto activeUserName = root.value("activeAccount").toString(""); + auto defaultUserName = root.value("activeAccount").toString(""); QJsonArray accounts = root.value("accounts").toArray(); for (QJsonValue accountVal : accounts) { @@ -411,9 +452,10 @@ bool AccountList::loadV2(QJsonObject& root) { continue; } connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); + connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); - if (activeUserName.size() && account->mojangUserName() == activeUserName) { - m_activeAccount = account; + if (defaultUserName.size() && account->mojangUserName() == defaultUserName) { + m_defaultAccount = account; } } else @@ -441,9 +483,10 @@ bool AccountList::loadV3(QJsonObject& root) { } } connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); + connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); if(accountObj.value("active").toBool(false)) { - m_activeAccount = account; + m_defaultAccount = account; } } else @@ -490,7 +533,7 @@ bool AccountList::saveList() for (MinecraftAccountPtr account : m_accounts) { QJsonObject accountObj = account->saveToJson(); - if(m_activeAccount == account) { + if(m_defaultAccount == account) { accountObj["active"] = true; } accounts.append(accountObj); diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h index d6d72cd3..08004628 100644 --- a/launcher/minecraft/auth/AccountList.h +++ b/launcher/minecraft/auth/AccountList.h @@ -42,11 +42,13 @@ public: ProfileNameColumn, MigrationColumn, TypeColumn, + StatusColumn, NUM_COLUMNS }; explicit AccountList(QObject *parent = 0); + virtual ~AccountList() noexcept; const MinecraftAccountPtr at(int i) const; int count() const; @@ -63,6 +65,7 @@ public: void removeAccount(QModelIndex index); int findAccountByProfileId(const QString &profileId) const; MinecraftAccountPtr getAccountByProfileName(const QString &profileName) const; + QStringList profileNames() const; /*! * Sets the path to load/save the list file from/to. @@ -78,13 +81,14 @@ public: bool loadV3(QJsonObject &root); bool saveList(); - MinecraftAccountPtr activeAccount() const; - void setActiveAccount(MinecraftAccountPtr profileId); + MinecraftAccountPtr defaultAccount() const; + void setDefaultAccount(MinecraftAccountPtr profileId); bool anyAccountIsValid(); signals: void listChanged(); - void activeAccountChanged(); + void listActivityChanged(); + void defaultAccountChanged(); public slots: /** @@ -92,6 +96,11 @@ public slots: */ void accountChanged(); + /** + * This is called when a (refresh/login) task involving the account starts or ends + */ + void accountActivityChanged(bool active); + protected: /*! * Called whenever the list changes. @@ -101,13 +110,13 @@ protected: /*! * Called whenever the active account changes. - * Emits the activeAccountChanged() signal and autosaves the list if enabled. + * Emits the defaultAccountChanged() signal and autosaves the list if enabled. */ - void onActiveChanged(); + void onDefaultAccountChanged(); QList m_accounts; - MinecraftAccountPtr m_activeAccount; + MinecraftAccountPtr m_defaultAccount; //! Path to the account list file. Empty string if there isn't one. QString m_listFilePath; diff --git a/launcher/minecraft/auth/AccountTask.cpp b/launcher/minecraft/auth/AccountTask.cpp index d400ce8d..25d753de 100644 --- a/launcher/minecraft/auth/AccountTask.cpp +++ b/launcher/minecraft/auth/AccountTask.cpp @@ -23,10 +23,6 @@ #include #include -#include - -#include - #include AccountTask::AccountTask(AccountData *data, QObject *parent) diff --git a/launcher/minecraft/auth/AuthSession.h b/launcher/minecraft/auth/AuthSession.h index f631a97d..55fbdf39 100644 --- a/launcher/minecraft/auth/AuthSession.h +++ b/launcher/minecraft/auth/AuthSession.h @@ -3,8 +3,10 @@ #include #include #include +#include "QObjectPtr.h" class MinecraftAccount; +class QNetworkAccessManager; struct AuthSession { @@ -41,7 +43,6 @@ struct AuthSession bool auth_server_online = false; // Did the user request online mode? bool wants_online = true; - std::shared_ptr m_accountPtr; }; typedef std::shared_ptr AuthSessionPtr; diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index 8e294443..5cfec49d 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -28,11 +28,11 @@ #include #include -#include -#include +#include "flows/MSASilent.h" +#include "flows/MSAInteractive.h" -#include -#include +#include "flows/MojangRefresh.h" +#include "flows/MojangLogin.h" MinecraftAccountPtr MinecraftAccount::loadFromJsonV2(const QJsonObject& json) { MinecraftAccountPtr account(new MinecraftAccount()); @@ -104,7 +104,7 @@ QPixmap MinecraftAccount::getFace() const { } -std::shared_ptr MinecraftAccount::login(AuthSessionPtr session, QString password) +shared_qobject_ptr MinecraftAccount::login(AuthSessionPtr session, QString password) { Q_ASSERT(m_currentTask.get() == nullptr); @@ -140,11 +140,12 @@ std::shared_ptr MinecraftAccount::login(AuthSessionPtr session, QSt connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + emit activityChanged(true); } return m_currentTask; } -std::shared_ptr MinecraftAccount::loginMSA(AuthSessionPtr session) { +shared_qobject_ptr MinecraftAccount::loginMSA(AuthSessionPtr session) { Q_ASSERT(m_currentTask.get() == nullptr); if(accountStatus() == Verified && !session->wants_online) @@ -161,11 +162,12 @@ std::shared_ptr MinecraftAccount::loginMSA(AuthSessionPtr session) connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + emit activityChanged(true); } return m_currentTask; } -std::shared_ptr MinecraftAccount::refresh(AuthSessionPtr session) { +shared_qobject_ptr MinecraftAccount::refresh(AuthSessionPtr session) { Q_ASSERT(m_currentTask.get() == nullptr); // take care of the true offline status @@ -203,6 +205,7 @@ std::shared_ptr MinecraftAccount::refresh(AuthSessionPtr session) { connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + emit activityChanged(true); } return m_currentTask; } @@ -233,6 +236,7 @@ void MinecraftAccount::authSucceeded() } m_currentTask.reset(); emit changed(); + emit activityChanged(false); } void MinecraftAccount::authFailed(QString reason) @@ -297,6 +301,45 @@ void MinecraftAccount::authFailed(QString reason) } } m_currentTask.reset(); + emit activityChanged(false); +} + +bool MinecraftAccount::isActive() const { + return m_currentTask; +} + +bool MinecraftAccount::shouldRefresh() const { + /* + * Never refresh accounts that are being used by the game, it breaks the game session. + * Always refresh accounts that have not been refreshed yet during this session. + * Don't refresh broken accounts. + * Refresh accounts that would expire in the next 12 hours (fresh token validity is 24 hours). + */ + if(isInUse()) { + return false; + } + switch(data.validity_) { + case Katabasis::Validity::Certain: { + break; + } + case Katabasis::Validity::None: { + return false; + } + case Katabasis::Validity::Assumed: { + return true; + } + } + auto now = QDateTime::currentDateTimeUtc(); + auto issuedTimestamp = data.yggdrasilToken.issueInstant; + auto expiresTimestamp = data.yggdrasilToken.notAfter; + + if(!expiresTimestamp.isValid()) { + expiresTimestamp = issuedTimestamp.addSecs(24 * 3600); + } + if (now.secsTo(expiresTimestamp) < 12 * 3600) { + return true; + } + return false; } void MinecraftAccount::fillSession(AuthSessionPtr session) @@ -322,7 +365,6 @@ void MinecraftAccount::fillSession(AuthSessionPtr session) { session->session = "-"; } - session->m_accountPtr = shared_from_this(); } void MinecraftAccount::decrementUses() diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h index 5b0c1ec7..928d3742 100644 --- a/launcher/minecraft/auth/MinecraftAccount.h +++ b/launcher/minecraft/auth/MinecraftAccount.h @@ -27,12 +27,13 @@ #include "AuthSession.h" #include "Usable.h" #include "AccountData.h" +#include "QObjectPtr.h" class Task; class AccountTask; class MinecraftAccount; -typedef std::shared_ptr MinecraftAccountPtr; +typedef shared_qobject_ptr MinecraftAccountPtr; Q_DECLARE_METATYPE(MinecraftAccountPtr) /** @@ -63,8 +64,7 @@ enum AccountStatus */ class MinecraftAccount : public QObject, - public Usable, - public std::enable_shared_from_this + public Usable { Q_OBJECT public: /* construction */ @@ -90,11 +90,11 @@ public: /* manipulation */ * Attempt to login. Empty password means we use the token. * If the attempt fails because we already are performing some task, it returns false. */ - std::shared_ptr login(AuthSessionPtr session, QString password = QString()); + shared_qobject_ptr login(AuthSessionPtr session, QString password); - std::shared_ptr loginMSA(AuthSessionPtr session); + shared_qobject_ptr loginMSA(AuthSessionPtr session); - std::shared_ptr refresh(AuthSessionPtr session); + shared_qobject_ptr refresh(AuthSessionPtr session); public: /* queries */ QString accountDisplayString() const { @@ -117,6 +117,8 @@ public: /* queries */ return data.profileName(); } + bool isActive() const; + bool canMigrate() const { return data.canMigrateToMSA; } @@ -153,19 +155,23 @@ public: /* queries */ return &data; } + bool shouldRefresh() const; + signals: /** * This signal is emitted when the account changes */ void changed(); + void activityChanged(bool active); + // TODO: better signalling for the various possible state changes - especially errors protected: /* variables */ AccountData data; // current task we are executing here - std::shared_ptr m_currentTask; + shared_qobject_ptr m_currentTask; protected: /* methods */ diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp index 39f14b26..32ee4cbd 100644 --- a/launcher/minecraft/auth/flows/AuthContext.cpp +++ b/launcher/minecraft/auth/flows/AuthContext.cpp @@ -4,28 +4,21 @@ #include #include #include - #include #include #include - #include - #include -#include -#include - #include "AuthContext.h" #include "katabasis/Globals.h" #include "AuthRequest.h" -#include "Secrets.h" - -#include "Env.h" - #include "Parsers.h" +#include +#include + using OAuth2 = Katabasis::OAuth2; using Activity = Katabasis::Activity; @@ -58,19 +51,14 @@ void AuthContext::initMSA() { return; } - auto clientId = Secrets::getMSAClientID('-'); - if(clientId.isEmpty()) { - return; - } - Katabasis::OAuth2::Options opts; opts.scope = "XboxLive.signin offline_access"; - opts.clientIdentifier = clientId; + opts.clientIdentifier = APPLICATION->msaClientId(); opts.authorizationUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"; opts.accessTokenUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"; opts.listenerPorts = {28562, 28563, 28564, 28565, 28566}; - m_oauth2 = new OAuth2(opts, m_data->msaToken, this, &ENV.network()); + m_oauth2 = new OAuth2(opts, m_data->msaToken, this, &ENV->network()); m_oauth2->setGrantFlow(Katabasis::OAuth2::GrantFlowDevice); connect(m_oauth2, &OAuth2::linkingFailed, this, &AuthContext::onOAuthLinkingFailed); diff --git a/launcher/minecraft/auth/flows/AuthRequest.cpp b/launcher/minecraft/auth/flows/AuthRequest.cpp index 513c4c08..751b079d 100644 --- a/launcher/minecraft/auth/flows/AuthRequest.cpp +++ b/launcher/minecraft/auth/flows/AuthRequest.cpp @@ -7,7 +7,8 @@ #include "AuthRequest.h" #include "katabasis/Globals.h" -#include "Env.h" + +#include AuthRequest::AuthRequest(QObject *parent): QObject(parent) { } @@ -17,7 +18,7 @@ AuthRequest::~AuthRequest() { void AuthRequest::get(const QNetworkRequest &req, int timeout/* = 60*1000*/) { setup(req, QNetworkAccessManager::GetOperation); - reply_ = ENV.network().get(request_); + reply_ = ENV->network().get(request_); status_ = Requesting; timedReplies_.add(new Katabasis::Reply(reply_, timeout)); connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError))); @@ -29,7 +30,7 @@ void AuthRequest::post(const QNetworkRequest &req, const QByteArray &data, int t setup(req, QNetworkAccessManager::PostOperation); data_ = data; status_ = Requesting; - reply_ = ENV.network().post(request_, data_); + reply_ = ENV->network().post(request_, data_); timedReplies_.add(new Katabasis::Reply(reply_, timeout)); connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError))); connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished())); @@ -89,7 +90,7 @@ void AuthRequest::onUploadProgress(qint64 uploaded, qint64 total) { emit uploadProgress(uploaded, total); } -void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Operation operation) { +void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Operation operation, const QByteArray &verb) { request_ = req; operation_ = operation; url_ = req.url(); @@ -97,6 +98,10 @@ void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Opera QUrl url = url_; request_.setUrl(url); + if (!verb.isEmpty()) { + request_.setRawHeader(Katabasis::HTTP_HTTP_HEADER, verb); + } + status_ = Requesting; error_ = QNetworkReply::NoError; } diff --git a/launcher/minecraft/auth/flows/AuthRequest.h b/launcher/minecraft/auth/flows/AuthRequest.h index 20f385b3..a547aea4 100644 --- a/launcher/minecraft/auth/flows/AuthRequest.h +++ b/launcher/minecraft/auth/flows/AuthRequest.h @@ -5,7 +5,6 @@ #include #include #include -#include #include "katabasis/Reply.h" @@ -48,7 +47,7 @@ protected slots: void onUploadProgress(qint64 uploaded, qint64 total); protected: - void setup(const QNetworkRequest &request, QNetworkAccessManager::Operation operation); + void setup(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &verb = QByteArray()); enum Status { Idle, Requesting, ReRequesting diff --git a/launcher/minecraft/auth/flows/MSAInteractive.cpp b/launcher/minecraft/auth/flows/MSAInteractive.cpp index 03beb279..6c597cf7 100644 --- a/launcher/minecraft/auth/flows/MSAInteractive.cpp +++ b/launcher/minecraft/auth/flows/MSAInteractive.cpp @@ -1,6 +1,9 @@ #include "MSAInteractive.h" -MSAInteractive::MSAInteractive(AccountData* data, QObject* parent) : AuthContext(data, parent) {} +MSAInteractive::MSAInteractive( + AccountData* data, + QObject* parent +) : AuthContext(data, parent) {} void MSAInteractive::executeTask() { m_requestsDone = 0; diff --git a/launcher/minecraft/auth/flows/MSAInteractive.h b/launcher/minecraft/auth/flows/MSAInteractive.h index 9556f254..6654e0d6 100644 --- a/launcher/minecraft/auth/flows/MSAInteractive.h +++ b/launcher/minecraft/auth/flows/MSAInteractive.h @@ -5,6 +5,9 @@ class MSAInteractive : public AuthContext { Q_OBJECT public: - explicit MSAInteractive(AccountData * data, QObject *parent = 0); + explicit MSAInteractive( + AccountData *data, + QObject *parent = 0 + ); void executeTask() override; }; diff --git a/launcher/minecraft/auth/flows/MSASilent.h b/launcher/minecraft/auth/flows/MSASilent.h index e1b3d43d..a442b49e 100644 --- a/launcher/minecraft/auth/flows/MSASilent.h +++ b/launcher/minecraft/auth/flows/MSASilent.h @@ -5,6 +5,9 @@ class MSASilent : public AuthContext { Q_OBJECT public: - explicit MSASilent(AccountData * data, QObject *parent = 0); + explicit MSASilent( + AccountData * data, + QObject *parent = 0 + ); void executeTask() override; }; diff --git a/launcher/minecraft/auth/flows/MojangLogin.cpp b/launcher/minecraft/auth/flows/MojangLogin.cpp index cca911b5..6c217cd1 100644 --- a/launcher/minecraft/auth/flows/MojangLogin.cpp +++ b/launcher/minecraft/auth/flows/MojangLogin.cpp @@ -1,6 +1,10 @@ #include "MojangLogin.h" -MojangLogin::MojangLogin(AccountData* data, QString password, QObject* parent) : AuthContext(data, parent), m_password(password) {} +MojangLogin::MojangLogin( + AccountData *data, + QString password, + QObject *parent +): AuthContext(data, parent), m_password(password) {} void MojangLogin::executeTask() { m_requestsDone = 0; diff --git a/launcher/minecraft/auth/flows/MojangLogin.h b/launcher/minecraft/auth/flows/MojangLogin.h index 2e765ae8..5f33752f 100644 --- a/launcher/minecraft/auth/flows/MojangLogin.h +++ b/launcher/minecraft/auth/flows/MojangLogin.h @@ -5,7 +5,11 @@ class MojangLogin : public AuthContext { Q_OBJECT public: - explicit MojangLogin(AccountData * data, QString password, QObject *parent = 0); + explicit MojangLogin( + AccountData *data, + QString password, + QObject *parent = 0 + ); void executeTask() override; private: diff --git a/launcher/minecraft/auth/flows/MojangRefresh.cpp b/launcher/minecraft/auth/flows/MojangRefresh.cpp index af99175c..008c0453 100644 --- a/launcher/minecraft/auth/flows/MojangRefresh.cpp +++ b/launcher/minecraft/auth/flows/MojangRefresh.cpp @@ -1,6 +1,9 @@ #include "MojangRefresh.h" -MojangRefresh::MojangRefresh(AccountData* data, QObject* parent) : AuthContext(data, parent) {} +MojangRefresh::MojangRefresh( + AccountData *data, + QObject *parent +) : AuthContext(data, parent) {} void MojangRefresh::executeTask() { m_requestsDone = 0; diff --git a/launcher/minecraft/auth/flows/MojangRefresh.h b/launcher/minecraft/auth/flows/MojangRefresh.h index fb4facd5..06e4e4ce 100644 --- a/launcher/minecraft/auth/flows/MojangRefresh.h +++ b/launcher/minecraft/auth/flows/MojangRefresh.h @@ -5,6 +5,6 @@ class MojangRefresh : public AuthContext { Q_OBJECT public: - explicit MojangRefresh(AccountData * data, QObject *parent = 0); + explicit MojangRefresh(AccountData *data, QObject *parent = 0); void executeTask() override; }; diff --git a/launcher/minecraft/auth/flows/Parsers.h b/launcher/minecraft/auth/flows/Parsers.h index 6c6b64ee..b484a073 100644 --- a/launcher/minecraft/auth/flows/Parsers.h +++ b/launcher/minecraft/auth/flows/Parsers.h @@ -1,6 +1,6 @@ #pragma once -#include "minecraft/auth/AccountData.h" +#include "../AccountData.h" namespace Parsers { diff --git a/launcher/minecraft/auth/flows/Yggdrasil.cpp b/launcher/minecraft/auth/flows/Yggdrasil.cpp index 4f94e91f..fc0b18bf 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.cpp +++ b/launcher/minecraft/auth/flows/Yggdrasil.cpp @@ -23,12 +23,10 @@ #include #include -#include - -#include - #include +#include + Yggdrasil::Yggdrasil(AccountData *data, QObject *parent) : AccountTask(data, parent) { @@ -40,7 +38,7 @@ void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) { QNetworkRequest netRequest(endpoint); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - m_netReply = ENV.network().post(netRequest, content); + m_netReply = ENV->network().post(netRequest, content); connect(m_netReply, &QNetworkReply::finished, this, &Yggdrasil::processReply); connect(m_netReply, &QNetworkReply::uploadProgress, this, &Yggdrasil::refreshTimers); connect(m_netReply, &QNetworkReply::downloadProgress, this, &Yggdrasil::refreshTimers); @@ -86,7 +84,7 @@ void Yggdrasil::refresh() { req.insert("requestUser", false); QJsonDocument doc(req); - QUrl reqUrl(BuildConfig.AUTH_BASE + "refresh"); + QUrl reqUrl("https://authserver.mojang.com/refresh"); QByteArray requestData = doc.toJson(); sendRequest(reqUrl, requestData); @@ -131,7 +129,7 @@ void Yggdrasil::login(QString password) { QJsonDocument doc(req); - QUrl reqUrl(BuildConfig.AUTH_BASE + "authenticate"); + QUrl reqUrl("https://authserver.mojang.com/authenticate"); QNetworkRequest netRequest(reqUrl); QByteArray requestData = doc.toJson(); @@ -140,20 +138,18 @@ void Yggdrasil::login(QString password) { -void Yggdrasil::refreshTimers(qint64, qint64) -{ +void Yggdrasil::refreshTimers(qint64, qint64) { timeout_keeper.stop(); timeout_keeper.start(timeout_max); progress(count = 0, timeout_max); } -void Yggdrasil::heartbeat() -{ + +void Yggdrasil::heartbeat() { count += time_step; progress(count, timeout_max); } -bool Yggdrasil::abort() -{ +bool Yggdrasil::abort() { progress(timeout_max, timeout_max); // TODO: actually use this in a meaningful way m_aborted = Yggdrasil::BY_USER; @@ -161,19 +157,16 @@ bool Yggdrasil::abort() return true; } -void Yggdrasil::abortByTimeout() -{ +void Yggdrasil::abortByTimeout() { progress(timeout_max, timeout_max); // TODO: actually use this in a meaningful way m_aborted = Yggdrasil::BY_TIMEOUT; m_netReply->abort(); } -void Yggdrasil::sslErrors(QList errors) -{ +void Yggdrasil::sslErrors(QList errors) { int i = 1; - for (auto error : errors) - { + for (auto error : errors) { qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString(); auto cert = error.certificate(); qCritical() << "Certificate in question:\n" << cert.toText(); @@ -181,8 +174,7 @@ void Yggdrasil::sslErrors(QList errors) } } -void Yggdrasil::processResponse(QJsonObject responseData) -{ +void Yggdrasil::processResponse(QJsonObject responseData) { // Read the response data. We need to get the client token, access token, and the selected // profile. qDebug() << "Processing authentication response."; @@ -191,8 +183,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) // If we already have a client token, make sure the one the server gave us matches our // existing one. QString clientToken = responseData.value("clientToken").toString(""); - if (clientToken.isEmpty()) - { + if (clientToken.isEmpty()) { // Fail if the server gave us an empty client token changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token.")); return; @@ -208,8 +199,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) // Now, we set the access token. qDebug() << "Getting access token."; QString accessToken = responseData.value("accessToken").toString(""); - if (accessToken.isEmpty()) - { + if (accessToken.isEmpty()) { // Fail if the server didn't give us an access token. changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token.")); return; @@ -217,6 +207,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) // Set the access token. m_data->yggdrasilToken.token = accessToken; m_data->yggdrasilToken.validity = Katabasis::Validity::Certain; + m_data->yggdrasilToken.issueInstant = QDateTime::currentDateTimeUtc(); // We've made it through the minefield of possible errors. Return true to indicate that // we've succeeded. @@ -224,8 +215,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) changeState(STATE_SUCCEEDED); } -void Yggdrasil::processReply() -{ +void Yggdrasil::processReply() { changeState(STATE_WORKING); switch (m_netReply->error()) @@ -247,9 +237,9 @@ void Yggdrasil::processReply() "
  • You use Windows and need to update your root certificates, please install any outstanding updates.
  • " "
  • Some device on your network is interfering with SSL traffic. In that case, " "you have bigger worries than Minecraft not starting.
  • " - "
  • Possibly something else. Check the %1 log file for details
  • " + "
  • Possibly something else. Check the log file for details
  • " "" - ).arg(BuildConfig.LAUNCHER_NAME) + ) ); return; // used for invalid credentials and similar errors. Fall through. @@ -278,19 +268,16 @@ void Yggdrasil::processReply() // Check the response code. int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (responseCode == 200) - { + if (responseCode == 200) { // If the response code was 200, then there shouldn't be an error. Make sure // anyways. // Also, sometimes an empty reply indicates success. If there was no data received, // pass an empty json object to the processResponse function. - if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0) - { + if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0) { processResponse(replyData.size() > 0 ? doc.object() : QJsonObject()); return; } - else - { + else { changeState( STATE_FAILED_SOFT, tr("Failed to parse authentication server response JSON response: %1 at offset %2.").arg(jsonError.errorString()).arg(jsonError.offset) @@ -304,16 +291,14 @@ void Yggdrasil::processReply() // about the error. // If we can parse the response, then get information from it. Otherwise just say // there was an unknown error. - if (jsonError.error == QJsonParseError::NoError) - { + if (jsonError.error == QJsonParseError::NoError) { // We were able to parse the server's response. Woo! // Call processError. If a subclass has overridden it then they'll handle their // stuff there. qDebug() << "The request failed, but the server gave us an error message. Processing error."; processError(doc.object()); } - else - { + else { // The server didn't say anything regarding the error. Give the user an unknown // error. qDebug() << "The request failed and the server gave no error message. Unknown error."; @@ -324,14 +309,12 @@ void Yggdrasil::processReply() } } -void Yggdrasil::processError(QJsonObject responseData) -{ +void Yggdrasil::processError(QJsonObject responseData) { QJsonValue errorVal = responseData.value("error"); QJsonValue errorMessageValue = responseData.value("errorMessage"); QJsonValue causeVal = responseData.value("cause"); - if (errorVal.isString() && errorMessageValue.isString()) - { + if (errorVal.isString() && errorMessageValue.isString()) { m_error = std::shared_ptr( new Error { errorVal.toString(""), @@ -341,8 +324,7 @@ void Yggdrasil::processError(QJsonObject responseData) ); changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose); } - else - { + else { // Error is not in standard format. Don't set m_error and return unknown error. changeState(STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred.")); } diff --git a/launcher/minecraft/auth/flows/Yggdrasil.h b/launcher/minecraft/auth/flows/Yggdrasil.h index e709cb9f..b9670ec7 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.h +++ b/launcher/minecraft/auth/flows/Yggdrasil.h @@ -24,6 +24,7 @@ #include "../MinecraftAccount.h" +class QNetworkAccessManager; class QNetworkReply; /** @@ -33,7 +34,10 @@ class Yggdrasil : public AccountTask { Q_OBJECT public: - explicit Yggdrasil(AccountData * data, QObject *parent = 0); + explicit Yggdrasil( + AccountData *data, + QObject *parent = 0 + ); virtual ~Yggdrasil() {}; void refresh(); diff --git a/launcher/minecraft/launch/ClaimAccount.cpp b/launcher/minecraft/launch/ClaimAccount.cpp index a1180f0a..bb4f6806 100644 --- a/launcher/minecraft/launch/ClaimAccount.cpp +++ b/launcher/minecraft/launch/ClaimAccount.cpp @@ -1,11 +1,15 @@ #include "ClaimAccount.h" #include +#include "Application.h" +#include "minecraft/auth/AccountList.h" + ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session): LaunchStep(parent) { if(session->status == AuthSession::Status::PlayableOnline) { - m_account = session->m_accountPtr; + auto accounts = APPLICATION->accounts(); + m_account = accounts->getAccountByProfileName(session->player_name); } } diff --git a/launcher/minecraft/launch/LauncherPartLaunch.cpp b/launcher/minecraft/launch/LauncherPartLaunch.cpp index ff022c40..190bbbbf 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.cpp +++ b/launcher/minecraft/launch/LauncherPartLaunch.cpp @@ -72,7 +72,7 @@ void LauncherPartLaunch::executeTask() m_process.setDetachable(true); auto classPath = minecraftInstance->getClassPath(); - classPath.prepend(FS::PathCombine(ENV.getJarsPath(), "NewLaunch.jar")); + classPath.prepend(FS::PathCombine(ENV->getJarsPath(), "NewLaunch.jar")); auto natPath = minecraftInstance->getNativePath(); #ifdef Q_OS_WIN diff --git a/launcher/minecraft/services/CapeChange.cpp b/launcher/minecraft/services/CapeChange.cpp index d439b091..43da74fb 100644 --- a/launcher/minecraft/services/CapeChange.cpp +++ b/launcher/minecraft/services/CapeChange.cpp @@ -12,7 +12,7 @@ void CapeChange::setCape(QString& cape) { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active")); auto requestString = QString("{\"capeId\":\"%1\"}").arg(m_capeId); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit()); - QNetworkReply *rep = ENV.network().put(request, requestString.toUtf8()); + QNetworkReply *rep = ENV->network().put(request, requestString.toUtf8()); setStatus(tr("Equipping cape")); @@ -26,7 +26,7 @@ void CapeChange::clearCape() { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active")); auto requestString = QString("{\"capeId\":\"%1\"}").arg(m_capeId); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit()); - QNetworkReply *rep = ENV.network().deleteResource(request); + QNetworkReply *rep = ENV->network().deleteResource(request); setStatus(tr("Removing cape")); diff --git a/launcher/minecraft/services/SkinDelete.cpp b/launcher/minecraft/services/SkinDelete.cpp index bb2bdb5b..4675b01a 100644 --- a/launcher/minecraft/services/SkinDelete.cpp +++ b/launcher/minecraft/services/SkinDelete.cpp @@ -12,7 +12,7 @@ void SkinDelete::executeTask() { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/skins/active")); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit()); - QNetworkReply *rep = ENV.network().deleteResource(request); + QNetworkReply *rep = ENV->network().deleteResource(request); m_reply = std::shared_ptr(rep); setStatus(tr("Deleting skin")); diff --git a/launcher/minecraft/services/SkinUpload.cpp b/launcher/minecraft/services/SkinUpload.cpp index b74f962c..e54f2327 100644 --- a/launcher/minecraft/services/SkinUpload.cpp +++ b/launcher/minecraft/services/SkinUpload.cpp @@ -37,7 +37,7 @@ void SkinUpload::executeTask() multiPart->append(skin); multiPart->append(model); - QNetworkReply *rep = ENV.network().post(request, multiPart); + QNetworkReply *rep = ENV->network().post(request, multiPart); m_reply = std::shared_ptr(rep); setStatus(tr("Uploading skin")); diff --git a/launcher/minecraft/update/AssetUpdateTask.cpp b/launcher/minecraft/update/AssetUpdateTask.cpp index e26ab4ef..c8dcdc53 100644 --- a/launcher/minecraft/update/AssetUpdateTask.cpp +++ b/launcher/minecraft/update/AssetUpdateTask.cpp @@ -24,7 +24,7 @@ void AssetUpdateTask::executeTask() QString localPath = assets->id + ".json"; auto job = new NetJob(tr("Asset index for %1").arg(m_inst->name())); - auto metacache = ENV.metacache(); + auto metacache = ENV->metacache(); auto entry = metacache->resolveEntry("asset_indexes", localPath); entry->setStale(true); auto hexSha1 = assets->sha1.toLatin1(); @@ -62,7 +62,7 @@ void AssetUpdateTask::assetIndexFinished() // FIXME: this looks like a job for a generic validator based on json schema? if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, index)) { - auto metacache = ENV.metacache(); + auto metacache = ENV->metacache(); auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json"); metacache->evictEntry(entry); emitFailed(tr("Failed to read the assets index!")); diff --git a/launcher/minecraft/update/FMLLibrariesTask.cpp b/launcher/minecraft/update/FMLLibrariesTask.cpp index 8f1a43ff..e7efb369 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.cpp +++ b/launcher/minecraft/update/FMLLibrariesTask.cpp @@ -60,7 +60,7 @@ void FMLLibrariesTask::executeTask() // download missing libs to our place setStatus(tr("Downloading FML libraries...")); auto dljob = new NetJob("FML libraries"); - auto metacache = ENV.metacache(); + auto metacache = ENV->metacache(); for (auto &lib : fmlLibsToProcess) { auto entry = metacache->resolveEntry("fmllibs", lib.filename); @@ -87,7 +87,7 @@ void FMLLibrariesTask::fmllibsFinished() { setStatus(tr("Copying FML libraries into the instance...")); MinecraftInstance *inst = (MinecraftInstance *)m_inst; - auto metacache = ENV.metacache(); + auto metacache = ENV->metacache(); int index = 0; for (auto &lib : fmlLibsToProcess) { diff --git a/launcher/minecraft/update/LibrariesTask.cpp b/launcher/minecraft/update/LibrariesTask.cpp index 7f66a651..40f0a78c 100644 --- a/launcher/minecraft/update/LibrariesTask.cpp +++ b/launcher/minecraft/update/LibrariesTask.cpp @@ -21,7 +21,7 @@ void LibrariesTask::executeTask() auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name())); downloadJob.reset(job); - auto metacache = ENV.metacache(); + auto metacache = ENV->metacache(); auto processArtifactPool = [&](const QList & pool, QStringList & errors, const QString & localPath) { diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 55087a27..66b592bb 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -76,7 +76,7 @@ void PackInstallTask::onDownloadSucceeded() } m_version = version; - auto vlist = ENV.metadataIndex()->get("net.minecraft"); + auto vlist = ENV->metadataIndex()->get("net.minecraft"); if(!vlist) { emitFailed(tr("Failed to get local metadata index for %1").arg("net.minecraft")); @@ -157,7 +157,7 @@ QString PackInstallTask::getDirForModType(ModType type, QString raw) QString PackInstallTask::getVersionForLoader(QString uid) { if(m_version.loader.recommended || m_version.loader.latest || m_version.loader.choose) { - auto vlist = ENV.metadataIndex()->get(uid); + auto vlist = ENV->metadataIndex()->get(uid); if(!vlist) { emitFailed(tr("Failed to get local metadata index for %1").arg(uid)); @@ -409,7 +409,7 @@ void PackInstallTask::installConfigs() auto path = QString("Configs/%1/%2.zip").arg(m_pack).arg(m_version_name); auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.zip") .arg(m_pack).arg(m_version_name); - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", path); + auto entry = ENV->metacache()->resolveEntry("ATLauncherPacks", path); entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); @@ -516,7 +516,7 @@ void PackInstallTask::downloadMods() auto cacheName = fileName.completeBaseName() + "-" + mod.md5 + "." + fileName.suffix(); if (mod.type == ModType::Extract || mod.type == ModType::TexturePackExtract || mod.type == ModType::ResourcePackExtract) { - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); + auto entry = ENV->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); modsToExtract.insert(entry->getFullPath(), mod); @@ -528,7 +528,7 @@ void PackInstallTask::downloadMods() jobPtr->addNetAction(dl); } else if(mod.type == ModType::Decomp) { - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); + auto entry = ENV->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); modsToDecomp.insert(entry->getFullPath(), mod); @@ -543,7 +543,7 @@ void PackInstallTask::downloadMods() auto relpath = getDirForModType(mod.type, mod.type_raw); if(relpath == Q_NULLPTR) continue; - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); + auto entry = ENV->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); @@ -558,7 +558,7 @@ void PackInstallTask::downloadMods() modsToCopy[entry->getFullPath()] = path; if(mod.type == ModType::Forge) { - auto vlist = ENV.metadataIndex()->get("net.minecraftforge"); + auto vlist = ENV->metadataIndex()->get("net.minecraftforge"); if(vlist) { auto ver = vlist->getVersion(mod.version); diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index c77f3250..70b0ab94 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -31,7 +31,7 @@ void PackInstallTask::downloadPack() setStatus(tr("Downloading zip for %1").arg(m_pack.name)); auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file); - auto entry = ENV.metacache()->resolveEntry("FTBPacks", packoffset); + auto entry = ENV->metacache()->resolveEntry("FTBPacks", packoffset); NetJob *job = new NetJob("Download FTB Pack"); entry->setStale(true); diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 496edde7..785d3dd6 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -102,7 +102,7 @@ void PackInstallTask::downloadPack() QFileInfo fileName(file.name); auto cacheName = fileName.completeBaseName() + "-" + file.sha1 + "." + fileName.suffix(); - auto entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", cacheName); + auto entry = ENV->metacache()->resolveEntry("ModpacksCHPacks", cacheName); entry->setStale(true); auto relpath = FS::PathCombine("minecraft", file.path, file.name); diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp index dbce8e53..f2aa37a0 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp @@ -41,7 +41,7 @@ void Technic::SingleZipPackInstallTask::executeTask() setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path(); - auto entry = ENV.metacache()->resolveEntry("general", path); + auto entry = ENV->metacache()->resolveEntry("general", path); entry->setStale(true); m_filesNetJob.reset(new NetJob(tr("Modpack download"))); m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry)); diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp index d19bbfc8..48c49dde 100644 --- a/launcher/net/Download.cpp +++ b/launcher/net/Download.cpp @@ -97,7 +97,7 @@ void Download::start() request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT); - QNetworkReply *rep = ENV.network().get(request); + QNetworkReply *rep = ENV->network().get(request); m_reply.reset(rep); connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64))); diff --git a/launcher/net/MetaCacheSink.cpp b/launcher/net/MetaCacheSink.cpp index d7f18533..ae9314f1 100644 --- a/launcher/net/MetaCacheSink.cpp +++ b/launcher/net/MetaCacheSink.cpp @@ -53,7 +53,7 @@ JobStatus MetaCacheSink::finalizeCache(QNetworkReply & reply) } m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); m_entry->setStale(false); - ENV.metacache()->updateEntry(m_entry); + ENV->metacache()->updateEntry(m_entry); return Job_Finished; } diff --git a/launcher/net/PasteUpload.cpp b/launcher/net/PasteUpload.cpp index 675e8f0b..159c3e2a 100644 --- a/launcher/net/PasteUpload.cpp +++ b/launcher/net/PasteUpload.cpp @@ -41,7 +41,7 @@ void PasteUpload::executeTask() request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size())); request.setRawHeader("X-Auth-Token", m_key.toStdString().c_str()); - QNetworkReply *rep = ENV.network().post(request, m_jsonContent); + QNetworkReply *rep = ENV->network().post(request, m_jsonContent); m_reply = std::shared_ptr(rep); setStatus(tr("Uploading to paste.ee")); diff --git a/launcher/notifications/NotificationChecker.cpp b/launcher/notifications/NotificationChecker.cpp index 8209c28b..4ccd3d6c 100644 --- a/launcher/notifications/NotificationChecker.cpp +++ b/launcher/notifications/NotificationChecker.cpp @@ -53,7 +53,7 @@ void NotificationChecker::checkForNotifications() return; } m_checkJob.reset(new NetJob("Checking for notifications")); - auto entry = ENV.metacache()->resolveEntry("root", "notifications.json"); + auto entry = ENV->metacache()->resolveEntry("root", "notifications.json"); entry->setStale(true); m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry)); connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded); diff --git a/launcher/pagedialog/PageDialog.cpp b/launcher/pagedialog/PageDialog.cpp index 79d7acd3..3f508990 100644 --- a/launcher/pagedialog/PageDialog.cpp +++ b/launcher/pagedialog/PageDialog.cpp @@ -20,7 +20,7 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include "settings/SettingsObject.h" #include "widgets/IconLabel.h" #include "widgets/PageContainer.h" @@ -45,7 +45,7 @@ PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidge connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close())); connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help())); - restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("PagedGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } void PageDialog::closeEvent(QCloseEvent *event) @@ -54,7 +54,7 @@ void PageDialog::closeEvent(QCloseEvent *event) if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; - LAUNCHER->settings()->set("PagedGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); qDebug() << "Paged dialog geometry saved"; QDialog::closeEvent(event); } diff --git a/launcher/pages/global/AccountListPage.cpp b/launcher/pages/global/AccountListPage.cpp index bf5ab633..d0138dcc 100644 --- a/launcher/pages/global/AccountListPage.cpp +++ b/launcher/pages/global/AccountListPage.cpp @@ -32,7 +32,7 @@ #include "minecraft/auth/AccountTask.h" #include "minecraft/services/SkinDelete.h" -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" #include @@ -50,7 +50,7 @@ AccountListPage::AccountListPage(QWidget *parent) ui->listView->setEmptyMode(VersionListView::String); ui->listView->setContextMenuPolicy(Qt::CustomContextMenu); - m_accounts = LAUNCHER->accounts(); + m_accounts = APPLICATION->accounts(); ui->listView->setModel(m_accounts.get()); ui->listView->header()->setSectionResizeMode(0, QHeaderView::Stretch); @@ -68,7 +68,8 @@ AccountListPage::AccountListPage(QWidget *parent) connect(ui->listView, &VersionListView::customContextMenuRequested, this, &AccountListPage::ShowContextMenu); connect(m_accounts.get(), &AccountList::listChanged, this, &AccountListPage::listChanged); - connect(m_accounts.get(), &AccountList::activeAccountChanged, this, &AccountListPage::listChanged); + connect(m_accounts.get(), &AccountList::listActivityChanged, this, &AccountListPage::listChanged); + connect(m_accounts.get(), &AccountList::defaultAccountChanged, this, &AccountListPage::listChanged); updateButtonStates(); @@ -117,11 +118,11 @@ void AccountListPage::on_actionAddMojang_triggered() tr("Please enter your Mojang account email and password to add your account.") ); - if (account != nullptr) + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { - m_accounts->setActiveAccount(account); + m_accounts->setDefaultAccount(account); } } } @@ -145,11 +146,11 @@ void AccountListPage::on_actionAddMicrosoft_triggered() tr("Please enter your Mojang account email and password to add your account.") ); - if (account != nullptr) + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { - m_accounts->setActiveAccount(account); + m_accounts->setDefaultAccount(account); } } } @@ -187,27 +188,34 @@ void AccountListPage::on_actionSetDefault_triggered() { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); - m_accounts->setActiveAccount(account); + m_accounts->setDefaultAccount(account); } } void AccountListPage::on_actionNoDefault_triggered() { - m_accounts->setActiveAccount(nullptr); + m_accounts->setDefaultAccount(nullptr); } void AccountListPage::updateButtonStates() { // If there is no selection, disable buttons that require something selected. QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + bool hasSelection = selection.size() > 0; + bool accountIsReady = false; + if (hasSelection) + { + QModelIndex selected = selection.first(); + MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); + accountIsReady = !account->isActive(); + } + ui->actionRemove->setEnabled(accountIsReady); + ui->actionSetDefault->setEnabled(accountIsReady); + ui->actionUploadSkin->setEnabled(accountIsReady); + ui->actionDeleteSkin->setEnabled(accountIsReady); + ui->actionRefresh->setEnabled(accountIsReady); - ui->actionRemove->setEnabled(selection.size() > 0); - ui->actionSetDefault->setEnabled(selection.size() > 0); - ui->actionUploadSkin->setEnabled(selection.size() > 0); - ui->actionDeleteSkin->setEnabled(selection.size() > 0); - ui->actionRefresh->setEnabled(selection.size() > 0); - - if(m_accounts->activeAccount().get() == nullptr) { + if(m_accounts->defaultAccount().get() == nullptr) { ui->actionNoDefault->setEnabled(false); ui->actionNoDefault->setChecked(true); } @@ -215,7 +223,6 @@ void AccountListPage::updateButtonStates() ui->actionNoDefault->setEnabled(true); ui->actionNoDefault->setChecked(false); } - } void AccountListPage::on_actionUploadSkin_triggered() diff --git a/launcher/pages/global/AccountListPage.h b/launcher/pages/global/AccountListPage.h index ee81acd1..eb131ea8 100644 --- a/launcher/pages/global/AccountListPage.h +++ b/launcher/pages/global/AccountListPage.h @@ -21,7 +21,7 @@ #include "pages/BasePage.h" #include "minecraft/auth/AccountList.h" -#include "Launcher.h" +#include "Application.h" namespace Ui { @@ -43,10 +43,10 @@ public: } QIcon icon() const override { - auto icon = LAUNCHER->getThemedIcon("accounts"); + auto icon = APPLICATION->getThemedIcon("accounts"); if(icon.isNull()) { - icon = LAUNCHER->getThemedIcon("noaccount"); + icon = APPLICATION->getThemedIcon("noaccount"); } return icon; } @@ -80,6 +80,6 @@ protected slots: private: void changeEvent(QEvent * event) override; QMenu * createPopupMenu() override; - std::shared_ptr m_accounts; + shared_qobject_ptr m_accounts; Ui::AccountListPage *ui; }; diff --git a/launcher/pages/global/CustomCommandsPage.cpp b/launcher/pages/global/CustomCommandsPage.cpp index 8a5c3445..8541e3c1 100644 --- a/launcher/pages/global/CustomCommandsPage.cpp +++ b/launcher/pages/global/CustomCommandsPage.cpp @@ -32,7 +32,7 @@ bool CustomCommandsPage::apply() void CustomCommandsPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); s->set("PreLaunchCommand", commands->prelaunchCommand()); s->set("WrapperCommand", commands->wrapperCommand()); s->set("PostExitCommand", commands->postexitCommand()); @@ -40,7 +40,7 @@ void CustomCommandsPage::applySettings() void CustomCommandsPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); commands->initialize( false, true, diff --git a/launcher/pages/global/CustomCommandsPage.h b/launcher/pages/global/CustomCommandsPage.h index ac69a997..f81b192a 100644 --- a/launcher/pages/global/CustomCommandsPage.h +++ b/launcher/pages/global/CustomCommandsPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "widgets/CustomCommands.h" class CustomCommandsPage : public QWidget, public BasePage @@ -36,7 +36,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("custom-commands"); + return APPLICATION->getThemedIcon("custom-commands"); } QString id() const override { diff --git a/launcher/pages/global/ExternalToolsPage.cpp b/launcher/pages/global/ExternalToolsPage.cpp index 7e1a915f..41d900aa 100644 --- a/launcher/pages/global/ExternalToolsPage.cpp +++ b/launcher/pages/global/ExternalToolsPage.cpp @@ -24,7 +24,7 @@ #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" #include -#include "Launcher.h" +#include "Application.h" #include ExternalToolsPage::ExternalToolsPage(QWidget *parent) : @@ -51,7 +51,7 @@ ExternalToolsPage::~ExternalToolsPage() void ExternalToolsPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString()); ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString()); ui->mceditPathEdit->setText(s->get("MCEditPath").toString()); @@ -61,7 +61,7 @@ void ExternalToolsPage::loadSettings() } void ExternalToolsPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); s->set("JProfilerPath", ui->jprofilerPathEdit->text()); s->set("JVisualVMPath", ui->jvisualvmPathEdit->text()); @@ -93,7 +93,7 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked() break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!LAUNCHER->profilers()["jprofiler"]->check(cooked_dir, &error)) + if (!APPLICATION->profilers()["jprofiler"]->check(cooked_dir, &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error)); continue; @@ -108,7 +108,7 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked() void ExternalToolsPage::on_jprofilerCheckBtn_clicked() { QString error; - if (!LAUNCHER->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) + if (!APPLICATION->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error)); } @@ -130,7 +130,7 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!LAUNCHER->profilers()["jvisualvm"]->check(cooked_dir, &error)) + if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); continue; @@ -145,7 +145,7 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() void ExternalToolsPage::on_jvisualvmCheckBtn_clicked() { QString error; - if (!LAUNCHER->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) + if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); } @@ -171,7 +171,7 @@ void ExternalToolsPage::on_mceditPathBtn_clicked() break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!LAUNCHER->mcedit()->check(cooked_dir, error)) + if (!APPLICATION->mcedit()->check(cooked_dir, error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error)); continue; @@ -186,7 +186,7 @@ void ExternalToolsPage::on_mceditPathBtn_clicked() void ExternalToolsPage::on_mceditCheckBtn_clicked() { QString error; - if (!LAUNCHER->mcedit()->check(ui->mceditPathEdit->text(), error)) + if (!APPLICATION->mcedit()->check(ui->mceditPathEdit->text(), error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error)); } diff --git a/launcher/pages/global/ExternalToolsPage.h b/launcher/pages/global/ExternalToolsPage.h index 1d99273a..9571ce75 100644 --- a/launcher/pages/global/ExternalToolsPage.h +++ b/launcher/pages/global/ExternalToolsPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { class ExternalToolsPage; @@ -38,10 +38,10 @@ public: } QIcon icon() const override { - auto icon = LAUNCHER->getThemedIcon("externaltools"); + auto icon = APPLICATION->getThemedIcon("externaltools"); if(icon.isNull()) { - icon = LAUNCHER->getThemedIcon("loadermods"); + icon = APPLICATION->getThemedIcon("loadermods"); } return icon; } diff --git a/launcher/pages/global/JavaPage.cpp b/launcher/pages/global/JavaPage.cpp index dd158fcd..fe545636 100644 --- a/launcher/pages/global/JavaPage.cpp +++ b/launcher/pages/global/JavaPage.cpp @@ -29,7 +29,7 @@ #include "settings/SettingsObject.h" #include -#include "Launcher.h" +#include "Application.h" #include JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) @@ -55,7 +55,7 @@ bool JavaPage::apply() void JavaPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Memory int min = ui->minMemSpinBox->value(); @@ -79,7 +79,7 @@ void JavaPage::applySettings() } void JavaPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Memory int min = s->get("MinMemAlloc").toInt(); int max = s->get("MaxMemAlloc").toInt(); @@ -104,7 +104,7 @@ void JavaPage::on_javaDetectBtn_clicked() { JavaInstallPtr java; - VersionSelectDialog vselect(LAUNCHER->javalist().get(), tr("Select a Java version"), this, true); + VersionSelectDialog vselect(APPLICATION->javalist().get(), tr("Select a Java version"), this, true); vselect.setResizeOn(2); vselect.exec(); diff --git a/launcher/pages/global/JavaPage.h b/launcher/pages/global/JavaPage.h index 93a586cd..56a1d36b 100644 --- a/launcher/pages/global/JavaPage.h +++ b/launcher/pages/global/JavaPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" #include "JavaCommon.h" -#include +#include #include class SettingsObject; @@ -43,7 +43,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("java"); + return APPLICATION->getThemedIcon("java"); } QString id() const override { diff --git a/launcher/pages/global/LanguagePage.cpp b/launcher/pages/global/LanguagePage.cpp index 409bf7d0..142517db 100644 --- a/launcher/pages/global/LanguagePage.cpp +++ b/launcher/pages/global/LanguagePage.cpp @@ -26,7 +26,7 @@ bool LanguagePage::apply() void LanguagePage::applySettings() { - auto settings = LAUNCHER->settings(); + auto settings = APPLICATION->settings(); QString key = mainWidget->getSelectedLanguageKey(); settings->set("Language", key); } diff --git a/launcher/pages/global/LanguagePage.h b/launcher/pages/global/LanguagePage.h index 22db8f94..c269cefc 100644 --- a/launcher/pages/global/LanguagePage.h +++ b/launcher/pages/global/LanguagePage.h @@ -17,7 +17,7 @@ #include #include "pages/BasePage.h" -#include +#include #include class LanguageSelectionWidget; @@ -36,7 +36,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("language"); + return APPLICATION->getThemedIcon("language"); } QString id() const override { diff --git a/launcher/pages/global/LauncherPage.cpp b/launcher/pages/global/LauncherPage.cpp index 5f8d87d8..b77a9e81 100644 --- a/launcher/pages/global/LauncherPage.cpp +++ b/launcher/pages/global/LauncherPage.cpp @@ -25,7 +25,7 @@ #include "settings/SettingsObject.h" #include -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" #include "themes/ITheme.h" @@ -53,20 +53,20 @@ LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::Launch defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat()); - m_languageModel = LAUNCHER->translations(); + m_languageModel = APPLICATION->translations(); loadSettings(); if(BuildConfig.UPDATER_ENABLED) { - QObject::connect(LAUNCHER->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &LauncherPage::refreshUpdateChannelList); + QObject::connect(APPLICATION->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &LauncherPage::refreshUpdateChannelList); - if (LAUNCHER->updateChecker()->hasChannels()) + if (APPLICATION->updateChecker()->hasChannels()) { refreshUpdateChannelList(); } else { - LAUNCHER->updateChecker()->updateChanList(false); + APPLICATION->updateChecker()->updateChanList(false); } } else @@ -171,7 +171,7 @@ void LauncherPage::refreshUpdateChannelList() QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateChannelSelectionChanged(int))); - QList channelList = LAUNCHER->updateChecker()->getChannelList(); + QList channelList = APPLICATION->updateChecker()->getChannelList(); ui->updateChannelComboBox->clear(); int selection = -1; for (int i = 0; i < channelList.count(); i++) @@ -216,7 +216,7 @@ void LauncherPage::updateChannelSelectionChanged(int index) void LauncherPage::refreshUpdateChannelDesc() { // Get the channel list. - QList channelList = LAUNCHER->updateChecker()->getChannelList(); + QList channelList = APPLICATION->updateChecker()->getChannelList(); int selectedIndex = ui->updateChannelComboBox->currentIndex(); if (selectedIndex < 0) { @@ -237,7 +237,7 @@ void LauncherPage::refreshUpdateChannelDesc() void LauncherPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); if (ui->resetNotificationsBtn->isChecked()) { @@ -283,7 +283,7 @@ void LauncherPage::applySettings() if(original != s->get("IconTheme")) { - LAUNCHER->setIconTheme(s->get("IconTheme").toString()); + APPLICATION->setIconTheme(s->get("IconTheme").toString()); } auto originalAppTheme = s->get("ApplicationTheme").toString(); @@ -291,7 +291,7 @@ void LauncherPage::applySettings() if(originalAppTheme != newAppTheme) { s->set("ApplicationTheme", newAppTheme); - LAUNCHER->setApplicationTheme(newAppTheme, false); + APPLICATION->setApplicationTheme(newAppTheme, false); } // Console settings @@ -330,7 +330,7 @@ void LauncherPage::applySettings() } void LauncherPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Updates ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); m_currentUpdateChannel = s->get("UpdateChannel").toString(); @@ -375,7 +375,7 @@ void LauncherPage::loadSettings() { auto currentTheme = s->get("ApplicationTheme").toString(); - auto themes = LAUNCHER->getValidApplicationThemes(); + auto themes = APPLICATION->getValidApplicationThemes(); int idx = 0; for(auto &theme: themes) { @@ -392,12 +392,12 @@ void LauncherPage::loadSettings() ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); ui->showConsoleErrorCheck->setChecked(s->get("ShowConsoleOnError").toBool()); - QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); QFont consoleFont(fontFamily); ui->consoleFont->setCurrentFont(consoleFont); bool conversionOk = true; - int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/global/LauncherPage.h b/launcher/pages/global/LauncherPage.h index e622ec48..62a4f84c 100644 --- a/launcher/pages/global/LauncherPage.h +++ b/launcher/pages/global/LauncherPage.h @@ -20,7 +20,7 @@ #include "java/JavaChecker.h" #include "pages/BasePage.h" -#include +#include #include "ColorCache.h" #include @@ -46,7 +46,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("launcher"); + return APPLICATION->getThemedIcon("launcher"); } QString id() const override { diff --git a/launcher/pages/global/MinecraftPage.cpp b/launcher/pages/global/MinecraftPage.cpp index 342941f4..c763f8ac 100644 --- a/launcher/pages/global/MinecraftPage.cpp +++ b/launcher/pages/global/MinecraftPage.cpp @@ -21,7 +21,7 @@ #include #include "settings/SettingsObject.h" -#include "Launcher.h" +#include "Application.h" MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage) { @@ -56,7 +56,7 @@ void MinecraftPage::on_maximizedCheckBox_clicked(bool checked) void MinecraftPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Window Size s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); @@ -75,7 +75,7 @@ void MinecraftPage::applySettings() void MinecraftPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Window Size ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); diff --git a/launcher/pages/global/MinecraftPage.h b/launcher/pages/global/MinecraftPage.h index 0fc6cc8e..96a90f6e 100644 --- a/launcher/pages/global/MinecraftPage.h +++ b/launcher/pages/global/MinecraftPage.h @@ -20,7 +20,7 @@ #include "java/JavaChecker.h" #include "pages/BasePage.h" -#include +#include class SettingsObject; @@ -43,7 +43,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("minecraft"); + return APPLICATION->getThemedIcon("minecraft"); } QString id() const override { diff --git a/launcher/pages/global/PasteEEPage.cpp b/launcher/pages/global/PasteEEPage.cpp index 9f7a7efb..4b375d9a 100644 --- a/launcher/pages/global/PasteEEPage.cpp +++ b/launcher/pages/global/PasteEEPage.cpp @@ -23,7 +23,7 @@ #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" -#include "Launcher.h" +#include "Application.h" PasteEEPage::PasteEEPage(QWidget *parent) : QWidget(parent), @@ -42,7 +42,7 @@ PasteEEPage::~PasteEEPage() void PasteEEPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); QString keyToUse = s->get("PasteEEAPIKey").toString(); if(keyToUse == "multimc") { @@ -57,7 +57,7 @@ void PasteEEPage::loadSettings() void PasteEEPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); QString pasteKeyToUse; if (ui->customButton->isChecked()) diff --git a/launcher/pages/global/PasteEEPage.h b/launcher/pages/global/PasteEEPage.h index c99cd51e..0ea74e7c 100644 --- a/launcher/pages/global/PasteEEPage.h +++ b/launcher/pages/global/PasteEEPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { class PasteEEPage; @@ -38,7 +38,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("log"); + return APPLICATION->getThemedIcon("log"); } QString id() const override { diff --git a/launcher/pages/global/ProxyPage.cpp b/launcher/pages/global/ProxyPage.cpp index d4e767e1..622b8ef3 100644 --- a/launcher/pages/global/ProxyPage.cpp +++ b/launcher/pages/global/ProxyPage.cpp @@ -19,7 +19,7 @@ #include #include "settings/SettingsObject.h" -#include "Launcher.h" +#include "Application.h" #include "Env.h" ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage) @@ -58,7 +58,7 @@ void ProxyPage::proxyChanged(int) void ProxyPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Proxy QString proxyType = "None"; @@ -77,12 +77,12 @@ void ProxyPage::applySettings() s->set("ProxyUser", ui->proxyUserEdit->text()); s->set("ProxyPass", ui->proxyPassEdit->text()); - ENV.updateProxySettings(proxyType, ui->proxyAddrEdit->text(), ui->proxyPortEdit->value(), + ENV->updateProxySettings(proxyType, ui->proxyAddrEdit->text(), ui->proxyPortEdit->value(), ui->proxyUserEdit->text(), ui->proxyPassEdit->text()); } void ProxyPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Proxy QString proxyType = s->get("ProxyType").toString(); if (proxyType == "Default") diff --git a/launcher/pages/global/ProxyPage.h b/launcher/pages/global/ProxyPage.h index 90c33c9d..91f1fbaa 100644 --- a/launcher/pages/global/ProxyPage.h +++ b/launcher/pages/global/ProxyPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -40,7 +40,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("proxy"); + return APPLICATION->getThemedIcon("proxy"); } QString id() const override { diff --git a/launcher/pages/instance/GameOptionsPage.h b/launcher/pages/instance/GameOptionsPage.h index ca7e31b1..31e7b2dd 100644 --- a/launcher/pages/instance/GameOptionsPage.h +++ b/launcher/pages/instance/GameOptionsPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("settings"); + return APPLICATION->getThemedIcon("settings"); } virtual QString id() const override { diff --git a/launcher/pages/instance/InstanceSettingsPage.cpp b/launcher/pages/instance/InstanceSettingsPage.cpp index c83832c6..730fcbbd 100644 --- a/launcher/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/pages/instance/InstanceSettingsPage.cpp @@ -7,7 +7,7 @@ #include "dialogs/VersionSelectDialog.h" #include "JavaCommon.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -22,8 +22,8 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) auto sysMB = Sys::getSystemRam() / Sys::mebibyte; ui->maxMemSpinBox->setMaximum(sysMB); connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); - connect(LAUNCHER, &Launcher::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); - connect(LAUNCHER, &Launcher::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); + connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); + connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); loadSettings(); } @@ -41,13 +41,13 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) { switch(ui->settingsTabs->currentIndex()) { case 0: - LAUNCHER->ShowGlobalSettings(this, "java-settings"); + APPLICATION->ShowGlobalSettings(this, "java-settings"); return; case 1: - LAUNCHER->ShowGlobalSettings(this, "minecraft-settings"); + APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); return; case 2: - LAUNCHER->ShowGlobalSettings(this, "custom-commands"); + APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; } } @@ -278,7 +278,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() { JavaInstallPtr java; - VersionSelectDialog vselect(LAUNCHER->javalist().get(), tr("Select a Java version"), this, true); + VersionSelectDialog vselect(APPLICATION->javalist().get(), tr("Select a Java version"), this, true); vselect.setResizeOn(2); vselect.exec(); diff --git a/launcher/pages/instance/InstanceSettingsPage.h b/launcher/pages/instance/InstanceSettingsPage.h index a039101c..88169a67 100644 --- a/launcher/pages/instance/InstanceSettingsPage.h +++ b/launcher/pages/instance/InstanceSettingsPage.h @@ -22,7 +22,7 @@ #include #include "pages/BasePage.h" #include "JavaCommon.h" -#include "Launcher.h" +#include "Application.h" class JavaChecker; namespace Ui @@ -43,7 +43,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("instance-settings"); + return APPLICATION->getThemedIcon("instance-settings"); } virtual QString id() const override { diff --git a/launcher/pages/instance/LegacyUpgradePage.cpp b/launcher/pages/instance/LegacyUpgradePage.cpp index b12174fa..21444756 100644 --- a/launcher/pages/instance/LegacyUpgradePage.cpp +++ b/launcher/pages/instance/LegacyUpgradePage.cpp @@ -4,7 +4,7 @@ #include "InstanceList.h" #include "minecraft/legacy/LegacyInstance.h" #include "minecraft/legacy/LegacyUpgradeTask.h" -#include "Launcher.h" +#include "Application.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/ProgressDialog.h" @@ -38,9 +38,9 @@ void LegacyUpgradePage::on_upgradeButton_clicked() QString newName = tr("%1 (Migrated)").arg(m_inst->name()); auto upgradeTask = new LegacyUpgradeTask(m_inst); upgradeTask->setName(newName); - upgradeTask->setGroup(LAUNCHER->instances()->getInstanceGroup(m_inst->id())); + upgradeTask->setGroup(APPLICATION->instances()->getInstanceGroup(m_inst->id())); upgradeTask->setIcon(m_inst->iconKey()); - unique_qobject_ptr task(LAUNCHER->instances()->wrapInstanceTask(upgradeTask)); + unique_qobject_ptr task(APPLICATION->instances()->wrapInstanceTask(upgradeTask)); runModalTask(task.get()); } diff --git a/launcher/pages/instance/LegacyUpgradePage.h b/launcher/pages/instance/LegacyUpgradePage.h index d8e98f6b..f4b7b57c 100644 --- a/launcher/pages/instance/LegacyUpgradePage.h +++ b/launcher/pages/instance/LegacyUpgradePage.h @@ -19,7 +19,7 @@ #include "minecraft/legacy/LegacyInstance.h" #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" namespace Ui @@ -40,7 +40,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("checkupdate"); + return APPLICATION->getThemedIcon("checkupdate"); } virtual QString id() const override { diff --git a/launcher/pages/instance/LogPage.cpp b/launcher/pages/instance/LogPage.cpp index 2846dc51..b9046b62 100644 --- a/launcher/pages/instance/LogPage.cpp +++ b/launcher/pages/instance/LogPage.cpp @@ -1,7 +1,7 @@ #include "LogPage.h" #include "ui_LogPage.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -125,9 +125,9 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent) // set up fonts in the log proxy { - QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); bool conversionOk = false; - int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/instance/LogPage.h b/launcher/pages/instance/LogPage.h index 285296cd..270a533a 100644 --- a/launcher/pages/instance/LogPage.h +++ b/launcher/pages/instance/LogPage.h @@ -20,7 +20,7 @@ #include "BaseInstance.h" #include "launch/LaunchTask.h" #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -42,7 +42,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("log"); + return APPLICATION->getThemedIcon("log"); } virtual QString id() const override { diff --git a/launcher/pages/instance/ModFolderPage.cpp b/launcher/pages/instance/ModFolderPage.cpp index caa81958..6d496e55 100644 --- a/launcher/pages/instance/ModFolderPage.cpp +++ b/launcher/pages/instance/ModFolderPage.cpp @@ -22,7 +22,7 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include "dialogs/CustomMessageBox.h" #include #include "minecraft/mod/ModFolderModel.h" @@ -301,7 +301,7 @@ void ModFolderPage::on_actionAdd_triggered() tr("Select %1", "Select whatever type of files the page contains. Example: 'Loader Mods'") .arg(m_displayName), - m_fileSelectionFilter.arg(m_displayName), LAUNCHER->settings()->get("CentralModsDir").toString(), + m_fileSelectionFilter.arg(m_displayName), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!list.empty()) { diff --git a/launcher/pages/instance/ModFolderPage.h b/launcher/pages/instance/ModFolderPage.h index 38fcc6a5..7a81f63a 100644 --- a/launcher/pages/instance/ModFolderPage.h +++ b/launcher/pages/instance/ModFolderPage.h @@ -19,7 +19,7 @@ #include "minecraft/MinecraftInstance.h" #include "pages/BasePage.h" -#include +#include class ModFolderModel; namespace Ui @@ -54,7 +54,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon(m_iconName); + return APPLICATION->getThemedIcon(m_iconName); } virtual QString id() const override { diff --git a/launcher/pages/instance/NotesPage.h b/launcher/pages/instance/NotesPage.h index 1bdb352d..23d2684a 100644 --- a/launcher/pages/instance/NotesPage.h +++ b/launcher/pages/instance/NotesPage.h @@ -19,7 +19,7 @@ #include "BaseInstance.h" #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -39,9 +39,9 @@ public: } virtual QIcon icon() const override { - auto icon = LAUNCHER->getThemedIcon("notes"); + auto icon = APPLICATION->getThemedIcon("notes"); if(icon.isNull()) - icon = LAUNCHER->getThemedIcon("news"); + icon = APPLICATION->getThemedIcon("news"); return icon; } virtual QString id() const override diff --git a/launcher/pages/instance/OtherLogsPage.cpp b/launcher/pages/instance/OtherLogsPage.cpp index 31cd44ed..6705c059 100644 --- a/launcher/pages/instance/OtherLogsPage.cpp +++ b/launcher/pages/instance/OtherLogsPage.cpp @@ -129,9 +129,9 @@ void OtherLogsPage::on_btnReload_clicked() { auto setPlainText = [&](const QString & text) { - QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); bool conversionOk = false; - int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/instance/OtherLogsPage.h b/launcher/pages/instance/OtherLogsPage.h index 25f127f6..c8323659 100644 --- a/launcher/pages/instance/OtherLogsPage.h +++ b/launcher/pages/instance/OtherLogsPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include namespace Ui @@ -46,7 +46,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("log"); + return APPLICATION->getThemedIcon("log"); } QString helpPage() const override { diff --git a/launcher/pages/instance/ScreenshotsPage.cpp b/launcher/pages/instance/ScreenshotsPage.cpp index 172e2eb3..f24cf486 100644 --- a/launcher/pages/instance/ScreenshotsPage.cpp +++ b/launcher/pages/instance/ScreenshotsPage.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include "dialogs/ProgressDialog.h" #include "dialogs/CustomMessageBox.h" @@ -104,7 +104,7 @@ public: { m_thumbnailingPool.setMaxThreadCount(4); m_thumbnailCache = std::make_shared(); - m_thumbnailCache->add("placeholder", LAUNCHER->getThemedIcon("screenshot-placeholder")); + m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); // FIXME: the watched file set is not updated when files are removed } diff --git a/launcher/pages/instance/ScreenshotsPage.h b/launcher/pages/instance/ScreenshotsPage.h index 01f26642..84145b0e 100644 --- a/launcher/pages/instance/ScreenshotsPage.h +++ b/launcher/pages/instance/ScreenshotsPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include class QFileSystemModel; class QIdentityProxyModel; @@ -53,7 +53,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("screenshots"); + return APPLICATION->getThemedIcon("screenshots"); } virtual QString id() const override { diff --git a/launcher/pages/instance/ServersPage.cpp b/launcher/pages/instance/ServersPage.cpp index 6c55fdac..8116d2bf 100644 --- a/launcher/pages/instance/ServersPage.cpp +++ b/launcher/pages/instance/ServersPage.cpp @@ -324,7 +324,7 @@ public: if(px.loadFromData(bytes)) return QIcon(px); } - return LAUNCHER->getThemedIcon("unknown_server"); + return APPLICATION->getThemedIcon("unknown_server"); } case Qt::DisplayRole: return m_servers[row].m_name; @@ -762,7 +762,7 @@ void ServersPage::on_actionMove_Down_triggered() void ServersPage::on_actionJoin_triggered() { const auto &address = m_model->at(currentServer)->m_address; - LAUNCHER->launch(m_inst, true, nullptr, std::make_shared(MinecraftServerTarget::parse(address))); + APPLICATION->launch(m_inst, true, nullptr, std::make_shared(MinecraftServerTarget::parse(address))); } #include "ServersPage.moc" diff --git a/launcher/pages/instance/ServersPage.h b/launcher/pages/instance/ServersPage.h index 63f3b9e3..1f678bce 100644 --- a/launcher/pages/instance/ServersPage.h +++ b/launcher/pages/instance/ServersPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -47,7 +47,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("unknown_server"); + return APPLICATION->getThemedIcon("unknown_server"); } virtual QString id() const override { diff --git a/launcher/pages/instance/VersionPage.cpp b/launcher/pages/instance/VersionPage.cpp index 103f0c7a..15d5d8d5 100644 --- a/launcher/pages/instance/VersionPage.cpp +++ b/launcher/pages/instance/VersionPage.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include #include @@ -70,14 +70,14 @@ public: auto string = var.toString(); if(string == "warning") { - return LAUNCHER->getThemedIcon("status-yellow"); + return APPLICATION->getThemedIcon("status-yellow"); } else if(string == "error") { - return LAUNCHER->getThemedIcon("status-bad"); + return APPLICATION->getThemedIcon("status-bad"); } } - return LAUNCHER->getThemedIcon("status-good"); + return APPLICATION->getThemedIcon("status-good"); } return var; } @@ -93,7 +93,7 @@ private: QIcon VersionPage::icon() const { - return LAUNCHER->icons()->getIcon(m_inst->iconKey()); + return APPLICATION->icons()->getIcon(m_inst->iconKey()); } bool VersionPage::shouldDisplay() const { @@ -297,7 +297,7 @@ void VersionPage::on_actionInstall_mods_triggered() void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() { - auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); + auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if(!list.empty()) { m_profile->installJarMods(list); @@ -307,7 +307,7 @@ void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() void VersionPage::on_actionReplace_Minecraft_jar_triggered() { - auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); + auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if(!jarPath.isEmpty()) { m_profile->installCustomJar(jarPath); @@ -395,7 +395,7 @@ void VersionPage::on_actionChange_version_triggered() void VersionPage::on_actionDownload_All_triggered() { - if (!LAUNCHER->accounts()->anyAccountIsValid()) + if (!APPLICATION->accounts()->anyAccountIsValid()) { CustomMessageBox::selectable( this, tr("Error"), @@ -420,7 +420,7 @@ void VersionPage::on_actionDownload_All_triggered() void VersionPage::on_actionInstall_Forge_triggered() { - auto vlist = ENV.metadataIndex()->get("net.minecraftforge"); + auto vlist = ENV->metadataIndex()->get("net.minecraftforge"); if(!vlist) { return; @@ -449,7 +449,7 @@ void VersionPage::on_actionInstall_Forge_triggered() void VersionPage::on_actionInstall_Fabric_triggered() { - auto vlist = ENV.metadataIndex()->get("net.fabricmc.fabric-loader"); + auto vlist = ENV->metadataIndex()->get("net.fabricmc.fabric-loader"); if(!vlist) { return; @@ -494,7 +494,7 @@ void VersionPage::on_actionAdd_Empty_triggered() void VersionPage::on_actionInstall_LiteLoader_triggered() { - auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader"); + auto vlist = ENV->metadataIndex()->get("com.mumfrey.liteloader"); if(!vlist) { return; @@ -614,7 +614,7 @@ void VersionPage::on_actionEdit_triggered() qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!"; return; } - LAUNCHER->openJsonEditor(filename); + APPLICATION->openJsonEditor(filename); } void VersionPage::on_actionRevert_triggered() diff --git a/launcher/pages/instance/WorldListPage.cpp b/launcher/pages/instance/WorldListPage.cpp index d25f23a8..1af38bb8 100644 --- a/launcher/pages/instance/WorldListPage.cpp +++ b/launcher/pages/instance/WorldListPage.cpp @@ -26,7 +26,7 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include #include #include @@ -48,7 +48,7 @@ public: auto iconFile = worlds->data(sourceIndex, WorldList::IconFileRole).toString(); if(iconFile.isNull()) { // NOTE: Minecraft uses the same placeholder for servers AND worlds - return LAUNCHER->getThemedIcon("unknown_server"); + return APPLICATION->getThemedIcon("unknown_server"); } return QIcon(iconFile); } @@ -218,7 +218,7 @@ void WorldListPage::on_actionCopy_Seed_triggered() return; } int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong(); - LAUNCHER->clipboard()->setText(QString::number(seed)); + APPLICATION->clipboard()->setText(QString::number(seed)); } void WorldListPage::on_actionMCEdit_triggered() @@ -226,7 +226,7 @@ void WorldListPage::on_actionMCEdit_triggered() if(m_mceditStarting) return; - auto mcedit = LAUNCHER->mcedit(); + auto mcedit = APPLICATION->mcedit(); const QString mceditPath = mcedit->path(); diff --git a/launcher/pages/instance/WorldListPage.h b/launcher/pages/instance/WorldListPage.h index b90d7ad1..7636d604 100644 --- a/launcher/pages/instance/WorldListPage.h +++ b/launcher/pages/instance/WorldListPage.h @@ -19,7 +19,7 @@ #include "minecraft/MinecraftInstance.h" #include "pages/BasePage.h" -#include +#include #include class WorldList; @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("worlds"); + return APPLICATION->getThemedIcon("worlds"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/ImportPage.cpp b/launcher/pages/modplatform/ImportPage.cpp index dd02e839..890cc3a0 100644 --- a/launcher/pages/modplatform/ImportPage.cpp +++ b/launcher/pages/modplatform/ImportPage.cpp @@ -1,7 +1,7 @@ #include "ImportPage.h" #include "ui_ImportPage.h" -#include "Launcher.h" +#include "Application.h" #include "dialogs/NewInstanceDialog.h" #include #include diff --git a/launcher/pages/modplatform/ImportPage.h b/launcher/pages/modplatform/ImportPage.h index cc8a0d1f..c39d2a74 100644 --- a/launcher/pages/modplatform/ImportPage.h +++ b/launcher/pages/modplatform/ImportPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" namespace Ui @@ -41,7 +41,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("viewfolder"); + return APPLICATION->getThemedIcon("viewfolder"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/VanillaPage.cpp b/launcher/pages/modplatform/VanillaPage.cpp index 1cf5bbc7..6dbc3970 100644 --- a/launcher/pages/modplatform/VanillaPage.cpp +++ b/launcher/pages/modplatform/VanillaPage.cpp @@ -1,7 +1,7 @@ #include "VanillaPage.h" #include "ui_VanillaPage.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -31,7 +31,7 @@ void VanillaPage::openedImpl() { if(!initialized) { - auto vlist = ENV.metadataIndex()->get("net.minecraft"); + auto vlist = ENV->metadataIndex()->get("net.minecraft"); ui->versionList->initialize(vlist.get()); initialized = true; } diff --git a/launcher/pages/modplatform/VanillaPage.h b/launcher/pages/modplatform/VanillaPage.h index e090d8bb..22acbcac 100644 --- a/launcher/pages/modplatform/VanillaPage.h +++ b/launcher/pages/modplatform/VanillaPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" namespace Ui @@ -41,7 +41,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("minecraft"); + return APPLICATION->getThemedIcon("minecraft"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/pages/modplatform/atlauncher/AtlListModel.cpp index 99d12601..68234f6b 100644 --- a/launcher/pages/modplatform/atlauncher/AtlListModel.cpp +++ b/launcher/pages/modplatform/atlauncher/AtlListModel.cpp @@ -1,7 +1,7 @@ #include "AtlListModel.h" #include -#include +#include #include #include @@ -48,7 +48,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.safeName)); } - auto icon = LAUNCHER->getThemedIcon("atlauncher-placeholder"); + auto icon = APPLICATION->getThemedIcon("atlauncher-placeholder"); auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(pack.safeName.toLower()); ((ListModel *)this)->requestLogo(pack.safeName, url); @@ -134,7 +134,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(ENV->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { @@ -167,7 +167,7 @@ void ListModel::requestLogo(QString file, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0))); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0))); NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); diff --git a/launcher/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/pages/modplatform/atlauncher/AtlPage.cpp index cdf5cc86..5d286182 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.cpp +++ b/launcher/pages/modplatform/atlauncher/AtlPage.cpp @@ -133,7 +133,7 @@ QVector AtlPage::chooseOptionalMods(QVector mod } QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) { - VersionSelectDialog vselect(vlist.get(), "Choose Version", LAUNCHER->activeWindow(), false); + VersionSelectDialog vselect(vlist.get(), "Choose Version", APPLICATION->activeWindow(), false); if (minecraftVersion != Q_NULLPTR) { vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); diff --git a/launcher/pages/modplatform/atlauncher/AtlPage.h b/launcher/pages/modplatform/atlauncher/AtlPage.h index 84c40656..7321021d 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.h +++ b/launcher/pages/modplatform/atlauncher/AtlPage.h @@ -21,7 +21,7 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include "pages/BasePage.h" #include "tasks/Task.h" @@ -45,7 +45,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("atlauncher"); + return APPLICATION->getThemedIcon("atlauncher"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/flame/FlameModel.cpp b/launcher/pages/modplatform/flame/FlameModel.cpp index 6dd29d21..c983eefd 100644 --- a/launcher/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/pages/modplatform/flame/FlameModel.cpp @@ -1,5 +1,5 @@ #include "FlameModel.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -62,7 +62,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.logoName)); } - QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; } @@ -100,7 +100,7 @@ void ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0))); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0))); NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); @@ -128,7 +128,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(ENV->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { diff --git a/launcher/pages/modplatform/flame/FlamePage.cpp b/launcher/pages/modplatform/flame/FlamePage.cpp index 8f798df6..11fc4222 100644 --- a/launcher/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/pages/modplatform/flame/FlamePage.cpp @@ -1,7 +1,7 @@ #include "FlamePage.h" #include "ui_FlamePage.h" -#include "Launcher.h" +#include "Application.h" #include #include "dialogs/NewInstanceDialog.h" #include diff --git a/launcher/pages/modplatform/flame/FlamePage.h b/launcher/pages/modplatform/flame/FlamePage.h index c3d2630a..4e22b3eb 100644 --- a/launcher/pages/modplatform/flame/FlamePage.h +++ b/launcher/pages/modplatform/flame/FlamePage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" #include @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("flame"); + return APPLICATION->getThemedIcon("flame"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/ftb/FtbListModel.cpp b/launcher/pages/modplatform/ftb/FtbListModel.cpp index c4c2c83e..16a744cf 100644 --- a/launcher/pages/modplatform/ftb/FtbListModel.cpp +++ b/launcher/pages/modplatform/ftb/FtbListModel.cpp @@ -2,7 +2,7 @@ #include "BuildConfig.h" #include "Env.h" -#include "Launcher.h" +#include "Application.h" #include "Json.h" #include @@ -46,7 +46,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const } else if(role == Qt::DecorationRole) { - QIcon placeholder = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon placeholder = APPLICATION->getThemedIcon("screenshot-placeholder"); auto iter = m_logoMap.find(pack.name); if (iter != m_logoMap.end()) { @@ -78,7 +78,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(ENV->metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { @@ -252,7 +252,7 @@ void ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); bool stale = entry->isStale(); diff --git a/launcher/pages/modplatform/ftb/FtbPage.h b/launcher/pages/modplatform/ftb/FtbPage.h index 0a4a6cea..b8331f8f 100644 --- a/launcher/pages/modplatform/ftb/FtbPage.h +++ b/launcher/pages/modplatform/ftb/FtbPage.h @@ -20,7 +20,7 @@ #include -#include "Launcher.h" +#include "Application.h" #include "pages/BasePage.h" #include "tasks/Task.h" @@ -44,7 +44,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("ftb_logo"); + return APPLICATION->getThemedIcon("ftb_logo"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/pages/modplatform/legacy_ftb/ListModel.cpp index 78063c5f..dfef278b 100644 --- a/launcher/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/pages/modplatform/legacy_ftb/ListModel.cpp @@ -1,5 +1,5 @@ #include "ListModel.h" -#include "Launcher.h" +#include "Application.h" #include #include @@ -130,7 +130,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.logo)); } - QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logo); return icon; } @@ -216,7 +216,7 @@ void ListModel::requestLogo(QString file) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0))); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0))); NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file)); job->addNetAction(Net::Download::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry)); @@ -244,7 +244,7 @@ void ListModel::getLogo(const QString &logo, LogoCallback callback) { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(ENV->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { diff --git a/launcher/pages/modplatform/legacy_ftb/Page.cpp b/launcher/pages/modplatform/legacy_ftb/Page.cpp index 6b6a7dcd..93002a87 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/pages/modplatform/legacy_ftb/Page.cpp @@ -3,7 +3,7 @@ #include -#include "Launcher.h" +#include "Application.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/NewInstanceDialog.h" #include "modplatform/legacy_ftb/PackFetchTask.h" diff --git a/launcher/pages/modplatform/legacy_ftb/Page.h b/launcher/pages/modplatform/legacy_ftb/Page.h index 6159cd9d..4c6fb35e 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.h +++ b/launcher/pages/modplatform/legacy_ftb/Page.h @@ -20,7 +20,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" #include "modplatform/legacy_ftb/PackHelpers.h" #include "modplatform/legacy_ftb/PackFetchTask.h" @@ -54,7 +54,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("ftb_logo"); + return APPLICATION->getThemedIcon("ftb_logo"); } QString id() const override { diff --git a/launcher/pages/modplatform/technic/TechnicModel.cpp b/launcher/pages/modplatform/technic/TechnicModel.cpp index cac6fef1..a07395ef 100644 --- a/launcher/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/pages/modplatform/technic/TechnicModel.cpp @@ -15,7 +15,7 @@ #include "TechnicModel.h" #include "Env.h" -#include "Launcher.h" +#include "Application.h" #include "Json.h" #include @@ -47,7 +47,7 @@ QVariant Technic::ListModel::data(const QModelIndex& index, int role) const { return (m_logoMap.value(pack.logoName)); } - QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; } @@ -163,7 +163,7 @@ void Technic::ListModel::getLogo(const QString& logo, const QString& logoUrl, Te { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath()); + callback(ENV->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath()); } else { @@ -216,7 +216,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo)); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo)); NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); diff --git a/launcher/pages/modplatform/technic/TechnicPage.cpp b/launcher/pages/modplatform/technic/TechnicPage.cpp index 4f27e685..2befda04 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.cpp +++ b/launcher/pages/modplatform/technic/TechnicPage.cpp @@ -16,7 +16,7 @@ #include "TechnicPage.h" #include "ui_TechnicPage.h" -#include "Launcher.h" +#include "Application.h" #include "dialogs/NewInstanceDialog.h" #include "TechnicModel.h" #include diff --git a/launcher/pages/modplatform/technic/TechnicPage.h b/launcher/pages/modplatform/technic/TechnicPage.h index f0619a52..efd5d726 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.h +++ b/launcher/pages/modplatform/technic/TechnicPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" #include "TechnicData.h" @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("technic"); + return APPLICATION->getThemedIcon("technic"); } virtual QString id() const override { diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp index 40f02f7c..d1b21f5f 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -33,7 +33,7 @@ void ImgurAlbumCreation::start() const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; - QNetworkReply *rep = ENV.network().post(request, data); + QNetworkReply *rep = ENV->network().post(request, data); m_reply.reset(rep); connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress); diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp index ceb14eeb..dfdbf2e8 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -49,7 +49,7 @@ void ImgurUpload::start() namePart.setBody(m_shot->m_file.baseName().toUtf8()); multipart->append(namePart); - QNetworkReply *rep = ENV.network().post(request, multipart); + QNetworkReply *rep = ENV->network().post(request, multipart); m_reply.reset(rep); connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress); diff --git a/launcher/setupwizard/AnalyticsWizardPage.cpp b/launcher/setupwizard/AnalyticsWizardPage.cpp index f1d7b006..3db2f6dc 100644 --- a/launcher/setupwizard/AnalyticsWizardPage.cpp +++ b/launcher/setupwizard/AnalyticsWizardPage.cpp @@ -1,5 +1,5 @@ #include "AnalyticsWizardPage.h" -#include +#include #include #include @@ -33,8 +33,8 @@ AnalyticsWizardPage::~AnalyticsWizardPage() bool AnalyticsWizardPage::validatePage() { - auto settings = LAUNCHER->settings(); - auto analytics = LAUNCHER->analytics(); + auto settings = APPLICATION->settings(); + auto analytics = APPLICATION->analytics(); auto status = checkBox->isChecked(); settings->set("AnalyticsSeen", analytics->version()); settings->set("Analytics", status); diff --git a/launcher/setupwizard/JavaWizardPage.cpp b/launcher/setupwizard/JavaWizardPage.cpp index a60090ce..8251e2ac 100644 --- a/launcher/setupwizard/JavaWizardPage.cpp +++ b/launcher/setupwizard/JavaWizardPage.cpp @@ -1,5 +1,5 @@ #include "JavaWizardPage.h" -#include +#include #include #include @@ -55,7 +55,7 @@ bool JavaWizardPage::wantsRefreshButton() bool JavaWizardPage::validatePage() { - auto settings = LAUNCHER->settings(); + auto settings = APPLICATION->settings(); auto result = m_java_widget->validate(); switch(result) { @@ -71,7 +71,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::JavaBad: { // Memory - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); s->set("MinMemAlloc", m_java_widget->minHeapSize()); s->set("MaxMemAlloc", m_java_widget->maxHeapSize()); if (m_java_widget->permGenEnabled()) diff --git a/launcher/setupwizard/LanguageWizardPage.cpp b/launcher/setupwizard/LanguageWizardPage.cpp index e352ccca..ccdc0c90 100644 --- a/launcher/setupwizard/LanguageWizardPage.cpp +++ b/launcher/setupwizard/LanguageWizardPage.cpp @@ -1,5 +1,5 @@ #include "LanguageWizardPage.h" -#include +#include #include #include "widgets/LanguageSelectionWidget.h" @@ -29,13 +29,13 @@ bool LanguageWizardPage::wantsRefreshButton() void LanguageWizardPage::refresh() { - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); translations->downloadIndex(); } bool LanguageWizardPage::validatePage() { - auto settings = LAUNCHER->settings(); + auto settings = APPLICATION->settings(); QString key = mainWidget->getSelectedLanguageKey(); settings->set("Language", key); return true; diff --git a/launcher/setupwizard/SetupWizard.cpp b/launcher/setupwizard/SetupWizard.cpp index 46b2ef79..5af5ba91 100644 --- a/launcher/setupwizard/SetupWizard.cpp +++ b/launcher/setupwizard/SetupWizard.cpp @@ -5,7 +5,7 @@ #include "AnalyticsWizardPage.h" #include "translations/TranslationsModel.h" -#include +#include #include #include diff --git a/launcher/themes/ITheme.cpp b/launcher/themes/ITheme.cpp index 321b0d9b..7247b444 100644 --- a/launcher/themes/ITheme.cpp +++ b/launcher/themes/ITheme.cpp @@ -2,7 +2,7 @@ #include "rainbow.h" #include #include -#include "Launcher.h" +#include "Application.h" void ITheme::apply(bool) { @@ -13,11 +13,11 @@ void ITheme::apply(bool) } if(hasStyleSheet()) { - LAUNCHER->setStyleSheet(appStyleSheet()); + APPLICATION->setStyleSheet(appStyleSheet()); } else { - LAUNCHER->setStyleSheet(QString()); + APPLICATION->setStyleSheet(QString()); } QDir::setSearchPaths("theme", searchPaths()); } diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 29a952b0..b96f87d7 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -558,7 +558,7 @@ void TranslationsModel::downloadIndex() } qDebug() << "Downloading Translations Index..."; d->m_index_job.reset(new NetJob("Translations Index")); - MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "index_v2.json"); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("translations", "index_v2.json"); entry->setStale(true); d->m_index_task = Net::Download::makeCached(QUrl("https://files.multimc.org/translations/index_v2.json"), entry); d->m_index_job->addNetAction(d->m_index_task); @@ -601,7 +601,7 @@ void TranslationsModel::downloadTranslation(QString key) } d->m_downloadingTranslation = key; - MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + key + ".qm"); + MetaEntryPtr entry = ENV->metacache()->resolveEntry("translations", "mmc_" + key + ".qm"); entry->setStale(true); auto dl = Net::Download::makeCached(QUrl(BuildConfig.TRANSLATIONS_BASE_URL + lang->file_name), entry); diff --git a/launcher/widgets/JavaSettingsWidget.cpp b/launcher/widgets/JavaSettingsWidget.cpp index 11f0653a..cfcba428 100644 --- a/launcher/widgets/JavaSettingsWidget.cpp +++ b/launcher/widgets/JavaSettingsWidget.cpp @@ -1,5 +1,5 @@ #include "JavaSettingsWidget.h" -#include +#include #include #include @@ -22,9 +22,9 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) { m_availableMemory = Sys::getSystemRam() / Sys::mebibyte; - goodIcon = LAUNCHER->getThemedIcon("status-good"); - yellowIcon = LAUNCHER->getThemedIcon("status-yellow"); - badIcon = LAUNCHER->getThemedIcon("status-bad"); + goodIcon = APPLICATION->getThemedIcon("status-good"); + yellowIcon = APPLICATION->getThemedIcon("status-yellow"); + badIcon = APPLICATION->getThemedIcon("status-bad"); setupUi(); connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); @@ -116,9 +116,9 @@ void JavaSettingsWidget::setupUi() void JavaSettingsWidget::initialize() { - m_versionWidget->initialize(LAUNCHER->javalist().get()); + m_versionWidget->initialize(APPLICATION->javalist().get()); m_versionWidget->setResizeOn(2); - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Memory observedMinMemory = s->get("MinMemAlloc").toInt(); observedMaxMemory = s->get("MaxMemAlloc").toInt(); diff --git a/launcher/widgets/LanguageSelectionWidget.cpp b/launcher/widgets/LanguageSelectionWidget.cpp index 2b972ba7..cf70c7b4 100644 --- a/launcher/widgets/LanguageSelectionWidget.cpp +++ b/launcher/widgets/LanguageSelectionWidget.cpp @@ -4,7 +4,7 @@ #include #include #include -#include "Launcher.h" +#include "Application.h" #include "translations/TranslationsModel.h" LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : @@ -29,7 +29,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : helpUsLabel->setWordWrap(true); verticalLayout->addWidget(helpUsLabel); - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); auto index = translations->selectedIndex(); languageView->setModel(translations.get()); languageView->setCurrentIndex(index); @@ -41,7 +41,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : QString LanguageSelectionWidget::getSelectedLanguageKey() const { - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); return translations->data(languageView->currentIndex(), Qt::UserRole).toString(); } @@ -59,7 +59,7 @@ void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, con { return; } - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); QString key = translations->data(current, Qt::UserRole).toString(); translations->selectLanguage(key); translations->updateLanguage(key); diff --git a/launcher/widgets/PageContainer.cpp b/launcher/widgets/PageContainer.cpp index 25e3b676..0bae2b27 100644 --- a/launcher/widgets/PageContainer.cpp +++ b/launcher/widgets/PageContainer.cpp @@ -26,11 +26,11 @@ #include #include -#include "Launcher.h" +#include "Application.h" #include "settings/SettingsObject.h" #include "widgets/IconLabel.h" #include "PageContainer_p.h" -#include +#include #include class PageEntryFilterModel : public QSortFilterProxyModel @@ -139,12 +139,12 @@ void PageContainer::createUI() m_header->setFont(headerLabelFont); QHBoxLayout *headerHLayout = new QHBoxLayout; - const int leftMargin = LAUNCHER->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + const int leftMargin = APPLICATION->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); headerHLayout->addWidget(m_header); headerHLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); headerHLayout->addWidget(m_iconHeader); - const int rightMargin = LAUNCHER->style()->pixelMetric(QStyle::PM_LayoutRightMargin); + const int rightMargin = APPLICATION->style()->pixelMetric(QStyle::PM_LayoutRightMargin); headerHLayout->addSpacerItem(new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); headerHLayout->setContentsMargins(0, 6, 0, 0); @@ -195,7 +195,7 @@ void PageContainer::showPage(int row) { m_pageStack->setCurrentIndex(0); m_header->setText(QString()); - m_iconHeader->setIcon(LAUNCHER->getThemedIcon("bug")); + m_iconHeader->setIcon(APPLICATION->getThemedIcon("bug")); } } -- cgit