mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-05 20:28:27 +02:00
extracted szs directory will now be repacked into szs files
This commit is contained in:
parent
7f5e709aec
commit
4d071e190f
4 changed files with 57 additions and 11 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import shutil
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Generator, IO
|
from typing import Generator, IO
|
||||||
|
@ -5,6 +6,7 @@ from typing import Generator, IO
|
||||||
from source.mkw.ModConfig import ModConfig
|
from source.mkw.ModConfig import ModConfig
|
||||||
from source.mkw.Patch.Patch import Patch
|
from source.mkw.Patch.Patch import Patch
|
||||||
from source.wt import szs
|
from source.wt import szs
|
||||||
|
from source.wt.wstrt import StrPath
|
||||||
|
|
||||||
|
|
||||||
class ExtractedGame:
|
class ExtractedGame:
|
||||||
|
@ -12,12 +14,12 @@ class ExtractedGame:
|
||||||
Class that represents an extracted game
|
Class that represents an extracted game
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, path: Path | str, original_game: "Game" = None):
|
def __init__(self, path: "Path | str", original_game: "Game" = None):
|
||||||
self.path = Path(path)
|
self.path = Path(path)
|
||||||
self.original_game = original_game
|
self.original_game = original_game
|
||||||
self._special_file: dict[str, IO] = {}
|
self._special_file: dict[str, IO] = {}
|
||||||
|
|
||||||
def extract_autoadd(self, destination_path: Path | str) -> Generator[dict, None, None]:
|
def extract_autoadd(self, destination_path: "Path | str") -> Generator[dict, None, None]:
|
||||||
"""
|
"""
|
||||||
Extract all the autoadd files from the game to destination_path
|
Extract all the autoadd files from the game to destination_path
|
||||||
:param destination_path: directory where the autoadd files will be extracted
|
:param destination_path: directory where the autoadd files will be extracted
|
||||||
|
@ -45,12 +47,31 @@ class ExtractedGame:
|
||||||
ct_icons.seek(0)
|
ct_icons.seek(0)
|
||||||
self._special_file["ct_icon"] = ct_icons
|
self._special_file["ct_icon"] = ct_icons
|
||||||
|
|
||||||
|
def prepare_dol(self) -> Generator[dict, None, None]:
|
||||||
|
"""
|
||||||
|
Prepare main.dol and StaticR.rel files (clean them and add lecode)
|
||||||
|
"""
|
||||||
|
yield {"description": "Preparing main.dol...", "determinate": False}
|
||||||
|
StrPath(self.path / "sys/main.dol").patch(clean_dol=True, add_lecode=True)
|
||||||
|
|
||||||
|
def recreate_all_szs(self) -> Generator[dict, None, None]:
|
||||||
|
"""
|
||||||
|
Repack all the .d directory into .szs files.
|
||||||
|
:param extracted_game: the extracted game
|
||||||
|
"""
|
||||||
|
yield {"description": f"Repacking all szs", "determinate": False}
|
||||||
|
|
||||||
|
for extracted_szs in filter(lambda path: path.is_dir(), self.path.rglob("*.d")):
|
||||||
|
# for every directory that end with a .d in the extracted game, recreate the szs
|
||||||
|
yield {"description": f"Repacking {extracted_szs} to szs", "determinate": False}
|
||||||
|
|
||||||
|
szs.create(extracted_szs, extracted_szs.with_suffix(".szs"), overwrite=True)
|
||||||
|
shutil.rmtree(str(extracted_szs.resolve()))
|
||||||
|
|
||||||
def install_all_patch(self, mod_config: ModConfig) -> Generator[dict, None, None]:
|
def install_all_patch(self, mod_config: ModConfig) -> Generator[dict, None, None]:
|
||||||
"""
|
"""
|
||||||
Install all patchs of the mod_config into the game
|
Install all patchs of the mod_config into the game
|
||||||
:param special_file: special file that can be used to patch the game
|
|
||||||
:param mod_config: the mod to install
|
:param mod_config: the mod to install
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
yield {"description": "Installing all Patch...", "determinate": False}
|
yield {"description": "Installing all Patch...", "determinate": False}
|
||||||
|
|
||||||
|
@ -62,3 +83,4 @@ class ExtractedGame:
|
||||||
for part_directory in mod_config.get_mod_directory().glob("[!_]*"):
|
for part_directory in mod_config.get_mod_directory().glob("[!_]*"):
|
||||||
for patch_directory in part_directory.glob("_PATCH/"):
|
for patch_directory in part_directory.glob("_PATCH/"):
|
||||||
yield from Patch(patch_directory, mod_config, self._special_file).install(self)
|
yield from Patch(patch_directory, mod_config, self._special_file).install(self)
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,19 @@ from source.wt.wit import WITPath, Region, Extension
|
||||||
|
|
||||||
|
|
||||||
class NotMKWGameError(Exception):
|
class NotMKWGameError(Exception):
|
||||||
def __init__(self, path: Path | str):
|
def __init__(self, path: "Path | str"):
|
||||||
path = Path(path)
|
path = Path(path)
|
||||||
super().__init__(f'Not a Mario Kart Wii game : "{path.name}"')
|
super().__init__(f'Not a Mario Kart Wii game : "{path.name}"')
|
||||||
|
|
||||||
|
|
||||||
class NotVanillaError(Exception):
|
class NotVanillaError(Exception):
|
||||||
def __init__(self, path: Path | str):
|
def __init__(self, path: "Path | str"):
|
||||||
path = Path(path)
|
path = Path(path)
|
||||||
super().__init__(f'This game is already modded : "{path.name}"')
|
super().__init__(f'This game is already modded : "{path.name}"')
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
def is_mkw(self) -> bool:
|
def is_mkw(self) -> bool:
|
||||||
|
@ -36,7 +36,7 @@ class Game:
|
||||||
"""
|
"""
|
||||||
return not any(self.wit_path[f"./files/rel/lecode-{region.value}.bin"].exists() for region in Region)
|
return not any(self.wit_path[f"./files/rel/lecode-{region.value}.bin"].exists() for region in Region)
|
||||||
|
|
||||||
def extract(self, dest: Path | str) -> Generator[dict, None, Path]:
|
def extract(self, dest: "Path | str") -> Generator[dict, None, Path]:
|
||||||
"""
|
"""
|
||||||
Extract the game to the destination directory. If the game is a FST, just copy to the destination
|
Extract the game to the destination directory. If the game is a FST, just copy to the destination
|
||||||
:param dest: destination directory
|
:param dest: destination directory
|
||||||
|
@ -67,7 +67,7 @@ class Game:
|
||||||
return e.value
|
return e.value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_output_directory(dest: Path | str, mod_config: ModConfig) -> Path:
|
def get_output_directory(dest: "Path | str", mod_config: ModConfig) -> Path:
|
||||||
"""
|
"""
|
||||||
Return the directory where the game will be installed
|
Return the directory where the game will be installed
|
||||||
:param dest: destination directory
|
:param dest: destination directory
|
||||||
|
@ -107,5 +107,7 @@ class Game:
|
||||||
yield from self.extract(extracted_game.path)
|
yield from self.extract(extracted_game.path)
|
||||||
yield from extracted_game.extract_autoadd(cache_directory / "autoadd/")
|
yield from extracted_game.extract_autoadd(cache_directory / "autoadd/")
|
||||||
yield from extracted_game.install_mystuff()
|
yield from extracted_game.install_mystuff()
|
||||||
|
yield from extracted_game.prepare_dol()
|
||||||
yield from extracted_game.install_all_patch(mod_config)
|
yield from extracted_game.install_all_patch(mod_config)
|
||||||
|
yield from extracted_game.recreate_all_szs()
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from typing import Generator, IO
|
||||||
|
|
||||||
from source.mkw.Patch import *
|
from source.mkw.Patch import *
|
||||||
from source.safe_eval import safe_eval, multiple_safe_eval
|
from source.safe_eval import safe_eval, multiple_safe_eval
|
||||||
|
from source.wt import szs
|
||||||
|
|
||||||
|
|
||||||
class Patch:
|
class Patch:
|
||||||
|
@ -34,8 +35,10 @@ class Patch:
|
||||||
def install(self, extracted_game: "ExtractedGame") -> Generator[dict, None, None]:
|
def install(self, extracted_game: "ExtractedGame") -> Generator[dict, None, None]:
|
||||||
"""
|
"""
|
||||||
patch a game with this Patch
|
patch a game with this Patch
|
||||||
|
:param extracted_game: the extracted game
|
||||||
"""
|
"""
|
||||||
from source.mkw.Patch.PatchDirectory import PatchDirectory
|
from source.mkw.Patch.PatchDirectory import PatchDirectory
|
||||||
|
yield {"description": f"Installing the patch", "determinate": False}
|
||||||
|
|
||||||
# take all the files in the root directory, and patch them into the game.
|
# take all the files in the root directory, and patch them into the game.
|
||||||
# Patch is not directly applied to the root to avoid custom configuration
|
# Patch is not directly applied to the root to avoid custom configuration
|
||||||
|
|
|
@ -21,6 +21,25 @@ def autoadd(course_directory: Path | str, destination_path: Path | str) -> Path:
|
||||||
return destination_path
|
return destination_path
|
||||||
|
|
||||||
|
|
||||||
|
@better_wt_error(tools_path)
|
||||||
|
def create(extracted_szs: Path | str, dest: Path | str, overwrite: bool = False) -> "SZSPath":
|
||||||
|
"""
|
||||||
|
Convert extracted_szs into a szs archive
|
||||||
|
:param overwrite: should the destination be overwritten
|
||||||
|
:param dest: destination where to create the szs file
|
||||||
|
:param extracted_szs: the extracted szs directory
|
||||||
|
:return: a SZSPath
|
||||||
|
"""
|
||||||
|
extracted_szs = Path(extracted_szs)
|
||||||
|
dest = Path(dest)
|
||||||
|
|
||||||
|
args = []
|
||||||
|
if overwrite: args.append("--overwrite")
|
||||||
|
|
||||||
|
_tools_run("CREATE", extracted_szs, "--DEST", dest, *args)
|
||||||
|
return SZSPath(dest)
|
||||||
|
|
||||||
|
|
||||||
class SZSPath:
|
class SZSPath:
|
||||||
__slots__ = ("path", "_analyze")
|
__slots__ = ("path", "_analyze")
|
||||||
|
|
||||||
|
@ -40,7 +59,7 @@ class SZSPath:
|
||||||
:param subfile: subfile name
|
:param subfile: subfile name
|
||||||
:return: the content of the subfile
|
:return: the content of the subfile
|
||||||
"""
|
"""
|
||||||
return _tools_run("cat", self.path / subfile)
|
return _tools_run("cat", (self.path / subfile))
|
||||||
|
|
||||||
def extract(self, subfile: str, dest: Path | str) -> Path:
|
def extract(self, subfile: str, dest: Path | str) -> Path:
|
||||||
"""
|
"""
|
||||||
|
@ -60,7 +79,7 @@ class SZSPath:
|
||||||
dest: Path = Path(dest)
|
dest: Path = Path(dest)
|
||||||
if dest.is_dir(): dest /= self.path.name
|
if dest.is_dir(): dest /= self.path.name
|
||||||
|
|
||||||
_tools_run("EXTRACT", self.path, "-D", dest)
|
_tools_run("EXTRACT", self.path, "--DEST", dest)
|
||||||
return dest
|
return dest
|
||||||
|
|
||||||
def analyze(self) -> dict:
|
def analyze(self) -> dict:
|
||||||
|
|
Loading…
Reference in a new issue