diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-05-31 13:20:21 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-05-31 13:27:20 -0500 |
| commit | 51419a3aa4f037869e2c9dd52377277bc4695010 (patch) | |
| tree | 21798001a460f24638911a5ccf98bfff53e2b50e /src | |
| parent | 5c4603f12a727625ece236fc43846330fad3b9f2 (diff) | |
fix updater restart and log cleanup
Diffstat (limited to 'src')
| -rw-r--r-- | src/src/mainwindow.cpp | 2 | ||||
| -rw-r--r-- | src/src/organizercore.cpp | 91 | ||||
| -rw-r--r-- | src/src/organizercore.h | 12 | ||||
| -rw-r--r-- | src/src/settingsdialogupdates.cpp | 41 |
4 files changed, 130 insertions, 16 deletions
diff --git a/src/src/mainwindow.cpp b/src/src/mainwindow.cpp index f8f7e97..ca92499 100644 --- a/src/src/mainwindow.cpp +++ b/src/src/mainwindow.cpp @@ -1457,6 +1457,8 @@ void MainWindow::paintEvent(QPaintEvent* event) void MainWindow::onBeforeClose() { storeSettings(); + m_ArchiveListWriter.writeImmediately(true); + m_OrganizerCore.pluginsWriter().writeImmediately(true); } void MainWindow::closeEvent(QCloseEvent* event) diff --git a/src/src/organizercore.cpp b/src/src/organizercore.cpp index d8e6da4..3721cf4 100644 --- a/src/src/organizercore.cpp +++ b/src/src/organizercore.cpp @@ -52,9 +52,12 @@ #include <thread> #include <QApplication> #include <QCoreApplication> +#include <QDateTime> #include <QDialog> #include <QDialogButtonBox> +#include <QDirIterator> #include <QFile> +#include <QFileInfo> #include <QMessageBox> #include <QNetworkInterface> #include <QProcess> @@ -91,6 +94,41 @@ using namespace MOBase; static env::CoreDumpTypes g_coreDumpType = env::CoreDumpTypes::Mini; +namespace +{ + +QString uniqueFilePath(const QDir& dir, const QString& fileName) +{ + QString candidate = dir.filePath(fileName); + if (!QFileInfo::exists(candidate)) { + return candidate; + } + + const QFileInfo info(fileName); + const QString base = info.completeBaseName(); + const QString suffix = info.suffix(); + const QString timestamp = + QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_hhmmss")); + + for (int i = 1; i < 1000; ++i) { + const QString numbered = + suffix.isEmpty() + ? QStringLiteral("%1_%2_%3").arg(base, timestamp).arg(i) + : QStringLiteral("%1_%2_%3.%4").arg(base, timestamp).arg(i).arg(suffix); + candidate = dir.filePath(numbered); + if (!QFileInfo::exists(candidate)) { + return candidate; + } + } + + return dir.filePath( + suffix.isEmpty() + ? QStringLiteral("%1_%2").arg(base, timestamp) + : QStringLiteral("%1_%2.%3").arg(base, timestamp, suffix)); +} + +} // namespace + template <typename InputIterator> QStringList toStringList(InputIterator current, InputIterator end) { @@ -756,6 +794,58 @@ void OrganizerCore::prepareVFS() void OrganizerCore::unmountVFS() { m_USVFS.unmount(); + movePGPatcherLogsToLogsFolder(); +} + +void OrganizerCore::movePGPatcherLogsToLogsFolder() +{ + const QString dataPath = qApp->property("dataPath").toString(); + if (dataPath.isEmpty()) { + log::warn("PGPatcher log cleanup skipped: dataPath is not set"); + return; + } + + QDir logsDir(QDir(dataPath).filePath(QString::fromStdWString(AppConfig::logPath()))); + if (!logsDir.exists() && !QDir().mkpath(logsDir.absolutePath())) { + log::warn("PGPatcher log cleanup skipped: failed to create '{}'", + logsDir.absolutePath()); + return; + } + + const QStringList roots = { + QDir::fromNativeSeparators(m_Settings.paths().overwrite()), + QDir::fromNativeSeparators(m_Settings.paths().mods()), + }; + + int moved = 0; + for (const QString& root : roots) { + if (root.isEmpty() || !QDir(root).exists()) { + continue; + } + + QDirIterator it(root, QStringList{QStringLiteral("PGPatcher.log")}, + QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + while (it.hasNext()) { + const QString source = it.next(); + const QString destination = + uniqueFilePath(logsDir, QFileInfo(source).fileName()); + + if (QFile::rename(source, destination) || + (QFile::copy(source, destination) && QFile::remove(source))) { + ++moved; + log::info("Moved PGPatcher log '{}' -> '{}'", source, destination); + } else { + log::warn("Failed to move PGPatcher log '{}' -> '{}'", source, + destination); + } + } + } + + if (moved > 0) { + log::info("PGPatcher log cleanup moved {} file(s) to '{}'", moved, + logsDir.absolutePath()); + } } void OrganizerCore::trackOverwriteMove(const QString& relativePath, @@ -2770,6 +2860,7 @@ void OrganizerCore::afterRun(const QFileInfo& binary, DWORD exitCode) // and tears down the FUSE session. This mirrors Windows behaviour where // USVFS is only active while a hooked process is running. m_USVFS.unmount(); + movePGPatcherLogsToLogsFolder(); // Restore write permissions on the game directory. In rare cases // (crashes, unclean Wine shutdown) file permissions can be changed to diff --git a/src/src/organizercore.h b/src/src/organizercore.h index 494e835..973ee64 100644 --- a/src/src/organizercore.h +++ b/src/src/organizercore.h @@ -534,11 +534,13 @@ private: const QString& customOverwrite);
std::vector<Mapping> fileMapping(const QString& dataPath, const QString& relPath,
- const MOShared::DirectoryEntry* base,
- const MOShared::DirectoryEntry* directoryEntry,
- int createDestination);
-
-private slots:
+ const MOShared::DirectoryEntry* base, + const MOShared::DirectoryEntry* directoryEntry, + int createDestination); + + void movePGPatcherLogsToLogsFolder(); + +private slots: void onDirectoryRefreshed();
void downloadRequested(QNetworkReply* reply, QString gameName, int modID,
diff --git a/src/src/settingsdialogupdates.cpp b/src/src/settingsdialogupdates.cpp index 8f76bae..57f5957 100644 --- a/src/src/settingsdialogupdates.cpp +++ b/src/src/settingsdialogupdates.cpp @@ -2,6 +2,7 @@ #include "fluorineupdater.h" #include "settings.h" +#include "shared/util.h" #include "ui_settingsdialog.h" #include <fluorine_build_info.h> @@ -10,7 +11,6 @@ #include <QApplication> #include <QCheckBox> #include <QComboBox> -#include <QCoreApplication> #include <QDir> #include <QFile> #include <QFileInfo> @@ -36,6 +36,17 @@ #include <algorithm> +namespace +{ + +bool isLauncherFile(const QString& path) +{ + const QFileInfo info(path); + return info.isFile(); +} + +} // namespace + UpdatesSettingsTab::UpdatesSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { @@ -324,22 +335,29 @@ void UpdatesSettingsTab::onInstall() QDir extract(extractDir); QString newLauncher = extract.absoluteFilePath(QStringLiteral("fluorine-manager")); - if (!QFileInfo::exists(newLauncher)) { + if (!isLauncherFile(newLauncher)) { const QStringList tops = extract.entryList( QDir::Dirs | QDir::NoDotAndDotDot); for (const QString& top : tops) { const QString candidate = extract.absoluteFilePath( top + QStringLiteral("/fluorine-manager")); - if (QFileInfo::exists(candidate)) { + if (isLauncherFile(candidate)) { newLauncher = candidate; break; } } } - if (!QFileInfo::exists(newLauncher)) { + if (isLauncherFile(newLauncher)) { + QFile::setPermissions( + newLauncher, + QFile::permissions(newLauncher) | QFile::ExeOwner | + QFile::ExeGroup | QFile::ExeOther); + } + if (!isLauncherFile(newLauncher) || + !QFileInfo(newLauncher).isExecutable()) { m_statusLabel->setText( tr("<i>Install failed:</i> launcher not found in " - "extracted archive")); + "extracted archive, or it is not executable")); m_progressBar->setVisible(false); m_installButton->setEnabled(true); m_checkNowButton->setEnabled(true); @@ -367,14 +385,13 @@ void UpdatesSettingsTab::onInstall() QStringLiteral( "#!/usr/bin/env bash\n" "set -u\n" - "OLD_PID=%1\n" - "NEW_LAUNCHER=%2\n" + "OLD_PID=\"$1\"\n" + "NEW_LAUNCHER=\"$2\"\n" "for _ in $(seq 1 200); do\n" " if ! kill -0 \"$OLD_PID\" 2>/dev/null; then break; fi\n" " sleep 0.1\n" "done\n" - "exec \"$NEW_LAUNCHER\"\n") - .arg(QString::number(currentPid), newLauncher); + "exec \"$NEW_LAUNCHER\"\n"); helper.write(script.toUtf8()); helper.close(); QFile::setPermissions( @@ -388,7 +405,9 @@ void UpdatesSettingsTab::onInstall() // Detach the helper so it survives our exit. QProcess::startDetached(QStringLiteral("/usr/bin/env"), - {QStringLiteral("bash"), helperPath}); + {QStringLiteral("bash"), helperPath, + QString::number(currentPid), + newLauncher}); MOBase::log::info( "update installer: spawned helper to restart into {}", @@ -396,7 +415,7 @@ void UpdatesSettingsTab::onInstall() // Give the signal a beat to propagate, then quit cleanly. QTimer::singleShot(250, qApp, - []() { QCoreApplication::quit(); }); + []() { ExitModOrganizer(Exit::Force); }); }); extractor->start(); }); |
