Skip to content

Commit dfd6462

Browse files
committed
Subnautica: fix _Root errors
- Set data path to "" instead of "_Root" - Exclude unsupported save dir with source=destination mapping
1 parent 3571d4a commit dfd6462

2 files changed

Lines changed: 15 additions & 94 deletions

File tree

games/game_subnautica-below-zero.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,23 @@
77
class SubnauticaBelowZeroGame(game_subnautica.SubnauticaGame):
88
Name = "Subnautica Below Zero Support Plugin"
99
Author = "dekart811, Zash"
10-
Version = "2.2"
10+
Version = "2.3"
1111

1212
GameName = "Subnautica: Below Zero"
1313
GameShortName = "subnauticabelowzero"
1414
GameNexusName = "subnauticabelowzero"
1515
GameSteamId = 848450
1616
GameEpicId = "foxglove"
1717
GameBinary = "SubnauticaZero.exe"
18-
GameDataPath = "_ROOT"
19-
GameDocumentsDirectory = "%GAME_PATH%"
2018
GameSupportURL = (
2119
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
2220
"Game:-Subnautica:-Below-Zero"
2321
)
24-
GameSavesDirectory = r"%GAME_PATH%\SNAppData\SavedGames"
2522

26-
_game_extra_save_paths = [
23+
_game_saves_directory_epic = (
2724
r"%USERPROFILE%\Appdata\LocalLow\Unknown Worlds"
2825
r"\Subnautica Below Zero\SubnauticaZero\SavedGames"
29-
]
26+
)
3027

3128
def _set_mod_data_checker(
3229
self, extra_patterns: GlobPatterns | None = None, use_qmod: bool | None = None

games/game_subnautica.py

Lines changed: 12 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22

33
import fnmatch
44
import os
5-
from collections.abc import Iterable
6-
from enum import Enum
75
from pathlib import Path
86

9-
from PyQt6.QtCore import QDir, qWarning
10-
117
import mobase
8+
from PyQt6.QtCore import QDir
129

1310
from ..basic_features import BasicModDataChecker, GlobPatterns
1411
from ..basic_features.basic_save_game_info import (
@@ -87,15 +84,15 @@ def fix(self, filetree: mobase.IFileTree) -> mobase.IFileTree:
8784
class SubnauticaGame(BasicGame, mobase.IPluginFileMapper):
8885
Name = "Subnautica Support Plugin"
8986
Author = "dekart811, Zash"
90-
Version = "2.2"
87+
Version = "2.3"
9188

9289
GameName = "Subnautica"
9390
GameShortName = "subnautica"
9491
GameNexusName = "subnautica"
9592
GameSteamId = 264710
9693
GameEpicId = "Jaguar"
9794
GameBinary = "Subnautica.exe"
98-
GameDataPath = "_ROOT" # Custom mappings to actual root folders below.
95+
GameDataPath = ""
9996
GameDocumentsDirectory = r"%GAME_PATH%"
10097
GameSupportURL = (
10198
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
@@ -110,21 +107,6 @@ class SubnauticaGame(BasicGame, mobase.IPluginFileMapper):
110107

111108
_forced_libraries = ["winhttp.dll"]
112109

113-
_root_blacklist = {GameDataPath.casefold()}
114-
115-
class MapType(Enum):
116-
FILE = 0
117-
FOLDER = 1
118-
119-
_root_extra_overwrites: dict[str, MapType] = {
120-
"qmodmanager_log-Subnautica.txt": MapType.FILE,
121-
"qmodmanager-config.json": MapType.FILE,
122-
"BepInEx_Shim_Backup": MapType.FOLDER,
123-
}
124-
"""Extra files & folders created in game root by mods / BepInEx after game launch,
125-
but not included in the mod archives.
126-
"""
127-
128110
def __init__(self):
129111
super().__init__()
130112
mobase.IPluginFileMapper.__init__(self)
@@ -205,73 +187,15 @@ def executableForcedLoads(self) -> list[mobase.ExecutableForcedLoadSetting]:
205187
]
206188

207189
def mappings(self) -> list[mobase.Mapping]:
208-
game = self._organizer.managedGame()
209-
game_path = Path(game.gameDirectory().absolutePath())
210-
overwrite_path = Path(self._organizer.overwritePath())
190+
game_dir = self._organizer.managedGame().gameDirectory()
211191

192+
# Save game file writes seem not compatible with USVFS:
193+
# exclude save folder from default root mappings (write back to game dir)
212194
return [
213-
*(
214-
# Extra overwrites
215-
self._overwrite_mapping(
216-
overwrite_path / name,
217-
dest,
218-
is_dir=(map_type is self.MapType.FOLDER),
219-
)
220-
for name, map_type in self._root_extra_overwrites.items()
221-
if not (dest := game_path / name).exists()
222-
),
223-
*self._root_mappings(game_path, overwrite_path),
195+
mobase.Mapping(
196+
source=(source := game_dir.absoluteFilePath("SNAppData")),
197+
destination=source,
198+
is_directory=True,
199+
create_target=True,
200+
)
224201
]
225-
226-
def _root_mappings(
227-
self, game_path: Path, overwrite_path: Path
228-
) -> Iterable[mobase.Mapping]:
229-
for mod_path in self._active_mod_paths():
230-
mod_name = mod_path.name
231-
232-
for child in mod_path.iterdir():
233-
# Check blacklist
234-
if child.name.casefold() in self._root_blacklist:
235-
qWarning(f"Skipping {child.name} ({mod_name})")
236-
continue
237-
destination = game_path / child.name
238-
# Check existing
239-
if destination.exists():
240-
qWarning(
241-
f"Overwriting of existing game files/folders is not supported! "
242-
f"{destination.as_posix()} ({mod_name})"
243-
)
244-
continue
245-
# Mapping: mod -> root
246-
yield mobase.Mapping(
247-
source=str(child),
248-
destination=str(destination),
249-
is_directory=child.is_dir(),
250-
create_target=False,
251-
)
252-
if child.is_dir():
253-
# Mapping: overwrite <-> root
254-
yield self._overwrite_mapping(
255-
overwrite_path / child.name, destination, is_dir=True
256-
)
257-
258-
def _active_mod_paths(self) -> Iterable[Path]:
259-
mods_parent_path = Path(self._organizer.modsPath())
260-
modlist = self._organizer.modList().allModsByProfilePriority()
261-
for mod in modlist:
262-
if self._organizer.modList().state(mod) & mobase.ModState.ACTIVE:
263-
yield mods_parent_path / mod
264-
265-
def _overwrite_mapping(
266-
self, overwrite_source: Path, destination: Path, is_dir: bool
267-
) -> mobase.Mapping:
268-
"""Mapping: overwrite <-> root"""
269-
if is_dir:
270-
# Root folders in overwrite need to exits.
271-
overwrite_source.mkdir(parents=True, exist_ok=True)
272-
return mobase.Mapping(
273-
str(overwrite_source),
274-
str(destination),
275-
is_dir,
276-
create_target=True,
277-
)

0 commit comments

Comments
 (0)