From 9b984cedaca78153bc865a3eac5def4535b4d664 Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 29 Aug 2022 09:15:06 -0300 Subject: [PATCH] feat: add image from pack.png to resource packs Signed-off-by: flow --- launcher/minecraft/mod/ResourcePack.cpp | 9 ++++ launcher/minecraft/mod/ResourcePack.h | 14 ++++++ .../mod/tasks/LocalResourcePackParseTask.cpp | 44 +++++++++++++++++-- .../mod/tasks/LocalResourcePackParseTask.h | 1 + 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 5f45254d..77bd98aa 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -35,6 +35,15 @@ void ResourcePack::setDescription(QString new_description) m_description = new_description; } +void ResourcePack::setImage(QImage new_image) +{ + QMutexLocker locker(&m_data_lock); + + Q_ASSERT(!new_image.isNull()); + + m_pack_image = new_image; +} + std::pair ResourcePack::compatibleVersions() const { if (!s_pack_format_versions.contains(m_pack_format)) { diff --git a/launcher/minecraft/mod/ResourcePack.h b/launcher/minecraft/mod/ResourcePack.h index 17de86a7..1a51d9ef 100644 --- a/launcher/minecraft/mod/ResourcePack.h +++ b/launcher/minecraft/mod/ResourcePack.h @@ -2,7 +2,9 @@ #include "Resource.h" +#include #include +#include class Version; @@ -28,12 +30,19 @@ class ResourcePack : public Resource { /** Gets the description of the resource pack. */ [[nodiscard]] QString description() const { return m_description; } + /** Gets the image of the resource pack, converted to a QPixmap for drawing, and scaled to size. */ + [[nodiscard]] QPixmap image(QSize size) const { return QPixmap::fromImage(m_pack_image).scaled(size); } + [[nodiscard]] QSize image_size() const { return m_pack_image.size(); } + /** Thread-safe. */ void setPackFormat(int new_format_id); /** Thread-safe. */ void setDescription(QString new_description); + /** Thread-safe. */ + void setImage(QImage new_image); + [[nodiscard]] auto compare(Resource const& other, SortType type) const -> std::pair override; [[nodiscard]] bool applyFilter(QRegularExpression filter) const override; @@ -48,4 +57,9 @@ class ResourcePack : public Resource { /** The resource pack's description, as defined in the pack.mcmeta file. */ QString m_description; + + /** The resource pack's image, as per the pack.png file. + * TODO: This could probably be just a key into a static image cache. + */ + QImage m_pack_image; }; diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp index 0fc7a87e..b13e5775 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp @@ -54,6 +54,16 @@ void LocalResourcePackParseTask::processMCMeta(QByteArray&& raw_data) } } +void LocalResourcePackParseTask::processPackPNG(QByteArray&& raw_data) +{ + auto img = QImage::fromData(raw_data); + if (!img.isNull()) { + m_resource_pack.setImage(img); + } else { + qWarning() << "Failed to parse pack.png."; + } +} + void LocalResourcePackParseTask::processAsFolder() { QFileInfo mcmeta_file_info(FS::PathCombine(m_resource_pack.fileinfo().filePath(), "pack.mcmeta")); @@ -63,10 +73,23 @@ void LocalResourcePackParseTask::processAsFolder() return; auto data = mcmeta_file.readAll(); - if (data.isEmpty() || data.isNull()) - return; processMCMeta(std::move(data)); + + mcmeta_file.close(); + } + + QFileInfo image_file_info(FS::PathCombine(m_resource_pack.fileinfo().filePath(), "pack.png")); + if (image_file_info.isFile()) { + QFile mcmeta_file(image_file_info.filePath()); + if (!mcmeta_file.open(QIODevice::ReadOnly)) + return; + + auto data = mcmeta_file.readAll(); + + processPackPNG(std::move(data)); + + mcmeta_file.close(); } } @@ -90,6 +113,21 @@ void LocalResourcePackParseTask::processAsZip() processMCMeta(std::move(data)); file.close(); - zip.close(); } + + if (zip.setCurrentFile("pack.png")) { + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "Failed to open file in zip."; + zip.close(); + return; + } + + auto data = file.readAll(); + + processPackPNG(std::move(data)); + + file.close(); + } + + zip.close(); } diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h index 7660d233..86ea033d 100644 --- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h +++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h @@ -21,6 +21,7 @@ class LocalResourcePackParseTask : public Task { private: void processMCMeta(QByteArray&& raw_data); + void processPackPNG(QByteArray&& raw_data); void processAsFolder(); void processAsZip();