feat:Update mods now fills missing dependencies

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2023-06-24 21:48:12 +03:00
parent bcf45c74a1
commit 564e394ec8
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
4 changed files with 94 additions and 32 deletions

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#include "minecraft/mod/Mod.h" #include "minecraft/mod/Mod.h"
#include "modplatform/ResourceAPI.h" #include "minecraft/mod/tasks/GetModDependenciesTask.h"
#include "modplatform/ModIndex.h" #include "modplatform/ModIndex.h"
#include "modplatform/ResourceAPI.h"
#include "tasks/Task.h" #include "tasks/Task.h"
class ResourceDownloadTask; class ResourceDownloadTask;
@ -12,8 +13,11 @@ class CheckUpdateTask : public Task {
Q_OBJECT Q_OBJECT
public: public:
CheckUpdateTask(QList<Mod*>& mods, std::list<Version>& mcVersions, std::optional<ResourceAPI::ModLoaderTypes> loaders, std::shared_ptr<ModFolderModel> mods_folder) CheckUpdateTask(QList<Mod*>& mods,
: Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder) {}; std::list<Version>& mcVersions,
std::optional<ResourceAPI::ModLoaderTypes> loaders,
std::shared_ptr<ModFolderModel> mods_folder)
: Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder){};
struct UpdatableMod { struct UpdatableMod {
QString name; QString name;
@ -25,12 +29,19 @@ class CheckUpdateTask : public Task {
shared_qobject_ptr<ResourceDownloadTask> download; shared_qobject_ptr<ResourceDownloadTask> download;
public: public:
UpdatableMod(QString name, QString old_h, QString old_v, QString new_v, QString changelog, ModPlatform::ResourceProvider p, shared_qobject_ptr<ResourceDownloadTask> t) UpdatableMod(QString name,
QString old_h,
QString old_v,
QString new_v,
QString changelog,
ModPlatform::ResourceProvider p,
shared_qobject_ptr<ResourceDownloadTask> t)
: name(name), old_hash(old_h), old_version(old_v), new_version(new_v), changelog(changelog), provider(p), download(t) : name(name), old_hash(old_h), old_version(old_v), new_version(new_v), changelog(changelog), provider(p), download(t)
{} {}
}; };
auto getUpdatable() -> std::vector<UpdatableMod>&& { return std::move(m_updatable); } auto getUpdatable() -> std::vector<UpdatableMod>&& { return std::move(m_updatable); }
auto getDependencies() -> QList<std::shared_ptr<GetModDependenciesTask::PackDependency>>&& { return std::move(m_deps); }
public slots: public slots:
bool abort() override = 0; bool abort() override = 0;
@ -48,4 +59,5 @@ class CheckUpdateTask : public Task {
std::shared_ptr<ModFolderModel> m_mods_folder; std::shared_ptr<ModFolderModel> m_mods_folder;
std::vector<UpdatableMod> m_updatable; std::vector<UpdatableMod> m_updatable;
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> m_deps;
}; };

View File

@ -12,6 +12,7 @@
#include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ModFolderModel.h"
#include "minecraft/mod/ResourceFolderModel.h" #include "minecraft/mod/ResourceFolderModel.h"
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
static FlameAPI api; static FlameAPI api;
@ -154,7 +155,6 @@ void FlameCheckUpdate::executeTask()
continue; continue;
} }
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
// Fake pack with the necessary info to pass to the download task :) // Fake pack with the necessary info to pass to the download task :)
auto pack = std::make_shared<ModPlatform::IndexedPack>(); auto pack = std::make_shared<ModPlatform::IndexedPack>();
pack->name = mod->name(); pack->name = mod->name();
@ -165,7 +165,7 @@ void FlameCheckUpdate::executeTask()
pack->authors.append({ author }); pack->authors.append({ author });
pack->description = mod->description(); pack->description = mod->description();
pack->provider = ModPlatform::ResourceProvider::FLAME; pack->provider = ModPlatform::ResourceProvider::FLAME;
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
auto old_version = mod->version(); auto old_version = mod->version();
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) { if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt()); auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
@ -177,6 +177,7 @@ void FlameCheckUpdate::executeTask()
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()), api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
ModPlatform::ResourceProvider::FLAME, download_task); ModPlatform::ResourceProvider::FLAME, download_task);
} }
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver));
} }
emitSucceeded(); emitSucceeded();

View File

