Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
""" Generates an RSTB log for the master BCML modpack containing merged files """
print('Updating RSTB for merged files...')
diffs = {}
files = [item for item in util.get_master_modpack_dir().rglob('**/*') if item.is_file()]
guess = util.get_settings_bool('guess_merge')
for file in files:
if file.parent == 'logs':
continue
if file.suffix not in RSTB_EXCLUDE_EXTS and file.name not in RSTB_EXCLUDE_NAMES:
size = calculate_size(file)
if size == 0 and guess:
if file.suffix in util.AAMP_EXTS:
size = guess_aamp_size(file)
elif file.suffix in ['.bfres', '.sbfres']:
size = guess_bfres_size(file)
canon = util.get_canon_name(file.relative_to(util.get_master_modpack_dir()))
if canon:
diffs[canon] = size
sarc_files = [file for file in files if util.is_file_sarc(str(file)) \
and file.suffix != '.ssarc']
if sarc_files:
num_threads = min(multiprocessing.cpu_count(), len(sarc_files))
pool = original_pool or multiprocessing.Pool(processes=num_threads)
results = pool.map(_get_sizes_in_sarc, sarc_files)
for result in results:
diffs.update(result)
if not original_pool:
pool.close()
pool.join()
with (util.get_master_modpack_dir() / 'logs' / 'rstb.log').open('w', encoding='utf-8') as log:
log.write('name,size,path\n')
for canon, size in diffs.items():
new_bytes = file_bytes
del file_bytes
print(f'Deep merging file {file} failed. No changes were made.')
new_bytes = new_bytes if not yazd else util.compress(new_bytes)
output_file = (util.get_master_modpack_dir() / file)
if base_file == output_file:
output_file.unlink()
output_file.parent.mkdir(parents=True, exist_ok=True)
output_file.write_bytes(new_bytes)
del new_bytes
if magic == b'SARC' and verbose:
print(f'Finished patching files inside {file}')
elif verbose:
print(f'Finished patching {file}')
return util.get_canon_name(file), failures
util.get_aoc_dir()
except FileNotFoundError as err:
err.error_text = ('This mod uses DLC files, but you do not appear to have the DLC '
'installed. If you still want to use this mod, unpack it and '
'remove the "aoc" folder.')
raise err
aoc_field = tmp_dir / 'aoc' / '0010' / 'Pack' / 'AocMainField.pack'
if aoc_field.exists() and aoc_field.stat().st_size > 0:
with aoc_field.open('rb') as a_file:
sarc.read_file_and_make_sarc(a_file).extract_to_dir(str(tmp_dir / 'aoc' / '0010'))
aoc_field.write_bytes(b'')
for file in tmp_dir.rglob('**/*'):
if file.is_file():
canon = util.get_canon_name(file.relative_to(tmp_dir).as_posix())
if canon is None:
if verbose:
print(f'Ignored unknown file {file.relative_to(tmp_dir).as_posix()}')
continue
if util.is_file_modded(canon, file, True):
modded_files.append(file)
if verbose:
print(f'Found modded file {canon}')
else:
if 'Aoc/0010/Map/MainField' in canon:
file.unlink()
if verbose:
print(f'Ignored unmodded file {canon}')
continue
total = len(modded_files)
print(f'Found {total} modified file{"s" if total > 1 else ""}')
def _clean_sarc(file: Path, hashes: dict, tmp_dir: Path):
canon = util.get_canon_name(file.relative_to(tmp_dir))
try:
stock_file = util.get_game_file(file.relative_to(tmp_dir))
except FileNotFoundError:
return
try:
old_sarc = oead.Sarc(util.unyaz_if_needed(stock_file.read_bytes()))
except (RuntimeError, ValueError, oead.InvalidDataError):
return
old_files = {f.name for f in old_sarc.get_files()}
if canon not in hashes:
return
try:
base_sarc = oead.Sarc(util.unyaz_if_needed(file.read_bytes()))
except (RuntimeError, ValueError, oead.InvalidDataError):
return
new_sarc = oead.SarcWriter(
def generate_diff(self, mod_dir: Path, modded_files: List[Union[str, Path]]):
packs = {}
for file in [file for file in modded_files \
if isinstance(file, Path) and file.suffix in util.SARC_EXTS]:
canon = util.get_canon_name(file.relative_to(mod_dir).as_posix())
if canon and not any(ex in file.name for ex in ['Dungeon', 'Bootup_', 'AocMainField']):
packs[canon] = file.relative_to(mod_dir).as_posix()
return packs
def _pack_sarc(folder: Path, tmp_dir: Path, hashes: dict):
packed = oead.SarcWriter(
endian=oead.Endianness.Big
if util.get_settings("wiiu")
else oead.Endianness.Little
)
try:
canon = util.get_canon_name(
folder.relative_to(tmp_dir).as_posix(), allow_no_source=True
)
if canon not in hashes:
raise FileNotFoundError("File not in game dump")
stock_file = util.get_game_file(folder.relative_to(tmp_dir))
try:
old_sarc = oead.Sarc(util.unyaz_if_needed(stock_file.read_bytes()))
except (RuntimeError, ValueError, oead.InvalidDataError):
raise ValueError("Cannot open file from game dump")
old_files = {f.name for f in old_sarc.get_files()}
except (FileNotFoundError, ValueError):
for file in {f for f in folder.rglob("**/*") if f.is_file()}:
packed.files[file.relative_to(folder).as_posix()] = file.read_bytes()
else:
for file in {
f
def _clean_sarc(file: Path, hashes: dict, tmp_dir: Path):
canon = util.get_canon_name(file.relative_to(tmp_dir))
try:
stock_file = util.get_game_file(file.relative_to(tmp_dir))
except FileNotFoundError:
return
with stock_file.open('rb') as old_file:
old_sarc = sarc.read_file_and_make_sarc(old_file)
if not old_sarc:
return
old_files = set(old_sarc.list_files())
if canon not in hashes:
return
with file.open('rb') as s_file:
base_sarc = sarc.read_file_and_make_sarc(s_file)
if not base_sarc:
return
new_sarc = sarc.SARCWriter(True)