Compare commits

...

2 Commits

Author SHA1 Message Date
99c099e3e3 docs: add more docs 2023-06-21 21:09:19 +07:00
359e2b30df feat: add version and channel override 2023-06-21 21:08:56 +07:00
2 changed files with 89 additions and 3 deletions

View File

@ -3,7 +3,7 @@ from os import PathLike
from pathlib import Path from pathlib import Path
from enum import Enum from enum import Enum
from vollerei.abc.launcher.game import GameABC from vollerei.abc.launcher.game import GameABC
from vollerei.hsr.constants import MD5SUMS from vollerei.hsr.constants import md5sums
class GameChannel(Enum): class GameChannel(Enum):
@ -14,9 +14,49 @@ class GameChannel(Enum):
class Game(GameABC): class Game(GameABC):
def __init__(self, path: PathLike = None): def __init__(self, path: PathLike = None):
self._path: Path | None = Path(path) if path else None self._path: Path | None = Path(path) if path else None
self._version_override: tuple[int, int, int] | None = None
self._channel_override: GameChannel | None = None
@property
def version_override(self) -> tuple[int, int, int] | None:
"""
Override the game version.
This can be useful if you want to override the version of the game
and additionally working around bugs.
"""
return self._version_override
@version_override.setter
def version_override(self, version: tuple[int, int, int] | str | None):
if isinstance(version, str):
version = tuple(int(i) for i in version.split("."))
self._version_override = version
@property
def channel_override(self) -> GameChannel | None:
"""
Override the game channel.
Because game channel detection isn't implemented yet, you may need
to use this for some functions to work.
This can be useful if you want to override the channel of the game
and additionally working around bugs.
"""
return self._channel_override
@channel_override.setter
def channel_override(self, channel: GameChannel | str | None):
if isinstance(channel, str):
channel = GameChannel[channel]
self._channel_override = channel
@property @property
def path(self) -> Path | None: def path(self) -> Path | None:
"""
Path to the game folder.
"""
return self._path return self._path
@path.setter @path.setter
@ -24,6 +64,9 @@ class Game(GameABC):
self._path = Path(path) self._path = Path(path)
def data_folder(self) -> Path: def data_folder(self) -> Path:
"""
Path to the game data folder.
"""
return self._path.joinpath("StarRail_Data") return self._path.joinpath("StarRail_Data")
def is_installed(self) -> bool: def is_installed(self) -> bool:
@ -115,11 +158,15 @@ class Game(GameABC):
Only works for Star Rail version 1.0.5, other versions will return None Only works for Star Rail version 1.0.5, other versions will return None
This is not needed for game patching, since the patcher will automatically
detect the channel.
Returns: Returns:
GameChannel: The current game channel. GameChannel: The current game channel.
""" """
if self.get_version() == (1, 0, 5): version = self._version_override or self.get_version()
for channel, v in MD5SUMS["1.0.5"].values(): if version == (1, 0, 5):
for channel, v in md5sums["1.0.5"].values():
for file, md5sum in v.values(): for file, md5sum in v.values():
if ( if (
md5(self._path.joinpath(file).read_bytes()).hexdigest() md5(self._path.joinpath(file).read_bytes()).hexdigest()

View File

@ -30,6 +30,8 @@ class PatchType(Enum):
class Patcher(PatcherABC): class Patcher(PatcherABC):
""" """
Patch helper for HSR. Patch helper for HSR.
By default this will use Jadeite as it is maintained and more stable.
""" """
def __init__(self, patch_type: PatchType = PatchType.Jadeite): def __init__(self, patch_type: PatchType = PatchType.Jadeite):
@ -43,6 +45,9 @@ class Patcher(PatcherABC):
@property @property
def patch_type(self) -> PatchType: def patch_type(self) -> PatchType:
"""
Patch type, can be either Astra or Jadeite
"""
return self._patch_type return self._patch_type
@patch_type.setter @patch_type.setter
@ -68,6 +73,9 @@ class Patcher(PatcherABC):
f.write(file_version) f.write(file_version)
def update_patch(self): def update_patch(self):
"""
Update the patch
"""
try: try:
match self._patch_type: match self._patch_type:
case PatchType.Astra: case PatchType.Astra:
@ -158,6 +166,15 @@ class Patcher(PatcherABC):
rmtree(self._jadeite, ignore_errors=True) rmtree(self._jadeite, ignore_errors=True)
def patch_game(self, game: Game): def patch_game(self, game: Game):
"""
Patch the game
If you use Jadeite (by default), this will just download Jadeite files
and won't actually patch the game because Jadeite will do that automatically.
Args:
game (Game): The game to patch
"""
if not game.is_installed(): if not game.is_installed():
raise PatcherError(GameNotInstalledError("Game is not installed")) raise PatcherError(GameNotInstalledError("Game is not installed"))
match self._patch_type: match self._patch_type:
@ -167,6 +184,14 @@ class Patcher(PatcherABC):
return self._patch_jadeite() return self._patch_jadeite()
def unpatch_game(self, game: Game): def unpatch_game(self, game: Game):
"""
Unpatch the game
If you use Jadeite (by default), this will just delete Jadeite files.
Args:
game (Game): The game to unpatch
"""
if not game.is_installed(): if not game.is_installed():
raise PatcherError(GameNotInstalledError("Game is not installed")) raise PatcherError(GameNotInstalledError("Game is not installed"))
match self._patch_type: match self._patch_type:
@ -176,9 +201,23 @@ class Patcher(PatcherABC):
self._unpatch_jadeite() self._unpatch_jadeite()
def check_telemetry(self) -> list[str]: def check_telemetry(self) -> list[str]:
"""
Check if telemetry servers are accessible by the user
Returns:
list[str]: A list of telemetry servers that are accessible
"""
return telemetry.check_telemetry() return telemetry.check_telemetry()
def block_telemetry(self, telemetry_list: list[str] = None): def block_telemetry(self, telemetry_list: list[str] = None):
"""
Block the telemetry servers
If telemetry_list is not provided, it will be checked automatically.
Args:
telemetry_list (list[str], optional): A list of telemetry servers to block.
"""
if not telemetry_list: if not telemetry_list:
telemetry_list = telemetry.check_telemetry() telemetry_list = telemetry.check_telemetry()
telemetry.block_telemetry(telemetry_list) telemetry.block_telemetry(telemetry_list)