NOISSUE fix multiple issues in ATLauncher integration
This commit is contained in:
parent
434369ca7c
commit
13a7f8d3b7
@ -138,7 +138,7 @@ void InstanceImportTask::processZipPack()
|
|||||||
void InstanceImportTask::extractFinished()
|
void InstanceImportTask::extractFinished()
|
||||||
{
|
{
|
||||||
m_packZip.reset();
|
m_packZip.reset();
|
||||||
if (m_extractFuture.result().isEmpty())
|
if (!m_extractFuture.result())
|
||||||
{
|
{
|
||||||
emitFailed(tr("Failed to extract modpack"));
|
emitFailed(tr("Failed to extract modpack"));
|
||||||
return;
|
return;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#include "settings/SettingsObject.h"
|
#include "settings/SettingsObject.h"
|
||||||
#include "QObjectPtr.h"
|
#include "QObjectPtr.h"
|
||||||
|
|
||||||
|
#include <nonstd/optional>
|
||||||
|
|
||||||
class QuaZip;
|
class QuaZip;
|
||||||
namespace Flame
|
namespace Flame
|
||||||
{
|
{
|
||||||
@ -60,8 +62,8 @@ private: /* data */
|
|||||||
QString m_archivePath;
|
QString m_archivePath;
|
||||||
bool m_downloadRequired = false;
|
bool m_downloadRequired = false;
|
||||||
std::unique_ptr<QuaZip> m_packZip;
|
std::unique_ptr<QuaZip> m_packZip;
|
||||||
QFuture<QStringList> m_extractFuture;
|
QFuture<nonstd::optional<QStringList>> m_extractFuture;
|
||||||
QFutureWatcher<QStringList> m_extractFutureWatcher;
|
QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
|
||||||
enum class ModpackType{
|
enum class ModpackType{
|
||||||
Unknown,
|
Unknown,
|
||||||
MultiMC,
|
MultiMC,
|
||||||
|
@ -208,16 +208,27 @@ bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & re
|
|||||||
|
|
||||||
|
|
||||||
// ours
|
// 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);
|
QDir directory(target);
|
||||||
QStringList extracted;
|
QStringList extracted;
|
||||||
|
|
||||||
qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target;
|
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";
|
qWarning() << "Failed to seek to first file in zip";
|
||||||
return QStringList();
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
QString name = zip->getCurrentFileName();
|
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;
|
qWarning() << "Failed to extract file" << name << "to" << absFilePath;
|
||||||
JlCompress::removeFile(extracted);
|
JlCompress::removeFile(extracted);
|
||||||
return QStringList();
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
extracted.append(absFilePath);
|
extracted.append(absFilePath);
|
||||||
qDebug() << "Extracted file" << name;
|
qDebug() << "Extracted file" << name;
|
||||||
@ -250,23 +261,35 @@ bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &tar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ours
|
// ours
|
||||||
QStringList MMCZip::extractDir(QString fileCompressed, QString dir)
|
nonstd::optional<QStringList> MMCZip::extractDir(QString fileCompressed, QString dir)
|
||||||
{
|
{
|
||||||
QuaZip zip(fileCompressed);
|
QuaZip zip(fileCompressed);
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
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);
|
return MMCZip::extractSubDir(&zip, "", dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ours
|
// ours
|
||||||
QStringList MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir)
|
nonstd::optional<QStringList> MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir)
|
||||||
{
|
{
|
||||||
QuaZip zip(fileCompressed);
|
QuaZip zip(fileCompressed);
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
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);
|
return MMCZip::extractSubDir(&zip, subdir, dir);
|
||||||
}
|
}
|
||||||
@ -277,7 +300,13 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target)
|
|||||||
QuaZip zip(fileCompressed);
|
QuaZip zip(fileCompressed);
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
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);
|
return MMCZip::extractRelFile(&zip, file, target);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "multimc_logic_export.h"
|
#include "multimc_logic_export.h"
|
||||||
|
|
||||||
#include <JlCompress.h>
|
#include <JlCompress.h>
|
||||||
|
#include <nonstd/optional>
|
||||||
|
|
||||||
namespace MMCZip
|
namespace MMCZip
|
||||||
{
|
{
|
||||||
@ -57,7 +58,7 @@ namespace MMCZip
|
|||||||
/**
|
/**
|
||||||
* Extract a subdirectory from an archive
|
* 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);
|
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.
|
* \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.
|
* \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
|
* 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.
|
* \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.
|
* \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
|
* Extract a single file from an archive into a directory
|
||||||
|
@ -289,7 +289,7 @@ bool World::install(const QString &to, const QString &name)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath).isEmpty();
|
ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath);
|
||||||
}
|
}
|
||||||
else if(m_containerFile.isDir())
|
else if(m_containerFile.isDir())
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@ bool PackInstallTask::abort()
|
|||||||
|
|
||||||
void PackInstallTask::executeTask()
|
void PackInstallTask::executeTask()
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::executeTask: " << QThread::currentThreadId();
|
||||||
auto *netJob = new NetJob("ATLauncher::VersionFetch");
|
auto *netJob = new NetJob("ATLauncher::VersionFetch");
|
||||||
auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json")
|
auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json")
|
||||||
.arg(m_pack).arg(m_version_name);
|
.arg(m_pack).arg(m_version_name);
|
||||||
@ -44,6 +45,7 @@ void PackInstallTask::executeTask()
|
|||||||
|
|
||||||
void PackInstallTask::onDownloadSucceeded()
|
void PackInstallTask::onDownloadSucceeded()
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::onDownloadSucceeded: " << QThread::currentThreadId();
|
||||||
jobPtr.reset();
|
jobPtr.reset();
|
||||||
|
|
||||||
QJsonParseError parse_error;
|
QJsonParseError parse_error;
|
||||||
@ -84,7 +86,7 @@ void PackInstallTask::onDownloadSucceeded()
|
|||||||
minecraftVersion = ver;
|
minecraftVersion = ver;
|
||||||
|
|
||||||
if(m_version.noConfigs) {
|
if(m_version.noConfigs) {
|
||||||
installMods();
|
downloadMods();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
installConfigs();
|
installConfigs();
|
||||||
@ -93,6 +95,7 @@ void PackInstallTask::onDownloadSucceeded()
|
|||||||
|
|
||||||
void PackInstallTask::onDownloadFailed(QString reason)
|
void PackInstallTask::onDownloadFailed(QString reason)
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::onDownloadFailed: " << QThread::currentThreadId();
|
||||||
jobPtr.reset();
|
jobPtr.reset();
|
||||||
emitFailed(reason);
|
emitFailed(reason);
|
||||||
}
|
}
|
||||||
@ -360,6 +363,7 @@ bool PackInstallTask::createPackComponent(QString instanceRoot, std::shared_ptr<
|
|||||||
|
|
||||||
void PackInstallTask::installConfigs()
|
void PackInstallTask::installConfigs()
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::installConfigs: " << QThread::currentThreadId();
|
||||||
setStatus(tr("Downloading configs..."));
|
setStatus(tr("Downloading configs..."));
|
||||||
jobPtr.reset(new NetJob(tr("Config download")));
|
jobPtr.reset(new NetJob(tr("Config download")));
|
||||||
|
|
||||||
@ -392,6 +396,7 @@ void PackInstallTask::installConfigs()
|
|||||||
|
|
||||||
void PackInstallTask::extractConfigs()
|
void PackInstallTask::extractConfigs()
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::extractConfigs: " << QThread::currentThreadId();
|
||||||
setStatus(tr("Extracting configs..."));
|
setStatus(tr("Extracting configs..."));
|
||||||
|
|
||||||
QDir extractDir(m_stagingPath);
|
QDir extractDir(m_stagingPath);
|
||||||
@ -406,7 +411,7 @@ void PackInstallTask::extractConfigs()
|
|||||||
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft");
|
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft");
|
||||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, [&]()
|
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, [&]()
|
||||||
{
|
{
|
||||||
installMods();
|
downloadMods();
|
||||||
});
|
});
|
||||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
|
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
|
||||||
{
|
{
|
||||||
@ -415,8 +420,9 @@ void PackInstallTask::extractConfigs()
|
|||||||
m_extractFutureWatcher.setFuture(m_extractFuture);
|
m_extractFutureWatcher.setFuture(m_extractFuture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackInstallTask::installMods()
|
void PackInstallTask::downloadMods()
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId();
|
||||||
setStatus(tr("Downloading mods..."));
|
setStatus(tr("Downloading mods..."));
|
||||||
|
|
||||||
jarmods.clear();
|
jarmods.clear();
|
||||||
@ -464,12 +470,17 @@ void PackInstallTask::installMods()
|
|||||||
else {
|
else {
|
||||||
auto relpath = getDirForModType(mod.type, mod.type_raw);
|
auto relpath = getDirForModType(mod.type, mod.type_raw);
|
||||||
if(relpath == Q_NULLPTR) continue;
|
if(relpath == Q_NULLPTR) continue;
|
||||||
auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file);
|
|
||||||
|
|
||||||
qDebug() << "Will download" << url << "to" << path;
|
auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName);
|
||||||
auto dl = Net::Download::makeFile(url, path);
|
entry->setStale(true);
|
||||||
|
|
||||||
|
auto dl = Net::Download::makeCached(url, entry);
|
||||||
jobPtr->addNetAction(dl);
|
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) {
|
if(mod.type == ModType::Forge) {
|
||||||
auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
|
auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
|
||||||
if(vlist)
|
if(vlist)
|
||||||
@ -493,11 +504,7 @@ void PackInstallTask::installMods()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
|
connect(jobPtr.get(), &NetJob::succeeded, this, &PackInstallTask::onModsDownloaded);
|
||||||
{
|
|
||||||
jobPtr.reset();
|
|
||||||
extractMods();
|
|
||||||
});
|
|
||||||
connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
|
connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
|
||||||
{
|
{
|
||||||
jobPtr.reset();
|
jobPtr.reset();
|
||||||
@ -511,88 +518,103 @@ void PackInstallTask::installMods()
|
|||||||
jobPtr->start();
|
jobPtr->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackInstallTask::extractMods()
|
void PackInstallTask::onModsDownloaded() {
|
||||||
{
|
qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId();
|
||||||
setStatus(tr("Extracting mods..."));
|
jobPtr.reset();
|
||||||
|
|
||||||
if(modsToExtract.isEmpty()) {
|
if(modsToExtract.size() || modsToDecomp.size() || modsToCopy.size()) {
|
||||||
decompMods();
|
m_modExtractFuture = QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy);
|
||||||
return;
|
connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onModsExtracted);
|
||||||
|
connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
|
||||||
|
{
|
||||||
|
emitAborted();
|
||||||
|
});
|
||||||
|
m_modExtractFutureWatcher.setFuture(m_modExtractFuture);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
auto modPath = modsToExtract.firstKey();
|
install();
|
||||||
auto mod = modsToExtract.value(modPath);
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "Extracting " + mod.file + " to " + extractToDir;
|
|
||||||
|
|
||||||
QDir extractDir(m_stagingPath);
|
|
||||||
auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir);
|
|
||||||
|
|
||||||
QString folderToExtract = "";
|
|
||||||
if(mod.type == ModType::Extract) {
|
|
||||||
folderToExtract = mod.extractFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
modsToExtract.remove(modPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackInstallTask::decompMods()
|
void PackInstallTask::onModsExtracted() {
|
||||||
{
|
qDebug() << "PackInstallTask::onModsExtracted: " << QThread::currentThreadId();
|
||||||
setStatus(tr("Extracting 'decomp' mods..."));
|
if(m_modExtractFuture.result()) {
|
||||||
|
|
||||||
if(modsToDecomp.isEmpty()) {
|
|
||||||
install();
|
install();
|
||||||
return;
|
}
|
||||||
|
else {
|
||||||
|
emitFailed(tr("Failed to extract mods..."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackInstallTask::extractMods(
|
||||||
|
const QMap<QString, VersionMod> &toExtract,
|
||||||
|
const QMap<QString, VersionMod> &toDecomp,
|
||||||
|
const QMap<QString, QString> &toCopy
|
||||||
|
) {
|
||||||
|
qDebug() << "PackInstallTask::extractMods: " << QThread::currentThreadId();
|
||||||
|
|
||||||
|
setStatus(tr("Extracting mods..."));
|
||||||
|
for (auto iter = toExtract.begin(); iter != toExtract.end(); iter++) {
|
||||||
|
auto &modPath = iter.key();
|
||||||
|
auto &mod = iter.value();
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir extractDir(m_stagingPath);
|
||||||
|
auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir);
|
||||||
|
|
||||||
|
QString folderToExtract = "";
|
||||||
|
if(mod.type == ModType::Extract) {
|
||||||
|
folderToExtract = mod.extractFolder;
|
||||||
|
folderToExtract.remove(QRegExp("^/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Extracting " + mod.file + " to " + extractToDir;
|
||||||
|
if(!MMCZip::extractDir(modPath, folderToExtract, extractToPath)) {
|
||||||
|
// assume error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto modPath = modsToDecomp.firstKey();
|
for (auto iter = toDecomp.begin(); iter != toDecomp.end(); iter++) {
|
||||||
auto mod = modsToDecomp.value(modPath);
|
auto &modPath = iter.key();
|
||||||
|
auto &mod = iter.value();
|
||||||
|
auto extractToDir = getDirForModType(mod.decompType, mod.decompType_raw);
|
||||||
|
|
||||||
auto extractToDir = getDirForModType(mod.decompType, mod.decompType_raw);
|
QDir extractDir(m_stagingPath);
|
||||||
|
auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir, mod.decompFile);
|
||||||
|
|
||||||
QDir extractDir(m_stagingPath);
|
qDebug() << "Extracting " + mod.decompFile + " to " + extractToDir;
|
||||||
auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir, mod.decompFile);
|
if(!MMCZip::extractFile(modPath, mod.decompFile, extractToPath)) {
|
||||||
|
qWarning() << "Failed to extract" << mod.decompFile;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qWarning() << "Extracting " + mod.decompFile + " to " + extractToDir;
|
for (auto iter = toCopy.begin(); iter != toCopy.end(); iter++) {
|
||||||
|
auto &from = iter.key();
|
||||||
m_decompFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractFile, modPath, mod.decompFile, extractToPath);
|
auto &to = iter.value();
|
||||||
connect(&m_decompFutureWatcher, &QFutureWatcher<bool>::finished, this, [&]()
|
FS::copy fileCopyOperation(from, to);
|
||||||
{
|
if(!fileCopyOperation()) {
|
||||||
install();
|
qWarning() << "Failed to copy" << from << "to" << to;
|
||||||
});
|
return false;
|
||||||
connect(&m_decompFutureWatcher, &QFutureWatcher<bool>::canceled, this, [&]()
|
}
|
||||||
{
|
}
|
||||||
emitAborted();
|
return true;
|
||||||
});
|
|
||||||
m_decompFutureWatcher.setFuture(m_decompFuture);
|
|
||||||
|
|
||||||
modsToDecomp.remove(modPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackInstallTask::install()
|
void PackInstallTask::install()
|
||||||
{
|
{
|
||||||
|
qDebug() << "PackInstallTask::install: " << QThread::currentThreadId();
|
||||||
setStatus(tr("Installing modpack"));
|
setStatus(tr("Installing modpack"));
|
||||||
|
|
||||||
auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
|
auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include "minecraft/PackProfile.h"
|
#include "minecraft/PackProfile.h"
|
||||||
#include "meta/Version.h"
|
#include "meta/Version.h"
|
||||||
|
|
||||||
|
#include <nonstd/optional>
|
||||||
|
|
||||||
namespace ATLauncher {
|
namespace ATLauncher {
|
||||||
|
|
||||||
class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
|
class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
|
||||||
@ -30,6 +32,9 @@ private slots:
|
|||||||
void onDownloadSucceeded();
|
void onDownloadSucceeded();
|
||||||
void onDownloadFailed(QString reason);
|
void onDownloadFailed(QString reason);
|
||||||
|
|
||||||
|
void onModsDownloaded();
|
||||||
|
void onModsExtracted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString getDirForModType(ModType type, QString raw);
|
QString getDirForModType(ModType type, QString raw);
|
||||||
QString getVersionForLoader(QString uid);
|
QString getVersionForLoader(QString uid);
|
||||||
@ -40,9 +45,12 @@ private:
|
|||||||
|
|
||||||
void installConfigs();
|
void installConfigs();
|
||||||
void extractConfigs();
|
void extractConfigs();
|
||||||
void installMods();
|
void downloadMods();
|
||||||
void extractMods();
|
bool extractMods(
|
||||||
void decompMods();
|
const QMap<QString, VersionMod> &toExtract,
|
||||||
|
const QMap<QString, VersionMod> &toDecomp,
|
||||||
|
const QMap<QString, QString> &toCopy
|
||||||
|
);
|
||||||
void install();
|
void install();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -55,14 +63,18 @@ private:
|
|||||||
|
|
||||||
QMap<QString, VersionMod> modsToExtract;
|
QMap<QString, VersionMod> modsToExtract;
|
||||||
QMap<QString, VersionMod> modsToDecomp;
|
QMap<QString, VersionMod> modsToDecomp;
|
||||||
|
QMap<QString, QString> modsToCopy;
|
||||||
|
|
||||||
QString archivePath;
|
QString archivePath;
|
||||||
QStringList jarmods;
|
QStringList jarmods;
|
||||||
Meta::VersionPtr minecraftVersion;
|
Meta::VersionPtr minecraftVersion;
|
||||||
QMap<QString, Meta::VersionPtr> componentsToInstall;
|
QMap<QString, Meta::VersionPtr> componentsToInstall;
|
||||||
|
|
||||||
QFuture<QStringList> m_extractFuture;
|
QFuture<nonstd::optional<QStringList>> m_extractFuture;
|
||||||
QFutureWatcher<QStringList> m_extractFutureWatcher;
|
QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
|
||||||
|
|
||||||
|
QFuture<bool> m_modExtractFuture;
|
||||||
|
QFutureWatcher<bool> m_modExtractFutureWatcher;
|
||||||
|
|
||||||
QFuture<bool> m_decompFuture;
|
QFuture<bool> m_decompFuture;
|
||||||
QFutureWatcher<bool> m_decompFutureWatcher;
|
QFutureWatcher<bool> m_decompFutureWatcher;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "meta/VersionList.h"
|
#include "meta/VersionList.h"
|
||||||
#include "PackHelpers.h"
|
#include "PackHelpers.h"
|
||||||
|
|
||||||
|
#include <nonstd/optional>
|
||||||
|
|
||||||
namespace LegacyFTB {
|
namespace LegacyFTB {
|
||||||
|
|
||||||
class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
|
class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
|
||||||
@ -40,8 +42,8 @@ private slots:
|
|||||||
private: /* data */
|
private: /* data */
|
||||||
bool abortable = false;
|
bool abortable = false;
|
||||||
std::unique_ptr<QuaZip> m_packZip;
|
std::unique_ptr<QuaZip> m_packZip;
|
||||||
QFuture<QStringList> m_extractFuture;
|
QFuture<nonstd::optional<QStringList>> m_extractFuture;
|
||||||
QFutureWatcher<QStringList> m_extractFutureWatcher;
|
QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
|
||||||
NetJobPtr netJobContainer;
|
NetJobPtr netJobContainer;
|
||||||
QString archivePath;
|
QString archivePath;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current,
|
|||||||
void Technic::SingleZipPackInstallTask::extractFinished()
|
void Technic::SingleZipPackInstallTask::extractFinished()
|
||||||
{
|
{
|
||||||
m_packZip.reset();
|
m_packZip.reset();
|
||||||
if (m_extractFuture.result().isEmpty())
|
if (!m_extractFuture.result())
|
||||||
{
|
{
|
||||||
emitFailed(tr("Failed to extract modpack"));
|
emitFailed(tr("Failed to extract modpack"));
|
||||||
return;
|
return;
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <nonstd/optional>
|
||||||
|
|
||||||
namespace Technic {
|
namespace Technic {
|
||||||
|
|
||||||
class MULTIMC_LOGIC_EXPORT SingleZipPackInstallTask : public InstanceTask
|
class MULTIMC_LOGIC_EXPORT SingleZipPackInstallTask : public InstanceTask
|
||||||
@ -51,8 +53,8 @@ private:
|
|||||||
QString m_archivePath;
|
QString m_archivePath;
|
||||||
NetJobPtr m_filesNetJob;
|
NetJobPtr m_filesNetJob;
|
||||||
std::unique_ptr<QuaZip> m_packZip;
|
std::unique_ptr<QuaZip> m_packZip;
|
||||||
QFuture<QStringList> m_extractFuture;
|
QFuture<nonstd::optional<QStringList>> m_extractFuture;
|
||||||
QFutureWatcher<QStringList> m_extractFutureWatcher;
|
QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Technic
|
} // namespace Technic
|
||||||
|
@ -117,7 +117,7 @@ void Technic::SolderPackInstallTask::downloadSucceeded()
|
|||||||
while (m_modCount > i)
|
while (m_modCount > i)
|
||||||
{
|
{
|
||||||
auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(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;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user