Advertisement
CosmicDreamsOfPastes

ubisoftsdf

Aug 15th, 2018
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.12 KB | None | 0 0
  1. # Ubisoft sdf.sdftoc sdfdata (script 0.1.3)
  2. # No support for the merging of the DDS headers with the raw data in the archives.
  3. #
  4. # Thanks to m0xf and his rouge_sdf tool:
  5. # https://forum.xentax.com/viewtopic.php?p=117435#p117435 (exe)
  6. # https://forum.xentax.com/viewtopic.php?p=117746#p117746 (source)
  7. # https://github.com/GoldFarmer/rouge_sdf/blob/master/main.cpp (source mirror)
  8. # script for QuickBMS http://quickbms.aluigi.org
  9.  
  10. get EXT extension
  11. if EXT != "sdftoc"
  12. open FDSE "sdf.sdftoc"
  13. endif
  14.  
  15. get BASE_NAME basename # "sdf"
  16.  
  17. idstring "WEST"
  18. get DUMMY long # 0x16
  19. get INFO_SIZE long
  20. get INFO_ZSIZE long
  21. get OFFSET asize
  22. math OFFSET - 0x30
  23. math OFFSET - INFO_ZSIZE
  24.  
  25. # how to know if the data is compressed with zlib or zstd?
  26. # Version is the same (0x16) and the other fields may be not useful.
  27. # I will check other samples in future, in the meantime let's guess it
  28. comtype zlib_noerror
  29. clog MEMORY_FILE OFFSET INFO_ZSIZE INFO_SIZE
  30. get TMP asize MEMORY_FILE
  31. if TMP == INFO_SIZE
  32. comtype zlib
  33. else
  34. comtype zstd
  35. clog MEMORY_FILE OFFSET INFO_ZSIZE INFO_SIZE
  36. endif
  37.  
  38. set name string ""
  39. callfunction ParseNames
  40.  
  41. startfunction ParseNames
  42. math LAST_packageId = -1
  43.  
  44. get ch byte MEMORY_FILE
  45. if ch == 0
  46. print "Error: Unexcepted byte in file tree"
  47. cleanexit
  48. elif ch >= 1 && ch <= 0x1f
  49. getdstring TMP ch MEMORY_FILE
  50. string name + TMP
  51. callfunction ParseNames
  52. elif ch >= 'A' && ch <= 'Z'
  53. math ch - 'A'
  54. math count1 = ch
  55. math count1 & 7
  56. #xmath flag1 "(ch >> 3) & 1"
  57. if count1 != 0
  58. get strangeId long MEMORY_FILE
  59. get ch2 byte MEMORY_FILE
  60. #xmath byteCount "ch2 & 3"
  61. #xmath byteValue "ch2 >> 2"
  62. #getdstring ddsType byteCount MEMORY_FILE
  63. math ch2 & 3
  64. getdstring ddsType ch2 MEMORY_FILE
  65. for chunkIndex = 0 < count1
  66. get ch3 byte MEMORY_FILE
  67. xmath compressedSizeByteCount "(ch3 & 3) + 1"
  68. xmath packageOffsetByteCount "(ch3 >> 2) & 7"
  69. xmath hasCompression "(ch3 >> 5) & 1"
  70. getdstring decompressedSize compressedSizeByteCount MEMORY_FILE
  71. putvarchr decompressedSize 8 0
  72. getvarchr decompressedSize decompressedSize 0 long
  73. math compressedSize = 0
  74. if hasCompression != 0
  75. getdstring compressedSize compressedSizeByteCount MEMORY_FILE
  76. putvarchr compressedSize 8 0
  77. getvarchr compressedSize compressedSize 0 long
  78. endif
  79. getdstring packageOffset packageOffsetByteCount MEMORY_FILE
  80. putvarchr packageOffset 8 0
  81. getvarchr packageOffset packageOffset 0 longlong
  82. get packageId short MEMORY_FILE
  83.  
  84. callfunction DUMP_FILE 1
  85.  
  86. get fileId long MEMORY_FILE
  87. next chunkIndex
  88. endif
  89. if ch & 8 # flag1
  90. get ch3 byte MEMORY_FILE
  91. getdstring DUMMY ch3 MEMORY_FILE
  92. endif
  93. else
  94. get offset long MEMORY_FILE
  95. callfunction ParseNames
  96. goto offset MEMORY_FILE
  97. callfunction ParseNames
  98. endif
  99. endfunction
  100.  
  101. startfunction DUMP_FILE
  102. if packageId != LAST_packageId
  103. math layer = packageId
  104. math layer / 1000
  105. math layer + 'A'
  106. string TMP p "%s-%C-%04i.sdfdata" BASE_NAME layer packageId
  107. open FDSE TMP 1 EXISTS
  108. math LAST_packageId = packageId
  109. endif
  110.  
  111. if hasCompression != 0
  112. math CHUNK_SIZE = 0x10000
  113. #xmath pageCount "(decompressedSize + 0xffff) >> 16"
  114. math pageCount = decompressedSize
  115. math pageCount x CHUNK_SIZE
  116. math pageCount / CHUNK_SIZE
  117. if pageCount > 1
  118. for page = 0 < pageCount
  119. get compSize short MEMORY_FILE
  120. putarray 0 page compSize
  121. next page
  122. endif
  123. endif
  124.  
  125. if EXISTS != 0
  126. if hasCompression == 0
  127. log name packageOffset decompressedSize 1
  128. else
  129. if pageCount > 1 # because 1 is no chunks
  130. log name 0 0
  131. append
  132. math MYSIZE = decompressedSize
  133. for page = 0 < pageCount
  134. if MYSIZE < CHUNK_SIZE
  135. math CHUNK_SIZE = MYSIZE
  136. endif
  137. getarray compSize 0 page
  138. if compSize == 0 || compSize >= CHUNK_SIZE # correct
  139. log name packageOffset CHUNK_SIZE 1
  140. math packageOffset + CHUNK_SIZE
  141. else
  142. clog name packageOffset compSize CHUNK_SIZE 1
  143. math packageOffset + compSize
  144. endif
  145. math MYSIZE - CHUNK_SIZE
  146. next page
  147. append
  148. else
  149. clog name packageOffset compressedSize decompressedSize 1
  150. endif
  151. endif
  152. endif
  153. endfunction
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement