From 0b26d24c9bdb4b6a52ce2ae90f0e0866152d0a35 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 4 Jan 2026 03:09:12 +0200 Subject: [PATCH] ask user if he wants to delete saves on modpack update Signed-off-by: Trial97 --- launcher/InstanceCreationTask.cpp | 27 ++++++++++++++++++- launcher/InstanceCreationTask.h | 4 ++- launcher/InstanceTask.cpp | 11 ++++++++ launcher/InstanceTask.h | 2 ++ .../flame/FlameInstanceCreationTask.cpp | 14 +++------- .../modrinth/ModrinthInstanceCreationTask.cpp | 20 +++----------- 6 files changed, 48 insertions(+), 30 deletions(-) diff --git a/launcher/InstanceCreationTask.cpp b/launcher/InstanceCreationTask.cpp index 1f0cc99c8..ecc9fe591 100644 --- a/launcher/InstanceCreationTask.cpp +++ b/launcher/InstanceCreationTask.cpp @@ -3,6 +3,7 @@ #include #include +#include "InstanceTask.h" #include "minecraft/MinecraftLoadAndCheck.h" #include "tasks/SequentialTask.h" @@ -61,7 +62,7 @@ void InstanceCreationTask::executeTask() setStatus(tr("Removing old conflicting files...")); qDebug() << "Removing old files"; - for (const QString& path : m_files_to_remove) { + for (const QString& path : m_filesToRemove) { if (!QFile::exists(path)) continue; @@ -108,3 +109,27 @@ void InstanceCreationTask::executeTask() m_gameFilesTask->start(); } } + +void InstanceCreationTask::scheduleToDelete(QWidget* parent, QDir dir, QString path, bool checkDisabled) +{ + if (path.isEmpty()) { + return; + } + if (path.startsWith("saves/")) { + if (m_shouldDeleteSaves == ShouldDeleteSaves::NotAsked) { + m_shouldDeleteSaves = askIfShouldDeleteSaves(parent); + } + if (m_shouldDeleteSaves == ShouldDeleteSaves::No) { + return; + } + } + qDebug() << "Scheduling" << path << "for removal"; + m_filesToRemove.append(dir.absoluteFilePath(path)); + if (checkDisabled) { + if (path.endsWith(".disabled")) { // remove it if it was enabled/disabled by user + m_filesToRemove.append(dir.absoluteFilePath(path.chopped(9))); + } else { + m_filesToRemove.append(dir.absoluteFilePath(path + ".disabled")); + } + } +} diff --git a/launcher/InstanceCreationTask.h b/launcher/InstanceCreationTask.h index e25afd3e9..416cf81db 100644 --- a/launcher/InstanceCreationTask.h +++ b/launcher/InstanceCreationTask.h @@ -38,11 +38,13 @@ class InstanceCreationTask : public InstanceTask { protected: void setError(const QString& message) { m_error_message = message; }; + void scheduleToDelete(QWidget* parent, QDir dir, QString path, bool checkDisabled = false); protected: bool m_abort = false; - QStringList m_files_to_remove; + QStringList m_filesToRemove; + ShouldDeleteSaves m_shouldDeleteSaves; private: QString m_error_message; diff --git a/launcher/InstanceTask.cpp b/launcher/InstanceTask.cpp index be10bbe07..01998a7aa 100644 --- a/launcher/InstanceTask.cpp +++ b/launcher/InstanceTask.cpp @@ -1,4 +1,5 @@ #include "InstanceTask.h" +#include #include "Application.h" #include "settings/SettingsObject.h" @@ -82,3 +83,13 @@ void InstanceName::setName(InstanceName& other) } InstanceTask::InstanceTask() : Task(), InstanceName() {} + +ShouldDeleteSaves askIfShouldDeleteSaves(QWidget* parent) +{ + auto dialog = CustomMessageBox::selectable(parent, QObject::tr("Delete Existing Save Files"), + QObject::tr("An earlier version of this mod pack installed save files.\n" + "Would you like to remove those existing saves as part of this update?"), + QMessageBox::Question, QMessageBox::No | QMessageBox::Yes); + auto result = dialog->exec(); + return result == QMessageBox::Yes ? ShouldDeleteSaves::Yes : ShouldDeleteSaves::No; +} diff --git a/launcher/InstanceTask.h b/launcher/InstanceTask.h index cd5a2b35a..125930a27 100644 --- a/launcher/InstanceTask.h +++ b/launcher/InstanceTask.h @@ -8,6 +8,8 @@ enum class InstanceNameChange { ShouldChange, ShouldKeep }; [[nodiscard]] InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& old_name, const QString& new_name); enum class ShouldUpdate { Update, SkipUpdating, Cancel }; [[nodiscard]] ShouldUpdate askIfShouldUpdate(QWidget* parent, QString original_version_name); +enum class ShouldDeleteSaves { NotAsked, Yes, No }; +[[nodiscard]] ShouldDeleteSaves askIfShouldDeleteSaves(QWidget* parent); struct InstanceName { public: diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index a79801cdf..66220fddd 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -35,6 +35,7 @@ #include "FlameInstanceCreationTask.h" +#include "InstanceTask.h" #include "QObjectPtr.h" #include "minecraft/mod/tasks/LocalResourceUpdateTask.h" #include "modplatform/flame/FileResolvingTask.h" @@ -170,10 +171,7 @@ bool FlameCreationTask::updateInstance() // FIXME: We may want to do something about disabled mods. auto old_overrides = Override::readOverrides("overrides", old_index_folder); for (const auto& entry : old_overrides) { - if (entry.isEmpty()) - continue; - qDebug() << "Scheduling" << entry << "for removal"; - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(entry)); + scheduleToDelete(m_parent, old_minecraft_dir, entry); } // Remove remaining old files (we need to do an API request to know which ids are which files...) @@ -224,13 +222,7 @@ bool FlameCreationTask::updateInstance() continue; QString relative_path(FS::PathCombine(file.targetFolder, file.version.fileName)); - qDebug() << "Scheduling" << relative_path << "for removal"; - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(relative_path)); - if (relative_path.endsWith(".disabled")) { // remove it if it was enabled/disabled by user - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(relative_path.chopped(9))); - } else { - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(relative_path + ".disabled")); - } + scheduleToDelete(m_parent, old_minecraft_dir, relative_path, true); } }); connect(job.get(), &Task::failed, this, [](QString reason) { qCritical() << "Failed to get files:" << reason; }); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 6409c4f35..f308c88bc 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -115,15 +115,7 @@ bool ModrinthCreationTask::updateInstance() // so we're fine removing them! if (!old_files.empty()) { for (auto const& file : old_files) { - if (file.path.isEmpty()) - continue; - qDebug() << "Scheduling" << file.path << "for removal"; - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(file.path)); - if (file.path.endsWith(".disabled")) { // remove it if it was enabled/disabled by user - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(file.path.chopped(9))); - } else { - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(file.path + ".disabled")); - } + scheduleToDelete(m_parent, old_minecraft_dir, file.path, true); } } @@ -132,18 +124,12 @@ bool ModrinthCreationTask::updateInstance() // FIXME: We may want to do something about disabled mods. auto old_overrides = Override::readOverrides("overrides", old_index_folder); for (const auto& entry : old_overrides) { - if (entry.isEmpty()) - continue; - qDebug() << "Scheduling" << entry << "for removal"; - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(entry)); + scheduleToDelete(m_parent, old_minecraft_dir, entry); } auto old_client_overrides = Override::readOverrides("client-overrides", old_index_folder); for (const auto& entry : old_client_overrides) { - if (entry.isEmpty()) - continue; - qDebug() << "Scheduling" << entry << "for removal"; - m_files_to_remove.append(old_minecraft_dir.absoluteFilePath(entry)); + scheduleToDelete(m_parent, old_minecraft_dir, entry); } } else { // We don't have an old index file, so we may duplicate stuff!