NOISSUE implement direct java launch

Just running the Java process and giving it params on the command line
This commit is contained in:
Petr Mrázek
2016-06-16 02:20:23 +02:00
parent 57c84ec2b1
commit 1f2bed2ef1
31 changed files with 990 additions and 627 deletions

View File

@ -210,6 +210,11 @@ public:
virtual bool reload();
/**
* 'print' a verbose desription of the instance into a QStringList
*/
virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
signals:
/*!
* \brief Signal emitted when properties relevant to the instance view change

View File

@ -202,8 +202,14 @@ set(MINECRAFT_SOURCES
minecraft/onesix/OneSixVersionFormat.h
minecraft/launch/ModMinecraftJar.cpp
minecraft/launch/ModMinecraftJar.h
minecraft/launch/LaunchMinecraft.cpp
minecraft/launch/LaunchMinecraft.h
minecraft/launch/DirectJavaLaunch.cpp
minecraft/launch/DirectJavaLaunch.h
minecraft/launch/ExtractNatives.cpp
minecraft/launch/ExtractNatives.h
minecraft/launch/LauncherPartLaunch.cpp
minecraft/launch/LauncherPartLaunch.h
minecraft/launch/PrintInstanceInfo.cpp
minecraft/launch/PrintInstanceInfo.h
minecraft/legacy/LegacyModList.h
minecraft/legacy/LegacyModList.cpp
minecraft/legacy/LegacyUpdate.h

View File

@ -87,4 +87,10 @@ public:
{
return false;
}
QStringList verboseDescription(AuthSessionPtr session) override
{
QStringList out;
out << "Null instance - placeholder.";
return out;
}
};

View File

@ -6,7 +6,7 @@
JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
{
string = javaVersionString;
m_string = javaVersionString;
auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int
{
@ -28,12 +28,12 @@ JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
}
auto match = pattern.match(string);
parseable = match.hasMatch();
major = getCapturedInteger(match, "major");
minor = getCapturedInteger(match, "minor");
security = getCapturedInteger(match, "security");
prerelease = match.captured("prerelease");
auto match = pattern.match(m_string);
m_parseable = match.hasMatch();
m_major = getCapturedInteger(match, "major");
m_minor = getCapturedInteger(match, "minor");
m_security = getCapturedInteger(match, "security");
m_prerelease = match.captured("prerelease");
return *this;
}
@ -44,38 +44,38 @@ JavaVersion::JavaVersion(const QString &rhs)
QString JavaVersion::toString()
{
return string;
return m_string;
}
bool JavaVersion::requiresPermGen()
{
if(parseable)
if(m_parseable)
{
return major < 8;
return m_major < 8;
}
return true;
}
bool JavaVersion::operator<(const JavaVersion &rhs)
{
if(parseable && rhs.parseable)
if(m_parseable && rhs.m_parseable)
{
if(major < rhs.major)
if(m_major < rhs.m_major)
return true;
if(major > rhs.major)
if(m_major > rhs.m_major)
return false;
if(minor < rhs.minor)
if(m_minor < rhs.m_minor)
return true;
if(minor > rhs.minor)
if(m_minor > rhs.m_minor)
return false;
if(security < rhs.security)
if(m_security < rhs.m_security)
return true;
if(security > rhs.security)
if(m_security > rhs.m_security)
return false;
// everything else being equal, consider prerelease status
bool thisPre = !prerelease.isEmpty();
bool rhsPre = !rhs.prerelease.isEmpty();
bool thisPre = !m_prerelease.isEmpty();
bool rhsPre = !rhs.m_prerelease.isEmpty();
if(thisPre && !rhsPre)
{
// this is a prerelease and the other one isn't -> lesser
@ -89,21 +89,21 @@ bool JavaVersion::operator<(const JavaVersion &rhs)
else if(thisPre && rhsPre)
{
// both are prereleases - use natural compare...
return Strings::naturalCompare(prerelease, rhs.prerelease, Qt::CaseSensitive) < 0;
return Strings::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0;
}
// neither is prerelease, so they are the same -> this cannot be less than rhs
return false;
}
else return Strings::naturalCompare(string, rhs.string, Qt::CaseSensitive) < 0;
else return Strings::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0;
}
bool JavaVersion::operator==(const JavaVersion &rhs)
{
if(parseable && rhs.parseable)
if(m_parseable && rhs.m_parseable)
{
return major == rhs.major && minor == rhs.minor && security == rhs.security && prerelease == rhs.prerelease;
return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease;
}
return string == rhs.string;
return m_string == rhs.m_string;
}
bool JavaVersion::operator>(const JavaVersion &rhs)

View File

@ -20,11 +20,23 @@ public:
QString toString();
int major()
{
return m_major;
}
int minor()
{
return m_minor;
}
int security()
{
return m_security;
}
private:
QString string;
int major = 0;
int minor = 0;
int security = 0;
bool parseable = false;
QString prerelease;
QString m_string;
int m_major = 0;
int m_minor = 0;
int m_security = 0;
bool m_parseable = false;
QString m_prerelease;
};

View File

@ -34,12 +34,12 @@ slots:
QFETCH(QString, prerelease);
JavaVersion test(string);
QCOMPARE(test.string, string);
QCOMPARE(test.m_string, string);
QCOMPARE(test.toString(), string);
QCOMPARE(test.major, major);
QCOMPARE(test.minor, minor);
QCOMPARE(test.security, security);
QCOMPARE(test.prerelease, prerelease);
QCOMPARE(test.m_major, major);
QCOMPARE(test.m_minor, minor);
QCOMPARE(test.m_security, security);
QCOMPARE(test.m_prerelease, prerelease);
}
void test_Sort_data()

View File

@ -53,20 +53,25 @@ void CheckJava::executeTask()
QFileInfo javaInfo(realJavaPath);
qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
auto storedArchitecture = settings->get("JavaArchitecture").toString();
auto storedVersion = settings->get("JavaVersion").toString();
m_javaUnixTime = javaUnixTime;
// if they are not the same, check!
if (javaUnixTime != storedUnixTime)
// if timestamps are not the same, or something is missing, check!
if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0)
{
m_JavaChecker = std::make_shared<JavaChecker>();
QString errorLog;
QString version;
emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this,
&CheckJava::checkJavaFinished);
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
m_JavaChecker->m_path = realJavaPath;
m_JavaChecker->performCheck();
return;
}
else
{
auto verString = instance->settings()->get("JavaVersion").toString();
auto archString = instance->settings()->get("JavaArchitecture").toString();
printJavaInfo(verString, archString);
}
emitSucceeded();
}
@ -83,10 +88,15 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
else
{
auto instance = m_parent->instance();
emit logLine(tr("Java version is %1!\n").arg(result.javaVersion.toString()),
MessageLevel::MultiMC);
printJavaInfo(result.javaVersion.toString(), result.mojangPlatform);
instance->settings()->set("JavaVersion", result.javaVersion.toString());
instance->settings()->set("JavaArchitecture", result.mojangPlatform);
instance->settings()->set("JavaTimestamp", m_javaUnixTime);
emitSucceeded();
}
}
void CheckJava::printJavaInfo(const QString& version, const QString& architecture)
{
emit logLine(tr("Java is version %1, using %2-bit architecture.\n\n").arg(version, architecture), MessageLevel::MultiMC);
}

View File

@ -34,6 +34,9 @@ public:
private slots:
void checkJavaFinished(JavaCheckResult result);
private:
void printJavaInfo(const QString & version, const QString & architecture);
private:
QString m_javaPath;
qlonglong m_javaUnixTime;

View File

@ -1,4 +1,6 @@
#include "MinecraftInstance.h"
#include <minecraft/launch/ExtractNatives.h>
#include <minecraft/launch/PrintInstanceInfo.h>
#include <settings/Setting.h>
#include "settings/SettingsObject.h"
#include "Env.h"
@ -9,6 +11,15 @@
#include <FileSystem.h>
#include <java/JavaVersion.h>
#include "launch/LaunchTask.h"
#include "launch/steps/PostLaunchCommand.h"
#include "launch/steps/Update.h"
#include "launch/steps/PreLaunchCommand.h"
#include "launch/steps/TextPrint.h"
#include "minecraft/launch/LauncherPartLaunch.h"
#include "minecraft/launch/ModMinecraftJar.h"
#include "java/launch/CheckJava.h"
#define IBUS "@im=ibus"
// all of this because keeping things compatible with deprecated old settings
@ -52,6 +63,7 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
// special!
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
m_settings->registerPassthrough(globalSettings->getSetting("JavaArchitecture"), javaOrLocation);
// Window Size
auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
@ -64,6 +76,10 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc"), memorySetting);
m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
m_settings->registerOverride(globalSettings->getSetting("PermGen"), memorySetting);
// Minecraft launch method
auto launchMethodOverride = m_settings->registerSetting("OverrideMCLaunchMethod", false);
m_settings->registerOverride(globalSettings->getSetting("MCLaunchMethod"), launchMethodOverride);
}
QString MinecraftInstance::minecraftRoot() const
@ -105,7 +121,7 @@ QStringList MinecraftInstance::javaArguments() const
args << QString("-Xmx%1m").arg(settings()->get("MaxMemAlloc").toInt());
// No PermGen in newer java.
JavaVersion javaVersion(settings()->get("JavaVersion").toString());
JavaVersion javaVersion = getJavaVersion();
if(javaVersion.requiresPermGen())
{
auto permgen = settings()->get("PermGen").toInt();
@ -116,7 +132,6 @@ QStringList MinecraftInstance::javaArguments() const
}
args << "-Duser.language=en";
args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
return args;
}
@ -366,4 +381,95 @@ QString MinecraftInstance::getStatusbarDescription()
return description;
}
std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session)
{
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
auto pptr = process.get();
// print a header
{
process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
}
// check java
{
auto step = std::make_shared<CheckJava>(pptr);
process->appendStep(step);
}
// check launch method
QStringList validMethods = validLaunchMethods();
QString method = launchMethod();
if(!validMethods.contains(method))
{
process->appendStep(std::make_shared<TextPrint>(pptr, "Selected launch method \"" + method + "\" is not valid.\n", MessageLevel::Fatal));
return process;
}
// 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);
}
// print some instance info here...
{
auto step = std::make_shared<PrintInstanceInfo>(pptr, session);
process->appendStep(step);
}
// extract native jars if needed
auto jars = getNativeJars();
if(jars.size())
{
auto step = std::make_shared<ExtractNatives>(pptr);
process->appendStep(step);
}
{
// actually launch the game
auto step = createMainLaunchStep(pptr, session);
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)
{
process->setCensorFilter(createCensorFilterFromSession(session));
}
return process;
}
QString MinecraftInstance::launchMethod()
{
return m_settings->get("MCLaunchMethod").toString();
}
JavaVersion MinecraftInstance::getJavaVersion() const
{
return JavaVersion(settings()->get("JavaVersion").toString());
}
#include "MinecraftInstance.moc"

View File

@ -1,5 +1,6 @@
#pragma once
#include "BaseInstance.h"
#include <java/JavaVersion.h>
#include "minecraft/Mod.h"
#include <QProcess>
@ -7,6 +8,7 @@
class ModList;
class WorldList;
class LaunchStep;
class MULTIMC_LOGIC_EXPORT MinecraftInstance: public BaseInstance
{
@ -36,7 +38,7 @@ public:
return QList<Mod>();
}
/// get the launch script to be used with this
virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
virtual QString createLaunchScript(AuthSessionPtr session) = 0;
//FIXME: nuke?
@ -60,8 +62,22 @@ public:
virtual QString getStatusbarDescription() override;
virtual QStringList getClassPath() const = 0;
virtual QStringList getNativeJars() const = 0;
virtual QString getMainClass() const = 0;
virtual QString getNativePath() const = 0;
virtual QStringList processMinecraftArgs(AuthSessionPtr account) const = 0;
virtual JavaVersion getJavaVersion() const;
protected:
QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
virtual QStringList validLaunchMethods() = 0;
virtual QString launchMethod();
virtual std::shared_ptr<LaunchStep> createMainLaunchStep(LaunchTask *parent, AuthSessionPtr session) = 0;
private:
QString prettifyTimeDuration(int64_t duration);
};

View File

@ -573,6 +573,26 @@ const QList<LibraryPtr> & MinecraftProfile::getLibraries() const
return m_libraries;
}
void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList& jars, QStringList& nativeJars) const
{
QStringList native32, native64;
jars.clear();
nativeJars.clear();
for (auto lib : getLibraries())
{
lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64);
}
if(architecture == "32")
{
nativeJars.append(native32);
}
else if(architecture == "64")
{
nativeJars.append(native64);
}
}
QString MinecraftProfile::getMainJarUrl() const
{
auto iter = mojangDownloads.find("client");

View File

@ -110,6 +110,7 @@ public: /* getters for profile variables */
const QStringList & getTweakers() const;
const QList<JarmodPtr> & getJarMods() const;
const QList<LibraryPtr> & getLibraries() const;
void getLibraryFiles(const QString & architecture, QStringList & jars, QStringList & nativeJars) const;
QString getMainJarUrl() const;
bool hasTrait(const QString & trait) const;
ProblemSeverity getProblemSeverity() const;

