summaryrefslogtreecommitdiffstats
path: root/api/logic
diff options
context:
space:
mode:
authorJanrupf <werbung.janrupf@t-online.de>2018-02-28 19:42:30 +0100
committerJanrupf <werbung.janrupf@t-online.de>2018-02-28 19:43:56 +0100
commitab3fe74c97158fd0f979c15a0d1b0f7eb9976e7d (patch)
treef37e1c28160f882dd8f224788a985370832d6814 /api/logic
parent1a43f2829743cb88ace3f650d3e060725990c1f1 (diff)
downloadMultiMC-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.txt15
-rw-r--r--api/logic/FolderInstanceProvider.cpp8
-rw-r--r--api/logic/FolderInstanceProvider.h4
-rw-r--r--api/logic/modplatform/FtbPackDownloader.cpp106
-rw-r--r--api/logic/modplatform/FtbPackDownloader.h63
-rw-r--r--api/logic/modplatform/FtbPackFetchTask.cpp75
-rw-r--r--api/logic/modplatform/FtbPackFetchTask.h34
-rw-r--r--api/logic/modplatform/FtbPackInstallTask.cpp65
-rw-r--r--api/logic/modplatform/FtbPackInstallTask.h45
-rw-r--r--api/logic/modplatform/PackHelpers.h21
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;