Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Choose where you dumped the files and where to put the decoded audio:
- itextureDirectory = r"F:\Symthic\BF4\Data\bf4 dump\bundles\res"
- targetDirectory = r"F:\Symthic\BF4\Data\bf4 dump\res"
- ##itextureDirectory = r"F:\Symthic\BF4\Data\bf4 dump\bundles\res"
- #These paths are relative to the dumpDirectory. They don't need to be changed.
- ##ebxFolder = r"bundles\ebx" #files are not restricted to the Sound folder in bf4. As a result it will seem that the script does nothing for a while.
- resFolder = r"bundles\res"
- chunkFolder = r"F:\Symthic\BF4\Data\bf4 dump\chunks"
- chunkFolder2 = r"F:\Symthic\BF4\Data\bf4 dump\bundles\chunks" #if the chunk is not found in the first folder, use this one
- #There was a console game for Frostbite 2 in which the byte order of the chunk ids given in the ebx was changed a bit
- #so it did not match the ids in the chunk folders. See also http://www.bfeditor.org/forums/index.php?showtopic=15780&view=findpost&p=106500
- #Unless you know for sure that the ids are obfuscated, don't set this to True.
- ChunkIdObfuscation=True
- obfuscationPermutation=[3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15]
- EXTENSION=".itexture" #Use a different file extension if you like.
- #I'm at a loss as to what the fuck the devs were thinking. I wrote tools to decrypt the toc files (all credit to gibbed/Rick though for the algorithm),
- #then read in the decrypted data to split the sb into separate bundles, then read in the bundles to get the individual entries.
- #Then wrote like 6 different functions to retrieve the actual payload depending on whether it's patched or not, and using cas or not.
- #Then wrote a tool to deal with the binary XML/ebx files. Then hacked something together to decode the audio.
- #And they expected me to get that far, but stop at a simplistic permutation, which leaves the second half of the id intact?
- #I'll just leave this in, just in case another dev has a brilliant idea again.
- ##############################################################
- ##############################################################
- from binascii import hexlify
- from struct import unpack,pack
- import os
- from cStringIO import StringIO
- import subprocess
- from ctypes import *
- def makeLongDirs(path):
- #create folders if necessary and return the file handle
- #first of all, create one folder level manully because makedirs might fail
- path=os.path.normpath(path)
- pathParts=path.split("\\")
- manualPart="\\".join(pathParts[:2])
- if not os.path.isdir(manualPart): os.makedirs(manualPart)
- #now handle the rest, including extra long path names
- folderPath=lp(os.path.dirname(path))
- if not os.path.isdir(folderPath): os.makedirs(folderPath)
- def open2(path,mode="rb"):
- if mode=="wb": makeLongDirs(path)
- return open(lp(path),mode)
- def lp(path): #long pathnames
- if len(path)<=247 or path=="" or path[:4]=='\\\\?\\': return path
- return unicode('\\\\?\\' + os.path.normpath(path))
- class iTexture:
- def __init__(self, f, relPath, newout):
- #metadata
- self.header=f.read(28)
- self.ChunkId=f.read(16)
- ##print "oldchunk "+hexlify(self.ChunkId)
- self.footer=f.read(84)
- f.close()
- chunkname=chunkFolder2+"\\"+(hexlify(self.ChunkId))+".chunk"
- if os.path.isfile(chunkname):
- raise ValueError("ChunkId is obfuscation FALSE: ")
- chunkname2=chunkFolder+"\\"+(hexlify(self.ChunkId))+".chunk"
- if os.path.isfile(chunkname2):
- raise ValueError("ChunkId is obfuscation FALSE: ")
- else:
- print newout[:-58]+ " is missing chunk"
- def decode(self, relPath, newout):
- if ChunkIdObfuscation: self.ChunkId="".join([self.ChunkId[permute] for permute in obfuscationPermutation])
- ##print "newchunk "+hexlify(self.ChunkId)
- outName=newout
- ##outName=targetDirectory+relPath+EXTENSION
- f2=open2(outName,"wb")
- f2.write(self.header+self.ChunkId+self.footer)
- f2.close()
- print "replaced"
- #make the paths absolute and normalize the slashes
- targetDirectory=os.path.normpath(targetDirectory) #it's an absolute path already
- def main():
- for dir0, dirs, ff in os.walk(itextureDirectory):
- for fname in ff:
- if fname[-9:]!=".itexture": continue
- absPath=os.path.join(dir0,fname)
- relPath=absPath[len(itextureDirectory):-9]
- f=open(lp(absPath),"rb")
- newout=absPath
- try:
- itexture=iTexture(f, relPath, newout)
- f.close()
- except ValueError as msg:
- f.close()
- if str(msg).startswith("ChunkId is obfuscation FALSE: "):
- continue
- else: asdf
- itexture.decode(relPath, newout)
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement