diff options
author | Petr Mrázek <peterix@gmail.com> | 2018-07-15 14:51:05 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2018-07-15 14:51:05 +0200 |
commit | bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9 (patch) | |
tree | e6497e304b7b9368367565fbc7c06efab1124b1c /application/MultiMC.cpp | |
parent | 03280cc62e75f8073f8d3d9e9e3952acf21fa77d (diff) | |
download | MultiMC-bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9.tar MultiMC-bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9.tar.gz MultiMC-bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9.tar.lz MultiMC-bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9.tar.xz MultiMC-bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9.zip |
NOISSUE tabs -> spaces
Diffstat (limited to 'application/MultiMC.cpp')
-rw-r--r-- | application/MultiMC.cpp | 2008 |
1 files changed, 1004 insertions, 1004 deletions
diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp index e7e6d337..c1996863 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -83,1146 +83,1146 @@ static const QLatin1String liveCheckFile("live.check"); using namespace Commandline; #define MACOS_HINT "If you are on macOS Sierra, you might have to move MultiMC.app to your /Applications or ~/Applications folder. "\ - "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ - "\n" + "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ + "\n" static void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - const char *levels = "DWCFIS"; - const QString format("%1 %2 %3\n"); - - qint64 msecstotal = MMC->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); - - MMC->logFile->write(out.toUtf8()); - MMC->logFile->flush(); - QTextStream(stderr) << out.toLocal8Bit(); - fflush(stderr); + const char *levels = "DWCFIS"; + const QString format("%1 %2 %3\n"); + + qint64 msecstotal = MMC->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); + + MMC->logFile->write(out.toUtf8()); + MMC->logFile->flush(); + QTextStream(stderr) << out.toLocal8Bit(); + fflush(stderr); } MultiMC::MultiMC(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; - } + // 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("MultiMC"); - setOrganizationDomain("multimc.org"); - setApplicationName("MultiMC5"); - setApplicationDisplayName("MultiMC 5"); - setApplicationVersion(BuildConfig.printableVersionString()); - - startTime = QDateTime::currentDateTime(); - - // Don't quit on hiding the last window - this->setQuitOnLastWindowClosed(false); - - // Commandline parsing - QHash<QString, QVariant> 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 MultiMC 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)"); - // --alive - parser.addSwitch("alive"); - parser.addDocumentation("alive", "write a small '" + liveCheckFile + "' file after MultiMC starts"); - - // parse the arguments - try - { - args = parser.parse(arguments()); - } - catch (const ParsingError &e) - { - std::cerr << "CommandLineError: " << e.what() << std::endl; - std::cerr << "Try '%1 -h' to get help on MultiMC's command line parameters." - << std::endl; - m_status = MultiMC::Failed; - return; - } - - // display help and exit - if (args["help"].toBool()) - { - std::cout << qPrintable(parser.compileHelp(arguments()[0])); - m_status = MultiMC::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 = MultiMC::Succeeded; - return; - } - } - m_instanceIdToLaunch = args["launch"].toString(); - m_liveCheck = args["alive"].toBool(); - - 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 - { + setOrganizationName("MultiMC"); + setOrganizationDomain("multimc.org"); + setApplicationName("MultiMC5"); + setApplicationDisplayName("MultiMC 5"); + setApplicationVersion(BuildConfig.printableVersionString()); + + startTime = QDateTime::currentDateTime(); + + // Don't quit on hiding the last window + this->setQuitOnLastWindowClosed(false); + + // Commandline parsing + QHash<QString, QVariant> 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 MultiMC 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)"); + // --alive + parser.addSwitch("alive"); + parser.addDocumentation("alive", "write a small '" + liveCheckFile + "' file after MultiMC starts"); + + // parse the arguments + try + { + args = parser.parse(arguments()); + } + catch (const ParsingError &e) + { + std::cerr << "CommandLineError: " << e.what() << std::endl; + std::cerr << "Try '%1 -h' to get help on MultiMC's command line parameters." + << std::endl; + m_status = MultiMC::Failed; + return; + } + + // display help and exit + if (args["help"].toBool()) + { + std::cout << qPrintable(parser.compileHelp(arguments()[0])); + m_status = MultiMC::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 = MultiMC::Succeeded; + return; + } + } + m_instanceIdToLaunch = args["launch"].toString(); + m_liveCheck = args["alive"].toBool(); + + 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 + { #ifdef MULTIMC_LINUX_DATADIR - QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME")); - if (xdgDataHome.isEmpty()) - xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); - dataPath = xdgDataHome + "/multimc"; - adjustedBy += "XDG standard " + dataPath; + QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME")); + if (xdgDataHome.isEmpty()) + xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); + dataPath = xdgDataHome + "/multimc"; + adjustedBy += "XDG standard " + dataPath; #else - dataPath = applicationDirPath(); - adjustedBy += "Fallback to binary path " + dataPath; + dataPath = applicationDirPath(); + adjustedBy += "Fallback to binary path " + dataPath; #endif - } - - if (!FS::ensureFolderPathExists(dataPath)) - { - showFatalErrorMessage( - "MultiMC data folder could not be created.", - "MultiMC data folder could not be created.\n" - "\n" + } + + if (!FS::ensureFolderPathExists(dataPath)) + { + showFatalErrorMessage( + "MultiMC data folder could not be created.", + "MultiMC data folder could not be created.\n" + "\n" #if defined(Q_OS_MAC) - MACOS_HINT + MACOS_HINT #endif - "Make sure you have the right permissions to the MultiMC data folder and any folder needed to access it.\n" - "\n" - "MultiMC cannot continue until you fix this problem." - ); - return; - } - if (!QDir::setCurrent(dataPath)) - { - showFatalErrorMessage( - "MultiMC data folder could not be opened.", - "MultiMC data folder could not be opened.\n" - "\n" + "Make sure you have the right permissions to the MultiMC data folder and any folder needed to access it.\n" + "\n" + "MultiMC cannot continue until you fix this problem." + ); + return; + } + if (!QDir::setCurrent(dataPath)) + { + showFatalErrorMessage( + "MultiMC data folder could not be opened.", + "MultiMC data folder could not be opened.\n" + "\n" #if defined(Q_OS_MAC) - MACOS_HINT + MACOS_HINT #endif - "Make sure you have the right permissions to the MultiMC data folder.\n" - "\n" - "MultiMC cannot continue until you fix this problem." - ); - return; - } - - /* - * 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, &MultiMC::messageReceived); - if(m_peerInstance->isClient()) - { - if(m_instanceIdToLaunch.isEmpty()) - { - m_peerInstance->sendMessage("activate", 2000); - } - else - { - m_peerInstance->sendMessage(m_instanceIdToLaunch, 2000); - } - m_status = MultiMC::Succeeded; - return; - } - } - - // init the logger - { - static const QString logBase = "MultiMC-%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<QFile>(new QFile(logBase.arg(0))); - if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) - { - showFatalErrorMessage( - "MultiMC data folder is not writable!", - "MultiMC couldn't create a log file - the MultiMC data folder is not writable.\n" - "\n" - #if defined(Q_OS_MAC) - MACOS_HINT - #endif - "Make sure you have write permissions to the MultiMC data folder.\n" - "\n" - "MultiMC cannot continue until you fix this problem." - ); - return; - } - qInstallMessageHandler(appDebugOutput); - qDebug() << "<> Log initialized."; - } - - // Set up paths - { - // Root path is used for updates. + "Make sure you have the right permissions to the MultiMC data folder.\n" + "\n" + "MultiMC cannot continue until you fix this problem." + ); + return; + } + + /* + * 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, &MultiMC::messageReceived); + if(m_peerInstance->isClient()) + { + if(m_instanceIdToLaunch.isEmpty()) + { + m_peerInstance->sendMessage("activate", 2000); + } + else + { + m_peerInstance->sendMessage(m_instanceIdToLaunch, 2000); + } + m_status = MultiMC::Succeeded; + return; + } + } + + // init the logger + { + static const QString logBase = "MultiMC-%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<QFile>(new QFile(logBase.arg(0))); + if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) + { + showFatalErrorMessage( + "MultiMC data folder is not writable!", + "MultiMC couldn't create a log file - the MultiMC data folder is not writable.\n" + "\n" + #if defined(Q_OS_MAC) + MACOS_HINT + #endif + "Make sure you have write permissions to the MultiMC data folder.\n" + "\n" + "MultiMC 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(); + QDir foo(FS::PathCombine(binPath, "..")); + m_rootPath = foo.absolutePath(); #elif defined(Q_OS_WIN32) - m_rootPath = binPath; + 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); + 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) ); + ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); #endif - qDebug() << "MultiMC 5, (c) 2013-2018 MultiMC Contributors"; - 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; - } - 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("multimc.cfg", 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; + qDebug() << "MultiMC 5, (c) 2013-2018 MultiMC Contributors"; + 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; + } + 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("multimc.cfg", 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; + defaultMonospace = "Courier"; + defaultSize = 10; #elif defined(Q_OS_MAC) - defaultMonospace = "Menlo"; + defaultMonospace = "Menlo"; #else - defaultMonospace = "Monospace"; + 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("LastHostname", ""); - m_settings->registerSetting("JvmArgs", ""); - - // 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<GenericPageProvider>(tr("Settings")); - m_globalSettingsProvider->addPage<MultiMCPage>(); - m_globalSettingsProvider->addPage<MinecraftPage>(); - m_globalSettingsProvider->addPage<JavaPage>(); - m_globalSettingsProvider->addPage<CustomCommandsPage>(); - m_globalSettingsProvider->addPage<ProxyPage>(); - // m_globalSettingsProvider->addPage<PackagesPage>(); - m_globalSettingsProvider->addPage<ExternalToolsPage>(); - m_globalSettingsProvider->addPage<AccountListPage>(); - m_globalSettingsProvider->addPage<PasteEEPage>(); - } - qDebug() << "<> Settings loaded."; - } - - // 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) - { - m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); - qDebug() << "<> Updater started."; - } - - // Instance icons - { - auto setting = MMC->settings()->getSetting("IconsDir"); - QStringList instFolders = - { - ":/icons/multimc/32x32/instances/", - ":/icons/multimc/50x50/instances/", - ":/icons/multimc/128x128/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<ITheme>(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 rememer 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(this)); - m_instanceFolder = new FolderInstanceProvider(m_settings, instDir); - connect(InstDirSetting.get(), &Setting::SettingChanged, m_instanceFolder, &FolderInstanceProvider::on_InstFolderChanged); - m_instances->addInstanceProvider(m_instanceFolder); - qDebug() << "Loading Instances..."; - m_instances->loadList(true); - qDebug() << "<> Instances loaded."; - } - - // and accounts - { - m_accounts.reset(new MojangAccountList(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<qint16>(); - 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<BaseProfilerFactory>(new JProfilerFactory())); - m_profilers.insert("jvisualvm", std::shared_ptr<BaseProfilerFactory>(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, &MultiMC::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, &MultiMC::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.qnam()); - - 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(); + // 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("LastHostname", ""); + m_settings->registerSetting("JvmArgs", ""); + + // 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<GenericPageProvider>(tr("Settings")); + m_globalSettingsProvider->addPage<MultiMCPage>(); + m_globalSettingsProvider->addPage<MinecraftPage>(); + m_globalSettingsProvider->addPage<JavaPage>(); + m_globalSettingsProvider->addPage<CustomCommandsPage>(); + m_globalSettingsProvider->addPage<ProxyPage>(); + // m_globalSettingsProvider->addPage<PackagesPage>(); + m_globalSettingsProvider->addPage<ExternalToolsPage>(); + m_globalSettingsProvider->addPage<AccountListPage>(); + m_globalSettingsProvider->addPage<PasteEEPage>(); + } + qDebug() << "<> Settings loaded."; + } + + // 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) + { + m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); + qDebug() << "<> Updater started."; + } + + // Instance icons + { + auto setting = MMC->settings()->getSetting("IconsDir"); + QStringList instFolders = + { + ":/icons/multimc/32x32/instances/", + ":/icons/multimc/50x50/instances/", + ":/icons/multimc/128x128/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<ITheme>(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 rememer 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(this)); + m_instanceFolder = new FolderInstanceProvider(m_settings, instDir); + connect(InstDirSetting.get(), &Setting::SettingChanged, m_instanceFolder, &FolderInstanceProvider::on_InstFolderChanged); + m_instances->addInstanceProvider(m_instanceFolder); + qDebug() << "Loading Instances..."; + m_instances->loadList(true); + qDebug() << "<> Instances loaded."; + } + + // and accounts + { + m_accounts.reset(new MojangAccountList(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<qint16>(); + 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<BaseProfilerFactory>(new JProfilerFactory())); + m_profilers.insert("jvisualvm", std::shared_ptr<BaseProfilerFactory>(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, &MultiMC::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, &MultiMC::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.qnam()); + + 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 MultiMC::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, &MultiMC::setupWizardFinished); - m_setupWizard->show(); - return true; - } - return false; + 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, &MultiMC::setupWizardFinished); + m_setupWizard->show(); + return true; + } + return false; } void MultiMC::setupWizardFinished(int status) { - qDebug() << "Wizard result =" << status; - performMainStartupAction(); + qDebug() << "Wizard result =" << status; + performMainStartupAction(); } void MultiMC::performMainStartupAction() { - m_status = MultiMC::Initialized; - if(!m_instanceIdToLaunch.isEmpty()) - { - auto inst = instances()->getInstanceById(m_instanceIdToLaunch); - if(inst) - { - qDebug() << "<> Instance launching:" << m_instanceIdToLaunch; - launch(inst, true, nullptr); - return; - } - } - if(!m_mainWindow) - { - // normal main window - showMainWindow(false); - qDebug() << "<> Main window shown."; - } + m_status = MultiMC::Initialized; + if(!m_instanceIdToLaunch.isEmpty()) + { + auto inst = instances()->getInstanceById(m_instanceIdToLaunch); + if(inst) + { + qDebug() << "<> Instance launching:" << m_instanceIdToLaunch; + launch(inst, true, nullptr); + return; + } + } + if(!m_mainWindow) + { + // normal main window + showMainWindow(false); + qDebug() << "<> Main window shown."; + } } void MultiMC::showFatalErrorMessage(const QString& title, const QString& content) { - m_status = MultiMC::Failed; - auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); - dialog->exec(); + m_status = MultiMC::Failed; + auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); + dialog->exec(); } MultiMC::~MultiMC() { - // kill the other globals. - Env::dispose(); + // kill the other globals. + Env::dispose(); - // Shut down logger by setting the logger function to nothing - qInstallMessageHandler(nullptr); + // 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(); - } + // Detach from Windows console + if(consoleAttached) + { + fclose(stdout); + fclose(stdin); + fclose(stderr); + FreeConsole(); + } #endif } void MultiMC::messageReceived(const QString& message) { - if(status() != Initialized) - { - qDebug() << "Received message" << message << "while still initializing. It will be ignored."; - return; - } - if(message == "activate") - { - showMainWindow(); - } - else - { - auto inst = instances()->getInstanceById(message); - if(inst) - { - launch(inst, true, nullptr); - } - } + if(status() != Initialized) + { + qDebug() << "Received message" << message << "while still initializing. It will be ignored."; + return; + } + if(message == "activate") + { + showMainWindow(); + } + else + { + auto inst = instances()->getInstanceById(message); + if(inst) + { + launch(inst, true, nullptr); + } + } } void MultiMC::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); + 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<TranslationsModel> MultiMC::translations() { - return m_translations; + return m_translations; } std::shared_ptr<JavaInstallList> MultiMC::javalist() { - if (!m_javalist) - { - m_javalist.reset(new JavaInstallList()); - } - return m_javalist; + if (!m_javalist) + { + m_javalist.reset(new JavaInstallList()); + } + return m_javalist; } std::vector<ITheme *> MultiMC::getValidApplicationThemes() { - std::vector<ITheme *> ret; - auto iter = m_themes.cbegin(); - while (iter != m_themes.cend()) - { - ret.push_back((*iter).second.get()); - iter++; - } - return ret; + std::vector<ITheme *> ret; + auto iter = m_themes.cbegin(); + while (iter != m_themes.cend()) + { + ret.push_back((*iter).second.get()); + iter++; + } + return ret; } void MultiMC::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; - } + 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 MultiMC::setIconTheme(const QString& name) { - XdgIcon::setThemeName(name); + XdgIcon::setThemeName(name); } QIcon MultiMC::getThemedIcon(const QString& name) { - return XdgIcon::fromTheme(name); + return XdgIcon::fromTheme(name); } bool MultiMC::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}); - } + 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 MultiMC::launch(InstancePtr instance, bool online, BaseProfilerFactory *profiler) { - if(m_updateRunning) - { - qDebug() << "Cannot launch instances while an update is running."; - } - 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); - if(window) - { - controller->setParentWidget(window); - } - else if(m_mainWindow) - { - controller->setParentWidget(m_mainWindow); - } - connect(controller.get(), &LaunchController::succeeded, this, &MultiMC::controllerSucceeded); - connect(controller.get(), &LaunchController::failed, this, &MultiMC::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; + if(m_updateRunning) + { + qDebug() << "Cannot launch instances while an update is running."; + } + 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); + if(window) + { + controller->setParentWidget(window); + } + else if(m_mainWindow) + { + controller->setParentWidget(m_mainWindow); + } + connect(controller.get(), &LaunchController::succeeded, this, &MultiMC::controllerSucceeded); + connect(controller.get(), &LaunchController::failed, this, &MultiMC::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 MultiMC::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; + 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 MultiMC::addRunningInstance() { - m_runningInstances ++; - if(m_runningInstances == 1) - { - emit updateAllowedChanged(false); - } + m_runningInstances ++; + if(m_runningInstances == 1) + { + emit updateAllowedChanged(false); + } } void MultiMC::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); - } + 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 MultiMC::shouldExitNow() const { - return m_runningInstances == 0 && m_openWindows == 0; + return m_runningInstances == 0 && m_openWindows == 0; } bool MultiMC::updatesAreAllowed() { - return m_runningInstances == 0; + return m_runningInstances == 0; } void MultiMC::updateIsRunning(bool running) { - m_updateRunning = running; + m_updateRunning = running; } void MultiMC::controllerSucceeded() { - auto controller = qobject_cast<LaunchController *>(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); - } + auto controller = qobject_cast<LaunchController *>(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 MultiMC::controllerFailed(const QString& error) { - Q_UNUSED(error); - auto controller = qobject_cast<LaunchController *>(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); - } + Q_UNUSED(error); + auto controller = qobject_cast<LaunchController *>(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); + } } MainWindow* MultiMC::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(MMC->settings()->get("MainWindowState").toByteArray())); - m_mainWindow->restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("MainWindowGeometry").toByteArray())); - if(minimized) - { - m_mainWindow->showMinimized(); - } - else - { - m_mainWindow->show(); - } - - m_mainWindow->checkInstancePathForProblems(); - connect(this, &MultiMC::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); - connect(m_mainWindow, &MainWindow::isClosing, this, &MultiMC::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; + 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(MMC->settings()->get("MainWindowState").toByteArray())); + m_mainWindow->restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("MainWindowGeometry").toByteArray())); + if(minimized) + { + m_mainWindow->showMinimized(); + } + else + { + m_mainWindow->show(); + } + + m_mainWindow->checkInstancePathForProblems(); + connect(this, &MultiMC::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); + connect(m_mainWindow, &MainWindow::isClosing, this, &MultiMC::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 *MultiMC::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, &MultiMC::on_windowClose); - } - if(!page.isEmpty()) - { - window->selectPage(page); - } - if(extras.controller) - { - extras.controller->setParentWidget(window); - } - return window; + 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, &MultiMC::on_windowClose); + } + if(!page.isEmpty()) + { + window->selectPage(page); + } + if(extras.controller) + { + extras.controller->setParentWidget(window); + } + return window; } void MultiMC::on_windowClose() { - m_openWindows--; - auto instWindow = qobject_cast<InstanceWindow *>(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<MainWindow *>(QObject::sender()); - if(mainWindow) - { - m_mainWindow = nullptr; - } - // quit when there are no more windows. - if(shouldExitNow()) - { - exit(0); - } + m_openWindows--; + auto instWindow = qobject_cast<InstanceWindow *>(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<MainWindow *>(QObject::sender()); + if(mainWindow) + { + m_mainWindow = nullptr; + } + // quit when there are no more windows. + if(shouldExitNow()) + { + exit(0); + } } |