feat(cli/hsr): implement 'voicepack install' & other changes
Rename 'voicepack update-all' to 'voicepack update', allowing update only a voicepack instead of having to upate all of them
This commit is contained in:
@ -31,8 +31,8 @@ since I want to support other anime games and the launcher code is very messy, t
|
|||||||
- [x] Repair the game (Smarter than the official launcher!)
|
- [x] Repair the game (Smarter than the official launcher!)
|
||||||
- [x] Update the game
|
- [x] Update the game
|
||||||
- [x] Update voicepacks
|
- [x] Update voicepacks
|
||||||
- [ ] Uninstall the game (Just remove the game files)
|
- [ ] Uninstall the game (Just remove the game directory lol)
|
||||||
- [ ] Voicepacks installation
|
- [x] Voicepacks installation
|
||||||
#### Advanced features
|
#### Advanced features
|
||||||
- [x] Apply the update archives
|
- [x] Apply the update archives
|
||||||
- [x] Download the update archives
|
- [x] Download the update archives
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from cleo.helpers import option, argument
|
|||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from pathlib import PurePath
|
from pathlib import PurePath
|
||||||
from platform import system
|
from platform import system
|
||||||
from vollerei.common.enums import GameChannel
|
from vollerei.common.enums import GameChannel, VoicePackLanguage
|
||||||
from vollerei.cli import utils
|
from vollerei.cli import utils
|
||||||
from vollerei.exceptions.game import GameError
|
from vollerei.exceptions.game import GameError
|
||||||
from vollerei.hsr import Game, Patcher
|
from vollerei.hsr import Game, Patcher
|
||||||
@ -129,9 +129,97 @@ class VoicepackList(Command):
|
|||||||
self.line(f"Available voicepacks: {', '.join(available_voicepacks_str)}")
|
self.line(f"Available voicepacks: {', '.join(available_voicepacks_str)}")
|
||||||
|
|
||||||
|
|
||||||
class VoicepackUpdateAll(Command):
|
class VoicepackInstall(Command):
|
||||||
name = "hsr voicepack update-all"
|
name = "hsr voicepack install"
|
||||||
description = "Updates all installed voicepacks"
|
description = (
|
||||||
|
"Installs the specified installed voicepacks"
|
||||||
|
)
|
||||||
|
options = default_options + [
|
||||||
|
option("pre-download", description="Pre-download the game if available"),
|
||||||
|
]
|
||||||
|
arguments = [
|
||||||
|
argument(
|
||||||
|
"language", description="Languages to install", multiple=True, optional=True
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
def handle(self):
|
||||||
|
callback(command=self)
|
||||||
|
pre_download = self.option("pre-download")
|
||||||
|
# Typing manually because pylance detect it as Any
|
||||||
|
languages: list[str] = self.argument("language")
|
||||||
|
# Get installed voicepacks
|
||||||
|
language_objects = []
|
||||||
|
for language in languages:
|
||||||
|
language = language.lower()
|
||||||
|
try:
|
||||||
|
language_objects.append(VoicePackLanguage[language.capitalize()])
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
language_objects.append(VoicePackLanguage.from_remote_str(language))
|
||||||
|
except ValueError:
|
||||||
|
self.line_error(f"<error>Invalid language: {language}</error>")
|
||||||
|
if len(language_objects) == 0:
|
||||||
|
self.line_error(
|
||||||
|
"<error>No valid languages specified, you must specify a language to install</error>"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
progress = utils.ProgressIndicator(self)
|
||||||
|
progress.start("Fetching install package information... ")
|
||||||
|
try:
|
||||||
|
game_info = State.game.get_remote_game(pre_download=pre_download)
|
||||||
|
except Exception as e:
|
||||||
|
progress.finish(
|
||||||
|
f"<error>Fetching failed with following error: {e} \n{traceback.format_exc()}</error>"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
progress.finish(
|
||||||
|
"<comment>Installation information fetched successfully.</comment>"
|
||||||
|
)
|
||||||
|
if not self.confirm("Do you want to install the specified voicepacks?"):
|
||||||
|
self.line("<error>Installation aborted.</error>")
|
||||||
|
return
|
||||||
|
# Voicepack update
|
||||||
|
for remote_voicepack in game_info.major.audio_pkgs:
|
||||||
|
if remote_voicepack.language not in language_objects:
|
||||||
|
continue
|
||||||
|
self.line(
|
||||||
|
f"Downloading install package for language: <comment>{remote_voicepack.language.name}</comment>... "
|
||||||
|
)
|
||||||
|
archive_file = State.game.cache.joinpath(PurePath(remote_voicepack.url).name)
|
||||||
|
try:
|
||||||
|
download_result = utils.download(
|
||||||
|
remote_voicepack.url, archive_file, file_len=remote_voicepack.size
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.line_error(f"<error>Couldn't download package: {e}</error>")
|
||||||
|
return
|
||||||
|
if not download_result:
|
||||||
|
self.line_error("<error>Download failed.</error>")
|
||||||
|
return
|
||||||
|
self.line("Download completed.")
|
||||||
|
progress = utils.ProgressIndicator(self)
|
||||||
|
progress.start("Installing package...")
|
||||||
|
try:
|
||||||
|
State.game.install_archive(archive_file)
|
||||||
|
except Exception as e:
|
||||||
|
progress.finish(
|
||||||
|
f"<error>Couldn't apply package: {e} \n{traceback.format_exc()}</error>"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
progress.finish(
|
||||||
|
f"<comment>Package applied for language {remote_voicepack.language.name}.</comment>"
|
||||||
|
)
|
||||||
|
self.line(
|
||||||
|
f"The voicepacks have been installed to version: <comment>{State.game.get_version_str()}</comment>"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VoicepackUpdate(Command):
|
||||||
|
name = "hsr voicepack update"
|
||||||
|
description = (
|
||||||
|
"Updates the specified installed voicepacks, if not specified, updates all"
|
||||||
|
)
|
||||||
options = default_options + [
|
options = default_options + [
|
||||||
option(
|
option(
|
||||||
"auto-repair", "R", description="Automatically repair the game if needed"
|
"auto-repair", "R", description="Automatically repair the game if needed"
|
||||||
@ -141,23 +229,44 @@ class VoicepackUpdateAll(Command):
|
|||||||
"from-version", description="Update from a specific version", flag=False
|
"from-version", description="Update from a specific version", flag=False
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
arguments = [
|
||||||
|
argument(
|
||||||
|
"language", description="Languages to update", multiple=True, optional=True
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
callback(command=self)
|
callback(command=self)
|
||||||
auto_repair = self.option("auto-repair")
|
auto_repair = self.option("auto-repair")
|
||||||
pre_download = self.option("pre-download")
|
pre_download = self.option("pre-download")
|
||||||
from_version = self.option("from-version")
|
from_version = self.option("from-version")
|
||||||
|
# Typing manually because pylance detect it as Any
|
||||||
|
languages: list[str] = self.argument("language")
|
||||||
if auto_repair:
|
if auto_repair:
|
||||||
self.line("<comment>Auto-repair is enabled.</comment>")
|
self.line("<comment>Auto-repair is enabled.</comment>")
|
||||||
if from_version:
|
if from_version:
|
||||||
self.line(f"Updating from version: <comment>{from_version}</comment>")
|
self.line(f"Updating from version: <comment>{from_version}</comment>")
|
||||||
State.game.version_override = from_version
|
State.game.version_override = from_version
|
||||||
# Get installed voicepacks
|
# Get installed voicepacks
|
||||||
|
if len(languages) == 0:
|
||||||
|
self.line(
|
||||||
|
"<comment>No languages specified, updating all installed voicepacks...</comment>"
|
||||||
|
)
|
||||||
installed_voicepacks = State.game.get_installed_voicepacks()
|
installed_voicepacks = State.game.get_installed_voicepacks()
|
||||||
|
if len(languages) > 0:
|
||||||
|
languages = [x.lower() for x in languages]
|
||||||
|
# Support both English and en-us and en
|
||||||
|
installed_voicepacks = [
|
||||||
|
x
|
||||||
|
for x in installed_voicepacks
|
||||||
|
if x.name.lower() in languages
|
||||||
|
or x.value.lower() in languages
|
||||||
|
or x.name.lower()[:2] in languages
|
||||||
|
]
|
||||||
installed_voicepacks_str = [
|
installed_voicepacks_str = [
|
||||||
f"<comment>{str(x.name)}</comment>" for x in installed_voicepacks
|
f"<comment>{str(x.name)}</comment>" for x in installed_voicepacks
|
||||||
]
|
]
|
||||||
self.line(f"Installed voicepacks: {', '.join(installed_voicepacks_str)}")
|
self.line(f"Updating voicepacks: {', '.join(installed_voicepacks_str)}")
|
||||||
progress = utils.ProgressIndicator(self)
|
progress = utils.ProgressIndicator(self)
|
||||||
progress.start("Checking for updates... ")
|
progress.start("Checking for updates... ")
|
||||||
try:
|
try:
|
||||||
@ -684,7 +793,7 @@ class InstallDownloadCommand(Command):
|
|||||||
self.line_error("<error>Download failed.</error>")
|
self.line_error("<error>Download failed.</error>")
|
||||||
return
|
return
|
||||||
self.line("Download completed.")
|
self.line("Download completed.")
|
||||||
|
|
||||||
|
|
||||||
class UpdateDownloadCommand(Command):
|
class UpdateDownloadCommand(Command):
|
||||||
name = "hsr update download"
|
name = "hsr update download"
|
||||||
@ -838,7 +947,8 @@ commands = [
|
|||||||
UpdatePatchCommand,
|
UpdatePatchCommand,
|
||||||
UpdateCommand,
|
UpdateCommand,
|
||||||
UpdateDownloadCommand,
|
UpdateDownloadCommand,
|
||||||
|
VoicepackInstall,
|
||||||
VoicepackList,
|
VoicepackList,
|
||||||
VoicepackListInstalled,
|
VoicepackListInstalled,
|
||||||
VoicepackUpdateAll,
|
VoicepackUpdate,
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user