From 61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 21 Jul 2015 02:38:15 +0200 Subject: GH-1053 explode launch task into many small steps, each a Task --- logic/minecraft/LegacyInstance.cpp | 6 +- logic/minecraft/MinecraftInstance.cpp | 132 ++++++++++++++++++++++++++++++++++ logic/minecraft/MinecraftInstance.h | 12 ++++ logic/minecraft/OneSixInstance.cpp | 65 ++++++++++++++++- 4 files changed, 209 insertions(+), 6 deletions(-) (limited to 'logic/minecraft') 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 LegacyInstance::createLaunchTask(AuthSessionPtr acco launchScript += "launcher legacy\n"; } auto process = LaunchTask::create(std::dynamic_pointer_cast(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 #include "Env.h" #include "minecraft/MinecraftVersionList.h" +#include + +#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 MinecraftInstance::getVariables() const +{ + QMap 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 class ModList; @@ -27,7 +28,18 @@ public: { return QList(); } + + //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 getVariables() const override; + + /// create an environment for launching processes + virtual QProcessEnvironment createEnvironment() override; }; typedef std::shared_ptr 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 +#include +#include +#include +#include +#include #include "minecraft/OneSixProfileStrategy.h" #include "MMCZip.h" @@ -231,9 +237,62 @@ std::shared_ptr OneSixInstance::createLaunchTask(AuthSessionPtr sess launchScript += "launcher onesix\n"; auto process = LaunchTask::create(std::dynamic_pointer_cast(getSharedPtr())); - process->setLaunchScript(launchScript); - process->setWorkdir(minecraftRoot()); - process->setLogin(session); + auto pptr = process.get(); + + // print a header + { + process->appendStep(std::make_shared(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(pptr); + step->setWorkingDirectory(minecraftRoot()); + process->appendStep(step); + } + // if we aren't in offline mode,. + if(session->status != AuthSession::PlayableOffline) + { + process->appendStep(std::make_shared(pptr)); + } + // if there are any jar mods + if(getJarMods().size()) + { + auto step = std::make_shared(pptr); + process->appendStep(step); + } + // actually launch the game + { + auto step = std::make_shared(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(pptr); + step->setWorkingDirectory(minecraftRoot()); + process->appendStep(step); + } + if (session) + { + QMap filter; + if (session->session != "-") + filter[session->session] = tr(""); + filter[session->access_token] = tr(""); + filter[session->client_token] = tr(""); + filter[session->uuid] = tr(""); + filter[session->player_name] = tr(""); + + auto i = session->u.properties.begin(); + while (i != session->u.properties.end()) + { + filter[i.value()] = "<" + i.key().toUpper() + ">"; + ++i; + } + process->setCensorFilter(filter); + } return process; } -- cgit v1.2.3