diff options
author | Petr Mrázek <peterix@gmail.com> | 2015-07-21 02:38:15 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2015-07-21 02:38:15 +0200 |
commit | 61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0 (patch) | |
tree | ce1e124a44f48d221d40c5534e438ef60491831c /logic/minecraft | |
parent | 8e7caf4e25dc3f56877a504c45d157860215496b (diff) | |
download | MultiMC-61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0.tar MultiMC-61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0.tar.gz MultiMC-61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0.tar.lz MultiMC-61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0.tar.xz MultiMC-61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0.zip |
GH-1053 explode launch task into many small steps, each a Task
Diffstat (limited to 'logic/minecraft')
-rw-r--r-- | logic/minecraft/LegacyInstance.cpp | 6 | ||||
-rw-r--r-- | logic/minecraft/MinecraftInstance.cpp | 132 | ||||
-rw-r--r-- | logic/minecraft/MinecraftInstance.h | 12 | ||||
-rw-r--r-- | logic/minecraft/OneSixInstance.cpp | 65 |
4 files changed, 209 insertions, 6 deletions
diff --git a/logic/minecraft/LegacyInstance.cpp b/logic/minecraft/LegacyInstance.cpp index 0991b7b5..a0af19dc 100644 --- a/logic/minecraft/LegacyInstance.cpp +++ b/logic/minecraft/LegacyInstance.cpp @@ -124,9 +124,9 @@ std::shared_ptr<LaunchTask> LegacyInstance::createLaunchTask(AuthSessionPtr acco launchScript += "launcher legacy\n"; } auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr())); - process->setLaunchScript(launchScript); - process->setWorkdir(minecraftRoot()); - process->setLogin(account); + // process->setLaunchScript(launchScript); + // process->setWorkdir(minecraftRoot()); + // process->setLogin(account); return process; } diff --git a/logic/minecraft/MinecraftInstance.cpp b/logic/minecraft/MinecraftInstance.cpp index 71bec71e..a078c8fd 100644 --- a/logic/minecraft/MinecraftInstance.cpp +++ b/logic/minecraft/MinecraftInstance.cpp @@ -4,6 +4,9 @@ #include <pathutils.h> #include "Env.h" #include "minecraft/MinecraftVersionList.h" +#include <MMCStrings.h> + +#define IBUS "@im=ibus" // all of this because keeping things compatible with deprecated old settings // if either of the settings {a, b} is true, this also resolves to true @@ -72,4 +75,133 @@ std::shared_ptr< BaseVersionList > MinecraftInstance::versionList() const return ENV.getVersionList("net.minecraft"); } +QStringList MinecraftInstance::javaArguments() const +{ + QStringList args; + + // custom args go first. we want to override them if we have our own here. + args.append(extraArguments()); + + // OSX dock icon and name +#ifdef Q_OS_MAC + args << "-Xdock:icon=icon.png"; + args << QString("-Xdock:name=\"%1\"").arg(windowTitle()); +#endif + + // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767 +#ifdef Q_OS_WIN32 + args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_" + "minecraft.exe.heapdump"); +#endif + + args << QString("-Xms%1m").arg(settings()->get("MinMemAlloc").toInt()); + args << QString("-Xmx%1m").arg(settings()->get("MaxMemAlloc").toInt()); + + // No PermGen in newer java. + auto javaVersion = settings()->get("JavaVersion"); + if(Strings::naturalCompare(javaVersion.toString(), "1.8.0", Qt::CaseInsensitive) < 0) + { + auto permgen = settings()->get("PermGen").toInt(); + if (permgen != 64) + { + args << QString("-XX:PermSize=%1m").arg(permgen); + } + } + + args << "-Duser.language=en"; + args << "-jar" << PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar"); + + return args; +} + +QMap<QString, QString> MinecraftInstance::getVariables() const +{ + QMap<QString, QString> out; + out.insert("INST_NAME", name()); + out.insert("INST_ID", id()); + out.insert("INST_DIR", QDir(instanceRoot()).absolutePath()); + out.insert("INST_MC_DIR", QDir(minecraftRoot()).absolutePath()); + out.insert("INST_JAVA", settings()->get("JavaPath").toString()); + out.insert("INST_JAVA_ARGS", javaArguments().join(' ')); + return out; +} + +QProcessEnvironment MinecraftInstance::createEnvironment() +{ + // prepare the process environment + QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment(); + QProcessEnvironment env; + + QStringList ignored = + { + "JAVA_ARGS", + "CLASSPATH", + "CONFIGPATH", + "JAVA_HOME", + "JRE_HOME", + "_JAVA_OPTIONS", + "JAVA_OPTIONS", + "JAVA_TOOL_OPTIONS" + }; + for(auto key: rawenv.keys()) + { + auto value = rawenv.value(key); + // filter out dangerous java crap + if(ignored.contains(key)) + { + qDebug() << "Env: ignoring" << key << value; + continue; + } + // filter MultiMC-related things + if(key.startsWith("QT_")) + { + qDebug() << "Env: ignoring" << key << value; + continue; + } +#ifdef Q_OS_LINUX + // Do not pass LD_* variables to java. They were intended for MultiMC + if(key.startsWith("LD_")) + { + qDebug() << "Env: ignoring" << key << value; + continue; + } + // Strip IBus + // IBus is a Linux IME framework. For some reason, it breaks MC? + if (key == "XMODIFIERS" && value.contains(IBUS)) + { + QString save = value; + value.replace(IBUS, ""); + qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value; + } + if(key == "GAME_PRELOAD") + { + env.insert("LD_PRELOAD", value); + continue; + } + if(key == "GAME_LIBRARY_PATH") + { + env.insert("LD_LIBRARY_PATH", value); + continue; + } +#endif + qDebug() << "Env: " << key << value; + env.insert(key, value); + } +#ifdef Q_OS_LINUX + // HACK: Workaround for QTBUG42500 + if(!env.contains("LD_LIBRARY_PATH")) + { + env.insert("LD_LIBRARY_PATH", ""); + } +#endif + + // export some infos + auto variables = getVariables(); + for (auto it = variables.begin(); it != variables.end(); ++it) + { + env.insert(it.key(), it.value()); + } + return env; +} + #include "MinecraftInstance.moc" diff --git a/logic/minecraft/MinecraftInstance.h b/logic/minecraft/MinecraftInstance.h index d7ae18ea..45589daf 100644 --- a/logic/minecraft/MinecraftInstance.h +++ b/logic/minecraft/MinecraftInstance.h @@ -1,6 +1,7 @@ #pragma once #include "BaseInstance.h" #include "minecraft/Mod.h" +#include <QProcess> class ModList; @@ -27,7 +28,18 @@ public: { return QList<Mod>(); } + + //FIXME: nuke? virtual std::shared_ptr< BaseVersionList > versionList() const; + + /// get arguments passed to java + QStringList javaArguments() const; + + /// get variables for launch command variable substitution/environment + virtual QMap<QString, QString> getVariables() const override; + + /// create an environment for launching processes + virtual QProcessEnvironment createEnvironment() override; }; typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr; diff --git a/logic/minecraft/OneSixInstance.cpp b/logic/minecraft/OneSixInstance.cpp index d66236f4..5e2f5c64 100644 --- a/logic/minecraft/OneSixInstance.cpp +++ b/logic/minecraft/OneSixInstance.cpp @@ -23,6 +23,12 @@ #include "minecraft/MinecraftProfile.h" #include "minecraft/VersionBuildError.h" #include "launch/LaunchTask.h" +#include <launch/steps/PreLaunchCommand.h> +#include <launch/steps/Update.h> +#include <launch/steps/LaunchCommand.h> +#include <launch/steps/PostLaunchCommand.h> +#include <launch/steps/TextPrint.h> +#include <launch/steps/ModMinecraftJar.h> #include "minecraft/OneSixProfileStrategy.h" #include "MMCZip.h" @@ -231,9 +237,62 @@ std::shared_ptr<LaunchTask> OneSixInstance::createLaunchTask(AuthSessionPtr sess launchScript += "launcher onesix\n"; auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr())); - process->setLaunchScript(launchScript); - process->setWorkdir(minecraftRoot()); - process->setLogin(session); + auto pptr = process.get(); + + // print a header + { + process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC)); + } + // run pre-launch command if that's needed + if(getPreLaunchCommand().size()) + { + auto step = std::make_shared<PreLaunchCommand>(pptr); + step->setWorkingDirectory(minecraftRoot()); + process->appendStep(step); + } + // if we aren't in offline mode,. + if(session->status != AuthSession::PlayableOffline) + { + process->appendStep(std::make_shared<Update>(pptr)); + } + // if there are any jar mods + if(getJarMods().size()) + { + auto step = std::make_shared<ModMinecraftJar>(pptr); + process->appendStep(step); + } + // actually launch the game + { + auto step = std::make_shared<LaunchCommand>(pptr); + step->setWorkingDirectory(minecraftRoot()); + step->setLaunchScript(launchScript); + process->appendStep(step); + } + // run post-exit command if that's needed + if(getPostExitCommand().size()) + { + auto step = std::make_shared<PostLaunchCommand>(pptr); + step->setWorkingDirectory(minecraftRoot()); + process->appendStep(step); + } + if (session) + { + QMap<QString, QString> filter; + if (session->session != "-") + filter[session->session] = tr("<SESSION ID>"); + filter[session->access_token] = tr("<ACCESS TOKEN>"); + filter[session->client_token] = tr("<CLIENT TOKEN>"); + filter[session->uuid] = tr("<PROFILE ID>"); + filter[session->player_name] = tr("<PROFILE NAME>"); + + auto i = session->u.properties.begin(); + while (i != session->u.properties.end()) + { + filter[i.value()] = "<" + i.key().toUpper() + ">"; + ++i; + } + process->setCensorFilter(filter); + } return process; } |