From d5db974008f6991c1d7aaec4fb47cfddbdebf04f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 19:52:30 +0100 Subject: [PATCH 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 111cdc240ef0232c155a9dbdd0bd87a077fcdf86 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 19 Apr 2025 09:34:12 +0100 Subject: [PATCH 7/8] 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 20626e6606ba07317fb4283f0814ecef4e1ea136 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 28 Apr 2025 10:28:57 +0100 Subject: [PATCH 8/8] 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;