Ejemplo n.º 1
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
    }
  }
Ejemplo n.º 2
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();
    }
  }
Ejemplo n.º 3
0
  public void refreshCommands() {
    for (Object c : new ArrayList(reader.getCompletors())) {
      reader.removeCompletor((Completor) c);
    }

    Completor[] list =
        new Completor[] {new SimpleCompletor(server.getAllCommands()), new NullCompletor()};
    reader.addCompletor(new ArgumentCompletor(list));
    sender.recalculatePermissions();
  }
Ejemplo n.º 4
0
  /**
   * Creates a new server on TCP port 25565 and starts listening for connections.
   *
   * @param args The command-line arguments.
   */
  public static void main(String[] args) {
    try {
      storeQueue.start();

      if (!configDir.exists() || !configDir.isDirectory()) configDir.mkdirs();
      config.load();
      config.options().indent(4);
      ConfigurationSerialization.registerClass(GlowOfflinePlayer.class);

      GlowServer server = new GlowServer();
      server.start();
      List<String> binds = config.getStringList("server.bind");
      boolean hasBound = false;
      if (binds != null) {
        for (String bind : binds) {
          String[] split = bind.split("@");
          if (split.length != 2) {
            split = bind.split(":");
          }
          if (split.length > 2) continue;
          int port = 25565;
          try {
            if (split.length > 1) {
              port = Integer.parseInt(split[1]);
            }
          } catch (NumberFormatException e) {
          }
          server.bind(new InetSocketAddress(split[0], port));
          hasBound = true;
        }
      }
      if (!hasBound) {
        server.bind(new InetSocketAddress(config.getInt("server.port", 25565)));
      }
      logger.info("Ready for connections.");
    } catch (Throwable t) {
      logger.log(Level.SEVERE, "Error during server startup.", t);
    }
  }
Ejemplo n.º 5
0
  public void writePlayerData(GlowPlayer player) {

    File playerDir = new File(world.getName(), "players");
    if (!playerDir.exists()) playerDir.mkdirs();

    File playerFile = new File(playerDir, player.getName() + ".dat");
    if (!playerFile.exists())
      try {
        playerFile.createNewFile();
      } catch (IOException e) {
        player.getSession().disconnect("Failed to access player.dat");
        server
            .getLogger()
            .severe(
                "Failed to access player.dat for player "
                    + player.getName()
                    + " in world "
                    + world.getName()
                    + "!");
      }

    Map<String, Tag> out = EntityStoreLookupService.find(GlowPlayer.class).save(player);
    try {
      NBTOutputStream outStream = new NBTOutputStream(new FileOutputStream(playerFile));
      outStream.writeTag(new CompoundTag("", out));
      outStream.close();
    } catch (IOException e) {
      player.getSession().disconnect("Failed to write player.dat", true);
      server
          .getLogger()
          .severe(
              "Failed to write player.dat for player "
                  + player.getName()
                  + " in world "
                  + world.getName()
                  + "!");
    }
  }
Ejemplo n.º 6
0
  /**
   * Creates a new server on TCP port 25565 and starts listening for connections.
   *
   * @param args The command-line arguments.
   */
  public static void main(String[] args) {
    try {
      ConfigurationSerialization.registerClass(GlowOfflinePlayer.class);
      GlowPotionEffect.register();

      // parse arguments and read config
      final ServerConfig config = parseArguments(args);
      if (config == null) {
        return;
      }

      // start server
      final GlowServer server = new GlowServer(config);
      server.start();
      server.bind();
      server.bindQuery();
      server.bindRcon();
      logger.info("Ready for connections.");
    } catch (Throwable t) {
      logger.log(Level.SEVERE, "Error during server startup.", t);
      System.exit(1);
    }
  }
