Merge branch 'develop' of github.com:MultiMC/MultiMC5 into feature_news
Conflicts: CMakeLists.txt gui/MainWindow.h
This commit is contained in:
commit
17f1864a71
153 changed files with 4702 additions and 2180 deletions
323
MultiMC.cpp
323
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)
|
||||
else
|
||||
for (auto proxy : proxies)
|
||||
{
|
||||
QLOG_INFO() << "Using no proxy is an option!";
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
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));
|
||||
|
@ -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);
|
||||
|
||||
// Folders
|
||||
m_settings->registerSetting(new Setting("InstanceDir", "instances"));
|
||||
m_settings->registerSetting(new Setting("CentralModsDir", "mods"));
|
||||
m_settings->registerSetting(new Setting("LWJGLDir", "lwjgl"));
|
||||
// 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);
|
||||
|
||||
// Console
|
||||
m_settings->registerSetting(new Setting("ShowConsole", true));
|
||||
m_settings->registerSetting(new Setting("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)));
|
||||
|
||||
// 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));
|
||||
|
||||
// Memory
|
||||
m_settings->registerSetting(new Setting("MinMemAlloc", 512));
|
||||
m_settings->registerSetting(new Setting("MaxMemAlloc", 1024));
|
||||
m_settings->registerSetting(new Setting("PermGen", 64));
|
||||
|
||||
// Java Settings
|
||||
m_settings->registerSetting(new Setting("JavaPath", ""));
|
||||
m_settings->registerSetting(new Setting("LastHostname", ""));
|
||||
m_settings->registerSetting(new Setting("JvmArgs", ""));
|
||||
|
||||
// Custom Commands
|
||||
m_settings->registerSetting(new Setting("PreLaunchCommand", ""));
|
||||
m_settings->registerSetting(new Setting("PostExitCommand", ""));
|
||||
|
||||
// The cat
|
||||
m_settings->registerSetting(new Setting("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())
|
||||
m_settings->registerSetting("FTBRoot");
|
||||
if (m_settings->get("FTBRoot").isNull())
|
||||
{
|
||||
QUuid uuid = QUuid::createUuid();
|
||||
m_settings->set("YggdrasilClientToken", uuid.toString());
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
// Window state and geometry
|
||||
m_settings->registerSetting(new Setting("MainWindowState", ""));
|
||||
m_settings->registerSetting(new Setting("MainWindowGeometry", ""));
|
||||
// Folders
|
||||
m_settings->registerSetting("InstanceDir", "instances");
|
||||
m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods");
|
||||
m_settings->registerSetting({"LWJGLDir", "LwjglDir"}, "lwjgl");
|
||||
m_settings->registerSetting("IconsDir", "icons");
|
||||
|
||||
m_settings->registerSetting(new Setting("ConsoleWindowState", ""));
|
||||
m_settings->registerSetting(new Setting("ConsoleWindowGeometry", ""));
|
||||
// Editors
|
||||
m_settings->registerSetting("JsonEditor", QString());
|
||||
|
||||
// Console
|
||||
m_settings->registerSetting("ShowConsole", true);
|
||||
m_settings->registerSetting("AutoCloseConsole", true);
|
||||
|
||||
// Console Colors
|
||||
// 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({"LaunchMaximized", "MCWindowMaximize"}, false);
|
||||
m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854);
|
||||
m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480);
|
||||
|
||||
// Memory
|
||||
m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512);
|
||||
m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024);
|
||||
m_settings->registerSetting("PermGen", 64);
|
||||
|
||||
// Java Settings
|
||||
m_settings->registerSetting("JavaPath", "");
|
||||
m_settings->registerSetting("LastHostname", "");
|
||||
m_settings->registerSetting("JvmArgs", "");
|
||||
|
||||
// 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", "");
|
||||
}
|
||||
|
||||
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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue