diff options
| author | Petr Mrázek <peterix@gmail.com> | 2016-08-14 02:33:31 +0200 |
|---|---|---|
| committer | Petr Mrázek <peterix@gmail.com> | 2016-08-14 23:22:54 +0200 |
| commit | 042f3ef55c0b469f438542152c4eb02b0789ea3c (patch) | |
| tree | 03e0c15b200786558babd0fe58edac88ed1bfd1e | |
| parent | 2f0441b3c1cd9fc3bcb176d2852da8f92a6e6777 (diff) | |
| download | PrismLauncher-042f3ef55c0b469f438542152c4eb02b0789ea3c.tar.gz PrismLauncher-042f3ef55c0b469f438542152c4eb02b0789ea3c.tar.bz2 PrismLauncher-042f3ef55c0b469f438542152c4eb02b0789ea3c.zip | |
GH-352 Make OneSix instance update downloads cancellable
32 files changed, 773 insertions, 337 deletions
diff --git a/api/logic/BaseInstance.h b/api/logic/BaseInstance.h index 9a6976cb..ebaaeb83 100644 --- a/api/logic/BaseInstance.h +++ b/api/logic/BaseInstance.h @@ -16,6 +16,7 @@ #pragma once #include <QObject> +#include "QObjectPtr.h" #include <QDateTime> #include <QSet> #include <QProcess> @@ -152,7 +153,7 @@ public: virtual SettingsObjectPtr settings() const; /// returns a valid update task - virtual std::shared_ptr<Task> createUpdateTask() = 0; + virtual shared_qobject_ptr<Task> createUpdateTask() = 0; /// returns a valid launcher (task container) virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0; diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index 4514d8c3..415584fc 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -200,6 +200,14 @@ set(MINECRAFT_SOURCES minecraft/onesix/OneSixProfileStrategy.h minecraft/onesix/OneSixVersionFormat.cpp minecraft/onesix/OneSixVersionFormat.h + minecraft/onesix/update/AssetUpdateTask.h + minecraft/onesix/update/AssetUpdateTask.cpp + minecraft/onesix/update/FMLLibrariesTask.cpp + minecraft/onesix/update/FMLLibrariesTask.h + minecraft/onesix/update/FoldersTask.cpp + minecraft/onesix/update/FoldersTask.h + minecraft/onesix/update/LibrariesTask.cpp + minecraft/onesix/update/LibrariesTask.h minecraft/launch/CreateServerResourcePacksFolder.cpp minecraft/launch/CreateServerResourcePacksFolder.h minecraft/launch/ModMinecraftJar.cpp diff --git a/api/logic/NullInstance.h b/api/logic/NullInstance.h index d87fb6f7..4fb31854 100644 --- a/api/logic/NullInstance.h +++ b/api/logic/NullInstance.h @@ -48,7 +48,7 @@ public: { return nullptr; } - virtual std::shared_ptr< Task > createUpdateTask() override + virtual shared_qobject_ptr< Task > createUpdateTask() override { return nullptr; } diff --git a/api/logic/QObjectPtr.h b/api/logic/QObjectPtr.h index b81b3234..000d228d 100644 --- a/api/logic/QObjectPtr.h +++ b/api/logic/QObjectPtr.h @@ -48,6 +48,10 @@ public: using namespace std::placeholders; m_ptr.reset(wrap, std::bind(&QObject::deleteLater, _1)); } + void reset(const shared_qobject_ptr<T> &other) + { + m_ptr = other.m_ptr; + } void reset() { m_ptr.reset(); diff --git a/api/logic/launch/steps/Update.cpp b/api/logic/launch/steps/Update.cpp index 4901f001..ad0c4fc4 100644 --- a/api/logic/launch/steps/Update.cpp +++ b/api/logic/launch/steps/Update.cpp @@ -18,7 +18,12 @@ void Update::executeTask() { - m_updateTask = m_parent->instance()->createUpdateTask(); + if(m_aborted) + { + emitFailed(tr("Task aborted.")); + return; + } + m_updateTask.reset(m_parent->instance()->createUpdateTask()); if(m_updateTask) { connect(m_updateTask.get(), SIGNAL(finished()), this, SLOT(updateFinished())); @@ -39,12 +44,37 @@ void Update::updateFinished() { if(m_updateTask->successful()) { + m_updateTask.reset(); emitSucceeded(); } else { QString reason = tr("Instance update failed because: %1.\n\n").arg(m_updateTask->failReason()); + m_updateTask.reset(); emit logLine(reason, MessageLevel::Fatal); emitFailed(reason); } } + +bool Update::canAbort() const +{ + if(m_updateTask) + { + return m_updateTask->canAbort(); + } + return true; +} + + +bool Update::abort() +{ + m_aborted = true; + if(m_updateTask) + { + if(m_updateTask->canAbort()) + { + return m_updateTask->abort(); + } + } + return true; +} diff --git a/api/logic/launch/steps/Update.h b/api/logic/launch/steps/Update.h index 14928253..1739de47 100644 --- a/api/logic/launch/steps/Update.h +++ b/api/logic/launch/steps/Update.h @@ -16,6 +16,7 @@ #pragma once #include <launch/LaunchStep.h> +#include <QObjectPtr.h> #include <launch/LoggedProcess.h> #include <java/JavaChecker.h> @@ -27,15 +28,16 @@ public: explicit Update(LaunchTask *parent):LaunchStep(parent) {}; virtual ~Update() {}; - virtual void executeTask(); - virtual bool canAbort() const - { - return false; - } - virtual void proceed(); + void executeTask() override; + bool canAbort() const override; + void proceed() override; +public slots: + bool abort() override; + private slots: void updateFinished(); private: - std::shared_ptr<Task> m_updateTask; + shared_qobject_ptr<Task> m_updateTask; + bool m_aborted = false; }; diff --git a/api/logic/minecraft/MinecraftVersionList.cpp b/api/logic/minecraft/MinecraftVersionList.cpp index 4e4eafbc..e3f416d9 100644 --- a/api/logic/minecraft/MinecraftVersionList.cpp +++ b/api/logic/minecraft/MinecraftVersionList.cpp @@ -61,6 +61,10 @@ public: explicit MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr<MinecraftVersion> updatedVersion); virtual ~MCVListVersionUpdateTask() override{}; virtual void executeTask() override; + bool canAbort() const override; + +public slots: + bool abort() override; protected slots: @@ -71,6 +75,7 @@ protected: QByteArray versionIndexData; std::shared_ptr<MinecraftVersion> updatedVersion; MinecraftVersionList *m_list; + bool m_aborted = false; }; class ListLoadError : public Exception @@ -410,6 +415,11 @@ MCVListVersionUpdateTask::MCVListVersionUpdateTask(MinecraftVersionList *vlist, void MCVListVersionUpdateTask::executeTask() { + if(m_aborted) + { + emitFailed(tr("Task aborted.")); + return; + } auto job = new NetJob("Version index"); job->addNetAction(Net::Download::makeByteArray(QUrl(updatedVersion->getUrl()), &versionIndexData)); specificVersionDownloadJob.reset(job); @@ -419,6 +429,21 @@ void MCVListVersionUpdateTask::executeTask() specificVersionDownloadJob->start(); } +bool MCVListVersionUpdateTask::canAbort() const +{ + return true; +} + +bool MCVListVersionUpdateTask::abort() +{ + m_aborted = true; + if(specificVersionDownloadJob) + { + return specificVersionDownloadJob->abort(); + } + return true; +} + void MCVListVersionUpdateTask::json_downloaded() { specificVersionDownloadJob.reset(); diff --git a/api/logic/minecraft/forge/ForgeXzDownload.cpp b/api/logic/minecraft/forge/ForgeXzDownload.cpp index adf96552..8b762866 100644 --- a/api/logic/minecraft/forge/ForgeXzDownload.cpp +++ b/api/logic/minecraft/forge/ForgeXzDownload.cpp @@ -35,6 +35,12 @@ ForgeXzDownload::ForgeXzDownload(QString relative_path, MetaEntryPtr entry) : Ne void ForgeXzDownload::start() { + if(m_status == Job_Aborted) + { + qWarning() << "Attempt to start an aborted Download:" << m_url.toString(); + emit aborted(m_index_within_job); + return; + } m_status = Job_InProgress; if (!m_entry->isStale()) { @@ -76,9 +82,17 @@ void ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error) { - // error happened during download. - // TODO: log the reason why - m_status = Job_Failed; + if(error == QNetworkReply::OperationCanceledError) + { + qCritical() << "Aborted " << m_url.toString(); + m_status = Job_Aborted; + } + else + { + // error happened during download. + qCritical() << "Failed " << m_url.toString() << " with reason " << error; + m_status = Job_Failed; + } } void ForgeXzDownload::failAndTryNextMirror() @@ -90,7 +104,7 @@ void ForgeXzDownload::failAndTryNextMirror() void ForgeXzDownload::downloadFinished() { // if the download succeeded - if (m_status != Job_Failed) + if (m_status != Job_Failed && m_status != Job_Aborted) { // nothing went wrong... m_status = Job_Finished; @@ -110,6 +124,14 @@ void ForgeXzDownload::downloadFinished() return; } } + else if(m_status == Job_Aborted) + { + m_pack200_xz_file.remove(); + m_reply.reset(); + emit failed(m_index_within_job); + emit aborted(m_index_within_job); + return; + } // else the download failed else { @@ -147,6 +169,7 @@ void ForgeXzDownload::downloadReadyRead() const size_t buffer_size = 8196; +// NOTE: once this gets here, it can't be aborted anymore. we don't care. void ForgeXzDownload::decompressAndInstall() { // rewind the downloaded temp file @@ -356,3 +379,16 @@ void ForgeXzDownload::decompressAndInstall() m_reply.reset(); emit succeeded(m_index_within_job); } + +bool ForgeXzDownload::abort() +{ + if(m_reply) + m_reply->abort(); + m_status = Job_Aborted; + return true; +} + +bool ForgeXzDownload::canAbort() +{ + return true; +} diff --git a/api/logic/minecraft/forge/ForgeXzDownload.h b/api/logic/minecraft/forge/ForgeXzDownload.h index 67524405..e51ff9e5 100644 --- a/api/logic/minecraft/forge/ForgeXzDownload.h +++ b/api/logic/minecraft/forge/ForgeXzDownload.h @@ -41,17 +41,19 @@ public: return ForgeXzDownloadPtr(new ForgeXzDownload(relative_path, entry)); } virtual ~ForgeXzDownload(){}; + bool canAbort() override; protected slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead(); + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; + void downloadError(QNetworkReply::NetworkError error) override; + void downloadFinished() override; + void downloadReadyRead() override; public slots: - virtual void start(); + void start() override; + bool abort() override; private: void decompressAndInstall(); diff --git a/api/logic/minecraft/ftb/OneSixFTBInstance.cpp b/api/logic/minecraft/ftb/OneSixFTBInstance.cpp index 81e939a1..5edad080 100644 --- a/api/logic/minecraft/ftb/OneSixFTBInstance.cpp +++ b/api/logic/minecraft/ftb/OneSixFTBInstance.cpp @@ -125,7 +125,7 @@ void OneSixFTBInstance::createProfile() m_profile.reset(new MinecraftProfile(new FTBProfileStrategy(this))); } -std::shared_ptr<Task> OneSixFTBInstance::createUpdateTask() +shared_qobject_ptr<Task> OneSixFTBInstance::createUpdateTask() { return OneSixInstance::createUpdateTask(); } diff --git a/api/logic/minecraft/ftb/OneSixFTBInstance.h b/api/logic/minecraft/ftb/OneSixFTBInstance.h index e7f8f485..a5621685 100644 --- a/api/logic/minecraft/ftb/OneSixFTBInstance.h +++ b/api/logic/minecraft/ftb/OneSixFTBInstance.h @@ -13,7 +13,7 @@ public: virtual void createProfile() override; - virtual std::shared_ptr<Task> createUpdateTask() override; + virtual shared_qobject_ptr<Task> createUpdateTask() override; virtual QString id() const override; diff --git a/api/logic/minecraft/legacy/LegacyInstance.cpp b/api/logic/minecraft/legacy/LegacyInstance.cpp index 7c552369..7ed2041c 100644 --- a/api/logic/minecraft/legacy/LegacyInstance.cpp +++ b/api/logic/minecraft/legacy/LegacyInstance.cpp @@ -87,12 +87,12 @@ bool LegacyInstance::shouldUseCustomBaseJar() const } -std::shared_ptr<Task> LegacyInstance::createUpdateTask() +shared_qobject_ptr<Task> LegacyInstance::createUpdateTask() { // 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, this)); + return shared_qobject_ptr<Task>(new LegacyUpdate(this, this)); } std::shared_ptr<Task> LegacyInstance::createJarModdingTask() diff --git a/api/logic/minecraft/legacy/LegacyInstance.h b/api/logic/minecraft/legacy/LegacyInstance.h index f1cefbcc..1d95340b 100644 --- a/api/logic/minecraft/legacy/LegacyInstance.h +++ b/api/logic/minecraft/legacy/LegacyInstance.h @@ -113,7 +113,7 @@ public: virtual bool shouldUpdate() const override; virtual void setShouldUpdate(bool val) override; - virtual std::shared_ptr<Task> createUpdateTask() override; + virtual shared_qobject_ptr<Task> createUpdateTask() override; virtual std::shared_ptr<Task> createJarModdingTask() override; virtual QString createLaunchScript(AuthSessionPtr session) override; diff --git a/api/logic/minecraft/onesix/OneSixInstance.cpp b/api/logic/minecraft/onesix/OneSixInstance.cpp index 8b5491e2..1bf75bdb 100644 --- a/api/logic/minecraft/onesix/OneSixInstance.cpp +++ b/api/logic/minecraft/onesix/OneSixInstance.cpp @@ -60,9 +60,9 @@ QSet<QString> OneSixInstance::traits() } } -std::shared_ptr<Task> OneSixInstance::createUpdateTask() +shared_qobject_ptr<Task> OneSixInstance::createUpdateTask() { - return std::shared_ptr<Task>(new OneSixUpdate(this)); + return shared_qobject_ptr<Task>(new OneSixUpdate(this)); } QString replaceTokensIn(QString text, QMap<QString, QString> with) diff --git a/api/logic/minecraft/onesix/OneSixInstance.h b/api/logic/minecraft/onesix/OneSixInstance.h index 1a917e79..c857075f 100644 --- a/api/logic/minecraft/onesix/OneSixInstance.h +++ b/api/logic/minecraft/onesix/OneSixInstance.h @@ -52,7 +52,7 @@ public: QString worldDir() const; virtual QString instanceConfigFolder() const override; - virtual std::shared_ptr<Task> createUpdateTask() override; + virtual shared_qobject_ptr<Task> createUpdateTask() override; virtual std::shared_ptr<Task> createJarModdingTask() override; virtual QString createLaunchScript(AuthSessionPtr session) override; QStringList verboseDescription(AuthSessionPtr session) override; diff --git a/api/logic/minecraft/onesix/OneSixUpdate.cpp b/api/logic/minecraft/onesix/OneSixUpdate.cpp index d3cd197d..02a6f561 100644 --- a/api/logic/minecraft/onesix/OneSixUpdate.cpp +++ b/api/logic/minecraft/onesix/OneSixUpdate.cpp @@ -18,332 +18,138 @@ #include "OneSixUpdate.h" #include "OneSixInstance.h" -#include <QtNetwork> - #include <QFile> #include <QFileInfo> #include <QTextStream> #include <QDataStream> -#include <JlCompress.h> #include "BaseInstance.h" #include "minecraft/MinecraftVersionList.h" #include "minecraft/MinecraftProfile.h" #include "minecraft/Library.h" #include "net/URLConstants.h" -#include "net/ChecksumValidator.h" -#include "minecraft/AssetsUtils.h" -#include "Exception.h" -#include "MMCZip.h" #include <FileSystem.h> -OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst) -{ -} +#include "update/FoldersTask.h" +#include "update/LibrariesTask.h" +#include "update/FMLLibrariesTask.h" +#include "update/AssetUpdateTask.h" -void OneSixUpdate::executeTask() +OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst) { - // Make directories - QDir mcDir(m_inst->minecraftRoot()); - if (!mcDir.exists() && !mcDir.mkpath(".")) + // create folders { - emitFailed(tr("Failed to create folder for minecraft binaries.")); - return; + m_tasks.append(std::make_shared<FoldersTask>(m_inst)); } - // Get a pointer to the version object that corresponds to the instance's version. - targetVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", m_inst->intendedVersionId())); - if (targetVersion == nullptr) - { - // don't do anything if it was invalid - emitFailed(tr("The specified Minecraft version is invalid. Choose a different one.")); - return; - } - if (m_inst->providesVersionFile() || !targetVersion->needsUpdate()) + // add a version update task, if necessary { - qDebug() << "Instance either provides a version file or doesn't need an update."; - jarlibStart(); - return; + auto list = std::dynamic_pointer_cast<MinecraftVersionList>(ENV.getVersionList("net.minecraft")); + auto version = std::dynamic_pointer_cast<MinecraftVersion>(list->findVersion(m_inst->intendedVersionId())); + if (version == nullptr) + { + // don't do anything if it was invalid + m_preFailure = tr("The specified Minecraft version is invalid. Choose a different one."); + } + else if (m_inst->providesVersionFile() || !version->needsUpdate()) + { + qDebug() << "Instance either provides a version file or doesn't need an update."; + } + else + { + auto versionUpdateTask = list->createUpdateTask(m_inst->intendedVersionId()); + if (!versionUpdateTask) + { + qDebug() << "Didn't spawn an update task."; + } + else + { + m_tasks.append(versionUpdateTask); + } + } } - versionUpdateTask = std::dynamic_pointer_cast<MinecraftVersionList>(ENV.getVersionList("net.minecraft"))->createUpdateTask(m_inst->intendedVersionId()); - if (!versionUpdateTask) + + // libraries download { - qDebug() << "Didn't spawn an update task."; - jarlibStart(); - return; + m_tasks.append(std::make_shared<LibrariesTask>(m_inst)); } - connect(versionUpdateTask.get(), SIGNAL(succeeded()), SLOT(jarlibStart())); - connect(versionUpdateTask.get(), &NetJob::failed, this, &OneSixUpdate::versionUpdateFailed); - connect(versionUpdateTask.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); - setStatus(tr("Getting the version files from Mojang...")); - versionUpdateTask->start(); -} -void OneSixUpdate::versionUpdateFailed(QString reason) -{ - emitFailed(reason); -} - -void OneSixUpdate::assetIndexStart() -{ - setStatus(tr("Updating assets index...")); - OneSixInstance *inst = (OneSixInstance *)m_inst; - auto profile = inst->getMinecraftProfile(); - auto assets = profile->getMinecraftAssets(); - QUrl indexUrl = assets->url; - QString localPath = assets->id + ".json"; - auto job = new NetJob(tr("Asset index for %1").arg(inst->name())); - - auto metacache = ENV.metacache(); - auto entry = metacache->resolveEntry("asset_indexes", localPath); - entry->setStale(true); - auto hexSha1 = assets->sha1.toLatin1(); - qDebug() << "Asset index SHA1:" << hexSha1; - auto dl = Net::Download::makeCached(indexUrl, entry); - auto rawSha1 = QByteArray::fromHex(assets->sha1.toLatin1()); - dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); - job->addNetAction(dl); - - jarlibDownloadJob.reset(job); - - connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetIndexFinished())); - connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetIndexFailed); - connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); - - qDebug() << m_inst->name() << ": Starting asset index download"; - jarlibDownloadJob->start(); -} - -void OneSixUpdate::assetIndexFinished() -{ - AssetsIndex index; - qDebug() << m_inst->name() << ": Finished asset index download"; - - OneSixInstance *inst = (OneSixInstance *)m_inst; - auto profile = inst->getMinecraftProfile(); - auto assets = profile->getMinecraftAssets(); - - QString asset_fname = "assets/indexes/" + assets->id + ".json"; - // FIXME: this looks like a job for a generic validator based on json schema? - if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, &index)) + // FML libraries download and copy into the instance { - auto metacache = ENV.metacache(); - auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json"); - metacache->evictEntry(entry); - emitFailed(tr("Failed to read the assets index!")); + m_tasks.append(std::make_shared<FMLLibrariesTask>(m_inst)); } - auto job = index.getDownloadJob(); - if(job) + // assets update { - setStatus(tr("Getting the assets files from Mojang...")); - jarlibDownloadJob = job; - connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished())); - connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetsFailed); - connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); - jarlibDownloadJob->start(); - return; + m_tasks.append(std::make_shared<AssetUpdateTask>(m_inst)); } - assetsFinished(); -} - -void OneSixUpdate::assetIndexFailed(QString reason) -{ - qDebug() << m_inst->name() << ": Failed asset index download"; - emitFailed(tr("Failed to download the assets index:\n%1").arg(reason)); -} - -void OneSixUpdate::assetsFinished() -{ - emitSucceeded(); -} - -void OneSixUpdate::assetsFailed(QString reason) -{ - emitFailed(tr("Failed to download assets:\n%1").arg(reason)); } -void OneSixUpdate::jarlibStart() +void OneSixUpdate::executeTask() { - setStatus(tr("Getting the library files from Mojang...")); - qDebug() << m_inst->name() << ": downloading libraries"; - OneSixInstance *inst = (OneSixInstance *)m_inst; - inst->reloadProfile(); - if(inst->flags() & BaseInstance::VersionBrokenFlag) + if(!m_preFailure.isEmpty()) { - emitFailed(tr("Failed to load the version description files - check the instance for errors.")); + emitFailed(m_preFailure); return; } + next(); +} - // Build a list of URLs that will need to be downloaded. - std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile(); - // minecraft.jar for this version +void OneSixUpdate::next() +{ + if(m_abort) { - QString version_id = profile->getMinecraftVersion(); - QString localPath = version_id + "/" + version_id + ".jar"; - QString urlstr = profile->getMainJarUrl(); - - auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name())); - - auto metacache = ENV.metacache(); - auto entry = metacache->resolveEntry("versions", localPath); - job->addNetAction(Net::Download::makeCached(QUrl(urlstr), entry)); - jarlibDownloadJob.reset(job); + emitFailed(tr("Aborted by user.")); + return; } - - auto libs = profile->getLibraries(); - - auto metacache = ENV.metacache(); - QList<LibraryPtr> brokenLocalLibs; - - QStringList failedFiles; - for (auto lib : libs) + m_currentTask ++; + if(m_currentTask > 0) { - auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles); - for(auto dl : dls) - { - jarlibDownloadJob->addNetAction(dl); - } + auto task = m_tasks[m_currentTask - 1]; + disconnect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded); + disconnect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed); + disconnect(task.get(), &Task::progress, this, &OneSixUpdate::progress); + disconnect(task.get(), &Task::status, this, &OneSixUpdate::setStatus); } - if (!brokenLocalLibs.empty()) + if(m_currentTask == m_tasks.size()) { - jarlibDownloadJob.reset(); - - QString failed_all = failedFiles.join("\n"); - emitFailed(tr("Some libraries marked as 'local' are missing their jar " - "files:\n%1\n\nYou'll have to correct this problem manually. If this is " - "an externally tracked instance, make sure to run it at least once " - "outside of MultiMC.").arg(failed_all)); + emitSucceeded(); return; } - - connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished())); - connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::jarlibFailed); - connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), - SIGNAL(progress(qint64, qint64))); - - jarlibDownloadJob->start(); + auto task = m_tasks[m_currentTask]; + connect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded); + connect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed); + connect(task.get(), &Task::progress, this, &OneSixUpdate::progress); + connect(task.get(), &Task::status, this, &OneSixUpdate::setStatus); + task->start(); } -void OneSixUpdate::jarlibFinished() +void OneSixUpdate::subtaskSucceeded() { - OneSixInstance *inst = (OneSixInstance *)m_inst; - std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile(); - - if (profile->hasTrait("legacyFML")) - { - fmllibsStart(); - } - else - { - assetIndexStart(); - } + next(); } -void OneSixUpdate::jarlibFailed(QString reason) +void OneSixUpdate::subtaskFailed(QString error) { - QStringList failed = jarlibDownloadJob->getFailedFiles(); - QString failed_all = failed.join("\n"); - emitFailed( - tr("Failed to download the following files:\n%1\n\nReason:%2\nPlease try again.").arg(failed_all, reason)); + emitFailed(error); } -void OneSixUpdate::fmllibsStart() -{ - // Get the mod list - OneSixInstance *inst = (OneSixInstance *)m_inst; - std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile(); - bool forge_present = false; - - QString version = inst->intendedVersionId(); - auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping; - if (!fmlLibsMapping.contains(version)) - { - assetIndexStart(); - return; - } - - auto &libList = fmlLibsMapping[version]; - - // determine if we need some libs for FML or forge - setStatus(tr("Checking for FML libraries...")); - forge_present = (profile->versionPatch("net.minecraftforge") != nullptr); - // we don't... - if (!forge_present) - { - assetIndexStart(); - return; - } - - // now check the lib folder inside the instance for files. - for (auto &lib : libList) - { - QFileInfo |
