forked from CVFireDragon/nspBuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnspBuild.py
64 lines (50 loc) · 1.82 KB
/
nspBuild.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import sys, os
from struct import pack as pk, unpack as upk
try:
input = raw_input
except NameError:
pass
def gen_header(argc, argv):
stringTable = '\x00'.join([os.path.basename(file) for file in argv[2:]])
headerSize = 0x10 + (argc-2)*0x18 + len(stringTable)
remainder = 0x10 - headerSize%0x10
headerSize += remainder
fileSizes = [os.path.getsize(file) for file in argv[2:]]
fileOffsets = [sum(fileSizes[:n]) for n in range(argc-2)]
fileNamesLengths = [len(os.path.basename(file))+1 for file in argv[2:]] # +1 for the \x00 separator
stringTableOffsets = [sum(fileNamesLengths[:n]) for n in range(argc-2)]
header = b''
header += b'PFS0'
header += pk('<I', argc-2)
header += pk('<I', len(stringTable)+remainder)
header += b'\x00\x00\x00\x00'
for n in range(argc-2):
header += pk('<Q', fileOffsets[n])
header += pk('<Q', fileSizes[n])
header += pk('<I', stringTableOffsets[n])
header += b'\x00\x00\x00\x00'
header += stringTable.encode()
header += remainder * b'\x00'
return header
def mk_nsp(argc, argv):
if argc < 3:
print('Usage is: %s output file1 file2 ...' % sys.argv[0])
return 1
name = argv[1]
outf = open(name, 'wb')
print('Generating header...')
header = gen_header(argc, argv)
outf.write(header)
for f in argv[2:]:
print('Appending %s...' % f)
with open(f, 'rb') as inf:
while True:
buf = inf.read(4096)
if not buf:
break
outf.write(buf)
print('Saved to %s!' % outf.name)
outf.close()
return 0
if __name__ == '__main__':
sys.exit(mk_nsp(len(sys.argv), sys.argv))