From bd304eee947847b1d8630568933e5d95046d349c Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 13 Apr 2025 12:16:07 -0700 Subject: [PATCH 01/21] chore: use nix-shell over nix develop in .envrc (brakes less things) Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .envrc | 2 +- flake.nix | 2 ++ shell.nix | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 shell.nix diff --git a/.envrc b/.envrc index 190b5b2b3..1d11c5354 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1,2 @@ -use flake +use nix watch_file nix/*.nix diff --git a/flake.nix b/flake.nix index fd3003bc4..594a82d91 100644 --- a/flake.nix +++ b/flake.nix @@ -132,6 +132,8 @@ { default = pkgs.mkShell { + name = "prism-launcher"; + inputsFrom = [ packages'.prismlauncher-unwrapped ]; packages = with pkgs; [ diff --git a/shell.nix b/shell.nix new file mode 100644 index 000000000..21bab1009 --- /dev/null +++ b/shell.nix @@ -0,0 +1,4 @@ +(import (fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/ff81ac966bb2cae68946d5ed5fc4994f96d0ffec.tar.gz"; + sha256 = "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU="; +}) { src = ./.; }).shellNix From d5db974008f6991c1d7aaec4fb47cfddbdebf04f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 19:52:30 +0100 Subject: [PATCH 02/21] Shallow search and lazy loading for Other Logs page Signed-off-by: TheKodeToad --- launcher/BaseInstance.h | 7 +- launcher/InstancePageProvider.h | 5 +- launcher/NullInstance.h | 4 +- launcher/minecraft/MinecraftInstance.cpp | 14 +--- launcher/minecraft/MinecraftInstance.h | 4 +- launcher/ui/pages/instance/OtherLogsPage.cpp | 85 ++++++++++++++------ launcher/ui/pages/instance/OtherLogsPage.h | 13 ++- 7 files changed, 78 insertions(+), 54 deletions(-) diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 2a2b4dc4a..f93321922 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -198,15 +198,10 @@ class BaseInstance : public QObject, public std::enable_shared_from_thisgameRoot(), "screenshots"))); values.append(new InstanceSettingsPage(onesix)); - auto logMatcher = inst->getLogFileMatcher(); - if (logMatcher) { - values.append(new OtherLogsPage(inst, logMatcher)); - } + values.append(new OtherLogsPage(inst)); return values; } diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h index 3d01c9d33..93bab6c8b 100644 --- a/launcher/NullInstance.h +++ b/launcher/NullInstance.h @@ -35,6 +35,7 @@ */ #pragma once +#include #include "BaseInstance.h" #include "launch/LaunchTask.h" @@ -57,8 +58,7 @@ class NullInstance : public BaseInstance { QProcessEnvironment createEnvironment() override { return QProcessEnvironment(); } QProcessEnvironment createLaunchEnvironment() override { return QProcessEnvironment(); } QMap getVariables() override { return QMap(); } - IPathMatcher::Ptr getLogFileMatcher() override { return nullptr; } - QString getLogFileRoot() override { return instanceRoot(); } + QStringList getLogFileSearchPaths() override { return {}; } QString typeName() const override { return "Null"; } bool canExport() const override { return false; } bool canEdit() const override { return false; } diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 6f367a1bd..121b8035c 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1055,19 +1055,9 @@ MessageLevel::Enum MinecraftInstance::guessLevel(const QString& line, MessageLev return level; } -IPathMatcher::Ptr MinecraftInstance::getLogFileMatcher() +QStringList MinecraftInstance::getLogFileSearchPaths() { - auto combined = std::make_shared(); - combined->add(std::make_shared(".*\\.log(\\.[0-9]*)?(\\.gz)?$")); - combined->add(std::make_shared("crash-.*\\.txt")); - combined->add(std::make_shared("IDMap dump.*\\.txt$")); - combined->add(std::make_shared("ModLoader\\.txt(\\..*)?$")); - return combined; -} - -QString MinecraftInstance::getLogFileRoot() -{ - return gameRoot(); + return { FS::PathCombine(gameRoot(), "logs"), FS::PathCombine(gameRoot(), "crash-reports"), gameRoot() }; } QString MinecraftInstance::getStatusbarDescription() diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 5d9bb45ef..677ea5b84 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -142,9 +142,7 @@ class MinecraftInstance : public BaseInstance { /// guess log level from a line of minecraft log MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level) override; - IPathMatcher::Ptr getLogFileMatcher() override; - - QString getLogFileRoot() override; + QStringList getLogFileSearchPaths() override; QString getStatusbarDescription() override; diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index b7d10a41a..671e0ab7f 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -43,16 +43,18 @@ #include #include +#include +#include +#include +#include #include -#include "RecursiveFileSystemWatcher.h" -OtherLogsPage::OtherLogsPage(InstancePtr instance, IPathMatcher::Ptr fileFilter, QWidget* parent) +OtherLogsPage::OtherLogsPage(InstancePtr instance, QWidget* parent) : QWidget(parent) , ui(new Ui::OtherLogsPage) , m_instance(instance) - , m_path(instance->getLogFileRoot()) - , m_fileFilter(fileFilter) - , m_watcher(new RecursiveFileSystemWatcher(this)) + , m_basePath(instance->gameRoot()) + , m_logSearchPaths(instance->getLogFileSearchPaths()) , m_model(new LogModel(this)) { ui->setupUi(this); @@ -78,11 +80,7 @@ OtherLogsPage::OtherLogsPage(InstancePtr instance, IPathMatcher::Ptr fileFilter, m_model->setOverflowMessage(tr("Cannot display this log since the log length surpassed %1 lines.").arg(m_model->getMaxLines())); m_proxy->setSourceModel(m_model.get()); - m_watcher->setMatcher(fileFilter); - m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path)); - - connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, &OtherLogsPage::populateSelectLogBox); - populateSelectLogBox(); + connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &OtherLogsPage::populateSelectLogBox); auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this); connect(findShortcut, &QShortcut::activated, this, &OtherLogsPage::findActivated); @@ -108,22 +106,39 @@ void OtherLogsPage::retranslate() void OtherLogsPage::openedImpl() { - m_watcher->enable(); + const QStringList failedPaths = m_watcher.addPaths(m_logSearchPaths); + + for (const QString& path : m_logSearchPaths) { + if (failedPaths.contains(path)) + qDebug() << "Failed to start watching" << path; + else + qDebug() << "Started watching" << path; + } + + populateSelectLogBox(); } + void OtherLogsPage::closedImpl() { - m_watcher->disable(); + const QStringList failedPaths = m_watcher.removePaths(m_logSearchPaths); + + for (const QString& path : m_logSearchPaths) { + if (failedPaths.contains(path)) + qDebug() << "Failed to stop watching" << path; + else + qDebug() << "Stopped watching" << path; + } } void OtherLogsPage::populateSelectLogBox() { + QString prevCurrentFile = m_currentFile; + ui->selectLogBox->clear(); - ui->selectLogBox->addItems(m_watcher->files()); - if (m_currentFile.isEmpty()) { - setControlsEnabled(false); - ui->selectLogBox->setCurrentIndex(-1); - } else { - const int index = ui->selectLogBox->findText(m_currentFile); + ui->selectLogBox->addItems(getPaths()); + + if (!prevCurrentFile.isEmpty()) { + const int index = ui->selectLogBox->findText(prevCurrentFile); if (index != -1) { ui->selectLogBox->setCurrentIndex(index); setControlsEnabled(true); @@ -140,7 +155,7 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) file = ui->selectLogBox->itemText(index); } - if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file))) { + if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_basePath, file))) { m_currentFile = QString(); ui->text->clear(); setControlsEnabled(false); @@ -199,7 +214,7 @@ void OtherLogsPage::on_btnReload_clicked() setControlsEnabled(false); return; } - QFile file(FS::PathCombine(m_path, m_currentFile)); + QFile file(FS::PathCombine(m_basePath, m_currentFile)); if (!file.open(QFile::ReadOnly)) { setControlsEnabled(false); ui->btnReload->setEnabled(true); // allow reload @@ -284,7 +299,7 @@ void OtherLogsPage::on_btnDelete_clicked() QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) { return; } - QFile file(FS::PathCombine(m_path, m_currentFile)); + QFile file(FS::PathCombine(m_basePath, m_currentFile)); if (FS::trash(file.fileName())) { return; @@ -297,7 +312,7 @@ void OtherLogsPage::on_btnDelete_clicked() void OtherLogsPage::on_btnClean_clicked() { - auto toDelete = m_watcher->files(); + auto toDelete = getPaths(); if (toDelete.isEmpty()) { return; } @@ -320,7 +335,9 @@ void OtherLogsPage::on_btnClean_clicked() } QStringList failed; for (auto item : toDelete) { - QFile file(FS::PathCombine(m_path, item)); + QString absolutePath = FS::PathCombine(m_basePath, item); + QFile file(absolutePath); + qDebug() << "Deleting log" << absolutePath; if (FS::trash(file.fileName())) { continue; } @@ -374,6 +391,28 @@ void OtherLogsPage::setControlsEnabled(const bool enabled) ui->btnClean->setEnabled(enabled); } +QStringList OtherLogsPage::getPaths() +{ + QDir baseDir(m_basePath); + + QStringList result; + + for (QString searchPath : m_logSearchPaths) { + QDirIterator iterator(searchPath, QDir::Files | QDir::Readable); + + while (iterator.hasNext()) { + const QString name = iterator.next(); + + if (!name.endsWith(".log") && !name.endsWith(".log.gz")) + continue; + + result.append(baseDir.relativeFilePath(name)); + } + } + + return result; +} + void OtherLogsPage::on_findButton_clicked() { auto modifiers = QApplication::keyboardModifiers(); diff --git a/launcher/ui/pages/instance/OtherLogsPage.h b/launcher/ui/pages/instance/OtherLogsPage.h index 9394ab9b8..fedb2506c 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.h +++ b/launcher/ui/pages/instance/OtherLogsPage.h @@ -39,6 +39,8 @@ #include #include +#include +#include #include "LogPage.h" #include "ui/pages/BasePage.h" @@ -52,7 +54,7 @@ class OtherLogsPage : public QWidget, public BasePage { Q_OBJECT public: - explicit OtherLogsPage(InstancePtr instance, IPathMatcher::Ptr fileFilter, QWidget* parent = 0); + explicit OtherLogsPage(InstancePtr instance, QWidget* parent = 0); ~OtherLogsPage(); QString id() const override { return "logs"; } @@ -85,13 +87,16 @@ class OtherLogsPage : public QWidget, public BasePage { private: void setControlsEnabled(bool enabled); + QStringList getPaths(); + private: Ui::OtherLogsPage* ui; InstancePtr m_instance; - QString m_path; + /** Path to display log paths relative to. */ + QString m_basePath; + QStringList m_logSearchPaths; QString m_currentFile; - IPathMatcher::Ptr m_fileFilter; - RecursiveFileSystemWatcher* m_watcher; + QFileSystemWatcher m_watcher; LogFormatProxyModel* m_proxy; shared_qobject_ptr m_model; From 01efd5b5d8b7f37b2e227cc8c448a78cccd84a24 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 21:24:25 +0100 Subject: [PATCH 03/21] Fix double load (again lol) Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/OtherLogsPage.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index 671e0ab7f..ec597497d 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -132,20 +132,25 @@ void OtherLogsPage::closedImpl() void OtherLogsPage::populateSelectLogBox() { - QString prevCurrentFile = m_currentFile; + const QString prevCurrentFile = m_currentFile; + ui->selectLogBox->blockSignals(true); ui->selectLogBox->clear(); ui->selectLogBox->addItems(getPaths()); + ui->selectLogBox->blockSignals(false); if (!prevCurrentFile.isEmpty()) { const int index = ui->selectLogBox->findText(prevCurrentFile); if (index != -1) { ui->selectLogBox->setCurrentIndex(index); setControlsEnabled(true); + return; } else { setControlsEnabled(false); } } + + on_selectLogBox_currentIndexChanged(ui->selectLogBox->currentIndex()); } void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) From 96a4b78e2edcc5225d4f831e6ef5c534e2c14d46 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 23:45:46 +0100 Subject: [PATCH 04/21] Remove accidental return Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/OtherLogsPage.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index ec597497d..63dcf5cff 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -43,11 +43,11 @@ #include #include -#include #include -#include -#include +#include +#include #include +#include OtherLogsPage::OtherLogsPage(InstancePtr instance, QWidget* parent) : QWidget(parent) @@ -144,7 +144,6 @@ void OtherLogsPage::populateSelectLogBox() if (index != -1) { ui->selectLogBox->setCurrentIndex(index); setControlsEnabled(true); - return; } else { setControlsEnabled(false); } From 8ea5eac29cd9340d9c2d1da6dd8e35355fdbce59 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 23:48:56 +0100 Subject: [PATCH 05/21] Make requested changes Signed-off-by: TheKodeToad --- launcher/NullInstance.h | 1 - launcher/ui/pages/instance/OtherLogsPage.h | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h index 93bab6c8b..e603b1634 100644 --- a/launcher/NullInstance.h +++ b/launcher/NullInstance.h @@ -35,7 +35,6 @@ */ #pragma once -#include #include "BaseInstance.h" #include "launch/LaunchTask.h" diff --git a/launcher/ui/pages/instance/OtherLogsPage.h b/launcher/ui/pages/instance/OtherLogsPage.h index fedb2506c..70eb145fb 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.h +++ b/launcher/ui/pages/instance/OtherLogsPage.h @@ -39,8 +39,7 @@ #include #include -#include -#include +#include #include "LogPage.h" #include "ui/pages/BasePage.h" From 19b241fd31d89cd159ab075475ab1270eb8b2799 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 23:59:35 +0100 Subject: [PATCH 06/21] Include txt too Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/OtherLogsPage.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index 63dcf5cff..4e401aa9c 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -404,13 +404,17 @@ QStringList OtherLogsPage::getPaths() for (QString searchPath : m_logSearchPaths) { QDirIterator iterator(searchPath, QDir::Files | QDir::Readable); + const bool isRoot = searchPath == m_basePath; + while (iterator.hasNext()) { const QString name = iterator.next(); - if (!name.endsWith(".log") && !name.endsWith(".log.gz")) + QString relativePath = baseDir.relativeFilePath(name); + + if (!(name.endsWith(".log") || name.endsWith(".log.gz") || (!isRoot && name.endsWith(".txt")))) continue; - result.append(baseDir.relativeFilePath(name)); + result.append(relativePath); } } From 0aa3341d5827c4a1529323cb682592891641488d Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 19 Apr 2025 00:04:30 +0100 Subject: [PATCH 07/21] Fix other weird import Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/OtherLogsPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index 4e401aa9c..caacea83e 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -43,8 +43,8 @@ #include #include -#include #include +#include #include #include #include From 92ba13cfdb839ece93cea2429193a8c6c3982cd8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 19 Apr 2025 00:12:38 +0100 Subject: [PATCH 08/21] Fix catastrophic regex mistake Signed-off-by: TheKodeToad --- launcher/minecraft/MinecraftInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index ec136ede0..638979578 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1011,7 +1011,7 @@ MessageLevel::Enum MinecraftInstance::guessLevel(const QString& line, MessageLev // NOTE: this diverges from the real regexp. no unicode, the first section is + instead of * static const QRegularExpression JAVA_EXCEPTION( - R"(Exception in thread|...\d more$|(\s+at |Caused by: )([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*)|([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*(Exception|Error|Throwable)"); + R"((Exception in thread|...\d more$|(\s+at |Caused by: )([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*)|([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*(Exception|Error|Throwable))"); if (line.contains(JAVA_EXCEPTION)) return MessageLevel::Error; From 111cdc240ef0232c155a9dbdd0bd87a077fcdf86 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 19 Apr 2025 09:34:12 +0100 Subject: [PATCH 09/21] Disable auto-reload of files Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/OtherLogsPage.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index caacea83e..f457195d8 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -142,8 +142,11 @@ void OtherLogsPage::populateSelectLogBox() if (!prevCurrentFile.isEmpty()) { const int index = ui->selectLogBox->findText(prevCurrentFile); if (index != -1) { + ui->selectLogBox->blockSignals(true); ui->selectLogBox->setCurrentIndex(index); + ui->selectLogBox->blockSignals(false); setControlsEnabled(true); + return; } else { setControlsEnabled(false); } From 3fd5557f89de1269f024b9bd146ff019170795ee Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 20 Apr 2025 00:28:02 +0000 Subject: [PATCH 10/21] chore(nix): update lockfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'libnbtplusplus': 'github:PrismLauncher/libnbtplusplus/23b955121b8217c1c348a9ed2483167a6f3ff4ad?narHash=sha256-yy0q%2Bbky80LtK1GWzz7qpM%2BaAGrOqLuewbid8WT1ilk%3D' (2023-11-06) → 'github:PrismLauncher/libnbtplusplus/531449ba1c930c98e0bcf5d332b237a8566f9d78?narHash=sha256-qhmjaRkt%2BO7A%2Bgu6HjUkl7QzOEb4r8y8vWZMG2R/C6o%3D' (2025-04-16) • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/2631b0b7abcea6e640ce31cd78ea58910d31e650?narHash=sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR%2BXhw3kr/3Xd0GPTM%3D' (2025-04-12) → 'github:NixOS/nixpkgs/b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef?narHash=sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU%3D' (2025-04-17) • Updated input 'qt-qrcodegenerator': 'github:nayuki/QR-Code-generator/f40366c40d8d1956081f7ec643d240c02a81df52?narHash=sha256-5%2BiYwsbX8wjKZPCy7ENj5HCYgOqzeSNLs/YrX2Vc7CQ%3D' (2024-11-18) → 'github:nayuki/QR-Code-generator/2c9044de6b049ca25cb3cd1649ed7e27aa055138?narHash=sha256-6SugPt0lp1Gz7nV23FLmsmpfzgFItkSw7jpGftsDPWc%3D' (2025-01-23) --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index 070d069e5..07fa5117a 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "libnbtplusplus": { "flake": false, "locked": { - "lastModified": 1699286814, - "narHash": "sha256-yy0q+bky80LtK1GWzz7qpM+aAGrOqLuewbid8WT1ilk=", + "lastModified": 1744811532, + "narHash": "sha256-qhmjaRkt+O7A+gu6HjUkl7QzOEb4r8y8vWZMG2R/C6o=", "owner": "PrismLauncher", "repo": "libnbtplusplus", - "rev": "23b955121b8217c1c348a9ed2483167a6f3ff4ad", + "rev": "531449ba1c930c98e0bcf5d332b237a8566f9d78", "type": "github" }, "original": { @@ -18,11 +18,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1744463964, - "narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=", + "lastModified": 1744932701, + "narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650", + "rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", "type": "github" }, "original": { @@ -35,11 +35,11 @@ "qt-qrcodegenerator": { "flake": false, "locked": { - "lastModified": 1731907326, - "narHash": "sha256-5+iYwsbX8wjKZPCy7ENj5HCYgOqzeSNLs/YrX2Vc7CQ=", + "lastModified": 1737616857, + "narHash": "sha256-6SugPt0lp1Gz7nV23FLmsmpfzgFItkSw7jpGftsDPWc=", "owner": "nayuki", "repo": "QR-Code-generator", - "rev": "f40366c40d8d1956081f7ec643d240c02a81df52", + "rev": "2c9044de6b049ca25cb3cd1649ed7e27aa055138", "type": "github" }, "original": { From e03870d3f2455d5db7ba701187af41abcda66d73 Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Sun, 20 Apr 2025 16:44:47 -0400 Subject: [PATCH 11/21] ci(get-merge-commit): init Signed-off-by: Seth Flynn --- .github/actions/get-merge-commit.yml | 103 +++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 .github/actions/get-merge-commit.yml diff --git a/.github/actions/get-merge-commit.yml b/.github/actions/get-merge-commit.yml new file mode 100644 index 000000000..8c67fdfc9 --- /dev/null +++ b/.github/actions/get-merge-commit.yml @@ -0,0 +1,103 @@ +# This file incorporates work covered by the following copyright and +# permission notice +# +# Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +name: Get merge commit +description: Get a merge commit of a given pull request + +inputs: + repository: + description: Repository containing the pull request + required: false + pull-request-id: + description: ID of a pull request + required: true + +outputs: + merge-commit-sha: + description: Git SHA of a merge commit + value: ${{ steps.query.outputs.merge-commit-sha }} + +runs: + using: composite + + steps: + - name: Wait for GitHub to report merge commit + id: query + shell: bash + env: + GITHUB_REPO: ${{ inputs.repository || github.repository }} + PR_ID: ${{ inputs.pull-request-id }} + # https://github.com/NixOS/nixpkgs/blob/8f77f3600f1ee775b85dc2c72fd842768e486ec9/ci/get-merge-commit.sh + run: | + set -euo pipefail + + log() { + echo "$@" >&2 + } + + # Retry the API query this many times + retryCount=5 + # Start with 5 seconds, but double every retry + retryInterval=5 + + while true; do + log "Checking whether the pull request can be merged" + prInfo=$(gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/$GITHUB_REPO/pulls/$PR_ID") + + # Non-open PRs won't have their mergeability computed no matter what + state=$(jq -r .state <<<"$prInfo") + if [[ "$state" != open ]]; then + log "PR is not open anymore" + exit 1 + fi + + mergeable=$(jq -r .mergeable <<<"$prInfo") + if [[ "$mergeable" == "null" ]]; then + if ((retryCount == 0)); then + log "Not retrying anymore. It's likely that GitHub is having internal issues: check https://www.githubstatus.com/" + exit 3 + else + ((retryCount -= 1)) || true + + # null indicates that GitHub is still computing whether it's mergeable + # Wait a couple seconds before trying again + log "GitHub is still computing whether this PR can be merged, waiting $retryInterval seconds before trying again ($retryCount retries left)" + sleep "$retryInterval" + + ((retryInterval *= 2)) || true + fi + else + break + fi + done + + if [[ "$mergeable" == "true" ]]; then + echo "merge-commit-sha=$(jq -r .merge_commit_sha <<<"$prInfo")" >> "$GITHUB_OUTPUT" + else + echo "# 🚨 The PR has a merge conflict!" >>> "$GITHUB_STEP_SUMMARY" + exit 2 + fi From f2a601f8153f974c73ad547198650de83889bd9d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 16:58:13 +0000 Subject: [PATCH 12/21] chore(deps): update determinatesystems/nix-installer-action action to v17 --- .github/workflows/nix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index fea0df6ce..765aa4ca8 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -65,7 +65,7 @@ jobs: uses: actions/checkout@v4 - name: Install Nix - uses: DeterminateSystems/nix-installer-action@v16 + uses: DeterminateSystems/nix-installer-action@v17 with: determinate: ${{ env.USE_DETERMINATE }} From 83ebb5984b47dbf393d4e2ad63bb6d9024c13f26 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 25 Apr 2025 19:18:28 -0700 Subject: [PATCH 13/21] fix: nullptr access style can't always be created Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/themes/SystemTheme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index 7fba08026..c9b2e5cfd 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -54,7 +54,7 @@ SystemTheme::SystemTheme(const QString& styleName, const QPalette& defaultPalett m_colorPalette = defaultPalette; } else { auto style = QStyleFactory::create(styleName); - m_colorPalette = style->standardPalette(); + m_colorPalette = style != nullptr ? style->standardPalette() : defaultPalette; delete style; } } From abe18fb144f707b57ee56dda996ca034c47a3bd6 Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Sun, 20 Apr 2025 16:54:44 -0400 Subject: [PATCH 14/21] ci(nix): checkout merge commit of pull request Signed-off-by: Seth Flynn --- .github/workflows/nix.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index fea0df6ce..816e2a7aa 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -61,8 +61,17 @@ jobs: id-token: write steps: + - name: Get merge commit + if: ${{ github.event_name == 'pull_request_target' }} + id: merge-commit + uses: ./.github/actions/get-merge-commit.yml + with: + pull-request-id: ${{ github.event.pull_request.id }} + - name: Checkout repository uses: actions/checkout@v4 + with: + ref: ${{ steps.merge-commit.outputs.merge-commit-sha || github.sha }} - name: Install Nix uses: DeterminateSystems/nix-installer-action@v16 From a702d06cd85737728a1ec15538127e4c418bde8e Mon Sep 17 00:00:00 2001 From: Xander Date: Sat, 26 Apr 2025 21:41:14 +0100 Subject: [PATCH 15/21] Pass mainclass and gameargs to the main game via system properties Signed-off-by: Xander --- .../launcher/impl/StandardLauncher.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java index 084fbc849..af9b41533 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java @@ -97,6 +97,18 @@ public final class StandardLauncher extends AbstractLauncher { gameArgs.add(worldName); } + StringBuilder joinedGameArgs = new StringBuilder(); + for (String gameArg : gameArgs) { + if (joinedGameArgs.length() > 0) { + joinedGameArgs.append(" "); + } + joinedGameArgs.append(gameArg); + } + + // pass the real main class and game arguments in so mods can access them + System.setProperty("org.prismlauncher.launch.mainclass", mainClassName); + System.setProperty("org.prismlauncher.launch.gameargs", joinedGameArgs.toString()); + // find and invoke the main method MethodHandle method = ReflectionUtils.findMainMethod(mainClassName); method.invokeExact(gameArgs.toArray(new String[0])); From a92e114236b54a23561fa4071cc1ec8486b43119 Mon Sep 17 00:00:00 2001 From: Xander Date: Sat, 26 Apr 2025 21:57:28 +0100 Subject: [PATCH 16/21] Use \u001F instead of a space as a delimeter for game args Signed-off-by: Xander --- .../org/prismlauncher/launcher/impl/StandardLauncher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java index af9b41533..96a809dfe 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java @@ -100,7 +100,7 @@ public final class StandardLauncher extends AbstractLauncher { StringBuilder joinedGameArgs = new StringBuilder(); for (String gameArg : gameArgs) { if (joinedGameArgs.length() > 0) { - joinedGameArgs.append(" "); + joinedGameArgs.append('\u001F'); // unit separator, designed for this purpose } joinedGameArgs.append(gameArg); } From 02106ab29a8761e44aab5c8e73fd8842c4802b32 Mon Sep 17 00:00:00 2001 From: Xander Date: Sat, 26 Apr 2025 23:42:22 +0100 Subject: [PATCH 17/21] comment on property about delimeter Signed-off-by: Xander --- .../org/prismlauncher/launcher/impl/StandardLauncher.java | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java index 96a809dfe..968499ff6 100644 --- a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java +++ b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java @@ -107,6 +107,7 @@ public final class StandardLauncher extends AbstractLauncher { // pass the real main class and game arguments in so mods can access them System.setProperty("org.prismlauncher.launch.mainclass", mainClassName); + // unit separator ('\u001F') delimited list of game args System.setProperty("org.prismlauncher.launch.gameargs", joinedGameArgs.toString()); // find and invoke the main method From 47cb58d326f5177c7337b531a8aec75b07edf1d7 Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Sun, 27 Apr 2025 07:16:20 -0400 Subject: [PATCH 18/21] ci(nix): fix get-merge-commit action call Signed-off-by: Seth Flynn --- .../{get-merge-commit.yml => get-merge-commit/action.yml} | 0 .github/workflows/nix.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/actions/{get-merge-commit.yml => get-merge-commit/action.yml} (100%) diff --git a/.github/actions/get-merge-commit.yml b/.github/actions/get-merge-commit/action.yml similarity index 100% rename from .github/actions/get-merge-commit.yml rename to .github/actions/get-merge-commit/action.yml diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 816e2a7aa..03d5f2089 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -64,7 +64,7 @@ jobs: - name: Get merge commit if: ${{ github.event_name == 'pull_request_target' }} id: merge-commit - uses: ./.github/actions/get-merge-commit.yml + uses: PrismLauncher/PrismLauncher/.github/actions/get-merge-commit@develop with: pull-request-id: ${{ github.event.pull_request.id }} From 3b7b9fa03c330aa8844b380be614dce9fde90097 Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Sun, 27 Apr 2025 06:59:19 -0400 Subject: [PATCH 19/21] ci: better filter workflow runs Signed-off-by: Seth Flynn --- .github/workflows/codeql.yml | 35 ++++++++++++++++++++- .github/workflows/trigger_builds.yml | 46 +++++++++++++++++++--------- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e3243097d..a5ac537f1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,6 +1,39 @@ name: "CodeQL Code Scanning" -on: [push, pull_request, workflow_dispatch] +on: + push: + # NOTE: `!` doesn't work with `paths-ignore` :( + # So we a catch-all glob instead + # https://github.com/orgs/community/discussions/25369#discussioncomment-3247674 + paths: + - "**" + - "!.github/**" + - ".github/workflows/codeql.yml" + - "!flatpak/" + - "!nix/" + - "!scripts/" + + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" + pull_request: + # See above + paths: + - "**" + - "!.github/**" + - ".github/workflows/codeql.yml" + - "!flatpak/" + - "!nix/" + - "!scripts/" + + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" + workflow_dispatch: jobs: CodeQL: diff --git a/.github/workflows/trigger_builds.yml b/.github/workflows/trigger_builds.yml index 9efafc8cc..e4c90ef0b 100644 --- a/.github/workflows/trigger_builds.yml +++ b/.github/workflows/trigger_builds.yml @@ -4,21 +4,39 @@ on: push: branches-ignore: - "renovate/**" - paths-ignore: - - "**.md" - - "**/LICENSE" - - "flake.lock" - - "packages/**" - - ".github/ISSUE_TEMPLATE/**" - - ".markdownlint**" + # NOTE: `!` doesn't work with `paths-ignore` :( + # So we a catch-all glob instead + # https://github.com/orgs/community/discussions/25369#discussioncomment-3247674 + paths: + - "**" + - "!.github/**" + - ".github/workflows/build.yml" + - ".github/workflows/trigger_builds.yml" + - "!flatpak/" + - "!nix/" + - "!scripts/" + + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" pull_request: - paths-ignore: - - "**.md" - - "**/LICENSE" - - "flake.lock" - - "packages/**" - - ".github/ISSUE_TEMPLATE/**" - - ".markdownlint**" + # See above + paths: + - "**" + - "!.github/**" + - ".github/workflows/build.yml" + - ".github/workflows/trigger_builds.yml" + - "!flatpak/" + - "!nix/" + - "!scripts/" + + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" workflow_dispatch: jobs: From 57a2ef1aed5a673f7772005e0dc4c4aa100e3c4d Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Sun, 27 Apr 2025 07:00:26 -0400 Subject: [PATCH 20/21] ci: fix improper paths-ignore usage Signed-off-by: Seth Flynn --- .github/workflows/flatpak.yml | 40 +++++++++++++++++++++---------- .github/workflows/nix.yml | 44 ++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 41cc2a51d..8caba46fa 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -2,22 +2,38 @@ name: Flatpak on: push: - paths-ignore: - - "**.md" - - "**/LICENSE" - - ".github/ISSUE_TEMPLATE/**" - - ".markdownlint**" - - "nix/**" # We don't do anything with these artifacts on releases. They go to Flathub tags-ignore: - "*" + # NOTE: `!` doesn't work with `paths-ignore` :( + # So we a catch-all glob instead + # https://github.com/orgs/community/discussions/25369#discussioncomment-3247674 + paths: + - "**" + - "!.github/**" + - ".github/workflows/flatpak.yml" + - "!nix/" + - "!scripts/" + + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" pull_request: - paths-ignore: - - "**.md" - - "**/LICENSE" - - ".github/ISSUE_TEMPLATE/**" - - ".markdownlint**" - - "nix/**" + # See above + paths: + - "**" + - "!.github/**" + - ".github/workflows/flatpak.yml" + - "!nix/" + - "!scripts/" + + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" workflow_dispatch: permissions: diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 816e2a7aa..b968062c9 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -4,28 +4,34 @@ on: push: tags: - "*" - paths-ignore: - - ".github/**" - - "!.github/workflows/nix.yml" - - "flatpak/" - - "scripts/" + # NOTE: `!` doesn't work with `paths-ignore` :( + # So we a catch-all glob instead + # https://github.com/orgs/community/discussions/25369#discussioncomment-3247674 + paths: + - "**" + - "!.github/**" + - ".github/workflows/nix.yml" + - "!flatpak/" + - "!scripts/" - - ".git*" - - ".envrc" - - "**.md" - - "!COPYING.md" - - "renovate.json" + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" pull_request_target: - paths-ignore: - - ".github/**" - - "flatpak/" - - "scripts/" + paths: + - "**" + - "!.github/**" + - ".github/workflows/nix.yml" + - "!flatpak/" + - "!scripts/" - - ".git*" - - ".envrc" - - "**.md" - - "!COPYING.md" - - "renovate.json" + - "!.git*" + - "!.envrc" + - "!**.md" + - "COPYING.md" + - "!renovate.json" workflow_dispatch: permissions: From 20626e6606ba07317fb4283f0814ecef4e1ea136 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 28 Apr 2025 10:28:57 +0100 Subject: [PATCH 21/21] Fix log sorting Signed-off-by: TheKodeToad --- launcher/minecraft/MinecraftInstance.cpp | 2 +- launcher/ui/pages/instance/OtherLogsPage.cpp | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 121b8035c..1009d7c42 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1057,7 +1057,7 @@ MessageLevel::Enum MinecraftInstance::guessLevel(const QString& line, MessageLev QStringList MinecraftInstance::getLogFileSearchPaths() { - return { FS::PathCombine(gameRoot(), "logs"), FS::PathCombine(gameRoot(), "crash-reports"), gameRoot() }; + return { FS::PathCombine(gameRoot(), "crash-reports"), FS::PathCombine(gameRoot(), "logs"), gameRoot() }; } QString MinecraftInstance::getStatusbarDescription() diff --git a/launcher/ui/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index f457195d8..80a9c0fdc 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -146,6 +146,7 @@ void OtherLogsPage::populateSelectLogBox() ui->selectLogBox->setCurrentIndex(index); ui->selectLogBox->blockSignals(false); setControlsEnabled(true); + // don't refresh file return; } else { setControlsEnabled(false); @@ -405,20 +406,17 @@ QStringList OtherLogsPage::getPaths() QStringList result; for (QString searchPath : m_logSearchPaths) { - QDirIterator iterator(searchPath, QDir::Files | QDir::Readable); + QDir searchDir(searchPath); - const bool isRoot = searchPath == m_basePath; + QStringList filters{ "*.log", "*.log.gz" }; - while (iterator.hasNext()) { - const QString name = iterator.next(); + if (searchPath != m_basePath) + filters.append("*.txt"); - QString relativePath = baseDir.relativeFilePath(name); + QStringList entries = searchDir.entryList(filters, QDir::Files | QDir::Readable, QDir::SortFlag::Time); - if (!(name.endsWith(".log") || name.endsWith(".log.gz") || (!isRoot && name.endsWith(".txt")))) - continue; - - result.append(relativePath); - } + for (const QString& name : entries) + result.append(baseDir.relativeFilePath(searchDir.filePath(name))); } return result;