Example #1
0
        /// <summary>
        /// Gets the Pk2 folder info
        /// </summary>
        /// <param name="FolderPath">Path to the location inside Pk2</param>
        public Pk2Folder GetFolder(string FolderPath)
        {
            if (FolderPath == "")
            {
                return(m_RootFolder);
            }

            // Normalize key format
            FolderPath = FolderPath.ToUpper(m_EnglishCulture).Replace("/", "\\");
            if (FolderPath.EndsWith("\\"))
            {
                FolderPath = FolderPath.Remove(FolderPath.Length - 1);
            }

            Pk2Folder folder = null;

            m_Folders.TryGetValue(FolderPath, out folder);
            return(folder);
        }
Example #2
0
        /// <summary>
        /// Creates and load all entries from the Pk2 file
        /// </summary>
        /// <param name="FullPath">Path to the file</param>
        /// <param name="BlowfishKey">Key used to decrypt the file</param>
        public Pk2Reader(string FullPath, string BlowfishKey)
        {
            if (!File.Exists(FullPath))
            {
                throw new FileNotFoundException("Pk2 file not found!");
            }

            // Normalize path
            this.FullPath = Path.GetFullPath(FullPath);

            // Generate key from string
            Key      = GenerateFinalBlowfishKey(BlowfishKey);
            ASCIIKey = BlowfishKey;

            // Open file
            m_FileStream = new FileStream(this.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            Size         = m_FileStream.Length;

            // Initialize the reader pointer
            m_Blowfish.Initialize(Key);
            BinaryReader reader = new BinaryReader(m_FileStream);

            Header = (sPk2Header)BufferToStruct(reader.ReadBytes(256), typeof(sPk2Header));

            // Initialize root folder
            m_RootFolder = new Pk2Folder {
                Name = Path.GetDirectoryName(this.FullPath)
            };

            // Check if the Pk2 file is loaded correctly
            try
            {
                // Reads stream
                Read(reader.BaseStream.Position, m_RootFolder, string.Empty);
            }
            catch (Exception ex)
            {
                // The only reason to fail is a wrong blowfish key or differents Pk2 structures
                throw new FormatException("The Pk2 structure cannot match with the blowfish key.", ex);
            }
        }
Example #3
0
        /// <summary>
        /// Reads Pk2 block structure from the position specified and save all data into the Folder
        /// </summary>
        private void Read(long Position, Pk2Folder CurrentFolder, string ParentPath)
        {
            // Set cursor position in the stream
            BinaryReader reader = new BinaryReader(m_FileStream);

            reader.BaseStream.Position = Position;

            // Keep a list with all folders from this block to add it to subfolders
            List <Pk2Folder> subfolders = new List <Pk2Folder>();

            // Read pk2 block
            sPk2EntryBlock entryBlock = (sPk2EntryBlock)BufferToStruct(m_Blowfish.Decode(reader.ReadBytes(Marshal.SizeOf(typeof(sPk2EntryBlock)))), typeof(sPk2EntryBlock));

            for (int i = 0; i < 20; i++)
            {
                // Entry
                sPk2Entry entry = entryBlock.Entries[i];

                // Check entry type
                switch (entry.Type)
                {
                // Null Entry
                case 0:
                    break;

                // Folder
                case 1:
                    // Check if is not a parent/root folder
                    if (entry.Name != "." && entry.Name != "..")
                    {
                        Pk2Folder folder = new Pk2Folder()
                        {
                            Name     = entry.Name,
                            Position = BitConverter.ToInt64(entry.g_Position, 0)
                        };
                        // Add subfolder
                        subfolders.Add(folder);

                        // Save dictionary reference
                        m_Folders[ParentPath + entry.Name.ToUpper(m_EnglishCulture)] = folder;
                    }
                    break;

                // File
                case 2:
                    Pk2File file = new Pk2File
                    {
                        Position     = entry.Position,
                        Name         = entry.Name,
                        Size         = entry.Size,
                        ParentFolder = CurrentFolder
                    };
                    // Add files to the current folder
                    CurrentFolder.Files.Add(file);

                    // Save dictionary reference
                    m_Files[ParentPath + entry.Name.ToUpper(m_EnglishCulture)] = file;
                    break;
                }
            }
            // Read the next pk2 block chain
            if (entryBlock.Entries[19].NextChain != 0)
            {
                Read(entryBlock.Entries[19].NextChain, CurrentFolder, ParentPath);
            }

            // Add subfolders to the current folder
            CurrentFolder.SubFolders.AddRange(subfolders);

            // Continue reading folder by folder
            foreach (var f in subfolders)
            {
                Read(f.Position, f, ParentPath + f.Name.ToUpper(m_EnglishCulture) + "\\");
            }
        }