diff options
Diffstat (limited to 'MultiMC.cpp')
-rw-r--r-- | MultiMC.cpp | 295 |
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" |