create mod meta information when importing modrinth pack

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2024-06-28 20:28:52 +03:00
parent 09d258670a
commit 1021222c95
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
4 changed files with 56 additions and 24 deletions

View File

@ -42,6 +42,9 @@ EnsureMetadataTask::EnsureMetadataTask(QList<Mod*>& mods, QDir dir, ModPlatform:
m_hashing_task->addTask(hash_task); m_hashing_task->addTask(hash_task);
} }
} }
EnsureMetadataTask::EnsureMetadataTask(QHash<QString, Mod*>& mods, QDir dir, ModPlatform::ResourceProvider prov)
: Task(nullptr), m_mods(mods), m_index_dir(dir), m_provider(prov), m_current_task(nullptr)
{}
Hashing::Hasher::Ptr EnsureMetadataTask::createNewHash(Mod* mod) Hashing::Hasher::Ptr EnsureMetadataTask::createNewHash(Mod* mod)
{ {

View File

@ -16,6 +16,7 @@ class EnsureMetadataTask : public Task {
public: public:
EnsureMetadataTask(Mod*, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); EnsureMetadataTask(Mod*, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH);
EnsureMetadataTask(QList<Mod*>&, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); EnsureMetadataTask(QList<Mod*>&, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH);
EnsureMetadataTask(QHash<QString, Mod*>&, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH);
~EnsureMetadataTask() = default; ~EnsureMetadataTask() = default;

View File

@ -5,8 +5,12 @@
#include "InstanceList.h" #include "InstanceList.h"
#include "Json.h" #include "Json.h"
#include "QObjectPtr.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h" #include "minecraft/PackProfile.h"
#include "minecraft/mod/Mod.h"
#include "modplatform/EnsureMetadataTask.h"
#include "modplatform/helpers/OverrideUtils.h" #include "modplatform/helpers/OverrideUtils.h"
#include "modplatform/modrinth/ModrinthPackManifest.h" #include "modplatform/modrinth/ModrinthPackManifest.h"
@ -21,6 +25,7 @@
#include <QAbstractButton> #include <QAbstractButton>
#include <QFileInfo> #include <QFileInfo>
#include <QHash>
#include <vector> #include <vector>
bool ModrinthCreationTask::abort() bool ModrinthCreationTask::abort()
@ -29,8 +34,8 @@ bool ModrinthCreationTask::abort()
return false; return false;
m_abort = true; m_abort = true;
if (m_files_job) if (m_task)
m_files_job->abort(); m_task->abort();
return Task::abort(); return Task::abort();
} }
@ -234,11 +239,11 @@ bool ModrinthCreationTask::createInstance()
instance.setName(name()); instance.setName(name());
instance.saveNow(); instance.saveNow();
m_files_job.reset(new NetJob(tr("Mod Download Modrinth"), APPLICATION->network())); auto downloadMods = makeShared<NetJob>(tr("Mod Download Modrinth"), APPLICATION->network());
auto root_modpack_path = FS::PathCombine(m_stagingPath, m_root_path); auto root_modpack_path = FS::PathCombine(m_stagingPath, m_root_path);
auto root_modpack_url = QUrl::fromLocalFile(root_modpack_path); auto root_modpack_url = QUrl::fromLocalFile(root_modpack_path);
QHash<QString, Mod*> mods;
for (auto file : m_files) { for (auto file : m_files) {
auto fileName = file.path; auto fileName = file.path;
fileName = FS::RemoveInvalidPathChars(fileName); fileName = FS::RemoveInvalidPathChars(fileName);
@ -249,20 +254,27 @@ bool ModrinthCreationTask::createInstance()
.arg(fileName)); .arg(fileName));
return false; return false;
} }
if (fileName.startsWith("mods/")) {
auto mod = new Mod(file_path);
ModDetails d;
d.mod_id = file_path;
mod->setDetails(d);
mods[file.hash.toHex()] = mod;
}
qDebug() << "Will try to download" << file.downloads.front() << "to" << file_path; qDebug() << "Will try to download" << file.downloads.front() << "to" << file_path;
auto dl = Net::ApiDownload::makeFile(file.downloads.dequeue(), file_path); auto dl = Net::ApiDownload::makeFile(file.downloads.dequeue(), file_path);
dl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash)); dl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash));
m_files_job->addNetAction(dl); downloadMods->addNetAction(dl);
if (!file.downloads.empty()) { if (!file.downloads.empty()) {
// FIXME: This really needs to be put into a ConcurrentTask of // FIXME: This really needs to be put into a ConcurrentTask of
// MultipleOptionsTask's , once those exist :) // MultipleOptionsTask's , once those exist :)
auto param = dl.toWeakRef(); auto param = dl.toWeakRef();
connect(dl.get(), &Task::failed, [this, &file, file_path, param] { connect(dl.get(), &Task::failed, [&file, file_path, param, downloadMods] {
auto ndl = Net::ApiDownload::makeFile(file.downloads.dequeue(), file_path); auto ndl = Net::ApiDownload::makeFile(file.downloads.dequeue(), file_path);
ndl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash)); ndl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash));
m_files_job->addNetAction(ndl); downloadMods->addNetAction(ndl);
if (auto shared = param.lock()) if (auto shared = param.lock())
shared->succeeded(); shared->succeeded();
}); });
@ -271,23 +283,44 @@ bool ModrinthCreationTask::createInstance()
bool ended_well = false; bool ended_well = false;
connect(m_files_job.get(), &NetJob::succeeded, this, [&]() { ended_well = true; }); connect(downloadMods.get(), &NetJob::succeeded, this, [&]() { ended_well = true; });
connect(m_files_job.get(), &NetJob::failed, [&](const QString& reason) { connect(downloadMods.get(), &NetJob::failed, [&](const QString& reason) {
ended_well = false; ended_well = false;
setError(reason); setError(reason);
}); });
connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); connect(downloadMods.get(), &NetJob::finished, &loop, &QEventLoop::quit);
connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { connect(downloadMods.get(), &NetJob::progress, [&](qint64 current, qint64 total) {
setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); setDetails(tr("%1 out of %2 complete").arg(current).arg(total));
setProgress(current, total); setProgress(current, total);
}); });
connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propagateStepProgress); connect(downloadMods.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propagateStepProgress);
setStatus(tr("Downloading mods...")); setStatus(tr("Downloading mods..."));
m_files_job->start(); downloadMods->start();
m_task = downloadMods;
loop.exec(); loop.exec();
QEventLoop ensureMetaLoop;
QDir folder = FS::PathCombine(m_stagingPath, "minecraft", "mods", ".index");
auto ensureMetadataTask = makeShared<EnsureMetadataTask>(mods, folder, ModPlatform::ResourceProvider::MODRINTH);
connect(ensureMetadataTask.get(), &Task::succeeded, this, [&]() { ended_well = true; });
connect(ensureMetadataTask.get(), &Task::finished, &ensureMetaLoop, &QEventLoop::quit);
connect(ensureMetadataTask.get(), &Task::progress, [&](qint64 current, qint64 total) {
setDetails(tr("%1 out of %2 complete").arg(current).arg(total));
setProgress(current, total);
});
connect(ensureMetadataTask.get(), &Task::stepProgress, this, &ModrinthCreationTask::propagateStepProgress);
ensureMetadataTask->start();
m_task = ensureMetadataTask;
ensureMetaLoop.exec();
for (auto m : mods) {
delete m;
}
mods.clear();
// Update information of the already installed instance, if any. // Update information of the already installed instance, if any.
if (m_instance && ended_well) { if (m_instance && ended_well) {
setAbortable(false); setAbortable(false);
@ -348,11 +381,11 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path,
QJsonObject hashes = Json::requireObject(modInfo, "hashes"); QJsonObject hashes = Json::requireObject(modInfo, "hashes");
QString hash; QString hash;
QCryptographicHash::Algorithm hashAlgorithm; QCryptographicHash::Algorithm hashAlgorithm;
hash = Json::ensureString(hashes, "sha1"); hash = Json::ensureString(hashes, "sha512");
hashAlgorithm = QCryptographicHash::Sha1; hashAlgorithm = QCryptographicHash::Sha512;
if (hash.isEmpty()) { if (hash.isEmpty()) {
hash = Json::ensureString(hashes, "sha512"); hash = Json::ensureString(hashes, "sha1");
hashAlgorithm = QCryptographicHash::Sha512; hashAlgorithm = QCryptographicHash::Sha1;
if (hash.isEmpty()) { if (hash.isEmpty()) {
hash = Json::ensureString(hashes, "sha256"); hash = Json::ensureString(hashes, "sha256");
hashAlgorithm = QCryptographicHash::Sha256; hashAlgorithm = QCryptographicHash::Sha256;

View File

@ -1,15 +1,10 @@
#pragma once #pragma once
#include "BaseInstance.h"
#include "InstanceCreationTask.h" #include "InstanceCreationTask.h"
#include <optional>
#include "minecraft/MinecraftInstance.h"
#include "modplatform/modrinth/ModrinthPackManifest.h" #include "modplatform/modrinth/ModrinthPackManifest.h"
#include "net/NetJob.h"
class ModrinthCreationTask final : public InstanceCreationTask { class ModrinthCreationTask final : public InstanceCreationTask {
Q_OBJECT Q_OBJECT
@ -43,7 +38,7 @@ class ModrinthCreationTask final : public InstanceCreationTask {
QString m_managed_id, m_managed_version_id, m_managed_name; QString m_managed_id, m_managed_version_id, m_managed_name;
std::vector<Modrinth::File> m_files; std::vector<Modrinth::File> m_files;
NetJob::Ptr m_files_job; Task::Ptr m_task;
std::optional<InstancePtr> m_instance; std::optional<InstancePtr> m_instance;