From 91a5c4bdcbd3ae18139b85899f051fb3d9cbd1fc Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 11 Jun 2022 17:19:34 -0300 Subject: [PATCH] feat: add metadata get/delete via mod id This is, in many cases, more reliable than name comparisons, so it's useful specially in cases where a mod changes name between versions Signed-off-by: flow --- launcher/ModDownloadTask.cpp | 8 +++-- launcher/minecraft/mod/MetadataHandler.h | 10 ++++++ launcher/minecraft/mod/Mod.cpp | 8 ++--- .../mod/tasks/LocalModUpdateTask.cpp | 2 +- launcher/modplatform/packwiz/Packwiz.cpp | 33 +++++++++++++++++-- launcher/modplatform/packwiz/Packwiz.h | 8 +++++ 6 files changed, 57 insertions(+), 12 deletions(-) diff --git a/launcher/ModDownloadTask.cpp b/launcher/ModDownloadTask.cpp index b1dd88d3..7d35ff69 100644 --- a/launcher/ModDownloadTask.cpp +++ b/launcher/ModDownloadTask.cpp @@ -46,8 +46,12 @@ ModDownloadTask::ModDownloadTask(ModPlatform::IndexedPack mod, ModPlatform::Inde void ModDownloadTask::downloadSucceeded() { m_filesNetJob.reset(); - if (!std::get<0>(to_delete).isEmpty()) - mods->uninstallMod(std::get<1>(to_delete), true); + auto name = std::get<0>(to_delete); + if (!name.isEmpty()) { + // If they have the same name, we keep the metadata. + // This is a workaround for mods that change names between versions ;c + mods->uninstallMod(std::get<1>(to_delete), name == m_mod.name); + } } void ModDownloadTask::downloadFailed(QString reason) diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 56962818..d5f01c42 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -52,8 +52,18 @@ class Metadata { Packwiz::V1::deleteModIndex(index_dir, mod_name); } + static void remove(QDir& index_dir, QVariant& mod_id) + { + Packwiz::V1::deleteModIndex(index_dir, mod_id); + } + static auto get(QDir& index_dir, QString& mod_name) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_name); } + + static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct + { + return Packwiz::V1::getIndexForMod(index_dir, mod_id); + } }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 81bb902f..bba7b342 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -164,12 +164,8 @@ void Mod::setMetadata(Metadata::ModStruct* metadata) auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool { - auto n = name(); - // FIXME: This can fail to remove the metadata if the - // "ModMetadataDisabled" setting is on, since there could - // be a name mismatch! - if(!preserve_metadata) - Metadata::remove(index_dir, n); + if (!preserve_metadata && status() != ModStatus::NoMetadata) + Metadata::remove(index_dir, metadata()->mod_id()); m_type = MOD_UNKNOWN; return FS::deletePath(m_file.filePath()); diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index c73e855e..f0ef795d 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -44,7 +44,7 @@ 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); + auto old_metadata = Metadata::get(m_index_dir, m_mod.addonId); if (old_metadata.isValid()) { emit hasOldMod(old_metadata.name, old_metadata.filename); } diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 0782b9f4..8bd66088 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -144,6 +144,9 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) QFile index_file(index_dir.absoluteFilePath(real_fname)); + if (real_fname != normalized_fname) + index_file.rename(normalized_fname); + // There's already data on there! // TODO: We should do more stuff here, as the user is likely trying to // override a file. In this case, check versions and ask the user what @@ -196,16 +199,28 @@ void V1::deleteModIndex(QDir& index_dir, QString& mod_name) QFile index_file(index_dir.absoluteFilePath(real_fname)); - if(!index_file.exists()){ + if (!index_file.exists()) { qWarning() << QString("Tried to delete non-existent mod metadata for %1!").arg(mod_name); return; } - if(!index_file.remove()){ + if (!index_file.remove()) { qWarning() << QString("Failed to remove metadata for mod %1!").arg(mod_name); } } +void V1::deleteModIndex(QDir& index_dir, QVariant& mod_id) +{ + for (auto& file_name : index_dir.entryList(QDir::Filter::Files)) { + auto mod = getIndexForMod(index_dir, file_name); + + if (mod.mod_id() == mod_id) { + deleteModIndex(index_dir, mod.name); + break; + } + } +} + auto V1::getIndexForMod(QDir& index_dir, QString& index_file_name) -> Mod { Mod mod; @@ -286,4 +301,16 @@ auto V1::getIndexForMod(QDir& index_dir, QString& index_file_name) -> Mod return mod; } -} // namespace Packwiz +auto V1::getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod +{ + for (auto& file_name : index_dir.entryList(QDir::Filter::Files)) { + auto mod = getIndexForMod(index_dir, file_name); + + if (mod.mod_id() == mod_id) + return mod; + } + + return {}; +} + +} // namespace Packwiz diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 3c99769c..9d643703 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -84,10 +84,18 @@ class V1 { /* Deletes the metadata for the mod with the given name. If the metadata doesn't exist, it does nothing. */ static void deleteModIndex(QDir& index_dir, QString& mod_name); + /* Deletes the metadata for the mod with the given id. If the metadata doesn't exist, it does nothing. */ + static void deleteModIndex(QDir& index_dir, QVariant& mod_id); + /* Gets the metadata for a mod with a particular name. * If the mod doesn't have a metadata, it simply returns an empty Mod object. * */ static auto getIndexForMod(QDir& index_dir, QString& index_file_name) -> Mod; + + /* Gets the metadata for a mod with a particular id. + * If the mod doesn't have a metadata, it simply returns an empty Mod object. + * */ + static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod; }; } // namespace Packwiz