/**
  * Called when this client disconnects.
  *
  * @param reason The reason of disconnection.
  */
 public void onDisconnect(String reason) {
   proxy
       .getLogger()
       .info(proxy.getLang().get(Lang.CLIENT_DISCONNECTED, username, remoteAddress, reason));
   downstream.disconnect();
   proxy.getSessionRegister().removeSession(this);
   packetProcessorScheule.cancel(true);
 }
  public void onLogin(LoginPacket packet) {
    if (username != null) {
      disconnect("Error! ");
      return;
    }

    LoginStatusPacket status = new LoginStatusPacket();
    if (packet.protocol1 != Versioning.MINECRAFT_PE_PROTOCOL) {
      status.status = LoginStatusPacket.LOGIN_FAILED_CLIENT;
      sendPacket(status, true);
      disconnect(proxy.getLang().get(Lang.MESSAGE_UNSUPPORTED_CLIENT));
      return;
    }
    status.status = LoginStatusPacket.LOGIN_SUCCESS;
    sendPacket(status, true);

    this.username = packet.username;
    proxy
        .getLogger()
        .info(proxy.getLang().get(Lang.MESSAGE_CLIENT_CONNECTED, username, remoteAddress));
    if (proxy.isOnlineMode()) {
      StartGamePacket pkStartGame = new StartGamePacket();
      pkStartGame.eid = 0; // Use EID 0 for eaisier management
      pkStartGame.dimension = (byte) 0;
      pkStartGame.seed = 0;
      pkStartGame.generator = 1;
      pkStartGame.spawnX = 0;
      pkStartGame.spawnY = 0;
      pkStartGame.spawnZ = 0;
      pkStartGame.x = 0.0f;
      pkStartGame.y = 72.0f;
      pkStartGame.z = 0.0f;
      sendPacket(pkStartGame, true);

      SetSpawnPositionPacket pkSpawn = new SetSpawnPositionPacket();
      pkSpawn.x = 0;
      pkSpawn.y = 72;
      pkSpawn.z = 0;
      sendPacket(pkSpawn, true);

      LoginStatusPacket pkStat = new LoginStatusPacket();
      pkStat.status = LoginStatusPacket.PLAYER_SPAWN;
      sendPacket(pkStat, true);

      dataCache.put(CacheKey.AUTHENTICATION_STATE, "email");

      sendChat(proxy.getLang().get(Lang.MESSAGE_ONLINE_NOTICE, username));
      sendChat(proxy.getLang().get(Lang.MESSAGE_ONLINE_EMAIL));
    } else {
      protocol = new MinecraftProtocol(username);
      downstream.connect(protocol, proxy.getRemoteServerAddress());
    }
  }
  public void authenticate(String password) {
    proxy
        .getGeneralThreadPool()
        .execute(
            () -> {
              try {
                protocol =
                    new MinecraftProtocol(
                        (String) dataCache.get(CacheKey.AUTHENTICATION_EMAIL), password, false);
              } catch (RequestException ex) {
                if (ex.getMessage().toLowerCase().contains("invalid")) {
                  sendChat(proxy.getLang().get(Lang.MESSAGE_ONLINE_LOGIN_FAILD));
                  disconnect(proxy.getLang().get(Lang.MESSAGE_ONLINE_LOGIN_FAILD));
                  return;
                } else {
                  sendChat(proxy.getLang().get(Lang.MESSAGE_ONLINE_ERROR));
                  disconnect(proxy.getLang().get(Lang.MESSAGE_ONLINE_ERROR));
                  return;
                }
              }

              if (!username.equals(protocol.getProfile().getName())) {
                username = protocol.getProfile().getName();
                sendChat(proxy.getLang().get(Lang.MESSAGE_ONLINE_USERNAME, username));
              }

              sendChat(proxy.getLang().get(Lang.MESSAGE_ONLINE_LOGIN_SUCCESS, username));

              proxy
                  .getLogger()
                  .info(
                      proxy
                          .getLang()
                          .get(
                              Lang.MESSAGE_ONLINE_LOGIN_SUCCESS_CONSOLE,
                              username,
                              remoteAddress,
                              username));
              downstream.connect(protocol, proxy.getRemoteServerAddress());
            });
  }