summaryrefslogtreecommitdiffstats
path: root/MultiMC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'MultiMC.cpp')
-rw-r--r--MultiMC.cpp295
1 files changed, 190 insertions, 105 deletions
diff --git a/MultiMC.cpp b/MultiMC.cpp
index 12c37d2a..4e06f558 100644
--- a/MultiMC.cpp
+++ b/MultiMC.cpp
@@ -8,11 +8,12 @@
#include <QLibraryInfo>
#include <QMessageBox>
#include <QStringList>
+#include <QDesktopServices>
#include "gui/dialogs/VersionSelectDialog.h"
#include "logic/lists/InstanceList.h"
#include "logic/auth/MojangAccountList.h"
-#include "logic/lists/IconList.h"
+#include "logic/icons/IconList.h"
#include "logic/lists/LwjglVersionList.h"
#include "logic/lists/MinecraftVersionList.h"
#include "logic/lists/ForgeVersionList.h"
@@ -34,16 +35,28 @@
#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 &root) : QApplication(argc, argv),
- m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_CHANNEL, VERSION_BUILD_TYPE}
+MultiMC::MultiMC(int &argc, char **argv, const QString &root)
+ : QApplication(argc, argv), m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD,
+ VERSION_CHANNEL, VERSION_BUILD_TYPE}
{
setOrganizationName("MultiMC");
setApplicationName("MultiMC5");
initTranslations();
+ setAttribute(Qt::AA_UseHighDpiPixmaps);
// Don't quit on hiding the last window
this->setQuitOnLastWindowClosed(false);
@@ -137,9 +150,10 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) : QApplication(arg
}
// change directory
- QDir::setCurrent(args["dir"].toString().isEmpty() ?
- (root.isEmpty() ? QDir::currentPath() : QDir::current().absoluteFilePath(root))
- : args["dir"].toString());
+ QDir::setCurrent(
+ args["dir"].toString().isEmpty()
+ ? (root.isEmpty() ? QDir::currentPath() : QDir::current().absoluteFilePath(root))
+ : args["dir"].toString());
// init the logger
initLogger();
@@ -158,7 +172,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) : QApplication(arg
m_instances.reset(new InstanceList(InstDirSetting->get().toString(), this));
QLOG_INFO() << "Loading Instances...";
m_instances->loadList();
- connect(InstDirSetting, SIGNAL(settingChanged(const Setting &, QVariant)),
+ connect(InstDirSetting.get(), SIGNAL(settingChanged(const Setting &, QVariant)),
m_instances.get(), SLOT(on_InstFolderChanged(const Setting &, QVariant)));
// and accounts
@@ -179,42 +193,43 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) : QApplication(arg
{
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())
+ else
+ for (auto proxy : proxies)
{
- 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;
+ 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;
}
- 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));
@@ -285,13 +300,26 @@ void MultiMC::initTranslations()
}
}
+void moveFile(const QString &oldName, const QString &newName)
+{
+ QFile::remove(newName);
+ QFile::copy(oldName, newName);
+ QFile::remove(oldName);
+}
void MultiMC::initLogger()
{
+ static const QString logBase = "MultiMC-%0.log";
+
+ 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));
+
// init the logging mechanism
QsLogging::Logger &logger = QsLogging::Logger::instance();
logger.setLoggingLevel(QsLogging::TraceLevel);
- m_fileDestination = QsLogging::DestinationFactory::MakeFileDestination("MultiMC.log");
- m_debugDestination = QsLogging::DestinationFactory::MakeDebugOutputDestination();
+ m_fileDestination = QsLogging::DestinationFactory::MakeFileDestination(logBase.arg(0));
+ m_debugDestination = QsLogging::DestinationFactory::MakeQDebugDestination();
logger.addDestination(m_fileDestination.get());
logger.addDestination(m_debugDestination.get());
// log all the things
@@ -302,67 +330,110 @@ void MultiMC::initGlobalSettings()
{
m_settings.reset(new INISettingsObject("multimc.cfg", this));
// Updates
- m_settings->registerSetting(new Setting("UseDevBuilds", false));
- m_settings->registerSetting(new Setting("AutoUpdate", true));
+ m_settings->registerSetting("UseDevBuilds", false);
+ m_settings->registerSetting("AutoUpdate", true);
+
+ // FTB
+ m_settings->registerSetting("TrackFTBInstances", false);
+#ifdef Q_OS_LINUX
+ QString ftbDefault = QDir::home().absoluteFilePath(".ftblauncher");
+#elif defined(Q_OS_WIN32)
+ QString ftbDefault = PathCombine(QDir::homePath(), "AppData/Roaming/ftblauncher");
+#elif defined(Q_OS_MAC)
+ QString ftbDefault =
+ PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher");
+#endif
+ m_settings->registerSetting("FTBLauncherRoot", ftbDefault);
+
+ m_settings->registerSetting("FTBRoot");
+ if (m_settings->get("FTBRoot").isNull())
+ {
+ QString ftbRoot;
+ QFile f(QDir(m_settings->get("FTBLauncherRoot").toString())
+ .absoluteFilePath("ftblaunch.cfg"));
+ QLOG_INFO() << "Attempting to read" << f.fileName();
+ if (f.open(QFile::ReadOnly))
+ {
+ const QString data = QString::fromLatin1(f.readAll());
+ QRegularExpression exp("installPath=(.*)");
+ ftbRoot = QDir::cleanPath(exp.match(data).captured(1));
+#ifdef Q_OS_WIN32
+ if (!ftbRoot.isEmpty())
+ {
+ if (ftbRoot.at(0).isLetter() && ftbRoot.size() > 1 && ftbRoot.at(1) == '/')
+ {
+ ftbRoot.remove(1, 1);
+ }
+ }
+#endif
+ if (ftbRoot.isEmpty())
+ {
+ QLOG_INFO() << "Failed to get FTB root path";
+ }
+ else
+ {
+ QLOG_INFO() << "FTB is installed at" << ftbRoot;
+ m_settings->set("FTBRoot", ftbRoot);
+ }
+ }
+ else
+ {
+ QLOG_WARN() << "Couldn't open" << f.fileName() << ":" << f.errorString();
+ QLOG_WARN() << "This is perfectly normal if you don't have FTB installed";
+ }
+ }
// Folders
- m_settings->registerSetting(new Setting("InstanceDir", "instances"));
- m_settings->registerSetting(new Setting("CentralModsDir", "mods"));
- m_settings->registerSetting(new Setting("LWJGLDir", "lwjgl"));
+ m_settings->registerSetting("InstanceDir", "instances");
+ m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods");
+ m_settings->registerSetting({"LWJGLDir", "LwjglDir"}, "lwjgl");
+ m_settings->registerSetting("IconsDir", "icons");
+
+ // Editors
+ m_settings->registerSetting("JsonEditor", QString());
// Console
- m_settings->registerSetting(new Setting("ShowConsole", true));
- m_settings->registerSetting(new Setting("AutoCloseConsole", true));
+ m_settings->registerSetting("ShowConsole", true);
+ m_settings->registerSetting("AutoCloseConsole", true);
// Console Colors
- // m_settings->registerSetting(new Setting("SysMessageColor", QColor(Qt::blue)));
- // m_settings->registerSetting(new Setting("StdOutColor", QColor(Qt::black)));
- // m_settings->registerSetting(new Setting("StdErrColor", QColor(Qt::red)));
+ // m_settings->registerSetting("SysMessageColor", QColor(Qt::blue));
+ // m_settings->registerSetting("StdOutColor", QColor(Qt::black));
+ // m_settings->registerSetting("StdErrColor", QColor(Qt::red));
// Window Size
- m_settings->registerSetting(new Setting("LaunchMaximized", false));
- m_settings->registerSetting(new Setting("MinecraftWinWidth", 854));
- m_settings->registerSetting(new Setting("MinecraftWinHeight", 480));
-
- // Auto login
- m_settings->registerSetting(new Setting("AutoLogin", false));
+ m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false);
+ m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854);
+ m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480);
// Memory
- m_settings->registerSetting(new Setting("MinMemAlloc", 512));
- m_settings->registerSetting(new Setting("MaxMemAlloc", 1024));
- m_settings->registerSetting(new Setting("PermGen", 64));
+ m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512);
+ m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024);
+ m_settings->registerSetting("PermGen", 64);
// Java Settings
- m_settings->registerSetting(new Setting("JavaPath", ""));
- m_settings->registerSetting(new Setting("LastHostname", ""));
- m_settings->registerSetting(new Setting("JvmArgs", ""));
+ m_settings->registerSetting("JavaPath", "");
+ m_settings->registerSetting("LastHostname", "");
+ m_settings->registerSetting("JvmArgs", "");
// Custom Commands
- m_settings->registerSetting(new Setting("PreLaunchCommand", ""));
- m_settings->registerSetting(new Setting("PostExitCommand", ""));
+ m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, "");
+ m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, "");
// The cat
- m_settings->registerSetting(new Setting("TheCat", false));
-
+ m_settings->registerSetting("TheCat", false);
- m_settings->registerSetting(new Setting("InstSortMode", "Name"));
- m_settings->registerSetting(new Setting("SelectedInstance", QString()));
-
- // Persistent value for the client ID
- m_settings->registerSetting(new Setting("YggdrasilClientToken", ""));
- QString currentYggID = m_settings->get("YggdrasilClientToken").toString();
- if (currentYggID.isEmpty())
- {
- QUuid uuid = QUuid::createUuid();
- m_settings->set("YggdrasilClientToken", uuid.toString());
- }
+ m_settings->registerSetting("InstSortMode", "Name");
+ m_settings->registerSetting("SelectedInstance", QString());
// Window state and geometry
- m_settings->registerSetting(new Setting("MainWindowState", ""));
- m_settings->registerSetting(new Setting("MainWindowGeometry", ""));
+ m_settings->registerSetting("MainWindowState", "");
+ m_settings->registerSetting("MainWindowGeometry", "");
+
+ m_settings->registerSetting("ConsoleWindowState", "");
+ m_settings->registerSetting("ConsoleWindowGeometry", "");
- m_settings->registerSetting(new Setting("ConsoleWindowState", ""));
- m_settings->registerSetting(new Setting("ConsoleWindowGeometry", ""));
+ m_settings->registerSetting("SettingsGeometry", "");
}
void MultiMC::initHttpMetaCache()
@@ -374,6 +445,7 @@ 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->Load();
}
@@ -422,27 +494,20 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist()
return m_javalist;
}
-#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
-
-void MultiMC::installUpdates(const QString& updateFilesDir, bool restartOnFinish)
+void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish)
{
QLOG_INFO() << "Installing updates.";
#if LINUX
- // On Linux, the MultiMC executable file is actually in the bin folder inside the installation directory.
+ // 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.
+ // 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.
+ // 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();
@@ -450,28 +515,35 @@ void MultiMC::installUpdates(const QString& updateFilesDir, bool restartOnFinish
#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
+ // 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
+ // ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script
+ // $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
args << "--install-dir" << appDir;
args << "--package-dir" << updateFilesDir;
- args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
- args << "--wait" << QString::number(MMC->applicationPid());
+ args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
+ args << "--wait" << QString::number(MMC->applicationPid());
if (restartOnFinish)
- args << "--finish-cmd" << finishCmd;
+ args << "--finish-cmd" << finishCmd;
QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" ");
+ QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755);
- QProcess::startDetached(updaterBinary, args);
+ if (!QProcess::startDetached(updaterBinary, args))
+ {
+ QLOG_ERROR() << "Failed to start the updater process!";
+ return;
+ }
// Now that we've started the updater, quit MultiMC.
MMC->quit();
}
-void MultiMC::setUpdateOnExit(const QString& updateFilesDir)
+void MultiMC::setUpdateOnExit(const QString &updateFilesDir)
{
m_updateOnExitPath = updateFilesDir;
}
@@ -481,5 +553,18 @@ QString MultiMC::getExitUpdatePath() const
return m_updateOnExitPath;
}
+bool MultiMC::openJsonEditor(const QString &filename)
+{
+ const QString file = QDir::current().absoluteFilePath(filename);
+ if (m_settings->get("JsonEditor").toString().isEmpty())
+ {
+ return QDesktopServices::openUrl(QUrl::fromLocalFile(file));
+ }
+ else
+ {
+ return QProcess::startDetached(m_settings->get("JsonEditor").toString(), QStringList()
+ << file);
+ }
+}
#include "MultiMC.moc"