public static bool Invoke(StsPacket reader, StsSession session)
        {
            var message = ((StsHeader)reader.Header).Message;

            Console.WriteLine($"Received Auth packet: {message} (0x{message:X}), Length: {reader.Data.Length}");

            HandleAuthPacket packet;

            if (AuthMessageHandlers.TryGetValue(message, out packet))
            {
                packet.Invoke(reader, session);

                return true;
            }

            return false;
        }
        public void Send(StsPacket packet)
        {
            try
            {
                packet.Finish();

                PacketLog.Write<StsPacket>(packet.Data, packet.Data.Length, client.RemoteEndPoint as IPEndPoint);

                if (ServerCrypt != null)
                    ServerCrypt.ProcessBuffer(packet.Data);

                var socketEventargs = new SocketAsyncEventArgs();

                socketEventargs.SetBuffer(packet.Data, 0, packet.Data.Length);

                socketEventargs.Completed += SendCompleted;
                socketEventargs.UserToken = packet;
                socketEventargs.RemoteEndPoint = client.RemoteEndPoint;
                socketEventargs.SocketFlags = SocketFlags.None;

                client.SendAsync(socketEventargs);
            }
            catch
            {
                Dispose();
            }
        }
        public void ProcessPacket(StsPacket packet)
        {
            PacketLog.Write<StsPacket>(packet.Data, packet.Data.Length, client.RemoteEndPoint as IPEndPoint);

            StsPacketManager.Invoke(packet, this);
        }
        public void Process(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                var socket = e.UserToken as Socket;
                var receivedBytes = e.BytesTransferred;

                if (receivedBytes > 0)
                {
                    byte[] packetData = null;

                    if (packetQueue.Count > 0)
                    {
                        var lastPacket = packetQueue.Pop();

                        if (receivedBytes != lastPacket.Header.DataLength)
                        {
                            Console.WriteLine("Wrong data received.");

                            Dispose();

                            return;
                        }

                        packetData = new byte[receivedBytes];

                        Buffer.BlockCopy(dataBuffer, 0, packetData, 0, receivedBytes);

                        lastPacket.Data.Combine(packetData);
                        lastPacket.ReadData(packetData);

                        ProcessPacket(lastPacket);
                    }

                    if (ClientCrypt != null)
                    {
                        if (receivedBytes <= 100)
                            State = 0;

                        if (State == 0)
                            ClientCrypt.ProcessBuffer(dataBuffer, receivedBytes);
                    }

                    packetData = new byte[receivedBytes];

                    Buffer.BlockCopy(dataBuffer, 0, packetData, 0, receivedBytes);

                    // POST
                    if (BitConverter.ToUInt32(packetData, 0) == 0x54534F50)
                    {
                        var packet = new StsPacket(packetData);
                        var packetInfo = GetMessageType(packetData);

                        packet.ReadHeader(packetInfo);

                        if ((receivedBytes - packet.Header.Length) != packet.Header.DataLength)
                            packetQueue.Push(packet);
                        else
                        {
                            receivedBytes -= packet.Header.Length;

                            packetData = new byte[receivedBytes];

                            Buffer.BlockCopy(packet.Data, packet.Header.Length, packetData, 0, receivedBytes);

                            if (packetData.Length > 0)
                                packet.ReadData(packetData);

                            ProcessPacket(packet);
                        }
                    }

                    client.ReceiveAsync(e);
                }
                else
                    Dispose();
            }
            catch
            {
                Dispose();
            }
        }
        public void OnConnection(object sender, SocketAsyncEventArgs e)
        {
            PacketLog.Write<StsPacket>(dataBuffer, e.BytesTransferred, client.RemoteEndPoint as IPEndPoint);

            if (e.BytesTransferred < 256 || e.BytesTransferred > 400)
            {
                Console.WriteLine("Wrong initialization packet.");

                Dispose();
            }
            else
            {
                // POST
                if (BitConverter.ToUInt32(dataBuffer, 0) == 0x54534F50)
                {
                    var packetData = new byte[e.BytesTransferred];

                    Buffer.BlockCopy(dataBuffer, 0, packetData, 0, e.BytesTransferred);

                    var packetInfo = GetMessageType(packetData);

                    if (packetInfo.Item1 != "Sts")
                    {
                        Console.WriteLine("Wrong packet type for first packet.");

                        Dispose();

                        return;
                    }

                    var packet = new StsPacket(packetData);

                    packet.ReadHeader(packetInfo);

                    packetData = new byte[packet.Header.DataLength];

                    Buffer.BlockCopy(packet.Data, packet.Header.Length, packetData, 0, packet.Header.DataLength);

                    packet.Data.Combine(packetData);

                    packet.ReadData(packetData);

                    StsPacketManager.Invoke(packet, this);

                    e.Completed -= OnConnection;
                    e.Completed += Process;

                    client.ReceiveAsync(e);
                }
            }
        }