Fix offline mode bugs

This commit is contained in:
Petr Mrázek 2013-12-08 22:06:04 +01:00
parent 9410dd042e
commit b0dbd4f4af
12 changed files with 83 additions and 40 deletions

View File

@ -791,17 +791,14 @@ void MainWindow::doLaunch()
progDialog.exec(task.get()); progDialog.exec(task.get());
auto status = account->accountStatus(); auto status = account->accountStatus();
if(status == Online) // Online mode! Refresh the token. if(status != NotVerified)
{ {
updateInstance(m_selectedInstance, account); updateInstance(m_selectedInstance, account);
return;
} }
else if(status == Verified) // Offline mode with a verified account // revert from online to verified.
{ account->downgrade();
launchInstance(m_selectedInstance, account);
return; return;
} }
}
if (loginWithPassword(account, tr("Your account is currently not logged in. Please enter your password to log in again."))) if (loginWithPassword(account, tr("Your account is currently not logged in. Please enter your password to log in again.")))
updateInstance(m_selectedInstance, account); updateInstance(m_selectedInstance, account);
} }
@ -828,7 +825,8 @@ bool MainWindow::loginWithPassword(MojangAccountPtr account, const QString& erro
void MainWindow::updateInstance(BaseInstance* instance, MojangAccountPtr account) 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) if (!updateTask)
{ {
launchInstance(instance, account); launchInstance(instance, account);

View File

@ -150,7 +150,7 @@ public:
virtual SettingsObject &settings() const; virtual SettingsObject &settings() const;
/// returns a valid update task if update is needed, NULL otherwise /// 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. /// returns a valid minecraft process, ready for launch with the given account.
virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) = 0; virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) = 0;

View File

@ -44,12 +44,12 @@ LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings,
settings->registerSetting(new Setting("IntendedJarVersion", "")); 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. // make sure the jar mods list is initialized by asking for it.
auto list = jarModList(); auto list = jarModList();
// create an update task // 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) MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)

View File

@ -76,7 +76,7 @@ public:
virtual bool shouldUpdate() const override; virtual bool shouldUpdate() const override;
virtual void setShouldUpdate(bool val) override; virtual void setShouldUpdate(bool val) override;
virtual std::shared_ptr<Task> doUpdate(bool prepare_for_launch) override; virtual std::shared_ptr<Task> doUpdate(bool only_prepare) override;
virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override; virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override;
virtual void cleanupAfterRun() override; virtual void cleanupAfterRun() override;

View File

@ -26,14 +26,30 @@
#include <JlCompress.h> #include <JlCompress.h>
#include "logger/QsLog.h" #include "logger/QsLog.h"
LegacyUpdate::LegacyUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent) LegacyUpdate::LegacyUpdate(BaseInstance *inst, bool only_prepare, QObject *parent)
: Task(parent), m_inst(inst), m_prepare_for_launch(prepare_for_launch) : Task(parent), m_inst(inst), m_only_prepare(only_prepare)
{ {
} }
void LegacyUpdate::executeTask() void LegacyUpdate::executeTask()
{ {
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(); lwjglStart();
}
} }
void LegacyUpdate::lwjglStart() void LegacyUpdate::lwjglStart()

View File

@ -31,7 +31,7 @@ class LegacyUpdate : public Task
{ {
Q_OBJECT Q_OBJECT
public: 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(); virtual void executeTask();
private private
@ -72,5 +72,5 @@ private:
private: private:
NetJobPtr legacyDownloadJob; NetJobPtr legacyDownloadJob;
BaseInstance *m_inst = nullptr; BaseInstance *m_inst = nullptr;
bool m_prepare_for_launch = false; bool m_only_prepare = false;
}; };

View File

@ -37,9 +37,9 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o
reloadFullVersion(); 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) QString replaceTokensIn(QString text, QMap<QString, QString> with)

View File

@ -39,7 +39,7 @@ public:
QString loaderModsDir() const; QString loaderModsDir() const;
virtual QString instanceConfigFolder() const override; 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 MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override;
virtual void cleanupAfterRun() override; virtual void cleanupAfterRun() override;

View File

