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 = {} write_msbts = [] for msbt in msg_sarc.list_files(): if any(exclusion in msbt for exclusion in EXCLUDE_TEXTS): continue m_data = msg_sarc.get_file_data(msbt) m_hash = xxhash.xxh32(m_data).hexdigest() if msbt not in hashes: added_msbts[msbt] = m_data elif m_hash != hashes[msbt]: write_msbts.append((tmp_dir / msbt, m_data.tobytes())) modded_msyts.append(msbt.replace('.msbt', '.msyt')) if write_msbts: pool = multiprocessing.Pool() pool.map(write_msbt, write_msbts) pool.close() pool.join() return modded_msyts, added_msbts
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 get_modded_savedata_entries(savedata: sarc.SARC) -> []: """ Gets all of the modified savedata entries in a dict of modded savedata contents. :param savedata: The saveformatdata.sarc to search for modded entries. :type savedata: class:`sarc.SARC` :return: Returns a list of modified savedata entries. :rtype: list """ ref_savedata = get_stock_savedata() ref_hashes = [] new_entries = [] for file in sorted(ref_savedata.list_files())[0:-2]: for item in byml.Byml(ref_savedata.get_file_data(file).tobytes()).parse()['file_list'][1]: ref_hashes.append(item['HashValue']) for file in sorted(savedata.list_files())[0:-2]: for item in byml.Byml(savedata.get_file_data(file).tobytes()).parse()['file_list'][1]: if item['HashValue'] not in ref_hashes: new_entries.append(item) return new_entries
def is_savedata_modded(savedata: sarc.SARC) -> {}: """ Detects if any .bgsvdata file has been modified. :param savedata: The saveformatdata.sarc to check for modification. :type savedata: class:`sarc.SARC` :returns: Returns True if any .bgsvdata in the given savedataformat.sarc has been modified. :rtype: bool """ hashes = get_savedata_hashes() sv_files = sorted(savedata.list_files()) fix_slash = '/' if not sv_files[0].startswith('/') else '' modded = False for svdata in sv_files[0:-2]: svdata_bytes = savedata.get_file_data(svdata).tobytes() svdata_hash = xxhash.xxh32(svdata_bytes).hexdigest() del svdata_bytes if not modded: modded = fix_slash + \ svdata not in hashes or svdata_hash != hashes[fix_slash + svdata] return modded