You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.6 KiB
163 lines
4.6 KiB
#!/usr/bin/python |
|
#! python2 |
|
#Pac Repacker |
|
#Coded by James |
|
|
|
#import |
|
import sys |
|
from struct import pack |
|
|
|
#get the files from the index |
|
def getFiles(index_file, folder): |
|
line = index_file.readline().strip() |
|
files = [] |
|
while line != "": |
|
#if there's a sub PTX archive, repack it first |
|
#then add a ptx file to the files array |
|
if line[-6:] == "folder": |
|
PTX(line[:-7], folder) |
|
files.append("%s.ptx" % line[:-7]) |
|
else: |
|
print "%s" % line |
|
files.append(line) |
|
line = index_file.readline().strip() |
|
return files #this value is an array of all the filenames |
|
|
|
#Another version of getFiles, for PTX usage |
|
def getFilesPTX(index_file): |
|
line = index_file.readline().strip() |
|
files = [] |
|
while line != "": |
|
print "\t%s" % line |
|
files.append(line) |
|
line = index_file.readline().strip() |
|
return files |
|
|
|
#repacks a PTX archive |
|
def PTX(file, folder): |
|
print "\nRepacking PTX Archive: %s" % file |
|
try: |
|
index_file = open("%s/%s/%s.index" % (folder, file, file), "r") |
|
except: |
|
print "Error Reading %s.index from PTX folder %s" % (file, file) |
|
|
|
files = getFilesPTX(index_file) |
|
num_files = len(files) |
|
header = pack("<I", num_files) |
|
body = "" |
|
trailer_open = open("%s/%s.trail" % (folder, file), "rb") |
|
#trailer_open.seek(2048) |
|
trailer = trailer_open.read(2160) |
|
outfile = open("%s/%s.ptx" % (folder, file), "wb") |
|
|
|
for i in range(num_files): |
|
bin_open = open("%s/%s/%s" % (folder, file, files[i]), "rb") |
|
bin_str = bin_open.read() |
|
header += pack("<I", len(bin_str)/1024/2) |
|
body += bin_str |
|
|
|
header += ("00000000".decode("hex"))*(513-num_files) + trailer #cushion |
|
outfile.write(header+body) |
|
print "" |
|
return 0 |
|
|
|
#make the body of the pac file |
|
def MakeBody(files, folder): |
|
header = "PAC" + "00".decode("hex") #default |
|
body = "" |
|
num_files = len(files) |
|
pointers = [0] #starting position |
|
for i in range(num_files): |
|
file_open = open("%s/%s" % (folder, files[i]), "rb") |
|
body += file_open.read() |
|
pointers.append(len(body)) |
|
del pointers[-1] #delete file size marker |
|
|
|
header_len = (num_files * 4) + 8 |
|
|
|
while header_len%16: #if header isn't divisible by 16, make it |
|
header_len += 4 |
|
|
|
|
|
for i in range((header_len-8)/4): |
|
try: |
|
pointers[i] = pointers[i] + header_len #correct the pointers |
|
except IndexError: |
|
pointers.append(0) |
|
|
|
#odd rule |
|
if pointers[-1] == 0 and pointers[-2] == 0 and pointers[-3] == 0: |
|
pointers[-3] = pointers[0] |
|
|
|
#another odd rule, size can't be 20 |
|
if len(pointers) == 42: |
|
pointers.append(0) |
|
pointers.append(0) |
|
pointers.append(pointers[0]) |
|
pointers.append(0) |
|
num_files += 2 |
|
|
|
for i in range(len(pointers)): |
|
pointers[i] = pointers[i] + ((len(pointers)*4)-(header_len-8)) if pointers[i] else 0#correct the pointers |
|
|
|
header += pack("<I", num_files) |
|
for point in pointers: |
|
header += pack("<I", point) |
|
return header+body |
|
|
|
|
|
def main(): |
|
#greetings |
|
print "\n=================================\nDevil May Cry 3 \nPac Repacker\nvBETA\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n" |
|
|
|
#if not enough args, usage |
|
if len(sys.argv) < 2: |
|
print "Usage: %s [folder] {outfile}\nif no outfile given, outfile is [folder].pac" % sys.argv[0] |
|
return -1 |
|
else: |
|
folder = sys.argv[1] #folder |
|
try: |
|
pac_file = sys.argv[2] #name of file if sufficient args |
|
except IndexError: |
|
pac_file = "%s.pac" % folder #else it's [folder].pac |
|
|
|
#if can't open, exit |
|
print "Opening: %s.index" % folder |
|
try: |
|
index_file = open("%s/%s.index" % (folder, folder), "r") |
|
except: |
|
print "Error Opening %s.index" % folder |
|
return -1 |
|
|
|
#if can't read, exit |
|
print "Reading: %s.index\n" % folder |
|
try: |
|
files = getFiles(index_file, folder) |
|
except: |
|
print "Error Reading %s.index" % folder |
|
return -1 |
|
|
|
#contents |
|
pac = MakeBody(files, folder) |
|
|
|
#if can't open output, exit |
|
print "\nOpening: %s" % pac_file |
|
try: |
|
pac_open = open(pac_file, "wb") |
|
except: |
|
print "Error Opening %s" % pac_file |
|
return -1 |
|
|
|
#if can't write output, exit |
|
print "Writing: %s" % pac_file |
|
try: |
|
pac_open.write(pac) |
|
except: |
|
print "Error Writing %s" % pac_file |
|
return -1 |
|
|
|
#all done! |
|
print "\nAll Done!" |
|
return 0 |
|
|
|
main()
|
|
|