View File

@ -0,0 +1,149 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "DirectJavaLaunch.h"
#include <launch/LaunchTask.h>
#include <minecraft/MinecraftInstance.h>
#include <FileSystem.h>
#include <QStandardPaths>
DirectJavaLaunch::DirectJavaLaunch(LaunchTask *parent) : LaunchStep(parent)
{
connect(&m_process, &LoggedProcess::log, this, &DirectJavaLaunch::logLines);
connect(&m_process, &LoggedProcess::stateChanged, this, &DirectJavaLaunch::on_state);
}
void DirectJavaLaunch::executeTask()
{
auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
QStringList args = minecraftInstance->javaArguments();
// HACK: this is a workaround for MCL-3732 - 'server-resource-packs' is created.
if(!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->minecraftRoot(), "server-resource-packs")))
{
emit logLine(tr("Couldn't create the 'server-resource-packs' folder"), MessageLevel::Error);
}
args.append("-Djava.library.path=" + minecraftInstance->getNativePath());
auto classPathEntries = minecraftInstance->getClassPath();
args.append("-cp");
QString classpath;
#ifdef Q_OS_WIN32
classpath = classPathEntries.join(';');
#else
classpath = classPathEntries.join(':');
#endif
args.append(classpath);
args.append(minecraftInstance->getMainClass());
QString allArgs = args.join(", ");
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
m_process.setProcessEnvironment(instance->createEnvironment());
auto mcArgs = minecraftInstance->processMinecraftArgs(m_session);
args.append(mcArgs);
QString wrapperCommand = instance->getWrapperCommand();
if(!wrapperCommand.isEmpty())
{
auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
if (realWrapperCommand.isEmpty())
{
QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand);
emit logLine(reason, MessageLevel::Fatal);
emitFailed(reason);
return;
}
emit logLine("Wrapper command is:\n" + wrapperCommand + "\n\n", MessageLevel::MultiMC);
args.prepend(javaPath);
m_process.start(wrapperCommand, args);
}
else
{
m_process.start(javaPath, args);
}
}
void DirectJavaLaunch::on_state(LoggedProcess::State state)
{
switch(state)
{
case LoggedProcess::FailedToStart:
{
//: Error message displayed if instace can't start
QString reason = tr("Could not launch minecraft!");
emit logLine(reason, MessageLevel::Fatal);
emitFailed(reason);
return;
}
case LoggedProcess::Aborted:
case LoggedProcess::Crashed:
{
m_parent->setPid(-1);
emitFailed("Game crashed.");
return;
}
case LoggedProcess::Finished:
{
m_parent->setPid(-1);
// if the exit code wasn't 0, report this as a crash
auto exitCode = m_process.exitCode();
if(exitCode != 0)
{
emitFailed("Game crashed.");
return;
}
//FIXME: make this work again
// m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode));
// run post-exit
emitSucceeded();
break;
}
case LoggedProcess::Running:
emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
m_parent->setPid(m_process.processId());
m_parent->instance()->setLastLaunch();
break;
default:
break;
}
}
void DirectJavaLaunch::setWorkingDirectory(const QString &wd)
{
m_process.setWorkingDirectory(wd);
}
void DirectJavaLaunch::proceed()
{
// nil
}
bool DirectJavaLaunch::abort()
{
auto state = m_process.state();
if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
{
m_process.kill();
}
return true;
}

