improve archive detection

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2025-12-09 22:56:42 +02:00
parent 40d1dccb9b
commit 808b09c403
No known key found for this signature in database
GPG key ID: 55EF5DA53DB36318
3 changed files with 50 additions and 49 deletions

View file

@ -108,70 +108,72 @@ void InstanceImportTask::downloadFromUrl()
filesNetJob->start(); filesNetJob->start();
} }
QString InstanceImportTask::getRootFromZip(QStringList files) QString cleanPath(QString path)
{ {
if (!isRunning()) { if (path == ".")
return {}; return QString();
} QString result = path;
auto cleanPath = [](QString path) { if (result.startsWith("./"))
if (path == ".") result = result.mid(2);
return QString(); return result;
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 {};
} }
void InstanceImportTask::processZipPack() void InstanceImportTask::processZipPack()
{ {
setStatus(tr("Attempting to determine instance type")); setStatus(tr("Attempting to determine instance type"));
setDetails("");
QDir extractDir(m_stagingPath); QDir extractDir(m_stagingPath);
qDebug() << "Attempting to create instance from" << m_archivePath; qDebug() << "Attempting to create instance from" << m_archivePath;
// open the zip and find relevant files in it // open the zip and find relevant files in it
MMCZip::ArchiveReader packZip(m_archivePath); MMCZip::ArchiveReader packZip(m_archivePath);
if (!packZip.collectFiles()) {
emitFailed(tr("Unable to open supplied modpack zip file."));
return;
}
qDebug() << "Attempting to determine instance type"; qDebug() << "Attempting to determine instance type";
QString root; QString root;
// NOTE: Prioritize modpack platforms that aren't searched for recursively. // 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 // 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 // https://docs.modrinth.com/docs/modpacks/format_definition/#storage
if (packZip.exists("/modrinth.index.json")) { auto detectInstance = [this, &extractDir, &root](MMCZip::ArchiveReader::File* f, bool& stop) {
// process as Modrinth pack if (!isRunning()) {
qDebug() << "Modrinth:" << true; stop = true;
m_modpackType = ModpackType::Modrinth; return true;
} else if (packZip.exists("/bin/modpack.jar") || packZip.exists("/bin/version.json")) { }
// process as Technic pack auto fileName = f->filename();
qDebug() << "Technic:" << true; if (fileName == "/modrinth.index.json") {
extractDir.mkpath("minecraft"); // process as Modrinth pack
extractDir.cd("minecraft"); qDebug() << "Modrinth:" << true;
m_modpackType = ModpackType::Technic; m_modpackType = ModpackType::Modrinth;
} else { stop = true;
root = getRootFromZip(packZip.getFiles()); } else if (fileName == "/bin/modpack.jar" || fileName == "/bin/version.json") {
setDetails(""); // 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) { if (m_modpackType == ModpackType::Unknown) {
emitFailed(tr("Archive does not contain a recognized modpack type.")); emitFailed(tr("Archive does not contain a recognized modpack type."));

View file

@ -56,7 +56,6 @@ class InstanceImportTask : public InstanceTask {
void processTechnic(); void processTechnic();
void processFlame(); void processFlame();
void processModrinth(); void processModrinth();
QString getRootFromZip(QStringList files);
private slots: private slots:
void processZipPack(); void processZipPack();

View file

@ -165,7 +165,7 @@ bool ArchiveReader::parse(std::function<bool(File*, bool&)> doStuff)
bool breakControl = false; bool breakControl = false;
while (f->readNextHeader() == ARCHIVE_OK) { 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(); qCritical() << "Failed to parse file:" << f->filename() << "-" << f->error();
return false; return false;
} }