From ddfb449b28fb24f1c3e4ed3802ee4415206f96f1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 22 Oct 2022 20:01:39 +0200 Subject: [PATCH 1/9] fix: remove PolyMC data paths Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 45cd94227..e2fdcd631 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -301,22 +301,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) dataPath = foo.absolutePath(); adjustedBy = "Persistent data path"; - QDir polymcData(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "PolyMC")); - if (polymcData.exists()) { - dataPath = polymcData.absolutePath(); - adjustedBy = "PolyMC data path"; - } - -#ifdef Q_OS_LINUX - // TODO: this should be removed in a future version - // TODO: provide a migration path similar to macOS migration - QDir bar(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "polymc")); - if (bar.exists()) { - dataPath = bar.absolutePath(); - adjustedBy = "Legacy data path"; - } -#endif - #ifndef Q_OS_MACOS if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) { dataPath = m_rootPath; From e048bce13ea4bd56ef96ba7a1a4699142d09600a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 22 Oct 2022 23:25:14 +0200 Subject: [PATCH 2/9] refactor: allow copy operation with whitelist Signed-off-by: Sefa Eyeoglu --- launcher/FileSystem.cpp | 2 +- launcher/FileSystem.h | 12 +++++++++--- launcher/InstanceCopyTask.cpp | 2 +- tests/FileSystem_test.cpp | 37 ++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 4a8f4bd3d..a3b9fe1f9 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -174,7 +174,7 @@ bool copy::operator()(const QString& offset) // Function that'll do the actual copying auto copy_file = [&](QString src_path, QString relative_dst_path) { - if (m_blacklist && m_blacklist->matches(relative_dst_path)) + if (m_matcher && (m_matcher->matches(relative_dst_path) == !m_whitelist)) return; auto dst_path = PathCombine(dst, relative_dst_path); diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index b7e175fdf..e239984ea 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -88,9 +88,14 @@ class copy { m_followSymlinks = follow; return *this; } - copy& blacklist(const IPathMatcher* filter) + copy& matcher(const IPathMatcher* filter) { - m_blacklist = filter; + m_matcher = filter; + return *this; + } + copy& whitelist(bool whitelist) + { + m_whitelist = whitelist; return *this; } bool operator()() { return operator()(QString()); } @@ -100,7 +105,8 @@ class copy { private: bool m_followSymlinks = true; - const IPathMatcher* m_blacklist = nullptr; + const IPathMatcher* m_matcher = nullptr; + bool m_whitelist = false; QDir m_src; QDir m_dst; }; diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index a4ea947d2..fb1183533 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -26,7 +26,7 @@ void InstanceCopyTask::executeTask() setStatus(tr("Copying instance %1").arg(m_origInstance->name())); FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath); - folderCopy.followSymlinks(false).blacklist(m_matcher.get()); + folderCopy.followSymlinks(false).matcher(m_matcher.get()); m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy); connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &InstanceCopyTask::copyFinished); diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp index 21270f6f6..3a5c38d04 100644 --- a/tests/FileSystem_test.cpp +++ b/tests/FileSystem_test.cpp @@ -126,7 +126,7 @@ slots: qDebug() << tempDir.path(); qDebug() << target_dir.path(); FS::copy c(folder, target_dir.path()); - c.blacklist(new RegexpMatcher("[.]?mcmeta")); + c.matcher(new RegexpMatcher("[.]?mcmeta")); c(); for(auto entry: target_dir.entryList()) @@ -147,6 +147,41 @@ slots: f(); } + void test_copy_with_whitelist() + { + QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); + auto f = [&folder]() + { + QTemporaryDir tempDir; + tempDir.setAutoRemove(true); + qDebug() << "From:" << folder << "To:" << tempDir.path(); + + QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder")); + qDebug() << tempDir.path(); + qDebug() << target_dir.path(); + FS::copy c(folder, target_dir.path()); + c.matcher(new RegexpMatcher("[.]?mcmeta")); + c.whitelist(true); + c(); + + for(auto entry: target_dir.entryList()) + { + qDebug() << entry; + } + QVERIFY(target_dir.entryList().contains("pack.mcmeta")); + QVERIFY(!target_dir.entryList().contains("assets")); + }; + + // first try variant without trailing / + QVERIFY(!folder.endsWith('/')); + f(); + + // then variant with trailing / + folder.append('/'); + QVERIFY(folder.endsWith('/')); + f(); + } + void test_copy_with_dot_hidden() { QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder"); From 15aaff7c1ce8d709c444d891bf640ee39494d10e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 22 Oct 2022 23:36:47 +0200 Subject: [PATCH 3/9] feat: add dryRun to copy operation Signed-off-by: Sefa Eyeoglu --- launcher/FileSystem.cpp | 10 ++++++---- launcher/FileSystem.h | 18 ++++++++++++++---- launcher/InstanceCopyTask.cpp | 4 +++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index a3b9fe1f9..06691fbf6 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -152,9 +152,10 @@ bool ensureFolderPathExists(QString foldernamepath) /// @brief Copies a directory and it's contents from src to dest /// @param offset subdirectory form src to copy to dest /// @return if there was an error during the filecopy -bool copy::operator()(const QString& offset) +bool copy::operator()(const QString& offset, bool dryRun) { using copy_opts = fs::copy_options; + m_copied = 0; // reset counter // NOTE always deep copy on windows. the alternatives are too messy. #if defined Q_OS_WIN32 @@ -178,9 +179,10 @@ bool copy::operator()(const QString& offset) return; auto dst_path = PathCombine(dst, relative_dst_path); - ensureFilePathExists(dst_path); - - fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err); + if (!dryRun) { + ensureFilePathExists(dst_path); + fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err); + } if (err) { qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); qDebug() << "Source file:" << src_path; diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index e239984ea..a9a81123a 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -40,6 +40,7 @@ #include #include +#include namespace FS { @@ -76,9 +77,10 @@ bool ensureFilePathExists(QString filenamepath); bool ensureFolderPathExists(QString filenamepath); /// @brief Copies a directory and it's contents from src to dest -class copy { +class copy : public QObject { + Q_OBJECT public: - copy(const QString& src, const QString& dst) + copy(const QString& src, const QString& dst, QObject* parent = nullptr) : QObject(parent) { m_src.setPath(src); m_dst.setPath(dst); @@ -98,10 +100,17 @@ class copy { m_whitelist = whitelist; return *this; } - bool operator()() { return operator()(QString()); } + + bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); } + + int totalCopied() { return m_copied; } + + signals: + void fileCopied(const QString& relativeName); + // TODO: maybe add a "shouldCopy" signal in the future? private: - bool operator()(const QString& offset); + bool operator()(const QString& offset, bool dryRun = false); private: bool m_followSymlinks = true; @@ -109,6 +118,7 @@ class copy { bool m_whitelist = false; QDir m_src; QDir m_dst; + int m_copied; }; /** diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index fb1183533..0a83ed9ce 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -28,7 +28,9 @@ void InstanceCopyTask::executeTask() FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath); folderCopy.followSymlinks(false).matcher(m_matcher.get()); - m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy); + m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&folderCopy]{ + return folderCopy(); + }); connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &InstanceCopyTask::copyFinished); connect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &InstanceCopyTask::copyAborted); m_copyFutureWatcher.setFuture(m_copyFuture); From bd7065eece443de59adbe47dd7d9bd16e1d35ff5 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 23 Oct 2022 00:44:57 +0200 Subject: [PATCH 4/9] feat: add SimplePrefixMatcher Signed-off-by: Sefa Eyeoglu --- launcher/CMakeLists.txt | 1 + launcher/pathmatcher/SimplePrefixMatcher.h | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 launcher/pathmatcher/SimplePrefixMatcher.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 8db934298..45d197efe 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -97,6 +97,7 @@ set(PATHMATCHER_SOURCES pathmatcher/IPathMatcher.h pathmatcher/MultiMatcher.h pathmatcher/RegexpMatcher.h + pathmatcher/SimplePrefixMatcher.h ) set(NET_SOURCES diff --git a/launcher/pathmatcher/SimplePrefixMatcher.h b/launcher/pathmatcher/SimplePrefixMatcher.h new file mode 100644 index 000000000..191d010cb --- /dev/null +++ b/launcher/pathmatcher/SimplePrefixMatcher.h @@ -0,0 +1,21 @@ +#include +#include "IPathMatcher.h" + +class SimplePrefixMatcher : public IPathMatcher { + public: + virtual ~SimplePrefixMatcher(){}; + SimplePrefixMatcher(const QString& prefix) + { + m_prefix = prefix; + m_isPrefix = prefix.endsWith('/'); + } + + virtual bool matches(const QString& string) const override + { + if (m_isPrefix) + return string.startsWith(m_prefix); + return string == m_prefix; + } + QString m_prefix; + bool m_isPrefix = false; +}; From 086304f7f24e70bfa35b26a7406930b0840f699b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 23 Oct 2022 01:45:32 +0200 Subject: [PATCH 5/9] feat: add initial Migration dialog Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 99 ++++++++++++++++++++++++++++++++++ launcher/Application.h | 1 + launcher/CMakeLists.txt | 2 + launcher/DataMigrationTask.cpp | 79 +++++++++++++++++++++++++++ launcher/DataMigrationTask.h | 38 +++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 launcher/DataMigrationTask.cpp create mode 100644 launcher/DataMigrationTask.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index e2fdcd631..2a7d6f220 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -38,10 +38,14 @@ #include "Application.h" #include "BuildConfig.h" +#include "DataMigrationTask.h" #include "net/PasteUpload.h" +#include "pathmatcher/MultiMatcher.h" +#include "pathmatcher/SimplePrefixMatcher.h" #include "ui/MainWindow.h" #include "ui/InstanceWindow.h" +#include "ui/dialogs/ProgressDialog.h" #include "ui/instanceview/AccessibleInstanceView.h" #include "ui/pages/BasePageProvider.h" @@ -423,6 +427,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) qDebug() << "<> Log initialized."; } + { + bool migrated = false; + + if (!migrated) + migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../PolyMC"), "PolyMC", "polymc.cfg"); + if (!migrated) + migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../multimc"), "MultiMC", "multimc.cfg"); + } + { qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; @@ -1589,3 +1602,89 @@ int Application::suitableMaxMem() return maxMemoryAlloc; } + +bool Application::handleDataMigration(const QString& currentData, + const QString& oldData, + const QString& name, + const QString& configFile) const +{ + QString nomigratePath = FS::PathCombine(oldData, BuildConfig.LAUNCHER_NAME + "_nomigrate.txt"); + QStringList configPaths = { FS::PathCombine(oldData, configFile), FS::PathCombine(oldData, BuildConfig.LAUNCHER_CONFIGFILE) }; + + QDir dir; // helper for QDir::exists + QLocale locale; + + // Is there a valid config at the old location? + bool configExists = false; + for (QString configPath : configPaths) { + configExists |= QFileInfo::exists(configPath); + } + + if (!configExists || QFileInfo::exists(nomigratePath)) { + qDebug() << "<> No migration needed from" << name; + return false; + } + + QString message; + bool currentExists = QFileInfo::exists(FS::PathCombine(currentData, BuildConfig.LAUNCHER_CONFIGFILE)); + + if (currentExists) { + message = tr("Old data from %1 was found, but you already have existing data for %2. Sadly you will need to migrate yourself. Do " + "you want to be reminded of the pending data migration next time you start %2?") + .arg(name, BuildConfig.LAUNCHER_DISPLAYNAME); + } else { + message = tr("It looks like you used %1 before. Do you want to migrate your data to the new location of %2?") + .arg(name, BuildConfig.LAUNCHER_DISPLAYNAME); + + QFileInfo logInfo(FS::PathCombine(oldData, name + "-0.log")); + if (logInfo.exists()) { + QString lastModified = logInfo.lastModified().toString(locale.dateFormat()); + message = tr("It looks like you used %1 on %2 before. Do you want to migrate your data to the new location of %3?") + .arg(name, lastModified, BuildConfig.LAUNCHER_DISPLAYNAME); + } + } + + QMessageBox::StandardButton askMoveDialogue = + QMessageBox::question(nullptr, BuildConfig.LAUNCHER_DISPLAYNAME, message, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + + auto setDoNotMigrate = [&nomigratePath] { + QFile file(nomigratePath); + file.open(QIODevice::WriteOnly); + }; + + // create no-migrate file if user doesn't want to migrate + if (askMoveDialogue != QMessageBox::Yes) { + qDebug() << "<> Migration declined for" << name; + setDoNotMigrate(); + return currentExists; // cancel further migrations, if we already have a data directory + } + + if (!currentExists) { + // Migrate! + auto matcher = std::make_shared(); + matcher->add(std::make_shared(configFile)); + matcher->add(std::make_shared( + BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before + matcher->add(std::make_shared("accounts.json")); + matcher->add(std::make_shared("accounts/")); + matcher->add(std::make_shared("assets/")); + matcher->add(std::make_shared("icons/")); + matcher->add(std::make_shared("instances/")); + matcher->add(std::make_shared("libraries/")); + matcher->add(std::make_shared("mods/")); + matcher->add(std::make_shared("themes/")); + + ProgressDialog diag = ProgressDialog(); + DataMigrationTask task(nullptr, oldData, currentData, matcher); + if (diag.execWithTask(&task)) { + qDebug() << "<> Migration succeeded"; + setDoNotMigrate(); + } else { + QString reason = task.failReason(); + QMessageBox::critical(nullptr, BuildConfig.LAUNCHER_DISPLAYNAME, tr("Migration failed! Reason: %1").arg(reason)); + } + } else { + qWarning() << "<> Migration was skipped, due to existing data"; + } + return true; +} diff --git a/launcher/Application.h b/launcher/Application.h index 4c2f62d4c..7884227a1 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -231,6 +231,7 @@ private slots: void setupWizardFinished(int status); private: + bool handleDataMigration(const QString & currentData, const QString & oldData, const QString & name, const QString & configFile) const; bool createSetupWizard(); void performMainStartupAction(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 45d197efe..7a5779355 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -576,6 +576,8 @@ SET(LAUNCHER_SOURCES # Application base Application.h Application.cpp + DataMigrationTask.h + DataMigrationTask.cpp UpdateController.cpp UpdateController.h ApplicationMessage.h diff --git a/launcher/DataMigrationTask.cpp b/launcher/DataMigrationTask.cpp new file mode 100644 index 000000000..8e7f45795 --- /dev/null +++ b/launcher/DataMigrationTask.cpp @@ -0,0 +1,79 @@ +#include "DataMigrationTask.h" + +#include "FileSystem.h" + +#include +#include +#include + +#include + +DataMigrationTask::DataMigrationTask(QObject* parent, + const QString& sourcePath, + const QString& targetPath, + const IPathMatcher::Ptr pathMatcher) + : Task(parent), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath) +{ + m_copy.matcher(m_pathMatcher.get()).whitelist(true); +} + +void DataMigrationTask::executeTask() +{ + setStatus(tr("Scanning files...")); + + // 1. Scan + // Check how many files we gotta copy + m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&] { + return m_copy(true); // dry run to collect amount of files + }); + connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &DataMigrationTask::dryRunFinished); + connect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &DataMigrationTask::dryRunAborted); + m_copyFutureWatcher.setFuture(m_copyFuture); +} + +void DataMigrationTask::dryRunFinished() +{ + disconnect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &DataMigrationTask::dryRunFinished); + disconnect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &DataMigrationTask::dryRunAborted); + + if (!m_copyFuture.result()) { + emitFailed("Some error"); // FIXME + return; + } + + setStatus(tr("Migrating...")); + + // 2. Copy + // Actually copy all files now. + m_toCopy = m_copy.totalCopied(); + connect(&m_copy, &FS::copy::fileCopied, [&, this] { setProgress(m_copy.totalCopied(), m_toCopy); }); + m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&] { + return m_copy(false); // actually copy now + }); + connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &DataMigrationTask::copyFinished); + connect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &DataMigrationTask::copyAborted); + m_copyFutureWatcher.setFuture(m_copyFuture); +} + +void DataMigrationTask::dryRunAborted() +{ + emitFailed(tr("Aborted")); +} + +void DataMigrationTask::copyFinished() +{ + disconnect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &DataMigrationTask::copyFinished); + disconnect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &DataMigrationTask::copyAborted); + + if (!m_copyFuture.result()) { + emitFailed("Some paths could not be copied!"); + return; + } + + emitSucceeded(); +} + +void DataMigrationTask::copyAborted() +{ + emitFailed(tr("Aborted")); +} diff --git a/launcher/DataMigrationTask.h b/launcher/DataMigrationTask.h new file mode 100644 index 000000000..105a94939 --- /dev/null +++ b/launcher/DataMigrationTask.h @@ -0,0 +1,38 @@ +#pragma once + +#include "FileSystem.h" +#include "pathmatcher/IPathMatcher.h" +#include "tasks/Task.h" + +#include +#include + +/* + * Migrate existing data from other MMC-like launchers. + */ + +class DataMigrationTask : public Task { + Q_OBJECT + public: + explicit DataMigrationTask(QObject* parent, const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathmatcher); + ~DataMigrationTask() override = default; + + protected: + virtual void executeTask() override; + + protected slots: + void dryRunFinished(); + void dryRunAborted(); + void copyFinished(); + void copyAborted(); + + private: + const QString& m_sourcePath; + const QString& m_targetPath; + const IPathMatcher::Ptr m_pathMatcher; + + FS::copy m_copy; + int m_toCopy = 0; + QFuture m_copyFuture; + QFutureWatcher m_copyFutureWatcher; +}; From bbb7e9f5c722039ba8b4fbd00fba78f65613b0a9 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 23 Oct 2022 14:24:11 +0200 Subject: [PATCH 6/9] feat: show current copy operation in migration dialog Signed-off-by: Sefa Eyeoglu --- launcher/DataMigrationTask.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/launcher/DataMigrationTask.cpp b/launcher/DataMigrationTask.cpp index 8e7f45795..fb2907fb6 100644 --- a/launcher/DataMigrationTask.cpp +++ b/launcher/DataMigrationTask.cpp @@ -41,12 +41,17 @@ void DataMigrationTask::dryRunFinished() return; } - setStatus(tr("Migrating...")); - // 2. Copy // Actually copy all files now. m_toCopy = m_copy.totalCopied(); - connect(&m_copy, &FS::copy::fileCopied, [&, this] { setProgress(m_copy.totalCopied(), m_toCopy); }); + connect(&m_copy, &FS::copy::fileCopied, [&, this](const QString& relativeName) { + QString shortenedName = relativeName; + // shorten the filename to hopefully fit into one line + if (shortenedName.length() > 50) + shortenedName = relativeName.left(20) + "…" + relativeName.right(29); + setProgress(m_copy.totalCopied(), m_toCopy); + setStatus(tr("Copying %1…").arg(shortenedName)); + }); m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&] { return m_copy(false); // actually copy now }); From 335bec68fb803f0a06400585b1dc4c2341951c7c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 23 Oct 2022 14:27:46 +0200 Subject: [PATCH 7/9] fix: prevent abort for un-abortable tasks Signed-off-by: Sefa Eyeoglu --- launcher/ui/dialogs/ProgressDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 05269f623..da73a4492 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -44,7 +44,8 @@ void ProgressDialog::setSkipButton(bool present, QString label) void ProgressDialog::on_skipButton_clicked(bool checked) { Q_UNUSED(checked); - task->abort(); + if (ui->skipButton->isEnabled()) // prevent other triggers from aborting + task->abort(); } ProgressDialog::~ProgressDialog() From 173aed7fd8e73b9e6a6055981ce284ea9cf5d33a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 24 Oct 2022 21:50:35 +0200 Subject: [PATCH 8/9] chore: add REUSE headers Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 5 ++++- launcher/DataMigrationTask.cpp | 4 ++++ launcher/DataMigrationTask.h | 4 ++++ launcher/pathmatcher/SimplePrefixMatcher.h | 4 ++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 2a7d6f220..8955e2970 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1,4 +1,7 @@ -// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu +// +// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0 + /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu diff --git a/launcher/DataMigrationTask.cpp b/launcher/DataMigrationTask.cpp index fb2907fb6..8de3158e6 100644 --- a/launcher/DataMigrationTask.cpp +++ b/launcher/DataMigrationTask.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu +// +// SPDX-License-Identifier: GPL-3.0-only + #include "DataMigrationTask.h" #include "FileSystem.h" diff --git a/launcher/DataMigrationTask.h b/launcher/DataMigrationTask.h index 105a94939..6cc23b1a8 100644 --- a/launcher/DataMigrationTask.h +++ b/launcher/DataMigrationTask.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu +// +// SPDX-License-Identifier: GPL-3.0-only + #pragma once #include "FileSystem.h" diff --git a/launcher/pathmatcher/SimplePrefixMatcher.h b/launcher/pathmatcher/SimplePrefixMatcher.h index 191d010cb..fc1f5cede 100644 --- a/launcher/pathmatcher/SimplePrefixMatcher.h +++ b/launcher/pathmatcher/SimplePrefixMatcher.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu +// +// SPDX-License-Identifier: GPL-3.0-only + #include #include "IPathMatcher.h" From fe94c3609ef875166b71b9f6c540c45eff97a5ab Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 10 Nov 2022 19:04:42 +0100 Subject: [PATCH 9/9] fix: implement code review suggestions Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 5 ++--- launcher/DataMigrationTask.cpp | 12 ++++++++++-- launcher/FileSystem.cpp | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 8955e2970..537e39038 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1611,10 +1611,9 @@ bool Application::handleDataMigration(const QString& currentData, const QString& name, const QString& configFile) const { - QString nomigratePath = FS::PathCombine(oldData, BuildConfig.LAUNCHER_NAME + "_nomigrate.txt"); + QString nomigratePath = FS::PathCombine(currentData, name + "_nomigrate.txt"); QStringList configPaths = { FS::PathCombine(oldData, configFile), FS::PathCombine(oldData, BuildConfig.LAUNCHER_CONFIGFILE) }; - QDir dir; // helper for QDir::exists QLocale locale; // Is there a valid config at the old location? @@ -1677,7 +1676,7 @@ bool Application::handleDataMigration(const QString& currentData, matcher->add(std::make_shared("mods/")); matcher->add(std::make_shared("themes/")); - ProgressDialog diag = ProgressDialog(); + ProgressDialog diag; DataMigrationTask task(nullptr, oldData, currentData, matcher); if (diag.execWithTask(&task)) { qDebug() << "<> Migration succeeded"; diff --git a/launcher/DataMigrationTask.cpp b/launcher/DataMigrationTask.cpp index 8de3158e6..27ce5f01b 100644 --- a/launcher/DataMigrationTask.cpp +++ b/launcher/DataMigrationTask.cpp @@ -40,8 +40,12 @@ void DataMigrationTask::dryRunFinished() disconnect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &DataMigrationTask::dryRunFinished); disconnect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &DataMigrationTask::dryRunAborted); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + if (!m_copyFuture.isValid() || !m_copyFuture.result()) { +#else if (!m_copyFuture.result()) { - emitFailed("Some error"); // FIXME +#endif + emitFailed(tr("Failed to scan source path.")); return; } @@ -74,8 +78,12 @@ void DataMigrationTask::copyFinished() disconnect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &DataMigrationTask::copyFinished); disconnect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &DataMigrationTask::copyAborted); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + if (!m_copyFuture.isValid() || !m_copyFuture.result()) { +#else if (!m_copyFuture.result()) { - emitFailed("Some paths could not be copied!"); +#endif + emitFailed(tr("Some paths could not be copied!")); return; } diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 06691fbf6..0c6527b1d 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -175,7 +175,7 @@ bool copy::operator()(const QString& offset, bool dryRun) // Function that'll do the actual copying auto copy_file = [&](QString src_path, QString relative_dst_path) { - if (m_matcher && (m_matcher->matches(relative_dst_path) == !m_whitelist)) + if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) return; auto dst_path = PathCombine(dst, relative_dst_path);