From 29b717b49b77cb9947cbce9f6afd3f31b5cc73a6 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 9 Sep 2021 02:56:21 +0200 Subject: [PATCH 1/2] GH-3068 Icons dont necessarly overwrite each other --- launcher/InstanceImportTask.cpp | 8 ++-- launcher/icons/IIconList.h | 2 +- launcher/icons/IconList.cpp | 85 +++++++++++++++++++++++++++++---- launcher/icons/IconList.h | 7 ++- 4 files changed, 87 insertions(+), 15 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 3eac4d5794..a0ab77a9f2 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -107,7 +107,7 @@ void InstanceImportTask::processZipPack() root = mmcFound; m_modpackType = ModpackType::MultiMC; } - else if (technicFound) + else if(technicFound) { // process as Technic pack qDebug() << "Technic:" << technicFound; @@ -445,11 +445,11 @@ void InstanceImportTask::processMultiMC() { // import icon auto iconList = ENV.icons(); - if (iconList->iconFileExists(m_instIcon)) + if (!iconList->iconFileExists(m_instIcon)) { - iconList->deleteIcon(m_instIcon); + iconList->installIcon(importIconPath, m_instIcon); } - iconList->installIcons({importIconPath}); + } } emitSucceeded(); diff --git a/launcher/icons/IIconList.h b/launcher/icons/IIconList.h index 15d7dd1526..eb56f561f4 100644 --- a/launcher/icons/IIconList.h +++ b/launcher/icons/IIconList.h @@ -21,5 +21,5 @@ class IIconList virtual void saveIcon(const QString &key, const QString &path, const char * format) const = 0; virtual bool iconFileExists(const QString &key) const = 0; virtual void installIcons(const QStringList &iconFiles) = 0; - virtual void installIcon(const QString &file, const QString &name) = 0; + virtual void installIcon(const QString &file, QString &name) = 0; }; diff --git a/launcher/icons/IconList.cpp b/launcher/icons/IconList.cpp index 70350534ea..503a4a4f78 100644 --- a/launcher/icons/IconList.cpp +++ b/launcher/icons/IconList.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #define MAX_SIZE 1024 @@ -255,28 +256,96 @@ void IconList::installIcons(const QStringList &iconFiles) for (QString file : iconFiles) { QFileInfo fileinfo(file); - if (!fileinfo.isReadable() || !fileinfo.isFile()) + if(!fileinfo.isReadable() || !fileinfo.isFile()) continue; - QString target = FS::PathCombine(m_dir.dirName(), fileinfo.fileName()); + QFile sourceFile(file); + if(!sourceFile.open(QIODevice::ReadOnly)) + continue; + QString suffix = fileinfo.suffix(); if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg" && suffix != "gif") continue; + + const QString sourceHash = getIconHash(sourceFile); + QString sourceFileName = fileinfo.baseName(); + sourceFileName = QString("%1_%2.%3").arg(sourceFileName, sourceHash, suffix); + QString target = FS::PathCombine(m_dir.dirName(), sourceFileName); + + if(QFile::exists(target)) + { + QFile targetFile(target); + if(!targetFile.open(QIODevice::ReadOnly)) + continue; + const QString targetHash = getIconHash(targetFile); + + if(sourceHash == targetHash) + continue; + + QString targetFileName = fileinfo.baseName(); + targetFileName = QString("%1_%2.%3").arg(targetFileName, targetHash, suffix); + targetFileName = FS::PathCombine(m_dir.dirName(), targetFileName); + if(!targetFile.rename(targetFileName)) + continue; + } if (!QFile::copy(file, target)) continue; } } -void IconList::installIcon(const QString &file, const QString &name) +void IconList::installIcon(const QString &file, QString &name) { - QFileInfo fileinfo(file); - if(!fileinfo.isReadable() || !fileinfo.isFile()) - return; + QFileInfo fileinfo(file); + if(!fileinfo.isReadable() || !fileinfo.isFile()) + return; + + QFile sourceFile(file); + if(!sourceFile.open(QIODevice::ReadOnly)) + return; + + QString suffix = fileinfo.suffix(); + if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg" && suffix != "gif") + return; + + const QString sourceHash = getIconHash(sourceFile); + name = QString("%1_%2.%3").arg(name, sourceHash, suffix); + QString target = FS::PathCombine(m_dir.dirName(), name); + + if(QFile::exists(target)) + { + QFile targetFile(target); + if(!targetFile.open(QIODevice::ReadOnly)) + return; + + const QString targetHash = getIconHash(targetFile); + + if(sourceHash == targetHash) + return; + + QString targetFileName = QString(name); + targetFileName = QString("%1_%2.%3").arg(targetFileName, targetHash, suffix); + targetFileName = FS::PathCombine(m_dir.dirName(), targetFileName); + if(!targetFile.rename(targetFileName)) + return; + } + if (!QFile::copy(file, target)) + return; +} - QString target = FS::PathCombine(m_dir.dirName(), name); +const QString IconList::getIconHash(QFile& file) +{ + QByteArray iconByteArray = file.readAll(); + const QString iconHash = QString(QCryptographicHash::hash((iconByteArray), QCryptographicHash::Md5).toHex()); + return iconHash; +} - QFile::copy(file, target); +const QString IconList::getIconHash(const QString& fileName) +{ + QFile file(fileName); + if(!file.open(QIODevice::ReadOnly)) + return ""; + return getIconHash(file); } bool IconList::iconFileExists(const QString &key) const diff --git a/launcher/icons/IconList.h b/launcher/icons/IconList.h index 70266ebb1d..ba20c922cf 100644 --- a/launcher/icons/IconList.h +++ b/launcher/icons/IconList.h @@ -54,10 +54,13 @@ class IconList : public QAbstractListModel, public IIconList virtual Qt::ItemFlags flags(const QModelIndex &index) const override; void installIcons(const QStringList &iconFiles) override; - void installIcon(const QString &file, const QString &name) override; - + void installIcon(const QString &file, QString &name) override; + const MMCIcon * icon(const QString &key) const; + const QString getIconHash(QFile& file); + const QString getIconHash(const QString& fileName); + void startWatching(); void stopWatching(); From e2448d55949fd472075a17b4e14e9569cc3163e7 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 9 Sep 2021 03:11:09 +0200 Subject: [PATCH 2/2] sanitize filename --- launcher/icons/IconList.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/launcher/icons/IconList.cpp b/launcher/icons/IconList.cpp index 503a4a4f78..f145de3bae 100644 --- a/launcher/icons/IconList.cpp +++ b/launcher/icons/IconList.cpp @@ -268,7 +268,7 @@ void IconList::installIcons(const QStringList &iconFiles) continue; const QString sourceHash = getIconHash(sourceFile); - QString sourceFileName = fileinfo.baseName(); + QString sourceFileName = fileinfo.baseName().remove("_" + sourceHash).remove(sourceHash); sourceFileName = QString("%1_%2.%3").arg(sourceFileName, sourceHash, suffix); QString target = FS::PathCombine(m_dir.dirName(), sourceFileName); @@ -283,7 +283,7 @@ void IconList::installIcons(const QStringList &iconFiles) if(sourceHash == targetHash) continue; - QString targetFileName = fileinfo.baseName(); + QString targetFileName = fileinfo.baseName().remove("_" + targetHash).remove(targetHash); targetFileName = QString("%1_%2.%3").arg(targetFileName, targetHash, suffix); targetFileName = FS::PathCombine(m_dir.dirName(), targetFileName); if(!targetFile.rename(targetFileName)) @@ -309,6 +309,7 @@ void IconList::installIcon(const QString &file, QString &name) return; const QString sourceHash = getIconHash(sourceFile); + name = name.remove("_" + sourceHash).remove(sourceHash); name = QString("%1_%2.%3").arg(name, sourceHash, suffix); QString target = FS::PathCombine(m_dir.dirName(), name); @@ -323,7 +324,7 @@ void IconList::installIcon(const QString &file, QString &name) if(sourceHash == targetHash) return; - QString targetFileName = QString(name); + QString targetFileName = QString(name).remove("_" + targetHash).remove(targetHash); targetFileName = QString("%1_%2.%3").arg(targetFileName, targetHash, suffix); targetFileName = FS::PathCombine(m_dir.dirName(), targetFileName); if(!targetFile.rename(targetFileName))