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); }
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); }
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); }
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(); } } } }
public override bool Equals(object obj) { PakEntry comparing = obj as PakEntry; if (comparing == null) { return(false); } return(Equals(comparing)); }
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]); } } }
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]); } } }