public override Stream OpenEntry(ArcFile arc, Entry entry) { var xp3_entry = entry as Xp3Entry; if (null == xp3_entry) { return(arc.File.CreateStream(entry.Offset, entry.Size)); } Stream input; if (1 == xp3_entry.Segments.Count && !xp3_entry.IsEncrypted) { var segment = xp3_entry.Segments.First(); if (segment.IsCompressed) { input = new ZLibStream(arc.File.CreateStream(segment.Offset, segment.PackedSize), CompressionMode.Decompress); } else { input = arc.File.CreateStream(segment.Offset, segment.Size); } } else { input = new Xp3Stream(arc.File, xp3_entry); } return(xp3_entry.Cipher.EntryReadFilter(xp3_entry, input)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var xp3_entry = entry as Xp3Entry; if (null == xp3_entry) { return(arc.File.CreateStream(entry.Offset, entry.Size)); } Stream input; if (1 == xp3_entry.Segments.Count && !xp3_entry.IsEncrypted) { var segment = xp3_entry.Segments.First(); if (segment.IsCompressed) { input = new ZLibStream(arc.File.CreateStream(segment.Offset, segment.PackedSize), CompressionMode.Decompress); } else { input = arc.File.CreateStream(segment.Offset, segment.Size); } } else { input = new Xp3Stream(arc.File, xp3_entry); } if (xp3_entry.UnpackedSize <= 5 || "audio" == entry.Type) { return(input); } var header = new byte[5]; input.Read(header, 0, 5); if (0x184D2204 == header.ToInt32(0)) // LZ4 magic { // assume no scripts are compressed using LZ4, return decompressed stream right away return(DecompressLz4(xp3_entry, header, input)); } if (0xFE == header[0] && 0xFE == header[1] && header[2] < 3 && 0xFF == header[3] && 0xFE == header[4]) { return(DecryptScript(header[2], input, xp3_entry.UnpackedSize)); } if (!input.CanSeek) { return(new PrefixStream(header, input)); } input.Position = 0; return(input); }