2010-12-21 17:52:15 +01:00
|
|
|
package org.bukkit.craftbukkit;
|
|
|
|
|
2011-01-04 01:43:23 +01:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2011-02-26 12:29:37 +01:00
|
|
|
import java.text.SimpleDateFormat;
|
2011-01-04 01:43:23 +01:00
|
|
|
import java.util.Arrays;
|
2016-11-17 02:41:03 +01:00
|
|
|
import java.util.Calendar;
|
|
|
|
import java.util.Date;
|
2011-01-04 01:43:23 +01:00
|
|
|
import java.util.List;
|
2016-11-17 02:41:03 +01:00
|
|
|
import java.util.TimeZone;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2011-01-04 01:43:23 +01:00
|
|
|
import java.util.logging.Level;
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
import joptsimple.OptionParser;
|
|
|
|
import joptsimple.OptionSet;
|
2010-12-21 17:52:15 +01:00
|
|
|
import net.minecraft.server.MinecraftServer;
|
2014-12-06 19:55:50 +01:00
|
|
|
import org.fusesource.jansi.AnsiConsole;
|
2010-12-21 17:52:15 +01:00
|
|
|
|
|
|
|
public class Main {
|
2011-05-19 22:46:47 +02:00
|
|
|
public static boolean useJline = true;
|
2011-11-05 21:14:26 +01:00
|
|
|
public static boolean useConsole = true;
|
2011-05-18 21:23:27 +02:00
|
|
|
|
2010-12-21 17:52:15 +01:00
|
|
|
public static void main(String[] args) {
|
|
|
|
// Todo: Installation script
|
2011-01-04 01:43:23 +01:00
|
|
|
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");
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
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")
|
2011-01-04 02:19:26 +01:00
|
|
|
.withRequiredArg()
|
|
|
|
.ofType(String.class)
|
2012-07-29 09:33:13 +02:00
|
|
|
.describedAs("World name");
|
2011-01-04 02:19:26 +01:00
|
|
|
|
2011-01-04 01:43:23 +01:00
|
|
|
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");
|
2011-02-26 12:29:37 +01:00
|
|
|
|
|
|
|
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");
|
2011-03-31 03:35:08 +02:00
|
|
|
|
2011-07-10 19:28:57 +02:00
|
|
|
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");
|
|
|
|
|
2012-06-02 21:43:38 +02:00
|
|
|
acceptsAll(asList("log-strip-color"), "Strips color codes from log file");
|
2012-05-16 03:18:35 +02:00
|
|
|
|
2011-03-31 03:35:08 +02:00
|
|
|
acceptsAll(asList("b", "bukkit-settings"), "File for bukkit settings")
|
|
|
|
.withRequiredArg()
|
|
|
|
.ofType(File.class)
|
|
|
|
.defaultsTo(new File("bukkit.yml"))
|
|
|
|
.describedAs("Yml file");
|
2011-05-18 21:23:27 +02:00
|
|
|
|
2014-02-08 00:40:59 +01:00
|
|
|
acceptsAll(asList("C", "commands-settings"), "File for command settings")
|
|
|
|
.withRequiredArg()
|
|
|
|
.ofType(File.class)
|
|
|
|
.defaultsTo(new File("commands.yml"))
|
|
|
|
.describedAs("Yml file");
|
|
|
|
|
2011-05-18 21:23:27 +02:00
|
|
|
acceptsAll(asList("nojline"), "Disables jline and emulates the vanilla console");
|
2012-01-14 23:02:10 +01:00
|
|
|
|
2011-11-05 21:14:26 +01:00
|
|
|
acceptsAll(asList("noconsole"), "Disables the console");
|
2011-07-28 06:46:18 +02:00
|
|
|
|
|
|
|
acceptsAll(asList("v", "version"), "Show the CraftBukkit Version");
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
acceptsAll(asList("demo"), "Demo mode");
|
2011-01-04 01:43:23 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
OptionSet options = null;
|
2011-01-01 14:06:04 +01:00
|
|
|
|
2010-12-21 17:52:15 +01:00
|
|
|
try {
|
2011-01-04 01:43:23 +01:00
|
|
|
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);
|
|
|
|
}
|
2011-07-28 06:46:18 +02:00
|
|
|
} else if (options.has("v")) {
|
|
|
|
System.out.println(CraftServer.class.getPackage().getImplementationVersion());
|
2011-01-04 01:43:23 +01:00
|
|
|
} else {
|
2015-01-04 23:24:38 +01:00
|
|
|
// Do you love Java using + and ! as string based identifiers? I sure do!
|
|
|
|
String path = new File(".").getAbsolutePath();
|
|
|
|
if (path.contains("!") || path.contains("+")) {
|
2015-01-04 23:25:27 +01:00
|
|
|
System.err.println("Cannot run server in a directory with ! or + in the pathname. Please rename the affected folders and try again.");
|
|
|
|
return;
|
2015-01-04 23:24:38 +01:00
|
|
|
}
|
|
|
|
|
2011-01-04 01:43:23 +01:00
|
|
|
try {
|
2012-09-02 01:56:13 +02:00
|
|
|
// 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));
|
2011-07-10 19:28:57 +02:00
|
|
|
|
2011-05-18 21:23:27 +02:00
|
|
|
if (options.has("nojline")) {
|
|
|
|
System.setProperty("user.language", "en");
|
2011-05-19 22:46:47 +02:00
|
|
|
useJline = false;
|
2011-05-18 21:23:27 +02:00
|
|
|
}
|
2012-01-14 23:02:10 +01:00
|
|
|
|
2014-12-06 19:55:50 +01:00
|
|
|
if (useJline) {
|
|
|
|
AnsiConsole.systemInstall();
|
|
|
|
} else {
|
2012-09-02 01:56:13 +02:00
|
|
|
// This ensures the terminal literal will always match the jline implementation
|
|
|
|
System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-05 21:14:26 +01:00
|
|
|
if (options.has("noconsole")) {
|
|
|
|
useConsole = false;
|
|
|
|
}
|
2011-05-19 22:46:47 +02:00
|
|
|
|
2016-11-17 02:41:03 +01:00
|
|
|
if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
|
|
|
|
Date buildDate = new SimpleDateFormat("yyyyMMdd-HHmm").parse(Main.class.getPackage().getImplementationVendor());
|
|
|
|
|
|
|
|
Calendar deadline = Calendar.getInstance();
|
|
|
|
deadline.add(Calendar.DAY_OF_YEAR, -3);
|
|
|
|
if (buildDate.before(deadline.getTime())) {
|
|
|
|
System.err.println("*** Error, this build is outdated ***");
|
|
|
|
System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/ ***");
|
|
|
|
System.err.println("*** Server will start in 30 seconds ***");
|
|
|
|
Thread.sleep(TimeUnit.SECONDS.toMillis(30));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-09 21:12:34 +01:00
|
|
|
System.out.println("Loading libraries, please wait...");
|
2011-01-04 01:43:23 +01:00
|
|
|
MinecraftServer.main(options);
|
|
|
|
} catch (Throwable t) {
|
|
|
|
t.printStackTrace();
|
|
|
|
}
|
2010-12-21 17:52:15 +01:00
|
|
|
}
|
|
|
|
}
|
2011-01-04 01:43:23 +01:00
|
|
|
|
|
|
|
private static List<String> asList(String... params) {
|
|
|
|
return Arrays.asList(params);
|
|
|
|
}
|
2010-12-21 17:52:15 +01:00
|
|
|
}
|