Пример #1
0
        public async ValueTask <IMemoryOwner <byte> > ReadEntryAsync(PakEntry entry, CancellationToken cancellationToken = default)
        {
            var taskData = entry.ReadAsync(SourceStream, cancellationToken);
            var buf      = taskData.IsCompletedSuccessfully ? taskData.Result : await taskData.ConfigureAwait(false);

            if (entry.IsEncrypted)
            {
                if (_aesProvider is null)
                {
                    throw new PakEncryptedException("Pak file contains encrypted entries. AES encryption key is necessary for reading this asset.");
                }

                _aesProvider.Decrypt(buf.Memory);
            }
            if (entry.IsCompressed)
            {
                var decompressTask = UnrealCompression.DecompressAsync(buf.Memory, entry, cancellationToken);
                var result         = decompressTask.IsCompletedSuccessfully ? decompressTask.Result : await decompressTask.ConfigureAwait(false);

                buf.Dispose();
                return(result);
            }
            else
            {
                return(buf);
            }
        }
Пример #2
0
        public static IMemoryOwner <byte> Decompress(Memory <byte> compressed, PakEntry entry)
        {
            var decompressed = PakMemoryPool.Shared.Rent((int)entry.TotalUncompressedSize);

            if (MemoryMarshal.TryGetArray <byte>(compressed, out var src) && MemoryMarshal.TryGetArray <byte>(decompressed.Memory, out var dst))
            {
                Decompress(src.Array !, src.Offset, src.Count, dst.Array !, dst.Offset, dst.Count, entry);
            }
            else
            {
                decompressed.Dispose();
                throw new NotImplementedException();
                //Decompress(data.Memory.ToArray(), 0, data.Memory.Length, buffer, compressionBlocks);
            }
            return(decompressed);
        }
Пример #3
0
        public IMemoryOwner <byte> ReadEntry(PakEntry entry)
        {
            var buf = entry.Read(SourceStream);

            if (entry.IsEncrypted)
            {
                if (_aesProvider is null)
                {
                    throw new PakEncryptedException("Pak file contains encrypted entries. AES encryption key is necessary for reading this asset.");
                }

                _aesProvider.Decrypt(buf.Memory);
            }
            if (entry.IsCompressed)
            {
                var decompressed = UnrealCompression.Decompress(buf.Memory, entry);
                buf.Dispose();
                return(decompressed);
            }
            else
            {
                return(buf);
            }
        }
Пример #4
0
        public static async ValueTask DecompressAsync(byte[] source, int srcOffset, int srcCount, byte[] destination, int dstOffset, int dstCount, PakEntry entry, CancellationToken cancellationToken = default)
        {
            using var mem = new MemoryStream(source, srcOffset, srcCount);
            var progress = 0;

            foreach (var block in entry.TotalBlocks)
            {
                mem.Seek(block.Start, SeekOrigin.Begin);
                using Stream stream = entry.CompressionMethod switch
                      {
                          1 => new ZlibStream(mem, CompressionMode.Decompress, true),
                          2 => new GZipStream(mem, CompressionMode.Decompress, true),
                          _ => throw new NotImplementedException($"CompressionMethod '{entry.CompressionMethod}' not implemented")
                      };
                var read = 0;
                do
                {
                    read = await stream.ReadAsync(destination, dstOffset + progress, dstCount - progress, cancellationToken).ConfigureAwait(false);

                    progress += read;
                } while (read > 0);
            }
        }
    }
Пример #5
0
        public static async ValueTask <IMemoryOwner <byte> > DecompressAsync(Memory <byte> compressed, PakEntry entry, CancellationToken cancellationToken = default)
        {
            var decompressed = PakMemoryPool.Shared.Rent((int)entry.TotalUncompressedSize);

            if (MemoryMarshal.TryGetArray <byte>(compressed, out var src) && MemoryMarshal.TryGetArray <byte>(decompressed.Memory, out var dst))
            {
                var task = DecompressAsync(src.Array !, src.Offset, src.Count, dst.Array !, dst.Offset, dst.Count, entry, cancellationToken);
                if (!task.IsCompletedSuccessfully)
                {
                    await task.ConfigureAwait(false);
                }
            }
            else
            {
                decompressed.Dispose();
                throw new NotImplementedException();
            }
            return(decompressed);
        }
Пример #6
0
        public static void Decompress(byte[] source, int srcOffset, int srcCount, byte[] destination, int dstOffset, int dstCount, PakEntry entry)
        {
            using var mem = new MemoryStream(source, srcOffset, srcCount);
            var progress = 0;

            foreach (var block in entry.TotalBlocks)
            {
                mem.Seek(block.Start, SeekOrigin.Begin);
                using Stream stream = entry.CompressionMethod switch
                      {
                          1 => new ZlibStream(mem, CompressionMode.Decompress, true),
                          2 => new GZipStream(mem, CompressionMode.Decompress, true),
                          _ => throw new NotImplementedException($"CompressionMethod '{entry.CompressionMethod}' not implemented")
                      };
                var read = 0;
                do
                {
                    read      = stream.Read(destination, dstOffset + progress, dstCount - progress);
                    progress += read;
                } while (read > 0);
            }
        }