Added FTB pack selection ad download, WIP
This commit is contained in:
@ -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})
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
106
api/logic/modplatform/FtbPackDownloader.cpp
Normal file
106
api/logic/modplatform/FtbPackDownloader.cpp
Normal file
@ -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
api/logic/modplatform/FtbPackDownloader.h
Normal file
63
api/logic/modplatform/FtbPackDownloader.h
Normal file
@ -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
api/logic/modplatform/FtbPackFetchTask.cpp
Normal file
75
api/logic/modplatform/FtbPackFetchTask.cpp
Normal file
@ -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
api/logic/modplatform/FtbPackFetchTask.h
Normal file
34
api/logic/modplatform/FtbPackFetchTask.h
Normal file
@ -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);
|
||||
|
||||
};
|
65
api/logic/modplatform/FtbPackInstallTask.cpp
Normal file
65
api/logic/modplatform/FtbPackInstallTask.cpp
Normal file
@ -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();
|
||||
}
|
45
api/logic/modplatform/FtbPackInstallTask.h
Normal file
45
api/logic/modplatform/FtbPackInstallTask.h
Normal file
@ -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();
|
||||
};
|
21
api/logic/modplatform/PackHelpers.h
Normal file
21
api/logic/modplatform/PackHelpers.h
Normal file
@ -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;
|
Reference in New Issue
Block a user