Example #1
0
 public static void Decompress(string filename)
 {
     using (var file = new FileStream("comp1.bin", FileMode.Open))
     {
         using (var compStream = new ZstandardStream(file, CompressionMode.Decompress, true))
         {
             using (var fileOut = new FileStream("comp1.bin.dec", FileMode.Create))
             {
                 compStream.CopyStream(fileOut, 0xc1f0);
             }
         }
     }
 }
Example #2
0
        public void ExtractFileIndex(int index, string outDir, IProgressReport progress, StringBuilder sb = null)
        {
            FileListTab          file       = Table20.FileList[index];
            string               name       = file.Path.GetText();
            DirectoryListTab     dir        = file.Directory;
            DirectoryOffsetTable dirOffset  = dir.DirOffset;
            FileOffsetTab        offsetInfo = file.FileOffset;

            bool isLink = false;

            long   offset = Header.Field10 + dirOffset.Offset + file.FileOffset.Offset * 4;
            string path;

            if (name != null)
            {
                path = Path.Combine(outDir, name);
            }
            else if (file.Parent.HasText())
            {
                path = Path.Combine(outDir, file.Parent.GetText(), index.ToString());
            }
            else
            {
                path = Path.Combine(outDir, "_", index.ToString());
            }

            if (file.IsLink)
            {
                isLink = true;

                while (file.IsLink)
                {
                    file = file.FileOffset.File;
                }

                dir        = file.Directory;
                dirOffset  = dir.DirOffset;
                offsetInfo = file.FileOffset;

                offset = Header.Field10 + dirOffset.Offset + offsetInfo.Offset * 4;
            }

            if (offsetInfo.Flag3)
            {
                dirOffset  = offsetInfo.LinkedDirOffset;
                offsetInfo = offsetInfo.LinkedOffset;

                offset = Header.Field10 + dirOffset.Offset + offsetInfo.Offset * 4;
            }

            //sb?.AppendLine($"{name}, 0x{file.Flags:x2}, 0x{dirOffset.Offset:x}, 0x{file.FileOffset.Offset:x}, 0x{offset:x}, 0x{file.FileOffset.SizeCompressed:x}, 0x{file.FileOffset.Size:x}, 0x{file.FileOffset.Flags:x2}, 0x{file.FileOffset.LinkFileIndex:x}, {file.Flag1}, {file.Flag9}, {file.Flag17}, {file.IsLink}, {file.Flag21}, {file.FileOffset.IsCompressed}, {file.FileOffset.Flag3}, {file.FileOffset.Flag4}, {file.FileOffset.Flag5}, {file.FileOffset.Flag6},");

            //return;

            try
            {
                //if (isLink) return;
                Directory.CreateDirectory(Path.GetDirectoryName(path));

                using (var fileOut = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
                //using (var fileOut = Stream.Null)
                {
                    Stream.Position = offset;

                    if (offsetInfo.Size == 0)
                    {
                        return;
                    }

                    if (offsetInfo.SizeCompressed == 0 || offsetInfo.SizeCompressed == offsetInfo.Size)
                    {
                        Stream.CopyStream(fileOut, offsetInfo.Size);
                    }
                    else
                    {
                        using (var compStream = new ZstandardStream(Stream, CompressionMode.Decompress, true))
                        {
                            compStream.CopyStream(fileOut, offsetInfo.Size);
                        }
                    }
                }

                sb?.AppendLine($"{name}, 0x{file.Flags:x2}, 0x{dirOffset.Offset:x}, 0x{offsetInfo.Offset:x}, 0x{offset:x}, 0x{offsetInfo.SizeCompressed:x}, 0x{offsetInfo.Size:x}, 0x{offsetInfo.Flags:x2}, 0x{offsetInfo.LinkFileIndex:x}, {file.Flag1}, {file.Flag9}, {file.Flag17}, {file.IsLink}, {file.Flag21}, {offsetInfo.IsCompressed}, {offsetInfo.Flag3}, {offsetInfo.Flag4}, {offsetInfo.Flag5}, {offsetInfo.Flag6}, ");
            }
            catch (InvalidDataException)
            {
                progress?.LogMessage($"File index 0x{file.Index:x5} Offset 0x{offset:x9}: Can't decompress {path}");
                try
                {
                    File.Delete(path);
                    sb?.AppendLine($"{name}, 0x{file.Flags:x2}, 0x{dirOffset.Offset:x}, 0x{offsetInfo.Offset:x}, 0x{offset:x}, 0x{offsetInfo.SizeCompressed:x}, 0x{offsetInfo.Size:x}, 0x{offsetInfo.Flags:x2}, 0x{offsetInfo.LinkFileIndex:x}, {file.Flag1}, {file.Flag9}, {file.Flag17}, {file.IsLink}, {file.Flag21}, {offsetInfo.IsCompressed}, {offsetInfo.Flag3}, {offsetInfo.Flag4}, {offsetInfo.Flag5}, {offsetInfo.Flag6}, X");

                    var badPath = Path.Combine(outDir, "bad", index.ToString());
                    Directory.CreateDirectory(Path.GetDirectoryName(badPath));

                    using (var fileOut = new FileStream(badPath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        Stream.Position = offset;
                        var info = file.FileOffset;

                        if (info.Size == 0)
                        {
                            return;
                        }

                        Stream.CopyStream(fileOut, info.Size);
                    }
                }
                catch (Exception) { }
            }
            catch (Exception)
            {
                progress?.LogMessage($"File index 0x{file.Index:x5}: Bad path {path}");
                try
                {
                    File.Delete(path);
                }
                catch (Exception) { }
            }
        }