added get_ctfile to Track, and implemented autoadd extraction

This commit is contained in:
Faraphel 2022-06-13 22:18:08 +02:00
parent 70ade3dc67
commit 3932716227
9 changed files with 87 additions and 21 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/.idea/ /.idea/
/.cache/
/option.json /option.json

View file

@ -77,8 +77,8 @@ class Window(tkinter.Tk):
self.after(0, self.run_after) self.after(0, self.run_after)
self.mainloop() self.mainloop()
@event.register @staticmethod
def run_after(self) -> None: def run_after() -> None:
""" """
Run after the installer has been initialised, can be used to add plugins Run after the installer has been initialised, can be used to add plugins
:return: :return:
@ -454,7 +454,13 @@ class ProgressBar(ttk.LabelFrame):
:param value: the value :param value: the value
:return: :return:
""" """
self.progress_bar.configure(mode="determinate" if value else "indeterminate") if value:
if self.progress_bar["mode"] == "indeterminate": self.progress_bar.stop()
self.progress_bar.configure(mode="determinate")
else:
if self.progress_bar["mode"] == "determinate": self.progress_bar.start(50)
self.progress_bar.configure(mode="indeterminate")
# Combobox to select the pack # Combobox to select the pack

View file

@ -1,11 +1,32 @@
import time
from pathlib import Path from pathlib import Path
from typing import Generator from typing import Generator
from source.mkw.ModConfig import ModConfig from source.mkw.ModConfig import ModConfig
from source.wt import szs
from source.wt.wit import WITPath, Region, Extension from source.wt.wit import WITPath, Region, Extension
def extract_autoadd(extracted_game: Path | str, destination_path: Path | str) -> Path:
"""
Extract all the autoadd files from the game to destination_path
:param extracted_game: path of the extracted game
:param destination_path: directory where the autoadd files will be extracted
:return: directory where the autoadd files were extracted
"""
yield {"description": "Extracting autoadd files...", "determinate": False}
szs.autoadd(extracted_game / "files/Race/Course/", destination_path)
def install_mystuff(extracted_game: Path | str) -> None:
"""
Install mystuff directory
:param extracted_game: the extracted game
:return:
"""
yield {"description": "Installing MyStuff directory...", "determinate": False}
class Game: class Game:
def __init__(self, path: Path | str): def __init__(self, path: Path | str):
self.wit_path = WITPath(path) self.wit_path = WITPath(path)
@ -34,7 +55,6 @@ class Game:
yield { yield {
"description": f'EXTRACTING - {gen_data["percentage"]}% - (estimated time remaining: ' "description": f'EXTRACTING - {gen_data["percentage"]}% - (estimated time remaining: '
f'{gen_data["estimation"] if gen_data["estimation"] is not None else "-:--"})', f'{gen_data["estimation"] if gen_data["estimation"] is not None else "-:--"})',
"maximum": 100, "maximum": 100,
"value": gen_data["percentage"], "value": gen_data["percentage"],
"determinate": True "determinate": True
@ -43,6 +63,25 @@ class Game:
except StopIteration as e: except StopIteration as e:
return e.value return e.value
def get_output_directory(self, dest: Path | str, mod_config: ModConfig) -> Path:
"""
Return the directory where the game will be installed
:param mod_config: mod configuration
:return: directory where the game will be installed
"""
dest = Path(dest)
extracted_game: Path = Path(dest / f"{mod_config.nickname} {mod_config.version}")
dest_name: str = extracted_game.name
# if the directory already exist, add a number to the name
i: int = 0
while extracted_game.exists():
i += 1
extracted_game = extracted_game.with_name(dest_name + f" ({i})")
return extracted_game
def install_mod(self, dest: Path, mod_config: ModConfig, output_type: Extension) -> Generator[dict, None, None]: def install_mod(self, dest: Path, mod_config: ModConfig, output_type: Extension) -> Generator[dict, None, None]:
""" """
Patch the game with the mod Patch the game with the mod
@ -50,6 +89,14 @@ class Game:
:mod_config: mod configuration :mod_config: mod configuration
:output_type: type of the destination game :output_type: type of the destination game
""" """
# yield from self.extract(dest / f"{mod_config.nickname} {mod_config.version}") # create a cache directory for some files
print(mod_config.get_ctfile()) cache_directory: Path = Path("./.cache")
yield {} cache_directory.mkdir(parents=True, exist_ok=True)
# get the directory where the game will be extracted
extracted_game: Path = self.get_output_directory(dest, mod_config)
yield from self.extract(extracted_game)
yield from extract_autoadd(extracted_game, cache_directory / "autoadd/")
yield from install_mystuff(extracted_game)

View file

@ -34,9 +34,9 @@ class ModConfig:
self.default_track: "Track | TrackGroup" = default_track if default_track is not None else None self.default_track: "Track | TrackGroup" = default_track if default_track is not None else None
self._tracks: list["Track | TrackGroup"] = tracks if tracks is not None else [] self._tracks: list["Track | TrackGroup"] = tracks if tracks is not None else []
self.track_formatting: dict[str, str] = { self.track_formatting: dict[str, str] = {
"menu_name": "{{ getattr(track, 'name', '/') }}", "menu_name": "{{ getattr(track, 'name', '') }}",
"race_name": "{{ getattr(track, 'name', '/') }}", "race_name": "{{ getattr(track, 'name', '') }}",
"file_name": "{{ getattr(track, 'sha1', '/') }}" "file_name": "{{ getattr(track, 'sha1', '_') }}",
} | (track_formatting if track_formatting is not None else {}) } | (track_formatting if track_formatting is not None else {})
self.original_track_prefix: bool = original_track_prefix if original_track_prefix is not None else True self.original_track_prefix: bool = original_track_prefix if original_track_prefix is not None else True

View file

@ -103,7 +103,6 @@ class Track:
:hidden: if the track is in a group :hidden: if the track is in a group
:return: ctfile :return: ctfile
""" """
# TODO: filename, info and - are not implemented
menu_name = f'{self.repr_format(mod_config=mod_config, format=mod_config.track_formatting["menu_name"])!r}' menu_name = f'{self.repr_format(mod_config=mod_config, format=mod_config.track_formatting["menu_name"])!r}'
file_name = f'{self.repr_format(mod_config=mod_config, format=mod_config.track_formatting["file_name"])!r}' file_name = f'{self.repr_format(mod_config=mod_config, format=mod_config.track_formatting["file_name"])!r}'

View file

@ -43,7 +43,7 @@ class Option:
:return: None :return: None
""" """
if option_file is None: option_file = self._path if option_file is None: option_file = self._path
if isinstance(option_file, str): option_file = Path(option_file) option_file = Path(option_file)
with option_file.open("w") as file: with option_file.open("w") as file:
json.dump(self._options, file, indent=4, ensure_ascii=False) json.dump(self._options, file, indent=4, ensure_ascii=False)
@ -68,7 +68,7 @@ class Option:
:param option_file: the option file :param option_file: the option file
:return: Option :return: Option
""" """
if isinstance(option_file, str): option_file = Path(option_file) option_file = Path(option_file)
if not option_file.exists(): obj = cls() if not option_file.exists(): obj = cls()
else: obj = cls.from_dict(json.loads(option_file.read_text(encoding="utf8"))) else: obj = cls.from_dict(json.loads(option_file.read_text(encoding="utf8")))

View file

@ -44,7 +44,7 @@ class SafeFunction:
:return: the attribute value :return: the attribute value
""" """
attr = getattr(obj, attr) if default is None else getattr(obj, attr, default) attr = getattr(obj, attr) if default is None else getattr(obj, attr, default)
if callable(attr): raise AttributeError(f"getattr can't be used for functions (tried: tr{attr})") if callable(attr): raise AttributeError(f"getattr can't be used for functions (tried: {attr})")
return attr return attr

View file

@ -4,11 +4,24 @@ from source.wt import _run, _run_dict
tools_path = tools_szs_dir / ("wszst.exe" if system == "win64" else "wszst") tools_path = tools_szs_dir / ("wszst.exe" if system == "win64" else "wszst")
@better_wt_error(tools_path)
def autoadd(course_directory: Path | str, destination_path: Path | str) -> Path:
"""
Extract all the autoadd files from course_directory to destination_path
:param course_directory: directory with all the default tracks of the game
:param destination_path: directory where the autoadd files will be extracted
:return: directory where the autoadd files were extracted
"""
destination_path = Path(destination_path)
_run(tools_path, "AUTOADD", course_directory, "-D", destination_path)
return destination_path
class SZSPath: class SZSPath:
__slots__ = ("path", "_analyze") __slots__ = ("path", "_analyze")
def __init__(self, path: Path | str): def __init__(self, path: Path | str):
self.path: Path = path if isinstance(path, Path) else Path(path) self.path: Path = Path(path)
self._analyze = None self._analyze = None
def __repr__(self) -> str: def __repr__(self) -> str:
@ -58,10 +71,10 @@ class SZSPath:
:param dest: output directory :param dest: output directory
:return: :return:
""" """
dest: Path = dest if isinstance(dest, Path) else Path(dest) dest: Path = Path(dest)
if dest.is_dir(): dest /= self.path.name if dest.is_dir(): dest /= self.path.name
self._run("EXTRACT", self.path, "-d", dest) self._run("EXTRACT", self.path, "-D", dest)
return dest return dest
def analyze(self) -> dict: def analyze(self) -> dict:
@ -128,7 +141,7 @@ class SZSSubPath:
""" """
if self.is_dir(): raise ValueError("Can't extract a directory") if self.is_dir(): raise ValueError("Can't extract a directory")
dest: Path = dest if isinstance(dest, Path) else Path(dest) dest: Path = Path(dest)
if dest.is_dir(): dest /= self.basename() if dest.is_dir(): dest /= self.basename()
with dest.open("wb") as file: with dest.open("wb") as file:

View file

@ -35,7 +35,7 @@ class Region(enum.Enum):
""" """
PAL = "PAL" PAL = "PAL"
USA = "USA" USA = "USA"
EUR = "EUR" JAP = "JAP"
KOR = "KOR" KOR = "KOR"
@ -214,7 +214,7 @@ class WITSubPath:
:param dest: destination directory :param dest: destination directory
:return: the extracted file path :return: the extracted file path
""" """
dest: Path = dest if isinstance(dest, Path) else Path(dest) dest: Path = Path(dest)
if self.wit_path.extension == Extension.FST: if self.wit_path.extension == Extension.FST:
# if flat is used, extract the file / dir into the destination directory, without subdirectory # if flat is used, extract the file / dir into the destination directory, without subdirectory