View File

@ -0,0 +1,47 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <launch/LaunchStep.h>
#include <launch/LoggedProcess.h>
#include <minecraft/auth/AuthSession.h>
class DirectJavaLaunch: public LaunchStep
{
Q_OBJECT
public:
explicit DirectJavaLaunch(LaunchTask *parent);
virtual void executeTask();
virtual bool abort();
virtual void proceed();
virtual bool canAbort() const
{
return true;
}
void setWorkingDirectory(const QString &wd);
void setAuthSession(AuthSessionPtr session)
{
m_session = session;
}
private slots:
void on_state(LoggedProcess::State state);
private:
LoggedProcess m_process;
QString m_command;
AuthSessionPtr m_session;
};

View File

@ -0,0 +1,86 @@
/* Copyright 2013-2016 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ExtractNatives.h"
#include <minecraft/MinecraftInstance.h>
#include <launch/LaunchTask.h>
#include <quazip.h>
#include <JlCompress.h>
#include <quazipdir.h>
#include "MMCZip.h"
#include "FileSystem.h"
#include <QDir>
static QString replaceSuffix (QString target, const QString &suffix, const QString &replacement)
{
if (!target.endsWith(suffix))
{
return target;
}
target.resize(target.length() - suffix.length());
return target + replacement;
}
static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibHack)
{
QuaZip zip(source);
if(!zip.open(QuaZip::mdUnzip))
{
return false;
}
QDir directory(targetFolder);
if (!zip.goToFirstFile())
{
return false;
}
do
{
QString name = zip.getCurrentFileName();
if(applyJnilibHack)
{
name = replaceSuffix(name, ".jnilib", ".dylib");
}
QString absFilePath = directory.absoluteFilePath(name);
if (!MMCZip::extractFile(&zip, "", absFilePath))
{
return false;
}
} while (zip.goToNextFile());
zip.close();
if(zip.getZipError()!=0)
{
return false;
}
return true;
}
void ExtractNatives::executeTask()
{
auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
auto outputPath = minecraftInstance->getNativePath();
auto toExtract = minecraftInstance->getNativeJars();
auto javaVersion = minecraftInstance->getJavaVersion();
bool jniHackEnabled = javaVersion.major() >= 8;
for(const auto &source: toExtract)
{
if(!unzipNatives(source, outputPath, jniHackEnabled))
{
emitFailed(tr("Couldn't extract native jar '%1' to destination '%2'").arg(source, outputPath));
}
}
emitSucceeded();
}

View File

@ -0,0 +1,37 @@
/* Copyright 2013-2016 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <launch/LaunchStep.h>
#include <memory>
#include "minecraft/auth/AuthSession.h"
// FIXME: temporary wrapper for existing task.
class ExtractNatives: public LaunchStep
{
Q_OBJECT
public:
explicit ExtractNatives(LaunchTask *parent) : LaunchStep(parent){};
virtual ~ExtractNatives(){};
virtual void executeTask();
virtual bool canAbort() const
{
return false;
}
};

View File

@ -13,25 +13,25 @@
* limitations under the License.
*/
#include "LaunchMinecraft.h"
#include "LauncherPartLaunch.h"
#include <QCoreApplication>
#include <launch/LaunchTask.h>
#include <minecraft/MinecraftInstance.h>
#include <FileSystem.h>
#include <QStandardPaths>
LaunchMinecraft::LaunchMinecraft(LaunchTask *parent) : LaunchStep(parent)
LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent)
{
connect(&m_process, &LoggedProcess::log, this, &LaunchMinecraft::logLines);
connect(&m_process, &LoggedProcess::stateChanged, this, &LaunchMinecraft::on_state);
connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines);
connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
}
void LaunchMinecraft::executeTask()
void LauncherPartLaunch::executeTask()
{
auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
m_launchScript = minecraftInstance->createLaunchScript(m_session);
QStringList args = minecraftInstance->javaArguments();
// HACK: this is a workaround for MCL-3732 - 'server-resource-packs' is created.
@ -47,6 +47,8 @@ void LaunchMinecraft::executeTask()
m_process.setProcessEnvironment(instance->createEnvironment());
args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
QString wrapperCommand = instance->getWrapperCommand();
if(!wrapperCommand.isEmpty())
{
@ -68,7 +70,7 @@ void LaunchMinecraft::executeTask()
}
}
void LaunchMinecraft::on_state(LoggedProcess::State state)
void LauncherPartLaunch::on_state(LoggedProcess::State state)
{
switch(state)
{
@ -120,12 +122,12 @@ void LaunchMinecraft::on_state(LoggedProcess::State state)
}
}
void LaunchMinecraft::setWorkingDirectory(const QString &wd)
void LauncherPartLaunch::setWorkingDirectory(const QString &wd)
{
m_process.setWorkingDirectory(wd);
}
void LaunchMinecraft::proceed()
void LauncherPartLaunch::proceed()
{
if(mayProceed)
{
@ -135,7 +137,7 @@ void LaunchMinecraft::proceed()
}
}
bool LaunchMinecraft::abort()
bool LauncherPartLaunch::abort()
{
if(mayProceed)
{

View File

@ -19,11 +19,11 @@
#include <launch/LoggedProcess.h>
#include <minecraft/auth/AuthSession.h>
class LaunchMinecraft: public LaunchStep
class LauncherPartLaunch: public LaunchStep
{
Q_OBJECT
public:
explicit LaunchMinecraft(LaunchTask *parent);
explicit LauncherPartLaunch(LaunchTask *parent);
virtual void executeTask();
virtual bool abort();
virtual void proceed();
@ -36,13 +36,14 @@ public:
{
m_session = session;
}
private slots:
void on_state(LoggedProcess::State state);
private:
LoggedProcess m_process;
QString m_command;
QString m_launchScript;
AuthSessionPtr m_session;
QString m_launchScript;
bool mayProceed = false;
};

View File

@ -0,0 +1,25 @@
/* Copyright 2013-2016 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "PrintInstanceInfo.h"
#include <launch/LaunchTask.h>
void PrintInstanceInfo::executeTask()
{
auto instance = m_parent->instance();
auto lines = instance->verboseDescription(m_session);
logLines(lines, MessageLevel::MultiMC);
emitSucceeded();
}

View File

@ -0,0 +1,38 @@
/* Copyright 2013-2016 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <launch/LaunchStep.h>
#include <memory>
#include "minecraft/auth/AuthSession.h"
// FIXME: temporary wrapper for existing task.
class PrintInstanceInfo: public LaunchStep
{
Q_OBJECT
public:
explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session) : LaunchStep(parent), m_session(session) {};
virtual ~PrintInstanceInfo(){};
virtual void executeTask();
virtual bool canAbort() const
{
return false;
}
private:
AuthSessionPtr m_session;
};

View File

@ -14,6 +14,7 @@
*/
#include <QFileInfo>
#include <minecraft/launch/LauncherPartLaunch.h>
#include <QDir>
#include <settings/Setting.h>
@ -21,14 +22,6 @@
#include "minecraft/legacy/LegacyUpdate.h"
#include "minecraft/legacy/LegacyModList.h"
#include "launch/LaunchTask.h"
#include <launch/steps/PostLaunchCommand.h>
#include <launch/steps/Update.h>
#include <launch/steps/PreLaunchCommand.h>
#include <launch/steps/TextPrint.h>
#include "minecraft/launch/LaunchMinecraft.h"
#include "minecraft/launch/ModMinecraftJar.h"
#include "java/launch/CheckJava.h"
#include "minecraft/ModList.h"
#include "minecraft/WorldList.h"
#include <MMCZip.h>
@ -102,58 +95,6 @@ std::shared_ptr<Task> LegacyInstance::createUpdateTask()
return std::shared_ptr<Task>(new LegacyUpdate(this, this));
}
std::shared_ptr<LaunchTask> LegacyInstance::createLaunchTask(AuthSessionPtr session)
{
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
auto pptr = process.get();
// print a header
{
process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
}
{
auto step = std::make_shared<CheckJava>(pptr);
process->appendStep(step);
}
// 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<LaunchMinecraft>(pptr);
step->setWorkingDirectory(minecraftRoot());
step->setAuthSession(session);
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)
{
process->setCensorFilter(createCensorFilterFromSession(session));
}
return process;
}
std::shared_ptr<Task> LegacyInstance::createJarModdingTask()
{
class JarModTask : public Task
@ -255,11 +196,35 @@ QString LegacyInstance::createLaunchScript(AuthSessionPtr session)
launchScript += "sessionId " + session->session + "\n";
launchScript += "windowTitle " + windowTitle() + "\n";
launchScript += "windowParams " + windowParams + "\n";
launchScript += "lwjgl " + lwjgl + "\n";
launchScript += "launcher legacy\n";
launchScript += "cp bin/minecraft.jar\n";
launchScript += "cp " + lwjgl + "/lwjgl.jar\n";
launchScript += "cp " + lwjgl + "/lwjgl_util.jar\n";
launchScript += "cp " + lwjgl + "/jinput.jar\n";
launchScript += "natives " + lwjgl + "/natives\n";
launchScript += "traits legacyLaunch\n";
launchScript += "launcher onesix\n";
return launchScript;
}
std::shared_ptr<LaunchStep> LegacyInstance::createMainLaunchStep(LaunchTask * parent, AuthSessionPtr session)
{
auto step = std::make_shared<LauncherPartLaunch>(parent);
step->setWorkingDirectory(minecraftRoot());
step->setAuthSession(session);
return step;
}
QString LegacyInstance::launchMethod()
{
return "Legacy";
}
QStringList LegacyInstance::validLaunchMethods()
{
return {"Legacy"};
}
void LegacyInstance::cleanupAfterRun()
{
// FIXME: delete the launcher and icons and whatnot.
@ -452,3 +417,112 @@ QString LegacyInstance::typeName() const
{
return tr("Legacy");
}
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session)
{
QStringList out;
auto alltraits = traits();
if(alltraits.size())
{
out << "Traits:";
for (auto trait : alltraits)
{
out << " " + trait;
}
out << "";
}
if(loaderModList()->size())
{
out << "Mods:";
for(auto & mod: loaderModList()->allMods())
{
if(!mod.enabled())
continue;
if(mod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
out << " " + mod.filename().completeBaseName();
}
out << "";
}
if(coreModList()->size())
{
out << "Core Mods:";
for(auto & coremod: coreModList()->allMods())
{
if(!coremod.enabled())
continue;
if(coremod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
out << " " + coremod.filename().completeBaseName();
}
out << "";
}
if(jarModList()->size())
{
out << "Jar Mods:";
for(auto & jarmod: jarModList()->allMods())
{
out << " " + jarmod.name() + " (" + jarmod.filename().filePath() + ")";
}
out << "";
}
QString windowParams;
if (settings()->get("LaunchMaximized").toBool())
{
out << "Window size: max (if available)";
}
else
{
auto width = settings()->get("MinecraftWinWidth").toInt();
auto height = settings()->get("MinecraftWinHeight").toInt();
out << "Window size: " + QString::number(width) + " x " + QString::number(height);
}
out << "";
return out;
}
QStringList LegacyInstance::getClassPath() const
{
QString launchScript;
QString lwjgl = getNativePath();
QStringList out =
{
"bin/minecraft.jar",
lwjgl + "/lwjgl.jar",
lwjgl + "/lwjgl_util.jar",
lwjgl + "/jinput.jar"
};
return out;
}
QString LegacyInstance::getMainClass() const
{
return "net.minecraft.client.Minecraft";
}
QString LegacyInstance::getNativePath() const
{
return QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath();
}
QStringList LegacyInstance::getNativeJars() const
{
return {};
}
QStringList LegacyInstance::processMinecraftArgs(AuthSessionPtr account) const
{
QStringList out;
out.append(account->player_name);
out.append(account->session);
return out;
}

View File

@ -114,11 +114,7 @@ public:
virtual bool shouldUpdate() const override;
virtual void setShouldUpdate(bool val) override;
virtual std::shared_ptr<Task> createUpdateTask() override;
virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
virtual std::shared_ptr<Task> createJarModdingTask() override;
virtual QString createLaunchScript(AuthSessionPtr session) override;
virtual void cleanupAfterRun() override;
@ -130,6 +126,20 @@ public:
return true;
}
QStringList getClassPath() const override;
QString getMainClass() const override;
QStringList getNativeJars() const override;
QString getNativePath() const override;
QStringList processMinecraftArgs(AuthSessionPtr account) const override;
QStringList verboseDescription(AuthSessionPtr session) override;
protected:
std::shared_ptr<LaunchStep> createMainLaunchStep(LaunchTask *parent, AuthSessionPtr session) override;
QStringList validLaunchMethods() override;
QString launchMethod() override;
protected:
mutable std::shared_ptr<LegacyModList> jar_mod_list;
mutable std::shared_ptr<ModList> core_mod_list;

View File

@ -14,6 +14,8 @@
*/
#include <QDebug>
#include <minecraft/launch/DirectJavaLaunch.h>
#include <minecraft/launch/LauncherPartLaunch.h>
#include <Env.h>
#include "OneSixInstance.h"
@ -22,14 +24,7 @@
#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/PostLaunchCommand.h"
#include "launch/steps/TextPrint.h"
#include "minecraft/launch/LaunchMinecraft.h"
#include "minecraft/launch/ModMinecraftJar.h"
#include "java/launch/CheckJava.h"
#include "MMCZip.h"
#include "minecraft/AssetsUtils.h"
@ -94,7 +89,7 @@ QString replaceTokensIn(QString text, QMap<QString, QString> with)
return result;
}
QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) const
{
QString args_pattern = m_profile->getMinecraftArguments();
for (auto tweaker : m_profile->getTweakers())
@ -104,11 +99,16 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
QMap<QString, QString> token_mapping;
// yggdrasil!
token_mapping["auth_username"] = session->username;
token_mapping["auth_session"] = session->session;
token_mapping["auth_access_token"] = session->access_token;
token_mapping["auth_player_name"] = session->player_name;
token_mapping["auth_uuid"] = session->uuid;
if(session)
{
token_mapping["auth_username"] = session->username;
token_mapping["auth_session"] = session->session;
token_mapping["auth_access_token"] = session->access_token;
token_mapping["auth_player_name"] = session->player_name;
token_mapping["auth_uuid"] = session->uuid;
token_mapping["user_properties"] = session->serializeUserProperties();
token_mapping["user_type"] = session->user_type;
}
// blatant self-promotion.
token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
@ -127,9 +127,6 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
auto assets = m_profile->getMinecraftAssets();
token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
token_mapping["user_properties"] = session->serializeUserProperties();
token_mapping["user_type"] = session->user_type;
// 1.7.3+ assets tokens
token_mapping["assets_root"] = absAssetsDir;
token_mapping["assets_index_name"] = assets->id;
@ -142,6 +139,26 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
return parts;
}
QString OneSixInstance::getNativePath() const
{
QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
return natives_dir.absolutePath();
}
QString OneSixInstance::mainJarPath() const
{
auto jarMods = getJarMods();
if (!jarMods.isEmpty())
{
return QDir(instanceRoot()).absoluteFilePath("minecraft.jar");
}
else
{
QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar";
return versionsPath().absoluteFilePath(relpath);
}
}
QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
{
QString launchScript;
@ -149,34 +166,7 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
if (!m_profile)
return nullptr;
for(auto & mod: loaderModList()->allMods())
{
if(!mod.enabled())
continue;
if(mod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
launchScript += "mod " + mod.filename().completeBaseName() + "\n";;
}
for(auto & coremod: coreModList()->allMods())
{
if(!coremod.enabled())
continue;
if(coremod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
launchScript += "coremod " + coremod.filename().completeBaseName() + "\n";;
}
for(auto & jarmod: m_profile->getJarMods())
{
launchScript += "jarmod " + jarmod->originalName + " (" + jarmod->name + ")\n";
}
auto mainClass = m_profile->getMainClass();
auto mainClass = getMainClass();
if (!mainClass.isEmpty())
{
launchScript += "mainClass " + mainClass + "\n";
@ -207,6 +197,7 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
}
// legacy auth
if(session)
{
launchScript += "userName " + session->player_name + "\n";
launchScript += "sessionId " + session->session + "\n";
@ -214,44 +205,21 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
// libraries and class path.
{
auto libs = m_profile->getLibraries();
QStringList jar, native, native32, native64;
for (auto lib : libs)
{
lib->getApplicableFiles(currentSystem, jar, native, native32, native64);
}
for(auto file: jar)
QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars);
for(auto file: jars)
{
launchScript += "cp " + file + "\n";
}
for(auto file: native)
launchScript += "cp " + mainJarPath() + "\n";
for(auto file: nativeJars)
{
launchScript += "ext " + file + "\n";
}
for(auto file: native32)
{
launchScript += "ext32 " + file + "\n";
}
for(auto file: native64)
{
launchScript += "ext64 " + file + "\n";
}
QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
launchScript += "natives " + natives_dir.absolutePath() + "\n";
auto jarMods = getJarMods();
if (!jarMods.isEmpty())
{
launchScript += "cp " + QDir(instanceRoot()).absoluteFilePath("minecraft.jar") + "\n";
}
else
{
QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar";
launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n";
}
launchScript += "natives " + getNativePath() + "\n";
}
// traits. including legacyLaunch and others ;)
for (auto trait : m_profile->getTraits())
{
launchScript += "traits " + trait + "\n";
@ -260,58 +228,139 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
return launchScript;
}
std::shared_ptr<LaunchTask> OneSixInstance::createLaunchTask(AuthSessionPtr session)
QStringList OneSixInstance::verboseDescription(AuthSessionPtr session)
{
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
auto pptr = process.get();
QStringList out;
out << "Main Class:" << " " + getMainClass() << "";
out << "Native path:" << " " + getNativePath() << "";
// print a header
auto alltraits = traits();
if(alltraits.size())
{
process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
out << "Traits:";
for (auto trait : alltraits)
{
out << "traits " + trait;
}
out << "";
}
// libraries and class path.
{
auto step = std::make_shared<CheckJava>(pptr);
process->appendStep(step);
out << "Libraries:";
QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars);
auto printLibFile = [&](const QString & path)
{
QFileInfo info(path);
if(info.exists())
{
out << " " + path;
}
else
{
out << " " + path + " (missing)";
}
};
for(auto file: jars)
{
printLibFile(file);
}
printLibFile(mainJarPath());
for(auto file: nativeJars)
{
printLibFile(file);
}
out << "";
}
// run pre-launch command if that's needed
if(getPreLaunchCommand().size())
if(loaderModList()->size())
{
auto step = std::make_shared<PreLaunchCommand>(pptr);
out << "Mods:";
for(auto & mod: loaderModList()->allMods())
{
if(!mod.enabled())
continue;
if(mod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
out << " " + mod.filename().completeBaseName();
}
out << "";
}
if(coreModList()->size())
{
out << "Core Mods:";
for(auto & coremod: coreModList()->allMods())
{
if(!coremod.enabled())
continue;
if(coremod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
out << " " + coremod.filename().completeBaseName();
}
out << "";
}
auto & jarMods = m_profile->getJarMods();
if(jarMods.size())
{
out << "Jar Mods:";
for(auto & jarmod: jarMods)
{
out << " " + jarmod->originalName + " (" + jarmod->name + ")";
}
out << "";
}
auto params = processMinecraftArgs(nullptr);
out << "Params:";
out << " " + params.join(' ');
out << "";
QString windowParams;
if (settings()->get("LaunchMaximized").toBool())
{
out << "Window size: max (if available)";
}
else
{
auto width = settings()->get("MinecraftWinWidth").toInt();
auto height = settings()->get("MinecraftWinHeight").toInt();
out << "Window size: " + QString::number(width) + " x " + QString::number(height);
}
out << "";
return out;
}
std::shared_ptr<LaunchStep> OneSixInstance::createMainLaunchStep(LaunchTask * parent, AuthSessionPtr session)
{
auto method = launchMethod();
if(method == "LauncherPart")
{
auto step = std::make_shared<LauncherPartLaunch>(parent);
step->setAuthSession(session);
step->setWorkingDirectory(minecraftRoot());
process->appendStep(step);
return step;
}
// if we aren't in offline mode,.
if(session->status != AuthSession::PlayableOffline)
else if (method == "DirectJava")
{
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<LaunchMinecraft>(pptr);
auto step = std::make_shared<DirectJavaLaunch>(parent);
step->setWorkingDirectory(minecraftRoot());
step->setAuthSession(session);
process->appendStep(step);
return 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)
{
process->setCensorFilter(createCensorFilterFromSession(session));
}
return process;
return nullptr;
}
std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
{
class JarModTask : public Task
@ -595,3 +644,30 @@ QString OneSixInstance::typeName() const
{
return tr("OneSix");
}
QStringList OneSixInstance::validLaunchMethods()
{
return {"LauncherPart", "DirectJava"};
}
QStringList OneSixInstance::getClassPath() const
{
QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars);
jars.append(mainJarPath());
return jars;
}
QString OneSixInstance::getMainClass() const
{
return m_profile->getMainClass();
}
QStringList OneSixInstance::getNativeJars() const
{
QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars);
return nativeJars;
}

View File

@ -53,10 +53,9 @@ public:
virtual QString instanceConfigFolder() const override;
virtual std::shared_ptr<Task> createUpdateTask() override;
virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
virtual std::shared_ptr<Task> createJarModdingTask() override;
virtual QString createLaunchScript(AuthSessionPtr session) override;
QStringList verboseDescription(AuthSessionPtr session) override;
virtual void cleanupAfterRun() override;
@ -99,11 +98,23 @@ public:
return true;
}
QStringList getClassPath() const override;
QString getMainClass() const override;
QStringList getNativeJars() const override;
QString getNativePath() const override;
QStringList processMinecraftArgs(AuthSessionPtr account) const override;
protected:
std::shared_ptr<LaunchStep> createMainLaunchStep(LaunchTask *parent, AuthSessionPtr session) override;
QStringList validLaunchMethods() override;
signals:
void versionReloaded();
private:
QStringList processMinecraftArgs(AuthSessionPtr account);
QString mainJarPath() const;
protected:
std::shared_ptr<MinecraftProfile> m_profile;