コード例 #1
0
 public bool Equals(PakEntry entry)
 {
     if (entry == null)
     {
         return(false);
     }
     if (CompressedSize != entry.CompressedSize)
     {
         return(false);
     }
     if (UncompressedSize != entry.UncompressedSize)
     {
         return(false);
     }
     if (CompressionType != entry.CompressionType)
     {
         return(false);
     }
     if (!Hash.SequenceEqual(entry.Hash))
     {
         return(false);
     }
     if (EncryptionType != entry.EncryptionType)
     {
         return(false);
     }
     if (ChunkSize != entry.ChunkSize)
     {
         return(false);
     }
     return(true);
 }
コード例 #2
0
        public void Write(PakEntry entry, bool fileLevel)
        {
            if (!fileLevel)
            {
                Write(entry.Name);
            }

            if (fileLevel)
            {
                Write(0L);
            }
            else
            {
                Write(entry.Offset);
            }

            Write(entry.CompressedSize);
            Write(entry.UncompressedSize);
            Write(entry.CompressionType);
            Write(entry.Hash);

            if (entry.CompressionType != 0)
            {
                Write(entry.Chunks.Count);

                foreach (var chunk in entry.Chunks)
                {
                    Write(chunk.ChunkOffset);
                    Write(chunk.ChunkEnd);
                }
            }

            Write(entry.EncryptionType);
            Write(entry.ChunkSize);
        }
コード例 #3
0
        private PakEntry ReadPakEntry(string name)
        {
            PakEntry pakEntry = new PakEntry();

            pakEntry.Name             = name;
            pakEntry.Offset           = ReadInt64();
            pakEntry.CompressedSize   = ReadInt64();
            pakEntry.UncompressedSize = ReadInt64();
            pakEntry.CompressionType  = ReadInt32();
            pakEntry.Hash             = ReadBytes(20);

            if (pakEntry.CompressionType != 0)
            {
                var numberOfCompressionChunks = ReadInt32();

                for (var i = 0; i < numberOfCompressionChunks; i++)
                {
                    var chunk = new PakChunkDescriptor();

                    chunk.ChunkOffset = ReadInt64();
                    chunk.ChunkEnd    = ReadInt64();

                    pakEntry.Chunks.Add(chunk);
                }
            }

            pakEntry.EncryptionType = ReadByte();
            pakEntry.ChunkSize      = ReadInt32();

            return(pakEntry);
        }
コード例 #4
0
        public void ExtractFile(string directory, PakEntry pakEntry, PakBinaryReader reader)
        {
            var currentPakEntry = reader.ReadFileLevelPakEntry();

            if (!currentPakEntry.Equals(pakEntry))
            {
                return;
            }

            string compoundName = directory + @"\" + pakEntry.Name.Replace(@"/", @"\");

            if (!compoundName.Contains(@"\"))
            {
                return;
            }

            Directory.CreateDirectory(Path.GetDirectoryName(compoundName));

            using (var fileStream = File.Open(compoundName, FileMode.Create))
            {
                using (var writer = new BinaryWriter(fileStream))
                {
                    switch (pakEntry.CompressionType)
                    {
                    case 0:
                        writer.Write(reader.ReadBytes((int)currentPakEntry.UncompressedSize));
                        break;

                    case 1:
                        foreach (var chunk in pakEntry.Chunks)
                        {
                            var compressedData = reader.ReadBytes((int)(chunk.ChunkEnd - chunk.ChunkOffset));
                            var decompressed   = ZlibStream.UncompressBuffer(compressedData);
                            writer.Write(decompressed);
                        }
                        break;

                    case 4:
                    case 16400:
                        var remainingSizeToUncompress = pakEntry.UncompressedSize;
                        foreach (var chunk in pakEntry.Chunks)
                        {
                            var decompressedSize = remainingSizeToUncompress > pakEntry.ChunkSize
                                    ? pakEntry.ChunkSize
                                    : remainingSizeToUncompress;
                            var compressedData = reader.ReadBytes((int)(chunk.ChunkEnd - chunk.ChunkOffset));
                            var decompressed   = OodleHandler.Decompress(compressedData, decompressedSize);
                            writer.Write(decompressed);
                            remainingSizeToUncompress -= pakEntry.ChunkSize;
                        }
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }
            }
        }
コード例 #5
0
        public override bool Equals(object obj)
        {
            PakEntry comparing = obj as PakEntry;

            if (comparing == null)
            {
                return(false);
            }
            return(Equals(comparing));
        }
コード例 #6
0
        public void CreateDataEntry(PakBinaryWriter writer, PakEntry pakEntry, bool usePadding)
        {
            pakEntry.Offset = writer.BaseStream.Position;

            var bytes = File.ReadAllBytes(pakEntry.Import);

            pakEntry.Hash = HashBytes(bytes);
            writer.Write(pakEntry, true);
            writer.Write(bytes);

            if (usePadding && pakEntry.Padded)
            {
                var toWrite = 2048 - writer.BaseStream.Position % 2048;
                if (toWrite != 2048)
                {
                    writer.Write(new byte[toWrite]);
                }
            }
        }
コード例 #7
0
        public void SaveDataEntry(PakBinaryReader reader, PakBinaryWriter writer, PakEntry pakEntry, bool usePadding)
        {
            if (pakEntry.Offset == -1)
            {
                return;
            }

            long originalOffset = pakEntry.Offset;

            pakEntry.Offset = writer.BaseStream.Position;

            if (Archive.Version < 7)
            {
                var offsetDifference = pakEntry.Offset - originalOffset;
                foreach (var chunk in pakEntry.Chunks)
                {
                    chunk.ChunkEnd    += offsetDifference;
                    chunk.ChunkOffset += offsetDifference;
                }
            }

            writer.Write(pakEntry, true);

            if (pakEntry.Import != null)
            {
                using (var importFileStream = File.Open(pakEntry.Import, FileMode.Open))
                {
                    var importReader = new PakBinaryReader(importFileStream);
                    writer.Write(importReader.ReadBytes((int)pakEntry.UncompressedSize));
                }
            }
            else
            {
                if (reader.BaseStream.Position != originalOffset)
                {
                    reader.BaseStream.Seek(originalOffset, SeekOrigin.Begin);
                }

                var importFilePakEntry = reader.ReadFileLevelPakEntry();
                if (!importFilePakEntry.Equals(pakEntry))
                {
                    return;
                }

                switch (pakEntry.CompressionType)
                {
                case 0:
                    writer.Write(reader.ReadBytes((int)pakEntry.UncompressedSize));
                    break;

                case 1:
                case 4:
                case 16400:
                    foreach (var chunk in pakEntry.Chunks)
                    {
                        var compressedData = reader.ReadBytes((int)(chunk.ChunkEnd - chunk.ChunkOffset));
                        writer.Write(compressedData);
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            if (usePadding && pakEntry.Padded)
            {
                var toWrite = 2048 - writer.BaseStream.Position % 2048;
                if (toWrite != 2048)
                {
                    writer.Write(new byte[toWrite]);
                }
            }
        }