Added support for updating game & applying voiceover packs
Implemented & Improved some CLI commands. Currently working in 2.5.0 version. A few more work and this should be fully usable,,,
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import re
|
||||
import appdirs
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from configparser import ConfigParser
|
||||
|
||||
@ -7,9 +8,12 @@ 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")
|
||||
def read_version_from_game_file(globalgamemanagers: Path | bytes):
|
||||
if isinstance(globalgamemanagers, Path):
|
||||
with globalgamemanagers.open("rb") as f:
|
||||
data = f.read().decode("ascii", errors="ignore")
|
||||
else:
|
||||
data = globalgamemanagers.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")
|
||||
@ -24,18 +28,24 @@ class Installer:
|
||||
cfg.read(str(self._config_file))
|
||||
return cfg.get("General", "game_version")
|
||||
|
||||
def get_game_data_name(self):
|
||||
if self._overseas:
|
||||
return "GenshinImpact_Data/"
|
||||
else:
|
||||
return "YuanShen_Data/"
|
||||
|
||||
def get_game_data_path(self):
|
||||
return self._gamedir.joinpath(self.get_game_data_name())
|
||||
|
||||
# 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")
|
||||
globalgamemanagers = self.get_game_data_path().joinpath("./globalgamemanagers")
|
||||
if not globalgamemanagers.exists():
|
||||
return
|
||||
return _read_version_from_game_file(globalgamemanagers)
|
||||
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):
|
||||
@ -55,6 +65,61 @@ class Installer:
|
||||
self._launcher = Launcher(self._gamedir, overseas=self._overseas)
|
||||
self._version = self.get_game_version()
|
||||
|
||||
def get_archive_version(self, game_archive: str | Path):
|
||||
if not game_archive.exists():
|
||||
raise FileNotFoundError(f"Game archive {game_archive} not found")
|
||||
archive = zipfile.ZipFile(game_archive, 'r')
|
||||
return read_version_from_game_file(archive.read(self.get_game_data_name() + "globalgamemanagers"))
|
||||
|
||||
def apply_voiceover(self, voiceover_archive: str | Path):
|
||||
if not self.get_game_data_path().exists():
|
||||
raise FileNotFoundError(f"Game not found in {self._gamedir}")
|
||||
if isinstance(voiceover_archive, str):
|
||||
game_archive = Path(voiceover_archive).resolve()
|
||||
if not voiceover_archive.exists():
|
||||
raise FileNotFoundError(f"Voiceover archive {voiceover_archive} not found")
|
||||
archive = zipfile.ZipFile(voiceover_archive, 'r')
|
||||
archive.extractall(self._gamedir)
|
||||
archive.close()
|
||||
|
||||
def update_game(self, game_archive: str | Path):
|
||||
if not self.get_game_data_path().exists():
|
||||
raise FileNotFoundError(f"Game not found in {self._gamedir}")
|
||||
if isinstance(game_archive, str):
|
||||
game_archive = Path(game_archive).resolve()
|
||||
if not game_archive.exists():
|
||||
raise FileNotFoundError(f"Update archive {game_archive} not found")
|
||||
archive = zipfile.ZipFile(game_archive, 'r')
|
||||
deletefiles = archive.read("deletefiles.txt").decode().split("\n")
|
||||
for file in deletefiles:
|
||||
current_game_file = self._gamedir.joinpath(file)
|
||||
if not current_game_file.exists():
|
||||
continue
|
||||
if current_game_file.is_file():
|
||||
current_game_file.unlink(missing_ok=True)
|
||||
archive.extractall(self._gamedir)
|
||||
archive.close()
|
||||
self._gamedir.joinpath("deletefiles.txt").unlink(missing_ok=True)
|
||||
self._gamedir.joinpath("hdifffiles.txt").unlink(missing_ok=True)
|
||||
|
||||
async def install_game(self, force_reinstall: bool = False):
|
||||
"""Installs the game to the current directory
|
||||
|
||||
If `from_version` is not specified, it will be taken from the game version.
|
||||
If `to_version` is not specified, it will be taken from the game version.
|
||||
"""
|
||||
raise NotImplementedError("Not implemented yet")
|
||||
# if not force:
|
||||
# if self._temp_path.exists():
|
||||
# raise FileExistsError(f"Directory {self._temp_path} already exists")
|
||||
# self._temp_path.mkdir(parents=True, exist_ok=True)
|
||||
# self._launcher.set_temp_path(self._temp_path)
|
||||
# await self._launcher.download_game_diff_archive(from_version, to_version)
|
||||
# await self._launcher.extract_game_diff_archive()
|
||||
# await self._launcher.install_game_diff_archive()
|
||||
# self._launcher.set_temp_path(None)
|
||||
# self._temp_path.rmdir()
|
||||
|
||||
async def get_game_diff_archive(self, from_version: str = None):
|
||||
"""Gets a diff archive from `from_version` to the latest one
|
||||
|
||||
|
||||
Reference in New Issue
Block a user