Don't rely on xdelta3 python module

Don't crash if xdelta3 module is not present, and add the ability to download game & voicepack in CLI
Bump to 1.2.8
This commit is contained in:
tretrauit 2022-02-19 18:57:45 +07:00
parent 2d6cff77c6
commit e4cc701166
No known key found for this signature in database
GPG Key ID: 862760FF1903319E
2 changed files with 67 additions and 12 deletions

View File

@ -31,6 +31,9 @@ class UI:
answer = input(question + " (y/n): ")
return answer.lower() == 'y'
def override_game_version(self, version: str):
self._installer._version = version
def get_game_version(self):
print(self._installer.get_game_version())
@ -40,9 +43,9 @@ class UI:
print("Updating game from archive (this may takes some time)...")
self._installer.update_game(filepath)
def _install_from_archive(self, filepath):
def _install_from_archive(self, filepath, force_reinstall):
print("Installing game from archive (this may takes some time)...")
self._installer.install_game(filepath)
self._installer.install_game(filepath, force_reinstall)
def _apply_voiceover_from_archive(self, filepath):
print("Applying voiceover from archive (this may takes some time)...")
@ -90,19 +93,44 @@ class UI:
if not self._ask("Do you want to install the game? ({})".format(filepath)):
print("Aborting installation process.")
return
self._install_from_archive(filepath)
self._install_from_archive(filepath, False)
print("Game installed successfully.")
def download_game(self):
print("Downloading full game (This will take a long time)...")
asyncio.run(self._installer.download_full_game())
def download_game_update(self):
print("Downloading game update (This will take a long time)...")
asyncio.run(self._installer.download_game_update())
def download_voiceover(self, languages: str):
res_info = asyncio.run(self._launcher.get_resource_info())
for lng in languages.split(" "):
for vo in res_info.game.latest.voice_packs:
if not self._installer.voiceover_lang_translate(lng) == vo.language:
continue
print("Downloading voiceover pack for {} (This will take a long time)...".format(lng))
asyncio.run(self._installer.download_full_voiceover(lng))
def download_voiceover_update(self, languages: str):
res_info = asyncio.run(self._launcher.get_resource_info())
for lng in languages.split(" "):
for vo in res_info.game.latest.voice_packs:
if not self._installer.voiceover_lang_translate(lng) == vo.language:
continue
print("Downloading voiceover update pack for {} (This will take a long time)...".format(lng))
asyncio.run(self._installer.download_voiceover_update(lng))
def install_game(self, forced: bool = False):
res_info = asyncio.run(self._launcher.get_resource_info())
print("Latest game version: {}".format(res_info.game.latest.version))
if not self._ask("Do you want to install the game?"):
print("Aborting game installation process.")
return
print("Downloading full game (This will take a long time)...")
asyncio.run(self._installer.download_full_game(forced))
self.download_game()
print("Installing game...")
self._install_from_archive(self._installer.temp_path.joinpath(res_info.game.latest.name))
self._install_from_archive(self._installer.temp_path.joinpath(res_info.game.latest.name), forced)
def install_voiceover(self, languages: str):
res_info = asyncio.run(self._launcher.get_resource_info())
@ -188,8 +216,16 @@ def main():
help="Patch the game (if not already patched, else do nothing)")
parser.add_argument("--login-fix", action="store_true",
help="Patch the game to fix login issues (if not already patched, else do nothing)")
parser.add_argument("-Sy", "--update", action="store", type=str,
parser.add_argument("-Sy", "--update", action="store", type=str, default="",
help="Update the game and specified voiceover pack only (or install if not found)")
parser.add_argument("-Sw", "--download-game", action="store_true",
help="Download the full game to the temporary directory")
parser.add_argument("-Swv", "--download-voiceover", action="store", type=str,
help="Download the full voiceover to the temporary directory")
parser.add_argument("-Syw", "--download-game-update", action="store", type=str, default="",
help="Download the game and the voiceover update to the temporary directory")
parser.add_argument("-Sywv", "--download-voiceover-update", action="store", type=str,
help="Download the voiceover update to the temporary directory")
parser.add_argument("-Sv", "--update-voiceover", action="store", type=str,
help="Update the voiceover pack only (or install if not found)")
parser.add_argument("-Syu", "--update-all", action="store_true",
@ -199,12 +235,15 @@ def main():
parser.add_argument("-Rv", "--remove-voiceover", action="store_true", help="Remove a Voiceover pack (if installed)")
parser.add_argument("--get-game-version", action="store_true", help="Get the current game version")
parser.add_argument("--no-overseas", action="store_true", help="Don't use overseas server")
parser.add_argument("--from-ver", action="store", help="Override the detected game version", type=str, default=None)
parser.add_argument("--noconfirm", action="store_true",
help="Do not ask any for confirmation. (Ignored in interactive mode)")
args = parser.parse_args()
interactive_mode = not args.install and not args.install_from_file and not args.patch and not args.update and not \
args.remove and not args.remove_patch and not args.remove_voiceover and not args.get_game_version and not \
args.install_voiceover_from_file and not args.update_voiceover
args.install_voiceover_from_file and not args.update_voiceover and not args.download_game and not \
args.download_voiceover and not args.download_game_update and not args.download_voiceover_update and not \
args.install_voiceover_from_file and not args.update_all and not args.login_fix
if args.temporary_dir:
args.temporary_dir.mkdir(parents=True, exist_ok=True)
@ -225,6 +264,18 @@ def main():
if args.get_game_version:
ui.get_game_version()
if args.download_game:
ui.download_game()
if args.download_voiceover:
ui.download_voiceover(args.download_voiceover)
if args.download_game_update:
ui.download_game_update()
if args.download_voiceover_update:
ui.download_voiceover_update(args.download_voiceover_update)
if args.install:
ui.install_game()

View File

@ -1,7 +1,5 @@
import os
import platform
import xdelta3
import tarfile
import appdirs
from pathlib import Path
@ -12,6 +10,12 @@ from worthless import constants
from worthless.launcher import Launcher
from worthless.installer import Installer
NO_XDELTA3_MODULE = False
try:
import xdelta3
except ImportError:
NO_XDELTA3_MODULE = True
class Patcher:
def __init__(self, gamedir=Path.cwd(), data_dir: str | Path = None, patch_url: str = None, overseas=True):
@ -147,7 +151,7 @@ class Patcher:
f.write(patched_xlua_bytes)
def apply_xlua_patch(self, fallback=True):
if fallback:
if NO_XDELTA3_MODULE or fallback:
asyncio.run(self._patch_xlua_fallback())
return
self._patch_xlua()
@ -161,7 +165,7 @@ class Patcher:
:return: None
"""
# Patch UnityPlayer.dll
if fallback:
if NO_XDELTA3_MODULE or fallback:
asyncio.run(self._patch_unityplayer_fallback())
else:
self._patch_unityplayer()