Skip to content

Instantly share code, notes, and snippets.

@PookyFan PookyFan/extract.py Secret
Created Jun 19, 2020

Embed
What would you like to do?
Extracting script for textures of RM VN
#Helping function for retrieving numbers from GTF headers (in big endian)
def getIntegerBE(data, index):
return (ord(data[index]) << 24) + (ord(data[index + 1]) << 16) + (ord(data[index + 2]) << 8) + ord(data[index + 3])
#Find block of data that contains file names
file = open("Graph.dat", "rb")
buf = file.read(1024)
while "Graph.dat" not in buf:
buf = buf[512:]
buf += file.read(512)
chunk = file.read(1024)
buf += chunk
while ".gtf" in chunk:
chunk = file.read(1024)
buf += chunk
while not buf.startswith("Graph.dat"):
buf = buf[1:]
#Get texture file names
textures_names = []
index = 0
start = 0
while buf[index] != '\0' or buf[index + 1] != '\0':
if buf[index] == '\0':
name = buf[start:index]
textures_names.append(name)
start = index + 1
index += 1
#Don't need Graph.dat filename
textures_names = textures_names[1:]
#Look for the beginning of first texture file
while buf[index] == '\0': index += 1
buf = buf[index:]
index = 0
#Extract files one by one
for filename in textures_names:
if ".PNG" in filename:
print "There's a plain PNG file - {0}".format(filename)
buf += file.read(16) #Buffer some more data
index += 8 #Ignore header
chunk_size = getIntegerBE(buf, index)
chunk_type = buf[index + 4:index + 8]
while chunk_type != "IEND":
index += 8 + chunk_size + 4
if index >= len(buf):
#Read only just the beginning of next chunk
buf += file.read(index - len(buf) + 8)
chunk_size = getIntegerBE(buf, index)
chunk_type = buf[index + 4:index + 8]
#Read rest of the last chunk (just 4 bytes of CRC) and save the file
buf += file.read(4)
with open(filename, "wb") as out:
out.write(buf)
buf = ""
index = 0
else:
#Main part of GTF header is 16 bytes long, plus there are additional 4 important bytes, so we need at least 20 bytes buffered for now
if len(buf) < 20:
buf += file.read(20 - len(buf))
#Check for GTF header (just to be extra sure)
if ord(buf[index]) != 2 or ord(buf[index + 1]) != 2 or ord(buf[index + 2]) != 0 or ord(buf[index + 3]) != 255:
raise Exception("No GTF header found for file {0}!".format(filename))
index += 4
#Get length of texture data from header
datasize = getIntegerBE(buf, index)
index += 4
#Get number of textures (just for the sake of it)
texnum = getIntegerBE(buf, index)
index += 8
#Get header size
headsize = getIntegerBE(buf, index)
#Count size of entire file
filesize = headsize + datasize
print "{0} has {1} textures, file size = {2}".format(filename, texnum, filesize)
if len(buf) < filesize:
buf += file.read(filesize - len(buf))
with open(filename, "wb") as out:
out.write(buf)
buf = ""
index = 0
print "Done extracting!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.