text: package org.bukkit.craftbukkit;
  
  import java.io.File;
  import java.io.IOException;
  import java.text.SimpleDateFormat;
  import java.util.Arrays;
  import java.util.List;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  import jline.UnsupportedTerminal;
  import joptsimple.OptionParser;
  import joptsimple.OptionSet;
  import org.apache.logging.log4j.LogManager;
  import org.fusesource.jansi.AnsiConsole;
  import com.mohistmc.MohistMC;
  import com.mohistmc.util.i18n.Message;
  
  public class Main {
      public static boolean useJline = true;
      public static boolean useConsole = true;
  
      public static OptionSet main(String[] args) {
          // Todo: Installation script
          MohistMC.LOGGER = LogManager.getLogger("Mohist");
          OptionParser parser = new OptionParser() {
              {
                  acceptsAll(asList("?", "help"), "Show the help");
  
                  acceptsAll(asList("c", "config"), "Properties file to use")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("server.properties"))
                          .describedAs("Properties file");
  
                  acceptsAll(asList("P", "plugins"), "Plugin directory to use")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("plugins"))
                          .describedAs("Plugin directory");
  
                  acceptsAll(asList("h", "host", "server-ip"), "Host to listen on")
                          .withRequiredArg()
                          .ofType(String.class)
                          .describedAs("Hostname or IP");
  
                  acceptsAll(asList("W", "world-dir", "universe", "world-container"), "World container")
                          .withRequiredArg()
                          .ofType(File.class)
                          .describedAs("Directory containing worlds");
  
                  acceptsAll(asList("w", "world", "level-name"), "World name")
                          .withRequiredArg()
                          .ofType(String.class)
                          .describedAs("World name");
  
                  acceptsAll(asList("p", "port", "server-port"), "Port to listen on")
                          .withRequiredArg()
                          .ofType(Integer.class)
                          .describedAs("Port");
  
                  acceptsAll(asList("o", "online-mode"), "Whether to use online authentication")
                          .withRequiredArg()
                          .ofType(Boolean.class)
                          .describedAs("Authentication");
  
                  acceptsAll(asList("s", "size", "max-players"), "Maximum amount of players")
                          .withRequiredArg()
                          .ofType(Integer.class)
                          .describedAs("Server size");
  
                  acceptsAll(asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
                          .withRequiredArg()
                          .ofType(SimpleDateFormat.class)
                          .describedAs("Log date format");
  
                  acceptsAll(asList("log-pattern"), "Specfies the log filename pattern")
                          .withRequiredArg()
                          .ofType(String.class)
                          .defaultsTo("server.log")
                          .describedAs("Log filename");
  
                  acceptsAll(asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)")
                          .withRequiredArg()
                          .ofType(Integer.class)
                          .defaultsTo(0)
                          .describedAs("Max log size");
  
                  acceptsAll(asList("log-count"), "Specified how many log files to cycle through")
                          .withRequiredArg()
                          .ofType(Integer.class)
                          .defaultsTo(1)
                          .describedAs("Log count");
  
                  acceptsAll(asList("log-append"), "Whether to append to the log file")
                          .withRequiredArg()
                          .ofType(Boolean.class)
                          .defaultsTo(true)
                          .describedAs("Log append");
  
                  acceptsAll(asList("log-strip-color"), "Strips color codes from log file");
  
                  acceptsAll(asList("b", "bukkit-settings"), "File for bukkit settings")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("bukkit.yml"))
                          .describedAs("Yml file");
  
                  acceptsAll(asList("C", "commands-settings"), "File for command settings")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("commands.yml"))
                          .describedAs("Yml file");
  
                  acceptsAll(asList("nojline"), "Disables jline and emulates the vanilla console");
  
                  acceptsAll(asList("noconsole"), "Disables the console");
  
                  acceptsAll(asList("v", "version"), "Show the CraftBukkit Version");
  
                  acceptsAll(asList("demo"), "Demo mode");
  
                  // Spigot Start
                  acceptsAll(asList("S", "spigot-settings"), "File for spigot settings")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("spigot.yml"))
                          .describedAs("Yml file");
                  // Spigot End
  
                  // Paper Start
                  acceptsAll(asList("paper", "paper-settings"), "File for paper settings")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("paper.yml"))
                          .describedAs("Yml file");
                  // Paper end
  
                  // Mohist Start
                  acceptsAll(asList("mohist", "mohist-settings"), "File for mohist settings")
                          .withRequiredArg()
                          .ofType(File.class)
                          .defaultsTo(new File("mohist-config", "mohist.yml"))
                          .describedAs("Yml file");
                  // Mohist End
  
  
                  // Paper start
                  acceptsAll(asList("server-name"), "Name of the server")
                          .withRequiredArg()
                          .ofType(String.class)
                          .defaultsTo("Mohist Server")
                          .describedAs("Name");
                  // Paper end
              }
          };
  
          OptionSet options = null;
  
          try {
              options = parser.parse(args);
          } catch (joptsimple.OptionException ex) {
              Logger.getLogger(Main.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage());
          }
  
          if ((options == null) || (options.has("?"))) {
              try {
                  parser.printHelpOn(System.out);
              } catch (IOException ex) {
                  Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
              }
          } else {
              // Do you love Java using + and ! as string based identifiers? I sure do!
              String path = new File(".").getAbsolutePath();
              if (path.contains("!") || path.contains("+")) {
                  System.err.println(Message.getString("error.start.directory"));
                  return null;
              }
              try {
                  // This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals
                  String jline_UnsupportedTerminal = new String(new char[]{'j', 'l', 'i', 'n', 'e', '.', 'U', 'n', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd', 'T', 'e', 'r', 'm', 'i', 'n', 'a', 'l'});
                  String jline_terminal = new String(new char[]{'j', 'l', 'i', 'n', 'e', '.', 't', 'e', 'r', 'm', 'i', 'n', 'a', 'l'});
  
                  useJline = !(jline_UnsupportedTerminal).equals(System.getProperty(jline_terminal));
  
                  if (options.has("nojline")) {
                      System.setProperty("user.language", "en");
                      useJline = false;
                  }
                  if (Main.useJline) {
                      AnsiConsole.systemInstall();
                  } else {
                      System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, UnsupportedTerminal.class.getName());
                  }
  
  
                  if (options.has("noconsole")) {
                      useConsole = false;
                  }
              } catch (Throwable t) {
                  t.printStackTrace();
              }
              return options;
          }
          return null;
      }
  
      private static List<String> asList(String... params) {
          return Arrays.asList(params);
      }
  }
  