Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions games/game_silenthill2remake.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
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]