NOISSUE implement direct java launch
Just running the Java process and giving it params on the command line
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -87,4 +87,10 @@ public: | ||||
| 	{ | ||||
| 		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) | ||||
| { | ||||
| 	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) | ||||
|   | ||||
| @@ -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; | ||||
| }; | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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); | ||||
| }; | ||||
|   | ||||
| @@ -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"); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
							
								
								
									
										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. | ||||
|  */ | ||||
| 
 | ||||
| #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) | ||||
| 	{ | ||||
| @@ -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; | ||||
| }; | ||||
							
								
								
									
										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 <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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -524,11 +524,15 @@ void MultiMC::initGlobalSettings(bool test_mode) | ||||
| 	// Java Settings | ||||
| 	m_settings->registerSetting("JavaPath", ""); | ||||
| 	m_settings->registerSetting("JavaTimestamp", 0); | ||||
| 	m_settings->registerSetting("JavaArchitecture", ""); | ||||
| 	m_settings->registerSetting("JavaVersion", ""); | ||||
| 	m_settings->registerSetting("LastHostname", ""); | ||||
| 	m_settings->registerSetting("JavaDetectionHack", ""); | ||||
| 	m_settings->registerSetting("JvmArgs", ""); | ||||
|  | ||||
| 	// Minecraft launch method | ||||
| 	m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); | ||||
|  | ||||
| 	// Wrapper command for launch | ||||
| 	m_settings->registerSetting("WrapperCommand", ""); | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,6 @@ set(SRC | ||||
| 	# legacy applet wrapper thing. | ||||
| 	# The launcher has to be there for silly FML/Forge relauncher. | ||||
| 	net/minecraft/Launcher.java | ||||
| 	org/multimc/legacy/LegacyLauncher.java | ||||
| 	org/multimc/LegacyFrame.java | ||||
|  | ||||
| 	# onesix launcher | ||||
|   | ||||
| @@ -14,7 +14,6 @@ package org.multimc;/* | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| import org.multimc.legacy.LegacyLauncher; | ||||
| import org.multimc.onesix.OneSixLauncher; | ||||
| import org.simplericity.macify.eawt.Application; | ||||
| import org.simplericity.macify.eawt.DefaultApplication; | ||||
| @@ -83,13 +82,6 @@ public class EntryPoint | ||||
|  | ||||
| 		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")) | ||||
| 			{ | ||||
| 				m_launcher = new OneSixLauncher(); | ||||
|   | ||||
| @@ -186,95 +186,5 @@ public class Utils | ||||
| 	{ | ||||
| 		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 | ||||
| 	private List<String> libraries; | ||||
| 	private List<String> extlibs; | ||||
| 	private List<String> extlibs32; | ||||
| 	private List<String> extlibs64; | ||||
| 	private List<String> mcparams; | ||||
| 	private List<String> mods; | ||||
| 	private List<String> jarmods; | ||||
| @@ -56,28 +53,9 @@ public class OneSixLauncher implements Launcher | ||||
| 	private void processParams(ParamBucket params) throws NotFoundException | ||||
| 	{ | ||||
| 		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>() ); | ||||
| 		mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft"); | ||||
| 		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>()); | ||||
| 		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() | ||||
| 	{ | ||||
| 		// Get the Minecraft Class and set the base folder | ||||
| @@ -310,27 +219,6 @@ public class OneSixLauncher implements Launcher | ||||
| 			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 | ||||
| 		try | ||||
| 		{ | ||||
|   | ||||
| @@ -68,6 +68,7 @@ void WonkoClient::initGlobalSettings() | ||||
|     // Java Settings | ||||
|     m_settings->registerSetting("JavaPath", ""); | ||||
|     m_settings->registerSetting("JavaTimestamp", 0); | ||||
|     m_settings->registerSetting("JavaArchitecture", ""); | ||||
|     m_settings->registerSetting("JavaVersion", ""); | ||||
|     m_settings->registerSetting("LastHostname", ""); | ||||
|     m_settings->registerSetting("JavaDetectionHack", ""); | ||||
| @@ -79,4 +80,7 @@ void WonkoClient::initGlobalSettings() | ||||
|     // Custom Commands | ||||
|     m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, ""); | ||||
|     m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, ""); | ||||
|  | ||||
|     // Minecraft launch method | ||||
|     m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user