summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorJanrupf <werbung.janrupf@t-online.de>2018-03-03 21:22:00 +0100
committerJanrupf <werbung.janrupf@t-online.de>2018-03-11 19:30:47 +0100
commitb8ca36372be11b9ddddb3daa3d32583d286f19e2 (patch)
treeb359357881d14e0b0871b3e5d0175234eb562b72 /api
parent2d295d5afbf6cb5ce1ca624c4aef8fd96b78992b (diff)
downloadMultiMC-b8ca36372be11b9ddddb3daa3d32583d286f19e2.tar
MultiMC-b8ca36372be11b9ddddb3daa3d32583d286f19e2.tar.gz
MultiMC-b8ca36372be11b9ddddb3daa3d32583d286f19e2.tar.lz
MultiMC-b8ca36372be11b9ddddb3daa3d32583d286f19e2.tar.xz
MultiMC-b8ca36372be11b9ddddb3daa3d32583d286f19e2.zip
GH-2124 First complete implementation, installing is working now! GH-2172 Added sorting
Diffstat (limited to 'api')
-rw-r--r--api/logic/modplatform/FtbPackDownloader.cpp9
-rw-r--r--api/logic/modplatform/FtbPackDownloader.h5
-rw-r--r--api/logic/modplatform/FtbPackFetchTask.cpp21
-rw-r--r--api/logic/modplatform/FtbPackFetchTask.h1
-rw-r--r--api/logic/modplatform/FtbPackInstallTask.cpp159
-rw-r--r--api/logic/modplatform/FtbPackInstallTask.h14
-rw-r--r--api/logic/modplatform/PackHelpers.h7
-rw-r--r--api/logic/net/NetJob.cpp4
8 files changed, 203 insertions, 17 deletions
diff --git a/api/logic/modplatform/FtbPackDownloader.cpp b/api/logic/modplatform/FtbPackDownloader.cpp
index a3951bfd..caadd4ae 100644
--- a/api/logic/modplatform/FtbPackDownloader.cpp
+++ b/api/logic/modplatform/FtbPackDownloader.cpp
@@ -9,8 +9,6 @@ FtbPackDownloader::FtbPackDownloader() {
}
FtbPackDownloader::~FtbPackDownloader(){
- delete netJobContainer.get();
- netJobContainer.reset(nullptr);
}
bool FtbPackDownloader::isValidPackSelected(){
@@ -22,7 +20,7 @@ bool FtbPackDownloader::isValidPackSelected(){
return false;
}
- return other.oldVersions.contains(selectedVersion);
+ return other.oldVersions.contains(selectedVersion) && !other.broken;
}
QString FtbPackDownloader::getSuggestedInstanceName() {
@@ -104,3 +102,8 @@ void FtbPackDownloader::_downloadFailed(QString reason) {
netJobContainer.reset();
emit downloadFailed(reason);
}
+
+NetJobPtr FtbPackDownloader::getNetJob()
+{
+ return netJobContainer;
+}
diff --git a/api/logic/modplatform/FtbPackDownloader.h b/api/logic/modplatform/FtbPackDownloader.h
index 45490afc..c5cc9bd2 100644
--- a/api/logic/modplatform/FtbPackDownloader.h
+++ b/api/logic/modplatform/FtbPackDownloader.h
@@ -18,8 +18,8 @@ class MULTIMC_LOGIC_EXPORT FtbPackDownloader : public QObject {
private:
QMap<QString, FtbModpack> fetchedPacks;
- bool fetching;
- bool done;
+ bool fetching = false;
+ bool done = false;
FtbModpack selected;
QString selectedVersion;
@@ -51,6 +51,7 @@ public:
QString getSuggestedInstanceName();
FtbModpackList getModpacks();
+ NetJobPtr getNetJob();
signals:
void ready();
diff --git a/api/logic/modplatform/FtbPackFetchTask.cpp b/api/logic/modplatform/FtbPackFetchTask.cpp
index 6f578e04..9e151186 100644
--- a/api/logic/modplatform/FtbPackFetchTask.cpp
+++ b/api/logic/modplatform/FtbPackFetchTask.cpp
@@ -58,6 +58,26 @@ void FtbPackFetchTask::fileDownloadFinished(){
modpack.mods = element.attribute("mods");
modpack.image = element.attribute("image");
modpack.oldVersions = element.attribute("oldVersions").split(";");
+
+ //remove empty if the xml is bugged
+ for(QString curr : modpack.oldVersions) {
+ if(curr.isNull() || curr.isEmpty()) {
+ modpack.oldVersions.removeAll(curr);
+ modpack.bugged = true;
+ qWarning() << "Removed some empty versions from" << modpack.name;
+ }
+ }
+
+ if(modpack.oldVersions.size() < 1) {
+ if(!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty()) {
+ modpack.oldVersions.append(modpack.currentVersion);
+ qWarning() << "Added current version to oldVersions because oldVersions was empty! (" + modpack.name + ")";
+ } else {
+ modpack.broken = true;
+ qWarning() << "Broken pack:" << modpack.name << " => No valid version!";
+ }
+ }
+
modpack.author = element.attribute("author");
modpack.dir = element.attribute("dir");
@@ -66,6 +86,7 @@ void FtbPackFetchTask::fileDownloadFinished(){
modpackList.append(modpack);
}
+
emit finished(modpackList);
}
diff --git a/api/logic/modplatform/FtbPackFetchTask.h b/api/logic/modplatform/FtbPackFetchTask.h
index df5a96e6..3cfac4ed 100644
--- a/api/logic/modplatform/FtbPackFetchTask.h
+++ b/api/logic/modplatform/FtbPackFetchTask.h
@@ -1,6 +1,5 @@
#pragma once
-#include "multimc_logic_export.h"
#include "net/NetJob.h"
#include <QTemporaryDir>
#include <QByteArray>
diff --git a/api/logic/modplatform/FtbPackInstallTask.cpp b/api/logic/modplatform/FtbPackInstallTask.cpp
index bedf3942..8c0bc70c 100644
--- a/api/logic/modplatform/FtbPackInstallTask.cpp
+++ b/api/logic/modplatform/FtbPackInstallTask.cpp
@@ -2,6 +2,11 @@
#include "Env.h"
#include "MMCZip.h"
#include "QtConcurrent"
+#include "BaseInstance.h"
+#include "FileSystem.h"
+#include "settings/INISettingsObject.h"
+#include "minecraft/MinecraftInstance.h"
+#include "minecraft/ComponentList.h"
FtbPackInstallTask::FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings,
const QString &stagingPath, const QString &instName, const QString &instIcon, const QString &instGroup) :
@@ -16,18 +21,19 @@ void FtbPackInstallTask::executeTask() {
void FtbPackInstallTask::downloadPack(){
FtbModpack toInstall = m_downloader->getSelectedPack();
- setStatus(tr("Installing new FTB Pack %1").arg(toInstall.name));
+ setStatus(tr("Downloading zip for %1").arg(toInstall.name));
- auto entry = ENV.metacache()->resolveEntry("general", "FTBPack/" + toInstall.name);
+ auto entry = ENV.metacache()->resolveEntry("general", "FTBPacks/" + 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);
+ progress(1, 4);
}
void FtbPackInstallTask::onDownloadSucceeded(QString archivePath){
- qDebug() << "Download succeeded!";
+ abortable = false;
unzip(archivePath);
}
@@ -36,11 +42,14 @@ void FtbPackInstallTask::onDownloadFailed(QString reason) {
}
void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total){
- progress(current, total);
+ abortable = true;
+ progress(current, total * 4);
+ setStatus(tr("Downloading zip for %1 (%2\%)").arg(m_downloader->getSelectedPack().name).arg(current / 10));
}
void FtbPackInstallTask::unzip(QString archivePath) {
- setStatus(QString("Extracting modpack from %1").arg(archivePath));
+ progress(2, 4);
+ setStatus(tr("Extracting modpack"));
QDir extractDir(m_stagingPath);
m_packZip.reset(new QuaZip(archivePath));
@@ -49,17 +58,151 @@ void FtbPackInstallTask::unzip(QString archivePath) {
return;
}
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString("/"), extractDir.absolutePath());
+ m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
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();
+ install();
}
void FtbPackInstallTask::onUnzipCanceled() {
emitAborted();
}
+
+void FtbPackInstallTask::install() {
+ progress(3, 4);
+ FtbModpack toInstall = m_downloader->getSelectedPack();
+ setStatus(tr("Installing modpack"));
+ QDir unzipMcDir(m_stagingPath + "/unzip/minecraft");
+ if(unzipMcDir.exists()) {
+ //ok, found minecraft dir, move contents to instance dir
+ moveRecursively(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft");
+ }
+
+ QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
+ auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+ instanceSettings->set("InstanceType", "OneSix");
+
+ MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
+ auto components = instance.getComponentList();
+ components->buildingFromScratch();
+ components->setComponentVersion("net.minecraft", toInstall.mcVersion, true);
+
+ bool fallback = true;
+
+ //handle different versions
+ QFile packJson(m_stagingPath + "/.minecraft/pack.json");
+ QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods");
+ if(packJson.exists()) {
+ packJson.open(QIODevice::ReadOnly | QIODevice::Text);
+ QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll());
+ packJson.close();
+
+ //we only care about the libs
+ QJsonArray libs = doc.object().value("libraries").toArray();
+
+ foreach (const QJsonValue &value, libs) {
+ QString nameValue = value.toObject().value("name").toString();
+ if(!nameValue.startsWith("net.minecraftforge")) {
+ continue;
+ }
+
+ //It is always maven like
+ //net.minecraftforge:forge:1.7.10-10.13.4.1448-1.7.10:universal => 1.7.10-10.13.4.1448-1.7.10
+ QString forgeVersion = nameValue.split(":").at(2);
+
+ //1.7.10-10.13.4.1448-1.7.10 => 10.13.4.1448
+ forgeVersion = forgeVersion.replace(toInstall.mcVersion, "").replace("-", "");
+ components->setComponentVersion("net.minecraftforge", forgeVersion);
+ packJson.remove();
+ fallback = false;
+ break;
+ }
+
+ }
+
+ if(jarmodDir.exists()) {
+ qDebug() << "Found jarmods, installing...";
+
+ QStringList jarmods;
+ for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
+ {
+ qDebug() << "Jarmod:" << info.fileName();
+ jarmods.push_back(info.absoluteFilePath());
+ }
+
+ components->installJarMods(jarmods);
+ fallback = false;
+ }
+
+ //just nuke unzip directory, it s not needed anymore
+ FS::deletePath(m_stagingPath + "/unzip");
+
+ if(fallback) {
+ //TODO: Some fallback mechanism... or just keep failing!
+ emitFailed(tr("No installation method found!"));
+ return;
+ }
+
+ components->saveNow();
+
+ progress(4, 4);
+
+ instance.init();
+ instance.setName(m_instName);
+ if(m_instIcon == "default") {
+ m_instIcon = "ftb_logo";
+ }
+ instance.setIconKey(m_instIcon);
+ instance.setGroupInitial(m_instGroup);
+ instanceSettings->resumeSave();
+
+ emitSucceeded();
+}
+
+bool FtbPackInstallTask::moveRecursively(QString sourceFolder, QString destFolder)
+{
+ bool success = false;
+ QDir sourceDir(sourceFolder);
+
+ if(!sourceDir.exists())
+ return false;
+
+ QDir destDir(destFolder);
+ if(!destDir.exists())
+ destDir.mkdir(destFolder);
+
+ QStringList files = sourceDir.entryList(QDir::Files);
+ for(int i = 0; i< files.count(); i++) {
+ QString srcName = sourceFolder + QDir::separator() + files[i];
+ QString destName = destFolder + QDir::separator() + files[i];
+ success = QFile::copy(srcName, destName);
+ if(!success)
+ return false;
+ QFile::remove(srcName);
+ }
+
+ files.clear();
+ files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ for(int i = 0; i< files.count(); i++)
+ {
+ QString srcName = sourceFolder + QDir::separator() + files[i];
+ QString destName = destFolder + QDir::separator() + files[i];
+ success = moveRecursively(srcName, destName);
+ if(!success)
+ return false;
+ }
+
+ return QDir(sourceFolder).rmdir(sourceFolder);
+}
+
+bool FtbPackInstallTask::abort() {
+ if(abortable) {
+ return m_downloader->getNetJob()->abort();
+ }
+ return false;
+}
diff --git a/api/logic/modplatform/FtbPackInstallTask.h b/api/logic/modplatform/FtbPackInstallTask.h
index 23ef0811..cf477ae2 100644
--- a/api/logic/modplatform/FtbPackInstallTask.h
+++ b/api/logic/modplatform/FtbPackInstallTask.h
@@ -5,14 +5,18 @@
#include "net/NetJob.h"
#include "quazip.h"
#include "quazipdir.h"
+#include "meta/Index.h"
+#include "meta/Version.h"
+#include "meta/VersionList.h"
class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public Task {
Q_OBJECT
public:
- explicit FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString & stagingPath, const QString &instName,
+ explicit FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString &stagingPath, const QString &instName,
const QString &instIcon, const QString &instGroup);
+ bool abort() override;
protected:
//! Entry point for tasks.
@@ -25,7 +29,8 @@ private: /* data */
QString m_instIcon;
QString m_instGroup;
NetJobPtr m_netJobPtr;
- FtbPackDownloader *m_downloader = nullptr;
+
+ FtbPackDownloader *m_downloader;
std::unique_ptr<QuaZip> m_packZip;
QFuture<QStringList> m_extractFuture;
@@ -35,6 +40,10 @@ private: /* data */
void unzip(QString archivePath);
void install();
+ bool moveRecursively(QString source, QString dest);
+
+ bool abortable = false;
+
private slots:
void onDownloadSucceeded(QString archivePath);
void onDownloadFailed(QString reason);
@@ -42,4 +51,5 @@ private slots:
void onUnzipFinished();
void onUnzipCanceled();
+
};
diff --git a/api/logic/modplatform/PackHelpers.h b/api/logic/modplatform/PackHelpers.h
index ba0e5cb0..f761ed6b 100644
--- a/api/logic/modplatform/PackHelpers.h
+++ b/api/logic/modplatform/PackHelpers.h
@@ -1,8 +1,8 @@
#pragma once
#include <QList>
+#include "qmetatype.h"
//Header for structs etc...
-
struct FtbModpack {
QString name;
QString description;
@@ -16,6 +16,11 @@ struct FtbModpack {
//Technical data
QString dir;
QString file; //<- Url in the xml, but doesn't make much sense
+
+ bool bugged = false;
+ bool broken = false;
};
+//We need it for the proxy model
+Q_DECLARE_METATYPE(FtbModpack)
typedef QList<FtbModpack> FtbModpackList;
diff --git a/api/logic/net/NetJob.cpp b/api/logic/net/NetJob.cpp
index 304b5820..1ff8e28f 100644
--- a/api/logic/net/NetJob.cpp
+++ b/api/logic/net/NetJob.cpp
@@ -84,6 +84,10 @@ void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal)
auto current = done * 1000 + doing * inprogress;
auto current_total = all * 1000;
// HACK: make sure it never jumps backwards.
+ // FAIL: This breaks if the size is not known (or is it something else?) and jumps to 1000, so if it is 1000 reset it to inprogress
+ if(m_current_progress == 1000) {
+ m_current_progress = inprogress;
+ }
if(m_current_progress > current)
{
current = m_current_progress;