NOISSUE implement direct java launch
Just running the Java process and giving it params on the command line
This commit is contained in:
parent
57c84ec2b1
commit
1f2bed2ef1
@ -210,6 +210,11 @@ public:
|
|||||||
|
|
||||||
virtual bool reload();
|
virtual bool reload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'print' a verbose desription of the instance into a QStringList
|
||||||
|
*/
|
||||||
|
virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/*!
|
/*!
|
||||||
* \brief Signal emitted when properties relevant to the instance view change
|
* \brief Signal emitted when properties relevant to the instance view change
|
||||||
|
@ -202,8 +202,14 @@ set(MINECRAFT_SOURCES
|
|||||||
minecraft/onesix/OneSixVersionFormat.h
|
minecraft/onesix/OneSixVersionFormat.h
|
||||||
minecraft/launch/ModMinecraftJar.cpp
|
minecraft/launch/ModMinecraftJar.cpp
|
||||||
minecraft/launch/ModMinecraftJar.h
|
minecraft/launch/ModMinecraftJar.h
|
||||||
minecraft/launch/LaunchMinecraft.cpp
|
minecraft/launch/DirectJavaLaunch.cpp
|
||||||
minecraft/launch/LaunchMinecraft.h
|
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.h
|
||||||
minecraft/legacy/LegacyModList.cpp
|
minecraft/legacy/LegacyModList.cpp
|
||||||
minecraft/legacy/LegacyUpdate.h
|
minecraft/legacy/LegacyUpdate.h
|
||||||
|
@ -87,4 +87,10 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
QStringList verboseDescription(AuthSessionPtr session) override
|
||||||
|
{
|
||||||
|
QStringList out;
|
||||||
|
out << "Null instance - placeholder.";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
|
JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
|
||||||
{
|
{
|
||||||
string = javaVersionString;
|
m_string = javaVersionString;
|
||||||
|
|
||||||
auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int
|
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]+))?");
|
pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto match = pattern.match(string);
|
auto match = pattern.match(m_string);
|
||||||
parseable = match.hasMatch();
|
m_parseable = match.hasMatch();
|
||||||
major = getCapturedInteger(match, "major");
|
m_major = getCapturedInteger(match, "major");
|
||||||
minor = getCapturedInteger(match, "minor");
|
m_minor = getCapturedInteger(match, "minor");
|
||||||
security = getCapturedInteger(match, "security");
|
m_security = getCapturedInteger(match, "security");
|
||||||
prerelease = match.captured("prerelease");
|
m_prerelease = match.captured("prerelease");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,38 +44,38 @@ JavaVersion::JavaVersion(const QString &rhs)
|
|||||||
|
|
||||||
QString JavaVersion::toString()
|
QString JavaVersion::toString()
|
||||||
{
|
{
|
||||||
return string;
|
return m_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JavaVersion::requiresPermGen()
|
bool JavaVersion::requiresPermGen()
|
||||||
{
|
{
|
||||||
if(parseable)
|
if(m_parseable)
|
||||||
{
|
{
|
||||||
return major < 8;
|
return m_major < 8;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JavaVersion::operator<(const JavaVersion &rhs)
|
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;
|
return true;
|
||||||
if(major > rhs.major)
|
if(m_major > rhs.m_major)
|
||||||
return false;
|
return false;
|
||||||
if(minor < rhs.minor)
|
if(m_minor < rhs.m_minor)
|
||||||
return true;
|
return true;
|
||||||
if(minor > rhs.minor)
|
if(m_minor > rhs.m_minor)
|
||||||
return false;
|
return false;
|
||||||
if(security < rhs.security)
|
if(m_security < rhs.m_security)
|
||||||
return true;
|
return true;
|
||||||
if(security > rhs.security)
|
if(m_security > rhs.m_security)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// everything else being equal, consider prerelease status
|
// everything else being equal, consider prerelease status
|
||||||
bool thisPre = !prerelease.isEmpty();
|
bool thisPre = !m_prerelease.isEmpty();
|
||||||
bool rhsPre = !rhs.prerelease.isEmpty();
|
bool rhsPre = !rhs.m_prerelease.isEmpty();
|
||||||
if(thisPre && !rhsPre)
|
if(thisPre && !rhsPre)
|
||||||
{
|
{
|
||||||
// this is a prerelease and the other one isn't -> lesser
|
// 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)
|
else if(thisPre && rhsPre)
|
||||||
{
|
{
|
||||||
// both are prereleases - use natural compare...
|
// 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
|
// neither is prerelease, so they are the same -> this cannot be less than rhs
|
||||||
return false;
|
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)
|
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)
|
bool JavaVersion::operator>(const JavaVersion &rhs)
|
||||||
|
@ -20,11 +20,23 @@ public:
|
|||||||
|
|
||||||
QString toString();
|
QString toString();
|
||||||
|
|
||||||
|
int major()
|
||||||
|
{
|
||||||
|
return m_major;
|
||||||
|
}
|
||||||
|
int minor()
|
||||||
|
{
|
||||||
|
return m_minor;
|
||||||
|
}
|
||||||
|
int security()
|
||||||
|
{
|
||||||
|
return m_security;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
QString string;
|
QString m_string;
|
||||||
int major = 0;
|
int m_major = 0;
|
||||||
int minor = 0;
|
int m_minor = 0;
|
||||||
int security = 0;
|
int m_security = 0;
|
||||||
bool parseable = false;
|
bool m_parseable = false;
|
||||||
QString prerelease;
|
QString m_prerelease;
|
||||||
};
|
};
|
||||||
|
@ -34,12 +34,12 @@ slots:
|
|||||||
QFETCH(QString, prerelease);
|
QFETCH(QString, prerelease);
|
||||||
|
|
||||||
JavaVersion test(string);
|
JavaVersion test(string);
|
||||||
QCOMPARE(test.string, string);
|
QCOMPARE(test.m_string, string);
|
||||||
QCOMPARE(test.toString(), string);
|
QCOMPARE(test.toString(), string);
|
||||||
QCOMPARE(test.major, major);
|
QCOMPARE(test.m_major, major);
|
||||||
QCOMPARE(test.minor, minor);
|
QCOMPARE(test.m_minor, minor);
|
||||||
QCOMPARE(test.security, security);
|
QCOMPARE(test.m_security, security);
|
||||||
QCOMPARE(test.prerelease, prerelease);
|
QCOMPARE(test.m_prerelease, prerelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_Sort_data()
|
void test_Sort_data()
|
||||||
|
@ -53,20 +53,25 @@ void CheckJava::executeTask()
|
|||||||
QFileInfo javaInfo(realJavaPath);
|
QFileInfo javaInfo(realJavaPath);
|
||||||
qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
|
qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
|
||||||
auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
|
auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
|
||||||
|
auto storedArchitecture = settings->get("JavaArchitecture").toString();
|
||||||
|
auto storedVersion = settings->get("JavaVersion").toString();
|
||||||
m_javaUnixTime = javaUnixTime;
|
m_javaUnixTime = javaUnixTime;
|
||||||
// if they are not the same, check!
|
// if timestamps are not the same, or something is missing, check!
|
||||||
if (javaUnixTime != storedUnixTime)
|
if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0)
|
||||||
{
|
{
|
||||||
m_JavaChecker = std::make_shared<JavaChecker>();
|
m_JavaChecker = std::make_shared<JavaChecker>();
|
||||||
QString errorLog;
|
|
||||||
QString version;
|
|
||||||
emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
|
emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
|
||||||
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this,
|
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
|
||||||
&CheckJava::checkJavaFinished);
|
|
||||||
m_JavaChecker->m_path = realJavaPath;
|
m_JavaChecker->m_path = realJavaPath;
|
||||||
m_JavaChecker->performCheck();
|
m_JavaChecker->performCheck();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto verString = instance->settings()->get("JavaVersion").toString();
|
||||||
|
auto archString = instance->settings()->get("JavaArchitecture").toString();
|
||||||
|
printJavaInfo(verString, archString);
|
||||||
|
}
|
||||||
emitSucceeded();
|
emitSucceeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +88,15 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto instance = m_parent->instance();
|
auto instance = m_parent->instance();
|
||||||
emit logLine(tr("Java version is %1!\n").arg(result.javaVersion.toString()),
|
printJavaInfo(result.javaVersion.toString(), result.mojangPlatform);
|
||||||
MessageLevel::MultiMC);
|
|
||||||
instance->settings()->set("JavaVersion", result.javaVersion.toString());
|
instance->settings()->set("JavaVersion", result.javaVersion.toString());
|
||||||
|
instance->settings()->set("JavaArchitecture", result.mojangPlatform);
|
||||||
instance->settings()->set("JavaTimestamp", m_javaUnixTime);
|
instance->settings()->set("JavaTimestamp", m_javaUnixTime);
|
||||||
emitSucceeded();
|
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);
|
||||||
|
}
|
||||||
|
@ -34,6 +34,9 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void checkJavaFinished(JavaCheckResult result);
|
void checkJavaFinished(JavaCheckResult result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void printJavaInfo(const QString & version, const QString & architecture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_javaPath;
|
QString m_javaPath;
|
||||||
qlonglong m_javaUnixTime;
|
qlonglong m_javaUnixTime;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "MinecraftInstance.h"
|
#include "MinecraftInstance.h"
|
||||||
|
#include <minecraft/launch/ExtractNatives.h>
|
||||||
|
#include <minecraft/launch/PrintInstanceInfo.h>
|
||||||
#include <settings/Setting.h>
|
#include <settings/Setting.h>
|
||||||
#include "settings/SettingsObject.h"
|
#include "settings/SettingsObject.h"
|
||||||
#include "Env.h"
|
#include "Env.h"
|
||||||
@ -9,6 +11,15 @@
|
|||||||
#include <FileSystem.h>
|
#include <FileSystem.h>
|
||||||
#include <java/JavaVersion.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"
|
#define IBUS "@im=ibus"
|
||||||
|
|
||||||
// all of this because keeping things compatible with deprecated old settings
|
// all of this because keeping things compatible with deprecated old settings
|
||||||
@ -52,6 +63,7 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
|
|||||||
// special!
|
// special!
|
||||||
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
|
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
|
||||||
m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
|
m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
|
||||||
|
m_settings->registerPassthrough(globalSettings->getSetting("JavaArchitecture"), javaOrLocation);
|
||||||
|
|
||||||
// Window Size
|
// Window Size
|
||||||
auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
|
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("MinMemAlloc"), memorySetting);
|
||||||
m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
|
m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
|
||||||
m_settings->registerOverride(globalSettings->getSetting("PermGen"), 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
|
QString MinecraftInstance::minecraftRoot() const
|
||||||
@ -105,7 +121,7 @@ QStringList MinecraftInstance::javaArguments() const
|
|||||||
args << QString("-Xmx%1m").arg(settings()->get("MaxMemAlloc").toInt());
|
args << QString("-Xmx%1m").arg(settings()->get("MaxMemAlloc").toInt());
|
||||||
|
|
||||||
// No PermGen in newer java.
|
// No PermGen in newer java.
|
||||||
JavaVersion javaVersion(settings()->get("JavaVersion").toString());
|
JavaVersion javaVersion = getJavaVersion();
|
||||||
if(javaVersion.requiresPermGen())
|
if(javaVersion.requiresPermGen())
|
||||||
{
|
{
|
||||||
auto permgen = settings()->get("PermGen").toInt();
|
auto permgen = settings()->get("PermGen").toInt();
|
||||||
@ -116,7 +132,6 @@ QStringList MinecraftInstance::javaArguments() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
args << "-Duser.language=en";
|
args << "-Duser.language=en";
|
||||||
args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
|
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
@ -366,4 +381,95 @@ QString MinecraftInstance::getStatusbarDescription()
|
|||||||
return description;
|
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"
|
#include "MinecraftInstance.moc"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "BaseInstance.h"
|
#include "BaseInstance.h"
|
||||||
|
#include <java/JavaVersion.h>
|
||||||
#include "minecraft/Mod.h"
|
#include "minecraft/Mod.h"
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
@ -7,6 +8,7 @@
|
|||||||
|
|
||||||
class ModList;
|
class ModList;
|
||||||
class WorldList;
|
class WorldList;
|
||||||
|
class LaunchStep;
|
||||||
|
|
||||||
class MULTIMC_LOGIC_EXPORT MinecraftInstance: public BaseInstance
|
class MULTIMC_LOGIC_EXPORT MinecraftInstance: public BaseInstance
|
||||||
{
|
{
|
||||||
@ -36,7 +38,7 @@ public:
|
|||||||
return QList<Mod>();
|
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;
|
virtual QString createLaunchScript(AuthSessionPtr session) = 0;
|
||||||
|
|
||||||
//FIXME: nuke?
|
//FIXME: nuke?
|
||||||
@ -60,8 +62,22 @@ public:
|
|||||||
|
|
||||||
virtual QString getStatusbarDescription() override;
|
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:
|
protected:
|
||||||
QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
|
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:
|
private:
|
||||||
QString prettifyTimeDuration(int64_t duration);
|
QString prettifyTimeDuration(int64_t duration);
|
||||||
};
|
};
|
||||||
|
@ -573,6 +573,26 @@ const QList<LibraryPtr> & MinecraftProfile::getLibraries() const
|
|||||||
return m_libraries;
|
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
|
QString MinecraftProfile::getMainJarUrl() const
|
||||||
{
|
{
|
||||||
auto iter = mojangDownloads.find("client");
|
auto iter = mojangDownloads.find("client");
|
||||||
|
@ -110,6 +110,7 @@ public: /* getters for profile variables */
|
|||||||
const QStringList & getTweakers() const;
|
const QStringList & getTweakers() const;
|
||||||
const QList<JarmodPtr> & getJarMods() const;
|
const QList<JarmodPtr> & getJarMods() const;
|
||||||
const QList<LibraryPtr> & getLibraries() const;
|
const QList<LibraryPtr> & getLibraries() const;
|
||||||
|
void getLibraryFiles(const QString & architecture, QStringList & jars, QStringList & nativeJars) const;
|
||||||
QString getMainJarUrl() const;
|
QString getMainJarUrl() const;
|
||||||
bool hasTrait(const QString & trait) const;
|
bool hasTrait(const QString & trait) const;
|
||||||
ProblemSeverity getProblemSeverity() const;
|
ProblemSeverity getProblemSeverity() const;
|
||||||
|
149
api/logic/minecraft/launch/DirectJavaLaunch.cpp
Normal file
149
api/logic/minecraft/launch/DirectJavaLaunch.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
47
api/logic/minecraft/launch/DirectJavaLaunch.h
Normal file
47
api/logic/minecraft/launch/DirectJavaLaunch.h
Normal 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;
|
||||||
|
};
|
||||||
|
|
86
api/logic/minecraft/launch/ExtractNatives.cpp
Normal file
86
api/logic/minecraft/launch/ExtractNatives.cpp
Normal 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();
|
||||||
|
}
|
37
api/logic/minecraft/launch/ExtractNatives.h
Normal file
37
api/logic/minecraft/launch/ExtractNatives.h
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -13,25 +13,25 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "LaunchMinecraft.h"
|
#include "LauncherPartLaunch.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <launch/LaunchTask.h>
|
#include <launch/LaunchTask.h>
|
||||||
#include <minecraft/MinecraftInstance.h>
|
#include <minecraft/MinecraftInstance.h>
|
||||||
#include <FileSystem.h>
|
#include <FileSystem.h>
|
||||||
#include <QStandardPaths>
|
#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::log, this, &LauncherPartLaunch::logLines);
|
||||||
connect(&m_process, &LoggedProcess::stateChanged, this, &LaunchMinecraft::on_state);
|
connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaunchMinecraft::executeTask()
|
void LauncherPartLaunch::executeTask()
|
||||||
{
|
{
|
||||||
auto instance = m_parent->instance();
|
auto instance = m_parent->instance();
|
||||||
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
|
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
|
||||||
|
|
||||||
m_launchScript = minecraftInstance->createLaunchScript(m_session);
|
m_launchScript = minecraftInstance->createLaunchScript(m_session);
|
||||||
|
|
||||||
QStringList args = minecraftInstance->javaArguments();
|
QStringList args = minecraftInstance->javaArguments();
|
||||||
|
|
||||||
// HACK: this is a workaround for MCL-3732 - 'server-resource-packs' is created.
|
// 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());
|
m_process.setProcessEnvironment(instance->createEnvironment());
|
||||||
|
|
||||||
|
args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
|
||||||
|
|
||||||
QString wrapperCommand = instance->getWrapperCommand();
|
QString wrapperCommand = instance->getWrapperCommand();
|
||||||
if(!wrapperCommand.isEmpty())
|
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)
|
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);
|
m_process.setWorkingDirectory(wd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaunchMinecraft::proceed()
|
void LauncherPartLaunch::proceed()
|
||||||
{
|
{
|
||||||
if(mayProceed)
|
if(mayProceed)
|
||||||
{
|
{
|
||||||
@ -135,7 +137,7 @@ void LaunchMinecraft::proceed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LaunchMinecraft::abort()
|
bool LauncherPartLaunch::abort()
|
||||||
{
|
{
|
||||||
if(mayProceed)
|
if(mayProceed)
|
||||||
{
|
{
|
@ -19,11 +19,11 @@
|
|||||||
#include <launch/LoggedProcess.h>
|
#include <launch/LoggedProcess.h>
|
||||||
#include <minecraft/auth/AuthSession.h>
|
#include <minecraft/auth/AuthSession.h>
|
||||||
|
|
||||||
class LaunchMinecraft: public LaunchStep
|
class LauncherPartLaunch: public LaunchStep
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LaunchMinecraft(LaunchTask *parent);
|
explicit LauncherPartLaunch(LaunchTask *parent);
|
||||||
virtual void executeTask();
|
virtual void executeTask();
|
||||||
virtual bool abort();
|
virtual bool abort();
|
||||||
virtual void proceed();
|
virtual void proceed();
|
||||||
@ -36,13 +36,14 @@ public:
|
|||||||
{
|
{
|
||||||
m_session = session;
|
m_session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_state(LoggedProcess::State state);
|
void on_state(LoggedProcess::State state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LoggedProcess m_process;
|
LoggedProcess m_process;
|
||||||
QString m_command;
|
QString m_command;
|
||||||
QString m_launchScript;
|
|
||||||
AuthSessionPtr m_session;
|
AuthSessionPtr m_session;
|
||||||
|
QString m_launchScript;
|
||||||
bool mayProceed = false;
|
bool mayProceed = false;
|
||||||
};
|
};
|
25
api/logic/minecraft/launch/PrintInstanceInfo.cpp
Normal file
25
api/logic/minecraft/launch/PrintInstanceInfo.cpp
Normal 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();
|
||||||
|
}
|
38
api/logic/minecraft/launch/PrintInstanceInfo.h
Normal file
38
api/logic/minecraft/launch/PrintInstanceInfo.h
Normal 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;
|
||||||
|
};
|
||||||
|
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <minecraft/launch/LauncherPartLaunch.h>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <settings/Setting.h>
|
#include <settings/Setting.h>
|
||||||
|
|
||||||
@ -21,14 +22,6 @@
|
|||||||
|
|
||||||
#include "minecraft/legacy/LegacyUpdate.h"
|
#include "minecraft/legacy/LegacyUpdate.h"
|
||||||
#include "minecraft/legacy/LegacyModList.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/ModList.h"
|
||||||
#include "minecraft/WorldList.h"
|
#include "minecraft/WorldList.h"
|
||||||
#include <MMCZip.h>
|
#include <MMCZip.h>
|
||||||
@ -102,58 +95,6 @@ std::shared_ptr<Task> LegacyInstance::createUpdateTask()
|
|||||||
return std::shared_ptr<Task>(new LegacyUpdate(this, this));
|
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()
|
std::shared_ptr<Task> LegacyInstance::createJarModdingTask()
|
||||||
{
|
{
|
||||||
class JarModTask : public Task
|
class JarModTask : public Task
|
||||||
@ -255,11 +196,35 @@ QString LegacyInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
launchScript += "sessionId " + session->session + "\n";
|
launchScript += "sessionId " + session->session + "\n";
|
||||||
launchScript += "windowTitle " + windowTitle() + "\n";
|
launchScript += "windowTitle " + windowTitle() + "\n";
|
||||||
launchScript += "windowParams " + windowParams + "\n";
|
launchScript += "windowParams " + windowParams + "\n";
|
||||||
launchScript += "lwjgl " + lwjgl + "\n";
|
launchScript += "cp bin/minecraft.jar\n";
|
||||||
launchScript += "launcher legacy\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;
|
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()
|
void LegacyInstance::cleanupAfterRun()
|
||||||
{
|
{
|
||||||
// FIXME: delete the launcher and icons and whatnot.
|
// FIXME: delete the launcher and icons and whatnot.
|
||||||
@ -452,3 +417,112 @@ QString LegacyInstance::typeName() const
|
|||||||
{
|
{
|
||||||
return tr("Legacy");
|
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;
|
||||||
|
}
|
||||||
|
@ -114,11 +114,7 @@ public:
|
|||||||
virtual bool shouldUpdate() const override;
|
virtual bool shouldUpdate() const override;
|
||||||
virtual void setShouldUpdate(bool val) override;
|
virtual void setShouldUpdate(bool val) override;
|
||||||
virtual std::shared_ptr<Task> createUpdateTask() 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 std::shared_ptr<Task> createJarModdingTask() override;
|
||||||
|
|
||||||
virtual QString createLaunchScript(AuthSessionPtr session) override;
|
virtual QString createLaunchScript(AuthSessionPtr session) override;
|
||||||
|
|
||||||
virtual void cleanupAfterRun() override;
|
virtual void cleanupAfterRun() override;
|
||||||
@ -130,6 +126,20 @@ public:
|
|||||||
return true;
|
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:
|
protected:
|
||||||
mutable std::shared_ptr<LegacyModList> jar_mod_list;
|
mutable std::shared_ptr<LegacyModList> jar_mod_list;
|
||||||
mutable std::shared_ptr<ModList> core_mod_list;
|
mutable std::shared_ptr<ModList> core_mod_list;
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <minecraft/launch/DirectJavaLaunch.h>
|
||||||
|
#include <minecraft/launch/LauncherPartLaunch.h>
|
||||||
#include <Env.h>
|
#include <Env.h>
|
||||||
|
|
||||||
#include "OneSixInstance.h"
|
#include "OneSixInstance.h"
|
||||||
@ -22,14 +24,7 @@
|
|||||||
|
|
||||||
#include "minecraft/MinecraftProfile.h"
|
#include "minecraft/MinecraftProfile.h"
|
||||||
#include "minecraft/VersionBuildError.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 "minecraft/launch/ModMinecraftJar.h"
|
||||||
#include "java/launch/CheckJava.h"
|
|
||||||
#include "MMCZip.h"
|
#include "MMCZip.h"
|
||||||
|
|
||||||
#include "minecraft/AssetsUtils.h"
|
#include "minecraft/AssetsUtils.h"
|
||||||
@ -94,7 +89,7 @@ QString replaceTokensIn(QString text, QMap<QString, QString> with)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
|
QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) const
|
||||||
{
|
{
|
||||||
QString args_pattern = m_profile->getMinecraftArguments();
|
QString args_pattern = m_profile->getMinecraftArguments();
|
||||||
for (auto tweaker : m_profile->getTweakers())
|
for (auto tweaker : m_profile->getTweakers())
|
||||||
@ -104,11 +99,16 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
|
|||||||
|
|
||||||
QMap<QString, QString> token_mapping;
|
QMap<QString, QString> token_mapping;
|
||||||
// yggdrasil!
|
// yggdrasil!
|
||||||
token_mapping["auth_username"] = session->username;
|
if(session)
|
||||||
token_mapping["auth_session"] = session->session;
|
{
|
||||||
token_mapping["auth_access_token"] = session->access_token;
|
token_mapping["auth_username"] = session->username;
|
||||||
token_mapping["auth_player_name"] = session->player_name;
|
token_mapping["auth_session"] = session->session;
|
||||||
token_mapping["auth_uuid"] = session->uuid;
|
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.
|
// blatant self-promotion.
|
||||||
token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
|
token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
|
||||||
@ -127,9 +127,6 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
|
|||||||
auto assets = m_profile->getMinecraftAssets();
|
auto assets = m_profile->getMinecraftAssets();
|
||||||
token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
|
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
|
// 1.7.3+ assets tokens
|
||||||
token_mapping["assets_root"] = absAssetsDir;
|
token_mapping["assets_root"] = absAssetsDir;
|
||||||
token_mapping["assets_index_name"] = assets->id;
|
token_mapping["assets_index_name"] = assets->id;
|
||||||
@ -142,6 +139,26 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
|
|||||||
return parts;
|
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 OneSixInstance::createLaunchScript(AuthSessionPtr session)
|
||||||
{
|
{
|
||||||
QString launchScript;
|
QString launchScript;
|
||||||
@ -149,34 +166,7 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
if (!m_profile)
|
if (!m_profile)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
for(auto & mod: loaderModList()->allMods())
|
auto mainClass = getMainClass();
|
||||||
{
|
|
||||||
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();
|
|
||||||
if (!mainClass.isEmpty())
|
if (!mainClass.isEmpty())
|
||||||
{
|
{
|
||||||
launchScript += "mainClass " + mainClass + "\n";
|
launchScript += "mainClass " + mainClass + "\n";
|
||||||
@ -207,6 +197,7 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// legacy auth
|
// legacy auth
|
||||||
|
if(session)
|
||||||
{
|
{
|
||||||
launchScript += "userName " + session->player_name + "\n";
|
launchScript += "userName " + session->player_name + "\n";
|
||||||
launchScript += "sessionId " + session->session + "\n";
|
launchScript += "sessionId " + session->session + "\n";
|
||||||
@ -214,44 +205,21 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
|
|
||||||
// libraries and class path.
|
// libraries and class path.
|
||||||
{
|
{
|
||||||
auto libs = m_profile->getLibraries();
|
QStringList jars, nativeJars;
|
||||||
|
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
|
||||||
QStringList jar, native, native32, native64;
|
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars);
|
||||||
for (auto lib : libs)
|
for(auto file: jars)
|
||||||
{
|
|
||||||
lib->getApplicableFiles(currentSystem, jar, native, native32, native64);
|
|
||||||
}
|
|
||||||
for(auto file: jar)
|
|
||||||
{
|
{
|
||||||
launchScript += "cp " + file + "\n";
|
launchScript += "cp " + file + "\n";
|
||||||
}
|
}
|
||||||
for(auto file: native)
|
launchScript += "cp " + mainJarPath() + "\n";
|
||||||
|
for(auto file: nativeJars)
|
||||||
{
|
{
|
||||||
launchScript += "ext " + file + "\n";
|
launchScript += "ext " + file + "\n";
|
||||||
}
|
}
|
||||||
for(auto file: native32)
|
launchScript += "natives " + getNativePath() + "\n";
|
||||||
{
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// traits. including legacyLaunch and others ;)
|
|
||||||
for (auto trait : m_profile->getTraits())
|
for (auto trait : m_profile->getTraits())
|
||||||
{
|
{
|
||||||
launchScript += "traits " + trait + "\n";
|
launchScript += "traits " + trait + "\n";
|
||||||
@ -260,58 +228,139 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
|
|||||||
return launchScript;
|
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()));
|
QStringList out;
|
||||||
auto pptr = process.get();
|
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);
|
out << "Libraries:";
|
||||||
process->appendStep(step);
|
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());
|
step->setWorkingDirectory(minecraftRoot());
|
||||||
process->appendStep(step);
|
return step;
|
||||||
}
|
}
|
||||||
// if we aren't in offline mode,.
|
else if (method == "DirectJava")
|
||||||
if(session->status != AuthSession::PlayableOffline)
|
|
||||||
{
|
{
|
||||||
process->appendStep(std::make_shared<Update>(pptr));
|
auto step = std::make_shared<DirectJavaLaunch>(parent);
|
||||||
}
|
|
||||||
// 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->setWorkingDirectory(minecraftRoot());
|
||||||
step->setAuthSession(session);
|
step->setAuthSession(session);
|
||||||
process->appendStep(step);
|
return step;
|
||||||
}
|
}
|
||||||
// run post-exit command if that's needed
|
return nullptr;
|
||||||
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> OneSixInstance::createJarModdingTask()
|
std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
|
||||||
{
|
{
|
||||||
class JarModTask : public Task
|
class JarModTask : public Task
|
||||||
@ -595,3 +644,30 @@ QString OneSixInstance::typeName() const
|
|||||||
{
|
{
|
||||||
return tr("OneSix");
|
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;
|
||||||
|
}
|
||||||
|
@ -53,10 +53,9 @@ public:
|
|||||||
virtual QString instanceConfigFolder() const override;
|
virtual QString instanceConfigFolder() const override;
|
||||||
|
|
||||||
virtual std::shared_ptr<Task> createUpdateTask() 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 std::shared_ptr<Task> createJarModdingTask() override;
|
||||||
|
|
||||||
virtual QString createLaunchScript(AuthSessionPtr session) override;
|
virtual QString createLaunchScript(AuthSessionPtr session) override;
|
||||||
|
QStringList verboseDescription(AuthSessionPtr session) override;
|
||||||
|
|
||||||
virtual void cleanupAfterRun() override;
|
virtual void cleanupAfterRun() override;
|
||||||
|
|
||||||
@ -99,11 +98,23 @@ public:
|
|||||||
return true;
|
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:
|
signals:
|
||||||
void versionReloaded();
|
void versionReloaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList processMinecraftArgs(AuthSessionPtr account);
|
QString mainJarPath() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<MinecraftProfile> m_profile;
|
std::shared_ptr<MinecraftProfile> m_profile;
|
||||||
|
@ -524,11 +524,15 @@ void MultiMC::initGlobalSettings(bool test_mode)
|
|||||||
// Java Settings
|
// Java Settings
|
||||||
m_settings->registerSetting("JavaPath", "");
|
m_settings->registerSetting("JavaPath", "");
|
||||||
m_settings->registerSetting("JavaTimestamp", 0);
|
m_settings->registerSetting("JavaTimestamp", 0);
|
||||||
|
m_settings->registerSetting("JavaArchitecture", "");
|
||||||
m_settings->registerSetting("JavaVersion", "");
|
m_settings->registerSetting("JavaVersion", "");
|
||||||
m_settings->registerSetting("LastHostname", "");
|
m_settings->registerSetting("LastHostname", "");
|
||||||
m_settings->registerSetting("JavaDetectionHack", "");
|
m_settings->registerSetting("JavaDetectionHack", "");
|
||||||
m_settings->registerSetting("JvmArgs", "");
|
m_settings->registerSetting("JvmArgs", "");
|
||||||
|
|
||||||
|
// Minecraft launch method
|
||||||
|
m_settings->registerSetting("MCLaunchMethod", "LauncherPart");
|
||||||
|
|
||||||
// Wrapper command for launch
|
// Wrapper command for launch
|
||||||
m_settings->registerSetting("WrapperCommand", "");
|
m_settings->registerSetting("WrapperCommand", "");
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ set(SRC
|
|||||||
# legacy applet wrapper thing.
|
# legacy applet wrapper thing.
|
||||||
# The launcher has to be there for silly FML/Forge relauncher.
|
# The launcher has to be there for silly FML/Forge relauncher.
|
||||||
net/minecraft/Launcher.java
|
net/minecraft/Launcher.java
|
||||||
org/multimc/legacy/LegacyLauncher.java
|
|
||||||
org/multimc/LegacyFrame.java
|
org/multimc/LegacyFrame.java
|
||||||
|
|
||||||
# onesix launcher
|
# onesix launcher
|
||||||
|
@ -14,7 +14,6 @@ package org.multimc;/*
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.multimc.legacy.LegacyLauncher;
|
|
||||||
import org.multimc.onesix.OneSixLauncher;
|
import org.multimc.onesix.OneSixLauncher;
|
||||||
import org.simplericity.macify.eawt.Application;
|
import org.simplericity.macify.eawt.Application;
|
||||||
import org.simplericity.macify.eawt.DefaultApplication;
|
import org.simplericity.macify.eawt.DefaultApplication;
|
||||||
@ -83,13 +82,6 @@ public class EntryPoint
|
|||||||
|
|
||||||
if(command.equals("launcher"))
|
if(command.equals("launcher"))
|
||||||
{
|
{
|
||||||
if(param.equals("legacy"))
|
|
||||||
{
|
|
||||||
m_launcher = new LegacyLauncher();
|
|
||||||
Utils.log("Using legacy launcher.");
|
|
||||||
Utils.log();
|
|
||||||
return Action.Proceed;
|
|
||||||
}
|
|
||||||
if(param.equals("onesix"))
|
if(param.equals("onesix"))
|
||||||
{
|
{
|
||||||
m_launcher = new OneSixLauncher();
|
m_launcher = new OneSixLauncher();
|
||||||
|
@ -186,95 +186,5 @@ public class Utils
|
|||||||
{
|
{
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Pushes bytes from in to out. Closes both streams no matter what.
|
|
||||||
* @param in the input stream
|
|
||||||
* @param out the output stream
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private static void copyStream(InputStream in, OutputStream out) throws IOException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
while((len = in.read(buffer)) >= 0)
|
|
||||||
out.write(buffer, 0, len);
|
|
||||||
} finally
|
|
||||||
{
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace a 'target' string 'suffix' with 'replacement'
|
|
||||||
*/
|
|
||||||
public static String replaceSuffix (String target, String suffix, String replacement)
|
|
||||||
{
|
|
||||||
if (!target.endsWith(suffix))
|
|
||||||
{
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
String prefix = target.substring(0, target.length() - suffix.length());
|
|
||||||
return prefix + replacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unzip zip file with natives 'source' into the folder 'targetFolder'
|
|
||||||
*
|
|
||||||
* Contains a hack for OSX. Yay.
|
|
||||||
* @param source
|
|
||||||
* @param targetFolder
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static void unzipNatives(File source, File targetFolder) throws IOException
|
|
||||||
{
|
|
||||||
ZipFile zip = new ZipFile(source);
|
|
||||||
|
|
||||||
boolean applyHacks = false;
|
|
||||||
String[] javaVersionElements = System.getProperty("java.version").split("[.\\-+]");
|
|
||||||
int major = Integer.parseInt(javaVersionElements[0]);
|
|
||||||
if(major == 1)
|
|
||||||
{
|
|
||||||
major = Integer.parseInt(javaVersionElements[1]);
|
|
||||||
}
|
|
||||||
if (major >= 8)
|
|
||||||
{
|
|
||||||
applyHacks = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Enumeration entries = zip.entries();
|
|
||||||
|
|
||||||
while (entries.hasMoreElements())
|
|
||||||
{
|
|
||||||
ZipEntry entry = (ZipEntry) entries.nextElement();
|
|
||||||
|
|
||||||
String entryName = entry.getName();
|
|
||||||
String fileName = entryName;
|
|
||||||
if(applyHacks)
|
|
||||||
{
|
|
||||||
fileName = replaceSuffix(entryName, ".jnilib", ".dylib");
|
|
||||||
}
|
|
||||||
File targetFile = new File(targetFolder, fileName);
|
|
||||||
if (targetFile.getParentFile() != null)
|
|
||||||
{
|
|
||||||
targetFile.getParentFile().mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.isDirectory())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
copyStream(zip.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(targetFile)));
|
|
||||||
}
|
|
||||||
} finally
|
|
||||||
{
|
|
||||||
zip.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,175 +0,0 @@
|
|||||||
package org.multimc.legacy;/*
|
|
||||||
* Copyright 2012-2014 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.multimc.*;
|
|
||||||
|
|
||||||
import java.applet.Applet;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
|
|
||||||
public class LegacyLauncher implements Launcher
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int launch(ParamBucket params)
|
|
||||||
{
|
|
||||||
String userName, sessionId, windowTitle, windowParams, lwjgl;
|
|
||||||
String mainClass = "net.minecraft.client.Minecraft";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
userName = params.first("userName");
|
|
||||||
sessionId = params.first("sessionId");
|
|
||||||
windowTitle = params.first("windowTitle");
|
|
||||||
windowParams = params.first("windowParams");
|
|
||||||
lwjgl = params.first("lwjgl");
|
|
||||||
} catch (NotFoundException e)
|
|
||||||
{
|
|
||||||
System.err.println("Not enough arguments.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
String cwd = System.getProperty("user.dir");
|
|
||||||
Dimension winSize = new Dimension(854, 480);
|
|
||||||
boolean maximize = false;
|
|
||||||
|
|
||||||
String[] dimStrings = windowParams.split("x");
|
|
||||||
|
|
||||||
if (windowParams.equalsIgnoreCase("max"))
|
|
||||||
{
|
|
||||||
maximize = true;
|
|
||||||
}
|
|
||||||
else if (dimStrings.length == 2)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
winSize = new Dimension(Integer.parseInt(dimStrings[0]), Integer.parseInt(dimStrings[1]));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
File binDir = new File(cwd, "bin");
|
|
||||||
File lwjglDir;
|
|
||||||
if (lwjgl.equalsIgnoreCase("Mojang"))
|
|
||||||
{
|
|
||||||
lwjglDir = binDir;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lwjglDir = new File(lwjgl);
|
|
||||||
}
|
|
||||||
|
|
||||||
URL[] classpath;
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
classpath = new URL[]
|
|
||||||
{
|
|
||||||
new File(binDir, "minecraft.jar").toURI().toURL(),
|
|
||||||
new File(lwjglDir, "lwjgl.jar").toURI().toURL(),
|
|
||||||
new File(lwjglDir, "lwjgl_util.jar").toURI().toURL(),
|
|
||||||
new File(lwjglDir, "jinput.jar").toURI().toURL(),
|
|
||||||
};
|
|
||||||
} catch (MalformedURLException e)
|
|
||||||
{
|
|
||||||
System.err.println("Class path entry is badly formed:");
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String nativesDir = new File(lwjglDir, "natives").toString();
|
|
||||||
|
|
||||||
System.setProperty("org.lwjgl.librarypath", nativesDir);
|
|
||||||
System.setProperty("net.java.games.input.librarypath", nativesDir);
|
|
||||||
|
|
||||||
// print the pretty things
|
|
||||||
{
|
|
||||||
Utils.log("Main Class:");
|
|
||||||
Utils.log(" " + mainClass);
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
Utils.log("Class Path:");
|
|
||||||
for (URL s : classpath)
|
|
||||||
{
|
|
||||||
Utils.log(" " + s);
|
|
||||||
}
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
Utils.log("Native Path:");
|
|
||||||
Utils.log(" " + nativesDir);
|
|
||||||
Utils.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
URLClassLoader cl = new URLClassLoader(classpath, LegacyLauncher.class.getClassLoader());
|
|
||||||
|
|
||||||
// Get the Minecraft Class and set the base folder
|
|
||||||
Class<?> mc;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mc = cl.loadClass(mainClass);
|
|
||||||
|
|
||||||
Field f = Utils.getMCPathField(mc);
|
|
||||||
|
|
||||||
if (f == null)
|
|
||||||
{
|
|
||||||
System.err.println("Could not find Minecraft path field. Launch failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
f.setAccessible(true);
|
|
||||||
f.set(null, new File(cwd));
|
|
||||||
} catch (Exception e)
|
|
||||||
{
|
|
||||||
System.err.println("Could not set base folder. Failed to find/access Minecraft main class:");
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("minecraft.applet.TargetDirectory", cwd);
|
|
||||||
|
|
||||||
String[] mcArgs = new String[2];
|
|
||||||
mcArgs[0] = userName;
|
|
||||||
mcArgs[1] = sessionId;
|
|
||||||
|
|
||||||
Utils.log("Launching with applet wrapper...");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class<?> MCAppletClass = cl.loadClass("net.minecraft.client.MinecraftApplet");
|
|
||||||
Applet mcappl = (Applet) MCAppletClass.newInstance();
|
|
||||||
LegacyFrame mcWindow = new LegacyFrame(windowTitle);
|
|
||||||
mcWindow.start(mcappl, userName, sessionId, winSize, maximize);
|
|
||||||
} catch (Exception e)
|
|
||||||
{
|
|
||||||
Utils.log("Applet wrapper failed:", "Error");
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
Utils.log();
|
|
||||||
Utils.log("Falling back to compatibility mode.");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mc.getMethod("main", String[].class).invoke(null, (Object) mcArgs);
|
|
||||||
} catch (Exception e1)
|
|
||||||
{
|
|
||||||
Utils.log("Failed to invoke the Minecraft main class:", "Fatal");
|
|
||||||
e1.printStackTrace(System.err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -30,9 +30,6 @@ public class OneSixLauncher implements Launcher
|
|||||||
{
|
{
|
||||||
// parameters, separated from ParamBucket
|
// parameters, separated from ParamBucket
|
||||||
private List<String> libraries;
|
private List<String> libraries;
|
||||||
private List<String> extlibs;
|
|
||||||
private List<String> extlibs32;
|
|
||||||
private List<String> extlibs64;
|
|
||||||
private List<String> mcparams;
|
private List<String> mcparams;
|
||||||
private List<String> mods;
|
private List<String> mods;
|
||||||
private List<String> jarmods;
|
private List<String> jarmods;
|
||||||
@ -56,28 +53,9 @@ public class OneSixLauncher implements Launcher
|
|||||||
private void processParams(ParamBucket params) throws NotFoundException
|
private void processParams(ParamBucket params) throws NotFoundException
|
||||||
{
|
{
|
||||||
libraries = params.all("cp");
|
libraries = params.all("cp");
|
||||||
extlibs = params.allSafe("ext", new ArrayList<String>());
|
|
||||||
extlibs32 = params.allSafe("ext32", new ArrayList<String>());
|
|
||||||
extlibs64 = params.allSafe("ext64", new ArrayList<String>());
|
|
||||||
|
|
||||||
// Unify the extracted native libs according to actual system architecture
|
|
||||||
String property = System.getProperty("os.arch");
|
|
||||||
boolean is_64 = property.equalsIgnoreCase("x86_64") || property.equalsIgnoreCase("amd64");
|
|
||||||
if(is_64)
|
|
||||||
{
|
|
||||||
extlibs.addAll(extlibs64);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
extlibs.addAll(extlibs32);
|
|
||||||
}
|
|
||||||
|
|
||||||
mcparams = params.allSafe("param", new ArrayList<String>() );
|
mcparams = params.allSafe("param", new ArrayList<String>() );
|
||||||
mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft");
|
mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft");
|
||||||
appletClass = params.firstSafe("appletClass", "net.minecraft.client.MinecraftApplet");
|
appletClass = params.firstSafe("appletClass", "net.minecraft.client.MinecraftApplet");
|
||||||
mods = params.allSafe("mod", new ArrayList<String>());
|
|
||||||
jarmods = params.allSafe("jarmod", new ArrayList<String>());
|
|
||||||
coremods = params.allSafe("coremod", new ArrayList<String>());
|
|
||||||
traits = params.allSafe("traits", new ArrayList<String>());
|
traits = params.allSafe("traits", new ArrayList<String>());
|
||||||
nativePath = params.first("natives");
|
nativePath = params.first("natives");
|
||||||
|
|
||||||
@ -105,75 +83,6 @@ public class OneSixLauncher implements Launcher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printStats()
|
|
||||||
{
|
|
||||||
Utils.log("Main Class:");
|
|
||||||
Utils.log(" " + mainClass);
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
Utils.log("Native path:");
|
|
||||||
Utils.log(" " + nativePath);
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
Utils.log("Traits:");
|
|
||||||
Utils.log(" " + traits);
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
Utils.log("Libraries:");
|
|
||||||
for (String s : libraries)
|
|
||||||
{
|
|
||||||
File f = new File(s);
|
|
||||||
if (f.exists())
|
|
||||||
{
|
|
||||||
Utils.log(" " + s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Utils.log(" " + s + " (missing)", "Warning");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
if(mods.size() > 0)
|
|
||||||
{
|
|
||||||
Utils.log("Mods:");
|
|
||||||
for (String s : mods)
|
|
||||||
{
|
|
||||||
Utils.log(" " + s);
|
|
||||||
}
|
|
||||||
Utils.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(coremods.size() > 0)
|
|
||||||
{
|
|
||||||
Utils.log("Core Mods:");
|
|
||||||
for (String s : coremods)
|
|
||||||
{
|
|
||||||
Utils.log(" " + s);
|
|
||||||
}
|
|
||||||
Utils.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(jarmods.size() > 0)
|
|
||||||
{
|
|
||||||
Utils.log("Jar Mods:");
|
|
||||||
for (String s : jarmods)
|
|
||||||
{
|
|
||||||
Utils.log(" " + s);
|
|
||||||
}
|
|
||||||
Utils.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.log("Params:");
|
|
||||||
Utils.log(" " + mcparams.toString());
|
|
||||||
Utils.log();
|
|
||||||
if(maximize)
|
|
||||||
Utils.log("Window size: max (if available)");
|
|
||||||
else
|
|
||||||
Utils.log("Window size: " + Integer.toString(winSize.width) + " x " + Integer.toString(winSize.height));
|
|
||||||
Utils.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
int legacyLaunch()
|
int legacyLaunch()
|
||||||
{
|
{
|
||||||
// Get the Minecraft Class and set the base folder
|
// Get the Minecraft Class and set the base folder
|
||||||
@ -310,27 +219,6 @@ public class OneSixLauncher implements Launcher
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the pretty things
|
|
||||||
printStats();
|
|
||||||
|
|
||||||
// extract native libs (depending on platform here... java!)
|
|
||||||
Utils.log("Preparing native libraries...");
|
|
||||||
for(String extlib: extlibs)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File extlibf = new File(extlib);
|
|
||||||
Utils.log("Extracting " + extlibf.getName());
|
|
||||||
Utils.unzipNatives(extlibf, new File(nativePath));
|
|
||||||
} catch (IOException e)
|
|
||||||
{
|
|
||||||
System.err.println("Failed to extract native library:");
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Utils.log();
|
|
||||||
|
|
||||||
// set the native libs path... the brute force way
|
// set the native libs path... the brute force way
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -68,6 +68,7 @@ void WonkoClient::initGlobalSettings()
|
|||||||
// Java Settings
|
// Java Settings
|
||||||
m_settings->registerSetting("JavaPath", "");
|
m_settings->registerSetting("JavaPath", "");
|
||||||
m_settings->registerSetting("JavaTimestamp", 0);
|
m_settings->registerSetting("JavaTimestamp", 0);
|
||||||
|
m_settings->registerSetting("JavaArchitecture", "");
|
||||||
m_settings->registerSetting("JavaVersion", "");
|
m_settings->registerSetting("JavaVersion", "");
|
||||||
m_settings->registerSetting("LastHostname", "");
|
m_settings->registerSetting("LastHostname", "");
|
||||||
m_settings->registerSetting("JavaDetectionHack", "");
|
m_settings->registerSetting("JavaDetectionHack", "");
|
||||||
@ -79,4 +80,7 @@ void WonkoClient::initGlobalSettings()
|
|||||||
// Custom Commands
|
// Custom Commands
|
||||||
m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, "");
|
m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, "");
|
||||||
m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, "");
|
m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, "");
|
||||||
|
|
||||||
|
// Minecraft launch method
|
||||||
|
m_settings->registerSetting("MCLaunchMethod", "LauncherPart");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user