From 3d84635b24e52c35b70e044bed67060adb1dcfd6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 26 Oct 2023 20:09:12 +0300 Subject: [PATCH 1/6] Remove file on mod duplication Signed-off-by: Trial97 --- launcher/InstanceList.cpp | 12 ++++++------ launcher/InstanceList.h | 2 +- launcher/minecraft/mod/Resource.cpp | 10 +++++----- launcher/minecraft/mod/ResourceFolderModel.cpp | 3 --- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index 756ff93dd..e245fc2c6 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -371,13 +371,13 @@ void InstanceList::undoTrashInstance() auto top = m_trashHistory.pop(); - while (QDir(top.polyPath).exists()) { + while (QDir(top.rootPath).exists()) { top.id += "1"; - top.polyPath += "1"; + top.rootPath += "1"; } - qDebug() << "Moving" << top.trashPath << "back to" << top.polyPath; - QFile(top.trashPath).rename(top.polyPath); + qDebug() << "Moving" << top.trashPath << "back to" << top.rootPath; + QFile(top.trashPath).rename(top.rootPath); m_instanceGroupIndex[top.id] = top.groupName; increaseGroupCount(top.groupName); @@ -634,8 +634,8 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) QString inst_type = instanceSettings->get("InstanceType").toString(); - // NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix - // instance + // NOTE: Some PrismLauncher versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a + // OneSix instance if (inst_type == "OneSix" || inst_type.isEmpty()) { inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot)); } else { diff --git a/launcher/InstanceList.h b/launcher/InstanceList.h index 6b0bcd810..1a70b57b9 100644 --- a/launcher/InstanceList.h +++ b/launcher/InstanceList.h @@ -58,7 +58,7 @@ enum class GroupsState { NotLoaded, Steady, Dirty }; struct TrashHistoryItem { QString id; - QString polyPath; + QString rootPath; QString trashPath; QString groupName; }; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index da806f0f4..05940fcb4 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -130,15 +130,15 @@ bool Resource::enable(EnableAction action) if (!path.endsWith(".disabled")) return false; path.chop(9); - - if (!file.rename(path)) - return false; } else { path += ".disabled"; - - if (!file.rename(path)) + } + if (QFileInfo::exists(path)) { // the path exists so just remove the file at path + if (!QFile::remove(path)) return false; } + if (!file.rename(path)) + return false; setFile(QFileInfo(path)); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 0503b660b..8f2c87747 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -213,9 +213,6 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena } auto new_id = resource->internal_id(); - if (m_resources_index.contains(new_id)) { - // FIXME: https://github.com/PolyMC/PolyMC/issues/550 - } m_resources_index.remove(old_id); m_resources_index[new_id] = row; From 60a7628dbbf21c27cdc8021b01278b173f56dedb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 26 Oct 2023 20:43:26 +0300 Subject: [PATCH 2/6] delete duplicate mods Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/BasicFolderLoadTask.h | 10 ++++++++-- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h index 23a2b649a..6e8b8ed43 100644 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h @@ -49,10 +49,16 @@ class BasicFolderLoadTask : public Task { connect(this, &Task::finished, this->thread(), &QThread::quit); m_dir.refresh(); + QStringList names; for (auto entry : m_dir.entryInfoList()) { auto resource = m_create_func(entry); - resource->moveToThread(m_thread_to_spawn_into); - m_result->resources.insert(resource->internal_id(), resource); + if (names.contains(resource->name())) { + resource->destroy(); + } else { + names << resource->name(); + resource->moveToThread(m_thread_to_spawn_into); + m_result->resources.insert(resource->internal_id(), resource); + } } if (m_aborted) diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 2094df4fc..c11759dd2 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -62,9 +62,15 @@ void ModFolderLoadTask::executeTask() // Read JAR files that don't have metadata m_mods_dir.refresh(); + QStringList names; for (auto entry : m_mods_dir.entryInfoList()) { Mod* mod(new Mod(entry)); + if (names.contains(mod->name())) { + mod->destroy(m_index_dir, true); + continue; + } + names << mod->name(); if (mod->enabled()) { if (m_result->mods.contains(mod->internal_id())) { m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); From d2510b851ba9576304f89c7e146bbd41215542a6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jun 2024 22:45:15 +0300 Subject: [PATCH 3/6] mark files as duplicate Signed-off-by: Trial97 --- launcher/FileSystem.cpp | 26 +++++++++++++++++++ launcher/FileSystem.h | 2 ++ launcher/minecraft/mod/Resource.cpp | 7 +++-- .../minecraft/mod/tasks/BasicFolderLoadTask.h | 17 ++++++------ .../minecraft/mod/tasks/ModFolderLoadTask.cpp | 13 +++++----- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index cafc4f25a..36410f03e 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -1701,4 +1701,30 @@ QString getPathNameInLocal8bit(const QString& file) } #endif +QString getUniqueResourceName(const QString& filePath) +{ + auto newFileName = filePath; + if (!newFileName.endsWith(".disabled")) { + return newFileName; // prioritize enabled mods + } + newFileName.chop(9); + if (!QFile::exists(newFileName)) { + return filePath; + } + QFileInfo fileInfo(filePath); + auto baseName = fileInfo.completeBaseName(); + auto path = fileInfo.absolutePath(); + + int counter = 1; + do { + if (counter == 1) { + newFileName = FS::PathCombine(path, baseName + ".duplicate"); + } else { + newFileName = FS::PathCombine(path, baseName + ".duplicate" + QString::number(counter)); + } + counter++; + } while (QFile::exists(newFileName)); + + return newFileName; +} } // namespace FS diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index 23bf5f16e..66adf7a36 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -560,4 +560,6 @@ uintmax_t hardLinkCount(const QString& path); QString getPathNameInLocal8bit(const QString& file); #endif +QString getUniqueResourceName(const QString& filePath); + } // namespace FS diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 62bf6b9a2..6066f02db 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -161,10 +161,13 @@ bool Resource::enable(EnableAction action) path.chop(9); } else { path += ".disabled"; + auto newFilePath = FS::getUniqueResourceName(path); + if (newFilePath != path) { + FS::move(path, newFilePath); + } } if (QFileInfo::exists(path)) { // the path exists so just remove the file at path - if (!QFile::remove(path)) - return false; + return false; } if (!file.rename(path)) return false; diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h index 6e8b8ed43..2bce2c137 100644 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h @@ -7,6 +7,7 @@ #include +#include "FileSystem.h" #include "minecraft/mod/Resource.h" #include "tasks/Task.h" @@ -49,16 +50,16 @@ class BasicFolderLoadTask : public Task { connect(this, &Task::finished, this->thread(), &QThread::quit); m_dir.refresh(); - QStringList names; for (auto entry : m_dir.entryInfoList()) { - auto resource = m_create_func(entry); - if (names.contains(resource->name())) { - resource->destroy(); - } else { - names << resource->name(); - resource->moveToThread(m_thread_to_spawn_into); - m_result->resources.insert(resource->internal_id(), resource); + auto filePath = entry.absoluteFilePath(); + auto newFilePath = FS::getUniqueResourceName(filePath); + if (newFilePath != filePath) { + FS::move(filePath, newFilePath); + entry = QFileInfo(newFilePath); } + auto resource = m_create_func(entry); + resource->moveToThread(m_thread_to_spawn_into); + m_result->resources.insert(resource->internal_id(), resource); } if (m_aborted) diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index c11759dd2..501d5be13 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -36,6 +36,7 @@ #include "ModFolderLoadTask.h" +#include "FileSystem.h" #include "minecraft/mod/MetadataHandler.h" #include @@ -62,15 +63,15 @@ void ModFolderLoadTask::executeTask() // Read JAR files that don't have metadata m_mods_dir.refresh(); - QStringList names; for (auto entry : m_mods_dir.entryInfoList()) { + auto filePath = entry.absoluteFilePath(); + auto newFilePath = FS::getUniqueResourceName(filePath); + if (newFilePath != filePath) { + FS::move(filePath, newFilePath); + entry = QFileInfo(newFilePath); + } Mod* mod(new Mod(entry)); - if (names.contains(mod->name())) { - mod->destroy(m_index_dir, true); - continue; - } - names << mod->name(); if (mod->enabled()) { if (m_result->mods.contains(mod->internal_id())) { m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); From b872f88617fa282f0b1a23e0a134225d360a000c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jun 2024 22:46:39 +0300 Subject: [PATCH 4/6] do not double rename Signed-off-by: Trial97 --- launcher/minecraft/mod/Resource.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 6066f02db..9228d5165 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -161,10 +161,7 @@ bool Resource::enable(EnableAction action) path.chop(9); } else { path += ".disabled"; - auto newFilePath = FS::getUniqueResourceName(path); - if (newFilePath != path) { - FS::move(path, newFilePath); - } + path = FS::getUniqueResourceName(path); } if (QFileInfo::exists(path)) { // the path exists so just remove the file at path return false; From 1a84dc9bcabbd212d1402d04f3f8a41021bdca8f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jun 2024 22:47:42 +0300 Subject: [PATCH 5/6] no need for extra exist check Signed-off-by: Trial97 --- launcher/minecraft/mod/Resource.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 9228d5165..62871cbf2 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -163,9 +163,6 @@ bool Resource::enable(EnableAction action) path += ".disabled"; path = FS::getUniqueResourceName(path); } - if (QFileInfo::exists(path)) { // the path exists so just remove the file at path - return false; - } if (!file.rename(path)) return false; From 8cdaf5d05f714fadc899081a1100f594f0e19782 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jun 2024 23:27:27 +0300 Subject: [PATCH 6/6] fix tests Signed-off-by: Trial97 --- launcher/minecraft/mod/Resource.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 62871cbf2..2a7626953 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -161,7 +161,9 @@ bool Resource::enable(EnableAction action) path.chop(9); } else { path += ".disabled"; - path = FS::getUniqueResourceName(path); + if (QFile::exists(path)) { + path = FS::getUniqueResourceName(path); + } } if (!file.rename(path)) return false;