Guest User

Untitled

a guest
Mar 21st, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.03 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. # CPK file extractor (e.g. used as ressource packages in some games)
  4.  
  5. import sys, struct, os, zlib
  6.  
  7. class DCPK:
  8. def read_uint(self):
  9. return struct.unpack('<I',self.f.read(4))[0]
  10.  
  11. def __init__(self, cpk, out_dir=''):
  12. self.f = open(cpk,'rb')
  13. self.out_dir = out_dir
  14. assert(self.f.read(4)==b'DCPK')
  15. self.block_count = self.read_uint()
  16. self.data_offset = self.read_uint()
  17. self.data_size = self.read_uint()
  18. self.B = []
  19. for _ in range(self.block_count):
  20. name_length = self.read_uint()
  21. name = self.f.read(name_length).decode().rstrip('\x00')
  22. offset = self.read_uint()
  23. size = self.read_uint()
  24. unknown_field = self.read_uint() # ??
  25. uncompressed_size = self.read_uint()
  26. compressed = self.read_uint() # 0 or 1
  27. self.B.append((name,offset,size,compressed))
  28.  
  29. def print_list(self):
  30. print('%d files in package' % self.block_count)
  31. for (name,_,size,_) in self.B:
  32. print('%s (%dB)' % (name,size))
  33.  
  34. def extract(self, name_size_filter):
  35. if not os.path.exists(self.out_dir):
  36. os.makedirs(self.out_dir)
  37. for (name,offset,size,compressed) in self.B:
  38. if name_size_filter(name,size):
  39. fout = open(os.path.join(self.out_dir,name.replace('/','_')),'wb')
  40. self.f.seek(self.data_offset+offset)
  41. data = self.f.read(size)
  42. if compressed:
  43. data = zlib.decompress(data)
  44. fout.write(data)
  45. fout.close()
  46.  
  47. def main():
  48. if not 2<=len(sys.argv)<=3:
  49. sys.stderr.write('usage: %s in.cpk [out_dir]\n' % sys.argv[0])
  50. sys.exit(1)
  51. out_dir = sys.argv[2] if len(sys.argv)==3 else 'OUT'
  52.  
  53. # filter to extract music in some games
  54. name_size_filter = lambda name,size: 'Music' in name and size > 600<<10
  55. P = DCPK(sys.argv[1],out_dir)
  56. #P.print_list()
  57. P.extract(name_size_filter)
  58.  
  59. main()
Add Comment
Please, Sign In to add comment