worthless-launcher/worthless/installer.py

76 lines
3.0 KiB
Python
Raw Normal View History

import re
import appdirs
from pathlib import Path
from configparser import ConfigParser
from worthless import constants
from worthless.launcher import Launcher
def _read_version_from_game_file(globalgamemanagers: Path):
with globalgamemanagers.open("rb") as f:
data = f.read().decode("ascii", errors="ignore")
result = re.search(r"([1-9]+\.[0-9]+\.[0-9]+)_[\d]+_[\d]+", data)
if not result:
raise ValueError("Could not find version in game file")
return result.group(1)
class Installer:
def _read_version_from_config(self):
if not self._config_file.exists():
raise FileNotFoundError(f"Config file {self._config_file} not found")
cfg = ConfigParser()
cfg.read(str(self._config_file))
return cfg.get("General", "game_version")
# https://gitlab.com/KRypt0n_/an-anime-game-launcher/-/blob/main/src/ts/Game.ts#L26
def get_game_version(self):
if self._config_file.exists():
return self._read_version_from_config()
else:
if self._overseas:
globalgamemanagers = self._gamedir.joinpath("./GenshinImpact_Data/globalgamemanagers")
else:
globalgamemanagers = self._gamedir.joinpath("./YuanShen_Data/globalgamemanagers")
if not globalgamemanagers.exists():
return
return _read_version_from_game_file(globalgamemanagers)
def __init__(self, gamedir: str | Path = Path.cwd(), overseas: bool = True, data_dir: str | Path = None):
if isinstance(gamedir, str):
gamedir = Path(gamedir)
self._gamedir = gamedir
if not data_dir:
self._appdirs = appdirs.AppDirs(constants.APP_NAME, constants.APP_AUTHOR)
self._temp_path = Path(self._appdirs.user_cache_dir).joinpath("Installer")
else:
if not isinstance(data_dir, Path):
data_dir = Path(data_dir)
self._temp_path = data_dir.joinpath("Temp/Installer/")
config_file = self._gamedir.joinpath("config.ini")
self._config_file = config_file.resolve()
self._version = None
self._overseas = overseas
self._launcher = Launcher(self._gamedir, overseas=self._overseas)
self._version = self.get_game_version()
async def get_game_diff_archive(self, from_version: str = None):
"""Gets a diff archive from `from_version` to the latest one
If from_version is not specified, it will be taken from the game version.
"""
if not from_version:
if self._version:
from_version = self._version
else:
from_version = self._version = self.get_game_version()
if not from_version:
raise ValueError("No game version found")
game_resource = await self._launcher.get_resource_info()
if not game_resource:
raise ValueError("Could not fetch game resource")
for v in game_resource.game.diffs:
if v.version == from_version:
return v