public void shutdown() {
    logger.info(lang.get(Lang.SHUTTING_DOWN));

    isDebug = false;
    this.shuttingDown = true;
    network.shutdown();
    try {
      Thread.sleep(2000); // Wait for all clients disconnected
    } catch (Exception e) {
    }
    System.exit(0);
  }
 private void status() {
   MinecraftProtocol protocol = new MinecraftProtocol(SubProtocol.STATUS);
   Client client =
       new Client(
           remoteServerAddress.getHostString(),
           remoteServerAddress.getPort(),
           protocol,
           new TcpSessionFactory(Proxy.NO_PROXY));
   client.getSession().setFlag(MinecraftConstants.AUTH_PROXY_KEY, Proxy.NO_PROXY);
   client.getSession().setConnectTimeout(10000);
   client
       .getSession()
       .setFlag(
           MinecraftConstants.SERVER_INFO_HANDLER_KEY,
           new ServerInfoHandler() {
             @Override
             public void handle(Session session, ServerStatusInfo info) {
               network.setBroadcastName(
                   motd,
                   info.getPlayerInfo().getOnlinePlayers(),
                   info.getPlayerInfo().getMaxPlayers());
               return;
             }
           });
   client
       .getSession()
       .setFlag(
           MinecraftConstants.SERVER_PING_TIME_HANDLER_KEY,
           new ServerPingTimeHandler() {
             public void handle(Session session, long pingTime) {}
           });
   client.getSession().connect();
   boolean connected = false;
   while (client.getSession().isConnected()) {
     try {
       connected = true;
       Thread.sleep(5);
     } catch (InterruptedException e) {
     }
   }
   if (!connected) {
     String error = lang.get(Lang.QUERY_FAILED);
     error = error.replace("%ip%", remoteServerAddress.getHostString());
     error = error.replace("%port%", remoteServerAddress.getPort() + "");
     logger.warning(error);
   }
 }
  public void run(String[] args) {

    // Need to initialize config before console
    try {
      config = new ServerConfig();
    } catch (IOException ex) {
      logger.severe("Failed to load configuration file!");
      ex.printStackTrace();
      return;
    }

    // Initialize console
    console = new ConsoleManager(this);
    console.startConsole();

    checkArguments(args);

    if (config.getConfig().getProperty("log_console").toLowerCase().contains("true")) {
      console.startFile("console.log");
      logger.info("Saving console output enabled"); // TODO: Translations
    } else {
      logger.info("Saving console output disabled");
    }

    try {
      lang = new Lang(config.getConfig().getProperty(ServerConfig.LANG_FILE));
    } catch (IOException ex) {
      logger.severe("Failed to load language file!");
      ex.printStackTrace();
      return;
    }
    logger.info(lang.get(Lang.INIT_LOADING, Versioning.RELEASE_VERSION));
    logger.info(lang.get(Lang.INIT_MC_PC_SUPPORT, Versioning.MINECRAFT_PC_VERSION));
    logger.info(lang.get(Lang.INIT_MC_PE_SUPPORT, Versioning.MINECRAFT_PE_VERSION));
    authMode = config.getConfig().getProperty("mode").toLowerCase();
    if (!authMode.equals("cls") && !authMode.equals("online") && !authMode.equals("offline")) {
      logger.severe(
          "Invalid 'mode' option detected, must be cls/online/offline, you set it to '"
              + authMode
              + "'! ");
      return;
    }
    remoteServerAddress =
        new InetSocketAddress(
            config.getConfig().getProperty("remote_ip"),
            Integer.parseInt(config.getConfig().getProperty("remote_port")));
    sessionRegister = new SessionRegister(this);
    commandRegister = new CommandRegister(this);
    if (IS_RELEASE) {
      try {
        metrics = new ServerMetrics(this);
        metrics.start();
      } catch (IOException ex) {
      }
    } else {
      logger.info("\n-----------------------------");
      logger.info(" This is a DEVELOPMENT build ");
      logger.info("     It may contain bugs     ");
      logger.info("-----------------------------\n");
    }

    // Create thread pool
    logger.info(
        lang.get(
            Lang.INIT_CREATING_THREAD_POOL,
            Integer.parseInt(config.getConfig().getProperty("thread_pool_size"))));
    generalThreadPool =
        Executors.newScheduledThreadPool(
            Integer.parseInt(config.getConfig().getProperty("thread_pool_size")));

    // Bind
    logger.info(
        lang.get(
            Lang.INIT_BINDING,
            config.getConfig().getProperty("udp_bind_ip"),
            config.getConfig().getProperty("udp_bind_port")));
    network =
        new RaknetInterface(
            this,
            config.getConfig().getProperty("udp_bind_ip"), // IP
            Integer.parseInt(config.getConfig().getProperty("udp_bind_port"))); // Port

    // MOTD
    motd = config.getConfig().getProperty("motd");
    motd = motd.replace("&", "§");
    motd = motd.replace("%ip%", remoteServerAddress.getHostString());
    motd = motd.replace("%port%", remoteServerAddress.getPort() + "");

    network.setBroadcastName(motd, -1, -1);
    ticker.start();
    logger.info(lang.get(Lang.INIT_DONE));

    // Ping the PC server to show the players online
    pingPCServer();
  }