Beispiel #1
0
  /**
   * Disconnects the session with the specified reason. This causes a KickMessage to be sent. When
   * it has been delivered, the channel is closed.
   *
   * @param reason The reason for disconnection.
   * @param overrideKick Whether to skip the kick event.
   */
  public void disconnect(String reason, boolean overrideKick) {
    if (player != null && !overrideKick) {
      PlayerKickEvent event = EventFactory.onPlayerKick(player, reason);
      if (event.isCancelled()) {
        return;
      }

      reason = event.getReason();

      if (player.isOnline() && event.getLeaveMessage() != null) {
        server.broadcastMessage(event.getLeaveMessage());
      }
    }

    // log that the player was kicked
    if (player != null) {
      GlowServer.logger.info(player.getName() + " kicked: " + reason);
    } else {
      GlowServer.logger.info("[" + address + "] kicked: " + reason);
    }

    if (quitReason == null) {
      quitReason = "kicked";
    }

    // perform the kick, sending a kick message if possible
    if (isActive()
        && (getProtocol() instanceof LoginProtocol || getProtocol() instanceof PlayProtocol)) {
      // channel is both currently connected and in a protocol state allowing kicks
      sendWithFuture(new KickMessage(reason)).addListener(ChannelFutureListener.CLOSE);
    } else {
      getChannel().close();
    }
  }
Beispiel #2
0
  /** Pulse this session, performing any updates needed. */
  void pulse() {
    // drop the previous placement if needed
    if (previousPlacementTicks > 0 && --previousPlacementTicks == 0) {
      previousPlacement = null;
    }

    // process messages
    Message message;
    while ((message = messageQueue.poll()) != null) {
      if (disconnected) {
        // disconnected, we are just seeing extra messages now
        continue;
      }

      super.messageReceived(message);
    }

    // check if the client is disconnected
    if (disconnected) {
      connectionManager.sessionInactivated(this);

      if (player == null) {
        return;
      }

      player.remove();

      Message userListMessage = UserListItemMessage.removeOne(player.getUniqueId());
      for (GlowPlayer player : server.getOnlinePlayers()) {
        if (player.canSee(this.player)) {
          player.getSession().send(userListMessage);
        } else {
          player.stopHidingDisconnectedPlayer(this.player);
        }
      }

      GlowServer.logger.info(player.getName() + " [" + address + "] lost connection");

      if (player.isSleeping()) {
        player.leaveBed(false);
      }

      final String text = EventFactory.onPlayerQuit(player).getQuitMessage();
      if (online && text != null && !text.isEmpty()) {
        server.broadcastMessage(text);
      }

      player = null; // in case we are disposed twice
    }
  }
Beispiel #3
0
  /**
   * Sets the player associated with this session.
   *
   * @param profile The player's profile with name and UUID information.
   * @throws IllegalStateException if there is already a player associated with this session.
   */
  public void setPlayer(PlayerProfile profile) {
    if (player != null) {
      throw new IllegalStateException("Cannot set player twice");
    }

    // isActive check here in case player disconnected during authentication
    if (!isActive()) {
      // no need to call onDisconnect() since it only does anything if there's a player set
      return;
    }

    // initialize the player
    PlayerDataService.PlayerReader reader =
        server.getPlayerDataService().beginReadingData(profile.getUniqueId());
    player = new GlowPlayer(this, profile, reader);

    // isActive check here in case player disconnected after authentication,
    // but before the GlowPlayer initialization was completed
    if (!isActive()) {
      onDisconnect();
      return;
    }

    // login event
    PlayerLoginEvent event = EventFactory.onPlayerLogin(player, hostname);
    if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
      disconnect(event.getKickMessage(), true);
      return;
    }

    // joins the player
    player.join(this, reader);

    // Kick other players with the same UUID
    for (GlowPlayer other : getServer().getOnlinePlayers()) {
      if (other != player && other.getUniqueId().equals(player.getUniqueId())) {
        other.getSession().disconnect("You logged in from another location.", true);
        break;
      }
    }

    player.getWorld().getRawPlayers().add(player);

    online = true;

    GlowServer.logger.info(
        player.getName() + " [" + address + "] connected, UUID: " + player.getUniqueId());

    // message and user list
    String message = EventFactory.onPlayerJoin(player).getJoinMessage();
    if (message != null && !message.isEmpty()) {
      server.broadcastMessage(message);
    }

    // todo: display names are included in the outgoing messages here, but
    // don't show up on the client. A workaround or proper fix is needed.
    Message addMessage =
        new UserListItemMessage(UserListItemMessage.Action.ADD_PLAYER, player.getUserListEntry());
    List<UserListItemMessage.Entry> entries = new ArrayList<>();
    for (GlowPlayer other : server.getOnlinePlayers()) {
      if (other != player && other.canSee(player)) {
        other.getSession().send(addMessage);
      }
      if (player.canSee(other)) {
        entries.add(other.getUserListEntry());
      }
    }
    send(new UserListItemMessage(UserListItemMessage.Action.ADD_PLAYER, entries));
  }