/// <summary>
        /// Read the Pk2 structure recursively.
        /// </summary>
        private void Read(long Position, string RootPath)
        {
            BinaryReader reader = new BinaryReader(m_FileStream);

            reader.BaseStream.Position = Position;
            List <Pk2Folder> folders    = new List <Pk2Folder>();
            sPk2EntryBlock   entryBlock = (sPk2EntryBlock)BufferToStruct(m_Blowfish.Decode(reader.ReadBytes(Marshal.SizeOf(typeof(sPk2EntryBlock)))), typeof(sPk2EntryBlock));

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

                    break;

                case 1:                         //Folder
                    if (entry.Name != "." && entry.Name != "..")
                    {
                        Pk2Folder folder = new Pk2Folder();
                        folder.Name     = entry.Name;
                        folder.Position = BitConverter.ToInt64(entry.g_Position, 0);
                        folders.Add(folder);
                        m_Folders[(RootPath + entry.Name).ToUpper()] = folder;
                        m_CurrentFolder.SubFolders.Add(folder);
                    }
                    break;

                case 2:                         //File
                    Pk2File file = new Pk2File();
                    file.Position     = entry.Position;
                    file.Name         = entry.Name;
                    file.Size         = entry.Size;
                    file.ParentFolder = m_CurrentFolder;
                    m_Files[(RootPath + entry.Name).ToUpper()] = file;
                    m_CurrentFolder.Files.Add(file);
                    break;
                }
            }
            if (entryBlock.Entries[19].NextChain != 0)
            {
                Read(entryBlock.Entries[19].NextChain, RootPath);
            }

            foreach (Pk2Folder folder in folders)
            {
                m_CurrentFolder = folder;
                if (folder.Files == null)
                {
                    folder.Files = new List <Pk2File>();
                }
                if (folder.SubFolders == null)
                {
                    folder.SubFolders = new List <Pk2Folder>();
                }
                Read(folder.Position, RootPath + folder.Name + "\\");
            }
        }
 public void Dispose()
 {
     m_CurrentFolder = null;
     m_Files         = null;
     m_FileStream    = null;
     m_Folders       = null;
     Key             = null;
     ASCIIKey        = null;
     m_MainFolder    = null;
     Size            = 0;
 }
        /// <summary>
        /// Check if a file exists in the Pk2 path specified.
        /// </summary>
        public bool FileExists(string FileName, string Path)
        {
            Pk2Folder folder = null;

            m_Folders.TryGetValue(Path, out folder);

            if (folder != null)
            {
                return(folder.Files.Exists(file => file.Name.Equals(FileName, StringComparison.OrdinalIgnoreCase)));
            }
            return(false);
        }
        /// <summary>
        /// Get folders from Pk2 path specified.
        /// </summary>
        public List <Pk2Folder> GetSubFolders(string Path)
        {
            List <Pk2Folder> folders = new List <Pk2Folder>();

            Pk2Folder folder = null;

            m_Folders.TryGetValue(Path, out folder);

            if (folder != null)
            {
                folders.AddRange(folder.SubFolders);
            }
            return(folders);
        }
        /// <summary>
        /// Get files from Pk2 path specified.
        /// </summary>
        public List <Pk2File> GetFiles(string Path)
        {
            List <Pk2File> files = new List <Pk2File>();

            Pk2Folder folder = null;

            m_Folders.TryGetValue(Path, out folder);

            if (folder != null)
            {
                files.AddRange(folder.Files);
            }
            return(files);
        }
        public Pk2Folder GetFolder(string FolderPath)
        {
            if (FolderPath == "")
            {
                return(null);
            }

            // Normalize to the same dictionary key path format
            FolderPath = FolderPath.ToUpper();
            FolderPath = FolderPath.Replace("/", "\\");
            if (FolderPath.EndsWith("\\"))
            {
                FolderPath = FolderPath.Substring(0, FolderPath.Length - 1);
            }

            Pk2Folder folder = null;

            m_Folders.TryGetValue(FolderPath, out folder);
            return(folder);
        }
        public Pk2Reader(string FilePath, string BlowfishKey)
        {
            if (!File.Exists(FilePath))
            {
                throw new Exception("File not found");
            }
            else
            {
                this.FullPath = Path.GetFullPath(FilePath);
                // Set default key for most clients
                if (BlowfishKey == "")
                {
                    ASCIIKey = "169841";
                }
                else
                {
                    ASCIIKey = BlowfishKey;
                }
                Key = GenerateFinalBlowfishKey(ASCIIKey);

                m_FileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                Size         = m_FileStream.Length;

                m_Blowfish.Initialize(Key);
                BinaryReader reader = new BinaryReader(m_FileStream);
                Header = (sPk2Header)BufferToStruct(reader.ReadBytes(256), typeof(sPk2Header));

                m_CurrentFolder            = new Pk2Folder();
                m_CurrentFolder.Name       = FilePath;
                m_CurrentFolder.Files      = new List <Pk2File>();
                m_CurrentFolder.SubFolders = new List <Pk2Folder>();

                m_MainFolder = m_CurrentFolder;
                Read(reader.BaseStream.Position, "");
            }
        }