summaryrefslogtreecommitdiffstats
path: root/MultiMC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'MultiMC.cpp')
-rw-r--r--MultiMC.cpp258
1 files changed, 150 insertions, 108 deletions
diff --git a/MultiMC.cpp b/MultiMC.cpp
index 80eddcd1..7a82c642 100644
--- a/MultiMC.cpp
+++ b/MultiMC.cpp
@@ -20,12 +20,16 @@
#include "logic/news/NewsChecker.h"
+#include "logic/status/StatusChecker.h"
+
#include "logic/InstanceLauncher.h"
#include "logic/net/HttpMetaCache.h"
+#include "logic/net/URLConstants.h"
#include "logic/JavaUtils.h"
#include "logic/updater/UpdateChecker.h"
+#include "logic/updater/NotificationChecker.h"
#include "pathutils.h"
#include "cmdutils.h"
@@ -34,22 +38,11 @@
#include "logger/QsLog.h"
#include <logger/QsLogDest.h>
-#include "config.h"
-#ifdef WINDOWS
-#define UPDATER_BIN "updater.exe"
-#elif LINUX
-#define UPDATER_BIN "updater"
-#elif OSX
-#define UPDATER_BIN "updater"
-#else
-#error Unsupported operating system.
-#endif
-
using namespace Util::Commandline;
-MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
- : QApplication(argc, argv), m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD,
- VERSION_CHANNEL, VERSION_BUILD_TYPE}
+MultiMC::MultiMC(int &argc, char **argv, bool root_override)
+ : QApplication(argc, argv), m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_HOTFIX,
+ VERSION_BUILD, MultiMCVersion::VERSION_TYPE, VERSION_CHANNEL, BUILD_PLATFORM}
{
setOrganizationName("MultiMC");
setApplicationName("MultiMC5");
@@ -119,20 +112,19 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
QString adjustedBy;
// change directory
QString dirParam = args["dir"].toString();
- if (!data_dir_override.isEmpty())
- {
- // the override is used for tests (although dirparam would be enough...)
- // TODO: remove the need for this extra logic
- adjustedBy += "Test override " + data_dir_override;
- dataPath = data_dir_override;
- }
- else if (!dirParam.isEmpty())
+ 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
+ {
+ dataPath = applicationDirPath();
+ adjustedBy += "Fallback to binary path " + dataPath;
+ }
+
if(!ensureFolderPathExists(dataPath) || !QDir::setCurrent(dataPath))
{
// BAD STUFF. WHAT DO?
@@ -142,13 +134,17 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
return;
}
+ if (root_override)
+ {
+ rootPath = binPath;
+ }
+ else
{
#ifdef Q_OS_LINUX
QDir foo(PathCombine(binPath, ".."));
rootPath = foo.absolutePath();
#elif defined(Q_OS_WIN32)
- QDir foo(PathCombine(binPath, ".."));
- rootPath = foo.absolutePath();
+ rootPath = binPath;
#elif defined(Q_OS_MAC)
QDir foo(PathCombine(binPath, "../.."));
rootPath = foo.absolutePath();
@@ -183,9 +179,15 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
// initialize the updater
m_updateChecker.reset(new UpdateChecker());
+ // initialize the notification checker
+ m_notificationChecker.reset(new NotificationChecker());
+
// initialize the news checker
m_newsChecker.reset(new NewsChecker(NEWS_RSS_URL));
+ // initialize the status checker
+ m_statusChecker.reset(new StatusChecker());
+
// and instances
auto InstDirSetting = m_settings->getSetting("InstanceDir");
m_instances.reset(new InstanceList(InstDirSetting->get().toString(), this));
@@ -203,56 +205,12 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
// init the http meta cache
initHttpMetaCache();
- // set up a basic autodetected proxy (system default)
- QNetworkProxyFactory::setUseSystemConfiguration(true);
-
- QLOG_INFO() << "Detecting system proxy settings...";
- auto proxies = QNetworkProxyFactory::systemProxyForQuery();
- if (proxies.size() == 1 && proxies[0].type() == QNetworkProxy::NoProxy)
- {
- QLOG_INFO() << "No proxy found.";
- }
- else
- for (auto proxy : proxies)
- {
- QString proxyDesc;
- if (proxy.type() == QNetworkProxy::NoProxy)
- {
- QLOG_INFO() << "Using no proxy is an option!";
- continue;
- }
- switch (proxy.type())
- {
- case QNetworkProxy::DefaultProxy:
- proxyDesc = "Default proxy: ";
- break;
- case QNetworkProxy::Socks5Proxy:
- proxyDesc = "Socks5 proxy: ";
- break;
- case QNetworkProxy::HttpProxy:
- proxyDesc = "HTTP proxy: ";
- break;
- case QNetworkProxy::HttpCachingProxy:
- proxyDesc = "HTTP caching: ";
- break;
- case QNetworkProxy::FtpCachingProxy:
- proxyDesc = "FTP caching: ";
- break;
- default:
- proxyDesc = "DERP proxy: ";
- break;
- }
- proxyDesc += QString("%3@%1:%2 pass %4")
- .arg(proxy.hostName())
- .arg(proxy.port())
- .arg(proxy.user())
- .arg(proxy.password());
- QLOG_INFO() << proxyDesc;
- }
-
// create the global network manager
m_qnam.reset(new QNetworkAccessManager(this));
+ // init proxy settings
+ updateProxySettings();
+
// launch instance, if that's what should be done
// WARNING: disabled until further notice
/*
@@ -265,6 +223,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
return;
}
*/
+ connect(this, SIGNAL(aboutToQuit()), SLOT(onExit()));
m_status = MultiMC::Initialized;
}
@@ -338,7 +297,7 @@ void MultiMC::initLogger()
QsLogging::Logger &logger = QsLogging::Logger::instance();
logger.setLoggingLevel(QsLogging::TraceLevel);
m_fileDestination = QsLogging::DestinationFactory::MakeFileDestination(logBase.arg(0));
- m_debugDestination = QsLogging::DestinationFactory::MakeDebugOutputDestination();
+ m_debugDestination = QsLogging::DestinationFactory::MakeQDebugDestination();
logger.addDestination(m_fileDestination.get());
logger.addDestination(m_debugDestination.get());
// log all the things
@@ -349,8 +308,11 @@ void MultiMC::initGlobalSettings()
{
m_settings.reset(new INISettingsObject("multimc.cfg", this));
// Updates
- m_settings->registerSetting("UseDevBuilds", false);
+ m_settings->registerSetting("UpdateChannel", version().channel);
m_settings->registerSetting("AutoUpdate", true);
+
+ // Notifications
+ m_settings->registerSetting("ShownNotifications", QString());
// FTB
m_settings->registerSetting("TrackFTBInstances", false);
@@ -428,6 +390,13 @@ void MultiMC::initGlobalSettings()
m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854);
m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480);
+ // Proxy Settings
+ m_settings->registerSetting("ProxyType", "Default");
+ 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);
@@ -467,10 +436,78 @@ void MultiMC::initHttpMetaCache()
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
m_metacache->addBase("skins", QDir("accounts/skins").absolutePath());
- m_metacache->addBase("root", QDir(".").absolutePath());
+ m_metacache->addBase("root", QDir(root()).absolutePath());
m_metacache->Load();
}
+void MultiMC::updateProxySettings()
+{
+ QString proxyTypeStr = settings()->get("ProxyType").toString();
+
+ // Get the proxy settings from the settings object.
+ 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();
+
+ // Set the application proxy settings.
+ if (proxyTypeStr == "SOCKS5")
+ {
+ QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, pass));
+ }
+ else if (proxyTypeStr == "HTTP")
+ {
+ QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, pass));
+ }
+ else if (proxyTypeStr == "None")
+ {
+ // If we have no proxy set, set no proxy and return.
+ QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
+ }
+ else
+ {
+ // If we have "Default" selected, set Qt to use the system proxy settings.
+ QNetworkProxyFactory::setUseSystemConfiguration(true);
+ }
+
+ QLOG_INFO() << "Detecting proxy settings...";
+ QNetworkProxy proxy = QNetworkProxy::applicationProxy();
+ if (m_qnam.get()) m_qnam->setProxy(proxy);
+ QString proxyDesc;
+ if (proxy.type() == QNetworkProxy::NoProxy)
+ {
+ QLOG_INFO() << "Using no proxy is an option!";
+ return;
+ }
+ switch (proxy.type())
+ {
+ case QNetworkProxy::DefaultProxy:
+ proxyDesc = "Default proxy: ";
+ break;
+ case QNetworkProxy::Socks5Proxy:
+ proxyDesc = "Socks5 proxy: ";
+ break;
+ case QNetworkProxy::HttpProxy:
+ proxyDesc = "HTTP proxy: ";
+ break;
+ case QNetworkProxy::HttpCachingProxy:
+ proxyDesc = "HTTP caching: ";
+ break;
+ case QNetworkProxy::FtpCachingProxy:
+ proxyDesc = "FTP caching: ";
+ break;
+ default:
+ proxyDesc = "DERP proxy: ";
+ break;
+ }
+ proxyDesc += QString("%3@%1:%2 pass %4")
+ .arg(proxy.hostName())
+ .arg(proxy.port())
+ .arg(proxy.user())
+ .arg(proxy.password());
+ QLOG_INFO() << proxyDesc;
+}
+
std::shared_ptr<IconList> MultiMC::icons()
{
if (!m_icons)
@@ -516,46 +553,53 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist()
return m_javalist;
}
-void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish)
+void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags)
{
+ // if we are going to update on exit, save the params now
+ if(flags & OnExit)
+ {
+ m_updateOnExitPath = updateFilesDir;
+ m_updateOnExitFlags = flags & ~OnExit;
+ return;
+ }
+ // otherwise if there already were some params for on exit update, clear them and continue
+ else if(m_updateOnExitPath.size())
+ {
+ m_updateOnExitFlags = None;
+ m_updateOnExitPath.clear();
+ }
QLOG_INFO() << "Installing updates.";
-#if LINUX
- // On Linux, the MultiMC executable file is actually in the bin folder inside the
- // installation directory.
- // This means that MultiMC's *actual* install path is the parent folder.
- // We need to tell the updater to run with this directory as the install path, rather than
- // the bin folder where the executable is.
- // On other operating systems, we'll just use the path to the executable.
- QString appDir = QFileInfo(MMC->applicationDirPath()).dir().path();
-
- // On Linux, we also need to set the finish command to the launch script, rather than the
- // binary.
- QString finishCmd = PathCombine(appDir, "MultiMC");
-#else
- QString appDir = MMC->applicationDirPath();
- QString finishCmd = MMC->applicationFilePath();
-#endif
+ #ifdef WINDOWS
+ QString finishCmd = MMC->applicationFilePath();
+ QString updaterBinary = PathCombine(bin(), "updater.exe");
+ #elif LINUX
+ QString finishCmd = PathCombine(root(), "MultiMC");
+ QString updaterBinary = PathCombine(bin(), "updater");
+ #elif OSX
+ QString finishCmd = MMC->applicationFilePath();
+ QString updaterBinary = PathCombine(bin(), "updater");
+ #else
+ #error Unsupported operating system.
+ #endif
- // Build the command we'll use to run the updater.
- // Note, the above comment about the app dir path on Linux is irrelevant here because the
- // updater binary is always in the
- // same folder as the main binary.
- QString updaterBinary = PathCombine(MMC->applicationDirPath(), UPDATER_BIN);
QStringList args;
// ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script
// $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
- args << "--install-dir" << appDir;
+ args << "--install-dir" << root();
args << "--package-dir" << updateFilesDir;
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
args << "--wait" << QString::number(MMC->applicationPid());
-
- if (restartOnFinish)
+ if(flags & DryRun)
+ args << "--dry-run";
+ if (flags & RestartOnFinish)
+ {
args << "--finish-cmd" << finishCmd;
-
+ args << "--finish-dir" << data();
+ }
QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" ");
QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755);
- if (!QProcess::startDetached(updaterBinary, args))
+ if (!QProcess::startDetached(updaterBinary, args/*, root()*/))
{
QLOG_ERROR() << "Failed to start the updater process!";
return;
@@ -565,14 +609,12 @@ void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish
MMC->quit();
}
-void MultiMC::setUpdateOnExit(const QString &updateFilesDir)
-{
- m_updateOnExitPath = updateFilesDir;
-}
-
-QString MultiMC::getExitUpdatePath() const
+void MultiMC::onExit()
{
- return m_updateOnExitPath;
+ if(m_updateOnExitPath.size())
+ {
+ installUpdates(m_updateOnExitPath, m_updateOnExitFlags);
+ }
}
bool MultiMC::openJsonEditor(const QString &filename)