From 7ee008e150bc5bcf76082d726f719ee0fdfda982 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Wed, 11 Feb 2026 02:37:39 -0600 Subject: 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 --- .../games/baldursgate3/bg3_data_checker.py | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 libs/basic_games/games/baldursgate3/bg3_data_checker.py (limited to 'libs/basic_games/games/baldursgate3/bg3_data_checker.py') diff --git a/libs/basic_games/games/baldursgate3/bg3_data_checker.py b/libs/basic_games/games/baldursgate3/bg3_data_checker.py new file mode 100644 index 0000000..695d21c --- /dev/null +++ b/libs/basic_games/games/baldursgate3/bg3_data_checker.py @@ -0,0 +1,58 @@ +from pathlib import Path + +import mobase + +from ...basic_features import BasicModDataChecker, GlobPatterns, utils +from . import bg3_utils + + +class BG3ModDataChecker(BasicModDataChecker): + def __init__(self): + super().__init__( + GlobPatterns( + valid=[ + "*.pak", + str(Path("Mods") / "*.pak"), # standard mods + "bin", # native mods / Script Extender + "Script Extender", # mods which are configured via jsons in this folder + "Data", # loose file mods + ] + + [str(Path("*") / f) for f in bg3_utils.loose_file_folders], + move={ + "Root/": "", # root builder not needed + "*.dll": "bin/", + "ScriptExtenderSettings.json": "bin/", + } + | {f: "Data/" for f in bg3_utils.loose_file_folders}, + delete=["info.json", "*.txt"], + ) + ) + + def dataLooksValid( + self, filetree: mobase.IFileTree + ) -> mobase.ModDataChecker.CheckReturn: + status = mobase.ModDataChecker.INVALID + rp = self._regex_patterns + for entry in filetree: + name = entry.name().casefold() + if rp.unfold.match(name): + if utils.is_directory(entry): + status = self.dataLooksValid(entry) + else: + status = mobase.ModDataChecker.INVALID + break + elif rp.valid.match(name): + if status is mobase.ModDataChecker.INVALID: + status = mobase.ModDataChecker.VALID + elif isinstance(entry, mobase.IFileTree): + status = ( + mobase.ModDataChecker.VALID + if all(rp.valid.match(e.pathFrom(filetree)) for e in entry) + else mobase.ModDataChecker.INVALID + ) + elif rp.delete.match(name) or rp.move_match(name) is not None: + status = mobase.ModDataChecker.FIXABLE + else: + status = mobase.ModDataChecker.INVALID + break + return status -- cgit v1.3.1