diff --git a/launcher/InstanceCreationTask.cpp b/launcher/InstanceCreationTask.cpp index 3971effa..73dc1789 100644 --- a/launcher/InstanceCreationTask.cpp +++ b/launcher/InstanceCreationTask.cpp @@ -25,9 +25,13 @@ void InstanceCreationTask::executeTask() return; qWarning() << "Instance creation failed!"; - if (!m_error_message.isEmpty()) + if (!m_error_message.isEmpty()) { qWarning() << "Reason: " << m_error_message; - emitFailed(tr("Error while creating new instance.")); + emitFailed(tr("Error while creating new instance:\n%1").arg(m_error_message)); + } else { + emitFailed(tr("Error while creating new instance.")); + } + return; } diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index b490620d..5f459649 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -164,18 +164,14 @@ void InstanceImportTask::processZipPack() } else { - QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg"); - QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json"); + QStringList paths_to_ignore { "overrides/" }; - if (!mmcRoot.isNull()) - { + if (QString mmcRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg", paths_to_ignore); !mmcRoot.isNull()) { // process as MultiMC instance/pack qDebug() << "MultiMC:" << mmcRoot; root = mmcRoot; m_modpackType = ModpackType::MultiMC; - } - else if(!flameRoot.isNull()) - { + } else if (QString flameRoot = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json", paths_to_ignore); !flameRoot.isNull()) { // process as Flame pack qDebug() << "Flame:" << flameRoot; root = flameRoot; diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 9f4e968f..f6600343 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -39,6 +39,7 @@ #include "MMCZip.h" #include "FileSystem.h" +#include #include // ours @@ -228,23 +229,27 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const } // ours -QString MMCZip::findFolderOfFileInZip(QuaZip * zip, const QString & what, const QString &root) +QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root) { QuaZipDir rootDir(zip, root); - for(auto fileName: rootDir.entryList(QDir::Files)) - { - if(fileName == what) + for (auto&& fileName : rootDir.entryList(QDir::Files)) { + if (fileName == what) return root; + + QCoreApplication::processEvents(); } - for(auto fileName: rootDir.entryList(QDir::Dirs)) - { - QString result = findFolderOfFileInZip(zip, what, root + fileName); - if(!result.isEmpty()) - { + + // Recurse the search to non-ignored subfolders + for (auto&& fileName : rootDir.entryList(QDir::Dirs)) { + if (ignore_paths.contains(fileName)) + continue; + + QString result = findFolderOfFileInZip(zip, what, ignore_paths, root + fileName); + if (!result.isEmpty()) return result; - } } - return QString(); + + return {}; } // ours diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index ce9775bd..81f9cb90 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -80,9 +80,11 @@ namespace MMCZip /** * Find a single file in archive by file name (not path) * + * \param ignore_paths paths to skip when recursing the search + * * \return the path prefix where the file is */ - QString findFolderOfFileInZip(QuaZip * zip, const QString & what, const QString &root = QString("")); + QString findFolderOfFileInZip(QuaZip * zip, const QString & what, const QStringList& ignore_paths = {}, const QString &root = QString("")); /** * Find a multiple files of the same name in archive by file name diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 25b56fbd..7f1beb1a 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -42,12 +42,25 @@ void Flame::FileResolvingTask::executeTask() void Flame::FileResolvingTask::netJobFinished() { setProgress(1, 3); - int index = 0; // job to check modrinth for blocked projects m_checkJob = new NetJob("Modrinth check", m_network); blockedProjects = QMap(); - auto doc = Json::requireDocument(*result); - auto array = Json::requireArray(doc.object()["data"]); + + QJsonDocument doc; + QJsonArray array; + + try { + doc = Json::requireDocument(*result); + array = Json::requireArray(doc.object()["data"]); + } catch (Json::JsonException& e) { + qCritical() << "Non-JSON data returned from the CF API"; + qCritical() << e.cause(); + + emitFailed(tr("Invalid data returned from the API.")); + + return; + } + for (QJsonValueRef file : array) { auto fileid = Json::requireInteger(Json::requireObject(file)["id"]); auto& out = m_toProcess.files[fileid]; @@ -68,7 +81,6 @@ void Flame::FileResolvingTask::netJobFinished() blockedProjects.insert(&out, output); } } - index++; } connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 91554b58..a00c948a 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -338,6 +338,7 @@ bool FlameCreationTask::createInstance() connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::failed, [&](QString reason) { m_mod_id_resolver.reset(); setError(tr("Unable to resolve mod IDs:\n") + reason); + loop.quit(); }); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::progress, this, &FlameCreationTask::setProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::status, this, &FlameCreationTask::setStatus);