diff --git a/experimental/bmg.py b/experimental/bmg.py index 0b3e20e..43ae6ba 100755 --- a/experimental/bmg.py +++ b/experimental/bmg.py @@ -11,6 +11,13 @@ def nullterm(str_plus): else: return str_plus +def denullterm(str_plus): + z = str_plus.find('\r\n') + if z != -1: + return str_plus[:z] + else: + return str_plus + class BMG(object): class BMG_DAT1(Struct): __endian__ = Struct.BE @@ -21,6 +28,10 @@ class BMG(object): return_string = "Magic: %s\n" % self.magic return_string += "Length: %08x\n " % self.length return return_string + def write(self, file): + file.write(self.magic) + file.write(struct.pack('>I', self.length)) + return class BMG_INF1(Struct): __endian__ = Struct.BE @@ -35,6 +46,12 @@ class BMG(object): return_string += "Count: %04x\n" % self.count return_string += "Unknown: %04x\n" % self.unknown01 return return_string + def write(self, file): + file.write(self.magic) + file.write(struct.pack('>I', self.length)) + file.write(struct.pack('>H', self.count)) + file.write(struct.pack('>H', self.unknown01)) + return class BMG_Header(Struct): __endian__ = Struct.BE @@ -61,122 +78,180 @@ class BMG(object): return_string += "Unknown05: %08x\n" % self.unknown05 return_string += "Unknown06: %08x\n" % self.unknown06 return return_string + def write(self, file): + file.write(self.magic) + file.write(self.magic2) + file.write(struct.pack('>I', self.length)) + file.write(struct.pack('>I', self.chunk_cnt)) + file.write(struct.pack('>B', self.unknown01)) + file.write(struct.pack('>B', self.unknown02)) + file.write(struct.pack('>H', self.unknown03)) + file.write(struct.pack('>I', self.unknown04)) + file.write(struct.pack('>I', self.unknown05)) + file.write(struct.pack('>I', self.unknown06)) + return - def __init__(self, data): + def __init__(self, data=None, out_file=None, debug=False): self.data = [] if data != None: - self.Unpack(data) + self.Unpack(data, out_file, debug) - def Unpack(self, data): - pos = 0 - header = self.BMG_Header() - header.unpack(data[pos:pos+len(header)]) - pos += len(header) - print header + def Unpack(self, data, out_file, debug): + file = open(out_file, 'wb') + if file: + pos = 0 + header = self.BMG_Header() + header.unpack(data[pos:pos+len(header)]) + pos += len(header) + if debug == True: + print header + print "\n%08x\n" % pos - print "\n%08x\n" % pos + info = self.BMG_INF1() + info.unpack(data[pos:pos+len(info)]) + pos += len(info) + if debug == True: + print info - info = self.BMG_INF1() - info.unpack(data[pos:pos+len(info)]) - pos += len(info) - print info - - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - - print "\n%08x\n" % pos - - offset_list = [] - for x in xrange(info.count): - offset = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Offset: %08x" % offset - offset_list.append(offset) - - while pos % 0x10: - padding = Struct.uint32(data[pos:pos+4], endian='>') + unknown = Struct.uint32(data[pos:pos+4], endian='>') pos += 4 - print "Padding: %08x" % padding + if debug == True: + print "Unknown: %08x" % unknown + print "\n%08x\n" % pos - print "\n%08x\n" % pos + offset_list = [] + for x in xrange(info.count): + offset = Struct.uint32(data[pos:pos+4], endian='>') + pos += 4 + if debug == True: + print "Offset: %08x" % offset + offset_list.append(offset) - dat1 = self.BMG_DAT1() - dat1.unpack(data[pos:pos+len(dat1)]) - pos += len(dat1) - print dat1 + while pos % 0x10: + padding = Struct.uint32(data[pos:pos+4], endian='>') + pos += 4 + if debug == True: + print "Padding: %08x" % padding - print "\n%08x\n" % pos - temp = pos + if debug == True: + print "\n%08x\n" % pos - unknown = Struct.uint16(data[pos:pos+2], endian='>') - pos += 2 - print "Unknown: %04x" % unknown + dat1 = self.BMG_DAT1() + dat1.unpack(data[pos:pos+len(dat1)]) + pos += len(dat1) + if debug == True: + print dat1 - for x in xrange(info.count): - pos = temp + offset_list[x] - string = nullterm(data[pos:]) - string = unicode(string, 'utf_16_be') - print "String: %s" % string + if debug == True: + print "\n%08x\n" % pos + temp = pos - #''' TEST DATA - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - unknown = Struct.uint32(data[pos:pos+4], endian='>') - pos += 4 - print "Unknown: %08x" % unknown - #END TEST DATA ''' + unknown = Struct.uint16(data[pos:pos+2], endian='>') + pos += 2 + if debug == True: + print "Unknown: %04x" % unknown + + for x in xrange(info.count): + pos = temp + offset_list[x] + string = nullterm(data[pos:]) + string = unicode(string, 'utf_16_be') + file.write(string.encode('utf-8')) + file.write('\r') + file.write('\n') + if debug == True: + print "String: %s" % string.encode('utf-8') + file.close() + else: + print "Could not open file for writing" + sys.exit(1) + def write(self, data, out_file): + file = open(out_file, 'wb') + if file: + pos = 0 + count = 0 + strings_list = [] + while pos < len(data): + temp = denullterm(data[pos:]) + pos += len(temp) + 2 + string = unicode(temp, 'utf-8') + strings_list.append(string) + count += 1 + offsets_list = [] + offset = 2 + for x in xrange(count): + offsets_list.append(offset) + offset += len(strings_list[x]) * 2 + 2 + dat1 = self.BMG_DAT1() + dat1.length = offset + 8 + (0x10 - (offset % 0x10)) + dat_pad_to_add = 0x10 - (offset % 0x10) + info = self.BMG_INF1() + info.length = 0x10 + 4 * count + (0x10 - ((4 * count) % 0x10)) + info_pad_to_add = 0x10 - ((4*count) % 0x10) + header = self.BMG_Header() + header.magic = "MESG" + header.magic2 = "bmg1" + header.length = info.length + dat1.length + 0x20 + header.chunk_cnt = 2 + header.unknown01 = 2 + header.unknown02 = 0 + header.unknown03 = 0 + header.unknown04 = 0 + header.unknown05 = 0 + header.unknown06 = 0 + header.write(file) + info.magic = "INF1" + info.count = count + info.unknown01 = 4 + info.write(file) + unknown = 0 + file.write(struct.pack('>I', unknown)) + offset_list = [] + for x in offsets_list: + file.write(struct.pack('>I', x)) + padding = 0 + for x in xrange(info_pad_to_add): + file.write(struct.pack('>B', padding)) + dat1.magic = "DAT1" + dat1.write(file) + unknown = 0 + file.write(struct.pack('>H', unknown)) + for x in strings_list: + file.write(x.encode('utf_16_be')) + file.write('\x00\x00') + file.write("\n") + padding = 0 + for x in xrange(dat_pad_to_add): + file.write(struct.pack('>B', padding)) + file.close() + else: + print "Could not open file for writing" + sys.exit(1) def main(): if len(sys.argv) == 1: - print 'Usage: python bmg.py' + print 'Usage: python bmg.py -r ' + print ' == OR == ' + print 'Usage: python bmg.py -w>