diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 92cc89510..04600daa9 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -59,8 +59,6 @@ #include #include -#include - InstanceImportTask::InstanceImportTask(const QUrl& sourceUrl, QWidget* parent, QMap&& extra_info) : m_sourceUrl(sourceUrl), m_extra_info(extra_info), m_parent(parent) {} diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index c3c833926..4c9e6feb5 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -40,8 +40,6 @@ #include #include "InstanceTask.h" -class QuaZip; - class InstanceImportTask : public InstanceTask { Q_OBJECT public: diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 6a051ba63..349c6a809 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -37,9 +37,6 @@ #include "MMCZip.h" #include #include -#include -#include -#include #include "FileSystem.h" #include "archive/ArchiveReader.h" @@ -201,21 +198,8 @@ std::optional extractSubDir(ArchiveReader* zip, const QString& subd return extracted; } - int flags; - - /* Select which attributes we want to restore. */ - flags = ARCHIVE_EXTRACT_TIME; - flags |= ARCHIVE_EXTRACT_PERM; - flags |= ARCHIVE_EXTRACT_ACL; - flags |= ARCHIVE_EXTRACT_FFLAGS; - - std::unique_ptr extPtr(archive_write_disk_new(), [](archive* a) { - archive_write_close(a); - archive_write_free(a); - }); + auto extPtr = ArchiveWriter::createDiskWriter(); auto ext = extPtr.get(); - archive_write_disk_set_options(ext, flags); - archive_write_disk_set_standard_lookup(ext); if (!zip->parse([&subdir, &target, &target_top_dir, ext, &extracted](ArchiveReader::File* f) { QString file_name = f->filename(); @@ -309,21 +293,8 @@ bool extractFile(QString fileCompressed, QString file, QString target) if (!f) { return false; } - int flags; - - /* Select which attributes we want to restore. */ - flags = ARCHIVE_EXTRACT_TIME; - flags |= ARCHIVE_EXTRACT_PERM; - flags |= ARCHIVE_EXTRACT_ACL; - flags |= ARCHIVE_EXTRACT_FFLAGS; - - std::unique_ptr extPtr(archive_write_disk_new(), [](archive* a) { - archive_write_close(a); - archive_write_free(a); - }); + auto extPtr = ArchiveWriter::createDiskWriter(); auto ext = extPtr.get(); - archive_write_disk_set_options(ext, flags); - archive_write_disk_set_standard_lookup(ext); return f->writeFile(ext, target); } diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index ab0f2d660..04fe90379 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -36,8 +36,6 @@ #pragma once -#include -#include #include #include #include @@ -46,14 +44,12 @@ #include #include #include -#include #include #include "archive/ArchiveReader.h" #if defined(LAUNCHER_APPLICATION) #include "minecraft/mod/Mod.h" #endif -#include "tasks/Task.h" namespace MMCZip { using FilterFileFunction = std::function; diff --git a/launcher/archive/ArchiveReader.cpp b/launcher/archive/ArchiveReader.cpp index e48d168ae..b2894b797 100644 --- a/launcher/archive/ArchiveReader.cpp +++ b/launcher/archive/ArchiveReader.cpp @@ -40,7 +40,6 @@ QByteArray ArchiveReader::File::readAll(int* outStatus) if (outStatus) { *outStatus = status; } - archive_read_close(m_archive.get()); return data; } @@ -131,7 +130,7 @@ bool ArchiveReader::File::writeFile(archive* out, QString targetFileName, bool n return (r > ARCHIVE_WARN); } -bool ArchiveReader::parse(std::function doStuff) +bool ArchiveReader::parse(std::function doStuff) { auto f = std::make_unique(); auto a = f->m_archive.get(); @@ -143,16 +142,24 @@ bool ArchiveReader::parse(std::function doStuff) return false; } + bool breakControl = false; while (f->readNextHeader() == ARCHIVE_OK) { - if (!doStuff(f.get())) { + if (!doStuff(f.get(), breakControl)) { qCritical() << "Failed to parse file:" << f->filename() << "-" << f->error(); return false; } + if (breakControl) { + break; + } } archive_read_close(a); return true; } +bool ArchiveReader::parse(std::function doStuff) +{ + return parse([doStuff](File* f, bool&) { return doStuff(f); }); +} bool ArchiveReader::File::isFile() { diff --git a/launcher/archive/ArchiveReader.h b/launcher/archive/ArchiveReader.h index 5cbf75308..383dfc760 100644 --- a/launcher/archive/ArchiveReader.h +++ b/launcher/archive/ArchiveReader.h @@ -45,6 +45,7 @@ class ArchiveReader { std::unique_ptr goToFile(QString filename); bool parse(std::function); + bool parse(std::function); private: QString m_archivePath; diff --git a/launcher/archive/ArchiveWriter.cpp b/launcher/archive/ArchiveWriter.cpp index a994f06aa..cc3b4ab27 100644 --- a/launcher/archive/ArchiveWriter.cpp +++ b/launcher/archive/ArchiveWriter.cpp @@ -176,4 +176,21 @@ bool ArchiveWriter::addFile(ArchiveReader::File* f) { return f->writeFile(m_archive, "", true); } +std::unique_ptr ArchiveWriter::createDiskWriter() +{ + int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS; + + std::unique_ptr extPtr(archive_write_disk_new(), [](archive* a) { + if (a) { + archive_write_close(a); + archive_write_free(a); + } + }); + + archive* ext = extPtr.get(); + archive_write_disk_set_options(ext, flags); + archive_write_disk_set_standard_lookup(ext); + + return extPtr; +} } // namespace MMCZip \ No newline at end of file diff --git a/launcher/archive/ArchiveWriter.h b/launcher/archive/ArchiveWriter.h index 2e26e4b5e..3dac29405 100644 --- a/launcher/archive/ArchiveWriter.h +++ b/launcher/archive/ArchiveWriter.h @@ -21,6 +21,8 @@ class ArchiveWriter { bool addFile(const QString& fileDest, const QByteArray& data); bool addFile(ArchiveReader::File* f); + static std::unique_ptr createDiskWriter(); + private: struct archive* m_archive = nullptr; QString m_filename; diff --git a/launcher/archive/ExtractZipTask.cpp b/launcher/archive/ExtractZipTask.cpp index 69069d550..15839ca45 100644 --- a/launcher/archive/ExtractZipTask.cpp +++ b/launcher/archive/ExtractZipTask.cpp @@ -2,6 +2,7 @@ #include #include "FileSystem.h" #include "archive/ArchiveReader.h" +#include "archive/ArchiveWriter.h" namespace MMCZip { @@ -28,21 +29,8 @@ auto ExtractZipTask::extractZip() -> ZipResult return ZipResult(); } - int flags; - - /* Select which attributes we want to restore. */ - flags = ARCHIVE_EXTRACT_TIME; - flags |= ARCHIVE_EXTRACT_PERM; - flags |= ARCHIVE_EXTRACT_ACL; - flags |= ARCHIVE_EXTRACT_FFLAGS; - - std::unique_ptr extPtr(archive_write_disk_new(), [](archive* a) { - archive_write_close(a); - archive_write_free(a); - }); + auto extPtr = ArchiveWriter::createDiskWriter(); auto ext = extPtr.get(); - archive_write_disk_set_options(ext, flags); - archive_write_disk_set_standard_lookup(ext); setStatus("Extracting files..."); setProgress(0, m_input.getFiles().count()); diff --git a/launcher/java/download/ArchiveDownloadTask.cpp b/launcher/java/download/ArchiveDownloadTask.cpp index e632225b0..92357930b 100644 --- a/launcher/java/download/ArchiveDownloadTask.cpp +++ b/launcher/java/download/ArchiveDownloadTask.cpp @@ -16,7 +16,6 @@ * along with this program. If not, see . */ #include "java/download/ArchiveDownloadTask.h" -#include #include #include "Application.h" diff --git a/launcher/minecraft/World.cpp b/launcher/minecraft/World.cpp index 854bb2ee8..8f7174a07 100644 --- a/launcher/minecraft/World.cpp +++ b/launcher/minecraft/World.cpp @@ -43,9 +43,6 @@ #include #include #include -#include -#include -#include #include #include #include diff --git a/launcher/minecraft/launch/ExtractNatives.cpp b/launcher/minecraft/launch/ExtractNatives.cpp index afe091758..3174e0e2a 100644 --- a/launcher/minecraft/launch/ExtractNatives.cpp +++ b/launcher/minecraft/launch/ExtractNatives.cpp @@ -17,11 +17,10 @@ #include #include -#include -#include #include #include "FileSystem.h" -#include "MMCZip.h" +#include "archive/ArchiveReader.h" +#include "archive/ArchiveWriter.h" #ifdef major #undef major @@ -41,30 +40,21 @@ static QString replaceSuffix(QString target, const QString& suffix, const QStrin static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibHack) { - QuaZip zip(source); - if (!zip.open(QuaZip::mdUnzip)) { - return false; - } + MMCZip::ArchiveReader zip(source); QDir directory(targetFolder); - if (!zip.goToFirstFile()) { - return false; - } - do { - QString name = zip.getCurrentFileName(); + + auto extPtr = MMCZip::ArchiveWriter::createDiskWriter(); + auto ext = extPtr.get(); + + return zip.parse([applyJnilibHack, directory, ext](MMCZip::ArchiveReader::File* f) { + QString name = f->filename(); auto lowercase = name.toLower(); if (applyJnilibHack) { name = replaceSuffix(name, ".jnilib", ".dylib"); } QString absFilePath = directory.absoluteFilePath(name); - if (!JlCompress::extractFile(&zip, "", absFilePath)) { - return false; - } - } while (zip.goToNextFile()); - zip.close(); - if (zip.getZipError() != 0) { - return false; - } - return true; + return f->writeFile(ext, absFilePath); + }); } void ExtractNatives::executeTask() diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp index c37a25c21..768ac086e 100644 --- a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp @@ -23,12 +23,9 @@ #include "FileSystem.h" #include "Json.h" +#include "archive/ArchiveReader.h" #include "minecraft/mod/ResourcePack.h" -#include -#include -#include - #include namespace DataPackUtils { @@ -111,72 +108,72 @@ bool processZIP(DataPack* pack, ProcessingLevel level) { Q_ASSERT(pack->type() == ResourceType::ZIPFILE); - QuaZip zip(pack->fileinfo().filePath()); - if (!zip.open(QuaZip::mdUnzip)) + MMCZip::ArchiveReader zip(pack->fileinfo().filePath()); + + bool metaParsed = false; + bool directoryFound = false; + bool iconParsed = false; + bool mcmeta_result = false; + bool pack_png_result = false; + if (!zip.parse([&metaParsed, &directoryFound, &iconParsed, &mcmeta_result, &pack_png_result, pack, level]( + MMCZip::ArchiveReader::File* f, bool& breakControl) { + bool skip = true; + if (!metaParsed && f->filename() == "pack.mcmeta") { + metaParsed = true; + skip = false; + auto data = f->readAll(); + + mcmeta_result = DataPackUtils::processMCMeta(pack, std::move(data)); + + if (!mcmeta_result) { + breakControl = true; + return true; // mcmeta invalid + } + } + if (!directoryFound) { + QString normalizedPath = QDir::cleanPath(pack->directory()) + QLatin1Char('/'); + if (normalizedPath.startsWith('/')) + normalizedPath.remove(0, 1); + directoryFound = f->filename().startsWith(normalizedPath, Qt::CaseInsensitive); + } + if (!iconParsed && level != ProcessingLevel::BasicInfoOnly && f->filename() == "pack.png") { + iconParsed = true; + skip = false; + auto data = f->readAll(); + + pack_png_result = DataPackUtils::processPackPNG(pack, std::move(data)); + if (!pack_png_result) { + breakControl = true; + return true; // pack.png invalid + } + } + if (skip) { + f->skip(); + } + if (metaParsed && directoryFound && (level == ProcessingLevel::BasicInfoOnly || iconParsed)) { + breakControl = true; + } + + return true; + })) { return false; // can't open zip file - - QuaZipFile file(&zip); - - auto mcmeta_invalid = [&pack]() { + } + if (!mcmeta_result) { qWarning() << "Data pack at" << pack->fileinfo().filePath() << "does not have a valid pack.mcmeta"; return false; // the mcmeta is not optional - }; - - if (zip.setCurrentFile("pack.mcmeta")) { - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open file in zip."; - zip.close(); - return mcmeta_invalid(); - } - - auto data = file.readAll(); - - bool mcmeta_result = DataPackUtils::processMCMeta(pack, std::move(data)); - - file.close(); - if (!mcmeta_result) { - return mcmeta_invalid(); // mcmeta invalid - } - } else { - return mcmeta_invalid(); // could not set pack.mcmeta as current file. } - - QuaZipDir zipDir(&zip); - if (!zipDir.exists(pack->directory())) { + if (!directoryFound) { return false; // data dir does not exists at zip root } if (level == ProcessingLevel::BasicInfoOnly) { - zip.close(); return true; // only need basic info already checked } - auto png_invalid = [&pack]() { + if (!pack_png_result) { qWarning() << "Data pack at" << pack->fileinfo().filePath() << "does not have a valid pack.png"; return true; // the png is optional - }; - - if (zip.setCurrentFile("pack.png")) { - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open file in zip."; - zip.close(); - return png_invalid(); - } - - auto data = file.readAll(); - - bool pack_png_result = DataPackUtils::processPackPNG(pack, std::move(data)); - - file.close(); - zip.close(); - if (!pack_png_result) { - return png_invalid(); // pack.png invalid - } - } else { - zip.close(); - return png_invalid(); // could not set pack.mcmeta as current file. } - zip.close(); return true; } @@ -321,28 +318,17 @@ bool processPackPNG(const DataPack* pack) return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740 } case ResourceType::ZIPFILE: { - QuaZip zip(pack->fileinfo().filePath()); - if (!zip.open(QuaZip::mdUnzip)) - return false; // can't open zip file + MMCZip::ArchiveReader zip(pack->fileinfo().filePath()); + auto f = zip.goToFile("pack.png"); + if (!f) { + return png_invalid(); + } + auto data = f->readAll(); - QuaZipFile file(&zip); - if (zip.setCurrentFile("pack.png")) { - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open file in zip."; - zip.close(); - return png_invalid(); - } + bool pack_png_result = DataPackUtils::processPackPNG(pack, std::move(data)); - auto data = file.readAll(); - - bool pack_png_result = DataPackUtils::processPackPNG(pack, std::move(data)); - - file.close(); - if (!pack_png_result) { - return png_invalid(); // pack.png invalid - } - } else { - return png_invalid(); // could not set pack.mcmeta as current file. + if (!pack_png_result) { + return png_invalid(); // pack.png invalid } return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740 } diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp index a6ecc5353..3443966d5 100644 --- a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp @@ -22,10 +22,7 @@ #include "LocalShaderPackParseTask.h" #include "FileSystem.h" - -#include -#include -#include +#include "archive/ArchiveReader.h" namespace ShaderPackUtils { @@ -63,25 +60,19 @@ bool processZIP(ShaderPack& pack, ProcessingLevel level) { Q_ASSERT(pack.type() == ResourceType::ZIPFILE); - QuaZip zip(pack.fileinfo().filePath()); - if (!zip.open(QuaZip::mdUnzip)) + MMCZip::ArchiveReader zip(pack.fileinfo().filePath()); + if (!zip.collectFiles()) return false; // can't open zip file - QuaZipFile file(&zip); - - QuaZipDir zipDir(&zip); - if (!zipDir.exists("/shaders")) { + if (!zip.exists("/shaders")) { return false; // assets dir does not exists at zip root } pack.setPackFormat(ShaderPackFormat::VALID); if (level == ProcessingLevel::BasicInfoOnly) { - zip.close(); return true; // only need basic info already checked } - zip.close(); - return true; } diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp index 18020808a..921b6ce09 100644 --- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp @@ -20,9 +20,7 @@ #include "LocalTexturePackParseTask.h" #include "FileSystem.h" - -#include -#include +#include "archive/ArchiveReader.h" #include @@ -91,54 +89,35 @@ bool processZIP(TexturePack& pack, ProcessingLevel level) { Q_ASSERT(pack.type() == ResourceType::ZIPFILE); - QuaZip zip(pack.fileinfo().filePath()); - if (!zip.open(QuaZip::mdUnzip)) - return false; + MMCZip::ArchiveReader zip(pack.fileinfo().filePath()); - QuaZipFile file(&zip); + { + auto file = zip.goToFile("pack.txt"); + if (file) { + auto data = file->readAll(); - if (zip.setCurrentFile("pack.txt")) { - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open file in zip."; - zip.close(); - return false; - } + bool packTXT_result = TexturePackUtils::processPackTXT(pack, std::move(data)); - auto data = file.readAll(); - - bool packTXT_result = TexturePackUtils::processPackTXT(pack, std::move(data)); - - file.close(); - if (!packTXT_result) { - return false; + if (!packTXT_result) { + return false; + } } } if (level == ProcessingLevel::BasicInfoOnly) { - zip.close(); return true; } - if (zip.setCurrentFile("pack.png")) { - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open file in zip."; - zip.close(); - return false; - } - - auto data = file.readAll(); + auto file = zip.goToFile("pack.png"); + if (file) { + auto data = file->readAll(); bool packPNG_result = TexturePackUtils::processPackPNG(pack, std::move(data)); - file.close(); - zip.close(); if (!packPNG_result) { return false; } } - - zip.close(); - return true; } @@ -189,32 +168,19 @@ bool processPackPNG(const TexturePack& pack) return false; } case ResourceType::ZIPFILE: { - QuaZip zip(pack.fileinfo().filePath()); - if (!zip.open(QuaZip::mdUnzip)) - return false; // can't open zip file + MMCZip::ArchiveReader zip(pack.fileinfo().filePath()); - QuaZipFile file(&zip); - if (zip.setCurrentFile("pack.png")) { - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open file in zip."; - zip.close(); - return png_invalid(); - } - - auto data = file.readAll(); + auto file = zip.goToFile("pack.png"); + if (file) { + auto data = file->readAll(); bool pack_png_result = TexturePackUtils::processPackPNG(pack, std::move(data)); - file.close(); if (!pack_png_result) { - zip.close(); return png_invalid(); // pack.png invalid } - } else { - zip.close(); - return png_invalid(); // could not set pack.mcmeta as current file. } - return false; + return png_invalid(); // could not set pack.mcmeta as current file. } default: qWarning() << "Invalid type for resource pack parse task!"; diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp index d45f537fa..e763bf64b 100644 --- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp @@ -23,13 +23,11 @@ #include "LocalWorldSaveParseTask.h" #include "FileSystem.h" - -#include -#include -#include +#include "archive/ArchiveReader.h" #include #include +#include namespace WorldSaveUtils { @@ -105,22 +103,41 @@ bool processFolder(WorldSave& save, ProcessingLevel level) /// QString , /// bool /// ) -static std::tuple contains_level_dat(QuaZip& zip) +static std::tuple contains_level_dat(QString fileName) { + MMCZip::ArchiveReader zip(fileName); + if (!zip.collectFiles()) { + return std::make_tuple(false, "", false); + } bool saves = false; - QuaZipDir zipDir(&zip); - if (zipDir.exists("/saves")) { + if (zip.exists("/saves")) { saves = true; - zipDir.cd("/saves"); } - for (auto const& entry : zipDir.entryList()) { - zipDir.cd(entry); - if (zipDir.exists("level.dat")) { - return std::make_tuple(true, entry, saves); + for (auto file : zip.getFiles()) { + QString relativePath = file; + if (saves) { + if (!relativePath.startsWith("saves/", Qt::CaseInsensitive)) + continue; + relativePath = relativePath.mid(QString("saves/").length()); + } + if (!relativePath.endsWith("/level.dat", Qt::CaseInsensitive)) + continue; + + int slashIndex = relativePath.indexOf('/'); + if (slashIndex == -1) + continue; // malformed: no slash between saves/ and level.dat + + QString worldName = relativePath.left(slashIndex); + QString remaining = relativePath.mid(slashIndex + 1); + + // Check that there's nothing between worldName/ and level.dat + if (remaining == "level.dat") { + QString worldDir = (saves ? "saves/" : "") + worldName; + return std::make_tuple(true, worldDir, saves); } - zipDir.cd(".."); } + return std::make_tuple(false, "", saves); } @@ -128,19 +145,14 @@ bool processZIP(WorldSave& save, ProcessingLevel level) { Q_ASSERT(save.type() == ResourceType::ZIPFILE); - QuaZip zip(save.fileinfo().filePath()); - if (!zip.open(QuaZip::mdUnzip)) - return false; // can't open zip file - - auto [found, save_dir_name, found_saves_dir] = contains_level_dat(zip); - - if (save_dir_name.endsWith("/")) { - save_dir_name.chop(1); - } + auto [found, save_dir_name, found_saves_dir] = contains_level_dat(save.fileinfo().filePath()); if (!found) { return false; } + if (save_dir_name.endsWith("/")) { + save_dir_name.chop(1); + } save.setSaveDirName(save_dir_name); @@ -151,14 +163,11 @@ bool processZIP(WorldSave& save, ProcessingLevel level) } if (level == ProcessingLevel::BasicInfoOnly) { - zip.close(); return true; // only need basic info already checked } // reserved for more intensive processing - zip.close(); - return true; } diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index a3f045d02..f107e4700 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -39,8 +39,6 @@ #include #include -#include - #include "FileSystem.h" #include "Json.h" #include "MMCZip.h" diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.h b/launcher/modplatform/legacy_ftb/PackInstallTask.h index 9d236decc..d3b8146ee 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.h +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.h @@ -1,6 +1,4 @@ #pragma once -#include -#include #include "InstanceTask.h" #include "PackHelpers.h" #include "meta/Index.h" diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.h b/launcher/modplatform/technic/SingleZipPackInstallTask.h index 09fc7b658..9dd54458d 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.h +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.h @@ -19,8 +19,6 @@ #include "archive/ArchiveReader.h" #include "net/NetJob.h" -#include - #include #include #include diff --git a/nix/unwrapped.nix b/nix/unwrapped.nix index d9144410f..1bdf193f9 100644 --- a/nix/unwrapped.nix +++ b/nix/unwrapped.nix @@ -17,6 +17,7 @@ zlib, msaClientID ? null, gamemodeSupport ? stdenv.hostPlatform.isLinux, + libarchive, }: assert lib.assertMsg ( gamemodeSupport -> stdenv.hostPlatform.isLinux @@ -82,6 +83,7 @@ stdenv.mkDerivation { kdePackages.qtbase kdePackages.qtnetworkauth kdePackages.quazip + libarchive tomlplusplus zlib ]