diff options
Diffstat (limited to 'launcher/modplatform/modrinth')
9 files changed, 66 insertions, 105 deletions
diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h index 88e1a675..4583dd6c 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h @@ -8,7 +8,10 @@ class ModrinthCheckUpdate : public CheckUpdateTask { Q_OBJECT public: - ModrinthCheckUpdate(QList<Mod*>& mods, std::list<Version>& mcVersions, std::optional<ResourceAPI::ModLoaderTypes> loaders, std::shared_ptr<ModFolderModel> mods_folder) + ModrinthCheckUpdate(QList<Mod*>& mods, + std::list<Version>& mcVersions, + std::optional<ResourceAPI::ModLoaderTypes> loaders, + std::shared_ptr<ModFolderModel> mods_folder) : CheckUpdateTask(mods, mcVersions, loaders, mods_folder) {} diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 76f07277..16e375cd 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -133,10 +133,10 @@ bool ModrinthCreationTask::updateInstance() } } else { // We don't have an old index file, so we may duplicate stuff! - auto dialog = CustomMessageBox::selectable(m_parent, - tr("No index file."), - tr("We couldn't find a suitable index file for the older version. This may cause some of the files to be duplicated. Do you want to continue?"), - QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); + auto dialog = CustomMessageBox::selectable(m_parent, tr("No index file."), + tr("We couldn't find a suitable index file for the older version. This may cause some " + "of the files to be duplicated. Do you want to continue?"), + QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); if (dialog->exec() == QDialog::DialogCode::Rejected) { m_abort = true; @@ -144,7 +144,6 @@ bool ModrinthCreationTask::updateInstance() } } - setOverride(true, inst->id()); qDebug() << "Will override instance!"; @@ -233,7 +232,8 @@ bool ModrinthCreationTask::createInstance() auto file_path = FS::PathCombine(root_modpack_path, file.path); if (!root_modpack_url.isParentOf(QUrl::fromLocalFile(file_path))) { // This means we somehow got out of the root folder, so abort here to prevent exploits - setError(tr("One of the files has a path that leads to an arbitrary location (%1). This is a security risk and isn't allowed.").arg(file.path)); + setError(tr("One of the files has a path that leads to an arbitrary location (%1). This is a security risk and isn't allowed.") + .arg(file.path)); return false; } @@ -250,7 +250,8 @@ bool ModrinthCreationTask::createInstance() auto ndl = Net::Download::makeFile(file.downloads.dequeue(), file_path); ndl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash)); m_files_job->addNetAction(ndl); - if (auto shared = param.lock()) shared->succeeded(); + if (auto shared = param.lock()) + shared->succeeded(); }); } } @@ -263,11 +264,11 @@ bool ModrinthCreationTask::createInstance() setError(reason); }); connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); - connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { + connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 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::propogateStepProgress); + connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propagateStepProgress); setStatus(tr("Downloading mods...")); m_files_job->start(); @@ -293,7 +294,10 @@ bool ModrinthCreationTask::createInstance() return ended_well; } -bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector<Modrinth::File>& files, bool set_internal_data, bool show_optional_dialog) +bool ModrinthCreationTask::parseManifest(const QString& index_path, + std::vector<Modrinth::File>& files, + bool set_internal_data, + bool show_optional_dialog) { try { auto doc = Json::requireDocument(index_path); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h index 6de24fd4..07e417be 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h @@ -20,10 +20,7 @@ class ModrinthCreationTask final : public InstanceCreationTask { QString id, QString version_id = {}, QString original_instance_id = {}) - : InstanceCreationTask() - , m_parent(parent) - , m_managed_id(std::move(id)) - , m_managed_version_id(std::move(version_id)) + : InstanceCreationTask(), m_parent(parent), m_managed_id(std::move(id)), m_managed_version_id(std::move(version_id)) { setStagingPath(staging_path); setParentSettings(global_settings); diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 30fe566d..7bf29639 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -55,20 +55,11 @@ void ModrinthPackExportTask::executeTask() bool ModrinthPackExportTask::abort() { - if (task != nullptr) { + if (task) { task->abort(); - task = nullptr; emitAborted(); return true; } - - if (buildZipFuture.isRunning()) { - buildZipFuture.cancel(); - // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur - // immediately. - return true; - } - return false; } @@ -205,63 +196,36 @@ void ModrinthPackExportTask::buildZip() { setStatus(tr("Adding files...")); - buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - QuaZip zip(output); - if (!zip.open(QuaZip::mdCreate)) { - QFile::remove(output); - return BuildZipResult(tr("Could not create file")); - } - - if (buildZipFuture.isCanceled()) - return BuildZipResult(); - - QuaZipFile indexFile(&zip); - if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("modrinth.index.json"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - indexFile.write(generateIndex()); - - size_t progress = 0; - for (const QFileInfo& file : files) { - if (buildZipFuture.isCanceled()) { - QFile::remove(output); - return BuildZipResult(); - } - - setProgress(progress, files.length()); - const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!resolvedFiles.contains(relative) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { - QFile::remove(output); - return BuildZipResult(tr("Could not read and compress %1").arg(relative)); - } - progress++; - } + auto zipTask = makeShared<MMCZip::ExportToZipTask>(output, gameRoot, files, "overrides/", true); + zipTask->addExtraFile("modrinth.index.json", generateIndex()); - zip.close(); + zipTask->setExcludeFiles(resolvedFiles.keys()); - if (zip.getZipError() != 0) { - QFile::remove(output); - return BuildZipResult(tr("A zip error occurred")); - } + auto progressStep = std::make_shared<TaskStepProgress>(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); + }); - return BuildZipResult(); + connect(zipTask.get(), &Task::succeeded, this, &ModrinthPackExportTask::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &ModrinthPackExportTask::emitAborted); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + emitFailed(reason); }); - connect(&buildZipWatcher, &QFutureWatcher<BuildZipResult>::finished, this, &ModrinthPackExportTask::finish); - buildZipWatcher.setFuture(buildZipFuture); -} + connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propagateStepProgress); -void ModrinthPackExportTask::finish() -{ - if (buildZipFuture.isCanceled()) - emitAborted(); - else { - const BuildZipResult result = buildZipFuture.result(); - if (result.has_value()) - emitFailed(result.value()); - else - emitSucceeded(); - } + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + task.reset(zipTask); + zipTask->start(); } QByteArray ModrinthPackExportTask::generateIndex() diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.h b/launcher/modplatform/modrinth/ModrinthPackExportTask.h index 96f292c1..1f9e0eb7 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.h +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.h @@ -56,22 +56,17 @@ class ModrinthPackExportTask : public Task { const QString output; const MMCZip::FilterFunction filter; - typedef std::optional<QString> BuildZipResult; - ModrinthAPI api; QFileInfoList files; QMap<QString, QString> pendingHashes; QMap<QString, ResolvedFile> resolvedFiles; Task::Ptr task; - QFuture<BuildZipResult> buildZipFuture; - QFutureWatcher<BuildZipResult> buildZipWatcher; void collectFiles(); void collectHashes(); void makeApiRequest(); void parseApiResponse(const std::shared_ptr<QByteArray> response); void buildZip(); - void finish(); QByteArray generateIndex(); }; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index b4037349..96dafe70 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index a8d986c5..58a0f227 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * * 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 diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 4dca786f..0d07c636 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> * * This program is free software: you can redistribute it and/or modify @@ -66,23 +66,23 @@ void loadIndexedInfo(Modpack& pack, QJsonObject& obj) pack.extra.projectUrl = QString("https://modrinth.com/modpack/%1").arg(Json::ensureString(obj, "slug")); pack.extra.issuesUrl = Json::ensureString(obj, "issues_url"); - if(pack.extra.issuesUrl.endsWith('/')) + if (pack.extra.issuesUrl.endsWith('/')) pack.extra.issuesUrl.chop(1); pack.extra.sourceUrl = Json::ensureString(obj, "source_url"); - if(pack.extra.sourceUrl.endsWith('/')) + if (pack.extra.sourceUrl.endsWith('/')) pack.extra.sourceUrl.chop(1); pack.extra.wikiUrl = Json::ensureString(obj, "wiki_url"); - if(pack.extra.wikiUrl.endsWith('/')) + if (pack.extra.wikiUrl.endsWith('/')) pack.extra.wikiUrl.chop(1); pack.extra.discordUrl = Json::ensureString(obj, "discord_url"); - if(pack.extra.discordUrl.endsWith('/')) + if (pack.extra.discordUrl.endsWith('/')) pack.extra.discordUrl.chop(1); auto donate_arr = Json::ensureArray(obj, "donation_urls"); - for(auto d : donate_arr){ + for (auto d : donate_arr) { auto d_obj = Json::requireObject(d); DonationData donate; @@ -107,7 +107,7 @@ void loadIndexedVersions(Modpack& pack, QJsonDocument& doc) auto obj = Json::requireObject(versionIter); auto file = loadIndexedVersion(obj); - if(!file.id.isEmpty()) // Heuristic to check if the returned value is valid + if (!file.id.isEmpty()) // Heuristic to check if the returned value is valid unsortedVersions.append(file); } auto orderSortPredicate = [](const ModpackVersion& a, const ModpackVersion& b) -> bool { @@ -122,7 +122,7 @@ void loadIndexedVersions(Modpack& pack, QJsonDocument& doc) pack.versionsLoaded = true; } -auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion +auto loadIndexedVersion(QJsonObject& obj) -> ModpackVersion { ModpackVersion file; @@ -132,12 +132,11 @@ auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion file.id = Json::requireString(obj, "id"); file.project_id = Json::requireString(obj, "project_id"); - + file.date = Json::requireString(obj, "date_published"); auto files = Json::requireArray(obj, "files"); - for (auto file_iter : files) { File indexed_file; auto parent = Json::requireObject(file_iter); @@ -146,21 +145,21 @@ auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion auto filename = Json::ensureString(parent, "filename"); // Checking suffix here is fine because it's the response from Modrinth, // so one would assume it will always be in English. - if(!filename.endsWith("mrpack") && !filename.endsWith("zip")) + if (!filename.endsWith("mrpack") && !filename.endsWith("zip")) continue; } auto url = Json::requireString(parent, "url"); file.download_url = url; - if(is_primary) + if (is_primary) break; } - if(file.download_url.isEmpty()) + if (file.download_url.isEmpty()) return {}; return file; -} +} } // namespace Modrinth diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.h b/launcher/modplatform/modrinth/ModrinthPackManifest.h index 2973dfba..effa1a84 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.h +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> * * This program is free software: you can redistribute it and/or modify @@ -74,7 +74,6 @@ struct ModpackExtra { QString discordUrl; QList<DonationData> donate; - }; struct ModpackVersion { @@ -97,10 +96,10 @@ struct Modpack { QString description; std::tuple<QString, QUrl> author; QString iconName; - QUrl iconUrl; + QUrl iconUrl; - bool versionsLoaded = false; - bool extraInfoLoaded = false; + bool versionsLoaded = false; + bool extraInfoLoaded = false; ModpackExtra extra; QVector<ModpackVersion> versions; @@ -113,7 +112,7 @@ auto loadIndexedVersion(QJsonObject&) -> ModpackVersion; auto validateDownloadUrl(QUrl) -> bool; -} +} // namespace Modrinth Q_DECLARE_METATYPE(Modrinth::Modpack) Q_DECLARE_METATYPE(Modrinth::ModpackVersion) |