diff --git a/Event.dat b/Event.dat new file mode 100644 index 0000000..7c4def1 Binary files /dev/null and b/Event.dat differ diff --git a/SLPS_254.50 b/SLPS_254.50 new file mode 100644 index 0000000..a6e9664 Binary files /dev/null and b/SLPS_254.50 differ diff --git a/TBL_All.json b/TBL_All.json index 59f0194..c7e75a7 100644 --- a/TBL_All.json +++ b/TBL_All.json @@ -1917,9 +1917,7 @@ "58762": "\u5766", "57527": "\u52ab", "57498": "\u7d05", - "39944": "\u3000", - "39945": "\u3000", - "39947": "\u3000", + "33088": "\u3000", "60352": "\u7526", "40158": "\u81c6", "39603": "\u203b", @@ -1961,7 +1959,7 @@ "0xD": "button", "0xE": "font" }, - "name": + "NAMES": { "1": "", "2": "", @@ -1974,7 +1972,7 @@ "9": "", "8191": "" }, - "color": + "COLORS": { "1": "", "2": "", diff --git a/TOR_Test.py b/TOR_Test.py index c348a7c..f37c77e 100644 --- a/TOR_Test.py +++ b/TOR_Test.py @@ -9,5 +9,37 @@ import pandas as pd tool = ToolsTOR.ToolsTOR("tbl") +tool.extractMainArchive() + + tool.extractAllStory() +tool.insertStoryFile("10247.scpk") +tool.insertMainArchive() + + +text = '自由青年' +text = ' is awesome' +bytesFinal = tool.textToBytes(text) + +def is_compressed(data): + if len(data) < 0x09: + return False + + expected_size = struct.unpack(")" + HEX_TAG = r"(\{[0-9A-F]{2}\})" POINTERS_BEGIN = 0xD76B0 # Offset to DAT.BIN pointer list start in SLPS_254.50 file POINTERS_END = 0xE60C8 # Offset to DAT.BIN pointer list end in SLPS_254.50 file HIGH_BITS = 0xFFFFFFC0 @@ -24,15 +26,18 @@ class ToolsTOR(ToolsTales): PRINTABLE_CHARS = "".join( (string.digits, string.ascii_letters, string.punctuation, " ") ) + VALID_FILE_NAME = r"([0-9]{2,5})(?:\.)?([1,3])?\.(\w+)$" + #Path to used - datBinPath = '../Data/Disc/Original/DAT.BIN' - elfPathExtract = '../Data/Disc/Original/SLPS_254.50' - storyPathArchives= '../Data/Story/SCPK' #Story XML files will be extracted here + datBinOriginal = '../Data/Disc/Original/DAT.BIN' + datBinNew = '../Data/Disc/New/DAT.BIN' + elfOriginal = '../Data/Disc/Original/SLPS_254.50' + elfNew = '../Data/Disc/New/SLPS_254.50' + storyPathArchives= '../Data/Story/SCPK/' #Story XML files will be extracted here storyPathXML = '../Data/Story/XML/' #SCPK will be repacked here skitPathArchives = '../Data//Skits/' #Skits XML files will be extracted here - datPathExtract = '../Data/DAT/' - allPathInsert = '../Data/Disc/PSP_GAME/USRDIR' + datPathExtract = '../Data/DAT/' def __init__(self, tbl): @@ -40,14 +45,18 @@ class ToolsTOR(ToolsTales): with open("TBL_All.json") as f: jsonRaw = json.load(f) + jsonTblTags = jsonTblTags ={ k1:{ int(k2,16) if (k1 != "TBL") else k2:v2 for k2,v2 in jsonRaw[k1].items()} for k1,v1 in jsonRaw.items()} self.jsonTblTags ={ k1:{ int(k2,16) if (k1 != "TBL") else k2:v2 for k2,v2 in jsonRaw[k1].items()} for k1,v1 in jsonRaw.items()} - + self.itable = dict([[i, struct.pack(">H", int(j))] for j, i in self.jsonTblTags['TBL'].items()]) + self.itags = dict([[i, j] for j, i in self.jsonTblTags['TAGS'].items()]) + self.inames = dict([[i, j] for j, i in self.jsonTblTags['NAMES'].items()]) + self.icolors = dict([[i, j] for j, i in self.jsonTblTags['COLORS'].items()]) def get_pointers(self): - f = open(self.elfPathExtract , "rb") + f = open(self.elfOriginal , "rb") f.seek(self.POINTERS_BEGIN, 0) pointers = [] @@ -101,15 +110,23 @@ class ToolsTOR(ToolsTales): pointers_offset = [] texts_offset = [] - + previous_addr = 0 while theirsce.tell() < strings_offset: b = theirsce.read(1) if b == b"\xF8": addr = struct.unpack(" 0): - # theirsce_data[name].append(theirsce.tell() - 2) + + current_pos = theirsce.tell() + theirsce.seek( addr + strings_offset-1) + bValidation = theirsce.read(1) + theirsce.seek(current_pos) + + if (addr < fsize - strings_offset) and (addr > 0) and (bValidation == b'\x00'): + pointers_offset.append(theirsce.tell() - 2) texts_offset.append(addr + strings_offset) + previous_addr = addr + return pointers_offset, texts_offset @@ -141,11 +158,14 @@ class ToolsTOR(ToolsTales): b2 = struct.unpack("" % (tag_name, b2)) else: @@ -174,6 +194,56 @@ class ToolsTOR(ToolsTales): return finalText + #Convert text to Bytes object to reinsert text into THEIRSCE and other files + def textToBytes(self, text): + + + + unames = [] + + splitLineBreak = text.split('\x0A') + nb = len(splitLineBreak) + + bytesFinal = b'' + i=0 + for line in splitLineBreak: + string_hex = re.split(self.HEX_TAG, line) + string_hex = [sh for sh in string_hex if sh] + + for s in string_hex: + if re.match(self.HEX_TAG, s): + bytesFinal += struct.pack("B", int(s[1:3], 16)) + else: + s_com = re.split(self.COMMON_TAG, s) + s_com = [sc for sc in s_com if sc] + for c in s_com: + if re.match(self.COMMON_TAG, c): + if ":" in c: + split = c.split(":") + if split[0][1:] in self.itags.keys(): + bytesFinal += struct.pack("B", self.itags[split[0][1:]]) + bytesFinal += struct.pack("=2 and i len(data_uncompressed)): + + scpk.seek( pointer_offset) + scpk.write( struct.pack(" 0: + file_list.extend( [os.path.join(path,file) for file in filenames]) + + + list_test = [os.path.splitext(os.path.basename(ele))[0] for ele in file_list] + previous = -1 + dummies = 0 + + for file in sorted(file_list, key=self.get_file_name): + size = 0 + remainder = 0 + current = int(re.search(self.VALID_FILE_NAME, file).group(1)) + + if current != previous + 1: + while previous < current - 1: + remainders.append(remainder) + buffer += size + remainder + sectors.append(buffer) + previous += 1 + dummies += 1 + + comp_type = re.search(self.VALID_FILE_NAME, file).group(2) + with open(file, "rb") as f2: + data = f2.read() + + if comp_type != None: + data = comptolib.compress_data(data, version=int(comp_type)) + + output_dat.write(data) + size = len(data) + print("file: {} size: {}".format(file, size)) + remainder = 0x40 - (size % 0x40) + if remainder == 0x40: + remainder = 0 + output_dat.write(b"\x00" * remainder) + + + remainders.append(remainder) + buffer += size + remainder + sectors.append(buffer) + previous += 1 + + print( + "Writing file %05d/%05d..." % (current - dummies, len(file_list)), end="\r" + ) + + print("Writing file %05d/%05d..." % (current - dummies, len(file_list))) + + shutil.copy( self.elfOriginal, self.elfNew) + output_elf = open(self.elfNew, "r+b") + output_elf.seek(self.POINTERS_BEGIN) + + for i in range(len(sectors) - 1): + output_elf.write(struct.pack(" 0: - print(value) - text = text.replace(value, '') - - lenValue = len(value) - x = [listFoundPositions.extend( list(range(posStart, posStart+lenValue))) for posStart in matches] - listKeys.extend( matches) - listValues.extend( [key] * lenMatches) - if text == "": - break - - b''.join([listValues[pos] for pos in sorted( listKeys)]) - - - + diff --git a/__pycache__/ToolsTOR.cpython-38.pyc b/__pycache__/ToolsTOR.cpython-38.pyc index 59d2b36..3732c9e 100644 Binary files a/__pycache__/ToolsTOR.cpython-38.pyc and b/__pycache__/ToolsTOR.cpython-38.pyc differ diff --git a/__pycache__/ToolsTales.cpython-38.pyc b/__pycache__/ToolsTales.cpython-38.pyc index 566da7a..c9b8331 100644 Binary files a/__pycache__/ToolsTales.cpython-38.pyc and b/__pycache__/ToolsTales.cpython-38.pyc differ diff --git a/bytes.bin b/bytes.bin new file mode 100644 index 0000000..a71cdaa Binary files /dev/null and b/bytes.bin differ diff --git a/createIsoTest.py b/createIsoTest.py new file mode 100644 index 0000000..c41b5e8 --- /dev/null +++ b/createIsoTest.py @@ -0,0 +1,77 @@ + +import sys +import os +try: + from cStringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO + +# Import pycdlib itself. +import pycdlib + +def get_file_name(path): + return os.path.basename(path) + + +# Create a new PyCdlib object. +iso = pycdlib.PyCdlib() +iso.open("Tales of Rebirth (Japan) - Copie.iso") +outiso = BytesIO() + +iso.write_fp(outiso) +iso.close() +outiso.seek(0) +dataOriginal = outiso.read() + + + +iso = pycdlib.PyCdlib() +outiso.seek(0) +iso.open_fp(outiso) + + +with open("Tales of Rebirth (Japan) - Copie.iso", "rb") as f: + dataIso = f.read() + + + + +#Grab datBin files +newDatBinPath = "../Data/Disc/New/Dat.bin" +with open(newDatBinPath, "rb") as datbin: + datbin_data = datbin.read() + + +#Grab SLPS file +newElfPath = "../Data/Disc/New/SLPS_254.50" +with open(newElfPath, "rb") as slps: + slps_data = slps.read() + + +with open("Tales of Rebirth (Japan) - Copie.iso", "r+b") as f: + + #DAT.bin + f.seek(0x6775E800) + f.write(datbin_data) + + f.seek(0x89000) + f.write(slps_data) + + + +originalFilePath = "../Data/Disc/Original" +listFiles = [os.path.join(originalFilePath, ele) for ele in os.listdir(originalFilePath) if ele not in ['DAT.BIN', 'SLPS_254.50']] + +for file in listFiles: + with open(file, "rb") as f: + data = f.read() + iso.add_fp(BytesIO(data), len(data), '/{};1'.format(os.path.basename(file))) + + +# Write out the ISO to the file called 'new.iso'. This will fully master the +# ISO, creating a file that can be burned onto a CD. +iso.write('new.iso') + +# Close the ISO object. After this call, the PyCdlib object has forgotten +# everything about the previous ISO, and can be re-used. +iso.close() \ No newline at end of file diff --git a/test_new.theirsce b/test_new.theirsce new file mode 100644 index 0000000..337db55 Binary files /dev/null and b/test_new.theirsce differ diff --git a/test_new_comp.theirsce b/test_new_comp.theirsce new file mode 100644 index 0000000..60f2337 Binary files /dev/null and b/test_new_comp.theirsce differ diff --git a/test_original.theirsce b/test_original.theirsce new file mode 100644 index 0000000..337db55 Binary files /dev/null and b/test_original.theirsce differ diff --git a/test_original_comp.theirsce b/test_original_comp.theirsce new file mode 100644 index 0000000..5b020ab Binary files /dev/null and b/test_original_comp.theirsce differ