Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pdb
- import binascii
- import struct
- import io
- import os
- import pdb
- import shutil
- import gzip
- def text_encode(s):
- #Non-printing characters don't copy to/from Google Sheets correctly
- #e.g., replace \x0c with {0c}
- s1 = ''
- flag = False
- for char in s:
- if ord(char) < 0x20 and ord(char) != 0xA:
- if not flag:
- flag = True
- s1 += '{'
- s1 += '{:0>2x}'.format(ord(char))
- else:
- if flag:
- flag = False
- s1 += '}'
- s1 += char
- return s1
- def text_decode(s):
- while '{' in s:
- pos1 = s.find('{')
- pos2 = s.find('}')
- s = s[:pos1] + \
- binascii.unhexlify(s[pos1+1:pos2].strip()).decode('ascii') + \
- s[pos2+1:]
- return s
- def build_offset_list(s):
- #Find offset of each string within string table
- pos = 0
- str_offset_list = []
- str_offset_list.append(0)
- for i, x in enumerate(range(string_num - 1), 1):
- pos = string.find(b'\x00', pos) + 1
- str_offset_list.append(pos)
- return(str_offset_list)
- ##pdb.set_trace()
- filename = 'MAP_T_KAN_00'
- if os.path.isfile(filename + '.orig'):
- with open(filename + '.orig', 'rb') as f:
- filedata = f.read()
- else:
- if os.path.isfile(filename + '.BIN'):
- with gzip.open(filename + '.BIN') as f:
- filedata = f.read()
- with open(filename + '.orig', 'wb') as f:
- f.write(filedata)
- quit()
- else:
- print('File {} not found.'.format(filename + '.BIN'))
- bscr_offset = struct.unpack('<I', filedata[0xC:0x10])[0]
- bscrsize = struct.unpack('<I', filedata[bscr_offset+0x24:bscr_offset+0x28])[0]
- #Reduce down to bscr sub-file
- filedata = bytearray(filedata[bscr_offset:bscr_offset+bscrsize])
- #------------------
- string_num, string_start, script_size, script_start = \
- struct.unpack('<IIII', filedata[0x30:0x40])
- string = filedata[string_start:script_start]
- script = filedata[script_start:script_start+script_size]
- str_offset_list = build_offset_list(string)
- pos = script_start #Find index number of each string within script
- count = 0
- scp_offset_list = []
- for x in range(script_size // 0x10):
- if filedata[pos:pos+4] == b'\x1a\xf0\xf1\x5a':
- count += 1
- str_offset = struct.unpack('<I', filedata[pos+4:pos+8])[0]
- #Where is the pointer, which string # is the pointer
- scp_offset_list.append([pos + 4, str_offset_list.index(str_offset)])
- pos += 0x10
- ##print(count)
- inputdata = [] #Load input data (from Google Sheets)
- with open(filename + '.tsv', 'r', encoding='utf-8') as f:
- for line in f:
- line = line.rstrip('\r\n').split('\t')
- if line[0] != '':
- inputdata.append(text_decode(line[2]).encode('utf-8'))
- else:
- inputdata[-1] += b'\n' + text_decode(line[2]).encode('utf-8')
- string = b'\x00'.join(inputdata) + b'\x00'
- if len(inputdata) > script_start - string_start:
- print('Too long.')
- quit()
- str_offset_list = build_offset_list(string)
- #Replace string data with new
- string += b'\x00' * (script_start - string_start - len(string))
- filedata[string_start:script_start] = string
- #Update pointers
- for scp_offset, i in scp_offset_list:
- filedata[scp_offset:
- scp_offset+4] = struct.pack('<I', str_offset_list[i])
- with open('bscr.bin', 'wb') as f:
- f.write(filedata)
- data_temp = io.BytesIO()
- with open(filename + '.orig', 'rb') as g:
- data_temp.write(g.read(bscr_offset))
- data_temp.write(filedata)
- g.seek(bscr_offset + bscrsize)
- data_temp.write(g.read())
- with open(filename + '.BIN', 'wb') as f:
- f.write(gzip.compress(data_temp.getvalue()))
Add Comment
Please, Sign In to add comment