@ -33,8 +33,8 @@
#include "pathutils.h" #include "pathutils.h"
#include <JlCompress.h> #include <JlCompress.h>
OneSixUpdate::OneSixUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent) OneSixUpdate::OneSixUpdate(BaseInstance *inst, bool only_prepare, QObject *parent)
: Task(parent), m_inst(inst), m_prepare_for_launch(prepare_for_launch) : Task(parent), m_inst(inst), m_only_prepare(only_prepare)
{ {
} }
@ -50,6 +50,23 @@ void OneSixUpdate::executeTask()
return; 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()) if (m_inst->shouldUpdate())
{ {
// Get a pointer to the version object that corresponds to the instance's version. // Get a pointer to the version object that corresponds to the instance's version.
@ -65,35 +82,43 @@ void OneSixUpdate::executeTask()
} }
else else
{ {
checkJava(); checkJavaOnline();
} }
} }
void OneSixUpdate::checkJava() void OneSixUpdate::checkJavaOnline()
{ {
QLOG_INFO() << m_inst->name() << ": checking java binary";
setStatus("Testing the Java installation."); 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(); QString java_path = m_inst->settings().get("JavaPath").toString();
checker.reset(new JavaChecker()); checker.reset(new JavaChecker());
connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
SLOT(checkFinished(JavaCheckResult))); SLOT(checkFinishedOnline(JavaCheckResult)));
checker->performCheck(java_path); checker->performCheck(java_path);
} }
void OneSixUpdate::checkFinished(JavaCheckResult result) void OneSixUpdate::checkFinishedOnline(JavaCheckResult result)
{ {
if (result.valid) if (result.valid)
{ {
QLOG_INFO() << m_inst->name() << ": java is "
<< (result.is_64bit ? "64 bit" : "32 bit");
java_is_64bit = result.is_64bit; java_is_64bit = result.is_64bit;
jarlibStart(); jarlibStart();
} }
else 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"); emitFailed("The java binary doesn't work. Check the settings and correct the problem");
} }
} }
@ -160,7 +185,7 @@ void OneSixUpdate::versionFileFinished()
} }
inst->reloadFullVersion(); inst->reloadFullVersion();
checkJava(); checkJavaOnline();
} }
void OneSixUpdate::versionFileFailed() void OneSixUpdate::versionFileFailed()
@ -240,10 +265,7 @@ void OneSixUpdate::jarlibStart()
void OneSixUpdate::jarlibFinished() void OneSixUpdate::jarlibFinished()
{ {
if (m_prepare_for_launch)
prepareForLaunch(); prepareForLaunch();
else
emitSucceeded();
} }
void OneSixUpdate::jarlibFailed() void OneSixUpdate::jarlibFailed()

View File

@ -43,8 +43,9 @@ slots:
void jarlibFinished(); void jarlibFinished();
void jarlibFailed(); void jarlibFailed();
void checkJava(); void checkJavaOnline();
void checkFinished(JavaCheckResult result); void checkFinishedOnline(JavaCheckResult result);
void checkFinishedOffline(JavaCheckResult result);
// extract the appropriate libraries // extract the appropriate libraries
void prepareForLaunch(); void prepareForLaunch();
@ -56,7 +57,7 @@ private:
// target version, determined during this task // target version, determined during this task
std::shared_ptr<MinecraftVersion> targetVersion; std::shared_ptr<MinecraftVersion> targetVersion;
BaseInstance *m_inst = nullptr; BaseInstance *m_inst = nullptr;
bool m_prepare_for_launch = false; bool m_only_prepare = false;
std::shared_ptr<JavaChecker> checker; std::shared_ptr<JavaChecker> checker;
bool java_is_64bit = false; bool java_is_64bit = false;

View File

@ -97,6 +97,10 @@ public: /* manipulation */
*/ */
std::shared_ptr<Task> login(QString password = QString()); std::shared_ptr<Task> login(QString password = QString());
void downgrade()
{
m_online = false;
}
public: /* queries */ public: /* queries */
const QString &username() const const QString &username() const
{ {

View File

@ -78,7 +78,9 @@ void YggdrasilTask::processReply()
{ {
setStatus(getStateMessage(STATE_PROCESSING_RESPONSE)); 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 // WARNING/FIXME: the value here is used in MojangAccount to detect the cancel/timeout
emitFailed("Yggdrasil task cancelled."); emitFailed("Yggdrasil task cancelled.");