From f8887a4bafc3ae1f8d97a001eba1e8c0ed6e594c Mon Sep 17 00:00:00 2001 From: tretrauit Date: Sat, 17 Jun 2023 03:33:37 +0700 Subject: [PATCH] feat: implement get_version Thanks An Anime Team for the code xD --- vollerei/hsr/launcher/game.py | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/vollerei/hsr/launcher/game.py b/vollerei/hsr/launcher/game.py index 14b0b9d..1c2d5cd 100644 --- a/vollerei/hsr/launcher/game.py +++ b/vollerei/hsr/launcher/game.py @@ -19,6 +19,9 @@ class Game(GameABC): def path(self) -> Path | None: return self._path + def data_folder(self) -> Path: + return self._path.joinpath("StarRail_Data") + def is_installed(self) -> bool: if self._path is None: return False @@ -28,6 +31,49 @@ class Game(GameABC): ): return False + def get_version(self) -> tuple[int, int, int]: + """ + Get the current installed game version. + + Credits to An Anime Team for the code that does the magic: + https://github.com/an-anime-team/anime-game-core/blob/main/src/games/star_rail/game.rs#L49 + """ + allowed = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57] + version_bytes: list[bytes] = [0, 0, 0] + version_ptr = 0 + correct = True + with self.data_folder().joinpath("data.unity3d").open("rb") as f: + f.seek(0x7D0) # 2000 in decimal + for byte in f.read(10000): + match byte: + case 0: + version_bytes = [0, 0, 0] + version_ptr = 0 + correct = True + case 46: + version_ptr += 1 + if version_ptr > 2: + correct = False + case 38: + if ( + correct + and version_bytes[0] > 0 + and version_bytes[1] > 0 + and version_bytes[2] > 0 + ): + # TODO: The below code is not correct. + return ( + int(version_bytes[0]), + int(version_bytes[1]), + int(version_bytes[2]), + ) + case _: + if correct and byte in allowed: + version_bytes[version_ptr] += byte + else: + correct = False + return (0, 0, 0) + def get_channel(self) -> GameChannel: if self.get_version() == (1, 0, 5): for channel, v in md5sums["1.0.5"].values(): @@ -42,3 +88,5 @@ class Game(GameABC): return GameChannel.China case "os": return GameChannel.Overseas + else: + return