aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft/mod/tasks
diff options
context:
space:
mode:
authorflow <flowlnlnln@gmail.com>2022-08-28 22:33:44 -0300
committerflow <flowlnlnln@gmail.com>2022-09-03 13:37:21 -0300
commitf21ae66265d5e3251bd996df1fc7ed7f52ec95b0 (patch)
tree2969b2c5911001f467d0f6950c35a0d5f515af07 /launcher/minecraft/mod/tasks
parentafa1a5e93228350ea5689b39655046b49a0133a5 (diff)
downloadPrismLauncher-f21ae66265d5e3251bd996df1fc7ed7f52ec95b0.tar.gz
PrismLauncher-f21ae66265d5e3251bd996df1fc7ed7f52ec95b0.tar.bz2
PrismLauncher-f21ae66265d5e3251bd996df1fc7ed7f52ec95b0.zip
feat: add basic resource pack parsing of pack.mcmeta
This parses the pack format ID and the description from the local file, from both a ZIP and a folder, and hooks it into the model. Signed-off-by: flow <flowlnlnln@gmail.com>
Diffstat (limited to 'launcher/minecraft/mod/tasks')
-rw-r--r--launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp95
-rw-r--r--launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h34
2 files changed, 129 insertions, 0 deletions
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
new file mode 100644
index 00000000..0fc7a87e
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
@@ -0,0 +1,95 @@
+#include "LocalResourcePackParseTask.h"
+
+#include "FileSystem.h"
+#include "Json.h"
+
+#include <quazip/quazip.h>
+#include <quazip/quazipfile.h>
+
+LocalResourcePackParseTask::LocalResourcePackParseTask(int token, ResourcePack& rp)
+ : Task(nullptr, false), m_token(token), m_resource_pack(rp)
+{}
+
+bool LocalResourcePackParseTask::abort()
+{
+ m_aborted = true;
+ return true;
+}
+
+void LocalResourcePackParseTask::executeTask()
+{
+ switch (m_resource_pack.type()) {
+ case ResourceType::FOLDER:
+ processAsFolder();
+ break;
+ case ResourceType::ZIPFILE:
+ processAsZip();
+ break;
+ default:
+ qWarning() << "Invalid type for resource pack parse task!";
+ emitFailed(tr("Invalid type."));
+ }
+
+ if (isFinished())
+ return;
+
+ if (m_aborted)
+ emitAborted();
+ else
+ emitSucceeded();
+}
+
+// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+void LocalResourcePackParseTask::processMCMeta(QByteArray&& raw_data)
+{
+ try {
+ auto json_doc = QJsonDocument::fromJson(raw_data);
+ auto pack_obj = Json::requireObject(json_doc.object(), "pack", {});
+
+ m_resource_pack.setPackFormat(Json::ensureInteger(pack_obj, "pack_format", 0));
+ m_resource_pack.setDescription(Json::ensureString(pack_obj, "description", ""));
+ } catch (Json::JsonException& e) {
+ qWarning() << "JsonException: " << e.what() << e.cause();
+ emitFailed(tr("Failed to process .mcmeta file."));
+ }
+}
+
+void LocalResourcePackParseTask::processAsFolder()
+{
+ QFileInfo mcmeta_file_info(FS::PathCombine(m_resource_pack.fileinfo().filePath(), "pack.mcmeta"));
+ if (mcmeta_file_info.isFile()) {
+ QFile mcmeta_file(mcmeta_file_info.filePath());
+ if (!mcmeta_file.open(QIODevice::ReadOnly))
+ return;
+
+ auto data = mcmeta_file.readAll();
+ if (data.isEmpty() || data.isNull())
+ return;
+
+ processMCMeta(std::move(data));
+ }
+}
+
+void LocalResourcePackParseTask::processAsZip()
+{
+ QuaZip zip(m_resource_pack.fileinfo().filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return;
+
+ QuaZipFile file(&zip);
+
+ if (zip.setCurrentFile("pack.mcmeta")) {
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCritical() << "Failed to open file in zip.";
+ zip.close();
+ return;
+ }
+
+ auto data = file.readAll();
+
+ processMCMeta(std::move(data));
+
+ file.close();
+ zip.close();
+ }
+}
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
new file mode 100644
index 00000000..7660d233
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <QDebug>
+#include <QObject>
+
+#include "minecraft/mod/ResourcePack.h"
+
+#include "tasks/Task.h"
+
+class LocalResourcePackParseTask : public Task {
+ Q_OBJECT
+ public:
+ LocalResourcePackParseTask(int token, ResourcePack& rp);
+
+ [[nodiscard]] bool canAbort() const override { return true; }
+ bool abort() override;
+
+ void executeTask() override;
+
+ [[nodiscard]] int token() const { return m_token; }
+
+ private:
+ void processMCMeta(QByteArray&& raw_data);
+
+ void processAsFolder();
+ void processAsZip();
+
+ private:
+ int m_token;
+
+ ResourcePack& m_resource_pack;
+
+ bool m_aborted = false;
+};