From b0dbd4f4afcf60e4021cbb3218bfe280c4989859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 8 Dec 2013 22:06:04 +0100 Subject: [PATCH] Fix offline mode bugs --- gui/MainWindow.cpp | 14 ++++------ logic/BaseInstance.h | 2 +- logic/LegacyInstance.cpp | 4 +-- logic/LegacyInstance.h | 2 +- logic/LegacyUpdate.cpp | 22 +++++++++++++-- logic/LegacyUpdate.h | 4 +-- logic/OneSixInstance.cpp | 4 +-- logic/OneSixInstance.h | 2 +- logic/OneSixUpdate.cpp | 54 +++++++++++++++++++++++++----------- logic/OneSixUpdate.h | 7 +++-- logic/auth/MojangAccount.h | 4 +++ logic/auth/YggdrasilTask.cpp | 4 ++- 12 files changed, 83 insertions(+), 40 deletions(-) diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index fd35e94e..bf2ce6b4 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -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); diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index 603f6105..93e57414 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -150,7 +150,7 @@ public: virtual SettingsObject &settings() const; /// returns a valid update task if update is needed, NULL otherwise - virtual std::shared_ptr doUpdate(bool prepare_for_launch) = 0; + virtual std::shared_ptr doUpdate(bool only_prepare) = 0; /// returns a valid minecraft process, ready for launch with the given account. virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) = 0; diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 55523048..fef27bcd 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -44,12 +44,12 @@ LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, settings->registerSetting(new Setting("IntendedJarVersion", "")); } -std::shared_ptr LegacyInstance::doUpdate(bool prepare_for_launch) +std::shared_ptr 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 (new LegacyUpdate(this, prepare_for_launch , this)); + return std::shared_ptr (new LegacyUpdate(this, only_prepare , this)); } MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account) diff --git a/logic/LegacyInstance.h b/logic/LegacyInstance.h index 948d4be4..1e7d9eb6 100644 --- a/logic/LegacyInstance.h +++ b/logic/LegacyInstance.h @@ -76,7 +76,7 @@ public: virtual bool shouldUpdate() const override; virtual void setShouldUpdate(bool val) override; - virtual std::shared_ptr doUpdate(bool prepare_for_launch) override; + virtual std::shared_ptr doUpdate(bool only_prepare) override; virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override; virtual void cleanupAfterRun() override; diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index 3fc17351..6125101b 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -26,14 +26,30 @@ #include #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() diff --git a/logic/LegacyUpdate.h b/logic/LegacyUpdate.h index d753197f..0b573ca5 100644 --- a/logic/LegacyUpdate.h +++ b/logic/LegacyUpdate.h @@ -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; }; diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 7a1d7dad..b18dd2ba 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -37,9 +37,9 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o reloadFullVersion(); } -std::shared_ptr OneSixInstance::doUpdate(bool prepare_for_launch) +std::shared_ptr OneSixInstance::doUpdate(bool only_prepare) { - return std::shared_ptr (new OneSixUpdate(this, prepare_for_launch)); + return std::shared_ptr (new OneSixUpdate(this, only_prepare)); } QString replaceTokensIn(QString text, QMap with) diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h index 7ea2d08b..cdfdf324 100644 --- a/logic/OneSixInstance.h +++ b/logic/OneSixInstance.h @@ -39,7 +39,7 @@ public: QString loaderModsDir() const; virtual QString instanceConfigFolder() const override; - virtual std::shared_ptr doUpdate(bool prepare_for_launch) override; + virtual std::shared_ptr doUpdate(bool only_prepare) override; virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override; virtual void cleanupAfterRun() override; diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index 25e16328..7be0c056 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -33,8 +33,8 @@ #include "pathutils.h" #include -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() diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h index 5fd2c59f..7ff9d881 100644 --- a/logic/OneSixUpdate.h +++ b/logic/OneSixUpdate.h @@ -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 targetVersion; BaseInstance *m_inst = nullptr; - bool m_prepare_for_launch = false; + bool m_only_prepare = false; std::shared_ptr checker; bool java_is_64bit = false; diff --git a/logic/auth/MojangAccount.h b/logic/auth/MojangAccount.h index 8c44ce58..95f777ce 100644 --- a/logic/auth/MojangAccount.h +++ b/logic/auth/MojangAccount.h @@ -97,6 +97,10 @@ public: /* manipulation */ */ std::shared_ptr login(QString password = QString()); + void downgrade() + { + m_online = false; + } public: /* queries */ const QString &username() const { diff --git a/logic/auth/YggdrasilTask.cpp b/logic/auth/YggdrasilTask.cpp index 6b938ea7..45155058 100644 --- a/logic/auth/YggdrasilTask.cpp +++ b/logic/auth/YggdrasilTask.cpp @@ -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.");