Files
modorganizer-basic_games/games/game_silenthill2remake.py

114 lines
4.1 KiB
Python

from typing import Tuple
import mobase
from ..basic_features import BasicModDataChecker, GlobPatterns
from ..basic_game import BasicGame
class SilentHill2RemakeModDataChecker(BasicModDataChecker):
def __init__(self):
super().__init__(
GlobPatterns(
delete=[
"*.txt",
"*.md",
"manifest.json",
"icon.png",
],
)
)
self.mod_path = ["SHProto", "Content", "Paks", "~mod"]
self.mod_path_lower = [name.lower() for name in self.mod_path]
def _find_tree(
self, filetree: mobase.IFileTree
) -> Tuple[str | None, mobase.FileTreeEntry | None]:
"""
Search the given filetree for a directory name that matches any component
of self.mod_path (case-insensitive).
Returns:
(prefix, entry)
prefix: The missing part before the match (e.g. 'SHProto/Content/')
entry: The IFileTree entry that matched (e.g. the 'Paks' directory)
(None, None) if nothing matches.
"""
for entry in filetree:
if not entry.isDir():
continue
name_lower = entry.name().lower()
for i, component in enumerate(self.mod_path_lower):
if name_lower == component:
# Build the prefix string for everything *before* this match
prefix_parts = self.mod_path[:i]
prefix = "/".join(prefix_parts) + ("/" if prefix_parts else "")
return (prefix, entry)
# No matches found
return (None, None)
def dataLooksValid(
self, filetree: mobase.IFileTree
) -> mobase.ModDataChecker.CheckReturn:
# Check for fully valid layout
has_entry, _ = self._find_tree(filetree)
if has_entry is None:
# in this case we check to make sure there's a .pak file
for entry in filetree:
if entry.name().lower().endswith(".pak") and entry.isFile():
return mobase.ModDataChecker.FIXABLE
elif has_entry == "":
return mobase.ModDataChecker.VALID
else:
return mobase.ModDataChecker.FIXABLE
# Otherwise, not recognizable
return mobase.ModDataChecker.INVALID
def fix(self, filetree: mobase.IFileTree) -> mobase.IFileTree:
filetree = super().fix(filetree)
prefix, item = self._find_tree(filetree)
if prefix is None:
foundAPak = False
# Move all top-level items to BepInEx/plugins/
items_to_move = list(filetree)
for cur_item in items_to_move:
if cur_item.name().lower().endswith(".pak"):
foundAPak = True
filetree.move(cur_item, f"SHProto/Content/Paks/~mod/{cur_item.name()}")
# foundAPack MUST be true because if 'prefix' returned None then
# there must be a .pak file or dataLooksValid wouldn't have returned
# a FIXABLE. This is therefore just a sanity check
assert foundAPak
return filetree
elif prefix == "":
return filetree
else:
# if prefix is not None then item cannot be None
assert item is not None
filetree.move(item, f"{prefix}{item.name()}")
return filetree
class SilentHill2RemakeGame(BasicGame):
def init(self, organizer: mobase.IOrganizer) -> bool:
super().init(organizer)
self._register_feature(SilentHill2RemakeModDataChecker())
return True
Name = "Silent Hill 2 Remake Support Plugin"
Author = "HomerSimpleton Returns"
Version = "1.0"
GameName = "Silent Hill 2 Remake"
GameShortName = "silenthill2"
GameNexusName = "silenthill2"
GameBinary = "SHProto/Binaries/Win64/SHProto-Win64-Shipping.exe"
GameLauncher = "SHProto.exe"
GameDataPath = "%GAME_PATH%"
GameSupportURL = "https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/Game:-Silent-Hill-2-Remake"
GameGogId = [1225972913, 2051029707]