Guest User

Wander Wonder Script Insert v1.1

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