Exemplo n.º 1
0
        //public Stream GetStream()
        //{
        //    MemoryStream mem = new MemoryStream();

        //    using (Stream raw = GetRawStream())
        //    using (IDecompressor decompressor = CompressorFactory.GetDecompressor(Compression))
        //        decompressor.Decompress(raw).CopyTo(mem);

        //    mem.Position = 0;

        //    return mem;
        //       // return decompressor.Decompress();
        //}

        public void CopyToMemory(Memory <byte> memory)
        {
            if (memory.Length < (int)UncompressedLength)
            {
                throw new ArgumentException("Memory buffer must be at least the uncompressed size of the chunk");
            }

            using var rawStream = GetRawStream();

            if (Compression == ArchiveChunkCompression.Zstandard)
            {
                using var zstdDecompressor = new ZstdDecompressor();

                using var buffer = MemoryPool <byte> .Shared.Rent((int) CompressedLength);

                var compressedMemory = buffer.Memory.Slice(0, (int)CompressedLength);

                rawStream.Read(compressedMemory.Span);

                zstdDecompressor.DecompressData(compressedMemory.Span, memory.Span, out _);
            }
            else
            {
                rawStream.Read(memory.Span);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Handler for any pipe requests.
        /// </summary>
        /// <param name="request">The command to execute.</param>
        /// <param name="argument">Any additional arguments.</param>
        /// <param name="handler">The streamhandler to use.</param>
        private static void Server_OnRequest(string request, string argument, StreamHandler handler)
        {
            if (request == "ready")
            {
                //Notify the AA2 instance that we are ready
                if (IsLoaded)
                {
                    Console.WriteLine("Connected to pipe");
                }

                handler.WriteString(IsLoaded.ToString());
            }
            else if (request == "matchfiles")
            {
                //Send a list of all loaded .pp files

                if (LogFiles)
                {
                    Console.WriteLine("!!LOADED FILELIST!!");
                }

                var loadedPP = Cache.LoadedFileReferences.Keys.Select(x => x.Archive).Distinct();

                foreach (string pp in loadedPP)
                {
                    handler.WriteString(pp + ".pp");

                    if (LogFiles)
                    {
                        Console.WriteLine(pp);
                    }
                }

                handler.WriteString("");
            }
            else if (request == "load")
            {
                //Transfer the file
                lock (Cache.LoadLock)
                {
                    string[]  splitNames = argument.Replace("data/", "").Split('/');
                    FileEntry entry      = new FileEntry(splitNames[0], splitNames[1]);

                    Logger.LogFile(argument);

                    //Ensure we have the file
                    if (!Cache.ReferenceMd5Sums.ContainsKey(entry))
                    {
                        //We don't have the file
                        handler.WriteString("NotAvailable");

                        if (LogFiles)
                        {
                            Console.WriteLine("!" + argument);
                        }

                        return;
                    }

                    if (LogFiles)
                    {
                        Console.WriteLine(argument);
                    }

                    //Write the data to the pipe

                    var fileMd5 = Cache.ReferenceMd5Sums[entry];

                    if (!Cache.LoadedFiles.TryGetValue(fileMd5, out var cachedFile))
                    {
                        //Console.WriteLine("Cache miss");

                        var chunk = Cache.LoadedFileReferences[entry];

                        chunk.Allocate();

                        // wait for the file to be available
                        while (true)
                        {
                            if (Cache.LoadedFiles.TryGetValue(fileMd5, out cachedFile) && cachedFile.Ready)
                            {
                                break;
                            }

                            Thread.Sleep(50);
                        }
                    }

                    while (!cachedFile.Ready)
                    {
                        Thread.Sleep(50);
                    }

                    using var compressedDataRef = cachedFile.GetMemory();
                    using var buffer            = MemoryPool <byte> .Shared.Rent((int) cachedFile.UncompressedSize * 2);

                    ZstdDecompressor.DecompressData(compressedDataRef.Memory.Span, buffer.Memory.Span, out int uncompressedSize);

                    //Console.WriteLine($"Expected: {Utility.GetBytesReadable(cachedFile.UncompressedSize)} Actual: {Utility.GetBytesReadable(uncompressedSize)}");

                    if (entry.File.EndsWith("wav"))
                    {
                        using (var inputStream = new ReadOnlyMemoryStream(buffer.Memory.Slice(0, (int)uncompressedSize)))
                            //using (var rentedSpan = MemoryPool<byte>.Shared.Rent(48_000_000))
                            using (var outputStream = new MemoryStream())
                            {
                                OpusEncoder.Decode(inputStream, outputStream, false);

                                outputStream.Position = 0;

                                //Console.WriteLine($"Decompressed wav size: {Utility.GetBytesReadable(outputStream.Length)}");

                                handler.WriteString(outputStream.Length.ToString());
                                outputStream.CopyTo(handler.BaseStream);
                            }
                    }
                    else
                    {
                        handler.WriteString(uncompressedSize.ToString());
                        handler.BaseStream.Write(buffer.Memory.Slice(0, (int)uncompressedSize).Span);
                    }
                }
            }
            else
            {
                //Unknown command
                //Ignore instead of throwing exception
                Console.WriteLine("Unknown request: " + request + " [:] " + argument);
            }
        }