Exemple #1
0
 public void ExtractAll(string path)
 {
     foreach (KeyValuePair <string, ZFSFileInfo> zfsFileInfo in _files)
     {
         using (FastBinaryReader stream = GetDataStream(zfsFileInfo.Value))
         {
             byte[] buf = stream.ReadBytes((int)zfsFileInfo.Value.Length);
             File.WriteAllBytes(Path.Combine(path, zfsFileInfo.Value.Filename), buf);
         }
     }
 }
Exemple #2
0
        public AudioClip GetAudioClip(string filename)
        {
            if (!_files.TryGetValue(filename.ToLower(), out ZFSFileInfo fileInfo))
            {
                Debug.Log("File '" + filename + "' does not exist.");
                return(null);
            }

            using (FastBinaryReader reader = GetFileStream(filename))
            {
                byte[] data = reader.ReadBytes((int)(reader.Length - reader.Position));
                return(WavUtility.ToAudioClip(data, filename));
            }
        }
Exemple #3
0
        public void Init()
        {
            _zfsMemory = File.ReadAllBytes(ZFSFilepath);

            List <ZFSFileInfo> pixFiles = new List <ZFSFileInfo>();
            FastBinaryReader   br       = new FastBinaryReader(_zfsMemory);

            string magic = br.ReadCString(4);

            if (magic != "ZFSF")
            {
                throw new Exception("Not an ZFS file");
            }
            uint version = br.ReadUInt32();

            if (version != 1)
            {
                throw new Exception("Only version 1 ZFS files supported");
            }
            uint unk1 = br.ReadUInt32();
            uint numFilesInEachDirectory = br.ReadUInt32();
            uint numFilesTotal           = br.ReadUInt32();
            uint unk2 = br.ReadUInt32();
            uint unk3 = br.ReadUInt32();

            while (true)
            {
                uint nextDirOffset = br.ReadUInt32();
                for (int fileIdx = 0; fileIdx < numFilesInEachDirectory; fileIdx++)
                {
                    if (_files.Count == numFilesTotal)
                    {
                        break;
                    }
                    ZFSFileInfo zfsFileInfo = new ZFSFileInfo();
                    zfsFileInfo.Filename = br.ReadCString(16).ToLower();
                    zfsFileInfo.Offset   = br.ReadUInt32();
                    zfsFileInfo.Id       = br.ReadUInt32();
                    zfsFileInfo.Length   = br.ReadUInt32();
                    br.ReadUInt32(); // Unk
                    zfsFileInfo.Compression        = br.ReadByte();
                    zfsFileInfo.DecompressedLength = br.ReadUInt16();
                    zfsFileInfo.DecompressedLength =
                        (uint)(br.ReadByte() << 16) |
                        zfsFileInfo.DecompressedLength; // Unk perhaps decompressed length is 3 bytes

                    _files.Add(zfsFileInfo.Filename, zfsFileInfo);
                    if (zfsFileInfo.Filename.EndsWithFast(".pix"))
                    {
                        pixFiles.Add(zfsFileInfo);
                    }
                }

                if (_files.Count == numFilesTotal)
                {
                    break;
                }
                br.Position = nextDirOffset;
            }

            // Parse all .pix-files
            //var pakContents = new Dictionary<string, ZFSFileInfo>();
            foreach (ZFSFileInfo pixFile in pixFiles)
            {
                using (FastBinaryReader sr = GetDataStream(pixFile))
                {
                    string l        = sr.ReadLine();
                    int    numFiles = int.Parse(l);
                    for (int i = 0; i < numFiles; i++)
                    {
                        string   line     = sr.ReadLine();
                        string[] splitted = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        string   filename = splitted[0].ToLower();
                        uint     offset   = uint.Parse(splitted[1]);
                        uint     length   = uint.Parse(splitted[2]);

                        if (_files.ContainsKey(filename))
                        {
                            continue;
                        }
                        _files.Add(filename, new ZFSFileInfo
                        {
                            Filename = filename,
                            Offset   = offset,
                            Length   = length,
                            ContainingPakFilename = pixFile.Filename.Replace(".pix", ".pak")
                        });
                    }
                }
            }
        }
Exemple #4
0
        private FastBinaryReader GetDataStream(ZFSFileInfo fileInfo)
        {
            ZFSFileInfo originalFile = null;

            if (fileInfo.ContainingPakFilename != null)
            {
                originalFile = fileInfo;
                fileInfo     = _files[fileInfo.ContainingPakFilename];
            }

            if (fileInfo.Compression == 0)
            {
                FastBinaryReader br = new FastBinaryReader(_zfsMemory)
                {
                    Position = fileInfo.Offset,
                    Length   = (int)(fileInfo.Offset + fileInfo.Length)
                };

                if (originalFile != null)
                {
                    br.Position += originalFile.Offset;
                    br.Length    = (int)(br.Position + originalFile.Length);
                }

                return(br);
            }

            CompressionAlgorithm compressionAlgorithm;

            if (fileInfo.Compression == 2)
            {
                compressionAlgorithm = CompressionAlgorithm.LZO1X;
            }
            else if (fileInfo.Compression == 4)
            {
                compressionAlgorithm = CompressionAlgorithm.LZO1Y;
            }
            else
            {
                throw new Exception("Unknown compression " + fileInfo.Compression);
            }

            byte[] fileData = new byte[fileInfo.Length];
            Buffer.BlockCopy(_zfsMemory, (int)fileInfo.Offset, fileData, 0, fileData.Length);

            byte[] decompressedData = new byte[fileInfo.DecompressedLength];
            uint   length           = LZO.Decompress(fileData, decompressedData, fileInfo.DecompressedLength, compressionAlgorithm);

            if (length != fileInfo.DecompressedLength)
            {
                throw new Exception("Decompressed length does not match expected decompressed length");
            }

            FastBinaryReader reader = new FastBinaryReader(decompressedData)
            {
                Position = 0,
                Length   = decompressedData.Length
            };

            if (originalFile != null)
            {
                reader.Position = originalFile.Offset;
                reader.Length   = (int)(originalFile.Offset + originalFile.Length);
            }

            return(reader);
        }
Exemple #5
0
 public FastBinaryReader(FastBinaryReader parent)
 {
     _data   = parent.Data;
     _offset = parent._offset;
     Length  = parent.Length;
 }