Advertisement
Guest User

Wander Wonder Script Insert v1.2

a guest
May 14th, 2015
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.63 KB | None | 0 0
  1. #1.2    Accurately measure original length of name strings
  2. #1.1    Change to accomodate new dump format
  3. #1      Initial release
  4. import os
  5. import struct
  6. import sys
  7. import codecs
  8. #List of ASCII characters used in scripts
  9. asciichar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ()0123456789\x00'
  10. #Directory name where bit-flipped files will go
  11. pathname = 'flipped'
  12.  
  13. #Gets data
  14. def get_data(filename):
  15.     totalbytes = os.path.getsize(filename)
  16.     infile = open(filename, 'rb')
  17.     totalfiledata = infile.read(totalbytes)
  18.     infile.close()
  19.     return totalfiledata
  20.  
  21. def is_jis_char(s):
  22. #Return whether a 2-length string is a SHIFT-JIS character
  23.     if len(s) != 2: #If it's not a string of length 2, then...
  24.         return False
  25.     try:            #Python error handling
  26.         if len(s.decode('cp932')) != 1: #For example, 2 ascii characters will be length 2
  27.             return False                #Two bytes that decode to a SHIFT-JIS character will be length 1
  28.     except UnicodeDecodeError:  #The string couldn't be decoded
  29.         return False            #Not a SHIFT-JIS character
  30.     return True                 #It is a SHIFT-JIS character
  31.  
  32. def replacestr(origstr,replacestr,startpos,replacelen):
  33. #Returns a string with a replaced sub-string
  34. #origstr - the original string, replacestr = the string to replace
  35. #startpos - where the replacement string should go
  36. #replacelen - how many characters of the original string to replace
  37.     return origstr[:startpos] + replacestr + origstr[startpos+replacelen:]
  38.  
  39. def SJIS_convert(filename):
  40.     with codecs.open(filename + '.tsv','rb','utf-8') as f:
  41.         with codecs.open(filename + '.csv','wb','cp932') as g:
  42.             for line in f:
  43.                 g.write(line)
  44.  
  45. def script_insert(filename):
  46.     SJIS_convert(filename)
  47.     inputdata = []                              #To hold input data
  48.     with open(filename + '.csv') as f:          #Open input file
  49.         for line in f:                          #Read by lines
  50.             line = line.translate(None,'\r\n')  #Delete linebreak characters
  51.             line = line.split('\t')             #Split along tabs
  52. #Data structure for inputdata: string (chunk number) and list.
  53. #The list is paired data and flag strings
  54.             if line[0] == '':   #Append line to previous entry
  55.                 inputdata[-1][1].append([line[2],line[3]])
  56.             else:               #Make new entry
  57.                 inputdata.append([line[0],[[line[2],line[3]]]])
  58.  
  59.     filedata = get_data(filename + '.orig')  #Get data
  60.     ptr = 0                         #Initialize variables
  61.     end_of_ptr_table = struct.unpack('<I',filedata[0:4])[0]
  62.     ptr_table = []
  63.     while ptr < end_of_ptr_table:   #Read in all pointers
  64.         ptr_table.append(struct.unpack('<I',filedata[ptr:ptr+4])[0])
  65.         ptr += 4
  66.     flag = True                     #Init variable
  67.     chunks = []                     #Break filedata into chunks
  68.     for ptr in ptr_table:
  69.         if flag == True:
  70.             flag = False
  71.         else:
  72.             chunks.append(filedata[prev_ptr:ptr])
  73.         prev_ptr = ptr
  74.     chunks.append(filedata[ptr:])
  75.     for i, chunk in enumerate(chunks):
  76.         if chunk == '4002000040033C804002010040160000'.decode('hex'):
  77.             delay_chunk = i
  78.             break
  79.  
  80.     for i, data in inputdata:   #Loop over input data
  81.         i = int(i,16)           #Convert chunk number to int
  82.         if len(data) == 1:      #Name entry
  83.             chunk = chunks[i]   #Access relevant chunk
  84.             pos = 4             #Start of text data in name chunks
  85.             #While the next character is a text character
  86.             while is_jis_char(chunk[pos:pos+2]) or chunk[pos] in asciichar:
  87.                 if is_jis_char(chunk[pos:pos+2]):
  88.                     pos += 2    #If a shift-JIS character, pos + 2
  89.                 elif chunk[pos] in asciichar:
  90.                     pos += 1    #If an ascii character, pos + 1
  91.             origlen = pos - 4   #Compute original length
  92.             s = data[0][0]      #s is the name string
  93.             while len(s) % 4 != 0:  #Word-align the name string
  94.                 s += '\x00'
  95.             #Within the chunk, replace the string
  96.             chunks[i] = replacestr(chunk, s, 4, origlen)
  97.             #Update pointer table
  98.             for j, ptr in enumerate(ptr_table):
  99.                 #If it's a pointer corresponding to a chunk after the current
  100.                 #one, update the pointer with the length difference.
  101.                 if j > i:  
  102.                     ptr_table[j] += len(s) - origlen
  103.         else:                           #Script entry
  104.             origlen = len(chunks[i])    #Get original length
  105.             chunk = ''                  #Init variable
  106.             for text, flag in data:
  107.                 if text[:2] == '0x':    #Opcode
  108.                     #This list of opcodes needs to be word-aligned
  109.                     if text[2:6] in ('4004','4006'):
  110.                         while len(chunk) % 4 != 0:  #Word-align the opcode
  111.                             chunk += '\x00'
  112.                     chunk += text[2:].decode('hex') #Add opcode to chunk
  113.                 else:                   #Text
  114.                     chunk += text                   #Add text to chunk
  115.                     if 'linebreak' in flag:         #If linebreak flag
  116.                         while len(chunk) % 4 != 0:  #Word align linebreak opcode
  117.                             chunk += '\x00'
  118.                         #Add linebreak opcode to chunk
  119.                         chunk += '40050000'.decode('hex')
  120.                     if 'delay' in flag:
  121.                         #Add delay opcode to chunk
  122.                         chunk += '4014'.decode('hex') + \
  123.                                  struct.pack('<H',delay_chunk)
  124.             chunks[i] = chunk                       #Write-back the new chunk
  125.             for j, ptr in enumerate(ptr_table):     #Update pointers
  126.                 if j > i:
  127.                     ptr_table[j] += len(chunk) - origlen
  128.  
  129.     with open(filename + '.sq','wb') as f:          #Open output file
  130.         #Write the pointers
  131.         f.write(''.join([struct.pack('<I',x) for x in ptr_table]))
  132.         #Write each chunk
  133.         f.write(''.join(chunks))
  134.  
  135.     filedata = get_data(filename + '.sq')   #Read in the file just outputted
  136.     with open(pathname + '\\' + filename + '.sq','wb') as g:    #Open other file
  137.         for x in filedata:                  #For each character in file
  138.             g.write(chr(ord(x) ^ 255))      #Flip and then write the byte
  139.  
  140. if os.path.exists(pathname) == False:       #Make a directory if there isn't already one
  141.     os.mkdir(pathname)
  142. script_insert(sys.argv[1])                  #Insert the script
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement