A base cancelable event data class with information about a proxy connection
Inheritance: CancelEventArgs
 public override void OnConnectionLost(UserEventArgs args)
 {
     foreach (PluginBase item in _triggerPlugins)
     {
         try
         {
             item.OnConnectionLost(args);
         }
         catch (Exception ex)
         {
             _logger.Warn("Could not pass event 'OnConnectionLost' to " + item.Name, ex);
         }
     }
 }
 public override void OnConnectionLost(UserEventArgs args)
 {
     //clean up
     TryRemoveConnection(args.Connection);
 }
        internal virtual async void HandleClient()
        {
            string kickMessage = "Failed to login";
            bool success = true;
            try
            {
                ClientRemoteInterface clientRemoteInterface =
                    ClientRemoteInterface.Create(new NetworkStream(_networkSocket), 60);
                _clientEndPoint = new ProxyEndPoint(clientRemoteInterface, clientRemoteInterface.EndPoint.Version);
                _clientEndPoint.RemoteEndPoint = (IPEndPoint) _networkSocket.RemoteEndPoint;

                Packet packet = await clientRemoteInterface.ReadPacketAsync ();

                var listPing = packet as PlayerListPing;
                var handshakeRequest = packet as HandshakeRequest;


                if (listPing != null) // send motd
                {
                    _isMotDRequest = true;

                    if (listPing.MagicByte == 1)
                    {
                        //Plugin Message begins @ 1.6

                        AdditionalServerListInformation additionalInformation = null;

                        try
                        {
                            clientRemoteInterface.EndPoint.Stream.ReadTimeout = 1;
                        }
                        catch (InvalidOperationException)
                        {
                        }

                        try
                        {
                            additionalInformation =
                                await clientRemoteInterface.ReadAdditionalServerListInformationAsync();
                        }
                        catch (TimeoutException timeOut)
                        {
                        }

                        additionalInformation = additionalInformation ?? new AdditionalServerListInformation
                        {
                            Host = _server.LocalEndPoint.Address.ToString(),
                            Port = _server.LocalEndPoint.Port,
                            ProtocolVersion = (byte) _server.PublicMinecraftVersion
                        };
                        additionalInformation.ProtocolVersion = ProtocolInformation.MaxSupportedClientVersion <
                                                                additionalInformation.ProtocolVersion
                            ? (byte) ProtocolInformation.MaxSupportedClientVersion
                            : additionalInformation.ProtocolVersion;
                        additionalInformation.ProtocolVersion = ProtocolInformation.MinSupportedClientVersion >
                                                                additionalInformation.ProtocolVersion
                            ? (byte) ProtocolInformation.MinSupportedClientVersion
                            : additionalInformation.ProtocolVersion;

                        string response = ProtocolHelper.BuildMotDString(additionalInformation.ProtocolVersion,
                            _server.ServerVersionName, _server.MotD,
                            _server.ConnectedUsers, _server.MaxUsers);
                        await KickUserAsync(response);
                    }
                    else
                    {
                        string response = ProtocolHelper.BuildMotDString(_server.MotD, _server.ConnectedUsers,
                            _server.MaxUsers);
                        await KickUserAsync(response);
                    }
                    return;
                }

                if (handshakeRequest != null)
                {
                    Username = handshakeRequest.UserName;
                    Host = handshakeRequest.Host;
                    ClientEndPoint.ProtocolVersion = handshakeRequest.ProtocolVersion;

                    if (handshakeRequest.ProtocolVersion < ProtocolInformation.MinSupportedClientVersion)
                    {
                        await KickUserAsync("Outdated Client");
                        return;
                    }
                    else if (handshakeRequest.ProtocolVersion > ProtocolInformation.MaxSupportedClientVersion)
                    {
                        await KickUserAsync("Outdated Server");
                        return;
                    }

                    var args = new UserEventArgs(this);

                    _server.PluginManager.TriggerPlugin.OnPlayerConnected(args);

                    if (args.Canceled)
                    {
                        await ClientEndPoint.SendPacketAsync(new DisconnectPacket {Reason = args.CancelMessage});
                        _networkSocket.Close ();
                        _server.RemoveConnection(this);
                        return;
                    }

                    bool onlineMode = _server.OnlineModeEnabled(this);
                    string serverId = onlineMode ? Session.GetSessionHash () : "-";

                    var randomBuffer = new byte[4];
                    _random.NextBytes(randomBuffer);
                    await ClientEndPoint.SendPacketAsync(new EncryptionKeyRequest
                                                             {
                                                                 ServerId = serverId,
                                                                 PublicKey =
                                                                     AsnKeyBuilder.PublicKeyToX509(_server.RSAKeyPair).
                                                                     GetBytes (),
                                                                 VerifyToken = randomBuffer
                                                             });
                    do
                    {
                        packet = await ClientEndPoint.ReceivePacketAsync ();
                    } while (packet is KeepAlive);

                    var encryptionKeyResponse = (EncryptionKeyResponse) packet;
                    byte[] verification = ProtocolSecurity.RsaDecrypt(
                        encryptionKeyResponse.VerifyToken.ToArray (), _server.RSACryptoServiceProvider, true);
                    byte[] sharedKey = ProtocolSecurity.RsaDecrypt(
                        encryptionKeyResponse.SharedKey.ToArray (), _server.RSACryptoServiceProvider, true);
                    if (verification.Length != randomBuffer.Length
                        || !verification.Zip(randomBuffer, (a, b) => a == b).All(a => a))
                    {
                        await KickUserAsync("Verify token failure");
                        _logger.Error("Failed to login a Client, Verify token failure");
                        return;
                    }

                    await ClientEndPoint.SendPacketAsync(new EncryptionKeyResponse {SharedKey = new byte[0]});

                    ClientEndPoint.ConnectionKey = sharedKey;
                    ClientEndPoint.EnableAes (); //now everything is encrypted

                    Packet p = await ClientEndPoint.ReceivePacketAsync ();

                    if (!(p is RespawnRequestPacket))
                    {
                        await KickUserAsync("Protocol failure");
                        _logger.Error("Failed to login a Client, Protocol failure");
                        return;
                    }

                    string hash = ProtocolSecurity.ComputeHash(
                        Encoding.ASCII.GetBytes(serverId),
                        ClientEndPoint.ConnectionKey,
                        AsnKeyBuilder.PublicKeyToX509(_server.RSAKeyPair).GetBytes ());

                    if (onlineMode)
                    {
                        bool result;
                        try
                        {
                            result = await _server.CheckUserAccountAsync(this, hash);
                        }
                        catch (OperationCanceledException ex)
                        {
                            Task t = KickUserAsync(ex.Message);
                            return;
                        }

                        if (!result)
                        {
                            await KickUserAsync("User not premium");
                            return;
                        }
                    }

                    _logger.InfoFormat("{0}[{1}] is connected", Username, _networkSocket.RemoteEndPoint);

                    _server.PromoteConnection(this);

                    Packet response = await InitializeServerAsync ();

                    var logonResponse = response as LogOnResponse;
                    if (logonResponse != null)
                    {
                        EntityID = logonResponse.EntityId;
                    }

                    await ClientEndPoint.SendPacketAsync(response);

                    StartClientListening ();
                    StartServerListening ();

                    args = new UserEventArgs(this);

                    _server.PluginManager.TriggerPlugin.OnUserConnectedCompleted(args);

                    args.EnsureSuccess ();
                }
            }
            catch (TaskCanceledException)
            {
                return;
            }
            catch (OperationCanceledException ex)
            {
                kickMessage = ex.Message;
                success = false;
                _quitMessagePosted = true;
                _logger.Error(string.Format("Client login aborted ({0})", Username), ex);
            }
            catch (Exception ex)
            {
                success = false;
                _quitMessagePosted = true;
                if (!string.IsNullOrEmpty(Username))
                    _logger.Error(string.Format("Failed to login a client ({0})", Username), ex);
            }
            if (!success)
                await KickUserAsync(kickMessage);
        }
 public override async void OnUserConnectedCompleted(UserEventArgs args)
 {
     await args.Connection.ClientEndPoint.SendPacketAsync(new ChatPacket { Message = "Ths proxy is using a fancy plugin!" });
 }
 /// <summary>
 ///   This method is called when the connection to a user is terminated because of the client disconnected, or a network problem appeared
 /// </summary>
 /// <param name="args"> The arguments give information about the user, who disconnected from the server </param>
 public virtual void OnConnectionLost(UserEventArgs args)
 {
 }
 /// <summary>
 ///   This method is called after the proxy verified, that the incoming connection is a user who wants to join the server and the proxy server verified that it knows
 ///   the protocol version the client wants to connect with
 /// </summary>
 /// <param name="args"> A UserEventArgs which give access to relevant operations like reading user information, or methods to cancel the request </param>
 public virtual void OnPlayerConnected(UserEventArgs args)
 {
 }
 /// <summary>
 ///   This event is called after a user successfully joined, and after connecting to the backend server
 /// </summary>
 /// <param name="args"> Information about the connected user </param>
 public virtual void OnUserConnectedCompleted(UserEventArgs args)
 {
 }