--- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -5,9 +5,9 @@ import com.mojang.datafixers.DataFixer; import com.mojang.logging.LogUtils; import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; -import java.io.Writer; import java.net.InetAddress; import java.net.Proxy; import java.nio.charset.StandardCharsets; @@ -48,113 +48,176 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameType; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.SkullBlockEntity; import net.minecraft.world.level.storage.LevelStorageSource; 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 ServerInterface { + static final Logger LOGGER = LogUtils.getLogger(); private static final int CONVERSION_RETRY_DELAY_MS = 5000; private static final int CONVERSION_RETRIES = 2; private final List consoleInput = Collections.synchronizedList(Lists.newArrayList()); @Nullable private QueryThreadGs4 queryThreadGs4; - private final RconConsoleSource rconConsoleSource; + // private final RemoteControlCommandListener rconConsoleSource; // CraftBukkit - remove field @Nullable private RconThread rconThread; - private final DedicatedServerSettings settings; + public DedicatedServerSettings settings; @Nullable private MinecraftServerGui gui; @Nullable private final TextFilterClient textFilterClient; - public DedicatedServer( - Thread serverThread, - LevelStorageSource.LevelStorageAccess storageSource, - PackRepository packRepository, - WorldStem worldStem, - DedicatedServerSettings settings, - DataFixer fixerUpper, - Services services, - ChunkProgressListenerFactory progressListenerFactory - ) { - super(serverThread, storageSource, packRepository, worldStem, Proxy.NO_PROXY, fixerUpper, services, progressListenerFactory); - this.settings = settings; - this.rconConsoleSource = new RconConsoleSource(this); - this.textFilterClient = TextFilterClient.createFromConfig(settings.getProperties().textFilteringConfig); + // CraftBukkit start - Signature changed + public DedicatedServer(joptsimple.OptionSet options, WorldLoader.a worldLoader, Thread thread, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PackRepository resourcepackrepository, WorldStem worldstem, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, Services services, ChunkProgressListenerFactory 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); // CraftBukkit - remove field + this.textFilterClient = TextFilterClient.createFromConfig(dedicatedserversettings.getProperties().textFilteringConfig); } @Override public boolean initServer() throws IOException { Thread thread = new Thread("Server console handler") { - @Override 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; - String string1; + // MC-33041, SPIGOT-5538: if System.in is not valid due to javaw, then return try { - while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning() && (string1 = bufferedReader.readLine()) != null) { - DedicatedServer.this.handleConsoleInput(string1, DedicatedServer.this.createCommandSourceStack()); + System.in.available(); + } catch (IOException ex) { + return; + } + // CraftBukkit end + + String s; + + try { + // 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 var4) { - DedicatedServer.LOGGER.error("Exception handling console input", (Throwable)var4); + } catch (IOException ioexception) { + DedicatedServer.LOGGER.error("Exception handling console input", ioexception); } + } }; + + // 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(LOGGER)); + thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER)); thread.start(); - LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().getName()); + DedicatedServer.LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().getName()); if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { - LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); + DedicatedServer.LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); } - LOGGER.info("Loading properties"); - DedicatedServerProperties properties = this.settings.getProperties(); + DedicatedServer.LOGGER.info("Loading properties"); + DedicatedServerProperties dedicatedserverproperties = this.settings.getProperties(); + if (this.isSingleplayer()) { this.setLocalIp("127.0.0.1"); } else { - this.setUsesAuthentication(properties.onlineMode); - this.setPreventProxyConnections(properties.preventProxyConnections); - this.setLocalIp(properties.serverIp); + this.setUsesAuthentication(dedicatedserverproperties.onlineMode); + this.setPreventProxyConnections(dedicatedserverproperties.preventProxyConnections); + this.setLocalIp(dedicatedserverproperties.serverIp); } - this.setPvpAllowed(properties.pvp); - this.setFlightAllowed(properties.allowFlight); - this.setMotd(properties.motd); - super.setPlayerIdleTimeout(properties.playerIdleTimeout.get()); - this.setEnforceWhitelist(properties.enforceWhitelist); - this.worldData.setGameType(properties.gamemode); - LOGGER.info("Default game type: {}", properties.gamemode); - InetAddress inetAddress = null; + this.setPvpAllowed(dedicatedserverproperties.pvp); + this.setFlightAllowed(dedicatedserverproperties.allowFlight); + this.setMotd(dedicatedserverproperties.motd); + super.setPlayerIdleTimeout((Integer) dedicatedserverproperties.playerIdleTimeout.get()); + this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist); + // this.worldData.setGameType(dedicatedserverproperties.gamemode); // CraftBukkit - moved to world loading + DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode); + InetAddress inetaddress = null; + if (!this.getLocalIp().isEmpty()) { - inetAddress = InetAddress.getByName(this.getLocalIp()); + inetaddress = InetAddress.getByName(this.getLocalIp()); } if (this.getPort() < 0) { - this.setPort(properties.serverPort); + this.setPort(dedicatedserverproperties.serverPort); } this.initializeKeyPair(); - LOGGER.info("Starting Minecraft server on {}:{}", this.getLocalIp().isEmpty() ? "*" : this.getLocalIp(), this.getPort()); + DedicatedServer.LOGGER.info("Starting Minecraft server on {}:{}", this.getLocalIp().isEmpty() ? "*" : this.getLocalIp(), this.getPort()); try { - this.getConnection().startTcpServerListener(inetAddress, this.getPort()); - } catch (IOException var10) { - LOGGER.warn("**** FAILED TO BIND TO PORT!"); - LOGGER.warn("The exception was: {}", var10.toString()); - LOGGER.warn("Perhaps a server is already running on that port?"); + this.getConnection().startTcpServerListener(inetaddress, this.getPort()); + } catch (IOException ioexception) { + DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!"); + DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString()); + DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?"); 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()) { - LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); - LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); - LOGGER.warn( - "While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose." - ); - LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); + DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); + DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); + DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); + DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); } if (this.convertOldUsers()) { @@ -164,40 +227,43 @@ if (!OldUsersConverter.serverReadyAfterUserconversion(this)) { return false; } else { - this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); - long nanos = Util.getNanos(); + // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // CraftBukkit - moved up + long i = Util.getNanos(); + SkullBlockEntity.setup(this.services, this); GameProfileCache.setUsesAuthentication(this.usesAuthentication()); - LOGGER.info("Preparing level \"{}\"", this.getLevelIdName()); - this.loadLevel(); - long l = Util.getNanos() - nanos; - String string = String.format(Locale.ROOT, "%.3fs", (double)l / 1.0E9); - LOGGER.info("Done ({})! For help, type \"help\"", string); - if (properties.announcePlayerAchievements != null) { - this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS).set(properties.announcePlayerAchievements, this); + DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getLevelIdName()); + this.loadLevel(storageSource.getLevelId()); // CraftBukkit + long j = Util.getNanos() - i; + String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D); + + DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); + if (dedicatedserverproperties.announcePlayerAchievements != null) { + ((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, this); } - if (properties.enableQuery) { - LOGGER.info("Starting GS4 status listener"); + if (dedicatedserverproperties.enableQuery) { + DedicatedServer.LOGGER.info("Starting GS4 status listener"); this.queryThreadGs4 = QueryThreadGs4.create(this); } - if (properties.enableRcon) { - LOGGER.info("Starting remote control listener"); + if (dedicatedserverproperties.enableRcon) { + DedicatedServer.LOGGER.info("Starting remote control listener"); this.rconThread = RconThread.create(this); } if (this.getMaxTickLength() > 0L) { Thread thread1 = new Thread(new ServerWatchdog(this)); - thread1.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandlerWithName(LOGGER)); + + thread1.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandlerWithName(DedicatedServer.LOGGER)); thread1.setName("Server Watchdog"); thread1.setDaemon(true); thread1.start(); } - if (properties.enableJmxMonitoring) { + if (dedicatedserverproperties.enableJmxMonitoring) { MinecraftServerStatistics.registerJmxMonitoring(this); - LOGGER.info("JMX monitoring enabled"); + DedicatedServer.LOGGER.info("JMX monitoring enabled"); } return true; @@ -236,29 +302,49 @@ @Override public SystemReport fillServerSystemReport(SystemReport report) { - report.setDetail("Is Modded", () -> this.getModdedStatus().fullDescription()); - report.setDetail("Type", () -> "Dedicated Server (map_server.txt)"); + report.setDetail("Is Modded", () -> { + return this.getModdedStatus().fullDescription(); + }); + report.setDetail("Type", () -> { + return "Dedicated Server (map_server.txt)"; + }); return report; } @Override public void dumpServerProperties(Path path) throws IOException { - DedicatedServerProperties properties = this.getProperties(); + DedicatedServerProperties dedicatedserverproperties = this.getProperties(); + BufferedWriter bufferedwriter = Files.newBufferedWriter(path); - try (Writer bufferedWriter = Files.newBufferedWriter(path)) { - bufferedWriter.write(String.format(Locale.ROOT, "sync-chunk-writes=%s%n", properties.syncChunkWrites)); - bufferedWriter.write(String.format(Locale.ROOT, "gamemode=%s%n", properties.gamemode)); - bufferedWriter.write(String.format(Locale.ROOT, "spawn-monsters=%s%n", properties.spawnMonsters)); - bufferedWriter.write(String.format(Locale.ROOT, "entity-broadcast-range-percentage=%d%n", properties.entityBroadcastRangePercentage)); - bufferedWriter.write(String.format(Locale.ROOT, "max-world-size=%d%n", properties.maxWorldSize)); - bufferedWriter.write(String.format(Locale.ROOT, "spawn-npcs=%s%n", properties.spawnNpcs)); - bufferedWriter.write(String.format(Locale.ROOT, "view-distance=%d%n", properties.viewDistance)); - bufferedWriter.write(String.format(Locale.ROOT, "simulation-distance=%d%n", properties.simulationDistance)); - bufferedWriter.write(String.format(Locale.ROOT, "spawn-animals=%s%n", properties.spawnAnimals)); - bufferedWriter.write(String.format(Locale.ROOT, "generate-structures=%s%n", properties.worldOptions.generateStructures())); - bufferedWriter.write(String.format(Locale.ROOT, "use-native=%s%n", properties.useNativeTransport)); - bufferedWriter.write(String.format(Locale.ROOT, "rate-limit=%d%n", properties.rateLimitPacketsPerSecond)); + try { + bufferedwriter.write(String.format(Locale.ROOT, "sync-chunk-writes=%s%n", dedicatedserverproperties.syncChunkWrites)); + bufferedwriter.write(String.format(Locale.ROOT, "gamemode=%s%n", dedicatedserverproperties.gamemode)); + bufferedwriter.write(String.format(Locale.ROOT, "spawn-monsters=%s%n", dedicatedserverproperties.spawnMonsters)); + bufferedwriter.write(String.format(Locale.ROOT, "entity-broadcast-range-percentage=%d%n", dedicatedserverproperties.entityBroadcastRangePercentage)); + bufferedwriter.write(String.format(Locale.ROOT, "max-world-size=%d%n", dedicatedserverproperties.maxWorldSize)); + bufferedwriter.write(String.format(Locale.ROOT, "spawn-npcs=%s%n", dedicatedserverproperties.spawnNpcs)); + bufferedwriter.write(String.format(Locale.ROOT, "view-distance=%d%n", dedicatedserverproperties.viewDistance)); + bufferedwriter.write(String.format(Locale.ROOT, "simulation-distance=%d%n", dedicatedserverproperties.simulationDistance)); + bufferedwriter.write(String.format(Locale.ROOT, "spawn-animals=%s%n", dedicatedserverproperties.spawnAnimals)); + bufferedwriter.write(String.format(Locale.ROOT, "generate-structures=%s%n", dedicatedserverproperties.worldOptions.generateStructures())); + bufferedwriter.write(String.format(Locale.ROOT, "use-native=%s%n", dedicatedserverproperties.useNativeTransport)); + bufferedwriter.write(String.format(Locale.ROOT, "rate-limit=%d%n", dedicatedserverproperties.rateLimitPacketsPerSecond)); + } catch (Throwable throwable) { + if (bufferedwriter != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable1) { + throwable.addSuppressed(throwable1); + } + } + + throw throwable; } + + if (bufferedwriter != null) { + bufferedwriter.close(); + } + } @Override @@ -278,6 +364,8 @@ if (this.queryThreadGs4 != null) { this.queryThreadGs4.stop(); } + + System.exit(0); // CraftBukkit } @Override @@ -297,9 +385,19 @@ public void handleConsoleInputs() { while (!this.consoleInput.isEmpty()) { - ConsoleInput consoleInput = this.consoleInput.remove(0); - this.getCommands().performPrefixedCommand(consoleInput.source, consoleInput.msg); + ConsoleInput servercommand = (ConsoleInput) this.consoleInput.remove(0); + + // CraftBukkit start - ServerCommand for preprocessing + ServerCommandEvent event = new ServerCommandEvent(console, servercommand.msg); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + servercommand = new ConsoleInput(event.getCommand(), servercommand.source); + + // this.getCommands().performPrefixedCommand(servercommand.source, servercommand.msg); // Called in dispatchServerCommand + server.dispatchServerCommand(console, servercommand); + // CraftBukkit end } + } @Override @@ -319,7 +417,7 @@ @Override public DedicatedPlayerList getPlayerList() { - return (DedicatedPlayerList)super.getPlayerList(); + return (DedicatedPlayerList) super.getPlayerList(); } @Override @@ -346,6 +444,7 @@ if (this.gui == null) { this.gui = MinecraftServerGui.showFrameFor(this); } + } @Override @@ -365,7 +464,7 @@ @Override public boolean isUnderSpawnProtection(ServerLevel level, BlockPos pos, Player player) { - if (level.dimension() != Level.OVERWORLD) { + if (level.dimension() != net.minecraft.world.level.Level.OVERWORLD) { return false; } else if (this.getPlayerList().getOps().isEmpty()) { return false; @@ -374,11 +473,12 @@ } else if (this.getSpawnProtectionRadius() <= 0) { return false; } else { - BlockPos sharedSpawnPos = level.getSharedSpawnPos(); - int abs = Mth.abs(pos.getX() - sharedSpawnPos.getX()); - int abs1 = Mth.abs(pos.getZ() - sharedSpawnPos.getZ()); - int max = Math.max(abs, abs1); - return max <= this.getSpawnProtectionRadius(); + BlockPos blockposition1 = level.getSharedSpawnPos(); + int i = Mth.abs(pos.getX() - blockposition1.getX()); + int j = Mth.abs(pos.getZ() - blockposition1.getZ()); + int k = Math.max(i, j); + + return k <= this.getSpawnProtectionRadius(); } } @@ -405,7 +505,9 @@ @Override public void setPlayerIdleTimeout(int idleTimeout) { super.setPlayerIdleTimeout(idleTimeout); - this.settings.update(dedicatedServerProperties -> dedicatedServerProperties.playerIdleTimeout.update(this.registryAccess(), idleTimeout)); + this.settings.update((dedicatedserverproperties) -> { + return (DedicatedServerProperties) dedicatedserverproperties.playerIdleTimeout.update(this.registryAccess(), idleTimeout); + }); } @Override @@ -430,8 +532,9 @@ @Override public boolean enforceSecureProfile() { - DedicatedServerProperties properties = this.getProperties(); - return properties.enforceSecureProfile && properties.onlineMode && this.services.canValidateProfileKeys(); + DedicatedServerProperties dedicatedserverproperties = this.getProperties(); + + return dedicatedserverproperties.enforceSecureProfile && dedicatedserverproperties.onlineMode && this.services.canValidateProfileKeys(); } @Override @@ -442,9 +545,11 @@ protected boolean convertOldUsers() { boolean flag = false; - for (int i = 0; !flag && i <= 2; i++) { + int i; + + for (i = 0; !flag && i <= 2; ++i) { if (i > 0) { - LOGGER.warn("Encountered a problem while converting the user banlist, retrying in a few seconds"); + DedicatedServer.LOGGER.warn("Encountered a problem while converting the user banlist, retrying in a few seconds"); this.waitForRetry(); } @@ -453,9 +558,9 @@ boolean flag1 = false; - for (int var7 = 0; !flag1 && var7 <= 2; var7++) { - if (var7 > 0) { - LOGGER.warn("Encountered a problem while converting the ip banlist, retrying in a few seconds"); + for (i = 0; !flag1 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the ip banlist, retrying in a few seconds"); this.waitForRetry(); } @@ -464,9 +569,9 @@ boolean flag2 = false; - for (int var8 = 0; !flag2 && var8 <= 2; var8++) { - if (var8 > 0) { - LOGGER.warn("Encountered a problem while converting the op list, retrying in a few seconds"); + for (i = 0; !flag2 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the op list, retrying in a few seconds"); this.waitForRetry(); } @@ -475,9 +580,9 @@ boolean flag3 = false; - for (int var9 = 0; !flag3 && var9 <= 2; var9++) { - if (var9 > 0) { - LOGGER.warn("Encountered a problem while converting the whitelist, retrying in a few seconds"); + for (i = 0; !flag3 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the whitelist, retrying in a few seconds"); this.waitForRetry(); } @@ -486,9 +591,9 @@ boolean flag4 = false; - for (int var10 = 0; !flag4 && var10 <= 2; var10++) { - if (var10 > 0) { - LOGGER.warn("Encountered a problem while converting the player save files, retrying in a few seconds"); + for (i = 0; !flag4 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the player save files, retrying in a few seconds"); this.waitForRetry(); } @@ -501,7 +606,8 @@ private void waitForRetry() { try { Thread.sleep(5000L); - } catch (InterruptedException var2) { + } catch (InterruptedException interruptedexception) { + ; } } @@ -516,18 +622,58 @@ @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 command) { - this.rconConsoleSource.prepareForCommand(); - this.executeBlocking(() -> this.getCommands().performPrefixedCommand(this.rconConsoleSource.createCommandSourceStack(), command)); - return this.rconConsoleSource.getCommandResponse(); + // CraftBukkit start - fire RemoteServerCommandEvent + throw new UnsupportedOperationException("Not supported - remote source required."); } + public String runCommand(RconConsoleSource rconConsoleSource, String s) { + rconConsoleSource.prepareForCommand(); + this.executeBlocking(() -> { + CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack(); + RemoteServerCommandEvent event = new RemoteServerCommandEvent(rconConsoleSource.getBukkitSender(wrapper), s); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), wrapper); + server.dispatchServerCommand(event.getSender(), serverCommand); + }); + return rconConsoleSource.getCommandResponse(); + // CraftBukkit end + } + public void storeUsingWhiteList(boolean isStoreUsingWhiteList) { - this.settings.update(dedicatedServerProperties -> dedicatedServerProperties.whiteList.update(this.registryAccess(), isStoreUsingWhiteList)); + this.settings.update((dedicatedserverproperties) -> { + return (DedicatedServerProperties) dedicatedserverproperties.whiteList.update(this.registryAccess(), isStoreUsingWhiteList); + }); } @Override @@ -572,4 +718,15 @@ public Optional getServerResourcePack() { return this.settings.getProperties().serverResourcePackInfo; } + + // CraftBukkit start + public boolean isDebugging() { + return this.getProperties().debug; + } + + @Override + public CommandSender getBukkitSender(CommandSourceStack wrapper) { + return console; + } + // CraftBukkit end }