private PakEntryMetadata ReadEntryMetadata(BinaryReader reader) { var metadata = new PakEntryMetadata { Offset = reader.ReadInt64(), Size = reader.ReadInt64(), UncompressedSize = reader.ReadInt64(), CompressionMethod = (PakCompressionMethod)reader.ReadInt32(), Hash = reader.ReadBytes(20) }; if (Version >= PakVersion.CompressionEncryption) { if (metadata.CompressionMethod != PakCompressionMethod.None) { // TODO: Compression blocks throw new NotImplementedException(); } metadata.Flags = (PakEntryFlags)reader.ReadByte(); metadata.CompressionBlockSize = reader.ReadInt32(); } return(metadata); }
/// <summary> /// Gets a <see cref="Stream"/> that contains the decrypted data for an entry. /// </summary> /// <param name="metadata">The metadata for the entry.</param> /// <param name="encryptionKey">The encryption key used to decrypt the data.</param> /// <returns></returns> public Task <Stream> GetEntryStreamAsync(PakEntryMetadata metadata, string encryptionKey) { return(Task.Run(() => { var stream = GetEntryStream(metadata); DecryptEntryStream(stream, metadata.Offset, encryptionKey); return stream; })); }
private void SwapEntry(PakEntryMetadata metadata, Stream newFileStream) { newFileStream.Seek(0, SeekOrigin.Begin); using (var writer = new BinaryWriter(_stream, Encoding.UTF8, true)) using (var reader = new BinaryReader(_stream, Encoding.UTF8, true)) { metadata.Flags = PakEntryFlags.None; // overwrite metadata _stream.Seek(metadata.Offset, SeekOrigin.Begin); WriteEntryMetadata(writer, metadata); // overwrite file block newFileStream.CopyTo(_stream); } }
private Stream GetEntryStream(PakEntryMetadata metadata) { var entryStream = new MemoryStream(); using (var reader = new BinaryReader(_stream, Encoding.UTF8, true)) using (var writer = new BinaryWriter(entryStream, Encoding.UTF8, true)) { _stream.Seek(metadata.Offset, SeekOrigin.Begin); ReadEntryMetadata(reader); byte[] buffer = reader.ReadBytes((int)metadata.Size); writer.Write(buffer, 0, buffer.Length); } entryStream.Seek(0, SeekOrigin.Begin); return(entryStream); }
private void WriteEntryMetadata(BinaryWriter writer, PakEntryMetadata metadata) { writer.Write(metadata.Offset); writer.Write(metadata.Size); writer.Write(metadata.UncompressedSize); writer.Write((int)metadata.CompressionMethod); writer.Write(metadata.Hash); if (Version >= PakVersion.CompressionEncryption) { if (metadata.CompressionMethod != PakCompressionMethod.None) { // TODO: Compression blocks throw new NotImplementedException(); } writer.Write((byte)metadata.Flags); writer.Write(metadata.CompressionBlockSize); } }
private void ReadEntries() { _entryTable = new PakEntryTable(); using (var reader = new BinaryReader(_stream, Encoding.UTF8, true)) { _stream.Seek(_indexOffset, SeekOrigin.Begin); MountPoint = reader.ReadFString(); int fileCount = reader.ReadInt32(); for (int i = 0; i < fileCount; i++) { string fileName = reader.ReadFString(); long metadataOffset = _stream.Position; PakEntryMetadata metadata = ReadEntryMetadata(reader); metadata.MetadataOffset = metadataOffset; metadata.FileName = fileName; _entryTable.Add(metadata); } } }
private void ReadEntries(string encryptionKey) { if (!IsIndexEncrypted) { ReadEntries(); return; } _entryTable = new PakEntryTable(); byte[] indexBlock = DecryptIndexBlock(encryptionKey); using (var reader = new BinaryReader(new MemoryStream(indexBlock))) { try { MountPoint = reader.ReadFString(); int fileCount = reader.ReadInt32(); for (int i = 0; i < fileCount; i++) { string fileName = reader.ReadFString(); long metadataOffset = reader.BaseStream.Position; PakEntryMetadata metadata = ReadEntryMetadata(reader); metadata.MetadataOffset = metadataOffset + _indexOffset; metadata.FileName = fileName; _entryTable.Add(metadata); } } catch (ArgumentOutOfRangeException) // reader.ReadFString will throw this if MountPoint cannot be read { _entryTable = null; throw new IncorrectEncryptionKeyException(); } } }
/// <summary> /// Swaps the file data for the given entry with the new data. /// </summary> /// <param name="metadata"></param> /// <param name="newFileStream"></param> /// <returns></returns> public Task SwapEntryAsync(PakEntryMetadata metadata, Stream newFileStream) { return(Task.Run(() => SwapEntry(metadata, newFileStream))); }
/// <summary> /// Gets a <see cref="Stream"/> that contains the data for an entry. /// </summary> /// <param name="metadata">The metadata for the entry.</param> /// <returns></returns> public Task <Stream> GetEntryStreamAsync(PakEntryMetadata metadata) { return(Task.Run(() => GetEntryStream(metadata))); }