aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
blob: 0fc7a87e0fa97a377b459bf155e241f6bfb452e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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();
    }
}