aboutsummaryrefslogtreecommitdiff
path: root/api/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2021-02-09 05:04:23 +0100
committerPetr Mrázek <peterix@gmail.com>2021-02-09 05:04:23 +0100
commit13a7f8d3b7b7d92387099141fad81ca74adedf1d (patch)
tree5d8b11759a521c1ca9e348732b1fb62e9c18d999 /api/logic
parent434369ca7cc8e56181d75474ac099eba76f407dc (diff)
downloadPrismLauncher-13a7f8d3b7b7d92387099141fad81ca74adedf1d.tar.gz
PrismLauncher-13a7f8d3b7b7d92387099141fad81ca74adedf1d.tar.bz2
PrismLauncher-13a7f8d3b7b7d92387099141fad81ca74adedf1d.zip
NOISSUE fix multiple issues in ATLauncher integration
Diffstat (limited to 'api/logic')
-rw-r--r--api/logic/InstanceImportTask.cpp2
-rw-r--r--api/logic/InstanceImportTask.h6
-rw-r--r--api/logic/MMCZip.cpp47
-rw-r--r--api/logic/MMCZip.h7
-rw-r--r--api/logic/minecraft/World.cpp2
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp168
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.h22
-rw-r--r--api/logic/modplatform/legacy_ftb/PackInstallTask.h6
-rw-r--r--api/logic/modplatform/technic/SingleZipPackInstallTask.cpp2
-rw-r--r--api/logic/modplatform/technic/SingleZipPackInstallTask.h6
-rw-r--r--api/logic/modplatform/technic/SolderPackInstallTask.cpp2
11 files changed, 170 insertions, 100 deletions
diff --git a/api/logic/InstanceImportTask.cpp b/api/logic/InstanceImportTask.cpp
index bd98f9d4..fe2cdd75 100644
--- a/api/logic/InstanceImportTask.cpp
+++ b/api/logic/InstanceImportTask.cpp
@@ -138,7 +138,7 @@ void InstanceImportTask::processZipPack()
void InstanceImportTask::extractFinished()
{
m_packZip.reset();
- if (m_extractFuture.result().isEmpty())
+ if (!m_extractFuture.result())
{
emitFailed(tr("Failed to extract modpack"));
return;
diff --git a/api/logic/InstanceImportTask.h b/api/logic/InstanceImportTask.h
index db658808..7291324d 100644
--- a/api/logic/InstanceImportTask.h
+++ b/api/logic/InstanceImportTask.h
@@ -24,6 +24,8 @@
#include "settings/SettingsObject.h"
#include "QObjectPtr.h"
+#include <nonstd/optional>
+
class QuaZip;
namespace Flame
{
@@ -60,8 +62,8 @@ private: /* data */
QString m_archivePath;
bool m_downloadRequired = false;
std::unique_ptr<QuaZip> m_packZip;
- QFuture<QStringList> m_extractFuture;
- QFutureWatcher<QStringList> m_extractFutureWatcher;
+ QFuture<nonstd::optional<QStringList>> m_extractFuture;
+ QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
enum class ModpackType{
Unknown,
MultiMC,
diff --git a/api/logic/MMCZip.cpp b/api/logic/MMCZip.cpp
index 50b95c8e..b25c61e7 100644
--- a/api/logic/MMCZip.cpp
+++ b/api/logic/MMCZip.cpp
@@ -208,16 +208,27 @@ bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & re
// ours
-QStringList MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target)
+nonstd::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target)
{
QDir directory(target);
QStringList extracted;
+
qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target;
- if (!zip->goToFirstFile())
+ auto numEntries = zip->getEntriesCount();
+ if(numEntries < 0) {
+ qWarning() << "Failed to enumerate files in archive";
+ return nonstd::nullopt;
+ }
+ else if(numEntries == 0) {
+ qDebug() << "Extracting empty archives seems odd...";
+ return extracted;
+ }
+ else if (!zip->goToFirstFile())
{
qWarning() << "Failed to seek to first file in zip";
- return QStringList();
+ return nonstd::nullopt;
}
+
do
{
QString name = zip->getCurrentFileName();
@@ -235,7 +246,7 @@ QStringList MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QSt
{
qWarning() << "Failed to extract file" << name << "to" << absFilePath;
JlCompress::removeFile(extracted);
- return QStringList();
+ return nonstd::nullopt;
}
extracted.append(absFilePath);
qDebug() << "Extracted file" << name;
@@ -250,23 +261,35 @@ bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &tar
}
// ours
-QStringList MMCZip::extractDir(QString fileCompressed, QString dir)
+nonstd::optional<QStringList> MMCZip::extractDir(QString fileCompressed, QString dir)
{
QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip))
{
- return {};
+ // check if this is a minimum size empty zip file...
+ QFileInfo fileInfo(fileCompressed);
+ if(fileInfo.size() == 22) {
+ return QStringList();
+ }
+ qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();;
+ return nonstd::nullopt;
}
return MMCZip::extractSubDir(&zip, "", dir);
}
// ours
-QStringList MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir)
+nonstd::optional<QStringList> MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir)
{
QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip))
{
- return {};
+ // check if this is a minimum size empty zip file...
+ QFileInfo fileInfo(fileCompressed);
+ if(fileInfo.size() == 22) {
+ return QStringList();
+ }
+ qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();;
+ return nonstd::nullopt;
}
return MMCZip::extractSubDir(&zip, subdir, dir);
}
@@ -277,7 +300,13 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target)
QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip))
{
- return {};
+ // check if this is a minimum size empty zip file...
+ QFileInfo fileInfo(fileCompressed);
+ if(fileInfo.size() == 22) {
+ return true;
+ }
+ qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();
+ return false;
}
return MMCZip::extractRelFile(&zip, file, target);
}
diff --git a/api/logic/MMCZip.h b/api/logic/MMCZip.h
index beff2e4d..98d9cd5b 100644
--- a/api/logic/MMCZip.h
+++ b/api/logic/MMCZip.h
@@ -24,6 +24,7 @@
#include "multimc_logic_export.h"
#include <JlCompress.h>
+#include <nonstd/optional>
namespace MMCZip
{
@@ -57,7 +58,7 @@ namespace MMCZip
/**
* Extract a subdirectory from an archive
*/
- QStringList MULTIMC_LOGIC_EXPORT extractSubDir(QuaZip *zip, const QString & subdir, const QString &target);
+ nonstd::optional<QStringList> MULTIMC_LOGIC_EXPORT extractSubDir(QuaZip *zip, const QString & subdir, const QString &target);
bool MULTIMC_LOGIC_EXPORT extractRelFile(QuaZip *zip, const QString & file, const QString &target);
@@ -68,7 +69,7 @@ namespace MMCZip
* \param dir The directory to extract to, the current directory if left empty.
* \return The list of the full paths of the files extracted, empty on failure.
*/
- QStringList MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString dir);
+ nonstd::optional<QStringList> MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString dir);
/**
* Extract a subdirectory from an archive
@@ -78,7 +79,7 @@ namespace MMCZip
* \param dir The directory to extract to, the current directory if left empty.
* \return The list of the full paths of the files extracted, empty on failure.
*/
- QStringList MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString subdir, QString dir);
+ nonstd::optional<QStringList> MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString subdir, QString dir);
/**
* Extract a single file from an archive into a directory
diff --git a/api/logic/minecraft/World.cpp b/api/logic/minecraft/World.cpp
index ddeaa3b6..a2b4dac7 100644
--- a/api/logic/minecraft/World.cpp
+++ b/api/logic/minecraft/World.cpp
@@ -289,7 +289,7 @@ bool World::install(const QString &to, const QString &name)
{
return false;
}
- ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath).isEmpty();
+ ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath);
}
else if(m_containerFile.isDir())
{
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
index 9719cef3..faa05e84 100644
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
+++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
@@ -31,6 +31,7 @@ bool PackInstallTask::abort()
void PackInstallTask::executeTask()
{
+ qDebug() << "PackInstallTask::executeTask: " << QThread::currentThreadId();
auto *netJob = new NetJob("ATLauncher::VersionFetch");
auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json")
.arg(m_pack).arg(m_version_name);
@@ -44,6 +45,7 @@ void PackInstallTask::executeTask()
void PackInstallTask::onDownloadSucceeded()
{
+ qDebug() << "PackInstallTask::onDownloadSucceeded: " << QThread::currentThreadId();
jobPtr.reset();
QJsonParseError parse_error;
@@ -84,7 +86,7 @@ void PackInstallTask::onDownloadSucceeded()
minecraftVersion = ver;
if(m_version.noConfigs) {
- installMods();
+ downloadMods();
}
else {
installConfigs();
@@ -93,6 +95,7 @@ void PackInstallTask::onDownloadSucceeded()
void PackInstallTask::onDownloadFailed(QString reason)
{
+ qDebug() << "PackInstallTask::onDownloadFailed: " << QThread::currentThreadId();
jobPtr.reset();
emitFailed(reason);
}
@@ -360,6 +363,7 @@ bool PackInstallTask::createPackComponent(QString instanceRoot, std::shared_ptr<
void PackInstallTask::installConfigs()
{
+ qDebug() << "PackInstallTask::installConfigs: " << QThread::currentThreadId();
setStatus(tr("Downloading configs..."));
jobPtr.reset(new NetJob(tr("Config download")));
@@ -392,6 +396,7 @@ void PackInstallTask::installConfigs()
void PackInstallTask::extractConfigs()
{
+ qDebug() << "PackInstallTask::extractConfigs: " << QThread::currentThreadId();
setStatus(tr("Extracting configs..."));
QDir extractDir(m_stagingPath);
@@ -406,7 +411,7 @@ void PackInstallTask::extractConfigs()
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft");
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, [&]()
{
- installMods();
+ downloadMods();
});
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
{
@@ -415,8 +420,9 @@ void PackInstallTask::extractConfigs()
m_extractFutureWatcher.setFuture(m_extractFuture);
}
-void PackInstallTask::installMods()
+void PackInstallTask::downloadMods()
{
+ qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId();
setStatus(tr("Downloading mods..."));
jarmods.clear();
@@ -464,12 +470,17 @@ void PackInstallTask::installMods()
else {
auto relpath = getDirForModType(mod.type, mod.type_raw);
if(relpath == Q_NULLPTR) continue;
- auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file);
- qDebug() << "Will download" << url << "to" << path;
- auto dl = Net::Download::makeFile(url, path);
+ auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName);
+ entry->setStale(true);
+
+ auto dl = Net::Download::makeCached(url, entry);
jobPtr->addNetAction(dl);
+ auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file);
+ qDebug() << "Will download" << url << "to" << path;
+ modsToCopy[entry->getFullPath()] = path;
+
if(mod.type == ModType::Forge) {
auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
if(vlist)
@@ -493,11 +504,7 @@ void PackInstallTask::installMods()
}
}
- connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
- {
- jobPtr.reset();
- extractMods();
- });
+ connect(jobPtr.get(), &NetJob::succeeded, this, &PackInstallTask::onModsDownloaded);
connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
{
jobPtr.reset();
@@ -511,88 +518,103 @@ void PackInstallTask::installMods()
jobPtr->start();
}
-void PackInstallTask::extractMods()
-{
- setStatus(tr("Extracting mods..."));
+void PackInstallTask::onModsDownloaded() {
+ qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId();
+ jobPtr.reset();
- if(modsToExtract.isEmpty()) {
- decompMods();
- return;
+ if(modsToExtract.size() || modsToDecomp.size() || modsToCopy.size()) {
+ m_modExtractFuture = QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy);
+ connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onModsExtracted);
+ connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
+ {
+ emitAborted();
+ });
+ m_modExtractFutureWatcher.setFuture(m_modExtractFuture);
}
-
- auto modPath = modsToExtract.firstKey();
- auto mod = modsToExtract.value(modPath);
-
- QString extractToDir;
- if(mod.type == ModType::Extract) {
- extractToDir = getDirForModType(mod.extractTo, mod.extractTo_raw);
+ else {
+ install();
}
- else if(mod.type == ModType::TexturePackExtract) {
- extractToDir = FS::PathCombine("texturepacks", "extracted");
+}
+
+void PackInstallTask::onModsExtracted() {
+ qDebug() << "PackInstallTask::onModsExtracted: " << QThread::currentThreadId();
+ if(m_modExtractFuture.result()) {
+ install();
}
- else if(mod.type == ModType::ResourcePackExtract) {
- extractToDir = FS::PathCombine("resourcepacks", "extracted");
+ else {
+ emitFailed(tr("Failed to extract mods..."));
}
+}
- qDebug() << "Extracting " + mod.file + " to " + extractToDir;
+bool PackInstallTask::extractMods(
+ const QMap<QString, VersionMod> &toExtract,
+ const QMap<QString, VersionMod> &toDecomp,
+ const QMap<QString, QString> &toCopy
+) {
+ qDebug() << "PackInstallTask::extractMods: " << QThread::currentThreadId();
- QDir extractDir(m_stagingPath);
- auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir);
-
- QString folderToExtract = "";
- if(mod.type == ModType::Extract) {
- folderToExtract = mod.extractFolder;
- }
+ setStatus(tr("Extracting mods..."));
+ for (auto iter = toExtract.begin(); iter != toExtract.end(); iter++) {
+ auto &modPath = iter.key();
+ auto &mod = iter.value();
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, modPath, folderToExtract, extractToPath);
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, [&]()
- {
- extractMods();
- });
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
- {
- emitAborted();
- });
- m_extractFutureWatcher.setFuture(m_extractFuture);
+ QString extractToDir;
+ if(mod.type == ModType::Extract) {
+ extractToDir = getDirForModType(mod.extractTo, mod.extractTo_raw);
+ }
+ else if(mod.type == ModType::TexturePackExtract) {
+ extractToDir = FS::PathCombine("texturepacks", "extracted");
+ }
+ else if(mod.type == ModType::ResourcePackExtract) {
+ extractToDir = FS::PathCombine("resourcepacks", "extracted");
+ }
- modsToExtract.remove(modPath);
-}
+ QDir extractDir(m_stagingPath);
+ auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir);
-void PackInstallTask::decompMods()
-{
- setStatus(tr("Extracting 'decomp' mods..."));
+ QString folderToExtract = "";
+ if(mod.type == ModType::Extract) {
+ folderToExtract = mod.extractFolder;
+ folderToExtract.remove(QRegExp("^/"));
+ }
- if(modsToDecomp.isEmpty()) {
- install();
- return;
+ qDebug() << "Extracting " + mod.file + " to " + extractToDir;
+ if(!MMCZip::extractDir(modPath, folderToExtract, extractToPath)) {
+ // assume error
+ return false;
+ }
}
- auto modPath = modsToDecomp.firstKey();
- auto mod = modsToDecomp.value(modPath);
-
- auto extractToDir = getDirForModType(mod.decompType, mod.decompType_raw);
-
- QDir extractDir(m_stagingPath);
- auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir, mod.decompFile);
+ for (auto iter = toDecomp.begin(); iter != toDecomp.end(); iter++) {
+ auto &modPath = iter.key();
+ auto &mod = iter.value();
+ auto extractToDir = getDirForModType(mod.decompType, mod.decompType_raw);
- qWarning() << "Extracting " + mod.decompFile + " to " + extractToDir;
+ QDir extractDir(m_stagingPath);
+ auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir, mod.decompFile);
- m_decompFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractFile, modPath, mod.decompFile, extractToPath);
- connect(&m_decompFutureWatcher, &QFutureWatcher<bool>::finished, this, [&]()
- {
- install();
- });
- connect(&m_decompFutureWatcher, &QFutureWatcher<bool>::canceled, this, [&]()
- {
- emitAborted();
- });
- m_decompFutureWatcher.setFuture(m_decompFuture);
+ qDebug() << "Extracting " + mod.decompFile + " to " + extractToDir;
+ if(!MMCZip::extractFile(modPath, mod.decompFile, extractToPath)) {
+ qWarning() << "Failed to extract" << mod.decompFile;
+ return false;
+ }
+ }
- modsToDecomp.remove(modPath);
+ for (auto iter = toCopy.begin(); iter != toCopy.end(); iter++) {
+ auto &from = iter.key();
+ auto &to = iter.value();
+ FS::copy fileCopyOperation(from, to);
+ if(!fileCopyOperation()) {
+ qWarning() << "Failed to copy" << from << "to" << to;
+ return false;
+ }
+ }
+ return true;
}
void PackInstallTask::install()
{
+ qDebug() << "PackInstallTask::install: " << QThread::currentThreadId();
setStatus(tr("Installing modpack"));
auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
index 12e6bcf5..78544bab 100644
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
+++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
@@ -11,6 +11,8 @@
#include "minecraft/PackProfile.h"
#include "meta/Version.h"
+#include <nonstd/optional>
+
namespace ATLauncher {
class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
@@ -30,6 +32,9 @@ private slots:
void onDownloadSucceeded();
void onDownloadFailed(QString reason);
+ void onModsDownloaded();
+ void onModsExtracted();
+
private:
QString getDirForModType(ModType type, QString raw);
QString getVersionForLoader(QString uid);
@@ -40,9 +45,12 @@ private:
void installConfigs();
void extractConfigs();
- void installMods();
- void extractMods();
- void decompMods();
+ void downloadMods();
+ bool extractMods(
+ const QMap<QString, VersionMod> &toExtract,
+ const QMap<QString, VersionMod> &toDecomp,
+ const QMap<QString, QString> &toCopy
+ );
void install();
private:
@@ -55,14 +63,18 @@ private:
QMap<QString, VersionMod> modsToExtract;
QMap<QString, VersionMod> modsToDecomp;
+ QMap<QString, QString> modsToCopy;
QString archivePath;
QStringList jarmods;
Meta::VersionPtr minecraftVersion;
QMap<QString, Meta::VersionPtr> componentsToInstall;
- QFuture<QStringList> m_extractFuture;
- QFutureWatcher<QStringList> m_extractFutureWatcher;
+ QFuture<nonstd::optional<QStringList>> m_extractFuture;
+ QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
+
+ QFuture<bool> m_modExtractFuture;
+ QFutureWatcher<bool> m_modExtractFutureWatcher;
QFuture<bool> m_decompFuture;
QFutureWatcher<bool> m_decompFutureWatcher;
diff --git a/api/logic/modplatform/legacy_ftb/PackInstallTask.h b/api/logic/modplatform/legacy_ftb/PackInstallTask.h
index 1eec1880..7868d1c4 100644
--- a/api/logic/modplatform/legacy_ftb/PackInstallTask.h
+++ b/api/logic/modplatform/legacy_ftb/PackInstallTask.h
@@ -8,6 +8,8 @@
#include "meta/VersionList.h"
#include "PackHelpers.h"
+#include <nonstd/optional>
+
namespace LegacyFTB {
class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
@@ -40,8 +42,8 @@ private slots:
private: /* data */
bool abortable = false;
std::unique_ptr<QuaZip> m_packZip;
- QFuture<QStringList> m_extractFuture;
- QFutureWatcher<QStringList> m_extractFutureWatcher;
+ QFuture<nonstd::optional<QStringList>> m_extractFuture;
+ QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
NetJobPtr netJobContainer;
QString archivePath;
diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
index 9be99d06..96e1804d 100644
--- a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
+++ b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
@@ -79,7 +79,7 @@ void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current,
void Technic::SingleZipPackInstallTask::extractFinished()
{
m_packZip.reset();
- if (m_extractFuture.result().isEmpty())
+ if (!m_extractFuture.result())
{
emitFailed(tr("Failed to extract modpack"));
return;
diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.h b/api/logic/modplatform/technic/SingleZipPackInstallTask.h
index ecf4445a..c56b9e46 100644
--- a/api/logic/modplatform/technic/SingleZipPackInstallTask.h
+++ b/api/logic/modplatform/technic/SingleZipPackInstallTask.h
@@ -25,6 +25,8 @@
#include <QStringList>
#include <QUrl>
+#include <nonstd/optional>
+
namespace Technic {
class MULTIMC_LOGIC_EXPORT SingleZipPackInstallTask : public InstanceTask
@@ -51,8 +53,8 @@ private:
QString m_archivePath;
NetJobPtr m_filesNetJob;
std::unique_ptr<QuaZip> m_packZip;
- QFuture<QStringList> m_extractFuture;
- QFutureWatcher<QStringList> m_extractFutureWatcher;
+ QFuture<nonstd::optional<QStringList>> m_extractFuture;
+ QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
};
} // namespace Technic
diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.cpp b/api/logic/modplatform/technic/SolderPackInstallTask.cpp
index a858de49..1d17073c 100644
--- a/api/logic/modplatform/technic/SolderPackInstallTask.cpp
+++ b/api/logic/modplatform/technic/SolderPackInstallTask.cpp
@@ -117,7 +117,7 @@ void Technic::SolderPackInstallTask::downloadSucceeded()
while (m_modCount > i)
{
auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i));
- if (MMCZip::extractDir(path, extractDir).isEmpty())
+ if (!MMCZip::extractDir(path, extractDir))
{
return false;
}