From dfab55112b783d191ac9b596df9c2972b5fe74cb Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 10 Jun 2022 16:43:01 -0300 Subject: [PATCH] feat: remove existing mod when updating/redownloading it Signed-off-by: flow --- launcher/ModDownloadTask.cpp | 11 ++++++++++- launcher/ModDownloadTask.h | 5 +++++ launcher/minecraft/mod/Mod.cpp | 7 +++++-- launcher/minecraft/mod/ModFolderModel.cpp | 14 ++++++++++++++ launcher/minecraft/mod/ModFolderModel.h | 2 ++ .../minecraft/mod/tasks/LocalModUpdateTask.cpp | 5 +++++ launcher/minecraft/mod/tasks/LocalModUpdateTask.h | 3 +++ 7 files changed, 44 insertions(+), 3 deletions(-) diff --git a/launcher/ModDownloadTask.cpp b/launcher/ModDownloadTask.cpp index 41856fb5..b1dd88d3 100644 --- a/launcher/ModDownloadTask.cpp +++ b/launcher/ModDownloadTask.cpp @@ -27,6 +27,7 @@ ModDownloadTask::ModDownloadTask(ModPlatform::IndexedPack mod, ModPlatform::Inde { if (is_indexed) { m_update_task.reset(new LocalModUpdateTask(mods->indexDir(), m_mod, m_mod_version)); + connect(m_update_task.get(), &LocalModUpdateTask::hasOldMod, this, &ModDownloadTask::hasOldMod); addTask(m_update_task); } @@ -40,12 +41,13 @@ ModDownloadTask::ModDownloadTask(ModPlatform::IndexedPack mod, ModPlatform::Inde connect(m_filesNetJob.get(), &NetJob::failed, this, &ModDownloadTask::downloadFailed); addTask(m_filesNetJob); - } void ModDownloadTask::downloadSucceeded() { m_filesNetJob.reset(); + if (!std::get<0>(to_delete).isEmpty()) + mods->uninstallMod(std::get<1>(to_delete), true); } void ModDownloadTask::downloadFailed(QString reason) @@ -58,3 +60,10 @@ void ModDownloadTask::downloadProgressChanged(qint64 current, qint64 total) { emit progress(current, total); } + +// This indirection is done so that we don't delete a mod before being sure it was +// downloaded successfully! +void ModDownloadTask::hasOldMod(QString name, QString filename) +{ + to_delete = {name, filename}; +} diff --git a/launcher/ModDownloadTask.h b/launcher/ModDownloadTask.h index 6e204e70..95020470 100644 --- a/launcher/ModDownloadTask.h +++ b/launcher/ModDownloadTask.h @@ -46,6 +46,11 @@ private: void downloadFailed(QString reason); void downloadSucceeded(); + + std::tuple to_delete {"", ""}; + +private slots: + void hasOldMod(QString name, QString filename); }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 37ec8eca..81bb902f 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -183,9 +183,12 @@ auto Mod::details() const -> const ModDetails& auto Mod::name() const -> QString { auto d_name = details().name; - if (!d_name.isEmpty()) { + if (!d_name.isEmpty()) return d_name; - } + + if (status() != ModStatus::NoMetadata) + return metadata()->name; + return m_name; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index e72eb13e..adc828c2 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -356,6 +356,20 @@ bool ModFolderModel::installMod(const QString &filename) return false; } +bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadata) +{ + + for(auto mod : allMods()){ + if(mod.fileinfo().fileName() == filename){ + auto index_dir = indexDir(); + mod.destroy(index_dir, preserve_metadata); + return true; + } + } + + return false; +} + bool ModFolderModel::setModStatus(const QModelIndexList& indexes, ModStatusAction enable) { if(interaction_disabled) { diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index c3b493b8..10289f8d 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -118,6 +118,8 @@ public: */ bool installMod(const QString& filename); + bool uninstallMod(const QString& filename, bool preserve_metadata = false); + /// Deletes all the selected mods bool deleteMods(const QModelIndexList &indexes); diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index 1bdecb8c..c73e855e 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -44,6 +44,11 @@ void LocalModUpdateTask::executeTask() { setStatus(tr("Updating index for mod:\n%1").arg(m_mod.name)); + auto old_metadata = Metadata::get(m_index_dir, m_mod.name); + if (old_metadata.isValid()) { + emit hasOldMod(old_metadata.name, old_metadata.filename); + } + auto pw_mod = Metadata::create(m_index_dir, m_mod, m_mod_version); Metadata::update(m_index_dir, pw_mod); diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h index 2db183e0..1d2f06a6 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.h +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.h @@ -37,6 +37,9 @@ class LocalModUpdateTask : public Task { //! Entry point for tasks. void executeTask() override; + signals: + void hasOldMod(QString name, QString filename); + private: QDir m_index_dir; ModPlatform::IndexedPack& m_mod;