#!/usr/bin/python3 import argparse import appdirs from pathlib import Path from worthless.launcher import Launcher from worthless.installer import Installer from worthless.patcher import Patcher import worthless.constants as constants class UI: def __init__(self, gamedir: str, noconfirm: bool, tempdir: str | Path = None) -> None: self._noconfirm = noconfirm self._gamedir = gamedir self._launcher = Launcher(gamedir) self._installer = Installer(gamedir, data_dir=tempdir) self._patcher = Patcher(gamedir) @staticmethod def _ask(question): answer = "" while answer.lower() not in ['y', 'n']: if answer != "": print("Invalid choice, please try again.") answer = input(question + " (y/n): ") return answer.lower() == 'y' def get_game_version(self): print(self._installer.get_game_version()) def _update_from_archive(self, filepath): print("Reverting patches if patched...") self._patcher.revert_patch(True) print("Updating game from archive (this may takes some time)...") self._installer.update_game(filepath) def _install_from_archive(self, filepath): print("Installing game from archive (this may takes some time)...") self._installer.install_game(filepath) def _apply_voiceover_from_archive(self, filepath): print("Applying voiceover from archive (this may takes some time)...") self._installer.apply_voiceover(filepath) def install_voiceover_from_file(self, filepath): print("Archive voiceover language: {} ({})".format( self._installer.get_voiceover_archive_language(filepath), "Full archive" if self._installer.get_voiceover_archive_type(filepath) else "Update archive")) if not self._ask("Do you want to apply this voiceover pack? ({})".format(filepath)): print("Aborting apply process.") return self._apply_voiceover_from_archive(filepath) print("Voiceover applied successfully.") def revert_patch(self): print("Reverting patches...") self._patcher.revert_patch(True) print("Patches reverted.") def install_from_file(self, filepath): gamever = self._installer.get_game_version() print("Archive game version: " + self._installer.get_game_archive_version(filepath)) if gamever: print("Current game installation detected. ({})".format(self._installer.get_game_version())) if not self._ask("Do you want to update the game? ({})".format(filepath)): print("Aborting update process.") return self._update_from_archive(filepath) print("Game updated successfully.") else: print("No game installation detected.") if not self._ask("Do you want to install the game? ({})".format(filepath)): print("Aborting installation process.") return self._install_from_archive(filepath) print("Game installed successfully.") def install_game(self): # TODO raise NotImplementedError("Install game is not implemented.") def update_game(self): print("Checking for current game version...") # Call check_game_version() print("Updating game...") # Call update_game(fromver) raise NotImplementedError("Update game is not implemented.") def interactive_ui(self): raise NotImplementedError() def main(): default_dirs = appdirs.AppDirs(constants.APP_NAME, constants.APP_AUTHOR) parser = argparse.ArgumentParser(prog="worthless", description="A worthless launcher written in Python.") parser.add_argument("-D", "--dir", action="store", type=Path, default=Path.cwd(), help="Specify the game directory (default current working directory)") parser.add_argument("-W", "--temporary-dir", action="store", type=Path, default=None, help="Specify the temporary directory (default {} and {})".format(default_dirs.user_data_dir, default_dirs.user_cache_dir)) parser.add_argument("-S", "--install", action="store_true", help="Install/update the game (if not already installed, else do nothing)") parser.add_argument("-U", "--install-from-file", action="store", type=Path, default=None, help="Install the game from an archive (if not already installed, \ else update from archive)") parser.add_argument("-Uv", "--install-voiceover-from-file", action="store", type=Path, default=None, help="Install the voiceover from an archive (if not already installed, \ else update from archive)") parser.add_argument("-Sp", "--patch", action="store_true", help="Patch the game (if not already patched, else do nothing)") parser.add_argument("-Sy", "--update", action="store_true", help="Update the game and specified voiceover pack only (or install if not found)") parser.add_argument("-Sv", "--update-voiceover", action="store_true", help="Update the voiceover pack only (or install if not found)") parser.add_argument("-Syu", "--update-all", action="store_true", help="Update the game and all installed voiceover packs (or install if not found)") parser.add_argument("-Rs", "--remove", action="store_true", help="Remove the game (if installed)") parser.add_argument("-Rp", "--remove-patch", action="store_true", help="Revert the game patch (if patched)") 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("--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 if args.temporary_dir: args.temporary_dir.mkdir(parents=True, exist_ok=True) ui = UI(args.dir, args.noconfirm, args.temporary_dir) if args.install and args.update: raise ValueError("Cannot specify both --install and --update arguments.") if args.install_from_file and args.update: raise ValueError("Cannot specify both --install-from-file and --update arguments.") if args.install_voiceover_from_file and args.update: raise ValueError("Cannot specify both --install-voiceover-from-file and --update arguments.") if args.install_from_file and args.install: raise ValueError("Cannot specify both --install-from-file and --install arguments.") if args.get_game_version: ui.get_game_version() if args.install: ui.install_game() if args.update: ui.update_game() if args.install_from_file: ui.install_from_file(args.install_from_file) if args.install_voiceover_from_file: ui.install_voiceover_from_file(args.install_voiceover_from_file) if args.remove_patch: ui.revert_patch() if interactive_mode: ui.interactive_ui() if __name__ == "__main__": main()