diff options
author | Janrupf <werbung.janrupf@t-online.de> | 2018-02-28 19:42:30 +0100 |
---|---|---|
committer | Janrupf <werbung.janrupf@t-online.de> | 2018-02-28 19:43:56 +0100 |
commit | ab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d (patch) | |
tree | f37e1c28160f882dd8f224788a985370832d6814 /api/logic | |
parent | 1a43f2829743cb88ace3f650d3e060725990c1f1 (diff) | |
download | MultiMC-ab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d.tar MultiMC-ab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d.tar.gz MultiMC-ab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d.tar.lz MultiMC-ab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d.tar.xz MultiMC-ab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d.zip |
Added FTB pack selection ad download, WIP
Diffstat (limited to 'api/logic')
-rw-r--r-- | api/logic/CMakeLists.txt | 15 | ||||
-rw-r--r-- | api/logic/FolderInstanceProvider.cpp | 8 | ||||
-rw-r--r-- | api/logic/FolderInstanceProvider.h | 4 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackDownloader.cpp | 106 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackDownloader.h | 63 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackFetchTask.cpp | 75 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackFetchTask.h | 34 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackInstallTask.cpp | 65 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackInstallTask.h | 45 | ||||
-rw-r--r-- | api/logic/modplatform/PackHelpers.h | 21 |
10 files changed, 436 insertions, 0 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index 3d5687b0..404044d8 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -418,6 +418,20 @@ set(META_SOURCES meta/Index.h ) +set(MODPLATFORM_SOURCES + # Modplatform sources + modplatform/FtbPackDownloader.h + modplatform/FtbPackDownloader.cpp + + modplatform/FtbPackFetchTask.h + modplatform/FtbPackFetchTask.cpp + modplatform/FtbPackInstallTask.h + modplatform/FtbPackInstallTask.cpp + + modplatform/PackHelpers.h + +) + add_unit_test(Index SOURCES meta/Index_test.cpp LIBS MultiMC_logic @@ -446,6 +460,7 @@ set(LOGIC_SOURCES ${TOOLS_SOURCES} ${META_SOURCES} ${ICONS_SOURCES} + ${MODPLATFORM_SOURCES} ) add_library(MultiMC_logic SHARED ${LOGIC_SOURCES}) diff --git a/api/logic/FolderInstanceProvider.cpp b/api/logic/FolderInstanceProvider.cpp index 5ef705d4..a6d3bdc8 100644 --- a/api/logic/FolderInstanceProvider.cpp +++ b/api/logic/FolderInstanceProvider.cpp @@ -428,6 +428,14 @@ Task * FolderInstanceProvider::creationTask(BaseVersionPtr version, const QStrin return new FolderInstanceStaging(this, task, stagingPath, instName, instGroup); } +#include <modplatform/FtbPackInstallTask.h> +Task * FolderInstanceProvider::ftbCreationTask(FtbPackDownloader *downloader, const QString& instName, const QString& instGroup, const QString& instIcon) +{ + auto stagingPath = getStagedInstancePath(); + auto task = new FtbPackInstallTask(downloader, m_globalSettings, stagingPath, instName, instIcon, instGroup); + return new FolderInstanceStaging(this, task, stagingPath, instName, instGroup); +} + #include "InstanceCopyTask.h" Task * FolderInstanceProvider::copyTask(const InstancePtr& oldInstance, const QString& instName, const QString& instGroup, const QString& instIcon, bool copySaves) { diff --git a/api/logic/FolderInstanceProvider.h b/api/logic/FolderInstanceProvider.h index a8d1a7bf..5117affc 100644 --- a/api/logic/FolderInstanceProvider.h +++ b/api/logic/FolderInstanceProvider.h @@ -2,6 +2,7 @@ #include "BaseInstanceProvider.h" #include <QMap> +#include <modplatform/FtbPackDownloader.h> class QFileSystemWatcher; @@ -28,6 +29,9 @@ public: // import zipped instance into this provider Task * zipImportTask(const QUrl sourceUrl, const QString &instName, const QString &instGroup, const QString &instIcon); + //create FtbInstance + Task * ftbCreationTask(FtbPackDownloader *downloader, const QString &instName, const QString &instGroup, const QString &instIcon); + // migrate an instance to the current format Task * legacyUpgradeTask(const InstancePtr& oldInstance); diff --git a/api/logic/modplatform/FtbPackDownloader.cpp b/api/logic/modplatform/FtbPackDownloader.cpp new file mode 100644 index 00000000..a3951bfd --- /dev/null +++ b/api/logic/modplatform/FtbPackDownloader.cpp @@ -0,0 +1,106 @@ +#include "FtbPackDownloader.h" +#include "PackHelpers.h" +#include "FtbPackFetchTask.h" +#include "Env.h" + +FtbPackDownloader::FtbPackDownloader() { + done = false; + fetching = false; +} + +FtbPackDownloader::~FtbPackDownloader(){ + delete netJobContainer.get(); + netJobContainer.reset(nullptr); +} + +bool FtbPackDownloader::isValidPackSelected(){ + FtbModpack dummy; + dummy.name = "__INVALID__"; + + FtbModpack other = fetchedPacks.value(selected.name, dummy); + if(other.name == "__INVALID__") { + return false; + } + + return other.oldVersions.contains(selectedVersion); +} + +QString FtbPackDownloader::getSuggestedInstanceName() { + return selected.name; +} + +FtbModpackList FtbPackDownloader::getModpacks() { + return static_cast<FtbModpackList>(fetchedPacks.values()); +} + +void FtbPackDownloader::fetchModpacks(bool force = false){ + if(fetching || (!force && done)) { + qDebug() << "Skipping modpack refetch because done or already fetching [done =>" << done << "| fetching =>" << fetching << "]"; + return; + } + + fetching = true; + + fetchTask = new FtbPackFetchTask(); + connect(fetchTask, &FtbPackFetchTask::finished, this, &FtbPackDownloader::fetchSuccess); + connect(fetchTask, &FtbPackFetchTask::failed, this, &FtbPackDownloader::fetchFailed); + fetchTask->fetch(); +} + + +void FtbPackDownloader::fetchSuccess(FtbModpackList modpacks) { + for(int i = 0; i < modpacks.size(); i++) { + fetchedPacks.insert(modpacks.at(i).name, modpacks.at(i)); + } + + fetching = false; + done = true; + emit ready(); + fetchTask->deleteLater(); +} + +void FtbPackDownloader::fetchFailed(QString reason) { + qWarning() << "Failed to fetch FtbData" << reason; + fetching = false; + emit packFetchFailed(); + fetchTask->deleteLater(); +} + +void FtbPackDownloader::selectPack(FtbModpack modpack, QString version) { + selected = modpack; + selectedVersion = version; +} + +FtbModpack FtbPackDownloader::getSelectedPack() { + return selected; +} + +void FtbPackDownloader::downloadSelected(MetaEntryPtr cache) { + NetJob *job = new NetJob("Downlad FTB Pack"); + + cache->setStale(true); + QString url = QString("http://ftb.cursecdn.com/FTB2/modpacks/%1/%2/%3").arg(selected.dir, selectedVersion.replace(".", "_"), selected.file); + job->addNetAction(Net::Download::makeCached(url, cache)); + downloadPath = cache->getFullPath(); + + netJobContainer.reset(job); + + connect(job, &NetJob::succeeded, this, &FtbPackDownloader::_downloadSucceeded); + connect(job, &NetJob::failed, this, &FtbPackDownloader::_downloadFailed); + connect(job, &NetJob::progress, this, &FtbPackDownloader::_downloadProgress); + job->start(); +} + +void FtbPackDownloader::_downloadSucceeded() { + netJobContainer.reset(); + emit downloadSucceded(downloadPath); +} + +void FtbPackDownloader::_downloadProgress(qint64 current, qint64 total) { + emit downloadProgress(current, total); +} + +void FtbPackDownloader::_downloadFailed(QString reason) { + netJobContainer.reset(); + emit downloadFailed(reason); +} diff --git a/api/logic/modplatform/FtbPackDownloader.h b/api/logic/modplatform/FtbPackDownloader.h new file mode 100644 index 00000000..45490afc --- /dev/null +++ b/api/logic/modplatform/FtbPackDownloader.h @@ -0,0 +1,63 @@ +#include <QString> +#include <QUrl> +#include <QList> +#include <QObject> +#include "FtbPackFetchTask.h" +#include "tasks/Task.h" +#include "net/NetJob.h" + +#include "PackHelpers.h" +#include "Env.h" + +#pragma once + +class FtbPackDownloader; +class MULTIMC_LOGIC_EXPORT FtbPackDownloader : public QObject { + + Q_OBJECT + +private: + QMap<QString, FtbModpack> fetchedPacks; + bool fetching; + bool done; + + FtbModpack selected; + QString selectedVersion; + QString downloadPath; + + FtbPackFetchTask *fetchTask = 0; + NetJobPtr netJobContainer; + + void _downloadSucceeded(); + void _downloadFailed(QString reason); + void _downloadProgress(qint64 current, qint64 total); + +private slots: + void fetchSuccess(FtbModpackList modlist); + void fetchFailed(QString reason); + +public: + FtbPackDownloader(); + ~FtbPackDownloader(); + + bool isValidPackSelected(); + void selectPack(FtbModpack modpack, QString version); + + FtbModpack getSelectedPack(); + + void fetchModpacks(bool force); + void downloadSelected(MetaEntryPtr cache); + + QString getSuggestedInstanceName(); + + FtbModpackList getModpacks(); + +signals: + void ready(); + void packFetchFailed(); + + void downloadSucceded(QString archivePath); + void downloadFailed(QString reason); + void downloadProgress(qint64 current, qint64 total); + +}; diff --git a/api/logic/modplatform/FtbPackFetchTask.cpp b/api/logic/modplatform/FtbPackFetchTask.cpp new file mode 100644 index 00000000..6f578e04 --- /dev/null +++ b/api/logic/modplatform/FtbPackFetchTask.cpp @@ -0,0 +1,75 @@ +#include "FtbPackFetchTask.h" +#include <QDomDocument> + +FtbPackFetchTask::FtbPackFetchTask() { + +} + +FtbPackFetchTask::~FtbPackFetchTask() { + +} + +void FtbPackFetchTask::fetch() { + NetJob *netJob = new NetJob("FtbModpackFetch"); + + QUrl url = QUrl("https://ftb.cursecdn.com/FTB2/static/modpacks.xml"); + qDebug() << "Downloading version info from " << url.toString(); + + netJob->addNetAction(downloadPtr = Net::Download::makeByteArray(url, &modpacksXmlFileData)); + + QObject::connect(netJob, &NetJob::succeeded, this, &FtbPackFetchTask::fileDownloadFinished); + QObject::connect(netJob, &NetJob::failed, this, &FtbPackFetchTask::fileDownloadFailed); + + jobPtr.reset(netJob); + netJob->start(); +} + +void FtbPackFetchTask::fileDownloadFinished(){ + + jobPtr.reset(); + + QDomDocument doc; + + QString errorMsg = "Unknown error."; + int errorLine = -1; + int errorCol = -1; + + if(!doc.setContent(modpacksXmlFileData, false, &errorMsg, &errorLine, &errorCol)){ + auto fullErrMsg = QString("Failed to fetch modpack data: %s %d:%d!").arg(errorMsg, errorLine, errorCol); + qWarning() << fullErrMsg; + emit failed(fullErrMsg); + modpacksXmlFileData.clear(); + return; + } + + modpacksXmlFileData.clear(); + + FtbModpackList modpackList; + + QDomNodeList nodes = doc.elementsByTagName("modpack"); + for(int i = 0; i < nodes.length(); i++) { + QDomElement element = nodes.at(i).toElement(); + + FtbModpack modpack; + modpack.name = element.attribute("name"); + modpack.currentVersion = element.attribute("version"); + modpack.mcVersion = element.attribute("mcVersion"); + modpack.description = element.attribute("description"); + modpack.mods = element.attribute("mods"); + modpack.image = element.attribute("image"); + modpack.oldVersions = element.attribute("oldVersions").split(";"); + modpack.author = element.attribute("author"); + + modpack.dir = element.attribute("dir"); + modpack.file = element.attribute("url"); + + modpackList.append(modpack); + } + + emit finished(modpackList); +} + +void FtbPackFetchTask::fileDownloadFailed(QString reason){ + qWarning() << "Fetching FtbPacks failed: " << reason; + emit failed(reason); +} diff --git a/api/logic/modplatform/FtbPackFetchTask.h b/api/logic/modplatform/FtbPackFetchTask.h new file mode 100644 index 00000000..df5a96e6 --- /dev/null +++ b/api/logic/modplatform/FtbPackFetchTask.h @@ -0,0 +1,34 @@ +#pragma once + +#include "multimc_logic_export.h" +#include "net/NetJob.h" +#include <QTemporaryDir> +#include <QByteArray> +#include <QObject> +#include "PackHelpers.h" + +class MULTIMC_LOGIC_EXPORT FtbPackFetchTask : public QObject { + + Q_OBJECT + +public: + FtbPackFetchTask(); + ~FtbPackFetchTask(); + + void fetch(); + +private: + NetJobPtr jobPtr; + Net::Download::Ptr downloadPtr; + + QByteArray modpacksXmlFileData; + +protected slots: + void fileDownloadFinished(); + void fileDownloadFailed(QString reason); + +signals: + void finished(FtbModpackList list); + void failed(QString reason); + +}; diff --git a/api/logic/modplatform/FtbPackInstallTask.cpp b/api/logic/modplatform/FtbPackInstallTask.cpp new file mode 100644 index 00000000..bedf3942 --- /dev/null +++ b/api/logic/modplatform/FtbPackInstallTask.cpp @@ -0,0 +1,65 @@ +#include "FtbPackInstallTask.h" +#include "Env.h" +#include "MMCZip.h" +#include "QtConcurrent" + +FtbPackInstallTask::FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, + const QString &stagingPath, const QString &instName, const QString &instIcon, const QString &instGroup) : + m_globalSettings(settings), m_stagingPath(stagingPath), m_instName(instName), m_instIcon(instIcon), m_instGroup(instGroup) +{ + m_downloader = downloader; +} + +void FtbPackInstallTask::executeTask() { + downloadPack(); +} + +void FtbPackInstallTask::downloadPack(){ + FtbModpack toInstall = m_downloader->getSelectedPack(); + setStatus(tr("Installing new FTB Pack %1").arg(toInstall.name)); + + auto entry = ENV.metacache()->resolveEntry("general", "FTBPack/" + toInstall.name); + m_downloader->downloadSelected(entry); + + connect(m_downloader, &FtbPackDownloader::downloadSucceded, this, &FtbPackInstallTask::onDownloadSucceeded); + connect(m_downloader, &FtbPackDownloader::downloadProgress, this, &FtbPackInstallTask::onDownloadProgress); + connect(m_downloader, &FtbPackDownloader::downloadFailed, this,&FtbPackInstallTask::onDownloadFailed); +} + +void FtbPackInstallTask::onDownloadSucceeded(QString archivePath){ + qDebug() << "Download succeeded!"; + unzip(archivePath); +} + +void FtbPackInstallTask::onDownloadFailed(QString reason) { + emitFailed(reason); +} + +void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total){ + progress(current, total); +} + +void FtbPackInstallTask::unzip(QString archivePath) { + setStatus(QString("Extracting modpack from %1").arg(archivePath)); + QDir extractDir(m_stagingPath); + + m_packZip.reset(new QuaZip(archivePath)); + if(!m_packZip->open(QuaZip::mdUnzip)) { + emitFailed(tr("Failed to open modpack file %1!").arg(archivePath)); + return; + } + + m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString("/"), extractDir.absolutePath()); + connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &FtbPackInstallTask::onUnzipFinished); + connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &FtbPackInstallTask::onUnzipCanceled); + m_extractFutureWatcher.setFuture(m_extractFuture); +} + +void FtbPackInstallTask::onUnzipFinished() { + qDebug() << "Unzipped:" << m_stagingPath; + emitSucceeded(); +} + +void FtbPackInstallTask::onUnzipCanceled() { + emitAborted(); +} diff --git a/api/logic/modplatform/FtbPackInstallTask.h b/api/logic/modplatform/FtbPackInstallTask.h new file mode 100644 index 00000000..23ef0811 --- /dev/null +++ b/api/logic/modplatform/FtbPackInstallTask.h @@ -0,0 +1,45 @@ +#pragma once +#include "tasks/Task.h" +#include "modplatform/FtbPackDownloader.h" +#include "BaseInstanceProvider.h" +#include "net/NetJob.h" +#include "quazip.h" +#include "quazipdir.h" + +class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public Task { + + Q_OBJECT + +public: + explicit FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString & stagingPath, const QString &instName, + const QString &instIcon, const QString &instGroup); + +protected: + //! Entry point for tasks. + virtual void executeTask() override; + +private: /* data */ + SettingsObjectPtr m_globalSettings; + QString m_stagingPath; + QString m_instName; + QString m_instIcon; + QString m_instGroup; + NetJobPtr m_netJobPtr; + FtbPackDownloader *m_downloader = nullptr; + + std::unique_ptr<QuaZip> m_packZip; + QFuture<QStringList> m_extractFuture; + QFutureWatcher<QStringList> m_extractFutureWatcher; + + void downloadPack(); + void unzip(QString archivePath); + void install(); + +private slots: + void onDownloadSucceeded(QString archivePath); + void onDownloadFailed(QString reason); + void onDownloadProgress(qint64 current, qint64 total); + + void onUnzipFinished(); + void onUnzipCanceled(); +}; diff --git a/api/logic/modplatform/PackHelpers.h b/api/logic/modplatform/PackHelpers.h new file mode 100644 index 00000000..ba0e5cb0 --- /dev/null +++ b/api/logic/modplatform/PackHelpers.h @@ -0,0 +1,21 @@ +#pragma once +#include <QList> + +//Header for structs etc... + +struct FtbModpack { + QString name; + QString description; + QString author; + QStringList oldVersions; + QString currentVersion; + QString mcVersion; + QString mods; + QString image; + + //Technical data + QString dir; + QString file; //<- Url in the xml, but doesn't make much sense +}; + +typedef QList<FtbModpack> FtbModpackList; |