--- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -53,6 +53,16 @@ import net.minecraft.world.level.storage.Convertable; import org.slf4j.Logger; +// CraftBukkit start +import net.minecraft.server.WorldLoader; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.io.IoBuilder; +import org.bukkit.command.CommandSender; +import org.bukkit.event.server.ServerCommandEvent; +import org.bukkit.event.server.RemoteServerCommandEvent; +// CraftBukkit end + public class DedicatedServer extends MinecraftServer implements IMinecraftServer { static final Logger LOGGER = LogUtils.getLogger(); @@ -61,7 +71,7 @@ private final List consoleInput = Collections.synchronizedList(Lists.newArrayList()); @Nullable private RemoteStatusListener queryThreadGs4; - private final RemoteControlCommandListener rconConsoleSource; + // private final RemoteControlCommandListener rconConsoleSource; // CraftBukkit - remove field @Nullable private RemoteControlListener rconThread; public DedicatedServerSettings settings; @@ -70,10 +80,12 @@ @Nullable private final TextFilter textFilterClient; - public DedicatedServer(Thread thread, Convertable.ConversionSession convertable_conversionsession, ResourcePackRepository resourcepackrepository, WorldStem worldstem, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, Services services, WorldLoadListenerFactory worldloadlistenerfactory) { - super(thread, convertable_conversionsession, resourcepackrepository, worldstem, Proxy.NO_PROXY, datafixer, services, worldloadlistenerfactory); + // CraftBukkit start - Signature changed + public DedicatedServer(joptsimple.OptionSet options, WorldLoader.a worldLoader, Thread thread, Convertable.ConversionSession convertable_conversionsession, ResourcePackRepository resourcepackrepository, WorldStem worldstem, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, Services services, WorldLoadListenerFactory worldloadlistenerfactory) { + super(options, worldLoader, thread, convertable_conversionsession, resourcepackrepository, worldstem, Proxy.NO_PROXY, datafixer, services, worldloadlistenerfactory); + // CraftBukkit end this.settings = dedicatedserversettings; - this.rconConsoleSource = new RemoteControlCommandListener(this); + // this.rconConsoleSource = new RemoteControlCommandListener(this); // CraftBukkit - remove field this.textFilterClient = TextFilter.createFromConfig(dedicatedserversettings.getProperties().textFilteringConfig); } @@ -81,13 +93,44 @@ public boolean initServer() 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.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack()); + // 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.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack()); + } + // CraftBukkit end } } catch (IOException ioexception) { DedicatedServer.LOGGER.error("Exception handling console input", ioexception); @@ -96,6 +139,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(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream()); + System.setErr(IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream()); + // CraftBukkit end + thread.setDaemon(true); thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER)); thread.start(); @@ -120,7 +184,7 @@ this.setMotd(dedicatedserverproperties.motd); super.setPlayerIdleTimeout((Integer) dedicatedserverproperties.playerIdleTimeout.get()); this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist); - this.worldData.setGameType(dedicatedserverproperties.gamemode); + // this.worldData.setGameType(dedicatedserverproperties.gamemode); // CraftBukkit - moved to world loading DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode); InetAddress inetaddress = null; @@ -144,6 +208,12 @@ return false; } + // CraftBukkit start + this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); + server.loadPlugins(); + server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); + // CraftBukkit end + if (!this.usesAuthentication()) { DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); @@ -158,13 +228,13 @@ if (!NameReferencingFileConverter.serverReadyAfterUserconversion(this)) { return false; } else { - this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); + // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // CraftBukkit - moved up long i = SystemUtils.getNanos(); TileEntitySkull.setup(this.services, this); UserCache.setUsesAuthentication(this.usesAuthentication()); DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getLevelIdName()); - this.loadLevel(); + this.loadLevel(storageSource.getLevelId()); // CraftBukkit long j = SystemUtils.getNanos() - i; String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D); @@ -296,6 +366,7 @@ this.queryThreadGs4.stop(); } + System.exit(0); // CraftBukkit } @Override @@ -317,7 +388,15 @@ while (!this.consoleInput.isEmpty()) { ServerCommand servercommand = (ServerCommand) this.consoleInput.remove(0); - this.getCommands().performPrefixedCommand(servercommand.source, servercommand.msg); + // CraftBukkit start - ServerCommand for preprocessing + ServerCommandEvent event = new ServerCommandEvent(console, servercommand.msg); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + servercommand = new ServerCommand(event.getCommand(), servercommand.source); + + // this.getCommands().performPrefixedCommand(servercommand.source, servercommand.msg); // Called in dispatchServerCommand + server.dispatchServerCommand(console, servercommand); + // CraftBukkit end } } @@ -544,16 +623,52 @@ @Override public String getPluginNames() { - 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 runCommand(String s) { - this.rconConsoleSource.prepareForCommand(); + // CraftBukkit start - fire RemoteServerCommandEvent + throw new UnsupportedOperationException("Not supported - remote source required."); + } + + public String runCommand(RemoteControlCommandListener rconConsoleSource, String s) { + rconConsoleSource.prepareForCommand(); this.executeBlocking(() -> { - this.getCommands().performPrefixedCommand(this.rconConsoleSource.createCommandSourceStack(), s); + CommandListenerWrapper wrapper = rconConsoleSource.createCommandSourceStack(); + RemoteServerCommandEvent event = new RemoteServerCommandEvent(rconConsoleSource.getBukkitSender(wrapper), s); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + ServerCommand serverCommand = new ServerCommand(event.getCommand(), wrapper); + server.dispatchServerCommand(event.getSender(), serverCommand); }); - return this.rconConsoleSource.getCommandResponse(); + return rconConsoleSource.getCommandResponse(); + // CraftBukkit end } public void storeUsingWhiteList(boolean flag) { @@ -604,4 +719,15 @@ public Optional getServerResourcePack() { return this.settings.getProperties().serverResourcePackInfo; } + + // CraftBukkit start + public boolean isDebugging() { + return this.getProperties().debug; + } + + @Override + public CommandSender getBukkitSender(CommandListenerWrapper wrapper) { + return console; + } + // CraftBukkit end }