Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class pk2Reader
- {
- Blowfish blowfish = new Blowfish(); //Credits as always to pushedx aka Drew_Benton
- byte[] bKey = new byte[] { 0x32, 0xCE, 0xDD, 0x7C, 0xBC, 0xA8 };
- public pk2Header header { get; set; }
- public List<Pk2EntryBlock> EntryBlocks = new List<Pk2EntryBlock>();
- public List<pFile> Files = new List<pFile>();
- public List<pFolder> Folders = new List<pFolder>();
- pFolder currentFolder;
- pFolder mainFolder;
- FileStream fileStream;
- public pk2Reader(string silkroadPath)
- {
- if (!File.Exists(silkroadPath))
- {
- throw new Exception("pk2 not found. Please set the correct Path to your Silkroad directory");
- }
- fileStream = new FileStream(silkroadPath, FileMode.Open, FileAccess.Read, FileShare.Read);
- blowfish.Initialize(bKey);
- BinaryReader reader = new BinaryReader(fileStream);
- header = (pk2Header)BufferToStruct(reader.ReadBytes(256), typeof(pk2Header));
- Console.WriteLine(header.Name);
- currentFolder = new pFolder();
- currentFolder.name = silkroadPath;
- currentFolder.files = new List<pFile>();
- currentFolder.subfolders = new List<pFolder>();
- mainFolder = currentFolder;
- Read(reader.BaseStream.Position);
- Console.WriteLine("Done. Found {0} files.", Files.Count);
- }
- public bool FileExists(string name)
- {
- pFile file = Files.Find(item => item.name.ToLower() == name.ToLower());
- if (file.position != 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- public byte[] getFile(string name)
- {
- if (FileExists(name))
- {
- BinaryReader reader = new BinaryReader(fileStream);
- pFile file = Files.Find(item => item.name.ToLower() == name.ToLower());
- reader.BaseStream.Position = file.position;
- return reader.ReadBytes((int)file.size);
- }
- else
- {
- throw new Exception(string.Format("pk2Reader: File not found: {0}", name));
- }
- }
- public List<string> GetFileNames()
- {
- List<string> tmpList = new List<string>();
- foreach(pFile file in Files)
- {
- tmpList.Add(file.name);
- }
- return tmpList;
- }
- void Read(long position)
- {
- BinaryReader reader = new BinaryReader(fileStream);
- reader.BaseStream.Position = position;
- List<pFolder> folders = new List<pFolder>();
- Pk2EntryBlock entryBlock = (Pk2EntryBlock)BufferToStruct(blowfish.Decode(reader.ReadBytes(Marshal.SizeOf(typeof(Pk2EntryBlock)))), typeof(Pk2EntryBlock));
- for (int i = 0; i < 20; i++)
- {
- pk2Entry entry = entryBlock.entries[i]; //.....
- switch (entry.type)
- {
- case 0: //Null Entry
- break;
- case 1: //Folder
- if (entry.name != "." && entry.name != "..")
- {
- pFolder folder = new pFolder();
- folder.name = entry.name;
- folder.position = BitConverter.ToInt64(entry.position, 0);
- folders.Add(folder);
- Folders.Add(folder);
- currentFolder.subfolders.Add(folder);
- }
- break;
- case 2: //File
- pFile file = new pFile();
- file.position = entry.Position;
- file.name = entry.name;
- file.size = entry.Size;
- file.parentFolder = currentFolder;
- Files.Add(file);
- currentFolder.files.Add(file);
- break;
- }
- }
- if (entryBlock.entries[19].nChain != 0)
- {
- Read(entryBlock.entries[19].nChain);
- }
- foreach (pFolder folder in folders)
- {
- currentFolder = folder;
- if (folder.files == null)
- {
- folder.files = new List<pFile>();
- }
- if (folder.subfolders == null)
- {
- folder.subfolders = new List<pFolder>();
- }
- Console.WriteLine(folder.name);
- Read(folder.position);
- }
- }
- object BufferToStruct(byte[] buffer, Type returnStruct)
- {
- IntPtr pointer = Marshal.AllocHGlobal(buffer.Length);
- Marshal.Copy(buffer, 0, pointer, buffer.Length);
- return Marshal.PtrToStructure(pointer, returnStruct);
- }
- }
- public struct pFile
- {
- public string name;
- public long position;
- public uint size;
- public pFolder parentFolder;
- }
- public class pFolder
- {
- public string name;
- public long position;
- public List<pFile> files;
- public List<pFolder> subfolders;
- }
- [StructLayout(LayoutKind.Sequential, Size = 256)]
- public struct pk2Header
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
- public string Name;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- public byte[] version;
- [MarshalAs(UnmanagedType.I1, SizeConst = 1)]
- public byte encryption;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
- public byte[] verify;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 205)]
- public byte[] reserved;
- }
- [StructLayout(LayoutKind.Sequential, Size = 128)]
- public struct pk2Entry
- {
- [MarshalAs(UnmanagedType.I1)]
- public byte type; //files are 2, folger are 1, null entries re 0
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
- public string name;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] accessTime;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] createTime;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] modifyTime;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] position;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- public byte[] size;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] nextChain;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
- public byte[] padding;
- public long nChain { get { return BitConverter.ToInt64(nextChain, 0); } }
- public long Position { get { return BitConverter.ToInt64(position, 0); } }
- public uint Size { get { return BitConverter.ToUInt32(size, 0); } }
- }
- [StructLayout(LayoutKind.Sequential, Size = 2560)]
- public struct Pk2EntryBlock
- {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
- public pk2Entry[] entries;
- }
Advertisement
Add Comment
Please, Sign In to add comment