aboutsummaryrefslogtreecommitdiff
path: root/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp
blob: 331fbf94d34af567d2406efe028e070190e47f27 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: GPL-3.0-only
/*
 *  Prism Launcher - Minecraft Launcher
 *  Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, version 3.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#include "ModrinthPackExportTask.h"
#include <qtconcurrentrun.h>
#include <QFileInfoList>
#include <QMessageBox>
#include "MMCZip.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"

ModrinthPackExportTask::ModrinthPackExportTask(const QString& name,
                                               const QString& version,
                                               const QString& summary,
                                               InstancePtr instance,
                                               const QString& output,
                                               MMCZip::FilterFunction filter)
    : name(name), version(version), summary(summary), instance(instance), output(output), filter(filter)
{}

void ModrinthPackExportTask::executeTask()
{
    QtConcurrent::run(QThreadPool::globalInstance(), [this] {
        QFileInfoList files;
        if (!MMCZip::collectFileListRecursively(instance->gameRoot(), nullptr, &files, filter)) {
            emitFailed(tr("Could not collect list of files"));
            return;
        }

        setStatus("Adding files...");

        QuaZip zip(output);
        if (!zip.open(QuaZip::mdCreate)) {
            QFile::remove(output);
            emitFailed(tr("Could not create file"));
            return;
        }

        {
            QuaZipFile indexFile(&zip);
            if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("modrinth.index.json"))) {
                QFile::remove(output);

                emitFailed(tr("Could not create index"));
                return;
            }
            indexFile.write(generateIndex());
        }

        // should exist
        QDir dotMinecraft(instance->gameRoot());

        {
            size_t i = 0;
            for (const QFileInfo& file : files) {
                setProgress(i, files.length());
                if (!JlCompress::compressFile(&zip, file.absoluteFilePath(),
                                              "overrides/" + dotMinecraft.relativeFilePath(file.absoluteFilePath()))) {
                    emitFailed(tr("Could not compress %1").arg(file.absoluteFilePath()));
                    return;
                }
                i++;
            }
        }

        zip.close();

        if (zip.getZipError() != 0) {
            QFile::remove(output);
            emitFailed(tr("A zip error occured"));
            return;
        }

        emitSucceeded();
    });
}

QByteArray ModrinthPackExportTask::generateIndex()
{
    QJsonObject obj;
    obj["formatVersion"] = 1;
    obj["game"] = "minecraft";
    obj["name"] = name;
    obj["versionId"] = version;
    obj["summary"] = summary;

    MinecraftInstance* mc = dynamic_cast<MinecraftInstance*>(instance.get());
    if (mc) {
        auto profile = mc->getPackProfile();
        auto minecraft = profile->getComponent("net.minecraft");

        QJsonObject dependencies;
        dependencies["minecraft"] = minecraft->m_version;
        obj["dependencies"] = dependencies;
    }

    return QJsonDocument(obj).toJson(QJsonDocument::Compact);
}