Advertisement
qazmlpok

Touhou Sky Arena - Repack.py

May 15th, 2012
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.63 KB | None | 0 0
  1. from insani import *
  2. import os
  3. import sys
  4. import zlib
  5.  
  6. trans_table = "\x49\xF2\xD0\x20\x37\x5E\x77\x3E\x3C\xFB\x3E\x21\x33\xE9\xF2\x96\xD0\xE6\x89\x8E\x27\xD7\x3C\x45\x77\xDD\x32\x6B\x06\x78\xE1\x87\xBC\x10\xBB\x04\xE5\x7F\x63\x98\xB0\xEB\x78\x04\x58\x01\xA9\x51\xA6\xE8\xAD\x92\x8E\x87\x49\x4A\x3E\x64\x81\x7E\xC7\x37\xA3\x93\xC4\x8B\x3E\x01\x1F\xFA\x46\x79\x5D\xD4\x5F\x09\x99\x4E\xAA\xDC\x00\x89\xF5\x9B\x89\x89\x3C\x99\x43\xE2\xD5\xBF\xCC\xC7\x31\xFA\xFC\xB2\x16\x02\xC2\x57\xB0\xC7\xAA\x1E\x67\x7B\xAE\x40\x4E\x4F\x32\x69\xA9\x77\xD1\x52\xD0\x1B\xE7\xD0\xE8\x1F\xE6\xC8\x4C\x99\x73\x72\x93\x36\xE2\xFB\x8A\xEF\x75\xCE\x92\x6B\x89\x29\xBE\x48\x07\xC7\x22\x39\xD2\xBC\x96\xBC\x05\xC6\x8A\xCD\x22\xBC\x8B\x4C\xAE\xE1\x1B\x90\x45\x35\x8D\xE0\x10\x14\x7B\x2E\x4C\xBC\x7D\x66\xBD\x8C\x4E\x33\x2D\x09\x73\x71\xE4\x07\x9E\xC1\x3B\x8D\x57\xF6\xA5\x37\x23\x49\xE4\x33\x4A\x8E\xBD\xBF\x4F\xD9\x4F\x95\x5E\x4E\x87\x41\xAE\x01\xB6\x56\xA0\xAE\xC6\xF2\x1B\xB5\x24\x85\xEE\xFE\xC3\x4D\x3B\xDA\xF0\x0B\x22\x70\x38\x45\x50\x4C\x9E\x30\x88\xA9\x8A\x12\x5B\xFC\xF5\xAE\x2A\xEC\xDD\x11\x0D\xA6\x81\x54\xE2\x00"
  7.  
  8. def writebytes(outfile, data, bytecount, xorkey, offset=0):
  9.     ret = ""
  10.     i = 0
  11.     while (offset < bytecount):
  12.         byte = long(ord(data[i]))
  13.         byte ^= xorkey
  14.         byte ^= ord(trans_table[offset&0xFF])
  15.  
  16.         outfile.write(chr(byte))
  17.  
  18.         offset += 1
  19.         if (offset&0xF0000000):
  20.             print "Offset got huge. This functionality not implemented."
  21.             sys.exit()
  22.         i += 1
  23.  
  24.     return ret
  25.  
  26. def convertfromint(value, size=INT_LENGTH, endian=LITTLE_ENDIAN):
  27.     result = ""
  28.     for i in xrange(size):
  29.         if endian == LITTLE_ENDIAN :
  30.             #result |= (temp << (8*i))
  31.             temp = (value >> (8*i)) & 0x00FF
  32.         elif endian == BIG_ENDIAN :
  33.             #result = (result << 8) | temp
  34.             temp = (value >> (8*(size-i-1))) & 0x00FF
  35.         else :
  36.                 raise 'convertfromint', 'Unknown endian specification'
  37.             result += chr(temp)
  38.  
  39.         return result
  40.  
  41. def converttoint(bytes, size=INT_LENGTH, endian=LITTLE_ENDIAN):
  42.     result = 0
  43.     for i in xrange(size):
  44.         temp=long(ord(bytes[i]))
  45.         if endian == LITTLE_ENDIAN :
  46.             result |= (temp << (8*i))
  47.         elif endian == BIG_ENDIAN :
  48.             result = (result << 8) | temp
  49.         else :
  50.                 raise 'converttoint', 'Unknown endian specification'
  51.  
  52.         return result
  53.  
  54. #===========================================
  55.  
  56. files = sys.argv[1:]
  57. for filename in files:
  58.     crc = None
  59.  
  60.     if (not os.path.isdir(filename)):
  61.         print filename, 'is not a directory.'
  62.         continue
  63.  
  64.  
  65.     entries = []
  66.     for (root, dirs, dirfiles) in os.walk(filename):
  67.         #first = dirfiles.pop(0)
  68.         #dirfiles.append(first)
  69.  
  70.         for name in dirfiles:
  71.             if (name == 'crc.txt'):
  72.                 infile = open(os.path.join(root, name))
  73.                 crc = infile.read()
  74.                 crc = converttoint(crc)
  75.                 infile.close()
  76.  
  77.                 continue
  78.             entry = {}
  79.  
  80.             #fuck. someimes need dir.....
  81.             entry['filename'] = os.path.join(root, name)
  82.             entry['name'] = name[4:]
  83.             stat = os.stat(entry['filename'])
  84.             entry['size'] = stat.st_size
  85.             entries.append(entry)
  86.             print 'Adding', entry['name'], 'with size', entry['size']
  87.  
  88.     filecount = convertfromint(len(entries))
  89.     xorkey = 0x50       #Completely arbitrary; works fine
  90.     rndkey = chr(xorkey)
  91.  
  92.     datastart = 9 + 0x10C * len(entries)
  93.     datapos = datastart
  94.     filedata = rndkey + "FFFF" + filecount
  95.     for entry in entries:
  96.         entry['start'] = datapos
  97.         datapos += entry['size']
  98.         filedata += entry['name'].replace('/', '\\')    #Just in case.
  99.         filedata += '\0' * (0x104 - len(entry['name']))
  100.         filedata += convertfromint(entry['size'])
  101.         filedata += convertfromint(entry['start'])
  102.  
  103.     for entry in entries:
  104.         infile = open(entry['filename'], 'rb')
  105.         data = infile.read()
  106.         filedata += data
  107.         infile.close()
  108.  
  109.     if (crc is None):
  110.         print 'Failed to find crc file?'
  111.         sys.exit()
  112.     print 'Final size is', len(filedata)
  113.     #crc = zlib.crc32(filedata) & 0xffffffff
  114.     #crc = 0xBFD4B96F       ###################
  115.     print 'CRC is %08X' % crc
  116.     crcbytes = convertfromint(crc)
  117.     filedata = filedata[0] + crcbytes + filedata[5:]
  118.     print 'Final size ckeck:', len(filedata)
  119.  
  120.     tmp = open('_tmp.gpk', 'wb')
  121.     tmp.write(filedata)
  122.     tmp.close()
  123.  
  124.     outfile = open(filename+'.gpk', 'wb')
  125.     outfile.write(filedata[0])
  126.     writebytes(outfile, filedata[1:5], 4, xorkey^0x92)
  127.     writebytes(outfile, filedata[5:9], 4, xorkey^0x92)
  128.  
  129.     filepos = 9
  130.     for entry in entries:
  131.         entrydata = filedata[filepos:filepos+0x10C]
  132.         writebytes(outfile, entrydata, 0x10C, xorkey^0x92)
  133.         filepos += 0x10C
  134.  
  135.     xorkey = (crc%0xFF)&0xFF
  136.  
  137.     for entry in entries:
  138.         #They're in order, but... play it safe
  139.         outfile.seek(entry['start'])
  140.         writebytes(outfile, filedata[entry['start']:entry['start']+entry['size']], entry['size'], xorkey)
  141.  
  142.  
  143.  
  144.     outfile.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement