Guest User

Untitled

a guest
Aug 15th, 2012
801
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.67 KB | None | 0 0
  1. public class pk2Reader
  2. {
  3. Blowfish blowfish = new Blowfish(); //Credits as always to pushedx aka Drew_Benton
  4. byte[] bKey = new byte[] { 0x32, 0xCE, 0xDD, 0x7C, 0xBC, 0xA8 };
  5. public pk2Header header { get; set; }
  6. public List<Pk2EntryBlock> EntryBlocks = new List<Pk2EntryBlock>();
  7. public List<pFile> Files = new List<pFile>();
  8. public List<pFolder> Folders = new List<pFolder>();
  9.  
  10. pFolder currentFolder;
  11. pFolder mainFolder;
  12. FileStream fileStream;
  13.  
  14.  
  15. public pk2Reader(string silkroadPath)
  16. {
  17. if (!File.Exists(silkroadPath))
  18. {
  19. throw new Exception("pk2 not found. Please set the correct Path to your Silkroad directory");
  20. }
  21. fileStream = new FileStream(silkroadPath, FileMode.Open, FileAccess.Read, FileShare.Read);
  22. blowfish.Initialize(bKey);
  23. BinaryReader reader = new BinaryReader(fileStream);
  24. header = (pk2Header)BufferToStruct(reader.ReadBytes(256), typeof(pk2Header));
  25. Console.WriteLine(header.Name);
  26. currentFolder = new pFolder();
  27. currentFolder.name = silkroadPath;
  28. currentFolder.files = new List<pFile>();
  29. currentFolder.subfolders = new List<pFolder>();
  30.  
  31. mainFolder = currentFolder;
  32. Read(reader.BaseStream.Position);
  33. Console.WriteLine("Done. Found {0} files.", Files.Count);
  34. }
  35.  
  36.  
  37.  
  38. public bool FileExists(string name)
  39. {
  40. pFile file = Files.Find(item => item.name.ToLower() == name.ToLower());
  41. if (file.position != 0)
  42. {
  43. return true;
  44. }
  45. else
  46. {
  47. return false;
  48. }
  49. }
  50.  
  51. public byte[] getFile(string name)
  52. {
  53. if (FileExists(name))
  54. {
  55. BinaryReader reader = new BinaryReader(fileStream);
  56. pFile file = Files.Find(item => item.name.ToLower() == name.ToLower());
  57. reader.BaseStream.Position = file.position;
  58. return reader.ReadBytes((int)file.size);
  59. }
  60. else
  61. {
  62. throw new Exception(string.Format("pk2Reader: File not found: {0}", name));
  63. }
  64. }
  65.  
  66. public List<string> GetFileNames()
  67. {
  68. List<string> tmpList = new List<string>();
  69. foreach(pFile file in Files)
  70. {
  71. tmpList.Add(file.name);
  72. }
  73. return tmpList;
  74. }
  75.  
  76. void Read(long position)
  77. {
  78. BinaryReader reader = new BinaryReader(fileStream);
  79. reader.BaseStream.Position = position;
  80. List<pFolder> folders = new List<pFolder>();
  81. Pk2EntryBlock entryBlock = (Pk2EntryBlock)BufferToStruct(blowfish.Decode(reader.ReadBytes(Marshal.SizeOf(typeof(Pk2EntryBlock)))), typeof(Pk2EntryBlock));
  82.  
  83.  
  84.  
  85. for (int i = 0; i < 20; i++)
  86. {
  87. pk2Entry entry = entryBlock.entries[i]; //.....
  88. switch (entry.type)
  89. {
  90. case 0: //Null Entry
  91.  
  92. break;
  93. case 1: //Folder
  94. if (entry.name != "." && entry.name != "..")
  95. {
  96. pFolder folder = new pFolder();
  97. folder.name = entry.name;
  98. folder.position = BitConverter.ToInt64(entry.position, 0);
  99. folders.Add(folder);
  100. Folders.Add(folder);
  101. currentFolder.subfolders.Add(folder);
  102. }
  103. break;
  104. case 2: //File
  105. pFile file = new pFile();
  106. file.position = entry.Position;
  107. file.name = entry.name;
  108. file.size = entry.Size;
  109. file.parentFolder = currentFolder;
  110. Files.Add(file);
  111. currentFolder.files.Add(file);
  112. break;
  113. }
  114.  
  115. }
  116. if (entryBlock.entries[19].nChain != 0)
  117. {
  118. Read(entryBlock.entries[19].nChain);
  119. }
  120.  
  121.  
  122. foreach (pFolder folder in folders)
  123. {
  124. currentFolder = folder;
  125. if (folder.files == null)
  126. {
  127. folder.files = new List<pFile>();
  128. }
  129. if (folder.subfolders == null)
  130. {
  131. folder.subfolders = new List<pFolder>();
  132. }
  133. Console.WriteLine(folder.name);
  134. Read(folder.position);
  135. }
  136.  
  137. }
  138. object BufferToStruct(byte[] buffer, Type returnStruct)
  139. {
  140. IntPtr pointer = Marshal.AllocHGlobal(buffer.Length);
  141. Marshal.Copy(buffer, 0, pointer, buffer.Length);
  142. return Marshal.PtrToStructure(pointer, returnStruct);
  143. }
  144. }
  145. public struct pFile
  146. {
  147. public string name;
  148. public long position;
  149. public uint size;
  150. public pFolder parentFolder;
  151. }
  152. public class pFolder
  153. {
  154. public string name;
  155. public long position;
  156. public List<pFile> files;
  157. public List<pFolder> subfolders;
  158. }
  159.  
  160. [StructLayout(LayoutKind.Sequential, Size = 256)]
  161. public struct pk2Header
  162. {
  163. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
  164. public string Name;
  165. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  166. public byte[] version;
  167. [MarshalAs(UnmanagedType.I1, SizeConst = 1)]
  168. public byte encryption;
  169. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
  170. public byte[] verify;
  171. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 205)]
  172. public byte[] reserved;
  173.  
  174. }
  175.  
  176. [StructLayout(LayoutKind.Sequential, Size = 128)]
  177. public struct pk2Entry
  178. {
  179. [MarshalAs(UnmanagedType.I1)]
  180. public byte type; //files are 2, folger are 1, null entries re 0
  181. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
  182. public string name;
  183. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  184. public byte[] accessTime;
  185. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  186. public byte[] createTime;
  187. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  188. public byte[] modifyTime;
  189. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  190. public byte[] position;
  191. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  192. public byte[] size;
  193. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  194. public byte[] nextChain;
  195. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  196. public byte[] padding;
  197.  
  198. public long nChain { get { return BitConverter.ToInt64(nextChain, 0); } }
  199. public long Position { get { return BitConverter.ToInt64(position, 0); } }
  200. public uint Size { get { return BitConverter.ToUInt32(size, 0); } }
  201. }
  202. [StructLayout(LayoutKind.Sequential, Size = 2560)]
  203. public struct Pk2EntryBlock
  204. {
  205. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  206. public pk2Entry[] entries;
  207. }
Advertisement
Add Comment
Please, Sign In to add comment