From 4f0ec908ecc0c14c1ffe8e9631d031c754e3540a Mon Sep 17 00:00:00 2001 From: leo78913 Date: Tue, 9 May 2023 23:29:16 -0300 Subject: feat: add a close button to the main toolbar when running on gamescope Signed-off-by: leo78913 --- launcher/ui/MainWindow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 72b7db64..9b8db1ae 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -219,6 +219,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // disabled until we have an instance selected ui->instanceToolBar->setEnabled(false); setInstanceActionsEnabled(false); + + // add a close button at the end of the main toolbar when running on gamescope / steam deck + if (qgetenv("XDG_CURRENT_DESKTOP") == "gamescope") { + ui->mainToolBar->addAction(ui->actionCloseWindow); + } + } // add the toolbar toggles to the view menu -- cgit From 529e2054eadf4c97231a51d7bd2d25cb75bd74c9 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 22:54:05 +0100 Subject: A few tweaks, with inspiration from Zeke :3 Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 6 +- launcher/ui/dialogs/NewInstanceDialog.cpp | 4 +- launcher/ui/pages/instance/VersionPage.cpp | 1 - launcher/ui/pages/instance/VersionPage.ui | 10 - launcher/ui/pages/modplatform/CustomPage.cpp | 241 +++++++++++++++++++++ launcher/ui/pages/modplatform/CustomPage.h | 104 +++++++++ launcher/ui/pages/modplatform/CustomPage.ui | 290 ++++++++++++++++++++++++++ launcher/ui/pages/modplatform/VanillaPage.cpp | 241 --------------------- launcher/ui/pages/modplatform/VanillaPage.h | 104 --------- launcher/ui/pages/modplatform/VanillaPage.ui | 290 -------------------------- 10 files changed, 640 insertions(+), 651 deletions(-) create mode 100644 launcher/ui/pages/modplatform/CustomPage.cpp create mode 100644 launcher/ui/pages/modplatform/CustomPage.h create mode 100644 launcher/ui/pages/modplatform/CustomPage.ui delete mode 100644 launcher/ui/pages/modplatform/VanillaPage.cpp delete mode 100644 launcher/ui/pages/modplatform/VanillaPage.h delete mode 100644 launcher/ui/pages/modplatform/VanillaPage.ui diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 9bad2a67..c10064c0 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -827,8 +827,8 @@ SET(LAUNCHER_SOURCES ui/pages/global/APIPage.h # GUI - platform pages - ui/pages/modplatform/VanillaPage.cpp - ui/pages/modplatform/VanillaPage.h + ui/pages/modplatform/CustomPage.cpp + ui/pages/modplatform/CustomPage.h ui/pages/modplatform/ResourcePage.cpp ui/pages/modplatform/ResourcePage.h @@ -1034,7 +1034,7 @@ qt_wrap_ui(LAUNCHER_UI ui/pages/instance/ScreenshotsPage.ui ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui ui/pages/modplatform/atlauncher/AtlPage.ui - ui/pages/modplatform/VanillaPage.ui + ui/pages/modplatform/CustomPage.ui ui/pages/modplatform/ResourcePage.ui ui/pages/modplatform/flame/FlamePage.ui ui/pages/modplatform/legacy_ftb/Page.ui diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index aafaf220..7b9bb944 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -54,7 +54,7 @@ #include #include "ui/widgets/PageContainer.h" -#include "ui/pages/modplatform/VanillaPage.h" +#include "ui/pages/modplatform/CustomPage.h" #include "ui/pages/modplatform/atlauncher/AtlPage.h" #include "ui/pages/modplatform/legacy_ftb/Page.h" #include "ui/pages/modplatform/flame/FlamePage.h" @@ -162,7 +162,7 @@ QList NewInstanceDialog::getPages() importPage = new ImportPage(this); - pages.append(new VanillaPage(this)); + pages.append(new CustomPage(this)); pages.append(importPage); pages.append(new AtlPage(this)); if (APPLICATION->capabilities() & Application::SupportsFlame) diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 74b7ec7c..59107c53 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -287,7 +287,6 @@ void VersionPage::updateButtons(int row) ui->actionAdd_Empty->setEnabled(controlsEnabled); ui->actionImport_Components->setEnabled(controlsEnabled); ui->actionReload->setEnabled(controlsEnabled); - ui->actionInstall_mods->setEnabled(controlsEnabled); ui->actionReplace_Minecraft_jar->setEnabled(controlsEnabled); ui->actionAdd_to_Minecraft_jar->setEnabled(controlsEnabled); ui->actionAdd_Agents->setEnabled(controlsEnabled); diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index 4777eafe..a73c42d6 100644 --- a/launcher/ui/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -102,7 +102,6 @@ - @@ -112,7 +111,6 @@ - @@ -204,14 +202,6 @@ Install the LiteLoader package. - - - Install mods - - - Install normal mods. - - Add to Minecraft.jar diff --git a/launcher/ui/pages/modplatform/CustomPage.cpp b/launcher/ui/pages/modplatform/CustomPage.cpp new file mode 100644 index 00000000..e164171a --- /dev/null +++ b/launcher/ui/pages/modplatform/CustomPage.cpp @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield + * + * 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 . + * + * 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 "CustomPage.h" +#include "ui_CustomPage.h" + +#include + +#include "Application.h" +#include "Filter.h" +#include "Version.h" +#include "meta/Index.h" +#include "meta/VersionList.h" +#include "minecraft/VanillaInstanceCreationTask.h" +#include "ui/dialogs/NewInstanceDialog.h" + +CustomPage::CustomPage(NewInstanceDialog *dialog, QWidget *parent) + : QWidget(parent), dialog(dialog), ui(new Ui::CustomPage) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &CustomPage::setSelectedVersion); + filterChanged(); + connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->betaFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->refreshBtn, &QPushButton::clicked, this, &CustomPage::refresh); + + connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &CustomPage::setSelectedLoaderVersion); + connect(ui->noneFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->forgeFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->fabricFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->quiltFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &CustomPage::loaderRefresh); + +} + +void CustomPage::openedImpl() +{ + if(!initialized) + { + auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); + ui->versionList->initialize(vlist.get()); + initialized = true; + } + else + { + suggestCurrent(); + } +} + +void CustomPage::refresh() +{ + ui->versionList->loadList(); +} + +void CustomPage::loaderRefresh() +{ + if(ui->noneFilter->isChecked()) + return; + ui->loaderVersionList->loadList(); +} + +void CustomPage::filterChanged() +{ + QStringList out; + if(ui->alphaFilter->isChecked()) + out << "(old_alpha)"; + if(ui->betaFilter->isChecked()) + out << "(old_beta)"; + if(ui->snapshotFilter->isChecked()) + out << "(snapshot)"; + if(ui->oldSnapshotFilter->isChecked()) + out << "(old_snapshot)"; + if(ui->releaseFilter->isChecked()) + out << "(release)"; + if(ui->experimentsFilter->isChecked()) + out << "(experiment)"; + auto regexp = out.join('|'); + ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); +} + +void CustomPage::loaderFilterChanged() +{ + QString minecraftVersion; + if (m_selectedVersion) + { + minecraftVersion = m_selectedVersion->descriptor(); + } + else + { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list + ui->loaderVersionList->setEmptyString(tr("No Minecraft version is selected.")); + ui->loaderVersionList->setEmptyMode(VersionListView::String); + return; + } + if(ui->noneFilter->isChecked()) + { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list + ui->loaderVersionList->setEmptyString(tr("No mod loader is selected.")); + ui->loaderVersionList->setEmptyMode(VersionListView::String); + return; + } + else if(ui->forgeFilter->isChecked()) + { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); + m_selectedLoader = "net.minecraftforge"; + } + else if(ui->fabricFilter->isChecked()) + { + // FIXME: dirty hack because the launcher is unaware of Fabric's dependencies + if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, ""); + else // Fabric/Quilt unsupported + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list + m_selectedLoader = "net.fabricmc.fabric-loader"; + } + else if(ui->quiltFilter->isChecked()) + { + // FIXME: dirty hack because the launcher is unaware of Quilt's dependencies (same as Fabric) + if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, ""); + else // Fabric/Quilt unsupported + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list + m_selectedLoader = "org.quiltmc.quilt-loader"; + } + else if(ui->liteLoaderFilter->isChecked()) + { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); + m_selectedLoader = "com.mumfrey.liteloader"; + } + + auto vlist = APPLICATION->metadataIndex()->get(m_selectedLoader); + ui->loaderVersionList->initialize(vlist.get()); + ui->loaderVersionList->selectRecommended(); + ui->loaderVersionList->setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); +} + +CustomPage::~CustomPage() +{ + delete ui; +} + +bool CustomPage::shouldDisplay() const +{ + return true; +} + +void CustomPage::retranslate() +{ + ui->retranslateUi(this); +} + +BaseVersion::Ptr CustomPage::selectedVersion() const +{ + return m_selectedVersion; +} + +BaseVersion::Ptr CustomPage::selectedLoaderVersion() const +{ + return m_selectedLoaderVersion; +} + +QString CustomPage::selectedLoader() const +{ + return m_selectedLoader; +} + +void CustomPage::suggestCurrent() +{ + if (!isOpened) + { + return; + } + + if(!m_selectedVersion) + { + dialog->setSuggestedPack(); + return; + } + + // There isn't a selected version if the version list is empty + if(ui->loaderVersionList->selectedVersion() == nullptr) + dialog->setSuggestedPack(m_selectedVersion->descriptor(), new VanillaCreationTask(m_selectedVersion)); + else + { + dialog->setSuggestedPack(m_selectedVersion->descriptor(), + new VanillaCreationTask(m_selectedVersion, m_selectedLoader, + m_selectedLoaderVersion)); + } + dialog->setSuggestedIcon("default"); +} + +void CustomPage::setSelectedVersion(BaseVersion::Ptr version) +{ + m_selectedVersion = version; + suggestCurrent(); + loaderFilterChanged(); +} + +void CustomPage::setSelectedLoaderVersion(BaseVersion::Ptr version) +{ + m_selectedLoaderVersion = version; + suggestCurrent(); +} diff --git a/launcher/ui/pages/modplatform/CustomPage.h b/launcher/ui/pages/modplatform/CustomPage.h new file mode 100644 index 00000000..8b5a5011 --- /dev/null +++ b/launcher/ui/pages/modplatform/CustomPage.h @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield + * + * 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 . + * + * 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 + +#include + +#include "ui/pages/BasePage.h" +#include +#include "tasks/Task.h" + +namespace Ui +{ +class CustomPage; +} + +class NewInstanceDialog; + +class CustomPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit CustomPage(NewInstanceDialog *dialog, QWidget *parent = 0); + virtual ~CustomPage(); + virtual QString displayName() const override + { + return tr("Custom"); + } + virtual QIcon icon() const override + { + return APPLICATION->getThemedIcon("minecraft"); + } + virtual QString id() const override + { + return "vanilla"; + } + virtual QString helpPage() const override + { + return "Vanilla-platform"; + } + virtual bool shouldDisplay() const override; + void retranslate() override; + + void openedImpl() override; + + BaseVersion::Ptr selectedVersion() const; + BaseVersion::Ptr selectedLoaderVersion() const; + QString selectedLoader() const; + +public slots: + void setSelectedVersion(BaseVersion::Ptr version); + void setSelectedLoaderVersion(BaseVersion::Ptr version); + +private slots: + void filterChanged(); + void loaderFilterChanged(); + +private: + void refresh(); + void loaderRefresh(); + void suggestCurrent(); + +private: + bool initialized = false; + NewInstanceDialog *dialog = nullptr; + Ui::CustomPage *ui = nullptr; + bool m_versionSetByUser = false; + BaseVersion::Ptr m_selectedVersion; + BaseVersion::Ptr m_selectedLoaderVersion; + QString m_selectedLoader; +}; diff --git a/launcher/ui/pages/modplatform/CustomPage.ui b/launcher/ui/pages/modplatform/CustomPage.ui new file mode 100644 index 00000000..0d89b595 --- /dev/null +++ b/launcher/ui/pages/modplatform/CustomPage.ui @@ -0,0 +1,290 @@ + + + CustomPage + + + + 0 + 0 + 815 + 607 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + + + + + + + Filter + + + Qt::AlignCenter + + + + + + + Releases + + + true + + + true + + + + + + + Snapshots + + + true + + + + + + + Old Snapshots + + + true + + + + + + + Betas + + + true + + + + + + + Alphas + + + true + + + + + + + Experiments + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Refresh + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + Mod Loader + + + Qt::AlignCenter + + + + + + + None + + + true + + + loaderBtnGroup + + + + + + + Forge + + + loaderBtnGroup + + + + + + + Fabric + + + loaderBtnGroup + + + + + + + Quilt + + + loaderBtnGroup + + + + + + + LiteLoader + + + loaderBtnGroup + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Refresh + + + + + + + + + + + + + + + + VersionSelectWidget + QWidget +
ui/widgets/VersionSelectWidget.h
+ 1 +
+
+ + tabWidget + releaseFilter + snapshotFilter + oldSnapshotFilter + betaFilter + alphaFilter + experimentsFilter + refreshBtn + + + + + + +
diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp deleted file mode 100644 index 29fecb85..00000000 --- a/launcher/ui/pages/modplatform/VanillaPage.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 Jamie Mansfield - * - * 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 . - * - * 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 "VanillaPage.h" -#include "ui_VanillaPage.h" - -#include - -#include "Application.h" -#include "Filter.h" -#include "Version.h" -#include "meta/Index.h" -#include "meta/VersionList.h" -#include "minecraft/VanillaInstanceCreationTask.h" -#include "ui/dialogs/NewInstanceDialog.h" - -VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent) - : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage) -{ - ui->setupUi(this); - ui->tabWidget->tabBar()->hide(); - connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion); - filterChanged(); - connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->refreshBtn, &QPushButton::clicked, this, &VanillaPage::refresh); - - connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedLoaderVersion); - connect(ui->noneFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->forgeFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->fabricFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->quiltFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); - connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &VanillaPage::loaderRefresh); - -} - -void VanillaPage::openedImpl() -{ - if(!initialized) - { - auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); - ui->versionList->initialize(vlist.get()); - initialized = true; - } - else - { - suggestCurrent(); - } -} - -void VanillaPage::refresh() -{ - ui->versionList->loadList(); -} - -void VanillaPage::loaderRefresh() -{ - if(ui->noneFilter->isChecked()) - return; - ui->loaderVersionList->loadList(); -} - -void VanillaPage::filterChanged() -{ - QStringList out; - if(ui->alphaFilter->isChecked()) - out << "(old_alpha)"; - if(ui->betaFilter->isChecked()) - out << "(old_beta)"; - if(ui->snapshotFilter->isChecked()) - out << "(snapshot)"; - if(ui->oldSnapshotFilter->isChecked()) - out << "(old_snapshot)"; - if(ui->releaseFilter->isChecked()) - out << "(release)"; - if(ui->experimentsFilter->isChecked()) - out << "(experiment)"; - auto regexp = out.join('|'); - ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); -} - -void VanillaPage::loaderFilterChanged() -{ - QString minecraftVersion; - if (m_selectedVersion) - { - minecraftVersion = m_selectedVersion->descriptor(); - } - else - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list - ui->loaderVersionList->setEmptyString(tr("No Minecraft version is selected.")); - ui->loaderVersionList->setEmptyMode(VersionListView::String); - return; - } - if(ui->noneFilter->isChecked()) - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list - ui->loaderVersionList->setEmptyString(tr("No mod loader is selected.")); - ui->loaderVersionList->setEmptyMode(VersionListView::String); - return; - } - else if(ui->forgeFilter->isChecked()) - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); - m_selectedLoader = "net.minecraftforge"; - } - else if(ui->fabricFilter->isChecked()) - { - // FIXME: dirty hack because the launcher is unaware of Fabric's dependencies - if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, ""); - else // Fabric/Quilt unsupported - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list - m_selectedLoader = "net.fabricmc.fabric-loader"; - } - else if(ui->quiltFilter->isChecked()) - { - // FIXME: dirty hack because the launcher is unaware of Quilt's dependencies (same as Fabric) - if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, ""); - else // Fabric/Quilt unsupported - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list - m_selectedLoader = "org.quiltmc.quilt-loader"; - } - else if(ui->liteLoaderFilter->isChecked()) - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); - m_selectedLoader = "com.mumfrey.liteloader"; - } - - auto vlist = APPLICATION->metadataIndex()->get(m_selectedLoader); - ui->loaderVersionList->initialize(vlist.get()); - ui->loaderVersionList->selectRecommended(); - ui->loaderVersionList->setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); -} - -VanillaPage::~VanillaPage() -{ - delete ui; -} - -bool VanillaPage::shouldDisplay() const -{ - return true; -} - -void VanillaPage::retranslate() -{ - ui->retranslateUi(this); -} - -BaseVersion::Ptr VanillaPage::selectedVersion() const -{ - return m_selectedVersion; -} - -BaseVersion::Ptr VanillaPage::selectedLoaderVersion() const -{ - return m_selectedLoaderVersion; -} - -QString VanillaPage::selectedLoader() const -{ - return m_selectedLoader; -} - -void VanillaPage::suggestCurrent() -{ - if (!isOpened) - { - return; - } - - if(!m_selectedVersion) - { - dialog->setSuggestedPack(); - return; - } - - // There isn't a selected version if the version list is empty - if(ui->loaderVersionList->selectedVersion() == nullptr) - dialog->setSuggestedPack(m_selectedVersion->descriptor(), new VanillaCreationTask(m_selectedVersion)); - else - { - dialog->setSuggestedPack(m_selectedVersion->descriptor(), - new VanillaCreationTask(m_selectedVersion, m_selectedLoader, - m_selectedLoaderVersion)); - } - dialog->setSuggestedIcon("default"); -} - -void VanillaPage::setSelectedVersion(BaseVersion::Ptr version) -{ - m_selectedVersion = version; - suggestCurrent(); - loaderFilterChanged(); -} - -void VanillaPage::setSelectedLoaderVersion(BaseVersion::Ptr version) -{ - m_selectedLoaderVersion = version; - suggestCurrent(); -} diff --git a/launcher/ui/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/VanillaPage.h deleted file mode 100644 index 39aba760..00000000 --- a/launcher/ui/pages/modplatform/VanillaPage.h +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 Jamie Mansfield - * - * 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 . - * - * 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 - -#include - -#include "ui/pages/BasePage.h" -#include -#include "tasks/Task.h" - -namespace Ui -{ -class VanillaPage; -} - -class NewInstanceDialog; - -class VanillaPage : public QWidget, public BasePage -{ - Q_OBJECT - -public: - explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0); - virtual ~VanillaPage(); - virtual QString displayName() const override - { - return tr("Vanilla"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("minecraft"); - } - virtual QString id() const override - { - return "vanilla"; - } - virtual QString helpPage() const override - { - return "Vanilla-platform"; - } - virtual bool shouldDisplay() const override; - void retranslate() override; - - void openedImpl() override; - - BaseVersion::Ptr selectedVersion() const; - BaseVersion::Ptr selectedLoaderVersion() const; - QString selectedLoader() const; - -public slots: - void setSelectedVersion(BaseVersion::Ptr version); - void setSelectedLoaderVersion(BaseVersion::Ptr version); - -private slots: - void filterChanged(); - void loaderFilterChanged(); - -private: - void refresh(); - void loaderRefresh(); - void suggestCurrent(); - -private: - bool initialized = false; - NewInstanceDialog *dialog = nullptr; - Ui::VanillaPage *ui = nullptr; - bool m_versionSetByUser = false; - BaseVersion::Ptr m_selectedVersion; - BaseVersion::Ptr m_selectedLoaderVersion; - QString m_selectedLoader; -}; diff --git a/launcher/ui/pages/modplatform/VanillaPage.ui b/launcher/ui/pages/modplatform/VanillaPage.ui deleted file mode 100644 index 43110927..00000000 --- a/launcher/ui/pages/modplatform/VanillaPage.ui +++ /dev/null @@ -1,290 +0,0 @@ - - - VanillaPage - - - - 0 - 0 - 815 - 607 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - - - - - - - Filter - - - Qt::AlignCenter - - - - - - - Releases - - - true - - - true - - - - - - - Snapshots - - - true - - - - - - - Old Snapshots - - - true - - - - - - - Betas - - - true - - - - - - - Alphas - - - true - - - - - - - Experiments - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Refresh - - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - Mod Loader - - - Qt::AlignCenter - - - - - - - None - - - true - - - loaderBtnGroup - - - - - - - Forge - - - loaderBtnGroup - - - - - - - Fabric - - - loaderBtnGroup - - - - - - - Quilt - - - loaderBtnGroup - - - - - - - LiteLoader - - - loaderBtnGroup - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Refresh - - - - - - - - - - - - - - - - VersionSelectWidget - QWidget -
ui/widgets/VersionSelectWidget.h
- 1 -
-
- - tabWidget - releaseFilter - snapshotFilter - oldSnapshotFilter - betaFilter - alphaFilter - experimentsFilter - refreshBtn - - - - - - -
-- cgit From bb8e6ef35ec4d911d199b06d3337dfcd1ab8b202 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:26:02 +0100 Subject: Fix flat white launcher icon Signed-off-by: TheKodeToad --- .../resources/flat_white/scalable/launcher.svg | 57 +++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg index 54131b65..aeee8433 100644 --- a/launcher/resources/flat_white/scalable/launcher.svg +++ b/launcher/resources/flat_white/scalable/launcher.svg @@ -1,2 +1,57 @@ - + + + Prism Launcher Logo + + + + + + + + + + + + + + + + + + + + + + + Prism Launcher Logo + 19/10/2022 + + + Prism Launcher + + + + + AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke + + + https://github.com/PrismLauncher/PrismLauncher + + + Prism Launcher + + + + + + + + + + + + + + + -- cgit From 8a3aba1634ca9f8b86c995687c7e2f99740d9111 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:30:51 +0100 Subject: Fix Open Global Settings, why not Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 08977841..893fe2a5 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -86,11 +86,11 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) APPLICATION->ShowGlobalSettings(this, "java-settings"); return; case 1: - APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); - return; - case 2: APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; + default: + APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); + return; } } -- cgit From 5eb71fc6a96690e3d9a658f383b0937446ec3f9e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:34:37 +0100 Subject: Revert "feat(Mods): hide 'Provider' column when no mods have providers" With Ryex's change, this causes issues. Apparently you need to sign off reverts! That's just weird... Signed-off-by: TheKodeToad --- launcher/ui/widgets/ModListView.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index 893cd120..80a918b6 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -14,9 +14,6 @@ */ #include "ModListView.h" - -#include "minecraft/mod/ModFolderModel.h" - #include #include #include @@ -65,19 +62,6 @@ void ModListView::setModel ( QAbstractItemModel* model ) for(int i = 1; i < head->count(); i++) head->setSectionResizeMode(i, QHeaderView::ResizeToContents); } - - auto real_model = model; - if (auto proxy_model = dynamic_cast(model); proxy_model) - real_model = proxy_model->sourceModel(); - - if (auto mod_model = dynamic_cast(real_model); mod_model) { - connect(mod_model, &ModFolderModel::updateFinished, this, [this, mod_model]{ - auto mods = mod_model->allMods(); - // Hide the 'Provider' column if no mod has a defined provider! - setColumnHidden(ModFolderModel::Columns::ProviderColumn, - std::none_of(mods.constBegin(), mods.constEnd(), [](auto const mod){ return mod->provider().has_value(); })); - }); - } } void ModListView::setResizeModes(const QList &modes) -- cgit From 603ed220151345f44a43e14538ea449bae843958 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 10:36:54 +0100 Subject: Replace accidental usages of QAbstractButton::pressed This signal is not usually what you want, and creates an inconsistent experience. Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ManagedPackPage.cpp | 4 ++-- launcher/ui/pages/modplatform/legacy_ftb/Page.cpp | 4 ++-- launcher/ui/setupwizard/SetupWizard.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index e0a7314f..d89c5bfc 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -205,7 +205,7 @@ ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWin { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); - connect(ui->updateButton, &QPushButton::pressed, this, &ModrinthManagedPackPage::update); + connect(ui->updateButton, &QPushButton::clicked, this, &ModrinthManagedPackPage::update); } // MODRINTH @@ -332,7 +332,7 @@ FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, InstanceWindow* i { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); - connect(ui->updateButton, &QPushButton::pressed, this, &FlameManagedPackPage::update); + connect(ui->updateButton, &QPushButton::clicked, this, &FlameManagedPackPage::update); } void FlameManagedPackPage::parseManagedPack() diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp index 98ab8799..b3f6261f 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp @@ -116,8 +116,8 @@ Page::Page(NewInstanceDialog* dialog, QWidget *parent) connect(ui->thirdPartyPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onThirdPartyPackSelectionChanged); connect(ui->privatePackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onPrivatePackSelectionChanged); - connect(ui->addPackBtn, &QPushButton::pressed, this, &Page::onAddPackClicked); - connect(ui->removePackBtn, &QPushButton::pressed, this, &Page::onRemovePackClicked); + connect(ui->addPackBtn, &QPushButton::clicked, this, &Page::onAddPackClicked); + connect(ui->removePackBtn, &QPushButton::clicked, this, &Page::onRemovePackClicked); connect(ui->tabWidget, &QTabWidget::currentChanged, this, &Page::onTabChanged); diff --git a/launcher/ui/setupwizard/SetupWizard.cpp b/launcher/ui/setupwizard/SetupWizard.cpp index 3fd9bb23..0a47334f 100644 --- a/launcher/ui/setupwizard/SetupWizard.cpp +++ b/launcher/ui/setupwizard/SetupWizard.cpp @@ -59,7 +59,7 @@ void SetupWizard::pageChanged(int id) { setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton}); auto customButton = button(QWizard::CustomButton1); - connect(customButton, &QAbstractButton::pressed, [&](){ + connect(customButton, &QAbstractButton::clicked, [&](){ auto basePagePtr = getCurrentBasePage(); if(basePagePtr) { -- cgit From 514080653f2a862c6d3b2f1efb279a6707ccfb1c Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 11:56:28 +0100 Subject: Fix unsafe usage of std::optional::value in FlameAPI Signed-off-by: TheKodeToad --- launcher/modplatform/flame/FlameAPI.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index a0611957..0a6dc78f 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -77,24 +77,28 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] std::optional getVersionsURL(VersionSearchArgs const& args) const override { - auto mappedModLoader = getMappedModLoader(args.loaders.value()); auto addonId = args.pack.addonId.toString(); - if (args.loaders.value() & Quilt) { - auto overide = ModPlatform::getOverrideDeps(); - auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) { - return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt; - }); - if (over != overide.cend()) { - mappedModLoader = 5; - } - } QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(addonId) }; QStringList get_parameters; if (args.mcVersions.has_value()) get_parameters.append(QString("gameVersion=%1").arg(args.mcVersions.value().front().toString())); - if (args.loaders.has_value()) + + if (args.loaders.has_value()) { + int mappedModLoader = getMappedModLoader(args.loaders.value()); + + if (args.loaders.value() & Quilt) { + auto overide = ModPlatform::getOverrideDeps(); + auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) { + return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt; + }); + if (over != overide.cend()) { + mappedModLoader = 5; + } + } + get_parameters.append(QString("modLoaderType=%1").arg(mappedModLoader)); + } return url + get_parameters.join('&'); }; -- cgit From c75ba0f8551e911b72152ebdd8b2fe1f8bd8f64f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 12:46:07 +0100 Subject: Fix big mistake :iea: Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 893fe2a5..2a7c5b27 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -85,7 +85,7 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) case 0: APPLICATION->ShowGlobalSettings(this, "java-settings"); return; - case 1: + case 2: APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; default: -- cgit From 02b628653b4d2574766e1148ebd71b426b52a5d2 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 13:42:45 +0100 Subject: Fix markdown header Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 1 + launcher/Markdown.cpp | 31 +++++++++++++++++++++++++++++++ launcher/Markdown.h | 12 +----------- 3 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 launcher/Markdown.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c10064c0..3cc8b6e1 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -684,6 +684,7 @@ SET(LAUNCHER_SOURCES VersionProxyModel.h VersionProxyModel.cpp Markdown.h + Markdown.cpp # Super secret! KonamiCode.h diff --git a/launcher/Markdown.cpp b/launcher/Markdown.cpp new file mode 100644 index 00000000..426067bf --- /dev/null +++ b/launcher/Markdown.cpp @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 Joshua Goins + * + * 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 . + */ + +#include "Markdown.h" + +QString markdownToHTML(const QString& markdown) +{ + const QByteArray markdownData = markdown.toUtf8(); + char* buffer = cmark_markdown_to_html(markdownData.constData(), markdownData.length(), CMARK_OPT_NOBREAKS | CMARK_OPT_UNSAFE); + + QString htmlStr(buffer); + + free(buffer); + + return htmlStr; +} \ No newline at end of file diff --git a/launcher/Markdown.h b/launcher/Markdown.h index f115dd57..6b261e60 100644 --- a/launcher/Markdown.h +++ b/launcher/Markdown.h @@ -21,14 +21,4 @@ #include #include -static QString markdownToHTML(const QString& markdown) -{ - const QByteArray markdownData = markdown.toUtf8(); - char* buffer = cmark_markdown_to_html(markdownData.constData(), markdownData.length(), CMARK_OPT_NOBREAKS | CMARK_OPT_UNSAFE); - - QString htmlStr(buffer); - - free(buffer); - - return htmlStr; -} \ No newline at end of file +QString markdownToHTML(const QString& markdown); \ No newline at end of file -- cgit From 953a2590e27954a3b1d163224bd343bb75a62b69 Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 25 Jun 2023 10:11:58 -0300 Subject: Add fixme comment for no SSD detection Co-authored-by: Sefa Eyeoglu Signed-off-by: Leo --- launcher/ui/MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 9b8db1ae..7e2c4acf 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -221,6 +221,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi setInstanceActionsEnabled(false); // add a close button at the end of the main toolbar when running on gamescope / steam deck + // FIXME: detect if we don't have server side decorations instead if (qgetenv("XDG_CURRENT_DESKTOP") == "gamescope") { ui->mainToolBar->addAction(ui->actionCloseWindow); } -- cgit From 4745ab64cdf073b781515f43f7b10cd7f776078b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 15:02:25 +0100 Subject: Deduplicate launcher icon Signed-off-by: TheKodeToad --- launcher/resources/OSX/OSX.qrc | 1 - launcher/resources/OSX/scalable/launcher.svg | 57 ---------------------- .../resources/breeze_dark/scalable/launcher.svg | 57 ---------------------- launcher/resources/flat/flat.qrc | 1 - launcher/resources/flat/scalable/launcher.svg | 57 ---------------------- launcher/resources/flat_white/flat_white.qrc | 1 - .../resources/flat_white/scalable/launcher.svg | 57 ---------------------- launcher/resources/iOS/iOS.qrc | 1 - launcher/resources/iOS/scalable/launcher.svg | 57 ---------------------- launcher/resources/pe_blue/pe_blue.qrc | 1 - launcher/resources/pe_blue/scalable/launcher.svg | 57 ---------------------- launcher/resources/pe_colored/pe_colored.qrc | 1 - .../resources/pe_colored/scalable/launcher.svg | 57 ---------------------- launcher/resources/pe_dark/pe_dark.qrc | 1 - launcher/resources/pe_dark/scalable/launcher.svg | 57 ---------------------- launcher/resources/pe_light/pe_light.qrc | 1 - launcher/resources/pe_light/scalable/launcher.svg | 57 ---------------------- 17 files changed, 521 deletions(-) delete mode 100644 launcher/resources/OSX/scalable/launcher.svg delete mode 100644 launcher/resources/breeze_dark/scalable/launcher.svg delete mode 100644 launcher/resources/flat/scalable/launcher.svg delete mode 100644 launcher/resources/flat_white/scalable/launcher.svg delete mode 100644 launcher/resources/iOS/scalable/launcher.svg delete mode 100644 launcher/resources/pe_blue/scalable/launcher.svg delete mode 100644 launcher/resources/pe_colored/scalable/launcher.svg delete mode 100644 launcher/resources/pe_dark/scalable/launcher.svg delete mode 100644 launcher/resources/pe_light/scalable/launcher.svg diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc index 9d4511d1..49f56b0c 100644 --- a/launcher/resources/OSX/OSX.qrc +++ b/launcher/resources/OSX/OSX.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/OSX/scalable/launcher.svg b/launcher/resources/OSX/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/OSX/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/breeze_dark/scalable/launcher.svg b/launcher/resources/breeze_dark/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/breeze_dark/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc index cadf8736..2fd5daef 100644 --- a/launcher/resources/flat/flat.qrc +++ b/launcher/resources/flat/flat.qrc @@ -18,7 +18,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/flat/scalable/launcher.svg b/launcher/resources/flat/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/flat/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index 2701462f..a1c940da 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -18,7 +18,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/flat_white/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc index 0b79efb2..9b8d84f5 100644 --- a/launcher/resources/iOS/iOS.qrc +++ b/launcher/resources/iOS/iOS.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/iOS/scalable/launcher.svg b/launcher/resources/iOS/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/iOS/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc index 1b2b6291..da45ef9a 100644 --- a/launcher/resources/pe_blue/pe_blue.qrc +++ b/launcher/resources/pe_blue/pe_blue.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_blue/scalable/launcher.svg b/launcher/resources/pe_blue/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/pe_blue/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc index 084fca93..ba5bd44f 100644 --- a/launcher/resources/pe_colored/pe_colored.qrc +++ b/launcher/resources/pe_colored/pe_colored.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_colored/scalable/launcher.svg b/launcher/resources/pe_colored/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/pe_colored/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc index 5c49b75a..2bfec42c 100644 --- a/launcher/resources/pe_dark/pe_dark.qrc +++ b/launcher/resources/pe_dark/pe_dark.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_dark/scalable/launcher.svg b/launcher/resources/pe_dark/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/pe_dark/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc index a8e3f157..25d5da73 100644 --- a/launcher/resources/pe_light/pe_light.qrc +++ b/launcher/resources/pe_light/pe_light.qrc @@ -16,7 +16,6 @@ scalable/jarmods.svg scalable/java.svg scalable/language.svg - scalable/launcher.svg scalable/loadermods.svg scalable/log.svg scalable/minecraft.svg diff --git a/launcher/resources/pe_light/scalable/launcher.svg b/launcher/resources/pe_light/scalable/launcher.svg deleted file mode 100644 index aeee8433..00000000 --- a/launcher/resources/pe_light/scalable/launcher.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - Prism Launcher Logo - - - - - - - - - - - - - - - - - - - - - - - Prism Launcher Logo - 19/10/2022 - - - Prism Launcher - - - - - AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke - - - https://github.com/PrismLauncher/PrismLauncher - - - Prism Launcher - - - - - - - - - - - - - - - -- cgit From 6d0e255ca18b1934d6eb514b6324cde67bb87d60 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 22:00:33 +0300 Subject: fix: Page container extra info set on logs page Signed-off-by: Trial97 --- launcher/ui/pages/BasePage.h | 2 +- launcher/ui/pages/instance/ExternalResourcesPage.cpp | 2 +- launcher/ui/widgets/PageContainer.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/ui/pages/BasePage.h b/launcher/ui/pages/BasePage.h index 5537c28f..dc2bde99 100644 --- a/launcher/ui/pages/BasePage.h +++ b/launcher/ui/pages/BasePage.h @@ -44,7 +44,7 @@ class BasePage { public: - using updateExtraInfoFunc = std::function; + using updateExtraInfoFunc = std::function; virtual ~BasePage() {} virtual QString id() const = 0; virtual QString displayName() const = 0; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 8e5226ef..173bcb66 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -83,7 +83,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared connect(selection_model, &QItemSelectionModel::currentChanged, this, &ExternalResourcesPage::current); auto updateExtra = [this]() { if (updateExtraInfo) - updateExtraInfo(extraHeaderInfoString()); + updateExtraInfo(id(), extraHeaderInfoString()); }; connect(selection_model, &QItemSelectionModel::selectionChanged, this, updateExtra); connect(model.get(), &ResourceFolderModel::updateFinished, this, updateExtra); diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 34df42ec..b98c9796 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -93,8 +93,8 @@ PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, page->listIndex = counter; page->setParentContainer(this); counter++; - page->updateExtraInfo = [this](QString info) { - if (m_currentPage) + page->updateExtraInfo = [this](QString id, QString info) { + if (m_currentPage && id == m_currentPage->id()) m_header->setText(m_currentPage->displayName() + info); }; } -- cgit From 8bebd7f042fc912dedb652c613a76a346c29a38f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 26 Jun 2023 01:18:55 +0100 Subject: Generate special signature :sparkles: composed of multiple elements instead of relying on timestamp for Java version cache invalidation Signed-off-by: TheKodeToad --- launcher/Application.cpp | 2 +- launcher/launch/steps/CheckJava.cpp | 15 ++++++++++----- launcher/launch/steps/CheckJava.h | 2 +- launcher/minecraft/MinecraftInstance.cpp | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 724e6e44..1d97a5f2 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -594,7 +594,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Java Settings m_settings->registerSetting("JavaPath", ""); - m_settings->registerSetting("JavaTimestamp", 0); + m_settings->registerSetting("JavaSignature", ""); m_settings->registerSetting("JavaArchitecture", ""); m_settings->registerSetting("JavaRealArchitecture", ""); m_settings->registerSetting("JavaVersion", ""); diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index f0187586..7d697ba9 100644 --- a/launcher/launch/steps/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp @@ -81,15 +81,20 @@ void CheckJava::executeTask() } QFileInfo javaInfo(realJavaPath); - qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch(); - auto storedUnixTime = settings->get("JavaTimestamp").toLongLong(); + qint64 javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch(); + auto storedSignature = settings->get("JavaSignature").toString(); auto storedArchitecture = settings->get("JavaArchitecture").toString(); auto storedRealArchitecture = settings->get("JavaRealArchitecture").toString(); auto storedVersion = settings->get("JavaVersion").toString(); auto storedVendor = settings->get("JavaVendor").toString(); - m_javaUnixTime = javaUnixTime; + + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(QByteArray::number(javaUnixTime)); + hash.addData(m_javaPath.toUtf8()); + m_javaSignature = hash.result().toHex(); + // if timestamps are not the same, or something is missing, check! - if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 + if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 || storedRealArchitecture.size() == 0 || storedVendor.size() == 0) { @@ -140,7 +145,7 @@ void CheckJava::checkJavaFinished(JavaCheckResult result) instance->settings()->set("JavaArchitecture", result.mojangPlatform); instance->settings()->set("JavaRealArchitecture", result.realPlatform); instance->settings()->set("JavaVendor", result.javaVendor); - instance->settings()->set("JavaTimestamp", m_javaUnixTime); + instance->settings()->set("JavaSignature", m_javaSignature); emitSucceeded(); return; } diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h index d084b132..bbf06b7c 100644 --- a/launcher/launch/steps/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h @@ -40,6 +40,6 @@ private: private: QString m_javaPath; - qlonglong m_javaUnixTime; + QString m_javaSignature; JavaCheckerPtr m_JavaChecker; }; diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index f8ed5214..aab930de 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -148,7 +148,7 @@ void MinecraftInstance::loadSpecificSettings() m_settings->registerOverride(global_settings->getSetting("IgnoreJavaCompatibility"), javaOrLocation); // special! - m_settings->registerPassthrough(global_settings->getSetting("JavaTimestamp"), javaOrLocation); + m_settings->registerPassthrough(global_settings->getSetting("JavaSignature"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaArchitecture"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaRealArchitecture"), javaOrLocation); m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), javaOrLocation); -- cgit From ed4dce2fb658de726435b06f1d8973b447279f1e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 08:59:23 +0200 Subject: fix: install logo to multimc theme in genicons.sh Signed-off-by: Sefa Eyeoglu --- program_info/genicons.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/program_info/genicons.sh b/program_info/genicons.sh index 42592c4e..fe8d2e35 100755 --- a/program_info/genicons.sh +++ b/program_info/genicons.sh @@ -67,7 +67,4 @@ else fi # replace icon in themes -for dir in ../launcher/resources/*/scalable -do - cp -v org.prismlauncher.PrismLauncher.svg "$dir/launcher.svg" -done +cp -v org.prismlauncher.PrismLauncher.svg "../launcher/resources/multimc/scalable/launcher.svg" -- cgit From f8f1c3cf231835de5fdee76532180d02d08e6a28 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 09:08:03 +0200 Subject: chore: add Git Blame ignore file Signed-off-by: Sefa Eyeoglu --- .git-blame-ignore-revs | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..2163db45 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,4 @@ +# .git-blame-ignore-revs + +# tabs -> spaces +bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9 -- cgit From dffffc784e0f9d250613a879c1ebe017b782cf77 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 26 Jun 2023 22:33:10 +0300 Subject: Removed unused files Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 2 - launcher/mojang/PackageManifest.cpp | 427 ------------------------------------ launcher/mojang/PackageManifest.h | 171 --------------- tests/CMakeLists.txt | 3 - tests/PackageManifest_test.cpp | 343 ----------------------------- 5 files changed, 946 deletions(-) delete mode 100644 launcher/mojang/PackageManifest.cpp delete mode 100644 launcher/mojang/PackageManifest.h delete mode 100644 tests/PackageManifest_test.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 9bad2a67..6ca31d46 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -377,8 +377,6 @@ set(MINECRAFT_SOURCES minecraft/services/SkinDelete.cpp minecraft/services/SkinDelete.h - mojang/PackageManifest.h - mojang/PackageManifest.cpp minecraft/Agent.h) # the screenshots feature diff --git a/launcher/mojang/PackageManifest.cpp b/launcher/mojang/PackageManifest.cpp deleted file mode 100644 index b3dfd7fc..00000000 --- a/launcher/mojang/PackageManifest.cpp +++ /dev/null @@ -1,427 +0,0 @@ -#include "PackageManifest.h" -#include -#include -#include -#include -#include - -#ifndef Q_OS_WIN32 -#include -#include -#include -#endif - -namespace mojang_files { - -const Hash hash_of_empty_string = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; - -int Path::compare(const Path& rhs) const -{ - auto left_cursor = begin(); - auto left_end = end(); - auto right_cursor = rhs.begin(); - auto right_end = rhs.end(); - - while (left_cursor != left_end && right_cursor != right_end) - { - if(*left_cursor < *right_cursor) - { - return -1; - } - else if(*left_cursor > *right_cursor) - { - return 1; - } - left_cursor++; - right_cursor++; - } - - if(left_cursor == left_end) - { - if(right_cursor == right_end) - { - return 0; - } - return -1; - } - return 1; -} - -void Package::addFile(const Path& path, const File& file) { - addFolder(path.parent_path()); - files[path] = file; -} - -void Package::addFolder(Path folder) { - if(!folder.has_parent_path()) { - return; - } - do { - folders.insert(folder); - folder = folder.parent_path(); - } while(folder.has_parent_path()); -} - -void Package::addLink(const Path& path, const Path& target) { - addFolder(path.parent_path()); - symlinks[path] = target; -} - -void Package::addSource(const FileSource& source) { - sources[source.hash] = source; -} - - -namespace { -void fromJson(QJsonDocument & doc, Package & out) { - std::set seen_paths; - if (!doc.isObject()) - { - throw JSONValidationError("file manifest is not an object"); - } - QJsonObject root = doc.object(); - - auto filesObj = Json::ensureObject(root, "files"); - auto iter = filesObj.begin(); - while (iter != filesObj.end()) - { - Path objectPath = Path(iter.key()); - auto value = iter.value(); - iter++; - if(seen_paths.count(objectPath)) { - throw JSONValidationError("duplicate path inside manifest, the manifest is invalid"); - } - if (!value.isObject()) - { - throw JSONValidationError("file entry inside manifest is not an an object"); - } - seen_paths.insert(objectPath); - - auto fileObject = value.toObject(); - auto type = Json::requireString(fileObject, "type"); - if(type == "directory") { - out.addFolder(objectPath); - continue; - } - else if(type == "file") { - FileSource bestSource; - File file; - file.executable = Json::ensureBoolean(fileObject, QString("executable"), false); - auto downloads = Json::requireObject(fileObject, "downloads"); - for(auto iter2 = downloads.begin(); iter2 != downloads.end(); iter2++) { - FileSource source; - - auto downloadObject = Json::requireObject(iter2.value()); - source.hash = Json::requireString(downloadObject, "sha1"); - source.size = Json::requireInteger(downloadObject, "size"); - source.url = Json::requireString(downloadObject, "url"); - - auto compression = iter2.key(); - if(compression == "raw") { - file.hash = source.hash; - file.size = source.size; - source.compression = Compression::Raw; - } - else if (compression == "lzma") { - source.compression = Compression::Lzma; - } - else { - continue; - } - bestSource.upgrade(source); - } - if(bestSource.isBad()) { - throw JSONValidationError("No valid compression method for file " + iter.key()); - } - out.addFile(objectPath, file); - out.addSource(bestSource); - } - else if(type == "link") { - auto target = Json::requireString(fileObject, "target"); - out.symlinks[objectPath] = target; - out.addLink(objectPath, target); - } - else { - throw JSONValidationError("Invalid item type in manifest: " + type); - } - } - // make sure the containing folder exists - out.folders.insert(Path()); -} -} - -Package Package::fromManifestContents(const QByteArray& contents) -{ - Package out; - try - { - auto doc = Json::requireDocument(contents, "Manifest"); - fromJson(doc, out); - return out; - } - catch (const Exception &e) - { - qDebug() << QString("Unable to parse manifest: %1").arg(e.cause()); - out.valid = false; - return out; - } -} - -Package Package::fromManifestFile(const QString & filename) { - Package out; - try - { - auto doc = Json::requireDocument(filename, filename); - fromJson(doc, out); - return out; - } - catch (const Exception &e) - { - qDebug() << QString("Unable to parse manifest file %1: %2").arg(filename, e.cause()); - out.valid = false; - return out; - } -} - -#ifndef Q_OS_WIN32 - -#include -#include -#include - -namespace { -// FIXME: Qt obscures symlink targets by making them absolute. that is useless. this is the workaround - we do it ourselves -bool actually_read_symlink_target(const QString & filepath, Path & out) -{ - struct ::stat st; - // FIXME: here, we assume the native filesystem encoding. May the Gods have mercy upon our Souls. - QByteArray nativePath = filepath.toUtf8(); - const char * filepath_cstr = nativePath.data(); - - if (lstat(filepath_cstr, &st) != 0) - { - return false; - } - - auto size = st.st_size ? st.st_size + 1 : PATH_MAX; - std::string temp(size, '\0'); - // because we don't realiably know how long the damn thing actually is, we loop and expand. POSIX is naff - do - { - auto link_length = ::readlink(filepath_cstr, &temp[0], temp.size()); - if(link_length == -1) - { - return false; - } - if(std::string::size_type(link_length) < temp.size()) - { - // buffer was long enough and we managed to read the link target. RETURN here. - temp.resize(link_length); - out = Path(QString::fromUtf8(temp.c_str())); - return true; - } - temp.resize(temp.size() * 2); - } while (true); -} -} -#endif - -// FIXME: Qt filesystem abstraction is bad, but ... let's hope it doesn't break too much? -// FIXME: The error handling is just DEFICIENT -Package Package::fromInspectedFolder(const QString& folderPath) -{ - QDir root(folderPath); - - Package out; - QDirIterator iterator(folderPath, QDir::NoDotAndDotDot | QDir::AllEntries | QDir::System | QDir::Hidden, QDirIterator::Subdirectories); - while(iterator.hasNext()) { - iterator.next(); - - auto fileInfo = iterator.fileInfo(); - auto relPath = root.relativeFilePath(fileInfo.filePath()); - // FIXME: this is probably completely busted on Windows anyway, so just disable it. - // Qt makes shit up and doesn't understand the platform details - // TODO: Actually use a filesystem library that isn't terrible and has decen license. - // I only know one, and I wrote it. Sadly, currently proprietary. PAIN. -#ifndef Q_OS_WIN32 - if(fileInfo.isSymLink()) { - Path targetPath; - if(!actually_read_symlink_target(fileInfo.filePath(), targetPath)) { - qCritical() << "Folder inspection: Unknown filesystem object:" << fileInfo.absoluteFilePath(); - out.valid = false; - } - out.addLink(relPath, targetPath); - } - else -#endif - if(fileInfo.isDir()) { - out.addFolder(relPath); - } - else if(fileInfo.isFile()) { - File f; - f.executable = fileInfo.isExecutable(); - f.size = fileInfo.size(); - // FIXME: async / optimize the hashing - QFile input(fileInfo.absoluteFilePath()); - if(!input.open(QIODevice::ReadOnly)) { - qCritical() << "Folder inspection: Failed to open file:" << fileInfo.absoluteFilePath(); - out.valid = false; - break; - } - f.hash = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1).toHex().constData(); - out.addFile(relPath, f); - } - else { - // Something else... oh my - qCritical() << "Folder inspection: Unknown filesystem object:" << fileInfo.absoluteFilePath(); - out.valid = false; - break; - } - } - out.folders.insert(Path(".")); - out.valid = true; - return out; -} - -namespace { -struct shallow_first_sort -{ - bool operator()(const Path &lhs, const Path &rhs) const - { - auto lhs_depth = lhs.length(); - auto rhs_depth = rhs.length(); - if(lhs_depth < rhs_depth) - { - return true; - } - else if(lhs_depth == rhs_depth) - { - if(lhs < rhs) - { - return true; - } - } - return false; - } -}; - -struct deep_first_sort -{ - bool operator()(const Path &lhs, const Path &rhs) const - { - auto lhs_depth = lhs.length(); - auto rhs_depth = rhs.length(); - if(lhs_depth > rhs_depth) - { - return true; - } - else if(lhs_depth == rhs_depth) - { - if(lhs < rhs) - { - return true; - } - } - return false; - } -}; -} - -UpdateOperations UpdateOperations::resolve(const Package& from, const Package& to) -{ - UpdateOperations out; - - if(!from.valid || !to.valid) { - out.valid = false; - return out; - } - - // Files - for(auto iter = from.files.begin(); iter != from.files.end(); iter++) { - const auto ¤t_hash = iter->second.hash; - const auto ¤t_executable = iter->second.executable; - const auto &path = iter->first; - - auto iter2 = to.files.find(path); - if(iter2 == to.files.end()) { - // removed - out.deletes.push_back(path); - continue; - } - auto new_hash = iter2->second.hash; - auto new_executable = iter2->second.executable; - if (current_hash != new_hash) { - out.deletes.push_back(path); - out.downloads.emplace( - std::pair{ - path, - FileDownload(to.sources.at(iter2->second.hash), iter2->second.executable) - } - ); - } - else if (current_executable != new_executable) { - out.executable_fixes[path] = new_executable; - } - } - for(auto iter = to.files.begin(); iter != to.files.end(); iter++) { - auto path = iter->first; - if(!from.files.count(path)) { - out.downloads.emplace( - std::pair{ - path, - FileDownload(to.sources.at(iter->second.hash), iter->second.executable) - } - ); - } - } - - // Folders - std::set remove_folders; - std::set make_folders; - for(auto from_path: from.folders) { - auto iter = to.folders.find(from_path); - if(iter == to.folders.end()) { - remove_folders.insert(from_path); - } - } - for(auto & rmdir: remove_folders) { - out.rmdirs.push_back(rmdir); - } - for(auto to_path: to.folders) { - auto iter = from.folders.find(to_path); - if(iter == from.folders.end()) { - make_folders.insert(to_path); - } - } - for(auto & mkdir: make_folders) { - out.mkdirs.push_back(mkdir); - } - - // Symlinks - for(auto iter = from.symlinks.begin(); iter != from.symlinks.end(); iter++) { - const auto ¤t_target = iter->second; - const auto &path = iter->first; - - auto iter2 = to.symlinks.find(path); - if(iter2 == to.symlinks.end()) { - // removed - out.deletes.push_back(path); - continue; - } - const auto &new_target = iter2->second; - if (current_target != new_target) { - out.deletes.push_back(path); - out.mklinks[path] = iter2->second; - } - } - for(auto iter = to.symlinks.begin(); iter != to.symlinks.end(); iter++) { - auto path = iter->first; - if(!from.symlinks.count(path)) { - out.mklinks[path] = iter->second; - } - } - out.valid = true; - return out; -} - -} diff --git a/launcher/mojang/PackageManifest.h b/launcher/mojang/PackageManifest.h deleted file mode 100644 index fd7ab0ad..00000000 --- a/launcher/mojang/PackageManifest.h +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "tasks/Task.h" - -namespace mojang_files { - -using Hash = QString; -extern const Hash empty_hash; - -// simple-ish path implementation. assumes always relative and does not allow '..' entries -class Path -{ -public: - using parts_type = QStringList; - - Path() = default; - Path(QString string) { - auto parts_in = string.split('/'); - for(auto & part: parts_in) { - if(part.isEmpty() || part == ".") { - continue; - } - if(part == "..") { - if(parts.size()) { - parts.pop_back(); - } - continue; - } - parts.push_back(part); - } - } - - bool has_parent_path() const - { - return parts.size() > 0; - } - - Path parent_path() const - { - if (parts.empty()) - return Path(); - return Path(parts.begin(), std::prev(parts.end())); - } - - bool empty() const - { - return parts.empty(); - } - - int length() const - { - return parts.length(); - } - - bool operator==(const Path & rhs) const { - return parts == rhs.parts; - } - - bool operator!=(const Path & rhs) const { - return parts != rhs.parts; - } - - inline bool operator<(const Path& rhs) const - { - return compare(rhs) < 0; - } - - parts_type::const_iterator begin() const - { - return parts.begin(); - } - - parts_type::const_iterator end() const - { - return parts.end(); - } - - QString toString() const { - return parts.join("/"); - } - -private: - Path(const parts_type::const_iterator & start, const parts_type::const_iterator & end) { - auto cursor = start; - while(cursor != end) { - parts.push_back(*cursor); - cursor++; - } - } - int compare(const Path& p) const; - - parts_type parts; -}; - - -enum class Compression { - Raw, - Lzma, - Unknown -}; - - -struct FileSource -{ - Compression compression = Compression::Unknown; - Hash hash; - QString url; - std::size_t size = 0; - void upgrade(const FileSource & other) { - if(compression == Compression::Unknown || other.size < size) { - *this = other; - } - } - bool isBad() const { - return compression == Compression::Unknown; - } -}; - -struct File -{ - Hash hash; - bool executable; - std::uint64_t size = 0; -}; - -struct Package { - static Package fromInspectedFolder(const QString &folderPath); - static Package fromManifestFile(const QString &path); - static Package fromManifestContents(const QByteArray& contents); - - explicit operator bool() const - { - return valid; - } - void addFolder(Path folder); - void addFile(const Path & path, const File & file); - void addLink(const Path & path, const Path & target); - void addSource(const FileSource & source); - - std::map sources; - bool valid = true; - std::set folders; - std::map files; - std::map symlinks; -}; - -struct FileDownload : FileSource -{ - FileDownload(const FileSource& source, bool executable) { - static_cast (*this) = source; - this->executable = executable; - } - bool executable = false; -}; - -struct UpdateOperations { - static UpdateOperations resolve(const Package & from, const Package & to); - bool valid = false; - std::vector deletes; - std::vector rmdirs; - std::vector mkdirs; - std::map downloads; - std::map mklinks; - std::map executable_fixes; -}; - -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 36a3b0f8..a26a49fe 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,9 +9,6 @@ ecm_add_test(GZip_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}:: ecm_add_test(GradleSpecifier_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test TEST_NAME GradleSpecifier) -ecm_add_test(PackageManifest_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test - TEST_NAME PackageManifest) - ecm_add_test(MojangVersionFormat_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test TEST_NAME MojangVersionFormat) diff --git a/tests/PackageManifest_test.cpp b/tests/PackageManifest_test.cpp deleted file mode 100644 index e38abf80..00000000 --- a/tests/PackageManifest_test.cpp +++ /dev/null @@ -1,343 +0,0 @@ -#include -#include - -#include - -using namespace mojang_files; - -QDebug operator<<(QDebug debug, const Path &path) -{ - debug << path.toString(); - return debug; -} - -class PackageManifestTest : public QObject -{ - Q_OBJECT - -private slots: - void test_parse(); - void test_parse_file(); - void test_inspect(); -#ifndef Q_OS_WIN32 - void test_inspect_symlinks(); -#endif - void mkdir_deep(); - void rmdir_deep(); - - void identical_file(); - void changed_file(); - void added_file(); - void removed_file(); -}; - -namespace { -QByteArray basic_manifest = R"END( -{ - "files": { - "a/b.txt": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/b.txt", - "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "size": 0 - } - }, - "executable": true - }, - "a/b/c": { - "type": "directory" - }, - "a/b/c.txt": { - "type": "link", - "target": "../b.txt" - } - } -} -)END"; -} - -void PackageManifestTest::test_parse() -{ - auto manifest = Package::fromManifestContents(basic_manifest); - QVERIFY(manifest.valid == true); - QVERIFY(manifest.files.size() == 1); - QVERIFY(manifest.files.count(Path("a/b.txt"))); - auto &file = manifest.files[Path("a/b.txt")]; - QVERIFY(file.executable == true); - QVERIFY(file.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file.size == 0); - QVERIFY(manifest.folders.size() == 4); - QVERIFY(manifest.folders.count(Path("."))); - QVERIFY(manifest.folders.count(Path("a"))); - QVERIFY(manifest.folders.count(Path("a/b"))); - QVERIFY(manifest.folders.count(Path("a/b/c"))); - QVERIFY(manifest.symlinks.size() == 1); - auto symlinkPath = Path("a/b/c.txt"); - QVERIFY(manifest.symlinks.count(symlinkPath)); - auto &symlink = manifest.symlinks[symlinkPath]; - QVERIFY(symlink == Path("../b.txt")); - QVERIFY(manifest.sources.size() == 1); -} - -void PackageManifestTest::test_parse_file() { - auto path = QFINDTESTDATA("testdata/PackageManifest/1.8.0_202-x64.json"); - auto manifest = Package::fromManifestFile(path); - QVERIFY(manifest.valid == true); -} - - -void PackageManifestTest::test_inspect() { - auto path = QFINDTESTDATA("testdata/PackageManifest/inspect_win/"); - auto manifest = Package::fromInspectedFolder(path); - QVERIFY(manifest.valid == true); - QVERIFY(manifest.files.size() == 2); - QVERIFY(manifest.files.count(Path("a/b.txt"))); - auto &file1 = manifest.files[Path("a/b.txt")]; - QVERIFY(file1.executable == false); - QVERIFY(file1.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file1.size == 0); - QVERIFY(manifest.files.count(Path("a/b/b.txt"))); - auto &file2 = manifest.files[Path("a/b/b.txt")]; - QVERIFY(file2.executable == false); - QVERIFY(file2.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file2.size == 0); - QVERIFY(manifest.folders.size() == 3); - QVERIFY(manifest.folders.count(Path("."))); - QVERIFY(manifest.folders.count(Path("a"))); - QVERIFY(manifest.folders.count(Path("a/b"))); - QVERIFY(manifest.symlinks.size() == 0); -} - -#ifndef Q_OS_WIN32 -void PackageManifestTest::test_inspect_symlinks() { - auto path = QFINDTESTDATA("testdata/PackageManifest/inspect/"); - auto manifest = Package::fromInspectedFolder(path); - QVERIFY(manifest.valid == true); - QVERIFY(manifest.files.size() == 1); - QVERIFY(manifest.files.count(Path("a/b.txt"))); - auto &file = manifest.files[Path("a/b.txt")]; - QVERIFY(file.executable == true); - QVERIFY(file.hash == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - QVERIFY(file.size == 0); - QVERIFY(manifest.folders.size() == 3); - QVERIFY(manifest.folders.count(Path("."))); - QVERIFY(manifest.folders.count(Path("a"))); - QVERIFY(manifest.folders.count(Path("a/b"))); - QVERIFY(manifest.symlinks.size() == 1); - QVERIFY(manifest.symlinks.count(Path("a/b/b.txt"))); - qDebug() << manifest.symlinks[Path("a/b/b.txt")]; - QVERIFY(manifest.symlinks[Path("a/b/b.txt")] == Path("../b.txt")); -} -#endif - -void PackageManifestTest::mkdir_deep() { - - Package from; - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/e": { - "type": "directory" - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - QVERIFY(operations.rmdirs.size() == 0); - - QVERIFY(operations.mkdirs.size() == 6); - QVERIFY(operations.mkdirs[0] == Path(".")); - QVERIFY(operations.mkdirs[1] == Path("a")); - QVERIFY(operations.mkdirs[2] == Path("a/b")); - QVERIFY(operations.mkdirs[3] == Path("a/b/c")); - QVERIFY(operations.mkdirs[4] == Path("a/b/c/d")); - QVERIFY(operations.mkdirs[5] == Path("a/b/c/d/e")); - - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::rmdir_deep() { - - Package to; - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/e": { - "type": "directory" - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - - QVERIFY(operations.rmdirs.size() == 6); - QVERIFY(operations.rmdirs[0] == Path("a/b/c/d/e")); - QVERIFY(operations.rmdirs[1] == Path("a/b/c/d")); - QVERIFY(operations.rmdirs[2] == Path("a/b/c")); - QVERIFY(operations.rmdirs[3] == Path("a/b")); - QVERIFY(operations.rmdirs[4] == Path("a")); - QVERIFY(operations.rmdirs[5] == Path(".")); - - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::identical_file() { - QByteArray manifest = R"END( -{ - "files": { - "a/b/c/d/empty.txt": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/empty.txt", - "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "size": 0 - } - }, - "executable": false - } - } -} -)END"; - auto from = Package::fromManifestContents(manifest); - auto to = Package::fromManifestContents(manifest); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::changed_file() { - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/empty.txt", - "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "size": 0 - } - }, - "executable": false - } - } -} -)END"); - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/space.txt", - "sha1": "dd122581c8cd44d0227f9c305581ffcb4b6f1b46", - "size": 1 - } - }, - "executable": false - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 1); - QCOMPARE(operations.deletes[0], Path("a/b/c/d/file")); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 1); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::added_file() { - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d": { - "type": "directory" - } - } -} -)END"); - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/space.txt", - "sha1": "dd122581c8cd44d0227f9c305581ffcb4b6f1b46", - "size": 1 - } - }, - "executable": false - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 0); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 1); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -void PackageManifestTest::removed_file() { - auto from = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d/file": { - "type": "file", - "downloads": { - "raw": { - "url": "http://dethware.org/space.txt", - "sha1": "dd122581c8cd44d0227f9c305581ffcb4b6f1b46", - "size": 1 - } - }, - "executable": false - } - } -} -)END"); - auto to = Package::fromManifestContents(R"END( -{ - "files": { - "a/b/c/d": { - "type": "directory" - } - } -} -)END"); - auto operations = UpdateOperations::resolve(from, to); - QVERIFY(operations.deletes.size() == 1); - QCOMPARE(operations.deletes[0], Path("a/b/c/d/file")); - QVERIFY(operations.rmdirs.size() == 0); - QVERIFY(operations.mkdirs.size() == 0); - QVERIFY(operations.downloads.size() == 0); - QVERIFY(operations.mklinks.size() == 0); - QVERIFY(operations.executable_fixes.size() == 0); -} - -QTEST_GUILESS_MAIN(PackageManifestTest) - -#include "PackageManifest_test.moc" - -- cgit From 6e5716f097d89b4b7b4c48ae18e37474ef23b3e8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:05:32 +0300 Subject: Fixed illegal characters in shortcuts name Signed-off-by: Trial97 --- launcher/FileSystem.cpp | 11 ++- launcher/ui/MainWindow.cpp | 203 +++++++++++++++++++-------------------------- 2 files changed, 95 insertions(+), 119 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 835ad925..1ea9f755 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -372,7 +372,7 @@ void create_link::make_link_list(const QString& offset) auto src_path = source_it.next(); auto relative_path = src_dir.relativeFilePath(src_path); - if (m_max_depth >= 0 && pathDepth(relative_path) > m_max_depth){ + if (m_max_depth >= 0 && pathDepth(relative_path) > m_max_depth) { relative_path = pathTruncate(relative_path, m_max_depth); src_path = src_dir.filePath(relative_path); if (linkedPaths.contains(src_path)) { @@ -663,7 +663,7 @@ QString pathTruncate(const QString& path, int depth) QString trunc = QFileInfo(path).path(); - if (pathDepth(trunc) > depth ) { + if (pathDepth(trunc) > depth) { return pathTruncate(trunc, depth); } @@ -769,6 +769,9 @@ QString getDesktopDir() // Cross-platform Shortcut creation bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon) { + if (destination.isEmpty()) { + destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); + } #if defined(Q_OS_MACOS) destination += ".command"; @@ -791,6 +794,8 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri return true; #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated + destination += ".desktop"; QFile f(destination); f.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&f); @@ -974,7 +979,7 @@ FilesystemType getFilesystemType(const QString& name) { for (auto iter = s_filesystem_type_names.constBegin(); iter != s_filesystem_type_names.constEnd(); ++iter) { auto fs_names = iter.value(); - if(fs_names.contains(name.toUpper())) + if (fs_names.contains(name.toUpper())) return iter.key(); } return FilesystemType::UNKNOWN; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index eeb78c53..7407483f 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1510,140 +1510,111 @@ void MainWindow::on_actionKillInstance_triggered() void MainWindow::on_actionCreateInstanceShortcut_triggered() { - if (m_selectedInstance) - { - auto desktopPath = FS::getDesktopDir(); - if (desktopPath.isEmpty()) { - // TODO come up with an alternative solution (open "save file" dialog) - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); - return; - } + if (!m_selectedInstance) + return; + auto desktopPath = FS::getDesktopDir(); + if (desktopPath.isEmpty()) { + // TODO come up with an alternative solution (open "save file" dialog) + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); + return; + } + QString desktopFilePath; + QString appPath = QApplication::applicationFilePath(); + QString iconPath; + QStringList args; #if defined(Q_OS_MACOS) - QString appPath = QApplication::applicationFilePath(); - if (appPath.startsWith("/private/var/")) { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); - return; - } - - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - appPath, { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), "")) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } + if (appPath.startsWith("/private/var/")) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); + return; + } #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - QString appPath = QApplication::applicationFilePath(); - if (appPath.startsWith("/tmp/.mount_")) { - // AppImage! - appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE")); - if (appPath.isEmpty()) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)")); - } - else if (appPath.endsWith("/")) - { - appPath.chop(1); - } + if (appPath.startsWith("/tmp/.mount_")) { + // AppImage! + appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE")); + if (appPath.isEmpty()) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)")); + } else if (appPath.endsWith("/")) { + appPath.chop(1); } + } - auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); - if (icon == nullptr) - { - icon = APPLICATION->icons()->icon("grass"); - } + auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (icon == nullptr) { + icon = APPLICATION->icons()->icon("grass"); + } - QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png"); + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png"); - QFile iconFile(iconPath); - if (!iconFile.open(QFile::WriteOnly)) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } - bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); - iconFile.close(); + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); + iconFile.close(); - if (!success) - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } + if (!success) { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + + if (DesktopServices::isFlatpak()) { + desktopFilePath = FS::PathCombine(desktopPath, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()) + ".desktop"); + QFileDialog fileDialog; + // workaround to make sure the portal file dialog opens in the desktop directory + fileDialog.setDirectoryUrl(desktopPath); + desktopFilePath = fileDialog.getSaveFileName(this, tr("Create Shortcut"), desktopFilePath, tr("Desktop Entries (*.desktop)")); + if (desktopFilePath.isEmpty()) + return; // file dialog canceled by user + appPath = "flatpak"; + QString flatpakAppId = BuildConfig.LAUNCHER_DESKTOPFILENAME; + flatpakAppId.remove(".desktop"); + args.append({ "run", flatpakAppId }); + } - QString desktopFilePath = FS::PathCombine(desktopPath, m_selectedInstance->name() + ".desktop"); - QStringList args; - if (DesktopServices::isFlatpak()) { - QFileDialog fileDialog; - // workaround to make sure the portal file dialog opens in the desktop directory - fileDialog.setDirectoryUrl(desktopPath); - desktopFilePath = fileDialog.getSaveFileName( - this, tr("Create Shortcut"), desktopFilePath, - tr("Desktop Entries (*.desktop)")); - if (desktopFilePath.isEmpty()) - return; // file dialog canceled by user - appPath = "flatpak"; - QString flatpakAppId = BuildConfig.LAUNCHER_DESKTOPFILENAME; - flatpakAppId.remove(".desktop"); - args.append({ "run", flatpakAppId }); - } - args.append({ "--launch", m_selectedInstance->id() }); - if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } #elif defined(Q_OS_WIN) - auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); - if (icon == nullptr) - { - icon = APPLICATION->icons()->icon("grass"); - } + auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (icon == nullptr) { + icon = APPLICATION->icons()->icon("grass"); + } - QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico"); + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico"); - // part of fix for weird bug involving the window icon being replaced - // dunno why it happens, but this 2-line fix seems to be enough, so w/e - auto appIcon = APPLICATION->getThemedIcon("logo"); + // part of fix for weird bug involving the window icon being replaced + // dunno why it happens, but this 2-line fix seems to be enough, so w/e + auto appIcon = APPLICATION->getThemedIcon("logo"); - QFile iconFile(iconPath); - if (!iconFile.open(QFile::WriteOnly)) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } - bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); - iconFile.close(); + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); + iconFile.close(); - // restore original window icon - QGuiApplication::setWindowIcon(appIcon); + // restore original window icon + QGuiApplication::setWindowIcon(appIcon); - if (!success) - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } + if (!success) { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - QApplication::applicationFilePath(), { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), iconPath)) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } #else - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!")); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!")); + return; #endif + args.append({ "--launch", m_selectedInstance->id() }); + if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); + } else { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); } } -- cgit From 92847b977409f4f4b4daa1e34196596e40becc05 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:15:20 +0300 Subject: omit icon remove on macos Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7407483f..496738e3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1613,7 +1613,9 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); } else { +#if not defined(Q_OS_MACOS) iconFile.remove(); +#endif QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); } } -- cgit From 54cb077b40b1785174a9bd111d055a399b725e52 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:31:36 +0300 Subject: Added more information to the screenshot upload warning Signed-off-by: Trial97 --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index ca368d3b..35237594 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -36,6 +36,7 @@ */ #include "ScreenshotsPage.h" +#include "BuildConfig.h" #include "ui_ScreenshotsPage.h" #include @@ -380,16 +381,18 @@ void ScreenshotsPage::on_actionUpload_triggered() if (selection.isEmpty()) return; - QString text; + QUrl baseUrl(BuildConfig.IMGUR_BASE_URL); if (selection.size() > 1) - text = tr("You are about to upload %1 screenshots.\n\n" + text = tr("You are about to upload %1 screenshots to %2.\n" + "You should double-check for personal information.\n\n" "Are you sure?") - .arg(selection.size()); + .arg(QString::number(selection.size()), baseUrl.host()); else - text = - tr("You are about to upload the selected screenshot.\n\n" - "Are you sure?"); + text = tr("You are about to upload the selected screenshot to %1.\n" + "You should double-check for personal information.\n\n" + "Are you sure?") + .arg(baseUrl.host()); auto response = CustomMessageBox::selectable(this, "Confirm Upload", text, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) -- cgit From 87efa700ab53148f0555605fa21c683f3a9c3d15 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 00:01:36 +0300 Subject: Removed logs from instance export Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 14 ++++++++++++++ launcher/FileIgnoreProxy.h | 8 ++++++++ launcher/ui/dialogs/ExportInstanceDialog.cpp | 22 +++++++++++++--------- launcher/ui/dialogs/ExportMrPackDialog.cpp | 3 ++- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index a3b7d505..1f6b664c 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "FileSystem.h" #include "SeparatorPrefixTree.h" #include "StringUtils.h" @@ -254,3 +255,16 @@ bool FileIgnoreProxy::filterAcceptsColumn(int source_column, const QModelIndex& return true; } + +bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + QFileSystemModel* fsm = qobject_cast(sourceModel()); + + auto fileInfo = fsm->fileInfo(index); + auto fileName = fileInfo.fileName(); + auto path = relPath(fileInfo.absoluteFilePath()); + return !(path.startsWith("..") || // just in case ignore files outside the gameroot + std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + std::any_of(m_ignoreFilePaths.cbegin(), m_ignoreFilePaths.cend(), [path](auto iPath) { return path == iPath; })); +} diff --git a/launcher/FileIgnoreProxy.h b/launcher/FileIgnoreProxy.h index a5a1153d..dbd353e0 100644 --- a/launcher/FileIgnoreProxy.h +++ b/launcher/FileIgnoreProxy.h @@ -63,10 +63,18 @@ class FileIgnoreProxy : public QSortFilterProxyModel { inline const SeparatorPrefixTree<'/'>& blockedPaths() const { return blocked; } inline SeparatorPrefixTree<'/'>& blockedPaths() { return blocked; } + // list of file names that need to be removed completely from model + inline QStringList& ignoreFilesWithName() { return m_ignoreFiles; } + // list of relative paths that need to be removed completely from model + inline QStringList& ignoreFilesWithPath() { return m_ignoreFilePaths; } + protected: bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; private: const QString root; SeparatorPrefixTree<'/'> blocked; + QStringList m_ignoreFiles; + QStringList m_ignoreFilePaths; }; diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 8ecd91a9..8d0e05a2 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -35,24 +35,24 @@ */ #include "ExportInstanceDialog.h" -#include "ui_ExportInstanceDialog.h" #include #include #include -#include #include +#include +#include "ui_ExportInstanceDialog.h" -#include +#include +#include #include +#include #include +#include #include -#include -#include "SeparatorPrefixTree.h" #include "Application.h" -#include -#include +#include "SeparatorPrefixTree.h" -ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent) +ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent) : QDialog(parent), ui(new Ui::ExportInstanceDialog), m_instance(instance) { ui->setupUi(this); @@ -60,8 +60,12 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent model->setIconProvider(&icons); auto root = instance->instanceRoot(); proxyModel = new FileIgnoreProxy(root, this); - loadPackIgnore(); proxyModel->setSourceModel(model); + auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); + proxyModel->ignoreFilesWithPath().append({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); + proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); + loadPackIgnore(); + ui->treeView->setModel(proxyModel); ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); ui->treeView->sortByColumn(0, Qt::AscendingOrder); diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 60ecefd5..f1d2610a 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -52,8 +52,9 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); + proxy->ignoreFilesWithPath().append({ "logs", "crash-reports" }); + proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); - proxy->setFilterRegularExpression("^(?!(\\.DS_Store)|([tT]humbs\\.db)).+$"); const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); -- cgit From 81207c65027a35d37394abe3ba6e3ef43777910a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 10:52:10 +0300 Subject: Made sure the logs are ignored when collecting files Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 16 +++++++++++++--- launcher/FileIgnoreProxy.h | 9 +++++++-- launcher/ui/dialogs/ExportInstanceDialog.cpp | 8 ++++---- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 ++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index 1f6b664c..556e992c 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -262,9 +262,19 @@ bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceP QFileSystemModel* fsm = qobject_cast(sourceModel()); auto fileInfo = fsm->fileInfo(index); + return !ignoreFile(fileInfo); +} + +bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const +{ auto fileName = fileInfo.fileName(); auto path = relPath(fileInfo.absoluteFilePath()); - return !(path.startsWith("..") || // just in case ignore files outside the gameroot - std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || - std::any_of(m_ignoreFilePaths.cbegin(), m_ignoreFilePaths.cend(), [path](auto iPath) { return path == iPath; })); + return (path.startsWith("..") || // just in case ignore files outside the gameroot + std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + m_ignoreFilePaths.covers(path)); +} + +bool FileIgnoreProxy::filterFile(const QString& fileName) const +{ + return blocked.covers(fileName) || ignoreFile(QFileInfo(QDir(root), fileName)); } diff --git a/launcher/FileIgnoreProxy.h b/launcher/FileIgnoreProxy.h index dbd353e0..e01a2651 100644 --- a/launcher/FileIgnoreProxy.h +++ b/launcher/FileIgnoreProxy.h @@ -36,6 +36,7 @@ #pragma once +#include #include #include "SeparatorPrefixTree.h" @@ -66,15 +67,19 @@ class FileIgnoreProxy : public QSortFilterProxyModel { // list of file names that need to be removed completely from model inline QStringList& ignoreFilesWithName() { return m_ignoreFiles; } // list of relative paths that need to be removed completely from model - inline QStringList& ignoreFilesWithPath() { return m_ignoreFilePaths; } + inline SeparatorPrefixTree<'/'>& ignoreFilesWithPath() { return m_ignoreFilePaths; } + + bool filterFile(const QString& fileName) const; protected: bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; + bool ignoreFile(QFileInfo file) const; + private: const QString root; SeparatorPrefixTree<'/'> blocked; QStringList m_ignoreFiles; - QStringList m_ignoreFilePaths; + SeparatorPrefixTree<'/'> m_ignoreFilePaths; }; diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 8d0e05a2..cc41c394 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -40,6 +40,7 @@ #include #include #include +#include "FileIgnoreProxy.h" #include "ui_ExportInstanceDialog.h" #include @@ -49,6 +50,7 @@ #include #include #include +#include #include "Application.h" #include "SeparatorPrefixTree.h" @@ -62,7 +64,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent proxyModel = new FileIgnoreProxy(root, this); proxyModel->setSourceModel(model); auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); - proxyModel->ignoreFilesWithPath().append({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); + proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); loadPackIgnore(); @@ -137,11 +139,9 @@ bool ExportInstanceDialog::doExport() SaveIcon(m_instance); - auto & blocked = proxyModel->blockedPaths(); - using std::placeholders::_1; auto files = QFileInfoList(); if (!MMCZip::collectFileListRecursively(m_instance->instanceRoot(), nullptr, &files, - std::bind(&SeparatorPrefixTree<'/'>::covers, blocked, _1))) { + std::bind(&FileIgnoreProxy::filterFile, proxyModel, std::placeholders::_1))) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false; } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index f1d2610a..b302f7ba 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -52,7 +52,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); - proxy->ignoreFilesWithPath().append({ "logs", "crash-reports" }); + proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports" }); proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); @@ -100,7 +100,7 @@ void ExportMrPackDialog::done(int result) return; ModrinthPackExportTask task(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1)); connect(&task, &Task::failed, [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); -- cgit From 18e628e8733df2f49f20cc1989817b2272cdf151 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 12:10:00 +0300 Subject: removed extra condition Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index 556e992c..4c8c64c7 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -269,9 +269,8 @@ bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const { auto fileName = fileInfo.fileName(); auto path = relPath(fileInfo.absoluteFilePath()); - return (path.startsWith("..") || // just in case ignore files outside the gameroot - std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || - m_ignoreFilePaths.covers(path)); + return std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + m_ignoreFilePaths.covers(path); } bool FileIgnoreProxy::filterFile(const QString& fileName) const -- cgit From 3fe518ff2b9ef902ff44b2c8249bafdf61f8e5eb Mon Sep 17 00:00:00 2001 From: Finian Wright Date: Sun, 2 Jul 2023 00:35:37 -0400 Subject: Fix compiling on OpenBSD Signed-off-by: Finian Wright --- launcher/FileSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 1ea9f755..3ce8dd2c 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -102,7 +102,7 @@ namespace fs = ghc::filesystem; #include #include #include -#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) #include #include #elif defined(Q_OS_WIN) @@ -1156,7 +1156,7 @@ bool clone_file(const QString& src, const QString& dst, std::error_code& ec) return false; } -#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) if (!macos_bsd_clonefile(src_path, dst_path, ec)) { qDebug() << "failed macos_bsd_clonefile:"; @@ -1385,7 +1385,7 @@ bool linux_ficlone(const std::string& src_path, const std::string& dst_path, std return true; } -#elif defined(Q_OS_MACOS) || defined(Q_OS_OPENBSD) +#elif defined(Q_OS_MACOS) bool macos_bsd_clonefile(const std::string& src_path, const std::string& dst_path, std::error_code& ec) { -- cgit