--- a/net/minecraft/server/DedicatedServer.java +++ b/net/minecraft/server/DedicatedServer.java @@ -22,6 +22,17 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +// CraftBukkit start +import java.io.PrintStream; +import org.apache.logging.log4j.Level; + +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.LoggerOutputStream; +import org.bukkit.event.server.ServerCommandEvent; +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.event.server.RemoteServerCommandEvent; +// CraftBukkit end + public class DedicatedServer extends MinecraftServer implements IMinecraftServer { private static final Logger LOGGER = LogManager.getLogger(); @@ -34,8 +45,10 @@ @Nullable private ServerGUI q; - public DedicatedServer(Thread thread, IRegistryCustom.Dimension iregistrycustom_dimension, Convertable.ConversionSession convertable_conversionsession, ResourcePackRepository resourcepackrepository, DataPackResources datapackresources, SaveData savedata, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory) { - super(thread, iregistrycustom_dimension, convertable_conversionsession, savedata, resourcepackrepository, Proxy.NO_PROXY, datafixer, datapackresources, minecraftsessionservice, gameprofilerepository, usercache, worldloadlistenerfactory); + // CraftBukkit start - Signature changed + public DedicatedServer(joptsimple.OptionSet options, DataPackConfiguration datapackconfiguration, Thread thread, IRegistryCustom.Dimension iregistrycustom_dimension, Convertable.ConversionSession convertable_conversionsession, ResourcePackRepository resourcepackrepository, DataPackResources datapackresources, SaveData savedata, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory) { + super(options, datapackconfiguration, thread, iregistrycustom_dimension, convertable_conversionsession, savedata, resourcepackrepository, Proxy.NO_PROXY, datafixer, datapackresources, minecraftsessionservice, gameprofilerepository, usercache, worldloadlistenerfactory); + // CraftBukkit end this.propertyManager = dedicatedserversettings; this.remoteControlCommandListener = new RemoteControlCommandListener(this); } @@ -44,13 +57,44 @@ public boolean init() throws IOException { Thread thread = new Thread("Server console handler") { public void run() { - BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); + // CraftBukkit start + if (!org.bukkit.craftbukkit.Main.useConsole) { + return; + } + jline.console.ConsoleReader bufferedreader = reader; + + // MC-33041, SPIGOT-5538: if System.in is not valid due to javaw, then return + try { + System.in.available(); + } catch (IOException ex) { + return; + } + // CraftBukkit end String s; try { - while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning() && (s = bufferedreader.readLine()) != null) { - DedicatedServer.this.issueCommand(s, DedicatedServer.this.getServerCommandListener()); + // CraftBukkit start - JLine disabling compatibility + while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning()) { + if (org.bukkit.craftbukkit.Main.useJline) { + s = bufferedreader.readLine(">", null); + } else { + s = bufferedreader.readLine(); + } + + // SPIGOT-5220: Throttle if EOF (ctrl^d) or stdin is /dev/null + if (s == null) { + try { + Thread.sleep(50L); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + continue; + } + if (s.trim().length() > 0) { // Trim to filter lines which are just spaces + DedicatedServer.this.issueCommand(s, DedicatedServer.this.getServerCommandListener()); + } + // CraftBukkit end } } catch (IOException ioexception) { DedicatedServer.LOGGER.error("Exception handling console input", ioexception); @@ -59,6 +103,27 @@ } }; + // CraftBukkit start - TODO: handle command-line logging arguments + java.util.logging.Logger global = java.util.logging.Logger.getLogger(""); + global.setUseParentHandlers(false); + for (java.util.logging.Handler handler : global.getHandlers()) { + global.removeHandler(handler); + } + global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler()); + + final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()); + for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) { + if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) { + logger.removeAppender(appender); + } + } + + new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader).start(); + + System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true)); + System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true)); + // CraftBukkit end + thread.setDaemon(true); thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER)); thread.start(); @@ -85,7 +150,7 @@ this.setForceGamemode(dedicatedserverproperties.forceGamemode); super.setIdleTimeout((Integer) dedicatedserverproperties.playerIdleTimeout.get()); this.i(dedicatedserverproperties.enforceWhitelist); - this.saveData.setGameType(dedicatedserverproperties.gamemode); + // this.saveData.setGameType(dedicatedserverproperties.gamemode); // CraftBukkit - moved to world loading DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode); InetAddress inetaddress = null; @@ -110,6 +175,12 @@ return false; } + // CraftBukkit start + this.a((PlayerList) (new DedicatedPlayerList(this, this.f, this.worldNBTStorage))); + server.loadPlugins(); + server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); + // CraftBukkit end + if (!this.getOnlineMode()) { DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); @@ -124,7 +195,7 @@ if (!NameReferencingFileConverter.e(this)) { return false; } else { - this.a((PlayerList) (new DedicatedPlayerList(this, this.f, this.worldNBTStorage))); + // this.a((PlayerList) (new DedicatedPlayerList(this, this.f, this.worldNBTStorage))); // CraftBukkit - moved up long i = SystemUtils.getMonotonicNanos(); this.c(dedicatedserverproperties.maxBuildHeight); @@ -132,7 +203,7 @@ TileEntitySkull.a(this.getMinecraftSessionService()); UserCache.a(this.getOnlineMode()); DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getWorld()); - this.loadWorld(); + this.loadWorld(convertable.getLevelName()); // CraftBukkit long j = SystemUtils.getMonotonicNanos() - i; String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D); @@ -149,6 +220,7 @@ if (dedicatedserverproperties.enableRcon) { DedicatedServer.LOGGER.info("Starting remote control listener"); this.remoteControlListener = RemoteControlListener.a((IMinecraftServer) this); + this.remoteConsole = new org.bukkit.craftbukkit.command.CraftRemoteConsoleCommandSender(this.remoteControlCommandListener); // CraftBukkit } if (this.getMaxTickTime() > 0L) { @@ -259,6 +331,7 @@ this.remoteStatusListener.b(); } + System.exit(0); // CraftBukkit } @Override @@ -287,7 +360,15 @@ while (!this.serverCommandQueue.isEmpty()) { ServerCommand servercommand = (ServerCommand) this.serverCommandQueue.remove(0); - this.getCommandDispatcher().a(servercommand.source, servercommand.command); + // CraftBukkit start - ServerCommand for preprocessing + ServerCommandEvent event = new ServerCommandEvent(console, servercommand.command); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + servercommand = new ServerCommand(event.getCommand(), servercommand.source); + + // this.getCommandDispatcher().a(servercommand.source, servercommand.command); // Called in dispatchServerCommand + server.dispatchServerCommand(console, servercommand); + // CraftBukkit end } } @@ -497,14 +578,45 @@ @Override public String getPlugins() { - return ""; + // CraftBukkit start - Whole method + StringBuilder result = new StringBuilder(); + org.bukkit.plugin.Plugin[] plugins = server.getPluginManager().getPlugins(); + + result.append(server.getName()); + result.append(" on Bukkit "); + result.append(server.getBukkitVersion()); + + if (plugins.length > 0 && server.getQueryPlugins()) { + result.append(": "); + + for (int i = 0; i < plugins.length; i++) { + if (i > 0) { + result.append("; "); + } + + result.append(plugins[i].getDescription().getName()); + result.append(" "); + result.append(plugins[i].getDescription().getVersion().replaceAll(";", ",")); + } + } + + return result.toString(); + // CraftBukkit end } @Override public String executeRemoteCommand(String s) { this.remoteControlCommandListener.clearMessages(); this.executeSync(() -> { - this.getCommandDispatcher().a(this.remoteControlCommandListener.getWrapper(), s); + // CraftBukkit start - fire RemoteServerCommandEvent + RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, s); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + ServerCommand serverCommand = new ServerCommand(event.getCommand(), remoteControlCommandListener.getWrapper()); + server.dispatchServerCommand(remoteConsole, serverCommand); + // CraftBukkit end }); return this.remoteControlCommandListener.getMessages(); } @@ -540,4 +652,15 @@ public boolean isSyncChunkWrites() { return this.propertyManager.getProperties().syncChunkWrites; } + + // CraftBukkit start + public boolean isDebugging() { + return this.getDedicatedServerProperties().debug; + } + + @Override + public CommandSender getBukkitSender(CommandListenerWrapper wrapper) { + return console; + } + // CraftBukkit end }