diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-02-11 02:37:39 -0600 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-02-11 02:37:39 -0600 |
| commit | 7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch) | |
| tree | 27fb39be241fdb5ac2734c574de678977d1856d0 /libs/game_gamebryo/src/gamebryo/gamebryobsainvalidation.cpp | |
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem,
Proton/umu-run integration, and Flatpak packaging.
Key features:
- FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak)
- Proton/GE-Proton/umu-run launcher with env var forwarding
- Flatpak support (sandbox-aware VFS, NXM handler, umu-run)
- Wine prefix management UI
- Case-insensitive path resolution for Linux filesystems
- QSettings-safe INI handling (avoids Bethesda INI corruption)
- Portable instance support with auto-generated launcher scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/game_gamebryo/src/gamebryo/gamebryobsainvalidation.cpp')
| -rw-r--r-- | libs/game_gamebryo/src/gamebryo/gamebryobsainvalidation.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/libs/game_gamebryo/src/gamebryo/gamebryobsainvalidation.cpp b/libs/game_gamebryo/src/gamebryo/gamebryobsainvalidation.cpp new file mode 100644 index 0000000..1b7144b --- /dev/null +++ b/libs/game_gamebryo/src/gamebryo/gamebryobsainvalidation.cpp @@ -0,0 +1,133 @@ +#include "gamebryobsainvalidation.h" + +#include "dummybsa.h" +#include "iplugingame.h" +#include "iprofile.h" +#include "registry.h" +#include <imoinfo.h> +#include <utility.h> + +#include <QDir> +#include <QStringList> + +#include <Windows.h> + +GamebryoBSAInvalidation::GamebryoBSAInvalidation(MOBase::DataArchives* dataArchives, + const QString& iniFilename, + MOBase::IPluginGame const* game) + : m_DataArchives(dataArchives), m_IniFileName(iniFilename), m_Game(game) +{} + +bool GamebryoBSAInvalidation::isInvalidationBSA(const QString& bsaName) +{ + static QStringList invalidation{invalidationBSAName()}; + + for (const QString& file : invalidation) { + if (file.compare(bsaName, Qt::CaseInsensitive) == 0) { + return true; + } + } + return false; +} + +void GamebryoBSAInvalidation::deactivate(MOBase::IProfile* profile) +{ + prepareProfile(profile); +} + +void GamebryoBSAInvalidation::activate(MOBase::IProfile* profile) +{ + prepareProfile(profile); +} + +bool GamebryoBSAInvalidation::prepareProfile(MOBase::IProfile* profile) +{ + bool dirty = false; + QString basePath = profile->localSettingsEnabled() + ? profile->absolutePath() + : m_Game->documentsDirectory().absolutePath(); + QString iniFilePath = basePath + "/" + m_IniFileName; + WCHAR setting[MAX_PATH]; + + // write bInvalidateOlderFiles = 1, if needed + if (!::GetPrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"0", setting, + MAX_PATH, iniFilePath.toStdWString().c_str()) || + wcstol(setting, nullptr, 10) != 1) { + dirty = true; + if (!MOBase::WriteRegistryValue(L"Archive", L"bInvalidateOlderFiles", L"1", + iniFilePath.toStdWString().c_str())) { + qWarning("failed to activate BSA invalidation in \"%s\"", + qUtf8Printable(m_IniFileName)); + } + } + + if (profile->invalidationActive(nullptr)) { + + // add the dummy bsa to the archive string, if needed + QStringList archives = m_DataArchives->archives(profile); + bool bsaInstalled = false; + for (const QString& archive : archives) { + if (isInvalidationBSA(archive)) { + bsaInstalled = true; + break; + } + } + if (!bsaInstalled) { + m_DataArchives->addArchive(profile, 0, invalidationBSAName()); + dirty = true; + } + + // create the dummy bsa if necessary + QString bsaFile = m_Game->dataDirectory().absoluteFilePath(invalidationBSAName()); + if (!QFile::exists(bsaFile)) { + DummyBSA bsa(bsaVersion()); + bsa.write(bsaFile); + dirty = true; + } + + // write SInvalidationFile = "", if needed + if (::GetPrivateProfileStringW(L"Archive", L"SInvalidationFile", + L"ArchiveInvalidation.txt", setting, MAX_PATH, + iniFilePath.toStdWString().c_str()) || + wcscmp(setting, L"") != 0) { + dirty = true; + if (!MOBase::WriteRegistryValue(L"Archive", L"SInvalidationFile", L"", + iniFilePath.toStdWString().c_str())) { + qWarning("failed to activate BSA invalidation in \"%s\"", + qUtf8Printable(m_IniFileName)); + } + } + } else { + + // remove the dummy bsa from the archive string, if needed + QStringList archivesBefore = m_DataArchives->archives(profile); + for (const QString& archive : archivesBefore) { + if (isInvalidationBSA(archive)) { + m_DataArchives->removeArchive(profile, archive); + dirty = true; + } + } + + // delete the dummy bsa, if needed + QString bsaFile = m_Game->dataDirectory().absoluteFilePath(invalidationBSAName()); + if (QFile::exists(bsaFile)) { + MOBase::shellDeleteQuiet(bsaFile); + dirty = true; + } + + // write SInvalidationFile = "ArchiveInvalidation.txt", if needed + if (!::GetPrivateProfileStringW(L"Archive", L"SInvalidationFile", L"", setting, + MAX_PATH, iniFilePath.toStdWString().c_str()) || + wcscmp(setting, L"ArchiveInvalidation.txt") != 0) { + dirty = true; + if (!MOBase::WriteRegistryValue(L"Archive", L"SInvalidationFile", + L"ArchiveInvalidation.txt", + iniFilePath.toStdWString().c_str())) { + qWarning("failed to activate BSA invalidation in \"%s\"", + qUtf8Printable(m_IniFileName)); + } + } + } + + return dirty; +} |