Ejemplo n.º 7
0
  public void readPlayerData(GlowPlayer player) {
    Map<String, Tag> playerData = new HashMap<String, Tag>();
    CompoundTag playerTag = null;
    // Map<PlayerData, Object> ret = new HashMap<PlayerData, Object>();

    File playerDir = new File(world.getName(), "players");
    if (!playerDir.exists()) playerDir.mkdirs();

    File playerFile = new File(playerDir, player.getName() + ".dat");
    if (!playerFile.exists()) {
      try {
        playerFile.createNewFile();
      } catch (IOException e) {
        e.printStackTrace();
      }
    } else {
      try {
        NBTInputStream in = new NBTInputStream(new FileInputStream(playerFile));
        playerTag = (CompoundTag) in.readTag();
        in.close();
        if (playerTag != null) playerData.putAll(playerTag.getValue());
      } catch (EOFException e) {
      } catch (IOException e) {
        player.kickPlayer("Failed to read " + player.getName() + ".dat!");
        server
            .getLogger()
            .severe(
                "Failed to read player.dat for player "
                    + player.getName()
                    + " in world "
                    + world.getName()
                    + "!");
        e.printStackTrace();
      }
    }

    if (playerTag == null) playerTag = new CompoundTag("", new HashMap<String, Tag>());
    EntityStoreLookupService.find(GlowPlayer.class).load(player, playerTag);
  }
Ejemplo n.º 8
0
 private void handleWorldException(String file, IOException e) {
   server.unloadWorld(world, false);
   server.getLogger().severe("Unable to access " + file + " for world " + world.getName());
   e.printStackTrace();
 }
Ejemplo n.º 9
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));
  }
 @Override
 public void sessionInactivated(Session session) {
   server.getSessionRegistry().remove((GlowSession) session);
 }
 @Override
 public GlowSession newSession(Channel c) {
   GlowSession session = new GlowSession(server, c, this);
   server.getSessionRegistry().add(session);
   return session;
 }
Ejemplo n.º 12
0
  public ConsoleManager(GlowServer server, String mode) {
    this.server = server;

    if (mode.equalsIgnoreCase("gui")) {
      JTerminalListener listener = new JTerminalListener();

      jFrame = new JFrame("Glowstone");
      jTerminal = new JTerminal();
      jInput =
          new JTextField(80) {
            @Override
            public void setBorder(Border border) {}
          };
      jInput.paint(null);
      jInput.setFont(new Font("Monospaced", Font.PLAIN, 12));
      jInput.setBackground(Color.BLACK);
      jInput.setForeground(Color.WHITE);
      jInput.setMargin(new Insets(0, 0, 0, 0));
      jInput.addKeyListener(listener);

      JLabel caret = new JLabel("> ");
      caret.setFont(new Font("Monospaced", Font.PLAIN, 12));
      caret.setForeground(Color.WHITE);

      JPanel ipanel = new JPanel();
      ipanel.add(caret, BorderLayout.WEST);
      ipanel.add(jInput, BorderLayout.EAST);
      ipanel.setBorder(BorderFactory.createEmptyBorder());
      ipanel.setBackground(Color.BLACK);
      ipanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
      ipanel.setSize(jTerminal.getWidth(), ipanel.getHeight());

      jFrame.getContentPane().add(jTerminal, BorderLayout.NORTH);
      jFrame.getContentPane().add(ipanel, BorderLayout.SOUTH);
      jFrame.addWindowListener(listener);
      jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
      jFrame.setLocationRelativeTo(null);
      jFrame.pack();
      jFrame.setVisible(true);
    } else if (mode.equalsIgnoreCase("jline")) {
      jLine = true;
    }

    consoleHandler = new FancyConsoleHandler();

    String logFile = server.getLogFile();
    if (new File(logFile).getParentFile() != null) {
      new File(logFile).getParentFile().mkdirs();
    }
    fileHandler = new RotatingFileHandler(logFile);

    consoleHandler.setFormatter(new DateOutputFormatter(new SimpleDateFormat("HH:mm:ss")));
    fileHandler.setFormatter(new DateOutputFormatter(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")));

    Logger logger = Logger.getLogger("");
    for (Handler h : logger.getHandlers()) {
      logger.removeHandler(h);
    }
    logger.addHandler(consoleHandler);
    logger.addHandler(fileHandler);

    try {
      reader = new ConsoleReader();
    } catch (IOException ex) {
      server
          .getLogger()
          .log(Level.SEVERE, "Exception inintializing console reader: {0}", ex.getMessage());
      ex.printStackTrace();
    }

    Runtime.getRuntime().addShutdownHook(new ServerShutdownThread());

    System.setOut(new PrintStream(new LoggerOutputStream(Level.INFO), true));
    System.setErr(new PrintStream(new LoggerOutputStream(Level.SEVERE), true));
  }