From 808b09c403f3bbecc9aaa38a3eec9baf040bf913 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 9 Dec 2025 22:56:42 +0200 Subject: [PATCH] improve archive detection Signed-off-by: Trial97 --- launcher/InstanceImportTask.cpp | 96 +++++++++++++++--------------- launcher/InstanceImportTask.h | 1 - launcher/archive/ArchiveReader.cpp | 2 +- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index d3cc3bd02..554a563a8 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -108,70 +108,72 @@ 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() { setStatus(tr("Attempting to determine instance type")); + setDetails(""); QDir extractDir(m_stagingPath); qDebug() << "Attempting to create instance from" << m_archivePath; // 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; }