mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-08-03 19:37:45 -04:00
move more zip parsings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
43ceacbe56
commit
e0fad4a784
@ -59,8 +59,6 @@
|
|||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
|
|
||||||
InstanceImportTask::InstanceImportTask(const QUrl& sourceUrl, QWidget* parent, QMap<QString, QString>&& extra_info)
|
InstanceImportTask::InstanceImportTask(const QUrl& sourceUrl, QWidget* parent, QMap<QString, QString>&& extra_info)
|
||||||
: m_sourceUrl(sourceUrl), m_extra_info(extra_info), m_parent(parent)
|
: m_sourceUrl(sourceUrl), m_extra_info(extra_info), m_parent(parent)
|
||||||
{}
|
{}
|
||||||
|
@ -40,8 +40,6 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "InstanceTask.h"
|
#include "InstanceTask.h"
|
||||||
|
|
||||||
class QuaZip;
|
|
||||||
|
|
||||||
class InstanceImportTask : public InstanceTask {
|
class InstanceImportTask : public InstanceTask {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -37,9 +37,6 @@
|
|||||||
#include "MMCZip.h"
|
#include "MMCZip.h"
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
#include <qcontainerfwd.h>
|
#include <qcontainerfwd.h>
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include <quazip/quazipfile.h>
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "archive/ArchiveReader.h"
|
#include "archive/ArchiveReader.h"
|
||||||
|
|
||||||
@ -201,21 +198,8 @@ std::optional<QStringList> extractSubDir(ArchiveReader* zip, const QString& subd
|
|||||||
return extracted;
|
return extracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags;
|
auto extPtr = ArchiveWriter::createDiskWriter();
|
||||||
|
|
||||||
/* 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<archive, void (*)(archive*)> extPtr(archive_write_disk_new(), [](archive* a) {
|
|
||||||
archive_write_close(a);
|
|
||||||
archive_write_free(a);
|
|
||||||
});
|
|
||||||
auto ext = extPtr.get();
|
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) {
|
if (!zip->parse([&subdir, &target, &target_top_dir, ext, &extracted](ArchiveReader::File* f) {
|
||||||
QString file_name = f->filename();
|
QString file_name = f->filename();
|
||||||
@ -309,21 +293,8 @@ bool extractFile(QString fileCompressed, QString file, QString target)
|
|||||||
if (!f) {
|
if (!f) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int flags;
|
auto extPtr = ArchiveWriter::createDiskWriter();
|
||||||
|
|
||||||
/* 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<archive, void (*)(archive*)> extPtr(archive_write_disk_new(), [](archive* a) {
|
|
||||||
archive_write_close(a);
|
|
||||||
archive_write_free(a);
|
|
||||||
});
|
|
||||||
auto ext = extPtr.get();
|
auto ext = extPtr.get();
|
||||||
archive_write_disk_set_options(ext, flags);
|
|
||||||
archive_write_disk_set_standard_lookup(ext);
|
|
||||||
|
|
||||||
return f->writeFile(ext, target);
|
return f->writeFile(ext, target);
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <quazip.h>
|
|
||||||
#include <quazip/JlCompress.h>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
@ -46,14 +44,12 @@
|
|||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "archive/ArchiveReader.h"
|
#include "archive/ArchiveReader.h"
|
||||||
|
|
||||||
#if defined(LAUNCHER_APPLICATION)
|
#if defined(LAUNCHER_APPLICATION)
|
||||||
#include "minecraft/mod/Mod.h"
|
#include "minecraft/mod/Mod.h"
|
||||||
#endif
|
#endif
|
||||||
#include "tasks/Task.h"
|
|
||||||
|
|
||||||
namespace MMCZip {
|
namespace MMCZip {
|
||||||
using FilterFileFunction = std::function<bool(const QFileInfo&)>;
|
using FilterFileFunction = std::function<bool(const QFileInfo&)>;
|
||||||
|
@ -40,7 +40,6 @@ QByteArray ArchiveReader::File::readAll(int* outStatus)
|
|||||||
if (outStatus) {
|
if (outStatus) {
|
||||||
*outStatus = status;
|
*outStatus = status;
|
||||||
}
|
}
|
||||||
archive_read_close(m_archive.get());
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +130,7 @@ bool ArchiveReader::File::writeFile(archive* out, QString targetFileName, bool n
|
|||||||
return (r > ARCHIVE_WARN);
|
return (r > ARCHIVE_WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArchiveReader::parse(std::function<bool(File*)> doStuff)
|
bool ArchiveReader::parse(std::function<bool(File*, bool&)> doStuff)
|
||||||
{
|
{
|
||||||
auto f = std::make_unique<File>();
|
auto f = std::make_unique<File>();
|
||||||
auto a = f->m_archive.get();
|
auto a = f->m_archive.get();
|
||||||
@ -143,16 +142,24 @@ bool ArchiveReader::parse(std::function<bool(File*)> doStuff)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool breakControl = false;
|
||||||
while (f->readNextHeader() == ARCHIVE_OK) {
|
while (f->readNextHeader() == ARCHIVE_OK) {
|
||||||
if (!doStuff(f.get())) {
|
if (!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;
|
||||||
}
|
}
|
||||||
|
if (breakControl) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
archive_read_close(a);
|
archive_read_close(a);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool ArchiveReader::parse(std::function<bool(File*)> doStuff)
|
||||||
|
{
|
||||||
|
return parse([doStuff](File* f, bool&) { return doStuff(f); });
|
||||||
|
}
|
||||||
|
|
||||||
bool ArchiveReader::File::isFile()
|
bool ArchiveReader::File::isFile()
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,7 @@ class ArchiveReader {
|
|||||||
|
|
||||||
std::unique_ptr<File> goToFile(QString filename);
|
std::unique_ptr<File> goToFile(QString filename);
|
||||||
bool parse(std::function<bool(File*)>);
|
bool parse(std::function<bool(File*)>);
|
||||||
|
bool parse(std::function<bool(File*, bool&)>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_archivePath;
|
QString m_archivePath;
|
||||||
|
@ -176,4 +176,21 @@ bool ArchiveWriter::addFile(ArchiveReader::File* f)
|
|||||||
{
|
{
|
||||||
return f->writeFile(m_archive, "", true);
|
return f->writeFile(m_archive, "", true);
|
||||||
}
|
}
|
||||||
|
std::unique_ptr<archive, void (*)(archive*)> ArchiveWriter::createDiskWriter()
|
||||||
|
{
|
||||||
|
int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;
|
||||||
|
|
||||||
|
std::unique_ptr<archive, void (*)(archive*)> 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
|
} // namespace MMCZip
|
@ -21,6 +21,8 @@ class ArchiveWriter {
|
|||||||
bool addFile(const QString& fileDest, const QByteArray& data);
|
bool addFile(const QString& fileDest, const QByteArray& data);
|
||||||
bool addFile(ArchiveReader::File* f);
|
bool addFile(ArchiveReader::File* f);
|
||||||
|
|
||||||
|
static std::unique_ptr<archive, void (*)(archive*)> createDiskWriter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct archive* m_archive = nullptr;
|
struct archive* m_archive = nullptr;
|
||||||
QString m_filename;
|
QString m_filename;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "archive/ArchiveReader.h"
|
#include "archive/ArchiveReader.h"
|
||||||
|
#include "archive/ArchiveWriter.h"
|
||||||
|
|
||||||
namespace MMCZip {
|
namespace MMCZip {
|
||||||
|
|
||||||
@ -28,21 +29,8 @@ auto ExtractZipTask::extractZip() -> ZipResult
|
|||||||
return ZipResult();
|
return ZipResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags;
|
auto extPtr = ArchiveWriter::createDiskWriter();
|
||||||
|
|
||||||
/* 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<archive, void (*)(archive*)> extPtr(archive_write_disk_new(), [](archive* a) {
|
|
||||||
archive_write_close(a);
|
|
||||||
archive_write_free(a);
|
|
||||||
});
|
|
||||||
auto ext = extPtr.get();
|
auto ext = extPtr.get();
|
||||||
archive_write_disk_set_options(ext, flags);
|
|
||||||
archive_write_disk_set_standard_lookup(ext);
|
|
||||||
|
|
||||||
setStatus("Extracting files...");
|
setStatus("Extracting files...");
|
||||||
setProgress(0, m_input.getFiles().count());
|
setProgress(0, m_input.getFiles().count());
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "java/download/ArchiveDownloadTask.h"
|
#include "java/download/ArchiveDownloadTask.h"
|
||||||
#include <quazip.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
@ -43,9 +43,6 @@
|
|||||||
#include <FileSystem.h>
|
#include <FileSystem.h>
|
||||||
#include <MMCZip.h>
|
#include <MMCZip.h>
|
||||||
#include <io/stream_reader.h>
|
#include <io/stream_reader.h>
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include <quazip/quazipfile.h>
|
|
||||||
#include <tag_primitive.h>
|
#include <tag_primitive.h>
|
||||||
#include <tag_string.h>
|
#include <tag_string.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -17,11 +17,10 @@
|
|||||||
#include <launch/LaunchTask.h>
|
#include <launch/LaunchTask.h>
|
||||||
#include <minecraft/MinecraftInstance.h>
|
#include <minecraft/MinecraftInstance.h>
|
||||||
|
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "MMCZip.h"
|
#include "archive/ArchiveReader.h"
|
||||||
|
#include "archive/ArchiveWriter.h"
|
||||||
|
|
||||||
#ifdef major
|
#ifdef major
|
||||||
#undef 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)
|
static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibHack)
|
||||||
{
|
{
|
||||||
QuaZip zip(source);
|
MMCZip::ArchiveReader zip(source);
|
||||||
if (!zip.open(QuaZip::mdUnzip)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QDir directory(targetFolder);
|
QDir directory(targetFolder);
|
||||||
if (!zip.goToFirstFile()) {
|
|
||||||
return false;
|
auto extPtr = MMCZip::ArchiveWriter::createDiskWriter();
|
||||||
}
|
auto ext = extPtr.get();
|
||||||
do {
|
|
||||||
QString name = zip.getCurrentFileName();
|
return zip.parse([applyJnilibHack, directory, ext](MMCZip::ArchiveReader::File* f) {
|
||||||
|
QString name = f->filename();
|
||||||
auto lowercase = name.toLower();
|
auto lowercase = name.toLower();
|
||||||
if (applyJnilibHack) {
|
if (applyJnilibHack) {
|
||||||
name = replaceSuffix(name, ".jnilib", ".dylib");
|
name = replaceSuffix(name, ".jnilib", ".dylib");
|
||||||
}
|
}
|
||||||
QString absFilePath = directory.absoluteFilePath(name);
|
QString absFilePath = directory.absoluteFilePath(name);
|
||||||
if (!JlCompress::extractFile(&zip, "", absFilePath)) {
|
return f->writeFile(ext, absFilePath);
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
} while (zip.goToNextFile());
|
|
||||||
zip.close();
|
|
||||||
if (zip.getZipError() != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractNatives::executeTask()
|
void ExtractNatives::executeTask()
|
||||||
|
@ -23,12 +23,9 @@
|
|||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
|
#include "archive/ArchiveReader.h"
|
||||||
#include "minecraft/mod/ResourcePack.h"
|
#include "minecraft/mod/ResourcePack.h"
|
||||||
|
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include <quazip/quazipfile.h>
|
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
namespace DataPackUtils {
|
namespace DataPackUtils {
|
||||||
@ -111,72 +108,72 @@ bool processZIP(DataPack* pack, ProcessingLevel level)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(pack->type() == ResourceType::ZIPFILE);
|
Q_ASSERT(pack->type() == ResourceType::ZIPFILE);
|
||||||
|
|
||||||
QuaZip zip(pack->fileinfo().filePath());
|
MMCZip::ArchiveReader zip(pack->fileinfo().filePath());
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
|
||||||
|
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
|
return false; // can't open zip file
|
||||||
|
}
|
||||||
QuaZipFile file(&zip);
|
if (!mcmeta_result) {
|
||||||
|
|
||||||
auto mcmeta_invalid = [&pack]() {
|
|
||||||
qWarning() << "Data pack at" << pack->fileinfo().filePath() << "does not have a valid pack.mcmeta";
|
qWarning() << "Data pack at" << pack->fileinfo().filePath() << "does not have a valid pack.mcmeta";
|
||||||
return false; // the mcmeta is not optional
|
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.
|
|
||||||
}
|
}
|
||||||
|
if (!directoryFound) {
|
||||||
QuaZipDir zipDir(&zip);
|
|
||||||
if (!zipDir.exists(pack->directory())) {
|
|
||||||
return false; // data dir does not exists at zip root
|
return false; // data dir does not exists at zip root
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level == ProcessingLevel::BasicInfoOnly) {
|
if (level == ProcessingLevel::BasicInfoOnly) {
|
||||||
zip.close();
|
|
||||||
return true; // only need basic info already checked
|
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";
|
qWarning() << "Data pack at" << pack->fileinfo().filePath() << "does not have a valid pack.png";
|
||||||
return true; // the png is optional
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -321,28 +318,17 @@ bool processPackPNG(const DataPack* pack)
|
|||||||
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
|
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
|
||||||
}
|
}
|
||||||
case ResourceType::ZIPFILE: {
|
case ResourceType::ZIPFILE: {
|
||||||
QuaZip zip(pack->fileinfo().filePath());
|
MMCZip::ArchiveReader zip(pack->fileinfo().filePath());
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
auto f = zip.goToFile("pack.png");
|
||||||
return false; // can't open zip file
|
if (!f) {
|
||||||
|
return png_invalid();
|
||||||
|
}
|
||||||
|
auto data = f->readAll();
|
||||||
|
|
||||||
QuaZipFile file(&zip);
|
bool pack_png_result = DataPackUtils::processPackPNG(pack, std::move(data));
|
||||||
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();
|
if (!pack_png_result) {
|
||||||
|
return png_invalid(); // pack.png invalid
|
||||||
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.
|
|
||||||
}
|
}
|
||||||
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
|
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,7 @@
|
|||||||
#include "LocalShaderPackParseTask.h"
|
#include "LocalShaderPackParseTask.h"
|
||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
#include "archive/ArchiveReader.h"
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include <quazip/quazipfile.h>
|
|
||||||
|
|
||||||
namespace ShaderPackUtils {
|
namespace ShaderPackUtils {
|
||||||
|
|
||||||
@ -63,25 +60,19 @@ bool processZIP(ShaderPack& pack, ProcessingLevel level)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
|
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
|
||||||
|
|
||||||
QuaZip zip(pack.fileinfo().filePath());
|
MMCZip::ArchiveReader zip(pack.fileinfo().filePath());
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
if (!zip.collectFiles())
|
||||||
return false; // can't open zip file
|
return false; // can't open zip file
|
||||||
|
|
||||||
QuaZipFile file(&zip);
|
if (!zip.exists("/shaders")) {
|
||||||
|
|
||||||
QuaZipDir zipDir(&zip);
|
|
||||||
if (!zipDir.exists("/shaders")) {
|
|
||||||
return false; // assets dir does not exists at zip root
|
return false; // assets dir does not exists at zip root
|
||||||
}
|
}
|
||||||
pack.setPackFormat(ShaderPackFormat::VALID);
|
pack.setPackFormat(ShaderPackFormat::VALID);
|
||||||
|
|
||||||
if (level == ProcessingLevel::BasicInfoOnly) {
|
if (level == ProcessingLevel::BasicInfoOnly) {
|
||||||
zip.close();
|
|
||||||
return true; // only need basic info already checked
|
return true; // only need basic info already checked
|
||||||
}
|
}
|
||||||
|
|
||||||
zip.close();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +20,7 @@
|
|||||||
#include "LocalTexturePackParseTask.h"
|
#include "LocalTexturePackParseTask.h"
|
||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
#include "archive/ArchiveReader.h"
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipfile.h>
|
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
@ -91,54 +89,35 @@ bool processZIP(TexturePack& pack, ProcessingLevel level)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
|
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
|
||||||
|
|
||||||
QuaZip zip(pack.fileinfo().filePath());
|
MMCZip::ArchiveReader zip(pack.fileinfo().filePath());
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QuaZipFile file(&zip);
|
{
|
||||||
|
auto file = zip.goToFile("pack.txt");
|
||||||
|
if (file) {
|
||||||
|
auto data = file->readAll();
|
||||||
|
|
||||||
if (zip.setCurrentFile("pack.txt")) {
|
bool packTXT_result = TexturePackUtils::processPackTXT(pack, std::move(data));
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
|
||||||
qCritical() << "Failed to open file in zip.";
|
|
||||||
zip.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data = file.readAll();
|
if (!packTXT_result) {
|
||||||
|
return false;
|
||||||
bool packTXT_result = TexturePackUtils::processPackTXT(pack, std::move(data));
|
}
|
||||||
|
|
||||||
file.close();
|
|
||||||
if (!packTXT_result) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level == ProcessingLevel::BasicInfoOnly) {
|
if (level == ProcessingLevel::BasicInfoOnly) {
|
||||||
zip.close();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zip.setCurrentFile("pack.png")) {
|
auto file = zip.goToFile("pack.png");
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (file) {
|
||||||
qCritical() << "Failed to open file in zip.";
|
auto data = file->readAll();
|
||||||
zip.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data = file.readAll();
|
|
||||||
|
|
||||||
bool packPNG_result = TexturePackUtils::processPackPNG(pack, std::move(data));
|
bool packPNG_result = TexturePackUtils::processPackPNG(pack, std::move(data));
|
||||||
|
|
||||||
file.close();
|
|
||||||
zip.close();
|
|
||||||
if (!packPNG_result) {
|
if (!packPNG_result) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zip.close();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,32 +168,19 @@ bool processPackPNG(const TexturePack& pack)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case ResourceType::ZIPFILE: {
|
case ResourceType::ZIPFILE: {
|
||||||
QuaZip zip(pack.fileinfo().filePath());
|
MMCZip::ArchiveReader zip(pack.fileinfo().filePath());
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
|
||||||
return false; // can't open zip file
|
|
||||||
|
|
||||||
QuaZipFile file(&zip);
|
auto file = zip.goToFile("pack.png");
|
||||||
if (zip.setCurrentFile("pack.png")) {
|
if (file) {
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
auto data = file->readAll();
|
||||||
qCritical() << "Failed to open file in zip.";
|
|
||||||
zip.close();
|
|
||||||
return png_invalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data = file.readAll();
|
|
||||||
|
|
||||||
bool pack_png_result = TexturePackUtils::processPackPNG(pack, std::move(data));
|
bool pack_png_result = TexturePackUtils::processPackPNG(pack, std::move(data));
|
||||||
|
|
||||||
file.close();
|
|
||||||
if (!pack_png_result) {
|
if (!pack_png_result) {
|
||||||
zip.close();
|
|
||||||
return png_invalid(); // pack.png invalid
|
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:
|
default:
|
||||||
qWarning() << "Invalid type for resource pack parse task!";
|
qWarning() << "Invalid type for resource pack parse task!";
|
||||||
|
@ -23,13 +23,11 @@
|
|||||||
#include "LocalWorldSaveParseTask.h"
|
#include "LocalWorldSaveParseTask.h"
|
||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
#include "archive/ArchiveReader.h"
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include <quazip/quazipfile.h>
|
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace WorldSaveUtils {
|
namespace WorldSaveUtils {
|
||||||
|
|
||||||
@ -105,22 +103,41 @@ bool processFolder(WorldSave& save, ProcessingLevel level)
|
|||||||
/// QString <name of folder containing level.dat>,
|
/// QString <name of folder containing level.dat>,
|
||||||
/// bool <saves folder found>
|
/// bool <saves folder found>
|
||||||
/// )
|
/// )
|
||||||
static std::tuple<bool, QString, bool> contains_level_dat(QuaZip& zip)
|
static std::tuple<bool, QString, bool> contains_level_dat(QString fileName)
|
||||||
{
|
{
|
||||||
|
MMCZip::ArchiveReader zip(fileName);
|
||||||
|
if (!zip.collectFiles()) {
|
||||||
|
return std::make_tuple(false, "", false);
|
||||||
|
}
|
||||||
bool saves = false;
|
bool saves = false;
|
||||||
QuaZipDir zipDir(&zip);
|
if (zip.exists("/saves")) {
|
||||||
if (zipDir.exists("/saves")) {
|
|
||||||
saves = true;
|
saves = true;
|
||||||
zipDir.cd("/saves");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& entry : zipDir.entryList()) {
|
for (auto file : zip.getFiles()) {
|
||||||
zipDir.cd(entry);
|
QString relativePath = file;
|
||||||
if (zipDir.exists("level.dat")) {
|
if (saves) {
|
||||||
return std::make_tuple(true, entry, 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);
|
return std::make_tuple(false, "", saves);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,19 +145,14 @@ bool processZIP(WorldSave& save, ProcessingLevel level)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(save.type() == ResourceType::ZIPFILE);
|
Q_ASSERT(save.type() == ResourceType::ZIPFILE);
|
||||||
|
|
||||||
QuaZip zip(save.fileinfo().filePath());
|
auto [found, save_dir_name, found_saves_dir] = contains_level_dat(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (save_dir_name.endsWith("/")) {
|
||||||
|
save_dir_name.chop(1);
|
||||||
|
}
|
||||||
|
|
||||||
save.setSaveDirName(save_dir_name);
|
save.setSaveDirName(save_dir_name);
|
||||||
|
|
||||||
@ -151,14 +163,11 @@ bool processZIP(WorldSave& save, ProcessingLevel level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (level == ProcessingLevel::BasicInfoOnly) {
|
if (level == ProcessingLevel::BasicInfoOnly) {
|
||||||
zip.close();
|
|
||||||
return true; // only need basic info already checked
|
return true; // only need basic info already checked
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserved for more intensive processing
|
// reserved for more intensive processing
|
||||||
|
|
||||||
zip.close();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@
|
|||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <quazip/quazip.h>
|
|
||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "MMCZip.h"
|
#include "MMCZip.h"
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <quazip/quazip.h>
|
|
||||||
#include <quazip/quazipdir.h>
|
|
||||||
#include "InstanceTask.h"
|
#include "InstanceTask.h"
|
||||||
#include "PackHelpers.h"
|
#include "PackHelpers.h"
|
||||||
#include "meta/Index.h"
|
#include "meta/Index.h"
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
#include "archive/ArchiveReader.h"
|
#include "archive/ArchiveReader.h"
|
||||||
#include "net/NetJob.h"
|
#include "net/NetJob.h"
|
||||||
|
|
||||||
#include <quazip/quazip.h>
|
|
||||||
|
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
zlib,
|
zlib,
|
||||||
msaClientID ? null,
|
msaClientID ? null,
|
||||||
gamemodeSupport ? stdenv.hostPlatform.isLinux,
|
gamemodeSupport ? stdenv.hostPlatform.isLinux,
|
||||||
|
libarchive,
|
||||||
}:
|
}:
|
||||||
assert lib.assertMsg (
|
assert lib.assertMsg (
|
||||||
gamemodeSupport -> stdenv.hostPlatform.isLinux
|
gamemodeSupport -> stdenv.hostPlatform.isLinux
|
||||||
@ -82,6 +83,7 @@ stdenv.mkDerivation {
|
|||||||
kdePackages.qtbase
|
kdePackages.qtbase
|
||||||
kdePackages.qtnetworkauth
|
kdePackages.qtnetworkauth
|
||||||
kdePackages.quazip
|
kdePackages.quazip
|
||||||
|
libarchive
|
||||||
tomlplusplus
|
tomlplusplus
|
||||||
zlib
|
zlib
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user