Hi Razor12911
Could you add support for Traveller's Tales games DAT files?
QuickBMS Script
Code:
# Traveller's Tales games DAT files extractor (script 0.9.11a)
# Lego Movie: The Video Game
# LEGO Batman 1
# LEGO Batman 2
# LEGO Star Wars
# LEGO Star Wars III
# LEGO Indiana Jones
# LEGO Harry Potter
# LEGO Pirates of the Caribbean
# LEGO Lord of the Rings
# Transformers
# LEGO Worlds
# LEGO MARVELs Avengers
# LEGO Dimensions
# Lego Marvel Super Heroes
# Lego Star Wars: The Force Awakens
# Lego NinjaGO
# others, check them on http://www.ttgames.com
#
# In case of problems with the extraction try setting NAMELESS to 1
# thanx to who fixed the handling of the names!
#
# Note that the script may not work with the compressed files of
# Lego Movie for PS3, in case of crashes or other issues you can
# extract only the non compressed files by setting
# EXTRACT_COMPRESSED to 0.
#
# script for QuickBMS http://quickbms.aluigi.org
math FORCE_CRC_BITS = 0 # use 32, 64 or 0 for auto-guess, just in case auto-guess fails
quickbmsver "0.8.0"
set NAMELESS long 0 # set to 1 to extract the files without names
set EXTRACT_COMPRESSED long 1 # set to 0 to extract ONLY the non-compressed files
math HAVE_CRCS = 0
math CRC_FNV_OFFSET = 0x811c9dc5
math CRC_FNV_PRIME = 0x199933
set SIGN_1234567a binary "\x7a\x56\x34\x12"
getdstring SIGN 4
goto 0
if SIGN u== SIGN_1234567a
goto 0
callfunction EXTRACT_1234567a 1
cleanexit
endif
string SIGN f SIGN
math ONE_FILE = 0
if SIGN == "LZ2K"
math ONE_FILE = 1
elif SIGN == "DFLT"
math ONE_FILE = 1
elif SIGN == "ZLIB" # currently doesn't exist
math ONE_FILE = 1
elif SIGN == "LZMA" # currently doesn't exist
math ONE_FILE = 1
elif SIGN == "ZIPX"
math ONE_FILE = 1
elif SIGN == "RFPK"
math ONE_FILE = 1
elif SIGN == "RNC_"
math ONE_FILE = 1
elif SIGN == "Defl" # "Deflate_v1.0"
goto 0
math OFFSET = 0
get SIZE asize
get NAME basename
get EXT extension
string NAME + "_unpack."
string NAME + EXT
callfunction DEFLATE_UNPACK 1
cleanexit
endif
if ONE_FILE != 0
math OFFSET = 0
get ZSIZE asize
math SIZE = ZSIZE
callfunction UNPACK
log "" 0 SIZE MEMORY_FILE2
cleanexit
endif
get HDR_NAME basename
string HDR_NAME += ".hdr"
open FDSE HDR_NAME 1 EXISTS
if EXISTS != 0
get NAME filename
if NAME == HDR_NAME
get NAME basename
string NAME += ".dat"
open FDSE NAME
endif
callfunction HANDLE_COMPRESSED_DAT 1
get HDR_SIZE asize 1
log MEMORY_FILE 0 HDR_SIZE 1
get DUMMY long MEMORY_FILE
else
callfunction HANDLE_COMPRESSED_DAT 1
get INFO_OFF long
if INFO_OFF & 0x80000000
math INFO_OFF ^= 0xffffffff
math INFO_OFF <<= 8
math INFO_OFF += 0x100
endif
get INFO_SIZE long
log MEMORY_FILE INFO_OFF INFO_SIZE
endif
get TYPE_BOH signed_long MEMORY_FILE
get FILES long MEMORY_FILE
math NEW_FORMAT = 1
if TYPE_BOH != 0x3443432e # game.hdr
if TYPE_BOH != 0x2e434334
if FILES != 0x3443432e # game.dat
if FILES != 0x2e434334
math NEW_FORMAT = 0
endif
endif
endif
endif
if NEW_FORMAT == 1 # ".CC400TAD"
goto 0 MEMORY_FILE
endian big
get HDR_SIZE long MEMORY_FILE
idstring MEMORY_FILE ".CC4"
idstring MEMORY_FILE "0TAD"
get TYPE_BOH signed_long MEMORY_FILE # -8
get NEW_FORMAT_VER long MEMORY_FILE # 1
get FILES long MEMORY_FILE
get NAMES long MEMORY_FILE
get NAMES_SIZE long MEMORY_FILE
savepos NAMES_OFF MEMORY_FILE
math OFFSET = NAMES_OFF
math OFFSET + NAMES_SIZE
goto OFFSET MEMORY_FILE
putarray 10 NAMES "" # necessary and useful
putarray 1 NAMES "" # necessary and useful
get DUMMY long MEMORY_FILE
math MYID = 0
xmath LAST_NAME_WORKAROUND "NAMES - 1"
for i = 0 < NAMES
get NAME_OFF long MEMORY_FILE
get FOLDER_ID short MEMORY_FILE
if NEW_FORMAT_VER >= 2
get DUMMY_ID short MEMORY_FILE
endif
get SOME_ID signed_short MEMORY_FILE
get FILE_ID short MEMORY_FILE
if NAME_OFF != 0xffffffff
savepos TMP MEMORY_FILE
math NAME_OFF + NAMES_OFF
goto NAME_OFF MEMORY_FILE
get NAME string MEMORY_FILE
goto TMP MEMORY_FILE
# I will find a solution another day maybe...
if i == LAST_NAME_WORKAROUND
math FILE_ID = MYID
endif
getarray PATH 1 FOLDER_ID
string NAME p "%s\%s" PATH NAME
if FILE_ID != 0
putarray 10 MYID NAME
math MYID + 1
else
putarray 1 i NAME
endif
endif
next i
get TYPE_BOH signed_long MEMORY_FILE # -8
get FILES long MEMORY_FILE
# performance
putarray 2 FILES 0
putarray 3 FILES 0
putarray 4 FILES 0
putarray 5 FILES 0
for i = 0 < FILES
if TYPE_BOH <= -11
get OFFSET longlong MEMORY_FILE
else
get OFFSET long MEMORY_FILE
endif
get ZSIZE long MEMORY_FILE
get SIZE long MEMORY_FILE
if TYPE_BOH <= -10
math PACKED = SIZE
math SIZE & 0x7fffffff
math PACKED u>> 31
if PACKED != 0
math PACKED = 2 # useless, but we need & 2
endif
else
get PACKED byte MEMORY_FILE
get ZERO short MEMORY_FILE
get OFFSET2 byte MEMORY_FILE
math OFFSET u<< 8
math OFFSET | OFFSET2
endif
putarray 2 i OFFSET
putarray 3 i ZSIZE
putarray 4 i SIZE
putarray 5 i PACKED
next i
callfunction GET_CRCS 1
get EXT extension
if EXT & "DAT" # both DAT and DAT2
else
open FDDE "DAT" # in case HDR has been opened
endif
for i = 0 < FILES
getarray FULLNAME 10 i
callfunction GET_NAME 1
getarray OFFSET 2 IDX
getarray ZSIZE 3 IDX
getarray SIZE 4 IDX
getarray PACKED 5 IDX
callfunction EXTRACT_FILE 1
next i
else
savepos INFO_OFF MEMORY_FILE
math TMP = FILES
math TMP *= 16
math NAME_INFO = INFO_OFF
math NAME_INFO += TMP
goto NAME_INFO MEMORY_FILE
get NAMES long MEMORY_FILE
savepos NAME_INFO MEMORY_FILE
math NAME_FIELD_SIZE = 8
if TYPE_BOH <= -5
math NAME_FIELD_SIZE = 12
endif
math TMP = NAMES
math TMP *= NAME_FIELD_SIZE
math NAME_OFF = NAME_INFO
math NAME_OFF += TMP
goto NAME_OFF MEMORY_FILE
get NAMECRC_OFF long MEMORY_FILE
savepos NAME_OFF MEMORY_FILE
math NAMECRC_OFF += NAME_OFF
goto NAMECRC_OFF MEMORY_FILE
callfunction GET_CRCS 1
if TYPE_BOH <= -2
get DUMMY1 signed_long MEMORY_FILE
get DUMMY2 long MEMORY_FILE
endif
# print "files: %FILES%"
# print "names: %NAMES%"
# print "info_off: %INFO_OFF%"
# print "info_size: %INFO_SIZE%"
# print "name_info: %NAME_INFO%"
# print "name_off: %NAME_OFF%"
# print "namecrc_off: %NAMECRC_OFF%"
set NAMEZ long 0
set FULLNAME string ""
set FULLPATH string ""
for i = 0 < FILES
callfunction SET_NAME 1
callfunction GET_NAME 1
math IDX *= 16
math IDX += INFO_OFF
goto IDX MEMORY_FILE
get OFFSET long MEMORY_FILE
get ZSIZE long MEMORY_FILE
get SIZE long MEMORY_FILE
get PACKED threebyte MEMORY_FILE
get OFFSET2 byte MEMORY_FILE
if TYPE_BOH == -1
# do nothing
else
math OFFSET <<= 8
endif
math OFFSET += OFFSET2
callfunction EXTRACT_FILE 1
next i
endif
startfunction GET_CRCS
math HAVE_CRCS = 0
putarray 0 FILES 0
putarray 11 FILES 0
get TMP1 asize MEMORY_FILE
savepos TMP2 MEMORY_FILE
if TMP2 u< TMP1
xmath TMP4 "TMP2 + (FILES * 4)"
xmath TMP8 "TMP2 + (FILES * 8)"
savepos TMP MEMORY_FILE
goto TMP4 MEMORY_FILE
get ZERO long MEMORY_FILE
if ZERO == 0 # this is just a test because there is no good way to guess if it's 64 or 32bit
math TMP8 = TMP1 # disable 64bit false positives
endif
goto TMP MEMORY_FILE
math CRC_BITS = 32
if TMP8 u< TMP1 && NEW_FORMAT_VER >= 2 # Lego NinjaGo
math CRC_BITS = 64
endif
if FORCE_CRC_BITS >= 32
math CRC_BITS = FORCE_CRC_BITS
endif
if CRC_BITS == 64
callfunction QUICKBMS_4GB_CHECK 1
math CRC_FNV_OFFSET = 0xcbf29ce484222325
math CRC_FNV_PRIME = 1099511628211
math HAVE_CRCS = 2
for i = 0 < FILES
get CRC longlong MEMORY_FILE
putarray 0 i CRC
putarray 11 i 0 # file has been extracted?
next i
elif TMP4 u< TMP1 # no need to check CRC_BITS == 32
math HAVE_CRCS = 1
for i = 0 < FILES
get CRC long MEMORY_FILE
putarray 0 i CRC
putarray 11 i 0 # file has been extracted?
next i
endif
endif
if HAVE_CRCS == 0
for i = 0 < FILES
putarray 0 i 0
putarray 11 i 0 # file has been extracted?
next i
endif
endfunction
startfunction EXTRACT_FILE
endian little # necessary, they are little endian on big endian archives too
goto OFFSET
getdstring SIGN 4
string SIGN f SIGN
if SIGN == "LZ2K"
set PACKED long 2
elif SIGN == "DFLT"
set PACKED long 3
elif SIGN == "ZLIB"
set PACKED long 3
elif SIGN == "LZMA"
set PACKED long 3
elif SIGN == "ZIPX"
set PACKED long 3
elif SIGN == "RFPK"
set PACKED long 3
elif SIGN == "RNC_"
set PACKED long 3
else
set PACKED long 0
endif
if PACKED & 2 # includes both 2 and 3
if EXTRACT_COMPRESSED != 0
callfunction UNPACK
log FULLNAME 0 SIZE MEMORY_FILE2
endif
else
if SIZE != 0
if ZSIZE != 0
if SIZE != ZSIZE
print "SIZE (%SIZE%) and ZSIZE (%ZSIZE%) differ at offset %OFFSET|x%, contact me"
cleanexit
endif
endif
endif
log FULLNAME OFFSET SIZE
endif
endfunction
startfunction SET_NAME
do
goto NAME_INFO MEMORY_FILE
get NEXT signed_short MEMORY_FILE
get PREV signed_short MEMORY_FILE
get OFF signed_long MEMORY_FILE
if TYPE_BOH <= -5 # if NAME_FIELD_SIZE >= 12
get DUMMY long MEMORY_FILE
endif
savepos NAME_INFO MEMORY_FILE
if OFF < 0
set NAME string ""
else
math OFF += NAME_OFF
goto OFF MEMORY_FILE
get NAME string MEMORY_FILE
endif
# used only for LEGO the game if you don't use the hdr file
getvarchr TMP0 NAME 0
if TMP0 >= 0xf0
set NAME string ""
endif
#string NAME u= NAME # needed for the crc check, but doesn't improve performances so much
if PREV != 0
getarray FULLPATH 1 PREV
endif
putarray 1 NAMEZ FULLPATH # putarray 1 NAMEZ NAME
if NEXT > 0 # folder
getarray TMP 1 PREV
if TMP != "" # long story to avoid things like 2foldername that gives problems to QuickBMS
set OLDNAME string \ # do not use /
string OLDNAME += TMP
string OLDNAME += \ # do not use /
string FULLPATH >>= OLDNAME
endif
if NAME != ""
#string FULLPATH += \ # do not use /
string FULLPATH += NAME
string FULLPATH += \ # do not use /
endif
endif
math NAMEZ += 1
while NEXT > 0
set FULLNAME string FULLPATH
string FULLNAME += NAME
endfunction
startfunction GET_CURRENT_NAME
for j = 0 < FILES
getarray TMP 11 j
if TMP == 0 # the first file not extracted yet
math IDX = j
break
endif
next j
endfunction
startfunction GET_NAME
if HAVE_CRCS == 0
callfunction GET_CURRENT_NAME 1
else
getvarchr TMP0 FULLNAME 0
if TMP0 == '\\'
string FULLNAME <<= 1
endif
math IDX = i
if NAMELESS == 0
strlen NAMESZ FULLNAME
string FULLNAME u= FULLNAME
string FULLNAME R= / \
math CRC = CRC_FNV_OFFSET
for j = 0 < NAMESZ
getvarchr CHR FULLNAME j
math CRC ^= CHR
math CRC *= CRC_FNV_PRIME
next j
if HAVE_CRCS <= 1
math CRC &= 0xffffffff # quickbms_4gb_files
endif
for j = 0 < FILES
getarray TMP 0 j # CRC database
if CRC == TMP
math IDX = j
break
endif
next j
if j >= FILES
print "Alert: the crc of the file %FULLNAME% has not been found, I extract the current file"
callfunction GET_CURRENT_NAME 1
endif
else
set FULLNAME string ""
endif
endif
putarray 11 IDX 1 # the file has been extracted
endfunction
startfunction UNPACK
putvarchr MEMORY_FILE2 SIZE 0
log MEMORY_FILE2 0 0
append
for TMPSZ = 0 < ZSIZE
goto OFFSET
getdstring SIGN 4
string SIGN f SIGN
if SIGN == "LZ2K"
comtype lz2k
get CHUNK_SIZE long
get CHUNK_ZSIZE long
elif SIGN == "DFLT"
comtype dflt
get CHUNK_ZSIZE long
get CHUNK_SIZE long
elif SIGN == "ZLIB" # currently doesn't exist
comtype zlib
get CHUNK_ZSIZE long
get CHUNK_SIZE long
elif SIGN == "LZMA" # currently doesn't exist
comtype lzma
get CHUNK_ZSIZE long
get CHUNK_SIZE long
elif SIGN == "ZIPX"
comtype deflate # ??? not tested
get CHUNK_ZSIZE long
get CHUNK_SIZE long
string TMP = CHUNK_ZSIZE
encryption rc4 TMP "" 0 4
elif SIGN == "RFPK"
comtype rfpk
get CHUNK_ZSIZE long
get CHUNK_SIZE long
elif SIGN == "RNC_"
comtype rnc
math CHUNK_SIZE = SIZE
math CHUNK_ZSIZE = ZSIZE
goto OFFSET
else
print "Error: the compressing signature at offset %OFFSET% (%SIGN%) is not known, contact me"
cleanexit
endif
savepos OFFSET
if CHUNK_ZSIZE == CHUNK_SIZE
log MEMORY_FILE2 OFFSET CHUNK_SIZE
else
clog MEMORY_FILE2 OFFSET CHUNK_ZSIZE CHUNK_SIZE
endif
encryption "" ""
math OFFSET += CHUNK_ZSIZE
savepos TMP MEMORY_FILE2
math TMPSZ += 12
math TMPSZ += CHUNK_ZSIZE
next
append
endfunction
startfunction HANDLE_COMPRESSED_DAT
goto 0
getdstring TMP 16
if TMP == "CMP2CMP2CMP2CMP2"
comtype lzma
getdstring DAT_HASH 16
get DAT_SIZE longlong
savepos DAT_OFFSET
get DAT_ZSIZE asize
math DAT_ZSIZE - DAT_OFFSET
clog TEMPORARY_FILE DAT_OFFSET DAT_ZSIZE DAT_SIZE
open "." TEMPORARY_FILE
endif
goto 0
endfunction
startfunction EXTRACT_1234567a
idstring "\x7a\x56\x34\x12" # 0x1234567a
get FILES long
get PAK_SIZE long
get CRC long
get ZERO long
get ZERO long
for i = 0 < FILES
get NAME_OFF long
get OFFSET long
get SIZE long
get DUMMY long # it's ever 4 in any case
get ZERO long
get CRC long
get ZERO long
savepos TMP_OFF
goto NAME_OFF
get NAME string
goto OFFSET
callfunction DEFLATE_UNPACK 1
goto TMP_OFF
next i
endfunction
startfunction DEFLATE_UNPACK
getdstring SIGN 0x20
if SIGN == "Deflate_v1.0"
comtype dflt
get XSIZE long
math OFFSET + 0x24
math SIZE - 0x24
clog NAME OFFSET SIZE XSIZE
else
log NAME OFFSET SIZE
endif
endfunction
startfunction QUICKBMS_4GB_CHECK
math TMP64 = 0x10000000
math TMP64 * 16
if TMP64 == 0
print "you must use quickbms_4gb_files.exe with this archive"
cleanexit
endif
endfunction