def consolidate_diffs(self, diffs): if not diffs: return {} all_diffs = oead.byml.Hash() for diff in diffs: util.dict_merge(all_diffs, diff, overwrite_lists=True) return all_diffs
def merge_actorinfo(verbose: bool = False): """Merges installed changes to actor info""" mods = get_actorinfo_mods() actor_path = (util.get_master_modpack_dir() / 'content' / 'Actor' / 'ActorInfo.product.sbyml') if not mods: print('No actor info merging necessary.') if actor_path.exists(): actor_path.unlink() return print('Loading modded actor info...') modded_actors = {} loader = yaml.CSafeLoader yaml_util.add_constructors(loader) for mod in mods: with (mod.path / 'logs' / 'actorinfo.yml').open( 'r', encoding='utf-8') as a_file: entries = yaml.load(a_file, Loader=loader) util.dict_merge(modded_actors, entries, overwrite_lists=True) if verbose: print(f'Loaded {len(entries)} entries from {mod.name}') del entries print('Loading unmodded actor info...') actorinfo = get_stock_actorinfo() print('Merging changes...') for actor_hash, actor_info in modded_actors.items(): if actor_hash in actorinfo['Hashes']: idx = actorinfo['Hashes'].index(actor_hash) util.dict_merge(actorinfo['Actors'][idx], actor_info, overwrite_lists=True) if verbose: print(f' Updated entry for {actorinfo["Actors"][idx]}') else: actorinfo['Hashes'].append(actor_hash) actorinfo['Actors'].append(actor_info) if verbose: print(f' Added entry for {actor_info["name"]}') print('Sorting new actor info...') actorinfo['Hashes'].sort() actorinfo['Hashes'] = list( map(lambda x: byml.Int(x) if x < 2147483648 else byml.UInt(x), actorinfo['Hashes'])) actorinfo['Actors'].sort( key=lambda x: zlib.crc32(x['name'].encode('utf-8'))) print('Saving new actor info...') buf = BytesIO() byml.Writer(actorinfo, True).write(buf) actor_path.parent.mkdir(parents=True, exist_ok=True) actor_path.write_bytes(util.compress(buf.getvalue())) print('Actor info merged successfully')
def get_mod_diff(self, mod: util.BcmlMod): diff = oead.byml.Hash() if self.is_mod_logged(mod): diff = oead.byml.from_text( (mod.path / "logs" / self._log_name).read_text("utf-8")) for opt in {d for d in (mod.path / "options").glob("*") if d.is_dir()}: if (opt / "logs" / self._log_name).exists(): util.dict_merge( diff, oead.byml.from_text( (opt / "logs" / self._log_name).read_text("utf-8")), overwrite_lists=True, ) return diff
def perform_merge(self): diffs = self.consolidate_diffs(self.get_all_diffs()) output: Path static_data: Path try: util.get_aoc_dir() output = (util.get_master_modpack_dir() / util.get_dlc_path() / ("0010" if util.get_settings("wiiu") else "") / STATIC_PATH) static_data = util.get_game_file("Map/MainField/Static.smubin", aoc=True).read_bytes() except FileNotFoundError: output = util.get_master_modpack_dir( ) / "logs" / "mainstatic.smubin" static_data = util.get_nested_file_bytes( (str(util.get_game_file("Pack/Bootup.pack")) + "//Map/MainField/Static.smubin"), unyaz=False, ) if not diffs: try: output.unlink() except: pass return stock_static = oead.byml.from_binary(util.decompress(static_data)) merged = Hash() for cat in stock_static: if cat in diffs: items = {get_id(item): item for item in stock_static[cat]} util.dict_merge(items, diffs[cat]) merged[cat] = Array([ item for _, item in items.items() if "remove" not in item ]) else: merged[cat] = stock_static[cat] data = util.compress( oead.byml.to_binary(merged, big_endian=util.get_settings("wiiu"))) output.parent.mkdir(parents=True, exist_ok=True) output.write_bytes(data) if "mainstatic" in str(output): util.inject_file_into_sarc( "Map/MainField/Static.smubin", data, "Pack/Bootup.pack", create_sarc=True, )
def consolidate_gamedata(gamedata: sarc.SARC) -> {}: """ Consolidates all game data in a game data SARC :return: Returns a dict of all game data entries in a SARC :rtype: dict of str: list """ data = {} pool = Pool(processes=cpu_count()) game_dict = {} for file in gamedata.list_files(): game_dict[file] = gamedata.get_file_data(file).tobytes() results = pool.map( partial(_bgdata_from_bytes, game_dict=game_dict), gamedata.list_files() ) pool.close() pool.join() del game_dict del gamedata for result in results: util.dict_merge(data, result) return data
def consolidate_diffs(self, diffs: list): all_diffs = {} for diff in diffs: util.dict_merge(all_diffs, diff, overwrite_lists=True) return all_diffs