Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def main(debug: bool = False):
set_start_method("spawn", True)
global logger # pylint: disable=invalid-name,global-statement
logger = None
try:
if SYSTEM != "Windows":
chmod(util.get_exec_dir() / "helpers/msyt", int("755", 8))
chmod(util.get_exec_dir() / "helpers/7z", int("755", 8))
LOG.parent.mkdir(parents=True, exist_ok=True)
for folder in util.get_work_dir().glob("*"):
rmtree(folder)
except (FileNotFoundError, OSError, PermissionError):
pass
_oneclick.register_handlers()
oneclick = Thread(target=_oneclick.listen)
oneclick.daemon = True
oneclick.start()
server_port = util.get_open_port()
server = Process(target=start_server, args=(server_port,))
server.daemon = True
server.start()
host = f"http://localhost:{server_port}"
api = Api(host)
def extract_ref_msyts(lang: str = 'USen', for_merge: bool = False,
tmp_dir: Path = util.get_work_dir() / 'tmp_text'):
"""
Extracts the reference MSYT texts for the given language to a temp dir
:param lang: The game language to use, defaults to USen.
:type lang: str, optional
:param for_merge: Whether the output is to be merged (or as reference), defaults to False
:type for_merge: bool
:param tmp_dir: The temp directory to extract to, defaults to "tmp_text" in BCML's working
directory.
:type tmp_dir: class:`pathlib.Path`, optional
"""
if tmp_dir.exists():
shutil.rmtree(tmp_dir, ignore_errors=True)
with util.get_game_file(f'Pack/Bootup_{lang}.pack').open('rb') as b_file:
bootup_pack = sarc.read_file_and_make_sarc(b_file)
def export(self, output: Path):
print('Loading files...')
tmp_dir = util.get_work_dir() / 'tmp_export'
if tmp_dir.drive != util.get_modpack_dir().drive:
tmp_dir = Path(util.get_modpack_dir().drive) / 'tmp_bcml_export'
install.link_master_mod(tmp_dir)
print('Adding rules.txt...')
rules_path = tmp_dir / 'rules.txt'
mods = util.get_installed_mods()
with rules_path.open('w', encoding='utf-8') as rules:
rules.writelines([
'[Definition]\n',
'titleIds = 00050000101C9300,00050000101C9400,00050000101C9500\n',
'name = Exported BCML Mod\n',
'path = The Legend of Zelda: Breath of the Wild/Mods/Exported BCML\n',
f'description = Exported merge of {", ".join([mod.name for mod in mods])}\n',
'version = 4\n'
])
if output.suffix == '.bnp' or output.name.endswith('.bnp.7z'):
def open_mod(path: Path) -> Path:
"""
Extracts a provided mod and returns the root path of the graphicpack inside
:param path: The path to the mod archive.
:type path: class:`pathlib.Path`
:returns: The path to the extracted root of the mod where the rules.txt file is found.
:rtype: class:`pathlib.Path`
"""
if isinstance(path, str):
path = Path(path)
tmpdir = util.get_work_dir() / f'tmp_{xxhash.xxh32(str(path)).hexdigest()}'
formats = ['.rar', '.zip', '.7z', '.bnp']
if tmpdir.exists():
shutil.rmtree(tmpdir, ignore_errors=True)
if path.suffix.lower() in formats:
x_args = [str(util.get_exec_dir() / 'helpers' / '7z.exe'),
'x', str(path), f'-o{str(tmpdir)}']
subprocess.run(x_args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, creationflags=util.CREATE_NO_WINDOW)
else:
raise Exception('The mod provided was not a supported archive (BNP, ZIP, RAR, or 7z).')
if not tmpdir.exists():
raise Exception('No files were extracted.')
rulesdir = tmpdir
found_rules = (rulesdir / 'rules.txt').exists()
if not found_rules:
for subdir in tmpdir.rglob('*'):
def get_modded_msyts(msg_sarc: sarc.SARC, lang: str = 'USen',
tmp_dir: Path = util.get_work_dir() / 'tmp_text') -> (list, dict):
"""
Gets a list of modified game text files in a given message SARC
:param msg_sarc: The message SARC to scan for changes.
:type msg_sarc: class:`sarc.SARC`
:param lang: The game language to use, defaults to USen.
:type lang: str, optional
:param tmp_dir: The temp directory to use, defaults to "tmp_text" in BCML's working directory.
:type tmp_dir: class:`pathlib.Path`, optional
:returns: Returns a tuple containing a list of modded text files and a dict of new text
files with their contents.
:rtype: (list of str, dict of str: bytes)
"""
hashes = get_msbt_hashes(lang)
modded_msyts = []
added_msbts = {}
def msyt_to_msbt(tmp_dir: Path = util.get_work_dir() / 'tmp_text'):
""" Converts merged MSYTs in given temp dir to MSBTs """
msyt_bin = util.get_exec_dir() / 'helpers' / 'msyt.exe'
merge_dir = tmp_dir / 'merged'
m_args = [str(msyt_bin), 'create', '-d', str(merge_dir),
'-p', 'wiiu', '-o', str(merge_dir)]
subprocess.run(m_args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, creationflags=util.CREATE_NO_WINDOW)
for merged_msyt in merge_dir.rglob('**/*.msyt'):
merged_msyt.unlink()
def bootup_from_msbts(lang: str = 'USen',
msbt_dir: Path = util.get_work_dir() / 'tmp_text' / 'merged') -> (Path, int):
"""
Generates a new Bootup_XXxx.pack from a directory of MSBT files
:param lang: The game language to use, defaults to USen.
:type lang: str, optional
:param msbt_dir: The directory to pull MSBTs from, defaults to "tmp_text/merged" in BCML's
working directory.
:type msbt_dir: class:`pathlib.Path`, optional
:returns: A tuple with the path to the new Bootup_XXxx.pack and the RSTB size of the new
Msg_XXxx.product.sarc
:rtype: (class:`pathlib.Path`, int)
"""
new_boot_path = msbt_dir.parent / f'Bootup_{lang}.pack'
with new_boot_path.open('wb') as new_boot:
s_msg = sarc.SARCWriter(True)
for new_msbt in msbt_dir.rglob('**/*.msbt'):