@ -145,9 +145,6 @@ void ModrinthCheckUpdate::executeTask()
auto mod = *mod_iter; auto mod = *mod_iter;
auto key = project_ver.hash; auto key = project_ver.hash;
if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
if (mod->version() == project_ver.version_number)
continue;
// Fake pack with the necessary info to pass to the download task :) // Fake pack with the necessary info to pass to the download task :)
auto pack = std::make_shared<ModPlatform::IndexedPack>(); auto pack = std::make_shared<ModPlatform::IndexedPack>();
@ -159,12 +156,16 @@ void ModrinthCheckUpdate::executeTask()
pack->authors.append({ author }); pack->authors.append({ author });
pack->description = mod->description(); pack->description = mod->description();
pack->provider = ModPlatform::ResourceProvider::MODRINTH; pack->provider = ModPlatform::ResourceProvider::MODRINTH;
if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
if (mod->version() == project_ver.version_number)
continue;
auto download_task = makeShared<ResourceDownloadTask>(pack, project_ver, m_mods_folder); auto download_task = makeShared<ResourceDownloadTask>(pack, project_ver, m_mods_folder);
m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.changelog, m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.changelog,
ModPlatform::ResourceProvider::MODRINTH, download_task); ModPlatform::ResourceProvider::MODRINTH, download_task);
} }
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, project_ver));
} }
} catch (Json::JsonException& e) { } catch (Json::JsonException& e) {
failed(e.cause() + " : " + e.what()); failed(e.cause() + " : " + e.what());

View File

@ -3,6 +3,9 @@
#include "CustomMessageBox.h" #include "CustomMessageBox.h"
#include "ProgressDialog.h" #include "ProgressDialog.h"
#include "ScrollMessageBox.h" #include "ScrollMessageBox.h"
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h"
#include "ui_ReviewMessageBox.h" #include "ui_ReviewMessageBox.h"
#include "FileSystem.h" #include "FileSystem.h"
@ -89,15 +92,17 @@ void ModUpdateDialog::checkCandidates()
if (!m_modrinth_to_update.empty()) { if (!m_modrinth_to_update.empty()) {
m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model)); m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model));
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({mod, reason, recover_url}); }); m_failed_check_update.append({ mod, reason, recover_url });
});
check_task.addTask(m_modrinth_check_task); check_task.addTask(m_modrinth_check_task);
} }
if (!m_flame_to_update.empty()) { if (!m_flame_to_update.empty()) {
m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model)); m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model));
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({mod, reason, recover_url}); }); m_failed_check_update.append({ mod, reason, recover_url });
});
check_task.addTask(m_flame_check_task); check_task.addTask(m_flame_check_task);
} }
@ -124,6 +129,8 @@ void ModUpdateDialog::checkCandidates()
return; return;
} }
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
// Add found updates for Modrinth // Add found updates for Modrinth
if (m_modrinth_check_task) { if (m_modrinth_check_task) {
auto modrinth_updates = m_modrinth_check_task->getUpdatable(); auto modrinth_updates = m_modrinth_check_task->getUpdatable();
@ -133,6 +140,7 @@ void ModUpdateDialog::checkCandidates()
appendMod(updatable); appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download); m_tasks.insert(updatable.name, updatable.download);
} }
selectedVers.append(m_modrinth_check_task->getDependencies());
} }
// Add found updated for Flame // Add found updated for Flame
@ -144,6 +152,7 @@ void ModUpdateDialog::checkCandidates()
appendMod(updatable); appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download); m_tasks.insert(updatable.name, updatable.download);
} }
selectedVers.append(m_flame_check_task->getDependencies());
} }
// Report failed update checking // Report failed update checking
@ -178,6 +187,45 @@ void ModUpdateDialog::checkCandidates()
} }
} }
{ // dependencies
auto depTask = makeShared<GetModDependenciesTask>(this, m_instance, m_mod_model.get(), selectedVers);
connect(depTask.get(), &Task::failed, this,
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
connect(depTask.get(), &Task::succeeded, this, [&]() {
QStringList warnings = depTask->warnings();
if (warnings.count()) {
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec();
}
});
ProgressDialog progress_dialog_deps(m_parent);
progress_dialog_deps.setSkipButton(true, tr("Abort"));
progress_dialog_deps.setWindowTitle(tr("Checking for dependencies..."));
auto dret = progress_dialog_deps.execWithTask(depTask.get());
// If the dialog was skipped / some download error happened
if (dret == QDialog::DialogCode::Rejected) {
m_aborted = true;
QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection);
return;
}
static FlameAPI api;
for (auto dep : depTask->getDependecies()) {
auto changelog = dep->version.changelog;
if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME)
changelog = api.getModFileChangelog(dep->version.addonId.toInt(), dep->version.fileId.toInt());
auto download_task = makeShared<ResourceDownloadTask>(dep->pack, dep->version, m_mod_model);
CheckUpdateTask::UpdatableMod updatable = { dep->pack->name, dep->version.hash, "", dep->version.version,
changelog, dep->pack->provider, download_task };
appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download);
}
}
// If there's no mod to be updated // If there's no mod to be updated
if (ui->modTreeWidget->topLevelItemCount() == 0) { if (ui->modTreeWidget->topLevelItemCount() == 0) {
m_no_updates = true; m_no_updates = true;
@ -342,7 +390,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R
} else { } else {
QString reason{ tr("Couldn't find a valid version on the selected mod provider(s)") }; QString reason{ tr("Couldn't find a valid version on the selected mod provider(s)") };
m_failed_metadata.append({mod, reason}); m_failed_metadata.append({ mod, reason });
} }
} }