def save(self, filename, luagnlBytes, luainfoBytes): """ Save the luabnd file as @filename. """ if (not self.useDCX): if (not os.path.isfile(filename + '.bak')): with open(filename + '.bak', 'wb') as bakf: with open(filename, 'rb') as oldf: bakf.write(oldf.read()) new_content = [] for i in range(len(self.luabnd_content)): if (self.luabnd_content[i][0] == 1000000): new_content.append((self.luabnd_content[i][0], self.luabnd_content[i][1], luagnlBytes)) elif (self.luabnd_content[i][0] == 1000001): new_content.append((self.luabnd_content[i][0], self.luabnd_content[i][1], luainfoBytes)) else: new_content.append(self.luabnd_content[i]) if (self.useDCX): self.dcxhandler.save_dcx(filename + '.dcx', bnd_rebuilder.repack_bnd(new_content)) else: with open(filename, 'wb') as f: f.write(bnd_rebuilder.repack_bnd(new_content))
def Save(self, fname): #Unused print("saving: " + fname) if (not os.path.isfile(fname + ".bak")): with open(fname, 'rb') as f: with open(fname + ".bak", 'wb') as f2: f2.write(f.read()) with open(fname, 'wb') as f: f.write(bnd_rebuilder.repack_bnd(self.currentContent)) self.fileOpen = False
def export_to_gameparam(self): if self.game_version.get() == rngopts.RandOptGameVersion.PTDE: paths_to_search = PTDE_GAMEPARAM_PATH_LIST elif self.game_version.get() == rngopts.RandOptGameVersion.REMASTERED: paths_to_search = DS1R_GAMEPARAM_PATH_LIST else: paths_to_search = [] has_gameparam = False for filepath in paths_to_search: normed_path = os.path.normpath(os.path.join(os.getcwd(), filepath)) if os.path.isfile(normed_path): has_gameparam = True gameparam_filepath = normed_path gameparambak_filepath = normed_path + ".bak" is_remastered = ( self.game_version.get() == rngopts.RandOptGameVersion.REMASTERED) if not has_gameparam: self.msg_area.config(state="normal") self.msg_area.delete(1.0, "end") self.msg_area.insert("end", "\n\n") self.msg_area.insert("end", "ERROR", "error_red") self.msg_area.insert( "end", ": GameParam.parambnd[.dcx] is missing or cannot be opened." + " Check that this program is in the correct directory and GameParam.parambnd[.dcx] is present and retry.\n\n" + "Click \"Continue\" to continue in seed-information-only mode, or" + " click \"Quit\" to exit.") self.msg_area.tag_config("error_red", foreground="red") self.msg_area.config(state="disabled") self.export_button.config(state="disabled") self.lift_msg_area() else: if is_remastered: gp_filename = "GameParam.parambnd.dcx" else: gp_filename = "GameParam.parambnd" with open(gameparam_filepath, "rb") as f: content = f.read() try: if is_remastered: if not dcx_handler.appears_dcx(content): raise ValueError( ".dcx file does not appear to be DCX-compressed.") content = dcx_handler.uncompress_dcx_content(content) content_list = bnd_rebuilder.unpack_bnd(content) except: self.msg_area.config(state="normal") self.msg_area.delete(1.0, "end") self.msg_area.insert("end", "\n\n") self.msg_area.insert("end", "ERROR", "error_red") self.msg_area.insert( "end", ": " + gp_filename + " is malformed or corrupted and cannot be" + " parsed to export randomized items. If possible, restore " + gp_filename + " from a backup copy.\n\n" + "Click \"Continue\" to continue in seed-information-only mode, or" + " click \"Quit\" to exit.") self.msg_area.tag_config("error_red", foreground="red") self.msg_area.config(state="disabled") self.export_button.config(state="disabled") self.lift_msg_area() return # Back up GameParam.parambnd if needed. if not os.path.isfile(gameparambak_filepath): shutil.copy2(gameparam_filepath, gameparambak_filepath) if self.is_seed_empty(): self.get_new_seed() for index, (file_id, filepath, filedata) in enumerate(content_list): if (filepath == "N:\FRPG\data\INTERROOT_win32\param\GameParam\CharaInitParam.param" or filepath == "N:\FRPG\data\INTERROOT_x64\param\GameParam\CharaInitParam.param" ): chr_init_data = filedata # TODO: Implement this system correctly by passing chr_init_data # instead of None to preserve externally modified characters (e.g. another mod). # However, we need some way to determine external modifications # compared to data left over from a previous run that changed # ChrInit data. (options, randomized_data, rng) = self.randomize_data(None) (item_table, randomized_chr_data) = randomized_data syncnum = self.get_syncnum_string(rng) result_ilp = item_table.build_itemlotparam() ilp_binary_export = result_ilp.export_as_binary() result_slp = item_table.build_shoplineup() slp_binary_export = result_slp.export_as_binary() cip_binary_export = randomized_chr_data.export_as_binary() for index, (file_id, filepath, filedata) in enumerate(content_list): if (filepath == "N:\FRPG\data\INTERROOT_win32\param\GameParam\ItemLotParam.param" or filepath == "N:\FRPG\data\INTERROOT_x64\param\GameParam\ItemLotParam.param" ): content_list[index] = (file_id, filepath, ilp_binary_export) if (filepath == "N:\FRPG\data\INTERROOT_win32\param\GameParam\ShopLineupParam.param" or filepath == "N:\FRPG\data\INTERROOT_x64\param\GameParam\ShopLineupParam.param" ): content_list[index] = (file_id, filepath, slp_binary_export) if (filepath == "N:\FRPG\data\INTERROOT_win32\param\GameParam\CharaInitParam.param" or filepath == "N:\FRPG\data\INTERROOT_x64\param\GameParam\CharaInitParam.param" ): content_list[index] = (file_id, filepath, cip_binary_export) new_content = bnd_rebuilder.repack_bnd(content_list) if is_remastered: new_content = dcx_handler.compress_dcx_content(new_content) with open(gameparam_filepath, "wb") as f: f.write(new_content) seed_folder = self.export_seed_info( (options, randomized_data, rng)) self.msg_continue_button.lower() self.msg_area.config(state="normal") self.msg_area.delete(1.0, "end") self.msg_area.insert("end", "\n\n") self.msg_area.insert("end", "SUCCESS", "yay") self.msg_area.insert( "end", "! " + gp_filename + " has been modified successfully.\n\n" + "The information for this seed has been exported in the directory\n\n " + seed_folder + "\n\n") self.msg_area.insert( "end", "SyncNum: " + syncnum + "\n (When racing, all SyncNums should be equal or settings do not match.)\n\n" ) self.msg_area.insert( "end", "Click \"Back\" to begin again, or click \"Quit\" to exit.") self.msg_area.tag_config("yay", foreground="green") self.msg_area.config(state="disabled") self.msg_area.lift() self.back_button.lift() self.msg_quit_button.lift()
def runTest(self): pack = repack_bnd([[3, '2', b'1']]) assert self.unpack_bnd_instance(pack) == [(3, '2', b'1')], \ "repack pass"
def AddEverythingToCommon(self, useDCX): """ Collects all effects from individual map effect files and adds them to CommonEffects """ inputFiles = ['m10', 'm10_00', 'm10_01', 'm10_02', 'm11', 'm12', 'm12_00', 'm12_01', 'm13', 'm13_00', 'm13_01', 'm13_02', 'm14', 'm14_00', 'm14_01', 'm15', 'm15_00', 'm15_01', 'm16', 'm17', 'm18', 'm18_00', 'm18_01'] MODEL_PATTERN = r'.*s1([0-9][0-9][0-9])[0-9].*' TPF_PATTERN = r'.*s1([0-9][0-9][0-9])[0-9].*' ENEMY_EFFECT_ID_PATTERN = r'.*00([1-9][0-9][0-9][0-9][0-9]).ffx' ENEMY_MODEL_ID_PATTERN = r'.*s([1-9][0-9][0-9][0-9][0-9]).flver' ENEMY_TPF_ID_PATTERN = r'.*s([1-9][0-9][0-9][0-9][0-9]).tpf' tempList = [] self.ffx_files.clear() for iFile in inputFiles: openFileName = 'sfx\\FRPG_SfxBnd_' + iFile + '.ffxbnd' if (useDCX): openFileName += '.dcx' with open(openFileName, 'rb') as f: upcontent = f.read() content = upcontent if (useDCX): dcxh = DCXHandler() content = dcxh.open_dcx(upcontent) data = bnd_rebuilder.unpack_bnd(content) for item in data: strName = item[1].decode('shift_jis') if not strName in tempList: if (useDCX): enFXMatch = re.match(ENEMY_EFFECT_ID_PATTERN, strName) if (enFXMatch != None): fid = int(enFXMatch.group(1)) if (fid < 20001): # prev = 60001 below as well in 2 locations tempList.append(strName) self.ffx_files.append(item) else: enMDLMatch = re.match(ENEMY_MODEL_ID_PATTERN, strName) if (enMDLMatch != None): fid = int(enMDLMatch.group(1)) if (fid < 20001): tempList.append(strName) self.ffx_files.append(item) else: enTPFMatch = re.match(ENEMY_TPF_ID_PATTERN, strName) if (enTPFMatch != None): fid = int(enTPFMatch.group(1)) if (fid < 20001): tempList.append(strName) self.ffx_files.append(item) else: tempList.append(strName) self.ffx_files.append(item) existingEffects = [] lastIndex = 0 lastIndexTpf = 0 lastIndexMdl = 0 ffxEntries = [] tpfEntries = [] mdlEntries = [] openFileName = 'sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd' if (useDCX): openFileName += '.dcx' oldCheckSum = sha256_checksum(openFileName) writeSuccessful = True with open(openFileName, 'rb') as f: upcontent = f.read() content = upcontent if (useDCX): dcxh = DCXHandler() content = dcxh.open_dcx(upcontent) data = bnd_rebuilder.unpack_bnd(content) for item in data: strName = item[1].decode('shift_jis') if not strName in existingEffects: existingEffects.append(strName) if (item[0] < 100000): ffxEntries.append(item) if (item[0] > lastIndex): lastIndex = item[0] elif (item[0] < 200000): tpfEntries.append(item) if (item[0] > lastIndexTpf): lastIndexTpf = item[0] else: mdlEntries.append(item) if (item[0] > lastIndexMdl): lastIndexMdl = item[0] if (not os.path.isfile(openFileName + '.bak')): with open(openFileName + '.bak', 'wb') as f2: f2.write(upcontent) oldLen = len(ffxEntries) + len(tpfEntries) + len(mdlEntries) lastIndex += 1 lastIndexTpf += 1 lastIndexMdl += 1 for i, ffx in enumerate(self.ffx_files): strName = ffx[1].decode('shift_jis') if not strName in existingEffects: if (ffx[0] < 100000): newEntry = (lastIndex, ffx[1], ffx[2]) lastIndex += 1 ffxEntries.append(newEntry) elif (ffx[0] < 200000): newEntry = (lastIndexTpf, ffx[1], ffx[2]) lastIndexTpf += 1 tpfEntries.append(newEntry) else: newEntry = (lastIndexMdl, ffx[1], ffx[2]) lastIndexMdl += 1 mdlEntries.append(newEntry) newContent = [] newContent += ffxEntries newContent += tpfEntries newContent += mdlEntries print("[FFX] Effect data gathered: " + str(len(newContent))) if not len(newContent) == oldLen: if (useDCX): print("[FFX] Saving and recompressing sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd.dcx. This takes quite a while with the Remaster.") dcxh = DCXHandler() temp = dcxh.open_file('sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd.dcx') dcxh.save_dcx('sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd.dcx', bnd_rebuilder.repack_bnd(newContent)) else: print("[FFX] Saving sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd.") with open('sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd', 'wb') as f: f.write(bnd_rebuilder.repack_bnd(newContent)) newCheckSum = sha256_checksum(openFileName) if (oldCheckSum == newCheckSum): writeSuccessful = False print('[FFX] sfx\\FRPG_SfxBnd_CommonEffects.ffxbnd saved') if not useDCX: for iFile in inputFiles: data = [] with open('sfx\\FRPG_SfxBnd_' + iFile + '.ffxbnd', 'rb') as f: content = f.read() data = bnd_rebuilder.unpack_bnd(content) if not (os.path.isfile('sfx\\FRPG_SfxBnd_' + iFile + '.ffxbnd.bak')): with open('sfx\\FRPG_SfxBnd_' + iFile + '.ffxbnd.bak', 'wb') as bakf: bakf.write(content) with open('sfx\\FRPG_SfxBnd_' + iFile + '.ffxbnd', 'wb') as sf: sf.write(bnd_rebuilder.repack_bnd(data[:1])) print('[FFX] Clean-up complete') else: print('[FFX] Ignored cleanup (REMASTERED Version being used)') print("[FFX] Done") return writeSuccessful