diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 9e399bbfb..a39f44015 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -1691,4 +1691,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 863b0165f..2a7626953 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -159,15 +159,14 @@ 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)) - return false; + if (QFile::exists(path)) { + path = FS::getUniqueResourceName(path); + } } + if (!file.rename(path)) + return false; setFile(QFileInfo(path)); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index aba0886e8..941e7ce58 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -215,9 +215,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; diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h index 23a2b649a..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" @@ -50,6 +51,12 @@ class BasicFolderLoadTask : public Task { m_dir.refresh(); for (auto entry : m_dir.entryInfoList()) { + 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); diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 2094df4fc..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 @@ -63,6 +64,12 @@ void ModFolderLoadTask::executeTask() // Read JAR files that don't have metadata m_mods_dir.refresh(); 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 (mod->enabled()) {