public void Pack(string source, string destination)
        {
            if (!Path.HasExtension(destination))
            {
                throw new Exception(String.Format("Destination '{0}' has no .ext, please use '.tro' or '.dat'",
                                                  destination));
            }
            string    ext = Path.GetExtension(destination).ToLower();
            HdrHeader header;

            if (ext == ".tro")
            {
                header = HdrHeader.ForTro();
            }
            else if (ext == ".dat")
            {
                header = HdrHeader.ForDat();
            }
            else
            {
                throw new Exception(
                          String.Format("Destination has invalid extension of '{0}', please use '.tro' or '.dat'", ext));
            }
            List <HdrFile> hdrFiles = ReadDirectory(source);
            HdrArchive     archive  = new HdrArchive(hdrFiles, header);

            Write(archive, destination);
        }
        public void Extract(string source, string destination)
        {
            HdrArchive archive = Read(source);

            foreach (HdrFile file in archive.Files)
            {
                string directory     = HdrToOsPath(file.HdrDirectoryPath);
                string directoryPath = Path.Combine(destination, directory);
                Directory.CreateDirectory(directoryPath);
                string filePath = Path.Combine(directoryPath, file.FileName);
                WriteFile(file.Data, filePath);
            }
        }
        public void ExtractOffset(string source, string destination, int offset, int length)
        {
            offset = 101798157;
            length = 4096;
            HdrArchive archive = Read(source);

            foreach (HdrFile hdrFile in archive.Files)
            {
                if (hdrFile.Offset == offset)
                {
                    Console.WriteLine(hdrFile.HdrFullPath);
                }
            }
        }
        public void Write(HdrArchive archive, string destinationPath)
        {
            Dictionary <string, List <HdrFile> > folderDictionary = new Dictionary <string, List <HdrFile> >();
            List <string> orderedKeys = new List <string>();

            foreach (HdrFile file in archive.Files)
            {
                if (archive.Header.ArchiveType == HdrArchiveType.Tro)
                {
                    string[] folderNameParts = file.HdrDirectoryPath.Split('\\');
                    string   folderName      = "";
                    for (int i = 0; i < folderNameParts.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(folderNameParts[i]))
                        {
                            folderName += folderNameParts[i] + '\\';
                            if (!folderDictionary.ContainsKey(folderName))
                            {
                                folderDictionary.Add(folderName, new List <HdrFile>());
                                orderedKeys.Add(folderName);
                            }
                        }
                    }
                }
                if (folderDictionary.ContainsKey(file.HdrDirectoryPath))
                {
                    folderDictionary[file.HdrDirectoryPath].Add(file);
                }
                else
                {
                    folderDictionary.Add(file.HdrDirectoryPath, new List <HdrFile>()
                    {
                        file
                    });
                    orderedKeys.Add(file.HdrDirectoryPath);
                }
            }
            orderedKeys.Sort((s1, s2) => string.Compare(s1, s2, StringComparison.InvariantCultureIgnoreCase));
            IBuffer buffer               = BufferProvider.Provide();
            int     totalFiles           = archive.Files.Count;
            int     currentFile          = 0;
            int     folderIndexStart     = archive.Header.IndexOffset;
            int     fileIndexStart       = folderIndexStart + folderDictionary.Count * IndexBlockSize;
            int     contentStart         = fileIndexStart + IndexBlockSize * archive.Files.Count;
            int     currentFolderIndex   = 0;
            int     currentFileIndex     = 0;
            int     currentContentLength = 0;

            foreach (string key in orderedKeys)
            {
                HdrIndex folderIndex = new HdrIndex();
                folderIndex.Name     = key;
                folderIndex.Length   = folderDictionary[key].Count;
                folderIndex.Position = folderIndexStart + currentFolderIndex;
                if (folderIndex.Length > 0)
                {
                    folderIndex.Offset = fileIndexStart + currentFileIndex;
                }
                else
                {
                    folderIndex.Offset = 0;
                }
                WriteIndex(buffer, folderIndex);
                foreach (HdrFile file in folderDictionary[key])
                {
                    HdrIndex fileIndex = new HdrIndex();
                    fileIndex.Name     = file.FileName;
                    fileIndex.Length   = file.Data.Length;
                    fileIndex.Position = fileIndexStart + currentFileIndex;
                    fileIndex.Offset   = contentStart + currentContentLength;
                    WriteIndex(buffer, fileIndex);
                    buffer.WriteBytes(file.Data, 0, fileIndex.Offset, fileIndex.Length);
                    currentFileIndex     += IndexBlockSize;
                    currentContentLength += file.Data.Length;
                    currentFile++;
                }
                currentFolderIndex += IndexBlockSize;
                OnProgressChanged(totalFiles, currentFile);
            }
            HdrHeader header = new HdrHeader();

            header.ContentOffset = contentStart;
            header.Created       = archive.Header.Created;
            header.FolderCount   = folderDictionary.Count;
            header.Format        = Hdr;
            header.Unknown0      = archive.Header.Unknown0;
            header.IndexOffset   = folderIndexStart;
            buffer.Position      = 0;
            WriteHeader(buffer, header);
            WriteFile(buffer.GetAllBytes(), destinationPath);
        }