Skip to content

Commit

Permalink
Added FTB pack selection ad download, WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Janrupf committed Feb 28, 2018
1 parent 1a43f28 commit ab3fe74
Show file tree
Hide file tree
Showing 21 changed files with 909 additions and 35 deletions.
15 changes: 15 additions & 0 deletions api/logic/CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -446,6 +460,7 @@ set(LOGIC_SOURCES
${TOOLS_SOURCES}
${META_SOURCES}
${ICONS_SOURCES}
${MODPLATFORM_SOURCES}
)

add_library(MultiMC_logic SHARED ${LOGIC_SOURCES})
Expand Down
8 changes: 8 additions & 0 deletions api/logic/FolderInstanceProvider.cpp
Expand Up @@ -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)
{
Expand Down
4 changes: 4 additions & 0 deletions api/logic/FolderInstanceProvider.h
Expand Up @@ -2,6 +2,7 @@

#include "BaseInstanceProvider.h"
#include <QMap>
#include <modplatform/FtbPackDownloader.h>

class QFileSystemWatcher;

Expand All @@ -28,6 +29,9 @@ class MULTIMC_LOGIC_EXPORT FolderInstanceProvider : public BaseInstanceProvider
// 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);

Expand Down
106 changes: 106 additions & 0 deletions 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);
}
63 changes: 63 additions & 0 deletions 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);

};
75 changes: 75 additions & 0 deletions 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);
}
34 changes: 34 additions & 0 deletions 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);

};

0 comments on commit ab3fe74

Please sign in to comment.