fix: update game & voiceover now works properly.

This commit is contained in:
tretrauit 2022-07-13 13:52:57 +07:00
parent efc2abf858
commit 5066a4e2b3
Signed by: tretrauit
GPG Key ID: CDDE1C97EE305DAF
3 changed files with 46 additions and 23 deletions

View File

@ -9,7 +9,7 @@ README = (HERE / "README.md").read_text()
setup( setup(
name='worthless', name='worthless',
version='2.1.0-1', version='2.1.1',
packages=['worthless', 'worthless.classes', 'worthless.classes.launcher', 'worthless.classes.installer'], packages=['worthless', 'worthless.classes', 'worthless.classes.launcher', 'worthless.classes.installer'],
url='https://git.froggi.es/tretrauit/worthless-launcher', url='https://git.froggi.es/tretrauit/worthless-launcher',
license='MIT License', license='MIT License',

View File

@ -13,6 +13,7 @@ import worthless.constants as constants
class UI: class UI:
def __init__(self, gamedir: str, noconfirm: bool, tempdir: str | Path = None) -> None: def __init__(self, gamedir: str, noconfirm: bool, tempdir: str | Path = None) -> None:
self._vo_version = None
self._noconfirm = noconfirm self._noconfirm = noconfirm
self._gamedir = gamedir self._gamedir = gamedir
self._launcher = Launcher(gamedir) self._launcher = Launcher(gamedir)
@ -34,6 +35,9 @@ class UI:
def override_game_version(self, version: str): def override_game_version(self, version: str):
self._installer._version = version self._installer._version = version
def override_voiceover_version(self, version: str):
self._vo_version = version
async def get_game_version(self): async def get_game_version(self):
print(await self._installer.get_game_version()) print(await self._installer.get_game_version())
@ -194,12 +198,12 @@ class UI:
print("Downloading game update (This will take a long time)...") print("Downloading game update (This will take a long time)...")
await self._installer.download_game_update() await self._installer.download_game_update()
print("Installing game update...") print("Installing game update...")
await self.install_from_file(self._installer.temp_path.joinpath(res_info.game.latest.name)) await self.install_from_file(self._installer.temp_path.joinpath(diff_archive.get_name()))
async def update_voiceover(self, languages: str | list): async def update_voiceover(self, languages: str | list):
if isinstance(languages, str): if isinstance(languages, str):
languages = languages.split(" ") languages = languages.split(" ")
game_ver = await self._installer.get_game_version() game_ver = self._vo_version or self._installer.get_game_version()
if not game_ver: if not game_ver:
print("Couldn't detect current game installation, is game installed?") print("Couldn't detect current game installation, is game installed?")
return return
@ -225,6 +229,9 @@ class UI:
await self.update_game() await self.update_game()
await self.update_voiceover(languages) await self.update_voiceover(languages)
async def update_voiceover_all(self):
await self.update_voiceover(await self._installer.get_installed_voiceovers())
async def update_all(self): async def update_all(self):
await self.update_game() await self.update_game()
await self.update_voiceover(await self._installer.get_installed_voiceovers()) await self.update_voiceover(await self._installer.get_installed_voiceovers())
@ -295,6 +302,8 @@ async def main():
parser.add_argument("--check-telemetry", action="store_true", help="Check for the telemetry information") parser.add_argument("--check-telemetry", action="store_true", help="Check for the telemetry information")
parser.add_argument("--clear-cache", action="store_true", help="Clear cache used by worthless") parser.add_argument("--clear-cache", action="store_true", help="Clear cache used by worthless")
parser.add_argument("--from-ver", action="store", help="Override the detected game version", type=str, default=None) parser.add_argument("--from-ver", action="store", help="Override the detected game version", type=str, default=None)
parser.add_argument("--from-vo-ver", action="store", help="Override the detected game version for voiceover "
"detection", type=str, default=None)
parser.add_argument("--noconfirm", action="store_true", parser.add_argument("--noconfirm", action="store_true",
help="Do not ask any for confirmation. (Ignored in interactive mode)") help="Do not ask any for confirmation. (Ignored in interactive mode)")
args = parser.parse_args() args = parser.parse_args()

View File

@ -91,8 +91,10 @@ class HDiffPatch:
if not any(self.data_path.iterdir()): if not any(self.data_path.iterdir()):
return None return None
platform_arch_path = self.data_path.joinpath(self._get_platform_arch()) platform_arch_path = self.data_path.joinpath(self._get_platform_arch())
if platform_arch_path.joinpath(exec_name).exists(): file = platform_arch_path.joinpath(exec_name)
return str(platform_arch_path.joinpath(exec_name)) if file.exists():
file.chmod(0o755)
return str(file)
return None return None
def get_hpatchz_executable(self): def get_hpatchz_executable(self):
@ -279,7 +281,8 @@ class Installer:
return self._gamedir.joinpath(self.get_game_data_name()) return self._gamedir.joinpath(self.get_game_data_name())
async def get_game_archive_version(self, game_archive: str | Path): async def get_game_archive_version(self, game_archive: str | Path):
if not game_archive.exists(): game_archive = Path(game_archive)
if not game_archive.is_file():
raise FileNotFoundError(f"Game archive {game_archive} not found") raise FileNotFoundError(f"Game archive {game_archive} not found")
with zipfile.ZipFile(game_archive, 'r') as f: with zipfile.ZipFile(game_archive, 'r') as f:
return await self.read_version_from_game_file( return await self.read_version_from_game_file(
@ -345,18 +348,21 @@ class Installer:
patch_file = str(file) + ".hdiff" patch_file = str(file) + ".hdiff"
async def extract_and_patch(old_file, diff_file): async def extract_and_patch(old_file, diff_file):
diff_path = self.temp_path.joinpath(diff_file)
if await diff_path.is_file():
await diff_path.unlink(missing_ok=True)
await asyncio.to_thread(archive.extract, diff_file, self.temp_path) await asyncio.to_thread(archive.extract, diff_file, self.temp_path)
patch_path = self.temp_path.joinpath(diff_file) patch_path = self.temp_path.joinpath(diff_file)
old_suffix = old_file.suffix old_suffix = old_file.suffix
old_file = old_file.rename(old_file.with_suffix(".bak")) old_file = await old_file.rename(old_file.with_suffix(".bak"))
proc = await self._hdiffpatch.patch_file(old_file, old_file.with_suffix(old_suffix), proc = await self._hdiffpatch.patch_file(old_file, old_file.with_suffix(old_suffix),
patch_path, wait=True) patch_path, wait=True)
patch_path.unlink() await patch_path.unlink()
if proc.returncode != 0: if proc.returncode != 0:
# Let the game download the file. # Let the game download the file.
old_file.rename(old_file.with_suffix(old_suffix)) await old_file.rename(old_file.with_suffix(old_suffix))
return return
old_file.unlink() await old_file.unlink()
files.remove(patch_file) files.remove(patch_file)
patch_jobs.append(extract_and_patch(current_game_file, patch_file)) patch_jobs.append(extract_and_patch(current_game_file, patch_file))
@ -365,8 +371,8 @@ class Installer:
deletefiles = archive.read("deletefiles.txt").decode().split("\n") deletefiles = archive.read("deletefiles.txt").decode().split("\n")
for file in deletefiles: for file in deletefiles:
current_game_file = self._gamedir.joinpath(file) current_game_file = Path(self._gamedir.joinpath(file))
if not await current_game_file.exists(): if not current_game_file.exists():
continue continue
if current_game_file.is_file(): if current_game_file.is_file():
current_game_file.unlink(missing_ok=True) current_game_file.unlink(missing_ok=True)
@ -433,20 +439,22 @@ class Installer:
self._version = await self.get_game_version() self._version = await self.get_game_version()
self.set_version_config() self.set_version_config()
async def _get_game_resource(self, from_version: str = None): async def _get_game_version(self):
if not from_version:
if self._version: if self._version:
from_version = self._version from_version = self._version
else: else:
from_version = self._version = await self.get_game_version() from_version = self._version = await self.get_game_version()
if not from_version: return from_version
raise ValueError("No game version found")
async def _get_game_resource(self):
game_resource = await self._launcher.get_resource_info() game_resource = await self._launcher.get_resource_info()
if not game_resource: if not game_resource:
raise ValueError("Could not fetch game resource") raise ValueError("Could not fetch game resource")
return game_resource return game_resource
async def download_game_update(self, from_version: str = None): async def download_game_update(self, from_version: str = None):
if not from_version:
from_version = await self._get_game_version()
version_info = await self._get_game_resource() version_info = await self._get_game_resource()
if self._version == version_info.game.latest.version: if self._version == version_info.game.latest.version:
raise ValueError("Game is already up to date.") raise ValueError("Game is already up to date.")
@ -456,6 +464,8 @@ class Installer:
await self._download_file(diff_archive.path, diff_archive.name, diff_archive.size) await self._download_file(diff_archive.path, diff_archive.name, diff_archive.size)
async def download_voiceover_update(self, language: str, from_version: str = None): async def download_voiceover_update(self, language: str, from_version: str = None):
if not from_version:
from_version = await self._get_game_version()
diff_archive = await self.get_voiceover_diff_archive(language, from_version) diff_archive = await self.get_voiceover_diff_archive(language, from_version)
if diff_archive is None: if diff_archive is None:
raise ValueError("Voiceover diff archive is not available for this version, please reinstall.") raise ValueError("Voiceover diff archive is not available for this version, please reinstall.")
@ -466,16 +476,18 @@ class Installer:
If from_version is not specified, it will be taken from the game version. If from_version is not specified, it will be taken from the game version.
""" """
if not from_version:
from_version = await self._get_game_version()
game_resource = await self._get_game_resource() game_resource = await self._get_game_resource()
if not game_resource: if not game_resource:
raise ValueError("Could not fetch game resource") raise ValueError("Could not fetch game resource")
translated_lang = self.voiceover_lang_translate(lang) translated_lang = self.voiceover_lang_translate(lang)
for v in game_resource.game.diffs: for v in game_resource.game.diffs:
print(v.raw)
if v.version != from_version: if v.version != from_version:
continue continue
for vo in v.voice_packs: for vo in v.voice_packs:
if vo.language != translated_lang: if vo.language == translated_lang:
continue
return vo return vo
async def get_game_diff_archive(self, from_version: str = None): async def get_game_diff_archive(self, from_version: str = None):
@ -483,6 +495,8 @@ class Installer:
If from_version is not specified, it will be taken from the game version. If from_version is not specified, it will be taken from the game version.
""" """
if not from_version:
from_version = await self._get_game_version()
game_resource = await self._get_game_resource() game_resource = await self._get_game_resource()
for v in game_resource.game.diffs: for v in game_resource.game.diffs:
if v.version == from_version: if v.version == from_version: