Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import hashlib
- import os
- import binascii
- import struct
- import glob
- from shutil import rmtree
- # os.getcwd()
- # os.chdir()
- inputName = 'savedata.bin'
- def handler(inputName):
- fileName = ''
- fileExtension = ''
- if inputName == '':
- inputName = 'savedata.bin'
- fileName = inputName.partition('.')[0]
- fileExtension = inputName.partition('.')[2]
- print('Please choose operation')
- print('1: Decompile')
- print('2: Compile')
- print('Else: Quit')
- pickOp = int(raw_input('--:'))
- # pickOp = 2
- if pickOp == 1:
- print('Decompiling')
- saveDecompile(inputName, fileName, fileExtension)
- return
- elif pickOp == 2:
- print('Compiling')
- saveCompile(fileName)
- return
- else:
- return
- return
- def saveDecompile(inputName, fileName, fileExtension):
- with open(inputName, 'rb+') as saveFile:
- saveData = dict()
- saveFile.seek(-1, 2)
- print('File Length ' + str(saveFile.tell() + 1))
- saveData['File Length'] = (saveFile.tell() + 1)
- saveFile.seek(0)
- saveData['SHA1'] = binascii.hexlify(saveFile.read(int('14', 16)))
- saveData['UNK1'] = binascii.hexlify(saveFile.read(int('C', 16)))
- saveData['UNK2'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Mii Data Offset location, should be 36', saveFile.tell()) # Should be 36, or 0x24
- saveData['Mii Data Offset'] = binascii.hexlify(saveFile.read(int('4', 16)))
- saveData['UNK3'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Mii-Trainer Data Offset location, should be 44', saveFile.tell()) # Should be 44, or 0x2C
- saveData['Mii-Trainer Data Offset'] = binascii.hexlify(saveFile.read(int('4', 16)))
- saveData['UNK4'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Pokemon Data Offset location, should be 52', saveFile.tell()) # Should be 52, or 0x34
- saveData['Pokemon Data Offset'] = binascii.hexlify(saveFile.read(int('4', 16)))
- saveData['UNK5'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Pokemon Data End Offset location, should be 60', saveFile.tell()) # Should be 60, or 0x3C
- saveData['Pokemon Data End Offset'] = binascii.hexlify(saveFile.read(int('4', 16)))
- saveData['UNK6'] = binascii.hexlify(saveFile.read(int('53', 16) - saveFile.tell()))
- saveData['Language'] = binascii.hexlify(saveFile.read(int('1', 16)))
- saveData['UNK7'] = binascii.hexlify(saveFile.read(int(saveData['Mii Data Offset'], 16) - saveFile.tell()))
- saveData['UNK8'] = binascii.hexlify(saveFile.read(int('4', 16))) # Possibly size of each Mii data entry
- print('Mii Data Offset location, should be 8876', saveFile.tell()) # Should be 8876, or 0x22AC
- saveData['Mii Count'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Mii Data location, should be 8880', saveFile.tell()) # Should be 8880, or 0x22B0
- saveData['Mii Data'] = binascii.hexlify(saveFile.read(int(saveData['Mii Count'], 16) * 40))
- print('Mii-Trainer Data location, should be ' + str(int(saveData['Mii-Trainer Data Offset'], 16)), saveFile.tell())
- saveData['UNK9'] = binascii.hexlify(saveFile.read(int('4', 16))) # Possibly size of each Mii-Trainer data entry
- print('unk9 is ' + str(int(saveData['UNK9'], 16)))
- saveData['Mii-Trainer Count'] = binascii.hexlify(saveFile.read(int('4', 16))) # This may be off by one, which would explain UNK12. Doesn't matter, I'm not touching it
- print('Mii-Trainer Count', int(saveData['Mii-Trainer Count'], 16))
- saveData['Mii-Trainer Data'] = binascii.hexlify(saveFile.read(int(saveData['Mii Count'], 16) * 44))
- saveData['UNK12'] = binascii.hexlify(saveFile.read(int('2C', 16))) # Could be Hayley's data?
- print('Pokemon Data location, should be ' + str(int(saveData['Pokemon Data Offset'], 16)), saveFile.tell())
- saveData['UNK10'] = binascii.hexlify(saveFile.read(int('4', 16))) # Possibly size of each Pokemon data entry
- saveData['Pokemon Count'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Pokemon Count', int(saveData['Pokemon Count'], 16))
- # saveData['Pokemon Data'] = binascii.hexlify(saveFile.read(int(saveData['Pokemon Count'], 16) * 164))
- pokemonData1 = list()
- pokemonData2 = list()
- pokemonData3 = list()
- pokemonData4 = list()
- i = 0
- j = range(int(saveData['Pokemon Count'], 16))
- for i in j:
- print('Pokemon ' + str(i+1) + 'loading')
- pokemonData1.append(binascii.hexlify(saveFile.read(int('88', 16))))
- pokemonData2.append(binascii.hexlify(saveFile.read(int('4', 16))))
- pokemonData3.append(binascii.hexlify(saveFile.read(int('14', 16))))
- pokemonData4.append(binascii.hexlify(saveFile.read(int('4', 16))))
- print('Pokemon ' + str(i+1) + ' loading done')
- saveData['UNK11'] = binascii.hexlify(saveFile.read(int('4', 16)))
- print('Making extraction directories')
- if os.path.exists(fileName+'-EXT'):
- # os.removedir(fileName+'-EXT')
- rmtree(fileName+'-EXT', 1)
- print('Deleted old extraction directory')
- os.mkdir(fileName+'-EXT')
- os.mkdir(fileName+'-EXT' + '/' + 'Unhandled Data')
- os.mkdir(fileName+'-EXT' + '/' + 'Pokemon')
- os.mkdir(fileName+'-EXT' + '/' + 'Trainers')
- print('Directories done')
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'File Length' + '.txt', 'w') as tempData:
- tempData.write(str(saveData['File Length']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'SHA1' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['SHA1'])) # Don't know why I'm even bothering
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK1' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK1']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK2' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK2']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK3' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK3']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK4' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK4']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK5' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK5']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK6' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK6']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'LANG' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['Language']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK7' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK7']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK8' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK8']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii Count' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['Mii Count']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii Data' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['Mii Data']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK9' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK9']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii-Trainer Count' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['Mii-Trainer Count']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii-Trainer Data' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['Mii-Trainer Data']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK12' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK12']))
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK10' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK10']))
- i = 0
- j = range(int(saveData['Pokemon Count'], 16))
- for i in j:
- print('Pokemon ' + str(i+1) + ' saving')
- with open(fileName + '-EXT' + '/' + 'Pokemon' + '/' + 'Ranch-Pokemon' + '{:04d}'.format(i+1) + '.pkm', 'wb') as tempData:
- tempData.write(binascii.unhexlify(pokemonData1[i]))
- with open(fileName + '-EXT' + '/' + 'Trainers' + '/' + 'Ranch-Pokemon' + '{:04d}'.format(i+1) + '.rid', 'wb') as tempData:
- tempData.write(binascii.unhexlify(pokemonData2[i]))
- with open(fileName + '-EXT' + '/' + 'Trainers' + '/' + 'Ranch-Pokemon' + '{:04d}'.format(i+1) + '.tnr', 'wb') as tempData:
- tempData.write(binascii.unhexlify(pokemonData3[i]))
- with open(fileName + '-EXT' + '/' + 'Trainers' + '/' + 'Ranch-Pokemon' + '{:04d}'.format(i+1) + '.pad', 'wb') as tempData:
- tempData.write(binascii.unhexlify(pokemonData4[i]))
- print('Pokemon ' + str(i+1) + ' saving done')
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK11' + '.hex', 'wb') as tempData:
- tempData.write(binascii.unhexlify(saveData['UNK11']))
- print('Done')
- def saveCompile(fileName):
- saveData = dict()
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'File Length' + '.txt', 'r') as fileData:
- saveData['File Length'] = int(fileData.read())
- # with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'SHA1' + '.hex', 'rb') as fileData:
- # saveData['SHA1'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK1' + '.hex', 'rb') as fileData:
- saveData['UNK1'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK2' + '.hex', 'rb') as fileData:
- saveData['UNK2'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK3' + '.hex', 'rb') as fileData:
- saveData['UNK3'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK4' + '.hex', 'rb') as fileData:
- saveData['UNK4'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK5' + '.hex', 'rb') as fileData:
- saveData['UNK5'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK6' + '.hex', 'rb') as fileData:
- saveData['UNK6'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'LANG' + '.hex', 'rb') as fileData:
- saveData['Language'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK7' + '.hex', 'rb') as fileData:
- saveData['UNK7'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK8' + '.hex', 'rb') as fileData:
- saveData['UNK8'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii Count' + '.hex', 'rb') as fileData:
- saveData['Mii Count'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii Data' + '.hex', 'rb') as fileData:
- saveData['Mii Data'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK9' + '.hex', 'rb') as fileData:
- saveData['UNK9'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii-Trainer Count' + '.hex', 'rb') as fileData:
- saveData['Mii-Trainer Count'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'Mii-Trainer Data' + '.hex', 'rb') as fileData:
- saveData['Mii-Trainer Data'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK12' + '.hex', 'rb') as fileData:
- saveData['UNK12'] = binascii.hexlify(fileData.read())
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK10' + '.hex', 'rb') as fileData:
- saveData['UNK10'] = binascii.hexlify(fileData.read())
- pokemonFileList = glob.glob(fileName + '-EXT' + '/' + 'Pokemon' + '/*.pkm')
- print(pokemonFileList)
- pokemonData1 = list()
- pokemonData2 = list()
- pokemonData3 = list()
- pokemonData4 = list()
- pokemonNewData = list()
- print('Pokemon file list length', len(pokemonFileList))
- saveData['Pokemon Count'] = '{:08X}'.format(len(pokemonFileList))
- i = 0
- j = range(int(saveData['Pokemon Count'], 16))
- for i in j:
- with open(pokemonFileList[i], 'rb') as fileData:
- print('Pokemon file name', fileData.name)
- if fileData.name.count('Ranch-Pokemon'):
- pokemonData1.append(binascii.hexlify(fileData.read()))
- fileData2 = open(fileData.name.partition('.')[0].replace('Pokemon', 'Trainers', 1) + '.rid', 'rb')
- fileData3 = open(fileData.name.partition('.')[0].replace('Pokemon', 'Trainers', 1) + '.tnr', 'rb')
- fileData4 = open(fileData.name.partition('.')[0].replace('Pokemon', 'Trainers', 1) + '.pad', 'rb')
- tempData = binascii.hexlify(fileData2.read())
- if len(tempData) != 0:
- pokemonData2.append(tempData)
- pokemonDataPrev2 = tempData
- else:
- pokemonData2.append(pokemonDataPrev2)
- tempData = binascii.hexlify(fileData3.read())
- if len(tempData) != 0:
- pokemonData3.append(tempData)
- pokemonDataPrev3 = tempData
- else:
- pokemonData3.append(pokemonDataPrev3)
- tempData = binascii.hexlify(fileData4.read())
- if len(tempData) != 0:
- pokemonData4.append(tempData)
- pokemonDataPrev4 = tempData
- else:
- pokemonData4.append(pokemonDataPrev4)
- fileData2.close()
- fileData3.close()
- fileData4.close()
- print('Pokemon Data 1', pokemonData1[-1])
- print('Pokemon Data 2', pokemonData2[-1])
- print('Pokemon Data 3', pokemonData3[-1])
- print('Pokemon Data 4', pokemonData4[-1])
- else:
- pokemonNewData.append(binascii.hexlify(fileData.read()))
- print('New Pokemon Data', pokemonNewData[-1])
- with open(fileName + '-EXT' + '/' + 'Unhandled Data' + '/' + 'UNK11' + '.hex', 'rb') as fileData:
- saveData['UNK11'] = binascii.hexlify(fileData.read())
- saveData['SHA1'] = '{:040X}'.format(0)
- saveData['Mii Data Offset'] = '{:08X}'.format(1)
- saveData['Mii-Trainer Data Offset'] = '{:08X}'.format(2)
- saveData['Pokemon Data Offset'] = '{:08X}'.format(3)
- saveData['Pokemon Data End Offset'] = '{:08X}'.format(4)
- with open(fileName + '.bin', 'wb') as tempData:
- tempData.seek(0)
- print('Padding for SHA1')
- tempData.write(binascii.unhexlify(saveData['SHA1']))
- print('UNK1 is ' + str(saveData['UNK1']))
- tempData.write(binascii.unhexlify(saveData['UNK1']))
- print('UNK2 is ' + str(saveData['UNK2']))
- tempData.write(binascii.unhexlify(saveData['UNK2']))
- print('Padding for Mii Data Offset')
- tempData.write(binascii.unhexlify(saveData['Mii Data Offset']))
- print('UNK3 is ' + str(saveData['UNK3']))
- tempData.write(binascii.unhexlify(saveData['UNK3']))
- print('Padding for Mii-Trainer Data Offset')
- tempData.write(binascii.unhexlify(saveData['Mii-Trainer Data Offset']))
- print('UNK4 is ' + str(saveData['UNK4']))
- tempData.write(binascii.unhexlify(saveData['UNK4']))
- print('Padding for Pokemon Data Offset')
- tempData.write(binascii.unhexlify(saveData['Pokemon Data Offset']))
- print('UNK5 is ' + str(saveData['UNK5']))
- tempData.write(binascii.unhexlify(saveData['UNK5']))
- print('Padding for Pokemon Data End Offset')
- tempData.write(binascii.unhexlify(saveData['Pokemon Data End Offset']))
- print('UNK6 is ' + str(saveData['UNK6']))
- tempData.write(binascii.unhexlify(saveData['UNK6']))
- print('Language is ' + str(saveData['Language']))
- tempData.write(binascii.unhexlify(saveData['Language']))
- # print('UNK7 is ' + str(saveData['UNK7']))
- tempData.write(binascii.unhexlify(saveData['UNK7']))
- saveData['Mii Data Offset'] = '{:08X}'.format(tempData.tell())
- print('Mii Data Offset is ' + str(saveData['Mii Data Offset']))
- print('UNK8 is ' + str(saveData['UNK8']))
- tempData.write(binascii.unhexlify(saveData['UNK8']))
- print('Mii Count is ' + str(saveData['Mii Count']))
- tempData.write(binascii.unhexlify(saveData['Mii Count']))
- # print('Mii Data is ' + str(saveData['Mii Data']))
- tempData.write(binascii.unhexlify(saveData['Mii Data']))
- saveData['Mii-Trainer Data Offset'] = '{:08X}'.format(tempData.tell())
- print('Mii-Trainer Data Offset is ' + str(saveData['Mii-Trainer Data Offset']))
- print('UNK9 is ' + str(saveData['UNK9']))
- tempData.write(binascii.unhexlify(saveData['UNK9']))
- print('Mii-Trainer Count is ' + str(saveData['Mii-Trainer Count']))
- tempData.write(binascii.unhexlify(saveData['Mii-Trainer Count']))
- # print('Mii-Trainer Data is ' + str(saveData['Mii-Trainer Data']))
- tempData.write(binascii.unhexlify(saveData['Mii-Trainer Data']))
- # print('UNK12 is ' + str(saveData['UNK12']))
- tempData.write(binascii.unhexlify(saveData['UNK12']))
- saveData['Pokemon Data Offset'] = '{:08X}'.format(tempData.tell())
- print('Pokemon Data Offset is ' + str(saveData['Pokemon Data Offset']))
- print('UNK10 is ' + str(saveData['UNK10']))
- tempData.write(binascii.unhexlify(saveData['UNK10']))
- print('Pokemon Count is ' + str(saveData['Pokemon Count']))
- tempData.write(binascii.unhexlify(saveData['Pokemon Count']))
- i = 0
- j = range(len(pokemonData1))
- print('Pokemon data 1 len', len(pokemonData1))
- for i in j:
- tempData.write(binascii.unhexlify(pokemonData1[i]))
- tempData.write(binascii.unhexlify(pokemonData2[i]))
- tempData.write(binascii.unhexlify(pokemonData3[i]))
- tempData.write(binascii.unhexlify(pokemonData4[i]))
- i = 0
- j = range(len(pokemonNewData))
- print('Pokemon new data len', len(pokemonNewData))
- if len(pokemonNewData) != 0:
- for i in j:
- print('New Pokemon data', pokemonNewData[i])
- tempData.write(binascii.unhexlify(pokemonNewData[i]))
- tempData.write(binascii.unhexlify(pokemonData2[-1]))
- tempData.write(binascii.unhexlify(pokemonData3[-1]))
- tempData.write(binascii.unhexlify(pokemonData4[-1]))
- saveData['Pokemon Data End Offset'] = '{:08X}'.format(tempData.tell())
- print('Pokemon Data End Offset is ' + str(saveData['Pokemon Data End Offset']))
- print('UNK11 is ' + str(saveData['UNK11']))
- tempData.write(binascii.unhexlify(saveData['UNK11']))
- while tempData.tell() < saveData['File Length']:
- tempData.write(binascii.unhexlify('00'))
- tempData.seek(int('24', 16))
- tempData.write(binascii.unhexlify(saveData['Mii Data Offset']))
- tempData.seek(int('2C', 16))
- tempData.write(binascii.unhexlify(saveData['Mii-Trainer Data Offset']))
- tempData.seek(int('34', 16))
- tempData.write(binascii.unhexlify(saveData['Pokemon Data Offset']))
- tempData.seek(int('3C', 16))
- tempData.write(binascii.unhexlify(saveData['Pokemon Data End Offset']))
- print('Done')
- calcHash(fileName + '.bin')
- def calcHash(toHash):
- with open(toHash, 'rb+') as fileData:
- fileData.seek(20)
- # sha1Result = '{:040X}'.format(hashlib.sha1(fileData.read()).hexdigest())
- sha1Result = hashlib.sha1(fileData.read()).hexdigest()
- print('New SHA1', sha1Result)
- fileData.seek(0)
- fileData.write(binascii.unhexlify(sha1Result))
- handler(inputName)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement