/// <summary>
        /// Decrypts the packet data
        /// </summary>
        public void Decrypt(Span <byte> data)
        {
            if (!RecvCipher.Handshaken)
            {
                var pr = new BinaryReader(new MemoryStream(MapleCipher.Handshake(data).ToArray(), false),
                                          Encoding.ASCII);
                var version          = pr.ReadInt16();
                var subVersionLength = pr.ReadInt16();
                var subVersion       = new string(pr.ReadChars(subVersionLength));
                var siv        = pr.ReadUInt32();
                var riv        = pr.ReadUInt32();
                var serverType = pr.ReadByte();
                SendCipher.SetIv(siv);
                RecvCipher.SetIv(riv);
                HandshakeFinished?.Invoke(siv, riv, version, subVersion, serverType);
            }
            else
            {
                if (!RecvCipher.CheckHeader(data, !ToClient))
                {
                    throw new InvalidOperationException($"Packet header mismatch Size:{data.Length}");
                }

                var decrypted = RecvCipher.Decrypt(data);

                if (decrypted.Length == 0)
                {
                    return;
                }

                PacketFinished?.Invoke(decrypted.ToArray());
            }
        }
Exemple #2
0
        /// <summary>
        /// Add binary data to the buffer
        /// </summary>
        /// <param name="data">data buffer to add</param>
        /// <param name="offset">data offset</param>
        /// <param name="length">data length</param>
        public void AddData(byte[] data, int offset, int length)
        {
            if (IsWaiting)
            {
                if (length < HeaderSize) // Packet error, not enough header byte
                {
                    return;
                }

                PacketReader pr           = new PacketReader(data);
                int          packetLength = pr.ReadInt();         // Get packet length
                DataBuffer = new byte[packetLength + HeaderSize]; // Create new buffer with length = packetLength + HeaderSize
                Buffer.BlockCopy(data, 0, DataBuffer, 0, length); // Copy data to general buffer
                if (length < packetLength + HeaderSize)           // If packet length including header size is smaller than actual size, wait for the remaining
                {
                    WaitForData = packetLength + HeaderSize - length;
                    IsWaiting   = false;
                }
                else // Finish processing packet
                {
                    PacketFinished?.Invoke(DataBuffer); // Invoke Finish handler
                }
            }
            else // Remaining received
            {
                Buffer.BlockCopy(data, 0, DataBuffer, DataBuffer.Length - WaitForData, length); // Add data in this buffer to general buffer
                WaitForData -= length; // Decrease data amount to be waited
                if (WaitForData <= 0)  // Received all data
                {
                    if (PacketFinished != null)
                    {
                        PacketFinished(DataBuffer);
                    }
                    IsWaiting = true; // Reset processor
                }
            }
        }