Subnautica: custom mapping to fix saving (saves in game dir)

This commit is contained in:
Zash
2022-05-27 20:58:58 +02:00
parent 3f7d0f1e9e
commit b53a9abb11
2 changed files with 100 additions and 7 deletions
+2 -2
View File
@@ -9,14 +9,14 @@ class SubnauticaBelowZeroGame(game_subnautica.SubnauticaGame):
Name = "Subnautica Below Zero Support Plugin"
Author = "dekart811, Zash"
Version = "2.0"
Version = "2.1"
GameName = "Subnautica: Below Zero"
GameShortName = "subnauticabelowzero"
GameNexusName = "subnauticabelowzero"
GameSteamId = 848450
GameBinary = "SubnauticaZero.exe"
GameDataPath = ""
GameDataPath = "_ROOT"
GameDocumentsDirectory = "%GAME_PATH%"
GameSupportURL = (
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
+98 -5
View File
@@ -1,9 +1,11 @@
from __future__ import annotations
from enum import Enum
import os
from collections.abc import Iterable
from pathlib import Path
from PyQt5.QtCore import QDir
from PyQt5.QtCore import QDir, qWarning
import mobase
@@ -30,11 +32,11 @@ class SubnauticaModDataChecker(BasicModDataChecker):
}
class SubnauticaGame(BasicGame):
class SubnauticaGame(BasicGame, mobase.IPluginFileMapper):
Name = "Subnautica Support Plugin"
Author = "dekart811, Zash"
Version = "2.0"
Version = "2.1"
GameName = "Subnautica"
GameShortName = "subnautica"
@@ -42,8 +44,8 @@ class SubnauticaGame(BasicGame):
GameSteamId = 264710
GameEpicId = "Jaguar"
GameBinary = "Subnautica.exe"
GameDataPath = ""
GameDocumentsDirectory = "%GAME_PATH%"
GameDataPath = "_ROOT" # Custom mappings to actual root folders below.
GameDocumentsDirectory = r"%GAME_PATH%"
GameSupportURL = (
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
"Game:-Subnautica"
@@ -57,6 +59,25 @@ class SubnauticaGame(BasicGame):
_forced_libraries = ["winhttp.dll"]
_root_blacklist = {GameDataPath.casefold()}
class MapType(Enum):
FILE = 0
FOLDER = 1
_root_extra_overwrites: dict[str, MapType] = {
"qmodmanager_log-Subnautica.txt": MapType.FILE,
"qmodmanager-config.json": MapType.FILE,
"BepInEx_Shim_Backup": MapType.FOLDER,
}
"""Extra files & folders created in game root by mods / BepInEx after game launch,
but not included in the mod archives.
"""
def __init__(self):
super().__init__()
mobase.IPluginFileMapper.__init__(self)
def init(self, organizer: mobase.IOrganizer) -> bool:
super().init(organizer)
self._featureMap[mobase.ModDataChecker] = SubnauticaModDataChecker()
@@ -80,3 +101,75 @@ class SubnauticaGame(BasicGame):
mobase.ExecutableForcedLoadSetting(self.binaryName(), lib).withEnabled(True)
for lib in self._forced_libraries
]
def mappings(self) -> list[mobase.Mapping]:
game = self._organizer.managedGame()
game_path = Path(game.gameDirectory().absolutePath())
overwrite_path = Path(self._organizer.overwritePath())
return [
*(
# Extra overwrites
self._overwrite_mapping(
overwrite_path / name,
dest,
is_dir=(map_type is self.MapType.FOLDER),
)
for name, map_type in self._root_extra_overwrites.items()
if not (dest := game_path / name).exists()
),
*self._root_mappings(game_path, overwrite_path),
]
def _root_mappings(
self, game_path: Path, overwrite_path: Path
) -> Iterable[mobase.Mapping]:
for mod_path in self._active_mod_paths():
mod_name = mod_path.name
for child in mod_path.iterdir():
# Check blacklist
if child.name.casefold() in self._root_blacklist:
qWarning(f"Skipping {child.name} ({mod_name})")
continue
destination = game_path / child.name
# Check existing
if destination.exists():
qWarning(
f"Overwriting of existing game files/folders is not supported! "
f"{destination.as_posix()} ({mod_name})"
)
continue
# Mapping: mod -> root
yield mobase.Mapping(
source=str(child),
destination=str(destination),
is_directory=child.is_dir(),
create_target=False,
)
if child.is_dir():
# Mapping: overwrite <-> root
yield self._overwrite_mapping(
overwrite_path / child.name, destination, is_dir=True
)
def _active_mod_paths(self) -> Iterable[Path]:
mods_parent_path = Path(self._organizer.modsPath())
modlist = self._organizer.modList().allModsByProfilePriority()
for mod in modlist:
if self._organizer.modList().state(mod) & mobase.ModState.ACTIVE:
yield mods_parent_path / mod
def _overwrite_mapping(
self, overwrite_source: Path, destination: Path, is_dir: bool
) -> mobase.Mapping:
"""Mapping: overwrite <-> root"""
if is_dir:
# Root folders in overwrite need to exits.
overwrite_source.mkdir(parents=True, exist_ok=True)
return mobase.Mapping(
str(overwrite_source),
str(destination),
is_dir,
create_target=True,
)