/// <summary>
        /// Create an encoder with the target initial buffer size.
        /// </summary>
        /// <param name="compress">True to compress collated data.</param>
        /// <param name="initialBufferSize">The initial buffer size (bytes).</param>
        public CollatedPacketEncoder(bool compress, int initialBufferSize = 64 * 1024)
        {
            CollatedBytes    = 0;
            _collationStream = _dataStream = new CompressionBuffer(initialBufferSize);
            _packet          = new PacketBuffer();

            // Prime the output stream, writing the initial header.
            PacketHeader header = PacketHeader.Create((ushort)RoutingID.CollatedPacket, 0);

            CollatedPacketMessage msg = new CollatedPacketMessage();

            msg.Flags             = (ushort)((compress) ? CollatedPacketFlag.GZipCompressed : 0u);
            msg.Reserved          = 0;
            msg.UncompressedBytes = 0;

            NetworkWriter writer = new NetworkWriter(_dataStream);

            header.Write(writer);
            msg.Write(writer);

            _resetPosition = (int)_dataStream.Position;

            CompressionEnabled = compress;
            if (compress)
            {
                _collationStream = new GZipStream(_dataStream, CompressionMode.Compress, CompressionLevel.BestCompression);
            }
        }
Example #2
0
        /// <summary>
        /// Sets the packet to decode.
        /// </summary>
        /// <param name="packet"></param>
        /// <remarks>
        /// The <paramref name="packet"/> need not be a collated packet, in which case it will be
        /// immediately returned on calling <see cref="Next()"/>, followed by <code>null</code>
        /// </remarks>
        public bool SetPacket(PacketBuffer packet)
        {
            _packet       = packet;
            _packetStream = null;
            _streamReader = null;

            // Check for a collated packet.
            if (_packet != null && _packet.Header.RoutingID == (ushort)RoutingID.CollatedPacket)
            {
                _packetStream = _packet.CreateReadStream(true);
                CollatedPacketMessage msg = new CollatedPacketMessage();
                _streamReader = new NetworkReader(_packetStream);
                if (!msg.Read(_streamReader))
                {
                    return(false);
                }

                _targetBytes  = msg.UncompressedBytes;
                _decodedBytes = 0;

                if ((msg.Flags & (ushort)CollatedPacketFlag.GZipCompressed) != 0)
                {
                    _packetStream = new GZipStream(_packetStream, CompressionMode.Decompress);
                    if (_packetStream != null)
                    {
                        _streamReader = new NetworkReader(_packetStream);
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Finalise the collated packet before sending.
        /// </summary>
        /// <returns>True on successful finalisation, false if already finalised</returns>
        public bool FinaliseEncoding()
        {
            if (_finalised)
            {
                return(false);
            }

            bool compressionSuccess = false;

            if (CompressionEnabled)
            {
                // Compress the raw buffer into the compression buffer then validate it's smaller.
                _finalisedBuffer.Position = 0;

                // First write the standard header for this buffer.
                // Prime the output stream, writing the initial header.
                PacketHeader header = PacketHeader.Create((ushort)RoutingID.CollatedPacket, 0);

                CollatedPacketMessage msg = new CollatedPacketMessage();
                msg.Flags             = (ushort)CollatedPacketFlag.GZipCompressed;
                msg.Reserved          = 0;
                msg.UncompressedBytes = 0;

                NetworkWriter writer = new NetworkWriter(_finalisedBuffer);
                header.Write(writer);
                msg.Write(writer);

                int overhead = (int)_finalisedBuffer.Position;

                // Now compress the collated packets.
                GZipStream compressionStream = new GZipStream(_finalisedBuffer, CompressionLevel.Fastest);
                compressionStream.Write(_collationBuffer.GetBuffer(), 0, (int)_collationBuffer.Position);
                compressionStream.Close();
                if (_finalisedBuffer.Position < _collationBuffer.Position + overhead)
                {
                    // The compressed data are smaller, so we accept it.
                    SetPayloadSize((ushort)(Count - PacketHeader.Size));
                    // Update the payload and uncompressed sizes.
                    SetUncompressedBytesSize((ushort)CollatedBytes);
                    compressionSuccess = true;
                }
            }

            if (!compressionSuccess)
            {
                // No compression or compression failed to reduce the data size. Write header then copy wrap packets.
                PacketHeader header = PacketHeader.Create((ushort)RoutingID.CollatedPacket, 0);

                _finalisedBuffer.Position = 0;

                CollatedPacketMessage msg = new CollatedPacketMessage();
                msg.Flags             = 0;
                msg.Reserved          = 0;
                msg.UncompressedBytes = 0;

                NetworkWriter writer = new NetworkWriter(_finalisedBuffer);
                header.Write(writer);
                msg.Write(writer);

                _finalisedBuffer.Write(_collationBuffer.GetBuffer(), 0, (int)_collationBuffer.Position);
                // The compressed data are smaller, so we accept it.
                SetPayloadSize((ushort)(Count - PacketHeader.Size));
                // Update the payload and uncompressed sizes.
                SetUncompressedBytesSize((ushort)CollatedBytes);
            }

            // Calculate the CRC
            ushort crc = Crc16.Crc.Calculate(_finalisedBuffer.GetBuffer(), (uint)_finalisedBuffer.Position);

            new NetworkWriter(_finalisedBuffer).Write(crc);
            _finalised = true;
            return(true);
        }
Example #4
0
        public void Run()
        {
            int                infoSearchPacketLimit = 10; // Don't look for info packets beyond this packet count. Should be first up.
            PacketBuffer       packetBuffer          = new PacketBuffer(4 * 1024);
            PacketStreamReader packetStream          = new PacketStreamReader(new FileStream(TargetFile, FileMode.Open, FileAccess.Read));

            Console.CancelKeyPress += new ConsoleCancelEventHandler(ControlCHandler);
            Console.WriteLine(string.Format("Reading {0}", TargetFile));

            PacketBuffer packet          = null;
            long         bytesRead       = 0;
            bool         foundFrameCount = false;
            bool         foundServerInfo = false;

            while (!Quit && !packetStream.EndOfStream)
            {
                Log.Flush();
                packet = packetStream.NextPacket(ref bytesRead);

                if (packet == null)
                {
                    if (!packetStream.EndOfStream)
                    {
                        Console.Error.WriteLine(string.Format("Null packet at {0}:{1}", _actualFrameCount, _packetCount));
                    }
                    continue;
                }

                if (packet.Status == PacketBufferStatus.Complete)
                {
                    ++_packetCount;
                    //Console.WriteLine("Msg: {0} {1}", completedPacket.Header.RoutingID, completedPacket.Header.MessageID);
                    switch (packet.Header.RoutingID)
                    {
                    case (ushort)RoutingID.Control:
                        switch (packet.Header.MessageID)
                        {
                        case (ushort)ControlMessageID.EndFrame:
                            ++_actualFrameCount;
                            break;

                        case (ushort)ControlMessageID.FrameCount:
                            if (foundFrameCount)
                            {
                                Console.Error.WriteLine(string.Format("Found additional FrameCount message at frame {0}:{1}",
                                                                      _actualFrameCount, _packetCount));
                            }
                            else
                            {
                                _frameCountPacketNumber = _packetCount;
                            }
                            HandleFrameCount(packet);
                            foundFrameCount = true;
                            break;
                        }
                        break;

                    case (ushort)RoutingID.ServerInfo:
                        if (foundServerInfo)
                        {
                            Console.Error.WriteLine(string.Format("Found additional ServerInfo message at frame {0}:{1}",
                                                                  _actualFrameCount, _packetCount));
                        }
                        else
                        {
                            _serverInfoPacket = _packetCount;
                        }
                        HandleServerInfo(packet);
                        foundServerInfo = true;
                        break;
                    }
                }
                else
                {
                    Console.Error.WriteLine(string.Format("Invalid packet static at {0}:{1}", _actualFrameCount, _packetCount));
                    Console.Error.WriteLine(string.Format("Invalid packet status is {0} ({1})", packet.Status.ToString(), (int)packet.Status));;

                    if (packet.Header.RoutingID == (ushort)RoutingID.CollatedPacket && packet.Header.PayloadSize > 0)
                    {
                        NetworkReader         packetReader = new NetworkReader(packet.CreateReadStream(true));
                        CollatedPacketMessage msg          = new CollatedPacketMessage();
                        if (msg.Read(packetReader))
                        {
                            Console.WriteLine(string.Format("Failed collated packet message:"));
                            Console.WriteLine(string.Format("  Flags: {0}", msg.Flags));
                            Console.WriteLine(string.Format("  Reserved: {0}", msg.Reserved));
                            Console.WriteLine(string.Format("  UncompressedBytes: {0}", msg.UncompressedBytes));
                            Console.WriteLine(string.Format("  PacketSize: {0}", packet.Header.PacketSize));
                        }
                    }
                }
            }

            if (!Decode)
            {
                if (foundServerInfo && foundFrameCount)
                {
                    Quit = true;
                }
            }

            if (_packetCount >= infoSearchPacketLimit)
            {
                if (!foundServerInfo)
                {
                    Quit = true;
                    Console.Error.WriteLine(string.Format("Failed to locate ServerInfo packet within {0} packets.", infoSearchPacketLimit));
                }
                if (!foundFrameCount)
                {
                    Quit = true;
                    Console.Error.WriteLine(string.Format("Failed to locate FrameCount packet within {0} packets.", infoSearchPacketLimit));
                }
            }

            Console.WriteLine(string.Format("Processed {0} packets{1}\n", _packetCount, Decode ? "" : " (info only)"));
            if (Decode)
            {
                if (_reportedFrameCount != _actualFrameCount)
                {
                    Console.Error.WriteLine(string.Format("Frame count mismatch. Expected {0}, processed {1}", _reportedFrameCount, _actualFrameCount));
                }
            }
        }