summaryrefslogtreecommitdiffstats
path: root/logic/minecraft
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2015-07-21 02:38:15 +0200
committerPetr Mrázek <peterix@gmail.com>2015-07-21 02:38:15 +0200
commit61c5a67777a6f7639c9d2f36b14f7a903bdfc5a0 (patch)
treece1e124a44f48d221d40c5534e438ef60491831c /logic/minecraft
parent8e7caf4e25dc3f56877a504c45d157860215496b (diff)
downloadMultiMC-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.cpp6
-rw-r--r--logic/minecraft/MinecraftInstance.cpp132
-rw-r--r--logic/minecraft/MinecraftInstance.h12
-rw-r--r--logic/minecraft/OneSixInstance.cpp65
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;
}