Merge pull request #557 from Scrumplex/fix-fswatcher-segfault

Closes https://github.com/PrismLauncher/PrismLauncher/issues/555
This commit is contained in:
flow 2022-12-06 11:50:03 -08:00 committed by GitHub
commit c6e4fdac7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 36 deletions

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "FlameInstanceCreationTask.h" #include "FlameInstanceCreationTask.h"
#include "modplatform/flame/FlameAPI.h" #include "modplatform/flame/FlameAPI.h"
@ -72,7 +107,8 @@ bool FlameCreationTask::updateInstance()
tr("One or more of your instances are from this same modpack%1. Do you want to create a " tr("One or more of your instances are from this same modpack%1. Do you want to create a "
"separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before "
"updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).")
.arg(version_str), QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort); .arg(version_str),
QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort);
info->setButtonText(QMessageBox::Ok, tr("Update existing instance")); info->setButtonText(QMessageBox::Ok, tr("Update existing instance"));
info->setButtonText(QMessageBox::Abort, tr("Create new instance")); info->setButtonText(QMessageBox::Abort, tr("Create new instance"));
info->setButtonText(QMessageBox::Reset, tr("Cancel")); info->setButtonText(QMessageBox::Reset, tr("Cancel"));
@ -197,10 +233,10 @@ bool FlameCreationTask::updateInstance()
m_process_update_file_info_job = nullptr; m_process_update_file_info_job = nullptr;
} else { } else {
// We don't have an old index file, so we may duplicate stuff! // We don't have an old index file, so we may duplicate stuff!
auto dialog = CustomMessageBox::selectable(m_parent, auto dialog = CustomMessageBox::selectable(m_parent, tr("No index file."),
tr("No index file."), tr("We couldn't find a suitable index file for the older version. This may cause some "
tr("We couldn't find a suitable index file for the older version. This may cause some of the files to be duplicated. Do you want to continue?"), "of the files to be duplicated. Do you want to continue?"),
QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel);
if (dialog->exec() == QDialog::DialogCode::Rejected) { if (dialog->exec() == QDialog::DialogCode::Rejected) {
m_abort = true; m_abort = true;
@ -377,7 +413,6 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
auto anyBlocked = false; auto anyBlocked = false;
for (const auto& result : results.files.values()) { for (const auto& result : results.files.values()) {
if (!result.resolved || result.url.isEmpty()) { if (!result.resolved || result.url.isEmpty()) {
BlockedMod blocked_mod; BlockedMod blocked_mod;
blocked_mod.name = result.fileName; blocked_mod.name = result.fileName;
blocked_mod.websiteUrl = result.websiteUrl; blocked_mod.websiteUrl = result.websiteUrl;
@ -393,14 +428,14 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
if (anyBlocked) { if (anyBlocked) {
qWarning() << "Blocked mods found, displaying mod list"; qWarning() << "Blocked mods found, displaying mod list";
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked mods found"), BlockedModsDialog message_dialog(m_parent, tr("Blocked mods found"),
tr("The following files are not available for download in third party launchers.<br/>" tr("The following files are not available for download in third party launchers.<br/>"
"You will need to manually download them and add them to the instance."), "You will need to manually download them and add them to the instance."),
blocked_mods); blocked_mods);
message_dialog->setModal(true); message_dialog.setModal(true);
if (message_dialog->exec()) { if (message_dialog.exec()) {
qDebug() << "Post dialog blocked mods list: " << blocked_mods; qDebug() << "Post dialog blocked mods list: " << blocked_mods;
copyBlockedMods(blocked_mods); copyBlockedMods(blocked_mods);
setupDownloadJob(loop); setupDownloadJob(loop);
@ -484,9 +519,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
} }
m_mod_id_resolver.reset(); m_mod_id_resolver.reset();
connect(m_files_job.get(), &NetJob::succeeded, this, [&]() { connect(m_files_job.get(), &NetJob::succeeded, this, [&]() { m_files_job.reset(); });
m_files_job.reset();
});
connect(m_files_job.get(), &NetJob::failed, [&](QString reason) { connect(m_files_job.get(), &NetJob::failed, [&](QString reason) {
m_files_job.reset(); m_files_job.reset();
setError(reason); setError(reason);

View File

@ -1,3 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
#include "InstanceCreationTask.h" #include "InstanceCreationTask.h"

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 flowln <flowlnlnln@gmail.com> * Copyright (C) 2022 flowln <flowlnlnln@gmail.com>
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
@ -189,7 +189,6 @@ void PackInstallTask::onResolveModsSucceeded()
// First check for blocked mods // First check for blocked mods
if (!results_file.resolved || results_file.url.isEmpty()) { if (!results_file.resolved || results_file.url.isEmpty()) {
BlockedMod blocked_mod; BlockedMod blocked_mod;
blocked_mod.name = local_file.name; blocked_mod.name = local_file.name;
blocked_mod.websiteUrl = results_file.websiteUrl; blocked_mod.websiteUrl = results_file.websiteUrl;
@ -210,12 +209,14 @@ void PackInstallTask::onResolveModsSucceeded()
if (anyBlocked) { if (anyBlocked) {
qDebug() << "Blocked files found, displaying file list"; qDebug() << "Blocked files found, displaying file list";
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"), BlockedModsDialog message_dialog(m_parent, tr("Blocked files found"),
tr("The following files are not available for download in third party launchers.<br/>" tr("The following files are not available for download in third party launchers.<br/>"
"You will need to manually download them and add them to the instance."), "You will need to manually download them and add them to the instance."),
m_blocked_mods); m_blocked_mods);
if (message_dialog->exec() == QDialog::Accepted) { message_dialog.setModal(true);
if (message_dialog.exec() == QDialog::Accepted) {
qDebug() << "Post dialog blocked mods list: " << m_blocked_mods; qDebug() << "Post dialog blocked mods list: " << m_blocked_mods;
createInstance(); createInstance();
} else { } else {

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
/* /*
* PolyMC - Minecraft Launcher * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 flowln <flowlnlnln@gmail.com> * Copyright (C) 2022 flowln <flowlnlnln@gmail.com>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *

View File

@ -79,6 +79,12 @@ void BlockedModsDialog::dropEvent(QDropEvent* e)
update(); update();
} }
void BlockedModsDialog::done(int r)
{
QDialog::done(r);
disconnect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
}
void BlockedModsDialog::openAll() void BlockedModsDialog::openAll()
{ {
for (auto& mod : m_mods) { for (auto& mod : m_mods) {

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <QDialog> #include <QDialog>
#include <QString>
#include <QList> #include <QList>
#include <QString>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
@ -16,28 +16,32 @@ struct BlockedMod {
QString hash; QString hash;
bool matched; bool matched;
QString localPath; QString localPath;
}; };
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class BlockedModsDialog; } namespace Ui {
class BlockedModsDialog;
}
QT_END_NAMESPACE QT_END_NAMESPACE
class BlockedModsDialog : public QDialog { class BlockedModsDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList<BlockedMod> &mods); BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods);
~BlockedModsDialog() override; ~BlockedModsDialog() override;
protected: protected:
void dragEnterEvent(QDragEnterEvent *event) override; void dragEnterEvent(QDragEnterEvent* event) override;
void dropEvent(QDropEvent *event) override; void dropEvent(QDropEvent* event) override;
private: protected slots:
Ui::BlockedModsDialog *ui; void done(int r) override;
QList<BlockedMod> &m_mods;
private:
Ui::BlockedModsDialog* ui;
QList<BlockedMod>& m_mods;
QFileSystemWatcher m_watcher; QFileSystemWatcher m_watcher;
shared_qobject_ptr<ConcurrentTask> m_hashing_task; shared_qobject_ptr<ConcurrentTask> m_hashing_task;
QSet<QString> m_pending_hash_paths; QSet<QString> m_pending_hash_paths;
@ -61,4 +65,4 @@ private:
bool allModsMatched(); bool allModsMatched();
}; };
QDebug operator<<(QDebug debug, const BlockedMod &m); QDebug operator<<(QDebug debug, const BlockedMod& m);