From 826da579447ca707bdbf3c74c1d586325185dab8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 8 Dec 2025 22:43:29 +0000 Subject: [PATCH 1/3] Properly rename shader config on update/version change Signed-off-by: TheKodeToad --- launcher/ResourceDownloadTask.cpp | 27 ++++++++++++++++--- launcher/ResourceDownloadTask.h | 1 + .../minecraft/mod/ResourceFolderModel.cpp | 2 +- launcher/minecraft/mod/ResourceFolderModel.h | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp index 0fe082ac4..c5d9a7c67 100644 --- a/launcher/ResourceDownloadTask.cpp +++ b/launcher/ResourceDownloadTask.cpp @@ -21,9 +21,11 @@ #include "Application.h" +#include "FileSystem.h" #include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ResourceFolderModel.h" +#include "minecraft/mod/ShaderPackFolderModel.h" #include "modplatform/helpers/HashUtils.h" #include "net/ApiDownload.h" #include "net/ChecksumValidator.h" @@ -55,7 +57,9 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, } } - auto action = Net::ApiDownload::makeFile(m_pack_version.downloadUrl, dir.absoluteFilePath(getFilename())); + m_targetPath = dir.absoluteFilePath(getFilename()); + + auto action = Net::ApiDownload::makeFile(m_pack_version.downloadUrl, m_targetPath); if (!m_pack_version.hash_type.isEmpty() && !m_pack_version.hash.isEmpty()) { switch (Hashing::algorithmFromString(m_pack_version.hash_type)) { case Hashing::Algorithm::Md4: @@ -91,8 +95,25 @@ void ResourceDownloadTask::downloadSucceeded() m_filesNetJob.reset(); auto name = std::get<0>(to_delete); auto filename = std::get<1>(to_delete); - if (!name.isEmpty() && filename != m_pack_version.fileName) - m_pack_model->uninstallResource(filename, true); + + if (name.isEmpty() || filename == m_pack_version.fileName) + return; + + m_pack_model->uninstallResource(filename, true); + + // also rename the shader config file + if (dynamic_cast(m_pack_model.get()) != nullptr) { + QFileInfo config(m_pack_model->dir(), filename + ".txt"); + + if (config.exists()) { + QString src = config.filePath(); + QString dest = m_targetPath + ".txt"; + bool success = QFile::rename(src, dest); + + if (!success) + emit logWarning(tr("Failed to rename shader config '%1' to '%2'").arg(src, dest)); + } + } } void ResourceDownloadTask::downloadFailed(QString reason) diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index a10e0ac2c..de599c501 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -48,6 +48,7 @@ class ResourceDownloadTask : public SequentialTask { ModPlatform::IndexedVersion m_pack_version; const std::shared_ptr m_pack_model; QString m_custom_target_folder; + QString m_targetPath; NetJob::Ptr m_filesNetJob; LocalResourceUpdateTask::Ptr m_update_task; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index e8b4c862c..785d3f7e5 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -204,7 +204,7 @@ void ResourceFolderModel::installResourceWithFlameMetadata(QString path, ModPlat } } -bool ResourceFolderModel::uninstallResource(QString file_name, bool preserve_metadata) +bool ResourceFolderModel::uninstallResource(const QString& file_name, bool preserve_metadata) { for (auto& resource : m_resources) { if (resource->fileinfo().fileName() == file_name) { diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 391c5c0c0..5c41fc520 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -99,7 +99,7 @@ class ResourceFolderModel : public QAbstractListModel { * * Returns whether the removal was successful. */ - virtual bool uninstallResource(QString file_name, bool preserve_metadata = false); + virtual bool uninstallResource(const QString& file_name, bool preserve_metadata = false); virtual bool deleteResources(const QModelIndexList&); virtual void deleteMetadata(const QModelIndexList&); From 2477c4f021a9cc4b9fd8ba518efaeb746b7af01b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 9 Dec 2025 11:04:01 +0000 Subject: [PATCH 2/3] Use FS::move instead; check new config does not exist Signed-off-by: TheKodeToad --- launcher/ResourceDownloadTask.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp index c5d9a7c67..89d09b9b3 100644 --- a/launcher/ResourceDownloadTask.cpp +++ b/launcher/ResourceDownloadTask.cpp @@ -103,15 +103,16 @@ void ResourceDownloadTask::downloadSucceeded() // also rename the shader config file if (dynamic_cast(m_pack_model.get()) != nullptr) { - QFileInfo config(m_pack_model->dir(), filename + ".txt"); + QFileInfo oldConfig(m_pack_model->dir(), filename + ".txt"); + QFileInfo newConfig(m_targetPath + ".txt"); - if (config.exists()) { - QString src = config.filePath(); - QString dest = m_targetPath + ".txt"; - bool success = QFile::rename(src, dest); + if (oldConfig.exists() && !newConfig.exists()) { + bool success = FS::move(oldConfig.filePath(), newConfig.filePath()); - if (!success) - emit logWarning(tr("Failed to rename shader config '%1' to '%2'").arg(src, dest)); + if (!success) { + emit logWarning( + tr("Failed to rename shader config from '%1' to '%2'").arg(oldConfig.absoluteFilePath(), newConfig.absoluteFilePath())); + } } } } From 66c8afe4d3487931e401a2defeaabb0a5fce891f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 9 Dec 2025 11:42:17 +0000 Subject: [PATCH 3/3] Simplify implementation by removing some unused code Only applies to cauldron loader which doesn't exist on Modrinth or CurseForge, and doesn't even make sense for shaders. Signed-off-by: TheKodeToad --- launcher/ResourceDownloadTask.cpp | 38 ++++++------------- launcher/ResourceDownloadTask.h | 6 +-- .../ui/dialogs/ResourceDownloadDialog.cpp | 5 +-- launcher/ui/dialogs/ReviewMessageBox.cpp | 13 +------ launcher/ui/dialogs/ReviewMessageBox.h | 1 - .../ui/pages/modplatform/ResourceModel.cpp | 5 +-- launcher/ui/pages/modplatform/ResourceModel.h | 3 +- .../ui/pages/modplatform/ShaderPackPage.cpp | 5 +-- 8 files changed, 19 insertions(+), 57 deletions(-) diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp index 89d09b9b3..875a7f02d 100644 --- a/launcher/ResourceDownloadTask.cpp +++ b/launcher/ResourceDownloadTask.cpp @@ -22,7 +22,6 @@ #include "Application.h" #include "FileSystem.h" -#include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ResourceFolderModel.h" #include "minecraft/mod/ShaderPackFolderModel.h" @@ -33,9 +32,8 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion version, const std::shared_ptr packs, - bool is_indexed, - QString custom_target_folder) - : m_pack(std::move(pack)), m_pack_version(std::move(version)), m_pack_model(packs), m_custom_target_folder(custom_target_folder) + bool is_indexed) + : m_pack(std::move(pack)), m_pack_version(std::move(version)), m_pack_model(packs) { if (is_indexed) { m_update_task.reset(new LocalResourceUpdateTask(m_pack_model->indexDir(), *m_pack, m_pack_version)); @@ -47,19 +45,7 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, m_filesNetJob.reset(new NetJob(tr("Resource download"), APPLICATION->network())); m_filesNetJob->setStatus(tr("Downloading resource:\n%1").arg(m_pack_version.downloadUrl)); - QDir dir{ m_pack_model->dir() }; - { - // FIXME: Make this more generic. May require adding additional info to IndexedVersion, - // or adquiring a reference to the base instance. - if (!m_custom_target_folder.isEmpty()) { - dir.cdUp(); - dir.cd(m_custom_target_folder); - } - } - - m_targetPath = dir.absoluteFilePath(getFilename()); - - auto action = Net::ApiDownload::makeFile(m_pack_version.downloadUrl, m_targetPath); + auto action = Net::ApiDownload::makeFile(m_pack_version.downloadUrl, m_pack_model->dir().absoluteFilePath(getFilename())); if (!m_pack_version.hash_type.isEmpty() && !m_pack_version.hash.isEmpty()) { switch (Hashing::algorithmFromString(m_pack_version.hash_type)) { case Hashing::Algorithm::Md4: @@ -93,26 +79,24 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, void ResourceDownloadTask::downloadSucceeded() { m_filesNetJob.reset(); - auto name = std::get<0>(to_delete); - auto filename = std::get<1>(to_delete); + auto oldName = std::get<0>(to_delete); + auto oldFilename = std::get<1>(to_delete); - if (name.isEmpty() || filename == m_pack_version.fileName) + if (oldName.isEmpty() || oldFilename == m_pack_version.fileName) return; - m_pack_model->uninstallResource(filename, true); + m_pack_model->uninstallResource(oldFilename, true); // also rename the shader config file if (dynamic_cast(m_pack_model.get()) != nullptr) { - QFileInfo oldConfig(m_pack_model->dir(), filename + ".txt"); - QFileInfo newConfig(m_targetPath + ".txt"); + QFileInfo oldConfig(m_pack_model->dir(), oldFilename + ".txt"); + QFileInfo newConfig(m_pack_model->dir(), getFilename() + ".txt"); if (oldConfig.exists() && !newConfig.exists()) { bool success = FS::move(oldConfig.filePath(), newConfig.filePath()); - if (!success) { - emit logWarning( - tr("Failed to rename shader config from '%1' to '%2'").arg(oldConfig.absoluteFilePath(), newConfig.absoluteFilePath())); - } + if (!success) + emit logWarning(tr("Failed to rename shader config from '%1' to '%2'").arg(oldConfig.fileName(), newConfig.fileName())); } } } diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h index de599c501..78fe8efc7 100644 --- a/launcher/ResourceDownloadTask.h +++ b/launcher/ResourceDownloadTask.h @@ -33,10 +33,8 @@ class ResourceDownloadTask : public SequentialTask { explicit ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion version, std::shared_ptr packs, - bool is_indexed = true, - QString custom_target_folder = {}); + bool is_indexed = true); const QString& getFilename() const { return m_pack_version.fileName; } - const QString& getCustomPath() const { return m_custom_target_folder; } const QVariant& getVersionID() const { return m_pack_version.fileId; } const ModPlatform::IndexedVersion& getVersion() const { return m_pack_version; } const ModPlatform::ResourceProvider& getProvider() const { return m_pack->provider; } @@ -47,8 +45,6 @@ class ResourceDownloadTask : public SequentialTask { ModPlatform::IndexedPack::Ptr m_pack; ModPlatform::IndexedVersion m_pack_version; const std::shared_ptr m_pack_model; - QString m_custom_target_folder; - QString m_targetPath; NetJob::Ptr m_filesNetJob; LocalResourceUpdateTask::Ptr m_update_task; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index fae9fa03e..181a9d486 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -185,9 +185,8 @@ void ResourceDownloadDialog::confirm() }); for (auto& task : selected) { auto extraInfo = dependencyExtraInfo.value(task->getPack()->addonId.toString()); - confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(), - ModPlatform::ProviderCapabilities::name(task->getProvider()), extraInfo.required_by, - ModPlatform::indexedVersionTypeToString(task->getVersion().version_type), + confirm_dialog->appendResource({ task->getName(), task->getFilename(), ModPlatform::ProviderCapabilities::name(task->getProvider()), + extraInfo.required_by, ModPlatform::indexedVersionTypeToString(task->getVersion().version_type), !extraInfo.maybe_installed }); } diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp index c2d884756..d9556979a 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.cpp +++ b/launcher/ui/dialogs/ReviewMessageBox.cpp @@ -68,17 +68,6 @@ void ReviewMessageBox::appendResource(ResourceInformation&& info) filenameItem->setText(0, tr("Filename: %1").arg(info.filename)); filenameItem->setData(0, Qt::UserRole, info.filename); - if (!info.custom_file_path.isEmpty()) { - auto customPathItem = new QTreeWidgetItem(itemTop); - customPathItem->setText(0, tr("This download will be placed in: %1").arg(info.custom_file_path)); - customPathItem->setData(0, Qt::UserRole, info.custom_file_path); - - itemTop->setIcon(1, QIcon(QIcon::fromTheme("status-yellow"))); - itemTop->setToolTip( - 1, - tr("This file will be downloaded to a folder location different from the default, possibly due to its loader requiring it.")); - } - auto providerItem = new QTreeWidgetItem(itemTop); providerItem->setText(0, tr("Provider: %1").arg(info.provider)); providerItem->setData(0, Qt::UserRole, info.provider); @@ -137,4 +126,4 @@ void ReviewMessageBox::on_toggleDepsButton_clicked() auto state = m_deps_checked ? Qt::Checked : Qt::Unchecked; for (auto dep : m_deps) dep->setCheckState(0, state); -}; \ No newline at end of file +}; diff --git a/launcher/ui/dialogs/ReviewMessageBox.h b/launcher/ui/dialogs/ReviewMessageBox.h index 82a43bc11..ebc4979a6 100644 --- a/launcher/ui/dialogs/ReviewMessageBox.h +++ b/launcher/ui/dialogs/ReviewMessageBox.h @@ -16,7 +16,6 @@ class ReviewMessageBox : public QDialog { using ResourceInformation = struct res_info { QString name; QString filename; - QString custom_file_path{}; QString provider; QStringList required_by; QString version_type; diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 2d5add0c0..30d3dbdf4 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -472,11 +472,10 @@ void ResourceModel::infoRequestSucceeded(ModPlatform::IndexedPack::Ptr pack, con void ResourceModel::addPack(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion& version, const std::shared_ptr packs, - bool is_indexed, - QString custom_target_folder) + bool is_indexed) { version.is_currently_selected = true; - m_selected.append(makeShared(pack, version, packs, is_indexed, custom_target_folder)); + m_selected.append(makeShared(pack, version, packs, is_indexed)); } void ResourceModel::removePack(const QString& rem) diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index a261c6e43..8a0b7e06a 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -94,8 +94,7 @@ class ResourceModel : public QAbstractListModel { void addPack(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion& version, std::shared_ptr packs, - bool is_indexed = false, - QString custom_target_folder = {}); + bool is_indexed = false); void removePack(const QString& rem); QList selectedPacks() { return m_selected; } diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp index ace07db0e..fda05b038 100644 --- a/launcher/ui/pages/modplatform/ShaderPackPage.cpp +++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp @@ -47,10 +47,7 @@ void ShaderPackResourcePage::addResourceToPage(ModPlatform::IndexedPack::Ptr pac const std::shared_ptr base_model) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); - QString custom_target_folder; - if (version.loaders & ModPlatform::Cauldron) - custom_target_folder = QStringLiteral("resourcepacks"); - m_model->addPack(pack, version, base_model, is_indexed, custom_target_folder); + m_model->addPack(pack, version, base_model, is_indexed); } } // namespace ResourceDownload