Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
pool.close()
pool.join()
print('Generating merged MSBTs...')
msyt_to_msbt(tmp_dir)
added_texts = get_added_text_mods(lang)
if added_texts:
print('Adding mod-original MSBTs...')
for added_text in added_texts:
for msbt in added_text.list_files():
Path(merge_dir / msbt).parent.mkdir(parents=True, exist_ok=True)
Path(merge_dir / msbt).write_bytes(added_text.get_file_data(msbt).tobytes())
print(f'Creating new Bootup_{lang}.pack...')
tmp_boot_path = bootup_from_msbts(lang)[0]
merged_boot_path = util.get_modpack_dir() / '9999_BCML' / 'content' / \
'Pack' / f'Bootup_{lang}.pack'
if merged_boot_path.exists():
if verbose:
print(f' Removing old Bootup_{lang}.pack...')
merged_boot_path.unlink()
merged_boot_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(str(tmp_boot_path), str(merged_boot_path))
rstb_path = util.get_modpack_dir() / '9999_BCML' / 'content' / 'System' / 'Resource' /\
'ResourceSizeTable.product.srsizetable'
if rstb_path.exists():
table: rstb.ResourceSizeTable = rstb.util.read_rstb(
str(rstb_path), True)
else:
table = rstable.get_stock_rstb()
msg_path = f'Message/Msg_{lang}.product.sarc'
for msbt in added_text.list_files():
Path(merge_dir / msbt).parent.mkdir(parents=True, exist_ok=True)
Path(merge_dir / msbt).write_bytes(added_text.get_file_data(msbt).tobytes())
print(f'Creating new Bootup_{lang}.pack...')
tmp_boot_path = bootup_from_msbts(lang)[0]
merged_boot_path = util.get_modpack_dir() / '9999_BCML' / 'content' / \
'Pack' / f'Bootup_{lang}.pack'
if merged_boot_path.exists():
if verbose:
print(f' Removing old Bootup_{lang}.pack...')
merged_boot_path.unlink()
merged_boot_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(str(tmp_boot_path), str(merged_boot_path))
rstb_path = util.get_modpack_dir() / '9999_BCML' / 'content' / 'System' / 'Resource' /\
'ResourceSizeTable.product.srsizetable'
if rstb_path.exists():
table: rstb.ResourceSizeTable = rstb.util.read_rstb(
str(rstb_path), True)
else:
table = rstable.get_stock_rstb()
msg_path = f'Message/Msg_{lang}.product.sarc'
if table.is_in_table(msg_path):
print('Correcting RSTB...')
table.delete_entry(msg_path)
rstb_path.parent.mkdir(parents=True, exist_ok=True)
rstb.util.write_rstb(table, str(rstb_path), True)
def convert_old_mods():
mod_dir = util.get_modpack_dir()
old_path = util.get_cemu_dir() / "graphicPacks" / "BCML"
print("Moving old mods...")
shutil.rmtree(mod_dir, ignore_errors=True)
try:
shutil.move(old_path, mod_dir)
except OSError:
shutil.copytree(old_path, mod_dir)
shutil.rmtree(old_path, ignore_errors=True)
print("Converting old mods...")
for mod in sorted(
{d for d in mod_dir.glob("*") if d.is_dir() and d.name != "9999_BCML"}
):
print(f"Converting {mod.name[4:]}")
try:
convert_old_mod(mod, True)
except Exception as err:
def link_master_mod(output: Path = None):
if not output:
output = util.get_cemu_dir() / 'graphicPacks' / 'BreathOfTheWild_BCML'
if output.exists():
shutil.rmtree(str(output), ignore_errors=True)
output.mkdir(parents=True, exist_ok=True)
mod_folders: List[Path] = sorted(
[item for item in util.get_modpack_dir().glob('*') if item.is_dir()],
reverse=True
)
shutil.copy(
str(util.get_master_modpack_dir() / 'rules.txt'),
str(output / 'rules.txt')
)
for mod_folder in mod_folders:
for item in mod_folder.rglob('**/*'):
rel_path = item.relative_to(mod_folder)
if (output / rel_path).exists()\
or (str(rel_path).startswith('logs'))\
or (len(rel_path.parts) == 1 and rel_path.suffix != '.txt'):
continue
if item.is_dir():
(output / rel_path).mkdir(parents=True, exist_ok=True)
elif item.is_file():
def uninstall_all(self):
for folder in {d for d in util.get_modpack_dir().glob("*") if d.is_dir()}:
rmtree(folder)
clean_error = RuntimeError()
try:
name = mod_name
except NameError:
name = 'your mod, the name of which could not be detected'
clean_error.error_text = (f'There was an error while processing {name}. '
'This could indicate there is a problem with the mod itself, '
'but it could also reflect a new or unusual edge case BCML does '
'not anticipate. Here is the error:\n\n'
f'{traceback.format_exc(limit=-4)}')
raise clean_error
priority = insert_priority
print(f'Assigned mod priority of {priority}')
mod_id = util.get_mod_id(mod_name, priority)
mod_dir = util.get_modpack_dir() / mod_id
try:
for existing_mod in util.get_installed_mods():
if existing_mod.priority >= priority:
priority_shifted = existing_mod.priority + 1
new_id = util.get_mod_id(existing_mod.name, priority_shifted)
new_path = util.get_modpack_dir() / new_id
shutil.move(str(existing_mod.path), str(new_path))
existing_mod_rules = util.RulesParser()
existing_mod_rules.read(str(new_path / 'rules.txt'))
existing_mod_rules['Definition']['fsPriority'] = str(priority_shifted)
with (new_path / 'rules.txt').open('w', encoding='utf-8') as r_file:
existing_mod_rules.write(r_file)
mod_dir.parent.mkdir(parents=True, exist_ok=True)
print()
def get_next_priority() -> int:
""" Gets the next available mod priority """
i = 100
while list(util.get_modpack_dir().glob(f'{i:04}_*')):
i += 1
return i
Creates a backup of the current mod installations. Saves it as a 7z file in
`CEMU_DIR/bcml_backups`.
:param name: The name to give the backup, defaults to "BCML_Backup_YYYY-MM-DD"
:type name: str, optional
"""
import re
if not name:
name = f'BCML_Backup_{datetime.datetime.now().strftime("%Y-%m-%d")}'
else:
name = re.sub(r'(?u)[^-\w.]', '', name.strip().replace(' ', '_'))
output = util.get_cemu_dir() / 'bcml_backups' / f'{name}.7z'
output.parent.mkdir(parents=True, exist_ok=True)
print(f'Saving backup {name}...')
x_args = [str(util.get_exec_dir() / 'helpers' / '7z.exe'),
'a', str(output), f'{str(util.get_modpack_dir() / "*")}']
subprocess.run(x_args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, creationflags=util.CREATE_NO_WINDOW)
print(f'Backup "{name}" created')
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'):
print('Exporting BNP...')