Files
Paper/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java
Kyle Wood 0dcb203960 Fix this stupid bullshit
Disable the 15 second sleep when the server jar hasn't been rebuilt within a period of time.

modified in order to prevent merge conflicts when Spigot changes/disables the warning,
and to provide some level of hint without being disruptive.
2017-08-06 17:17:53 -05:00

276 lines
13 KiB
Java

package org.bukkit.craftbukkit;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.util.PathConverter;
public class Main {
public static final java.time.Instant BOOT_TIME = java.time.Instant.now(); // Paper - track initial start time
public static boolean useJline = true;
public static boolean useConsole = true;
public static void main(String[] args) {
// Paper start
final String warnWhenLegacyFormattingDetected = String.join(".", "net", "kyori", "adventure", "text", "warnWhenLegacyFormattingDetected");
if (false && System.getProperty(warnWhenLegacyFormattingDetected) == null) {
System.setProperty(warnWhenLegacyFormattingDetected, String.valueOf(true));
}
// Paper end
// Todo: Installation script
OptionParser parser = new OptionParser() {
{
this.acceptsAll(Main.asList("?", "help"), "Show the help");
this.acceptsAll(Main.asList("c", "config"), "Properties file to use")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File("server.properties"))
.describedAs("Properties file");
this.acceptsAll(Main.asList("P", "plugins"), "Plugin directory to use")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File("plugins"))
.describedAs("Plugin directory");
this.acceptsAll(Main.asList("h", "host", "server-ip"), "Host to listen on")
.withRequiredArg()
.ofType(String.class)
.describedAs("Hostname or IP");
this.acceptsAll(Main.asList("W", "world-dir", "universe", "world-container"), "World container")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File("."))
.describedAs("Directory containing worlds");
this.acceptsAll(Main.asList("w", "world", "level-name"), "World name")
.withRequiredArg()
.ofType(String.class)
.describedAs("World name");
this.acceptsAll(Main.asList("p", "port", "server-port"), "Port to listen on")
.withRequiredArg()
.ofType(Integer.class)
.describedAs("Port");
this.accepts("serverId", "Server ID")
.withRequiredArg();
this.accepts("jfrProfile", "Enable JFR profiling");
this.accepts("pidFile", "pid File")
.withRequiredArg()
.withValuesConvertedBy(new PathConverter());
this.acceptsAll(Main.asList("o", "online-mode"), "Whether to use online authentication")
.withRequiredArg()
.ofType(Boolean.class)
.describedAs("Authentication");
this.acceptsAll(Main.asList("s", "size", "max-players"), "Maximum amount of players")
.withRequiredArg()
.ofType(Integer.class)
.describedAs("Server size");
this.acceptsAll(Main.asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
.withRequiredArg()
.ofType(SimpleDateFormat.class)
.describedAs("Log date format");
this.acceptsAll(Main.asList("log-pattern"), "Specfies the log filename pattern")
.withRequiredArg()
.ofType(String.class)
.defaultsTo("server.log")
.describedAs("Log filename");
this.acceptsAll(Main.asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)")
.withRequiredArg()
.ofType(Integer.class)
.defaultsTo(0)
.describedAs("Max log size");
this.acceptsAll(Main.asList("log-count"), "Specified how many log files to cycle through")
.withRequiredArg()
.ofType(Integer.class)
.defaultsTo(1)
.describedAs("Log count");
this.acceptsAll(Main.asList("log-append"), "Whether to append to the log file")
.withRequiredArg()
.ofType(Boolean.class)
.defaultsTo(true)
.describedAs("Log append");
this.acceptsAll(Main.asList("log-strip-color"), "Strips color codes from log file");
this.acceptsAll(Main.asList("b", "bukkit-settings"), "File for bukkit settings")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File("bukkit.yml"))
.describedAs("Yml file");
this.acceptsAll(Main.asList("C", "commands-settings"), "File for command settings")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File("commands.yml"))
.describedAs("Yml file");
this.acceptsAll(Main.asList("forceUpgrade"), "Whether to force a world upgrade");
this.acceptsAll(Main.asList("eraseCache"), "Whether to force cache erase during world upgrade");
this.acceptsAll(Main.asList("recreateRegionFiles"), "Whether to recreate region files during world upgrade");
this.accepts("safeMode", "Loads level with vanilla datapack only"); // Paper
this.acceptsAll(Main.asList("nogui"), "Disables the graphical console");
this.acceptsAll(Main.asList("nojline"), "Disables jline and emulates the vanilla console");
this.acceptsAll(Main.asList("noconsole"), "Disables the console");
this.acceptsAll(Main.asList("v", "version"), "Show the CraftBukkit Version");
this.acceptsAll(Main.asList("demo"), "Demo mode");
this.acceptsAll(Main.asList("initSettings"), "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option
// Spigot Start
this.acceptsAll(Main.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-dir", "paper-settings-directory"), "Directory for Paper settings")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR))
.describedAs("Config directory");
acceptsAll(asList("paper", "paper-settings"), "File for Paper settings")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File("paper.yml"))
.describedAs("Yml file");
acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.")
.withRequiredArg()
.ofType(File.class)
.defaultsTo(new File[] {})
.describedAs("Jar file");
// Paper end
// Paper start
acceptsAll(asList("server-name"), "Name of the server")
.withRequiredArg()
.ofType(String.class)
.defaultsTo("Unknown 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 if (options.has("v")) {
System.out.println(CraftServer.class.getPackage().getImplementationVersion());
} 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("Cannot run server in a directory with ! or + in the pathname. Please rename the affected folders and try again.");
return;
}
float javaVersion = Float.parseFloat(System.getProperty("java.class.version"));
if (javaVersion > 67.0) {
System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 23 is supported.");
return;
}
try {
// Paper start - Handled by TerminalConsoleAppender
/*
// 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'});
Main.useJline = !(jline_UnsupportedTerminal).equals(System.getProperty(jline_terminal));
if (options.has("nojline")) {
System.setProperty("user.language", "en");
Main.useJline = false;
}
if (Main.useJline) {
AnsiConsole.systemInstall();
} else {
// This ensures the terminal literal will always match the jline implementation
System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName());
}
*/
if (options.has("nojline")) {
System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false");
useJline = false;
}
// Paper end
if (options.has("noconsole")) {
Main.useConsole = false;
useJline = false; // Paper
System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper
}
if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(Main.class.getPackage().getImplementationVendor()); // Paper
Calendar deadline = Calendar.getInstance();
deadline.add(Calendar.DAY_OF_YEAR, -2);
if (buildDate.before(deadline.getTime())) {
// Paper start - This is some stupid bullshit
System.err.println("*** Warning, you've not updated in a while! ***");
System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads/paper ***"); // Paper
//System.err.println("*** Server will start in 20 seconds ***");
//Thread.sleep(TimeUnit.SECONDS.toMillis(20));
// Paper end
}
}
System.setProperty("library.jansi.version", "Paper"); // Paper - set meaningless jansi version to prevent git builds from crashing on Windows
System.setProperty("jdk.console", "java.base"); // Paper - revert default console provider back to java.base so we can have our own jline
//System.out.println("Loading libraries, please wait...");
//net.minecraft.server.Main.main(options);
io.papermc.paper.PaperBootstrap.boot(options);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
private static List<String> asList(String... params) {
return Arrays.asList(params);
}
}