diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index d3cc3bd02..17066fd22 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -108,35 +108,14 @@ void InstanceImportTask::downloadFromUrl() filesNetJob->start(); } -QString InstanceImportTask::getRootFromZip(QStringList files) +QString cleanPath(QString path) { - if (!isRunning()) { - return {}; - } - auto cleanPath = [](QString path) { - if (path == ".") - return QString(); - QString result = path; - if (result.startsWith("./")) - result = result.mid(2); - return result; - }; - for (auto&& fileName : files) { - setDetails(fileName); - QFileInfo fileInfo(fileName); - if (fileInfo.fileName() == "instance.cfg") { - qDebug() << "MultiMC:" << true; - m_modpackType = ModpackType::MultiMC; - return cleanPath(fileInfo.path()); - } - if (fileInfo.fileName() == "manifest.json") { - qDebug() << "Flame:" << true; - m_modpackType = ModpackType::Flame; - return cleanPath(fileInfo.path()); - } - QCoreApplication::processEvents(); - } - return {}; + if (path == ".") + return QString(); + QString result = path; + if (result.startsWith("./")) + result = result.mid(2); + return result; } void InstanceImportTask::processZipPack() @@ -147,31 +126,53 @@ void InstanceImportTask::processZipPack() // open the zip and find relevant files in it MMCZip::ArchiveReader packZip(m_archivePath); - if (!packZip.collectFiles()) { - emitFailed(tr("Unable to open supplied modpack zip file.")); - return; - } - qDebug() << "Attempting to determine instance type"; QString root; - // NOTE: Prioritize modpack platforms that aren't searched for recursively. // Especially Flame has a very common filename for its manifest, which may appear inside overrides for example // https://docs.modrinth.com/docs/modpacks/format_definition/#storage - if (packZip.exists("/modrinth.index.json")) { - // process as Modrinth pack - qDebug() << "Modrinth:" << true; - m_modpackType = ModpackType::Modrinth; - } else if (packZip.exists("/bin/modpack.jar") || packZip.exists("/bin/version.json")) { - // process as Technic pack - qDebug() << "Technic:" << true; - extractDir.mkpath("minecraft"); - extractDir.cd("minecraft"); - m_modpackType = ModpackType::Technic; - } else { - root = getRootFromZip(packZip.getFiles()); - setDetails(""); + auto detectInstance = [this, &extractDir, &root](MMCZip::ArchiveReader::File* f, bool& stop) { + if (!isRunning()) { + stop = true; + return true; + } + auto fileName = f->filename(); + if (fileName == "/modrinth.index.json") { + // process as Modrinth pack + qDebug() << "Modrinth:" << true; + m_modpackType = ModpackType::Modrinth; + stop = true; + } else if (fileName == "/bin/modpack.jar" || fileName == "/bin/version.json") { + // process as Technic pack + qDebug() << "Technic:" << true; + extractDir.mkpath("minecraft"); + extractDir.cd("minecraft"); + m_modpackType = ModpackType::Technic; + stop = true; + } else { + QFileInfo fileInfo(fileName); + if (fileInfo.fileName() == "instance.cfg") { + qDebug() << "MultiMC:" << true; + m_modpackType = ModpackType::MultiMC; + root = cleanPath(fileInfo.path()); + stop = true; + return true; + } + if (fileInfo.fileName() == "manifest.json") { + qDebug() << "Flame:" << true; + m_modpackType = ModpackType::Flame; + root = cleanPath(fileInfo.path()); + stop = true; + return true; + } + } + QCoreApplication::processEvents(); + return true; + }; + if (!packZip.parse(detectInstance)) { + emitFailed(tr("Unable to open supplied modpack zip file.")); + return; } if (m_modpackType == ModpackType::Unknown) { emitFailed(tr("Archive does not contain a recognized modpack type.")); diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index 4c9e6feb5..c92e229a0 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -56,7 +56,6 @@ class InstanceImportTask : public InstanceTask { void processTechnic(); void processFlame(); void processModrinth(); - QString getRootFromZip(QStringList files); private slots: void processZipPack(); diff --git a/launcher/archive/ArchiveReader.cpp b/launcher/archive/ArchiveReader.cpp index a866b49c5..26ea9840f 100644 --- a/launcher/archive/ArchiveReader.cpp +++ b/launcher/archive/ArchiveReader.cpp @@ -165,7 +165,7 @@ bool ArchiveReader::parse(std::function doStuff) bool breakControl = false; while (f->readNextHeader() == ARCHIVE_OK) { - if (!doStuff(f.get(), breakControl)) { + if (f && !doStuff(f.get(), breakControl)) { qCritical() << "Failed to parse file:" << f->filename() << "-" << f->error(); return false; } diff --git a/launcher/archive/ExportToZipTask.cpp b/launcher/archive/ExportToZipTask.cpp index 4886dc963..9df9539be 100644 --- a/launcher/archive/ExportToZipTask.cpp +++ b/launcher/archive/ExportToZipTask.cpp @@ -26,9 +26,9 @@ void ExportToZipTask::executeTask() { setStatus("Adding files..."); setProgress(0, m_files.length()); - m_build_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return exportZip(); }); - connect(&m_build_zip_watcher, &QFutureWatcher::finished, this, &ExportToZipTask::finish); - m_build_zip_watcher.setFuture(m_build_zip_future); + m_buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return exportZip(); }); + connect(&m_buildZipWatcher, &QFutureWatcher::finished, this, &ExportToZipTask::finish); + m_buildZipWatcher.setFuture(m_buildZipFuture); } auto ExportToZipTask::exportZip() -> ZipResult @@ -40,30 +40,30 @@ auto ExportToZipTask::exportZip() -> ZipResult return ZipResult(tr("Could not create file")); } - for (auto fileName : m_extra_files.keys()) { - if (m_build_zip_future.isCanceled()) + for (auto fileName : m_extraFiles.keys()) { + if (m_buildZipFuture.isCanceled()) return ZipResult(); - if (!m_output.addFile(fileName, m_extra_files[fileName])) { + if (!m_output.addFile(fileName, m_extraFiles[fileName])) { return ZipResult(tr("Could not add:") + fileName); } } for (const QFileInfo& file : m_files) { - if (m_build_zip_future.isCanceled()) + if (m_buildZipFuture.isCanceled()) return ZipResult(); auto absolute = file.absoluteFilePath(); auto relative = m_dir.relativeFilePath(absolute); setStatus("Compressing: " + relative); setProgress(m_progress + 1, m_progressTotal); - if (m_follow_symlinks) { + if (m_followSymlinks) { if (file.isSymLink()) absolute = file.symLinkTarget(); else absolute = file.canonicalFilePath(); } - if (!m_exclude_files.contains(relative) && !m_output.addFile(absolute, m_destination_prefix + relative)) { + if (!m_excludeFiles.contains(relative) && !m_output.addFile(absolute, m_destinationPrefix + relative)) { return ZipResult(tr("Could not read and compress %1").arg(relative)); } } @@ -76,11 +76,11 @@ auto ExportToZipTask::exportZip() -> ZipResult void ExportToZipTask::finish() { - if (m_build_zip_future.isCanceled()) { - FS::deletePath(m_output_path); + if (m_buildZipFuture.isCanceled()) { + FS::deletePath(m_outputPath); emitAborted(); - } else if (auto result = m_build_zip_future.result(); result.has_value()) { - FS::deletePath(m_output_path); + } else if (auto result = m_buildZipFuture.result(); result.has_value()) { + FS::deletePath(m_outputPath); emitFailed(result.value()); } else { emitSucceeded(); @@ -89,8 +89,8 @@ void ExportToZipTask::finish() bool ExportToZipTask::abort() { - if (m_build_zip_future.isRunning()) { - m_build_zip_future.cancel(); + if (m_buildZipFuture.isRunning()) { + m_buildZipFuture.cancel(); // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not occur // immediately. return true; diff --git a/launcher/archive/ExportToZipTask.h b/launcher/archive/ExportToZipTask.h index 2e0a8273e..21ad1db48 100644 --- a/launcher/archive/ExportToZipTask.h +++ b/launcher/archive/ExportToZipTask.h @@ -30,12 +30,12 @@ class ExportToZipTask : public Task { Q_OBJECT public: ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : m_output_path(outputPath) + : m_outputPath(outputPath) , m_output(outputPath) , m_dir(dir) , m_files(files) - , m_destination_prefix(destinationPrefix) - , m_follow_symlinks(followSymlinks) + , m_destinationPrefix(destinationPrefix) + , m_followSymlinks(followSymlinks) { setAbortable(true); }; @@ -44,8 +44,8 @@ class ExportToZipTask : public Task { virtual ~ExportToZipTask() = default; - void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } - void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); } + void setExcludeFiles(QStringList excludeFiles) { m_excludeFiles = excludeFiles; } + void addExtraFile(QString fileName, QByteArray data) { m_extraFiles.insert(fileName, data); } using ZipResult = std::optional; @@ -57,16 +57,16 @@ class ExportToZipTask : public Task { void finish(); private: - QString m_output_path; + QString m_outputPath; ArchiveWriter m_output; QDir m_dir; QFileInfoList m_files; - QString m_destination_prefix; - bool m_follow_symlinks; - QStringList m_exclude_files; - QHash m_extra_files; + QString m_destinationPrefix; + bool m_followSymlinks; + QStringList m_excludeFiles; + QHash m_extraFiles; - QFuture m_build_zip_future; - QFutureWatcher m_build_zip_watcher; + QFuture m_buildZipFuture; + QFutureWatcher m_buildZipWatcher; }; } // namespace MMCZip \ No newline at end of file diff --git a/launcher/archive/ExtractZipTask.cpp b/launcher/archive/ExtractZipTask.cpp index 7dd002017..b958640c9 100644 --- a/launcher/archive/ExtractZipTask.cpp +++ b/launcher/archive/ExtractZipTask.cpp @@ -25,14 +25,14 @@ namespace MMCZip { void ExtractZipTask::executeTask() { - m_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return extractZip(); }); - connect(&m_zip_watcher, &QFutureWatcher::finished, this, &ExtractZipTask::finish); - m_zip_watcher.setFuture(m_zip_future); + m_zipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return extractZip(); }); + connect(&m_zipWatcher, &QFutureWatcher::finished, this, &ExtractZipTask::finish); + m_zipWatcher.setFuture(m_zipFuture); } auto ExtractZipTask::extractZip() -> ZipResult { - auto target = m_output_dir.absolutePath(); + auto target = m_outputDir.absolutePath(); auto target_top_dir = QUrl::fromLocalFile(target); QStringList extracted; @@ -52,8 +52,9 @@ auto ExtractZipTask::extractZip() -> ZipResult setStatus("Extracting files..."); setProgress(0, m_input.getFiles().count()); ZipResult result; + auto fileName = m_input.getZipName(); if (!m_input.parse([this, &result, &target, &target_top_dir, ext, &extracted](ArchiveReader::File* f) { - if (m_zip_future.isCanceled()) + if (m_zipFuture.isCanceled()) return false; setProgress(m_progress + 1, m_progressTotal); QString file_name = f->filename(); @@ -104,17 +105,16 @@ auto ExtractZipTask::extractZip() -> ZipResult return true; })) { FS::removeFiles(extracted); - return result.has_value() || m_zip_future.isCanceled() ? result - : ZipResult(tr("Failed to parse file %1").arg(m_input.getZipName())); + return result.has_value() ? result : ZipResult(tr("Failed to parse file %1").arg(fileName)); } return ZipResult(); } void ExtractZipTask::finish() { - if (m_zip_future.isCanceled()) { + if (m_zipFuture.isCanceled()) { emitAborted(); - } else if (auto result = m_zip_future.result(); result.has_value()) { + } else if (auto result = m_zipFuture.result(); result.has_value()) { emitFailed(result.value()); } else { emitSucceeded(); @@ -123,8 +123,8 @@ void ExtractZipTask::finish() bool ExtractZipTask::abort() { - if (m_zip_future.isRunning()) { - m_zip_future.cancel(); + if (m_zipFuture.isRunning()) { + m_zipFuture.cancel(); // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not occur // immediately. return true; diff --git a/launcher/archive/ExtractZipTask.h b/launcher/archive/ExtractZipTask.h index a9ad0a548..284d873fe 100644 --- a/launcher/archive/ExtractZipTask.h +++ b/launcher/archive/ExtractZipTask.h @@ -29,7 +29,7 @@ class ExtractZipTask : public Task { Q_OBJECT public: ExtractZipTask(QString input, QDir outputDir, QString subdirectory = "") - : m_input(input), m_output_dir(outputDir), m_subdirectory(subdirectory) + : m_input(input), m_outputDir(outputDir), m_subdirectory(subdirectory) {} virtual ~ExtractZipTask() = default; @@ -44,10 +44,10 @@ class ExtractZipTask : public Task { private: ArchiveReader m_input; - QDir m_output_dir; + QDir m_outputDir; QString m_subdirectory; - QFuture m_zip_future; - QFutureWatcher m_zip_watcher; + QFuture m_zipFuture; + QFutureWatcher m_zipWatcher; }; } // namespace MMCZip \ No newline at end of file