diff options
Diffstat (limited to 'application/MultiMC.cpp')
-rw-r--r-- | application/MultiMC.cpp | 214 |
1 files changed, 188 insertions, 26 deletions
diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp index 3a9c281e..2dd4f83f 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -2,15 +2,19 @@ #include "BuildConfig.h" #include "MainWindow.h" #include "InstanceWindow.h" + +#include "groupview/AccessibleGroupView.h" +#include <QAccessible> + #include "pages/BasePageProvider.h" #include "pages/global/MultiMCPage.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/PackagesPage.h" #include "pages/global/CustomCommandsPage.h" #include "themes/ITheme.h" @@ -30,6 +34,7 @@ #include <QNetworkAccessManager> #include <QTranslator> #include <QLibraryInfo> +#include <QList> #include <QStringList> #include <QDebug> #include <QStyleFactory> @@ -40,7 +45,6 @@ #include <minecraft/auth/MojangAccountList.h> #include "icons/IconList.h" #include "net/HttpMetaCache.h" -#include "net/URLConstants.h" #include "Env.h" #include "java/JavaUtils.h" @@ -65,6 +69,8 @@ #include <ganalytics.h> #include <sys.h> +#include "pagedialog/PageDialog.h" + #if defined Q_OS_WIN32 #ifndef WIN32_LEAN_AND_MEAN @@ -139,6 +145,27 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) 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 MultiMC binary when playing on Windows." + ); + return; + } + } + } +#endif + // Don't quit on hiding the last window this->setQuitOnLastWindowClosed(false); @@ -150,23 +177,32 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) // --help parser.addSwitch("help"); parser.addShortOpt("help", 'h'); - parser.addDocumentation("help", "display this help and exit."); + parser.addDocumentation("help", "Display this help and exit."); // --version parser.addSwitch("version"); parser.addShortOpt("version", 'V'); - parser.addDocumentation("version", "display program version and exit."); + 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 " + 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)"); + 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)"); // --alive parser.addSwitch("alive"); - parser.addDocumentation("alive", "write a small '" + liveCheckFile + "' file after MultiMC starts"); + parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after MultiMC 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 @@ -176,8 +212,9 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) 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; + if(argc > 0) + std::cerr << "Try '" << argv[0] << " -h' to get help on MultiMC's command line parameters." + << std::endl; m_status = MultiMC::Failed; return; } @@ -200,7 +237,9 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) } } m_instanceIdToLaunch = args["launch"].toString(); + m_serverToJoin = args["server"].toString(); m_liveCheck = args["alive"].toBool(); + m_zipToImport = args["import"].toUrl(); QString origcwdPath = QDir::currentPath(); QString binPath = applicationDirPath(); @@ -260,6 +299,13 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) return; } + if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty()) + { + std::cerr << "--server can only be used in combination with --launch!" << std::endl; + m_status = MultiMC::Failed; + 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. @@ -272,13 +318,28 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) connect(m_peerInstance, &LocalPeer::messageReceived, this, &MultiMC::messageReceived); if(m_peerInstance->isClient()) { + int timeout = 2000; + if(m_instanceIdToLaunch.isEmpty()) { - m_peerInstance->sendMessage("activate", 2000); + m_peerInstance->sendMessage("activate", timeout); + + if(!m_zipToImport.isEmpty()) + { + m_peerInstance->sendMessage("import " + m_zipToImport.toString(), timeout); + } } else { - m_peerInstance->sendMessage(m_instanceIdToLaunch, 2000); + if(!m_serverToJoin.isEmpty()) + { + m_peerInstance->sendMessage( + "launch-with-server " + m_instanceIdToLaunch + " " + m_serverToJoin, timeout); + } + else + { + m_peerInstance->sendMessage("launch " + m_instanceIdToLaunch, timeout); + } } m_status = MultiMC::Succeeded; return; @@ -339,7 +400,7 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); #endif - qDebug() << "MultiMC 5, (c) 2013-2018 MultiMC Contributors"; + qDebug() << "MultiMC 5, (c) 2013-2021 MultiMC Contributors"; qDebug() << "Version : " << BuildConfig.printableVersionString(); qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; @@ -359,6 +420,10 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) { qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; } + if(!m_serverToJoin.isEmpty()) + { + qDebug() << "Address of server to join :" << m_serverToJoin; + } qDebug() << "<> Paths set."; } @@ -375,7 +440,7 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) auto payload = appID.toString().toUtf8(); if(check.write(payload) != payload.size()) { - qWarning() << "Could not write into" << liveCheckFile; + qWarning() << "Could not write into" << liveCheckFile << "!"; check.remove(); break; } @@ -466,9 +531,18 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) 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("RecordGameTime", true); + // Minecraft launch method m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); @@ -517,9 +591,9 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) m_globalSettingsProvider->addPage<MultiMCPage>(); m_globalSettingsProvider->addPage<MinecraftPage>(); m_globalSettingsProvider->addPage<JavaPage>(); + m_globalSettingsProvider->addPage<LanguagePage>(); m_globalSettingsProvider->addPage<CustomCommandsPage>(); m_globalSettingsProvider->addPage<ProxyPage>(); - // m_globalSettingsProvider->addPage<PackagesPage>(); m_globalSettingsProvider->addPage<ExternalToolsPage>(); m_globalSettingsProvider->addPage<AccountListPage>(); m_globalSettingsProvider->addPage<PasteEEPage>(); @@ -527,6 +601,10 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) qDebug() << "<> Settings loaded."; } +#ifndef QT_NO_ACCESSIBILITY + QAccessible::installFactory(groupViewAccessibleFactory); +#endif /* !QT_NO_ACCESSIBILITY */ + // load translations { m_translations.reset(new TranslationsModel("translations")); @@ -550,7 +628,8 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) { ":/icons/multimc/32x32/instances/", ":/icons/multimc/50x50/instances/", - ":/icons/multimc/128x128/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) @@ -589,12 +668,12 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) { 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) + // 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"; + 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); @@ -790,8 +869,19 @@ void MultiMC::performMainStartupAction() auto inst = instances()->getInstanceById(m_instanceIdToLaunch); if(inst) { - qDebug() << "<> Instance launching:" << m_instanceIdToLaunch; - launch(inst, true, nullptr); + MinecraftServerTargetPtr serverToJoin = nullptr; + + if(!m_serverToJoin.isEmpty()) + { + serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); + qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching with server" << m_serverToJoin; + } + else + { + qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; + } + + launch(inst, true, nullptr, serverToJoin); return; } } @@ -801,6 +891,11 @@ void MultiMC::performMainStartupAction() showMainWindow(false); qDebug() << "<> Main window shown."; } + if(!m_zipToImport.isEmpty()) + { + qDebug() << "<> Importing instance from zip:" << m_zipToImport; + m_mainWindow->droppedURLs({ m_zipToImport }); + } } void MultiMC::showFatalErrorMessage(const QString& title, const QString& content) @@ -837,18 +932,66 @@ void MultiMC::messageReceived(const QString& message) qDebug() << "Received message" << message << "while still initializing. It will be ignored."; return; } - if(message == "activate") + + QString command = message.section(' ', 0, 0); + + if(command == "activate") { showMainWindow(); } - else + else if(command == "import") + { + QString arg = message.section(' ', 1); + if(arg.isEmpty()) + { + qWarning() << "Received" << command << "message without a zip path/URL."; + return; + } + m_mainWindow->droppedURLs({ QUrl(arg) }); + } + else if(command == "launch") { - auto inst = instances()->getInstanceById(message); + QString arg = message.section(' ', 1); + if(arg.isEmpty()) + { + qWarning() << "Received" << command << "message without an instance ID."; + return; + } + auto inst = instances()->getInstanceById(arg); if(inst) { launch(inst, true, nullptr); } } + else if(command == "launch-with-server") + { + QString instanceID = message.section(' ', 1, 1); + QString serverToJoin = message.section(' ', 2, 2); + if(instanceID.isEmpty()) + { + qWarning() << "Received" << command << "message without an instance ID."; + return; + } + if(serverToJoin.isEmpty()) + { + qWarning() << "Received" << command << "message without a server to join."; + return; + } + auto inst = instances()->getInstanceById(instanceID); + if(inst) + { + launch( + inst, + true, + nullptr, + std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(serverToJoin)) + ); + } + } + else + { + qWarning() << "Received invalid message" << message; + } } void MultiMC::analyticsSettingChanged(const Setting&, QVariant value) @@ -932,11 +1075,15 @@ bool MultiMC::openJsonEditor(const QString &filename) } } -bool MultiMC::launch(InstancePtr instance, bool online, BaseProfilerFactory *profiler) -{ +bool MultiMC::launch( + InstancePtr instance, + bool online, + BaseProfilerFactory *profiler, + MinecraftServerTargetPtr serverToJoin +) { if(m_updateRunning) { - qDebug() << "Cannot launch instances while an update is running."; + qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; } else if(instance->canLaunch()) { @@ -954,6 +1101,7 @@ bool MultiMC::launch(InstancePtr instance, bool online, BaseProfilerFactory *pro controller->setInstance(instance); controller->setOnline(online); controller->setProfiler(profiler); + controller->setServerToJoin(serverToJoin); if(window) { controller->setParentWidget(window); @@ -985,7 +1133,7 @@ bool MultiMC::kill(InstancePtr instance) { if (!instance->isRunning()) { - qWarning() << "Attempted to kill instance" << instance->id() << "which isn't running."; + qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; return false; } auto & extras = m_instanceExtras[instance->id()]; @@ -1085,6 +1233,20 @@ void MultiMC::controllerFailed(const QString& error) } } +void MultiMC::ShowGlobalSettings(class QWidget* parent, QString open_page) +{ + if(!m_globalSettingsProvider) { + return; + } + emit globalSettingsAboutToOpen(); + { + SettingsObject::Lock lock(MMC->settings()); + PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); + dlg.exec(); + } + emit globalSettingsClosed(); +} + MainWindow* MultiMC::showMainWindow(bool minimized) { if(m_mainWindow) |