Fix offline mode bugs
This commit is contained in:
		| @@ -791,16 +791,13 @@ void MainWindow::doLaunch() | ||||
| 		progDialog.exec(task.get()); | ||||
|  | ||||
| 		auto status = account->accountStatus(); | ||||
| 		if(status == Online) // Online mode! Refresh the token. | ||||
| 		if(status != NotVerified) | ||||
| 		{ | ||||
| 			updateInstance(m_selectedInstance, account); | ||||
| 			return; | ||||
| 		} | ||||
| 		else if(status == Verified) // Offline mode with a verified account | ||||
| 		{ | ||||
| 			launchInstance(m_selectedInstance, account); | ||||
| 			return; | ||||
| 		} | ||||
| 		// revert from online to verified. | ||||
| 		account->downgrade(); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (loginWithPassword(account, tr("Your account is currently not logged in. Please enter your password to log in again."))) | ||||
| 		updateInstance(m_selectedInstance, account); | ||||
| @@ -828,7 +825,8 @@ bool MainWindow::loginWithPassword(MojangAccountPtr account, const QString& erro | ||||
|  | ||||
| void MainWindow::updateInstance(BaseInstance* instance, MojangAccountPtr account) | ||||
| { | ||||
| 	auto updateTask = instance->doUpdate(true); | ||||
| 	bool only_prepare = account->accountStatus() != Online; | ||||
| 	auto updateTask = instance->doUpdate(only_prepare); | ||||
| 	if (!updateTask) | ||||
| 	{ | ||||
| 		launchInstance(instance, account); | ||||
|   | ||||
| @@ -150,7 +150,7 @@ public: | ||||
| 	virtual SettingsObject &settings() const; | ||||
|  | ||||
| 	/// returns a valid update task if update is needed, NULL otherwise | ||||
| 	virtual std::shared_ptr<Task> doUpdate(bool prepare_for_launch) = 0; | ||||
| 	virtual std::shared_ptr<Task> doUpdate(bool only_prepare) = 0; | ||||
|  | ||||
| 	/// returns a valid minecraft process, ready for launch with the given account. | ||||
| 	virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) = 0; | ||||
|   | ||||
| @@ -44,12 +44,12 @@ LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, | ||||
| 	settings->registerSetting(new Setting("IntendedJarVersion", "")); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<Task> LegacyInstance::doUpdate(bool prepare_for_launch) | ||||
| std::shared_ptr<Task> LegacyInstance::doUpdate(bool only_prepare) | ||||
| { | ||||
| 	// make sure the jar mods list is initialized by asking for it. | ||||
| 	auto list = jarModList(); | ||||
| 	// create an update task | ||||
| 	return std::shared_ptr<Task> (new LegacyUpdate(this, prepare_for_launch , this)); | ||||
| 	return std::shared_ptr<Task> (new LegacyUpdate(this, only_prepare , this)); | ||||
| } | ||||
|  | ||||
| MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account) | ||||
|   | ||||
| @@ -76,7 +76,7 @@ public: | ||||
|  | ||||
| 	virtual bool shouldUpdate() const override; | ||||
| 	virtual void setShouldUpdate(bool val) override; | ||||
| 	virtual std::shared_ptr<Task> doUpdate(bool prepare_for_launch) override; | ||||
| 	virtual std::shared_ptr<Task> doUpdate(bool only_prepare) override; | ||||
|  | ||||
| 	virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override; | ||||
| 	virtual void cleanupAfterRun() override; | ||||
|   | ||||
| @@ -26,14 +26,30 @@ | ||||
| #include <JlCompress.h> | ||||
| #include "logger/QsLog.h" | ||||
|  | ||||
| LegacyUpdate::LegacyUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent) | ||||
| 	: Task(parent), m_inst(inst), m_prepare_for_launch(prepare_for_launch) | ||||
| LegacyUpdate::LegacyUpdate(BaseInstance *inst, bool only_prepare, QObject *parent) | ||||
| 	: Task(parent), m_inst(inst), m_only_prepare(only_prepare) | ||||
| { | ||||
| } | ||||
|  | ||||
| void LegacyUpdate::executeTask() | ||||
| { | ||||
| 	lwjglStart(); | ||||
| 	if(m_only_prepare) | ||||
| 	{ | ||||
| 		// FIXME: think this through some more. | ||||
| 		LegacyInstance *inst = (LegacyInstance *)m_inst; | ||||
| 		if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar()) | ||||
| 		{ | ||||
| 			ModTheJar(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			emitSucceeded(); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		lwjglStart(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void LegacyUpdate::lwjglStart() | ||||
|   | ||||
| @@ -31,7 +31,7 @@ class LegacyUpdate : public Task | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	explicit LegacyUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent = 0); | ||||
| 	explicit LegacyUpdate(BaseInstance *inst, bool only_prepare, QObject *parent = 0); | ||||
| 	virtual void executeTask(); | ||||
|  | ||||
| private | ||||
| @@ -72,5 +72,5 @@ private: | ||||
| private: | ||||
| 	NetJobPtr legacyDownloadJob; | ||||
| 	BaseInstance *m_inst = nullptr; | ||||
| 	bool m_prepare_for_launch = false; | ||||
| 	bool m_only_prepare = false; | ||||
| }; | ||||
|   | ||||
| @@ -37,9 +37,9 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o | ||||
| 	reloadFullVersion(); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<Task> OneSixInstance::doUpdate(bool prepare_for_launch) | ||||
| std::shared_ptr<Task> OneSixInstance::doUpdate(bool only_prepare) | ||||
| { | ||||
| 	return std::shared_ptr<Task> (new OneSixUpdate(this, prepare_for_launch)); | ||||
| 	return std::shared_ptr<Task> (new OneSixUpdate(this, only_prepare)); | ||||
| } | ||||
|  | ||||
| QString replaceTokensIn(QString text, QMap<QString, QString> with) | ||||
|   | ||||
| @@ -39,7 +39,7 @@ public: | ||||
| 	QString loaderModsDir() const; | ||||
| 	virtual QString instanceConfigFolder() const override; | ||||
|  | ||||
| 	virtual std::shared_ptr<Task> doUpdate(bool prepare_for_launch) override; | ||||
| 	virtual std::shared_ptr<Task> doUpdate(bool only_prepare) override; | ||||
| 	virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override; | ||||
|  | ||||
| 	virtual void cleanupAfterRun() override; | ||||
|   | ||||
| @@ -33,8 +33,8 @@ | ||||
| #include "pathutils.h" | ||||
| #include <JlCompress.h> | ||||
|  | ||||
| OneSixUpdate::OneSixUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent) | ||||
| 	: Task(parent), m_inst(inst), m_prepare_for_launch(prepare_for_launch) | ||||
| OneSixUpdate::OneSixUpdate(BaseInstance *inst, bool only_prepare, QObject *parent) | ||||
| 	: Task(parent), m_inst(inst), m_only_prepare(only_prepare) | ||||
| { | ||||
| } | ||||
|  | ||||
| @@ -50,6 +50,23 @@ void OneSixUpdate::executeTask() | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if(m_only_prepare) | ||||
| 	{ | ||||
| 		if (m_inst->shouldUpdate()) | ||||
| 		{ | ||||
| 			emitFailed("Unable to update instance in offline mode."); | ||||
| 			return; | ||||
| 		} | ||||
| 		setStatus("Testing the Java installation."); | ||||
| 		QString java_path = m_inst->settings().get("JavaPath").toString(); | ||||
|  | ||||
| 		checker.reset(new JavaChecker()); | ||||
| 		connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, | ||||
| 				SLOT(checkFinishedOffline(JavaCheckResult))); | ||||
| 		checker->performCheck(java_path); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (m_inst->shouldUpdate()) | ||||
| 	{ | ||||
| 		// Get a pointer to the version object that corresponds to the instance's version. | ||||
| @@ -65,35 +82,43 @@ void OneSixUpdate::executeTask() | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		checkJava(); | ||||
| 		checkJavaOnline(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void OneSixUpdate::checkJava() | ||||
| void OneSixUpdate::checkJavaOnline() | ||||
| { | ||||
| 	QLOG_INFO() << m_inst->name() << ": checking java binary"; | ||||
| 	setStatus("Testing the Java installation."); | ||||
| 	// TODO: cache this so we don't have to run an extra java process every time. | ||||
| 	QString java_path = m_inst->settings().get("JavaPath").toString(); | ||||
|  | ||||
| 	checker.reset(new JavaChecker()); | ||||
| 	connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, | ||||
| 			SLOT(checkFinished(JavaCheckResult))); | ||||
| 		SLOT(checkFinishedOnline(JavaCheckResult))); | ||||
| 	checker->performCheck(java_path); | ||||
| } | ||||
|  | ||||
| void OneSixUpdate::checkFinished(JavaCheckResult result) | ||||
| void OneSixUpdate::checkFinishedOnline(JavaCheckResult result) | ||||
| { | ||||
| 	if (result.valid) | ||||
| 	{ | ||||
| 		QLOG_INFO() << m_inst->name() << ": java is " | ||||
| 					<< (result.is_64bit ? "64 bit" : "32 bit"); | ||||
| 		java_is_64bit = result.is_64bit; | ||||
| 		jarlibStart(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		QLOG_INFO() << m_inst->name() << ": java isn't valid"; | ||||
| 		emitFailed("The java binary doesn't work. Check the settings and correct the problem"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void OneSixUpdate::checkFinishedOffline(JavaCheckResult result) | ||||
| { | ||||
| 	if (result.valid) | ||||
| 	{ | ||||
| 		java_is_64bit = result.is_64bit; | ||||
| 		prepareForLaunch(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		emitFailed("The java binary doesn't work. Check the settings and correct the problem"); | ||||
| 	} | ||||
| } | ||||
| @@ -160,7 +185,7 @@ void OneSixUpdate::versionFileFinished() | ||||
| 	} | ||||
| 	inst->reloadFullVersion(); | ||||
|  | ||||
| 	checkJava(); | ||||
| 	checkJavaOnline(); | ||||
| } | ||||
|  | ||||
| void OneSixUpdate::versionFileFailed() | ||||
| @@ -240,10 +265,7 @@ void OneSixUpdate::jarlibStart() | ||||
|  | ||||
| void OneSixUpdate::jarlibFinished() | ||||
| { | ||||
| 	if (m_prepare_for_launch) | ||||
| 		prepareForLaunch(); | ||||
| 	else | ||||
| 		emitSucceeded(); | ||||
| 	prepareForLaunch(); | ||||
| } | ||||
|  | ||||
| void OneSixUpdate::jarlibFailed() | ||||
|   | ||||
| @@ -43,8 +43,9 @@ slots: | ||||
| 	void jarlibFinished(); | ||||
| 	void jarlibFailed(); | ||||
|  | ||||
| 	void checkJava(); | ||||
| 	void checkFinished(JavaCheckResult result); | ||||
| 	void checkJavaOnline(); | ||||
| 	void checkFinishedOnline(JavaCheckResult result); | ||||
| 	void checkFinishedOffline(JavaCheckResult result); | ||||
|  | ||||
| 	// extract the appropriate libraries | ||||
| 	void prepareForLaunch(); | ||||
| @@ -56,7 +57,7 @@ private: | ||||
| 	// target version, determined during this task | ||||
| 	std::shared_ptr<MinecraftVersion> targetVersion; | ||||
| 	BaseInstance *m_inst = nullptr; | ||||
| 	bool m_prepare_for_launch = false; | ||||
| 	bool m_only_prepare = false; | ||||
| 	std::shared_ptr<JavaChecker> checker; | ||||
|  | ||||
| 	bool java_is_64bit = false; | ||||
|   | ||||
| @@ -97,6 +97,10 @@ public: /* manipulation */ | ||||
| 	 */ | ||||
| 	std::shared_ptr<Task> login(QString password = QString()); | ||||
|  | ||||
| 	void downgrade() | ||||
| 	{ | ||||
| 		m_online = false; | ||||
| 	} | ||||
| public: /* queries */ | ||||
| 	const QString &username() const | ||||
| 	{ | ||||
|   | ||||
| @@ -78,7 +78,9 @@ void YggdrasilTask::processReply() | ||||
| { | ||||
| 	setStatus(getStateMessage(STATE_PROCESSING_RESPONSE)); | ||||
|  | ||||
| 	if (m_netReply->error() == QNetworkReply::OperationCanceledError) | ||||
| 	// any network errors lead to offline mode right now | ||||
| 	if (m_netReply->error() >= QNetworkReply::ConnectionRefusedError && | ||||
| 		m_netReply->error() <= QNetworkReply::UnknownNetworkError) | ||||
| 	{ | ||||
| 		// WARNING/FIXME: the value here is used in MojangAccount to detect the cancel/timeout | ||||
| 		emitFailed("Yggdrasil task cancelled."); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user