From 57c683647f72d55fb6b46febe5ed5ba7cbfcfd02 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:22:36 +0100 Subject: [PATCH] reformat spigot package --- .../main/java/org/spigotmc/AsyncCatcher.java | 13 +- .../main/java/org/spigotmc/LimitStream.java | 27 +- .../src/main/java/org/spigotmc/Metrics.java | 641 ------------------ .../java/org/spigotmc/RestartCommand.java | 159 ++--- .../main/java/org/spigotmc/SpigotCommand.java | 16 +- .../main/java/org/spigotmc/SpigotConfig.java | 391 +++++------ .../java/org/spigotmc/SpigotWorldConfig.java | 408 +++++------ .../main/java/org/spigotmc/TickLimiter.java | 4 +- .../org/spigotmc/TicksPerSecondCommand.java | 64 +- .../main/java/org/spigotmc/TrackingRange.java | 4 +- .../java/org/spigotmc/WatchdogThread.java | 208 +++--- 11 files changed, 559 insertions(+), 1376 deletions(-) delete mode 100644 paper-server/src/main/java/org/spigotmc/Metrics.java diff --git a/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java b/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java index ef25987604..86fba4d18a 100644 --- a/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java +++ b/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java @@ -2,17 +2,14 @@ package org.spigotmc; import net.minecraft.server.MinecraftServer; -public class AsyncCatcher -{ +public class AsyncCatcher { public static boolean enabled = true; - public static void catchOp(String reason) - { - if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) - { - MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper - throw new IllegalStateException( "Asynchronous " + reason + "!" ); + public static void catchOp(String reason) { + if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) { + MinecraftServer.LOGGER.error("Thread {} failed main thread check: {}", Thread.currentThread().getName(), reason, new Throwable()); // Paper + throw new IllegalStateException("Asynchronous " + reason + "!"); } } } diff --git a/paper-server/src/main/java/org/spigotmc/LimitStream.java b/paper-server/src/main/java/org/spigotmc/LimitStream.java index 8de241a921..60e9ec374e 100644 --- a/paper-server/src/main/java/org/spigotmc/LimitStream.java +++ b/paper-server/src/main/java/org/spigotmc/LimitStream.java @@ -5,35 +5,30 @@ import java.io.IOException; import java.io.InputStream; import net.minecraft.nbt.NbtAccounter; -public class LimitStream extends FilterInputStream -{ +public class LimitStream extends FilterInputStream { private final NbtAccounter limit; - public LimitStream(InputStream is, NbtAccounter limit) - { - super( is ); + public LimitStream(InputStream is, NbtAccounter limit) { + super(is); this.limit = limit; } @Override - public int read() throws IOException - { - this.limit.accountBytes( 1 ); + public int read() throws IOException { + this.limit.accountBytes(1); return super.read(); } @Override - public int read(byte[] b) throws IOException - { - this.limit.accountBytes( b.length ); - return super.read( b ); + public int read(byte[] b) throws IOException { + this.limit.accountBytes(b.length); + return super.read(b); } @Override - public int read(byte[] b, int off, int len) throws IOException - { - this.limit.accountBytes( len ); - return super.read( b, off, len ); + public int read(byte[] b, int off, int len) throws IOException { + this.limit.accountBytes(len); + return super.read(b, off, len); } } diff --git a/paper-server/src/main/java/org/spigotmc/Metrics.java b/paper-server/src/main/java/org/spigotmc/Metrics.java deleted file mode 100644 index 0abb93bd40..0000000000 --- a/paper-server/src/main/java/org/spigotmc/Metrics.java +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright 2011-2013 Tyler Blair. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and contributors and should not be interpreted as representing official policies, - * either expressed or implied, of anybody else. - */ -package org.spigotmc; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.net.Proxy; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import net.minecraft.server.MinecraftServer; -import org.bukkit.Bukkit; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; - -/** - *

The metrics class obtains data about a plugin and submits statistics about it to the metrics backend.

- * Public methods provided by this class:

- * - * Graph createGraph(String name);
- * void addCustomData(BukkitMetrics.Plotter plotter);
- * void start();
- *
- */ -public class Metrics { - - /** - * The current revision number - */ - private static final int REVISION = 6; - /** - * The base url of the metrics domain - */ - private static final String BASE_URL = "https://mcstats.spigotmc.org"; - /** - * The url used to report a server's status - */ - private static final String REPORT_URL = "/report/%s"; - /** - * The separator to use for custom data. This MUST NOT change unless you are hosting your own version of metrics and - * want to change it. - */ - private static final String CUSTOM_DATA_SEPARATOR = "~~"; - /** - * Interval of time to ping (in minutes) - */ - private static final int PING_INTERVAL = 10; - /** - * All of the custom graphs to submit to metrics - */ - private final Set graphs = Collections.synchronizedSet(new HashSet()); - /** - * The default graph, used for addCustomData when you don't want a specific graph - */ - private final Graph defaultGraph = new Graph("Default"); - /** - * The plugin configuration file - */ - private final YamlConfiguration configuration; - /** - * The plugin configuration file - */ - private final File configurationFile; - /** - * Unique server id - */ - private final String guid; - /** - * Debug mode - */ - private final boolean debug; - /** - * Lock for synchronization - */ - private final Object optOutLock = new Object(); - /** - * The scheduled task - */ - private volatile Timer task = null; - - public Metrics() throws IOException { - // load the config - this.configurationFile = this.getConfigFile(); - this.configuration = YamlConfiguration.loadConfiguration(this.configurationFile); - - // add some defaults - this.configuration.addDefault("opt-out", false); - this.configuration.addDefault("guid", UUID.randomUUID().toString()); - this.configuration.addDefault("debug", false); - - // Do we need to create the file? - if (this.configuration.get("guid", null) == null) { - this.configuration.options().header("http://mcstats.org").copyDefaults(true); - this.configuration.save(this.configurationFile); - } - - // Load the guid then - this.guid = this.configuration.getString("guid"); - this.debug = this.configuration.getBoolean("debug", false); - } - - /** - * Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics - * website. Plotters can be added to the graph object returned. - * - * @param name The name of the graph - * @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given - */ - public Graph createGraph(final String name) { - if (name == null) { - throw new IllegalArgumentException("Graph name cannot be null"); - } - - // Construct the graph object - final Graph graph = new Graph(name); - - // Now we can add our graph - this.graphs.add(graph); - - // and return back - return graph; - } - - /** - * Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend - * - * @param graph The name of the graph - */ - public void addGraph(final Graph graph) { - if (graph == null) { - throw new IllegalArgumentException("Graph cannot be null"); - } - - this.graphs.add(graph); - } - - /** - * Adds a custom data plotter to the default graph - * - * @param plotter The plotter to use to plot custom data - */ - public void addCustomData(final Plotter plotter) { - if (plotter == null) { - throw new IllegalArgumentException("Plotter cannot be null"); - } - - // Add the plotter to the graph o/ - this.defaultGraph.addPlotter(plotter); - - // Ensure the default graph is included in the submitted graphs - this.graphs.add(this.defaultGraph); - } - - /** - * Start measuring statistics. This will immediately create an async repeating task as the plugin and send the - * initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200 - * ticks. - * - * @return True if statistics measuring is running, otherwise false. - */ - public boolean start() { - synchronized (this.optOutLock) { - // Did we opt out? - if (this.isOptOut()) { - return false; - } - - // Is metrics already running? - if (this.task != null) { - return true; - } - - // Begin hitting the server with glorious data - this.task = new Timer("Spigot Metrics Thread", true); - - this.task.scheduleAtFixedRate(new TimerTask() { - private boolean firstPost = true; - - public void run() { - try { - // This has to be synchronized or it can collide with the disable method. - synchronized (Metrics.this.optOutLock) { - // Disable Task, if it is running and the server owner decided to opt-out - if (Metrics.this.isOptOut() && Metrics.this.task != null) { - Metrics.this.task.cancel(); - Metrics.this.task = null; - // Tell all plotters to stop gathering information. - for (Graph graph : Metrics.this.graphs) { - graph.onOptOut(); - } - } - } - - // We use the inverse of firstPost because if it is the first time we are posting, - // it is not a interval ping, so it evaluates to FALSE - // Each time thereafter it will evaluate to TRUE, i.e PING! - Metrics.this.postPlugin(!this.firstPost); - - // After the first post we set firstPost to false - // Each post thereafter will be a ping - this.firstPost = false; - } catch (IOException e) { - if (Metrics.this.debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage()); - } - } - } - }, 0, TimeUnit.MINUTES.toMillis(Metrics.PING_INTERVAL)); - - return true; - } - } - - /** - * Has the server owner denied plugin metrics? - * - * @return true if metrics should be opted out of it - */ - public boolean isOptOut() { - synchronized (this.optOutLock) { - try { - // Reload the metrics file - this.configuration.load(this.getConfigFile()); - } catch (IOException ex) { - if (this.debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); - } - return true; - } catch (InvalidConfigurationException ex) { - if (this.debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); - } - return true; - } - return this.configuration.getBoolean("opt-out", false); - } - } - - /** - * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task. - * - * @throws java.io.IOException - */ - public void enable() throws IOException { - // This has to be synchronized or it can collide with the check in the task. - synchronized (this.optOutLock) { - // Check if the server owner has already set opt-out, if not, set it. - if (this.isOptOut()) { - this.configuration.set("opt-out", false); - this.configuration.save(this.configurationFile); - } - - // Enable Task, if it is not running - if (this.task == null) { - this.start(); - } - } - } - - /** - * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task. - * - * @throws java.io.IOException - */ - public void disable() throws IOException { - // This has to be synchronized or it can collide with the check in the task. - synchronized (this.optOutLock) { - // Check if the server owner has already set opt-out, if not, set it. - if (!this.isOptOut()) { - this.configuration.set("opt-out", true); - this.configuration.save(this.configurationFile); - } - - // Disable Task, if it is running - if (this.task != null) { - this.task.cancel(); - this.task = null; - } - } - } - - /** - * Gets the File object of the config file that should be used to store data such as the GUID and opt-out status - * - * @return the File object for the config file - */ - public File getConfigFile() { - // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use - // is to abuse the plugin object we already have - // plugin.getDataFolder() => base/plugins/PluginA/ - // pluginsFolder => base/plugins/ - // The base is not necessarily relative to the startup directory. - // File pluginsFolder = plugin.getDataFolder().getParentFile(); - - // return => base/plugins/PluginMetrics/config.yml - return new File(new File((File) MinecraftServer.getServer().options.valueOf("plugins"), "PluginMetrics"), "config.yml"); - } - - /** - * Generic method that posts a plugin to the metrics website - */ - private void postPlugin(final boolean isPing) throws IOException { - // Server software specific section - String pluginName = "Spigot"; - boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled - String pluginVersion = (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown"; - String serverVersion = Bukkit.getVersion(); - int playersOnline = Bukkit.getServer().getOnlinePlayers().size(); - - // END server software specific section -- all code below does not use any code outside of this class / Java - - // Construct the post data - final StringBuilder data = new StringBuilder(); - - // The plugin's description file containg all of the plugin data such as name, version, author, etc - data.append(Metrics.encode("guid")).append('=').append(Metrics.encode(this.guid)); - Metrics.encodeDataPair(data, "version", pluginVersion); - Metrics.encodeDataPair(data, "server", serverVersion); - Metrics.encodeDataPair(data, "players", Integer.toString(playersOnline)); - Metrics.encodeDataPair(data, "revision", String.valueOf(Metrics.REVISION)); - - // New data as of R6 - String osname = System.getProperty("os.name"); - String osarch = System.getProperty("os.arch"); - String osversion = System.getProperty("os.version"); - String java_version = System.getProperty("java.version"); - int coreCount = Runtime.getRuntime().availableProcessors(); - - // normalize os arch .. amd64 -> x86_64 - if (osarch.equals("amd64")) { - osarch = "x86_64"; - } - - Metrics.encodeDataPair(data, "osname", osname); - Metrics.encodeDataPair(data, "osarch", osarch); - Metrics.encodeDataPair(data, "osversion", osversion); - Metrics.encodeDataPair(data, "cores", Integer.toString(coreCount)); - Metrics.encodeDataPair(data, "online-mode", Boolean.toString(onlineMode)); - Metrics.encodeDataPair(data, "java_version", java_version); - - // If we're pinging, append it - if (isPing) { - Metrics.encodeDataPair(data, "ping", "true"); - } - - // Acquire a lock on the graphs, which lets us make the assumption we also lock everything - // inside of the graph (e.g plotters) - synchronized (this.graphs) { - final Iterator iter = this.graphs.iterator(); - - while (iter.hasNext()) { - final Graph graph = iter.next(); - - for (Plotter plotter : graph.getPlotters()) { - // The key name to send to the metrics server - // The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top - // Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME - final String key = String.format("C%s%s%s%s", Metrics.CUSTOM_DATA_SEPARATOR, graph.getName(), Metrics.CUSTOM_DATA_SEPARATOR, plotter.getColumnName()); - - // The value to send, which for the foreseeable future is just the string - // value of plotter.getValue() - final String value = Integer.toString(plotter.getValue()); - - // Add it to the http post data :) - Metrics.encodeDataPair(data, key, value); - } - } - } - - // Create the url - URL url = new URL(Metrics.BASE_URL + String.format(Metrics.REPORT_URL, Metrics.encode(pluginName))); - - // Connect to the website - URLConnection connection; - - // Mineshafter creates a socks proxy, so we can safely bypass it - // It does not reroute POST requests so we need to go around it - if (this.isMineshafterPresent()) { - connection = url.openConnection(Proxy.NO_PROXY); - } else { - connection = url.openConnection(); - } - - connection.setDoOutput(true); - - // Write the data - final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); - writer.write(data.toString()); - writer.flush(); - - // Now read the response - final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); - final String response = reader.readLine(); - - // close resources - writer.close(); - reader.close(); - - if (response == null || response.startsWith("ERR")) { - throw new IOException(response); //Throw the exception - } else { - // Is this the first update this hour? - if (response.contains("OK This is your first update this hour")) { - synchronized (this.graphs) { - final Iterator iter = this.graphs.iterator(); - - while (iter.hasNext()) { - final Graph graph = iter.next(); - - for (Plotter plotter : graph.getPlotters()) { - plotter.reset(); - } - } - } - } - } - } - - /** - * Check if mineshafter is present. If it is, we need to bypass it to send POST requests - * - * @return true if mineshafter is installed on the server - */ - private boolean isMineshafterPresent() { - try { - Class.forName("mineshafter.MineServer"); - return true; - } catch (Exception e) { - return false; - } - } - - /** - *

Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first key/value pair - * MUST be included manually, e.g:

- * - * StringBuffer data = new StringBuffer(); - * data.append(encode("guid")).append('=').append(encode(guid)); - * encodeDataPair(data, "version", description.getVersion()); - * - * - * @param buffer the stringbuilder to append the data pair onto - * @param key the key value - * @param value the value - */ - private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException { - buffer.append('&').append(Metrics.encode(key)).append('=').append(Metrics.encode(value)); - } - - /** - * Encode text as UTF-8 - * - * @param text the text to encode - * @return the encoded text, as UTF-8 - */ - private static String encode(final String text) throws UnsupportedEncodingException { - return URLEncoder.encode(text, "UTF-8"); - } - - /** - * Represents a custom graph on the website - */ - public static class Graph { - - /** - * The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is - * rejected - */ - private final String name; - /** - * The set of plotters that are contained within this graph - */ - private final Set plotters = new LinkedHashSet(); - - private Graph(final String name) { - this.name = name; - } - - /** - * Gets the graph's name - * - * @return the Graph's name - */ - public String getName() { - return this.name; - } - - /** - * Add a plotter to the graph, which will be used to plot entries - * - * @param plotter the plotter to add to the graph - */ - public void addPlotter(final Plotter plotter) { - this.plotters.add(plotter); - } - - /** - * Remove a plotter from the graph - * - * @param plotter the plotter to remove from the graph - */ - public void removePlotter(final Plotter plotter) { - this.plotters.remove(plotter); - } - - /** - * Gets an unmodifiable set of the plotter objects in the graph - * - * @return an unmodifiable {@link java.util.Set} of the plotter objects - */ - public Set getPlotters() { - return Collections.unmodifiableSet(this.plotters); - } - - @Override - public int hashCode() { - return this.name.hashCode(); - } - - @Override - public boolean equals(final Object object) { - if (!(object instanceof Graph)) { - return false; - } - - final Graph graph = (Graph) object; - return graph.name.equals(this.name); - } - - /** - * Called when the server owner decides to opt-out of BukkitMetrics while the server is running. - */ - protected void onOptOut() { - } - } - - /** - * Interface used to collect custom data for a plugin - */ - public abstract static class Plotter { - - /** - * The plot's name - */ - private final String name; - - /** - * Construct a plotter with the default plot name - */ - public Plotter() { - this("Default"); - } - - /** - * Construct a plotter with a specific plot name - * - * @param name the name of the plotter to use, which will show up on the website - */ - public Plotter(final String name) { - this.name = name; - } - - /** - * Get the current value for the plotted point. Since this function defers to an external function it may or may - * not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called - * from any thread so care should be taken when accessing resources that need to be synchronized. - * - * @return the current value for the point to be plotted. - */ - public abstract int getValue(); - - /** - * Get the column name for the plotted point - * - * @return the plotted point's column name - */ - public String getColumnName() { - return this.name; - } - - /** - * Called after the website graphs have been updated - */ - public void reset() { - } - - @Override - public int hashCode() { - return this.getColumnName().hashCode(); - } - - @Override - public boolean equals(final Object object) { - if (!(object instanceof Plotter)) { - return false; - } - - final Plotter plotter = (Plotter) object; - return plotter.name.equals(this.name) && plotter.getValue() == this.getValue(); - } - } -} diff --git a/paper-server/src/main/java/org/spigotmc/RestartCommand.java b/paper-server/src/main/java/org/spigotmc/RestartCommand.java index 39e56b95aa..b87f66ad04 100644 --- a/paper-server/src/main/java/org/spigotmc/RestartCommand.java +++ b/paper-server/src/main/java/org/spigotmc/RestartCommand.java @@ -1,115 +1,85 @@ package org.spigotmc; import java.io.File; -import java.util.List; +import java.util.Locale; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.util.CraftChatMessage; -public class RestartCommand extends Command -{ +public class RestartCommand extends Command { - public RestartCommand(String name) - { - super( name ); + public RestartCommand(String name) { + super(name); this.description = "Restarts the server"; this.usageMessage = "/restart"; - this.setPermission( "bukkit.command.restart" ); + this.setPermission("bukkit.command.restart"); } @Override - public boolean execute(CommandSender sender, String currentAlias, String[] args) - { - if ( this.testPermission( sender ) ) - { - MinecraftServer.getServer().processQueue.add( new Runnable() - { - @Override - public void run() - { - RestartCommand.restart(); - } - } ); + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (this.testPermission(sender)) { + MinecraftServer.getServer().processQueue.add(RestartCommand::restart); } return true; } - public static void restart() - { - RestartCommand.restart( SpigotConfig.restartScript ); + public static void restart() { + RestartCommand.restart(SpigotConfig.restartScript); } - private static void restart(final String restartScript) - { - AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us - try - { + private static void restart(final String restartScript) { + AsyncCatcher.enabled = false; // Disable async catcher in case it interferes with us + try { // Paper - extract method and cleanup - boolean isRestarting = addShutdownHook( restartScript ); - if ( isRestarting ) - { - System.out.println( "Attempting to restart with " + SpigotConfig.restartScript ); - } else - { - System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); + boolean isRestarting = addShutdownHook(restartScript); + if (isRestarting) { + System.out.println("Attempting to restart with " + SpigotConfig.restartScript); + } else { + System.out.println("Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server."); } // Stop the watchdog WatchdogThread.doStop(); - shutdownServer( isRestarting ); + shutdownServer(isRestarting); // Paper end - } catch ( Exception ex ) - { + } catch (Exception ex) { ex.printStackTrace(); } } // Paper start - sync copied from above with minor changes, async added - private static void shutdownServer(boolean isRestarting) - { - if ( MinecraftServer.getServer().isSameThread() ) - { + private static void shutdownServer(boolean isRestarting) { + if (MinecraftServer.getServer().isSameThread()) { // Kick all players - for ( ServerPlayer p : com.google.common.collect.ImmutableList.copyOf( MinecraftServer.getServer().getPlayerList().players ) ) - { - p.connection.disconnect( CraftChatMessage.fromStringOrEmpty( SpigotConfig.restartMessage, true ), org.bukkit.event.player.PlayerKickEvent.Cause.RESTART_COMMAND); // Paper - kick event reason (cause is never used)) + for (ServerPlayer p : com.google.common.collect.ImmutableList.copyOf(MinecraftServer.getServer().getPlayerList().players)) { + p.connection.disconnect(CraftChatMessage.fromStringOrEmpty(SpigotConfig.restartMessage, true), org.bukkit.event.player.PlayerKickEvent.Cause.RESTART_COMMAND); // Paper - kick event reason (cause is never used) } // Give the socket a chance to send the packets - try - { - Thread.sleep( 100 ); - } catch ( InterruptedException ex ) - { + try { + Thread.sleep(100); + } catch (InterruptedException ex) { } closeSocket(); // Actually shutdown - try - { + try { MinecraftServer.getServer().close(); // calls stop() - } catch ( Throwable t ) - { + } catch (Throwable t) { } // Actually stop the JVM - System.exit( 0 ); - - } else - { + System.exit(0); + } else { // Mark the server to shutdown at the end of the tick - MinecraftServer.getServer().safeShutdown( false, isRestarting ); + MinecraftServer.getServer().safeShutdown(false, isRestarting); // wait 10 seconds to see if we're actually going to try shutdown - try - { - Thread.sleep( 10000 ); - } - catch (InterruptedException ignored) - { - } + try { + Thread.sleep(10000); + } catch (InterruptedException ignored) {} // Check if we've actually hit a state where the server is going to safely shutdown // if we have, let the server stop as usual @@ -117,63 +87,46 @@ public class RestartCommand extends Command // If the server hasn't stopped by now, assume worse case and kill closeSocket(); - System.exit( 0 ); + System.exit(0); } } // Paper end // Paper - Split from moved code - private static void closeSocket() - { + private static void closeSocket() { // Close the socket so we can rebind with the new process MinecraftServer.getServer().getConnection().stop(); // Give time for it to kick in - try - { - Thread.sleep( 100 ); - } catch ( InterruptedException ex ) - { - } + try { + Thread.sleep(100); + } catch (InterruptedException ignored) {} } // Paper end // Paper start - copied from above and modified to return if the hook registered - private static boolean addShutdownHook(String restartScript) - { - String[] split = restartScript.split( " " ); - if ( split.length > 0 && new File( split[0] ).isFile() ) - { - Thread shutdownHook = new Thread() - { - @Override - public void run() - { - try - { - String os = System.getProperty( "os.name" ).toLowerCase(java.util.Locale.ENGLISH); - if ( os.contains( "win" ) ) - { - Runtime.getRuntime().exec( "cmd /c start " + restartScript ); - } else - { - Runtime.getRuntime().exec( "sh " + restartScript ); - } - } catch ( Exception e ) - { - e.printStackTrace(); + private static boolean addShutdownHook(String restartScript) { + String[] split = restartScript.split(" "); + if (split.length > 0 && new File(split[0]).isFile()) { + Thread shutdownHook = new Thread(() -> { + try { + String os = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); + if (os.contains("win")) { + Runtime.getRuntime().exec("cmd /c start " + restartScript); + } else { + Runtime.getRuntime().exec("sh " + restartScript); } + } catch (Exception e) { + e.printStackTrace(); } - }; + }); - shutdownHook.setDaemon( true ); - Runtime.getRuntime().addShutdownHook( shutdownHook ); + shutdownHook.setDaemon(true); + Runtime.getRuntime().addShutdownHook(shutdownHook); return true; - } else - { + } else { return false; } } // Paper end - } diff --git a/paper-server/src/main/java/org/spigotmc/SpigotCommand.java b/paper-server/src/main/java/org/spigotmc/SpigotCommand.java index ac0fd418fc..1b60abf5f5 100644 --- a/paper-server/src/main/java/org/spigotmc/SpigotCommand.java +++ b/paper-server/src/main/java/org/spigotmc/SpigotCommand.java @@ -1,12 +1,14 @@ package org.spigotmc; import java.io.File; +import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import static net.kyori.adventure.text.Component.text; + public class SpigotCommand extends Command { public SpigotCommand(String name) { @@ -21,13 +23,17 @@ public class SpigotCommand extends Command { if (!this.testPermission(sender)) return true; if (args.length != 1) { - sender.sendMessage(ChatColor.RED + "Usage: " + this.usageMessage); + sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED)); return false; } if (args[0].equals("reload")) { - Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues."); - Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server."); + Command.broadcastCommandMessage(sender, text().color(NamedTextColor.RED) + .append(text("Please note that this command is not supported and may cause issues.")) + .appendNewline() + .append(text("If you encounter any issues please use the /stop command to restart your server.")) + .build() + ); MinecraftServer console = MinecraftServer.getServer(); org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); @@ -36,7 +42,7 @@ public class SpigotCommand extends Command { } console.server.reloadCount++; - Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); + Command.broadcastCommandMessage(sender, text("Reload complete.", NamedTextColor.GREEN)); } return true; diff --git a/paper-server/src/main/java/org/spigotmc/SpigotConfig.java b/paper-server/src/main/java/org/spigotmc/SpigotConfig.java index 4dbb109d05..e0d4222a99 100644 --- a/paper-server/src/main/java/org/spigotmc/SpigotConfig.java +++ b/paper-server/src/main/java/org/spigotmc/SpigotConfig.java @@ -28,360 +28,289 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; -public class SpigotConfig -{ +public class SpigotConfig { private static File CONFIG_FILE; - private static final String HEADER = "This is the main configuration file for Spigot.\n" - + "As you can see, there's tons to configure. Some options may impact gameplay, so use\n" - + "with caution, and make sure you know what each option does before configuring.\n" - + "For a reference for any variable inside this file, check out the Spigot wiki at\n" - + "http://www.spigotmc.org/wiki/spigot-configuration/\n" - + "\n" - + "If you need help with the configuration or have any questions related to Spigot,\n" - + "join us at the Discord or drop by our forums and leave a post.\n" - + "\n" - + "Discord: https://www.spigotmc.org/go/discord\n" - + "Forums: http://www.spigotmc.org/\n"; + private static final String HEADER = """ + This is the main configuration file for Spigot. + As you can see, there's tons to configure. Some options may impact gameplay, so use + with caution, and make sure you know what each option does before configuring. + For a reference for any variable inside this file, check out the Spigot wiki at + http://www.spigotmc.org/wiki/spigot-configuration/ + + If you need help with the configuration or have any questions related to Spigot, + join us at the Discord or drop by our forums and leave a post. + + Discord: https://www.spigotmc.org/go/discord + Forums: http://www.spigotmc.org/ + """; /*========================================================================*/ public static YamlConfiguration config; static int version; static Map commands; /*========================================================================*/ - private static Metrics metrics; - public static void init(File configFile) - { + public static void init(File configFile) { SpigotConfig.CONFIG_FILE = configFile; SpigotConfig.config = new YamlConfiguration(); - try - { - SpigotConfig.config.load( SpigotConfig.CONFIG_FILE ); - } catch ( IOException ex ) - { - } catch ( InvalidConfigurationException ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Could not load spigot.yml, please correct your syntax errors", ex ); - throw Throwables.propagate( ex ); + try { + SpigotConfig.config.load(SpigotConfig.CONFIG_FILE); + } catch (IOException ignored) { + } catch (InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Could not load spigot.yml, please correct your syntax errors", ex); + throw Throwables.propagate(ex); } - SpigotConfig.config.options().header( SpigotConfig.HEADER ); - SpigotConfig.config.options().copyDefaults( true ); + SpigotConfig.config.options().header(SpigotConfig.HEADER); + SpigotConfig.config.options().copyDefaults(true); - SpigotConfig.commands = new HashMap(); - SpigotConfig.commands.put( "spigot", new SpigotCommand( "spigot" ) ); + SpigotConfig.commands = new HashMap<>(); + SpigotConfig.commands.put("spigot", new SpigotCommand("spigot")); - SpigotConfig.version = SpigotConfig.getInt( "config-version", 12 ); - SpigotConfig.set( "config-version", 12 ); - SpigotConfig.readConfig( SpigotConfig.class, null ); + SpigotConfig.version = SpigotConfig.getInt("config-version", 12); + SpigotConfig.set("config-version", 12); + SpigotConfig.readConfig(SpigotConfig.class, null); } - public static void registerCommands() - { - for ( Map.Entry entry : SpigotConfig.commands.entrySet() ) - { - MinecraftServer.getServer().server.getCommandMap().register( entry.getKey(), "Spigot", entry.getValue() ); + public static void registerCommands() { + for (Map.Entry entry : SpigotConfig.commands.entrySet()) { + MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Spigot", entry.getValue()); } - - /* // Paper - Replace with our own - if ( SpigotConfig.metrics == null ) - { - try - { - SpigotConfig.metrics = new Metrics(); - SpigotConfig.metrics.start(); - } catch ( IOException ex ) - { - Bukkit.getServer().getLogger().log( Level.SEVERE, "Could not start metrics service", ex ); - } - } - */ // Paper end } - public static void readConfig(Class clazz, Object instance) // Paper - package-private -> public - { - for ( Method method : clazz.getDeclaredMethods() ) - { - if ( Modifier.isPrivate( method.getModifiers() ) ) - { - if ( method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE ) - { - try - { - method.setAccessible( true ); - method.invoke( instance ); - } catch ( InvocationTargetException ex ) - { - throw Throwables.propagate( ex.getCause() ); - } catch ( Exception ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Error invoking " + method, ex ); + public static void readConfig(Class clazz, Object instance) { // Paper - package-private -> public + for (Method method : clazz.getDeclaredMethods()) { + if (Modifier.isPrivate(method.getModifiers())) { + if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) { + try { + method.setAccessible(true); + method.invoke(instance); + } catch (InvocationTargetException ex) { + throw Throwables.propagate(ex.getCause()); + } catch (Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex); } } } } - try - { - SpigotConfig.config.save( SpigotConfig.CONFIG_FILE ); - } catch ( IOException ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Could not save " + SpigotConfig.CONFIG_FILE, ex ); + try { + SpigotConfig.config.save(SpigotConfig.CONFIG_FILE); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Could not save " + SpigotConfig.CONFIG_FILE, ex); } } - private static void set(String path, Object val) - { - SpigotConfig.config.set( path, val ); + private static void set(String path, Object val) { + SpigotConfig.config.set(path, val); } - private static boolean getBoolean(String path, boolean def) - { - SpigotConfig.config.addDefault( path, def ); - return SpigotConfig.config.getBoolean( path, SpigotConfig.config.getBoolean( path ) ); + private static boolean getBoolean(String path, boolean def) { + SpigotConfig.config.addDefault(path, def); + return SpigotConfig.config.getBoolean(path, SpigotConfig.config.getBoolean(path)); } - private static int getInt(String path, int def) - { - SpigotConfig.config.addDefault( path, def ); - return SpigotConfig.config.getInt( path, SpigotConfig.config.getInt( path ) ); + private static int getInt(String path, int def) { + SpigotConfig.config.addDefault(path, def); + return SpigotConfig.config.getInt(path, SpigotConfig.config.getInt(path)); } - private static List getList(String path, T def) - { - SpigotConfig.config.addDefault( path, def ); - return (List) SpigotConfig.config.getList( path, SpigotConfig.config.getList( path ) ); + private static List getList(String path, T def) { + SpigotConfig.config.addDefault(path, def); + return (List) SpigotConfig.config.getList(path, SpigotConfig.config.getList(path)); } - private static String getString(String path, String def) - { - SpigotConfig.config.addDefault( path, def ); - return SpigotConfig.config.getString( path, SpigotConfig.config.getString( path ) ); + private static String getString(String path, String def) { + SpigotConfig.config.addDefault(path, def); + return SpigotConfig.config.getString(path, SpigotConfig.config.getString(path)); } - private static double getDouble(String path, double def) - { - SpigotConfig.config.addDefault( path, def ); - return SpigotConfig.config.getDouble( path, SpigotConfig.config.getDouble( path ) ); + private static double getDouble(String path, double def) { + SpigotConfig.config.addDefault(path, def); + return SpigotConfig.config.getDouble(path, SpigotConfig.config.getDouble(path)); } public static boolean logCommands; - private static void logCommands() - { - SpigotConfig.logCommands = SpigotConfig.getBoolean( "commands.log", true ); + private static void logCommands() { + SpigotConfig.logCommands = SpigotConfig.getBoolean("commands.log", true); } public static int tabComplete; public static boolean sendNamespaced; - private static void tabComplete() - { - if ( SpigotConfig.version < 6 ) - { - boolean oldValue = SpigotConfig.getBoolean( "commands.tab-complete", true ); - if ( oldValue ) - { - SpigotConfig.set( "commands.tab-complete", 0 ); - } else - { - SpigotConfig.set( "commands.tab-complete", -1 ); + private static void tabComplete() { + if (SpigotConfig.version < 6) { + boolean oldValue = SpigotConfig.getBoolean("commands.tab-complete", true); + if (oldValue) { + SpigotConfig.set("commands.tab-complete", 0); + } else { + SpigotConfig.set("commands.tab-complete", -1); } } - SpigotConfig.tabComplete = SpigotConfig.getInt( "commands.tab-complete", 0 ); - SpigotConfig.sendNamespaced = SpigotConfig.getBoolean( "commands.send-namespaced", true ); + SpigotConfig.tabComplete = SpigotConfig.getInt("commands.tab-complete", 0); + SpigotConfig.sendNamespaced = SpigotConfig.getBoolean("commands.send-namespaced", true); } public static String whitelistMessage; public static String unknownCommandMessage; public static String serverFullMessage; public static String outdatedClientMessage = "Outdated client! Please use {0}"; - public static String outdatedServerMessage = "Outdated server! I\'m still on {0}"; - private static String transform(String s) - { - return ChatColor.translateAlternateColorCodes( '&', s ).replaceAll( "\\\\n", "\n" ); + public static String outdatedServerMessage = "Outdated server! I'm still on {0}"; + + private static String transform(String s) { + return ChatColor.translateAlternateColorCodes('&', s).replaceAll("\\\\n", "\n"); } - private static void messages() - { - if (SpigotConfig.version < 8) - { - SpigotConfig.set( "messages.outdated-client", SpigotConfig.outdatedClientMessage ); - SpigotConfig.set( "messages.outdated-server", SpigotConfig.outdatedServerMessage ); + + private static void messages() { + if (SpigotConfig.version < 8) { + SpigotConfig.set("messages.outdated-client", SpigotConfig.outdatedClientMessage); + SpigotConfig.set("messages.outdated-server", SpigotConfig.outdatedServerMessage); } - SpigotConfig.whitelistMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.whitelist", "You are not whitelisted on this server!" ) ); - SpigotConfig.unknownCommandMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.unknown-command", "Unknown command. Type \"/help\" for help." ) ); - SpigotConfig.serverFullMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.server-full", "The server is full!" ) ); - SpigotConfig.outdatedClientMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.outdated-client", SpigotConfig.outdatedClientMessage ) ); - SpigotConfig.outdatedServerMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.outdated-server", SpigotConfig.outdatedServerMessage ) ); + SpigotConfig.whitelistMessage = SpigotConfig.transform(SpigotConfig.getString("messages.whitelist", "You are not whitelisted on this server!")); + SpigotConfig.unknownCommandMessage = SpigotConfig.transform(SpigotConfig.getString("messages.unknown-command", "Unknown command. Type \"/help\" for help.")); + SpigotConfig.serverFullMessage = SpigotConfig.transform(SpigotConfig.getString("messages.server-full", "The server is full!")); + SpigotConfig.outdatedClientMessage = SpigotConfig.transform(SpigotConfig.getString("messages.outdated-client", SpigotConfig.outdatedClientMessage)); + SpigotConfig.outdatedServerMessage = SpigotConfig.transform(SpigotConfig.getString("messages.outdated-server", SpigotConfig.outdatedServerMessage)); } public static int timeoutTime = 60; public static boolean restartOnCrash = true; public static String restartScript = "./start.sh"; public static String restartMessage; - private static void watchdog() - { - SpigotConfig.timeoutTime = SpigotConfig.getInt( "settings.timeout-time", SpigotConfig.timeoutTime ); - SpigotConfig.restartOnCrash = SpigotConfig.getBoolean( "settings.restart-on-crash", SpigotConfig.restartOnCrash ); - SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript ); - SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) ); - SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) ); - // WatchdogThread.doStart( SpigotConfig.timeoutTime, SpigotConfig.restartOnCrash ); // Paper - moved to after paper config initialization + private static void watchdog() { + SpigotConfig.timeoutTime = SpigotConfig.getInt("settings.timeout-time", SpigotConfig.timeoutTime); + SpigotConfig.restartOnCrash = SpigotConfig.getBoolean("settings.restart-on-crash", SpigotConfig.restartOnCrash); + SpigotConfig.restartScript = SpigotConfig.getString("settings.restart-script", SpigotConfig.restartScript); + SpigotConfig.restartMessage = SpigotConfig.transform(SpigotConfig.getString("messages.restart", "Server is restarting")); + SpigotConfig.commands.put("restart", new RestartCommand("restart")); } public static boolean bungee; private static void bungee() { - if ( SpigotConfig.version < 4 ) - { - SpigotConfig.set( "settings.bungeecord", false ); - System.out.println( "Outdated config, disabling BungeeCord support!" ); + if (SpigotConfig.version < 4) { + SpigotConfig.set("settings.bungeecord", false); + System.out.println("Outdated config, disabling BungeeCord support!"); } - SpigotConfig.bungee = SpigotConfig.getBoolean( "settings.bungeecord", false ); + SpigotConfig.bungee = SpigotConfig.getBoolean("settings.bungeecord", false); } - private static void nettyThreads() - { - int count = SpigotConfig.getInt( "settings.netty-threads", 4 ); - System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) ); - Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); + private static void nettyThreads() { + int count = SpigotConfig.getInt("settings.netty-threads", 4); + System.setProperty("io.netty.eventLoopThreads", Integer.toString(count)); + Bukkit.getLogger().log(Level.INFO, "Using {0} threads for Netty based IO", count); } public static boolean disableStatSaving; public static Map forcedStats = new HashMap<>(); - private static void stats() - { - SpigotConfig.disableStatSaving = SpigotConfig.getBoolean( "stats.disable-saving", false ); - if ( !SpigotConfig.config.contains( "stats.forced-stats" ) ) { - SpigotConfig.config.createSection( "stats.forced-stats" ); + private static void stats() { + SpigotConfig.disableStatSaving = SpigotConfig.getBoolean("stats.disable-saving", false); + + if (!SpigotConfig.config.contains("stats.forced-stats")) { + SpigotConfig.config.createSection("stats.forced-stats"); } - ConfigurationSection section = SpigotConfig.config.getConfigurationSection( "stats.forced-stats" ); - for ( String name : section.getKeys( true ) ) - { - if ( section.isInt( name ) ) - { - try - { - ResourceLocation key = ResourceLocation.parse( name ); - if ( BuiltInRegistries.CUSTOM_STAT.get( key ) == null ) - { + ConfigurationSection section = SpigotConfig.config.getConfigurationSection("stats.forced-stats"); + for (String name : section.getKeys(true)) { + if (section.isInt(name)) { + try { + ResourceLocation key = ResourceLocation.parse(name); + if (BuiltInRegistries.CUSTOM_STAT.get(key) == null) { Bukkit.getLogger().log(Level.WARNING, "Ignoring non existent stats.forced-stats " + name); continue; } - SpigotConfig.forcedStats.put( key, section.getInt( name ) ); - } catch (Exception ex) - { + SpigotConfig.forcedStats.put(key, section.getInt(name)); + } catch (Exception ex) { Bukkit.getLogger().log(Level.WARNING, "Ignoring invalid stats.forced-stats " + name); } } } } - private static void tpsCommand() - { - SpigotConfig.commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); + private static void tpsCommand() { + SpigotConfig.commands.put("tps", new TicksPerSecondCommand("tps")); } public static int playerSample; - private static void playerSample() - { - SpigotConfig.playerSample = Math.max( SpigotConfig.getInt( "settings.sample-count", 12 ), 0 ); // Paper - Avoid negative counts - Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger + private static void playerSample() { + SpigotConfig.playerSample = Math.max(SpigotConfig.getInt("settings.sample-count", 12), 0); // Paper - Avoid negative counts + Bukkit.getLogger().log(Level.INFO, "Server Ping Player Sample Count: {0}", playerSample); // Paper - Use logger } public static int playerShuffle; - private static void playerShuffle() - { - SpigotConfig.playerShuffle = SpigotConfig.getInt( "settings.player-shuffle", 0 ); + private static void playerShuffle() { + SpigotConfig.playerShuffle = SpigotConfig.getInt("settings.player-shuffle", 0); } public static List spamExclusions; - private static void spamExclusions() - { - SpigotConfig.spamExclusions = SpigotConfig.getList( "commands.spam-exclusions", Arrays.asList( new String[] - { - "/skill" - } ) ); + private static void spamExclusions() { + SpigotConfig.spamExclusions = SpigotConfig.getList("commands.spam-exclusions", List.of("/skill")); } public static boolean silentCommandBlocks; - private static void silentCommandBlocks() - { - SpigotConfig.silentCommandBlocks = SpigotConfig.getBoolean( "commands.silent-commandblock-console", false ); + private static void silentCommandBlocks() { + SpigotConfig.silentCommandBlocks = SpigotConfig.getBoolean("commands.silent-commandblock-console", false); } public static Set replaceCommands; - private static void replaceCommands() - { - if ( SpigotConfig.config.contains( "replace-commands" ) ) - { - SpigotConfig.set( "commands.replace-commands", SpigotConfig.config.getStringList( "replace-commands" ) ); - SpigotConfig.config.set( "replace-commands", null ); + private static void replaceCommands() { + if (SpigotConfig.config.contains("replace-commands")) { + SpigotConfig.set("commands.replace-commands", SpigotConfig.config.getStringList("replace-commands")); + SpigotConfig.config.set("replace-commands", null); } - SpigotConfig.replaceCommands = new HashSet( (List) SpigotConfig.getList( "commands.replace-commands", - Arrays.asList( "setblock", "summon", "testforblock", "tellraw" ) ) ); + SpigotConfig.replaceCommands = new HashSet<>(SpigotConfig.getList("commands.replace-commands", + Arrays.asList("setblock", "summon", "testforblock", "tellraw"))); } public static int userCacheCap; - private static void userCacheCap() - { - SpigotConfig.userCacheCap = SpigotConfig.getInt( "settings.user-cache-size", 1000 ); + private static void userCacheCap() { + SpigotConfig.userCacheCap = SpigotConfig.getInt("settings.user-cache-size", 1000); } public static boolean saveUserCacheOnStopOnly; - private static void saveUserCacheOnStopOnly() - { - SpigotConfig.saveUserCacheOnStopOnly = SpigotConfig.getBoolean( "settings.save-user-cache-on-stop-only", false ); + private static void saveUserCacheOnStopOnly() { + SpigotConfig.saveUserCacheOnStopOnly = SpigotConfig.getBoolean("settings.save-user-cache-on-stop-only", false); } public static double movedWronglyThreshold; - private static void movedWronglyThreshold() - { - SpigotConfig.movedWronglyThreshold = SpigotConfig.getDouble( "settings.moved-wrongly-threshold", 0.0625D ); + private static void movedWronglyThreshold() { + SpigotConfig.movedWronglyThreshold = SpigotConfig.getDouble("settings.moved-wrongly-threshold", 0.0625D); } public static double movedTooQuicklyMultiplier; - private static void movedTooQuicklyMultiplier() - { - SpigotConfig.movedTooQuicklyMultiplier = SpigotConfig.getDouble( "settings.moved-too-quickly-multiplier", 10.0D ); + private static void movedTooQuicklyMultiplier() { + SpigotConfig.movedTooQuicklyMultiplier = SpigotConfig.getDouble("settings.moved-too-quickly-multiplier", 10.0D); } public static double maxAbsorption = 2048; - public static double maxHealth = 2048; - public static double movementSpeed = 2048; + public static double maxHealth = 1024; + public static double movementSpeed = 1024; public static double attackDamage = 2048; - private static void attributeMaxes() - { - SpigotConfig.maxAbsorption = SpigotConfig.getDouble( "settings.attribute.maxAbsorption.max", SpigotConfig.maxAbsorption ); - ( (RangedAttribute) Attributes.MAX_ABSORPTION.value() ).maxValue = SpigotConfig.maxAbsorption; - SpigotConfig.maxHealth = SpigotConfig.getDouble( "settings.attribute.maxHealth.max", SpigotConfig.maxHealth ); - ( (RangedAttribute) Attributes.MAX_HEALTH.value() ).maxValue = SpigotConfig.maxHealth; - SpigotConfig.movementSpeed = SpigotConfig.getDouble( "settings.attribute.movementSpeed.max", SpigotConfig.movementSpeed ); - ( (RangedAttribute) Attributes.MOVEMENT_SPEED.value() ).maxValue = SpigotConfig.movementSpeed; - SpigotConfig.attackDamage = SpigotConfig.getDouble( "settings.attribute.attackDamage.max", SpigotConfig.attackDamage ); - ( (RangedAttribute) Attributes.ATTACK_DAMAGE.value() ).maxValue = SpigotConfig.attackDamage; + private static void attributeMaxes() { + SpigotConfig.maxAbsorption = SpigotConfig.getDouble("settings.attribute.maxAbsorption.max", SpigotConfig.maxAbsorption); + ((RangedAttribute) Attributes.MAX_ABSORPTION.value()).maxValue = SpigotConfig.maxAbsorption; + SpigotConfig.maxHealth = SpigotConfig.getDouble("settings.attribute.maxHealth.max", SpigotConfig.maxHealth); + ((RangedAttribute) Attributes.MAX_HEALTH.value()).maxValue = SpigotConfig.maxHealth; + SpigotConfig.movementSpeed = SpigotConfig.getDouble("settings.attribute.movementSpeed.max", SpigotConfig.movementSpeed); + ((RangedAttribute) Attributes.MOVEMENT_SPEED.value()).maxValue = SpigotConfig.movementSpeed; + SpigotConfig.attackDamage = SpigotConfig.getDouble("settings.attribute.attackDamage.max", SpigotConfig.attackDamage); + ((RangedAttribute) Attributes.ATTACK_DAMAGE.value()).maxValue = SpigotConfig.attackDamage; } public static boolean debug; - private static void debug() - { - SpigotConfig.debug = SpigotConfig.getBoolean( "settings.debug", false ); + private static void debug() { + SpigotConfig.debug = SpigotConfig.getBoolean("settings.debug", false); - if ( SpigotConfig.debug && !LogManager.getRootLogger().isTraceEnabled() ) - { + if (SpigotConfig.debug && !LogManager.getRootLogger().isTraceEnabled()) { // Enable debug logging - LoggerContext ctx = (LoggerContext) LogManager.getContext( false ); + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration conf = ctx.getConfiguration(); - conf.getLoggerConfig( LogManager.ROOT_LOGGER_NAME ).setLevel( org.apache.logging.log4j.Level.ALL ); - ctx.updateLoggers( conf ); + conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(org.apache.logging.log4j.Level.ALL); + ctx.updateLoggers(conf); } - if ( LogManager.getRootLogger().isTraceEnabled() ) - { - Bukkit.getLogger().info( "Debug logging is enabled" ); - } else - { - // Bukkit.getLogger().info( "Debug logging is disabled" ); // Paper - Don't log if debug logging isn't enabled. + if (LogManager.getRootLogger().isTraceEnabled()) { + Bukkit.getLogger().info("Debug logging is enabled"); } } @@ -389,7 +318,7 @@ public class SpigotConfig public static List disabledAdvancements; private static void disabledAdvancements() { SpigotConfig.disableAdvancementSaving = SpigotConfig.getBoolean("advancements.disable-saving", false); - SpigotConfig.disabledAdvancements = SpigotConfig.getList("advancements.disabled", Arrays.asList(new String[]{"minecraft:story/disabled"})); + SpigotConfig.disabledAdvancements = SpigotConfig.getList("advancements.disabled", List.of("minecraft:story/disabled")); } public static boolean logVillagerDeaths; diff --git a/paper-server/src/main/java/org/spigotmc/SpigotWorldConfig.java b/paper-server/src/main/java/org/spigotmc/SpigotWorldConfig.java index 2c408fa4ab..89e2adbc1e 100644 --- a/paper-server/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/paper-server/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -4,86 +4,73 @@ import java.util.List; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; -public class SpigotWorldConfig -{ +public class SpigotWorldConfig { private final String worldName; private final YamlConfiguration config; private boolean verbose; - public SpigotWorldConfig(String worldName) - { + public SpigotWorldConfig(String worldName) { this.worldName = worldName; this.config = SpigotConfig.config; this.init(); } - public void init() - { - this.verbose = this.getBoolean( "verbose", false ); // Paper + public void init() { + this.verbose = this.getBoolean("verbose", false); // Paper - this.log( "-------- World Settings For [" + this.worldName + "] --------" ); - SpigotConfig.readConfig( SpigotWorldConfig.class, this ); + this.log("-------- World Settings For [" + this.worldName + "] --------"); + SpigotConfig.readConfig(SpigotWorldConfig.class, this); } - private void log(String s) - { - if ( this.verbose ) - { - Bukkit.getLogger().info( s ); + private void log(String s) { + if (this.verbose) { + Bukkit.getLogger().info(s); } } - private void set(String path, Object val) - { - this.config.set( "world-settings.default." + path, val ); + private void set(String path, Object val) { + this.config.set("world-settings.default." + path, val); } - public boolean getBoolean(String path, boolean def) - { - this.config.addDefault( "world-settings.default." + path, def ); - return this.config.getBoolean( "world-settings." + this.worldName + "." + path, this.config.getBoolean( "world-settings.default." + path ) ); + public boolean getBoolean(String path, boolean def) { + this.config.addDefault("world-settings.default." + path, def); + return this.config.getBoolean("world-settings." + this.worldName + "." + path, this.config.getBoolean("world-settings.default." + path)); } - public double getDouble(String path, double def) - { - this.config.addDefault( "world-settings.default." + path, def ); - return this.config.getDouble( "world-settings." + this.worldName + "." + path, this.config.getDouble( "world-settings.default." + path ) ); + public double getDouble(String path, double def) { + this.config.addDefault("world-settings.default." + path, def); + return this.config.getDouble("world-settings." + this.worldName + "." + path, this.config.getDouble("world-settings.default." + path)); } - public int getInt(String path) - { - return this.config.getInt( "world-settings." + this.worldName + "." + path ); + public int getInt(String path) { + return this.config.getInt("world-settings." + this.worldName + "." + path); } - public int getInt(String path, int def) - { + public int getInt(String path, int def) { // Paper start - get int without setting default return this.getInt(path, def, true); } - public int getInt(String path, int def, boolean setDef) - { - if (setDef) this.config.addDefault( "world-settings.default." + path, def ); - return this.config.getInt( "world-settings." + this.worldName + "." + path, this.config.getInt( "world-settings.default." + path, def ) ); + + public int getInt(String path, int def, boolean setDef) { + if (setDef) this.config.addDefault("world-settings.default." + path, def); + return this.config.getInt("world-settings." + this.worldName + "." + path, this.config.getInt("world-settings.default." + path, def)); // Paper end } - public List getList(String path, T def) - { - this.config.addDefault( "world-settings.default." + path, def ); - return (List) this.config.getList( "world-settings." + this.worldName + "." + path, this.config.getList( "world-settings.default." + path ) ); + public List getList(String path, T def) { + this.config.addDefault("world-settings.default." + path, def); + return (List) this.config.getList("world-settings." + this.worldName + "." + path, this.config.getList("world-settings.default." + path)); } - public String getString(String path, String def) - { - this.config.addDefault( "world-settings.default." + path, def ); - return this.config.getString( "world-settings." + this.worldName + "." + path, this.config.getString( "world-settings.default." + path ) ); + public String getString(String path, String def) { + this.config.addDefault("world-settings.default." + path, def); + return this.config.getString("world-settings." + this.worldName + "." + path, this.config.getString("world-settings.default." + path)); } - private Object get(String path, Object def) - { - this.config.addDefault( "world-settings.default." + path, def ); - return this.config.get( "world-settings." + this.worldName + "." + path, this.config.get( "world-settings.default." + path ) ); + private Object get(String path, Object def) { + this.config.addDefault("world-settings.default." + path, def); + return this.config.get("world-settings." + this.worldName + "." + path, this.config.get("world-settings.default." + path)); } // Crop growth rates @@ -109,102 +96,92 @@ public class SpigotWorldConfig public int caveVinesModifier; public int glowBerryModifier; // Paper public int pitcherPlantModifier; // Paper - private int getAndValidateGrowth(String crop) - { - int modifier = this.getInt( "growth." + crop.toLowerCase(java.util.Locale.ENGLISH) + "-modifier", 100 ); - if ( modifier == 0 ) - { - this.log( "Cannot set " + crop + " growth to zero, defaulting to 100" ); + + private int getAndValidateGrowth(String crop) { + int modifier = this.getInt("growth." + crop.toLowerCase(java.util.Locale.ENGLISH) + "-modifier", 100); + if (modifier == 0) { + this.log("Cannot set " + crop + " growth to zero, defaulting to 100"); modifier = 100; } - this.log( crop + " Growth Modifier: " + modifier + "%" ); + this.log(crop + " Growth Modifier: " + modifier + "%"); return modifier; } - private void growthModifiers() - { - this.cactusModifier = this.getAndValidateGrowth( "Cactus" ); - this.caneModifier = this.getAndValidateGrowth( "Cane" ); - this.melonModifier = this.getAndValidateGrowth( "Melon" ); - this.mushroomModifier = this.getAndValidateGrowth( "Mushroom" ); - this.pumpkinModifier = this.getAndValidateGrowth( "Pumpkin" ); - this.saplingModifier = this.getAndValidateGrowth( "Sapling" ); - this.beetrootModifier = this.getAndValidateGrowth( "Beetroot" ); - this.carrotModifier = this.getAndValidateGrowth( "Carrot" ); - this.potatoModifier = this.getAndValidateGrowth( "Potato" ); + + private void growthModifiers() { + this.cactusModifier = this.getAndValidateGrowth("Cactus"); + this.caneModifier = this.getAndValidateGrowth("Cane"); + this.melonModifier = this.getAndValidateGrowth("Melon"); + this.mushroomModifier = this.getAndValidateGrowth("Mushroom"); + this.pumpkinModifier = this.getAndValidateGrowth("Pumpkin"); + this.saplingModifier = this.getAndValidateGrowth("Sapling"); + this.beetrootModifier = this.getAndValidateGrowth("Beetroot"); + this.carrotModifier = this.getAndValidateGrowth("Carrot"); + this.potatoModifier = this.getAndValidateGrowth("Potato"); this.torchFlowerModifier = this.getAndValidateGrowth("TorchFlower"); // Paper - this.wheatModifier = this.getAndValidateGrowth( "Wheat" ); - this.wartModifier = this.getAndValidateGrowth( "NetherWart" ); - this.vineModifier = this.getAndValidateGrowth( "Vine" ); - this.cocoaModifier = this.getAndValidateGrowth( "Cocoa" ); - this.bambooModifier = this.getAndValidateGrowth( "Bamboo" ); - this.sweetBerryModifier = this.getAndValidateGrowth( "SweetBerry" ); - this.kelpModifier = this.getAndValidateGrowth( "Kelp" ); - this.twistingVinesModifier = this.getAndValidateGrowth( "TwistingVines" ); - this.weepingVinesModifier = this.getAndValidateGrowth( "WeepingVines" ); - this.caveVinesModifier = this.getAndValidateGrowth( "CaveVines" ); + this.wheatModifier = this.getAndValidateGrowth("Wheat"); + this.wartModifier = this.getAndValidateGrowth("NetherWart"); + this.vineModifier = this.getAndValidateGrowth("Vine"); + this.cocoaModifier = this.getAndValidateGrowth("Cocoa"); + this.bambooModifier = this.getAndValidateGrowth("Bamboo"); + this.sweetBerryModifier = this.getAndValidateGrowth("SweetBerry"); + this.kelpModifier = this.getAndValidateGrowth("Kelp"); + this.twistingVinesModifier = this.getAndValidateGrowth("TwistingVines"); + this.weepingVinesModifier = this.getAndValidateGrowth("WeepingVines"); + this.caveVinesModifier = this.getAndValidateGrowth("CaveVines"); this.glowBerryModifier = this.getAndValidateGrowth("GlowBerry"); // Paper this.pitcherPlantModifier = this.getAndValidateGrowth("PitcherPlant"); // Paper } public double itemMerge; - private void itemMerge() - { - this.itemMerge = this.getDouble("merge-radius.item", 0.5 ); - this.log( "Item Merge Radius: " + this.itemMerge ); + private void itemMerge() { + this.itemMerge = this.getDouble("merge-radius.item", 0.5); + this.log("Item Merge Radius: " + this.itemMerge); } public double expMerge; - private void expMerge() - { - this.expMerge = this.getDouble("merge-radius.exp", -1 ); - this.log( "Experience Merge Radius: " + this.expMerge ); + private void expMerge() { + this.expMerge = this.getDouble("merge-radius.exp", -1); + this.log("Experience Merge Radius: " + this.expMerge); } public int viewDistance; - private void viewDistance() - { - if ( SpigotConfig.version < 12 ) - { - this.set( "view-distance", null ); + private void viewDistance() { + if (SpigotConfig.version < 12) { + this.set("view-distance", null); } - Object viewDistanceObject = this.get( "view-distance", "default" ); - this.viewDistance = ( viewDistanceObject ) instanceof Number ? ( (Number) viewDistanceObject ).intValue() : -1; - if ( this.viewDistance <= 0 ) - { + Object viewDistanceObject = this.get("view-distance", "default"); + this.viewDistance = (viewDistanceObject) instanceof Number ? ((Number) viewDistanceObject).intValue() : -1; + if (this.viewDistance <= 0) { this.viewDistance = Bukkit.getViewDistance(); } - this.viewDistance = Math.max( Math.min( this.viewDistance, 32 ), 3 ); - this.log( "View Distance: " + this.viewDistance ); + this.viewDistance = Math.max(Math.min(this.viewDistance, 32), 3); + this.log("View Distance: " + this.viewDistance); } public int simulationDistance; - private void simulationDistance() - { - Object simulationDistanceObject = this.get( "simulation-distance", "default" ); - this.simulationDistance = ( simulationDistanceObject ) instanceof Number ? ( (Number) simulationDistanceObject ).intValue() : -1; - if ( this.simulationDistance <= 0 ) - { + private void simulationDistance() { + Object simulationDistanceObject = this.get("simulation-distance", "default"); + this.simulationDistance = (simulationDistanceObject) instanceof Number ? ((Number) simulationDistanceObject).intValue() : -1; + if (this.simulationDistance <= 0) { this.simulationDistance = Bukkit.getSimulationDistance(); } - this.log( "Simulation Distance: " + this.simulationDistance ); + this.log("Simulation Distance: " + this.simulationDistance); } public byte mobSpawnRange; - private void mobSpawnRange() - { - this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla - this.log( "Mob Spawn Range: " + this.mobSpawnRange ); + private void mobSpawnRange() { + this.mobSpawnRange = (byte) getInt("mob-spawn-range", 8); // Paper - Vanilla + this.log("Mob Spawn Range: " + this.mobSpawnRange); } public int itemDespawnRate; - private void itemDespawnRate() - { - this.itemDespawnRate = this.getInt( "item-despawn-rate", 6000 ); - this.log( "Item Despawn Rate: " + this.itemDespawnRate ); + private void itemDespawnRate() { + this.itemDespawnRate = this.getInt("item-despawn-rate", 6000); + this.log("Item Despawn Rate: " + this.itemDespawnRate); } public int animalActivationRange = 32; @@ -216,34 +193,34 @@ public class SpigotWorldConfig public int waterActivationRange = 16; public int villagerActivationRange = 32; public int wakeUpInactiveAnimals = 4; - public int wakeUpInactiveAnimalsEvery = 60*20; - public int wakeUpInactiveAnimalsFor = 5*20; + public int wakeUpInactiveAnimalsEvery = 60 * 20; + public int wakeUpInactiveAnimalsFor = 5 * 20; public int wakeUpInactiveMonsters = 8; - public int wakeUpInactiveMonstersEvery = 20*20; - public int wakeUpInactiveMonstersFor = 5*20; + public int wakeUpInactiveMonstersEvery = 20 * 20; + public int wakeUpInactiveMonstersFor = 5 * 20; public int wakeUpInactiveVillagers = 4; - public int wakeUpInactiveVillagersEvery = 30*20; - public int wakeUpInactiveVillagersFor = 5*20; + public int wakeUpInactiveVillagersEvery = 30 * 20; + public int wakeUpInactiveVillagersFor = 5 * 20; public int wakeUpInactiveFlying = 8; - public int wakeUpInactiveFlyingEvery = 10*20; - public int wakeUpInactiveFlyingFor = 5*20; - public int villagersWorkImmunityAfter = 5*20; + public int wakeUpInactiveFlyingEvery = 10 * 20; + public int wakeUpInactiveFlyingFor = 5 * 20; + public int villagersWorkImmunityAfter = 5 * 20; public int villagersWorkImmunityFor = 20; public boolean villagersActiveForPanic = true; // Paper end public boolean tickInactiveVillagers = true; public boolean ignoreSpectatorActivation = false; - private void activationRange() - { + + private void activationRange() { boolean hasAnimalsConfig = config.getInt("entity-activation-range.animals", this.animalActivationRange) != this.animalActivationRange; // Paper - this.animalActivationRange = this.getInt( "entity-activation-range.animals", this.animalActivationRange ); - this.monsterActivationRange = this.getInt( "entity-activation-range.monsters", this.monsterActivationRange ); - this.raiderActivationRange = this.getInt( "entity-activation-range.raiders", this.raiderActivationRange ); - this.miscActivationRange = this.getInt( "entity-activation-range.misc", this.miscActivationRange ); + this.animalActivationRange = this.getInt("entity-activation-range.animals", this.animalActivationRange); + this.monsterActivationRange = this.getInt("entity-activation-range.monsters", this.monsterActivationRange); + this.raiderActivationRange = this.getInt("entity-activation-range.raiders", this.raiderActivationRange); + this.miscActivationRange = this.getInt("entity-activation-range.misc", this.miscActivationRange); // Paper start - this.waterActivationRange = this.getInt( "entity-activation-range.water", this.waterActivationRange ); - this.villagerActivationRange = this.getInt( "entity-activation-range.villagers", hasAnimalsConfig ? this.animalActivationRange : this.villagerActivationRange ); - this.flyingMonsterActivationRange = this.getInt( "entity-activation-range.flying-monsters", this.flyingMonsterActivationRange ); + this.waterActivationRange = this.getInt("entity-activation-range.water", this.waterActivationRange); + this.villagerActivationRange = this.getInt("entity-activation-range.villagers", hasAnimalsConfig ? this.animalActivationRange : this.villagerActivationRange); + this.flyingMonsterActivationRange = this.getInt("entity-activation-range.flying-monsters", this.flyingMonsterActivationRange); this.wakeUpInactiveAnimals = this.getInt("entity-activation-range.wake-up-inactive.animals-max-per-tick", this.wakeUpInactiveAnimals); this.wakeUpInactiveAnimalsEvery = this.getInt("entity-activation-range.wake-up-inactive.animals-every", this.wakeUpInactiveAnimalsEvery); @@ -261,13 +238,13 @@ public class SpigotWorldConfig this.wakeUpInactiveFlyingEvery = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-every", this.wakeUpInactiveFlyingEvery); this.wakeUpInactiveFlyingFor = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-for", this.wakeUpInactiveFlyingFor); - this.villagersWorkImmunityAfter = this.getInt( "entity-activation-range.villagers-work-immunity-after", this.villagersWorkImmunityAfter ); - this.villagersWorkImmunityFor = this.getInt( "entity-activation-range.villagers-work-immunity-for", this.villagersWorkImmunityFor ); - this.villagersActiveForPanic = this.getBoolean( "entity-activation-range.villagers-active-for-panic", this.villagersActiveForPanic ); + this.villagersWorkImmunityAfter = this.getInt("entity-activation-range.villagers-work-immunity-after", this.villagersWorkImmunityAfter); + this.villagersWorkImmunityFor = this.getInt("entity-activation-range.villagers-work-immunity-for", this.villagersWorkImmunityFor); + this.villagersActiveForPanic = this.getBoolean("entity-activation-range.villagers-active-for-panic", this.villagersActiveForPanic); // Paper end - this.tickInactiveVillagers = this.getBoolean( "entity-activation-range.tick-inactive-villagers", this.tickInactiveVillagers ); - this.ignoreSpectatorActivation = this.getBoolean( "entity-activation-range.ignore-spectators", this.ignoreSpectatorActivation ); - this.log( "Entity Activation Range: An " + this.animalActivationRange + " / Mo " + this.monsterActivationRange + " / Ra " + this.raiderActivationRange + " / Mi " + this.miscActivationRange + " / Tiv " + this.tickInactiveVillagers + " / Isa " + this.ignoreSpectatorActivation ); + this.tickInactiveVillagers = this.getBoolean("entity-activation-range.tick-inactive-villagers", this.tickInactiveVillagers); + this.ignoreSpectatorActivation = this.getBoolean("entity-activation-range.ignore-spectators", this.ignoreSpectatorActivation); + this.log("Entity Activation Range: An " + this.animalActivationRange + " / Mo " + this.monsterActivationRange + " / Ra " + this.raiderActivationRange + " / Mi " + this.miscActivationRange + " / Tiv " + this.tickInactiveVillagers + " / Isa " + this.ignoreSpectatorActivation); } public int playerTrackingRange = 128; @@ -276,81 +253,71 @@ public class SpigotWorldConfig public int miscTrackingRange = 96; public int displayTrackingRange = 128; public int otherTrackingRange = 64; - private void trackingRange() - { - this.playerTrackingRange = this.getInt( "entity-tracking-range.players", this.playerTrackingRange ); - this.animalTrackingRange = this.getInt( "entity-tracking-range.animals", this.animalTrackingRange ); - this.monsterTrackingRange = this.getInt( "entity-tracking-range.monsters", this.monsterTrackingRange ); - this.miscTrackingRange = this.getInt( "entity-tracking-range.misc", this.miscTrackingRange ); - this.displayTrackingRange = this.getInt( "entity-tracking-range.display", this.displayTrackingRange ); - this.otherTrackingRange = this.getInt( "entity-tracking-range.other", this.otherTrackingRange ); - this.log( "Entity Tracking Range: Pl " + this.playerTrackingRange + " / An " + this.animalTrackingRange + " / Mo " + this.monsterTrackingRange + " / Mi " + this.miscTrackingRange + " / Di " + this.displayTrackingRange + " / Other " + this.otherTrackingRange ); + private void trackingRange() { + this.playerTrackingRange = this.getInt("entity-tracking-range.players", this.playerTrackingRange); + this.animalTrackingRange = this.getInt("entity-tracking-range.animals", this.animalTrackingRange); + this.monsterTrackingRange = this.getInt("entity-tracking-range.monsters", this.monsterTrackingRange); + this.miscTrackingRange = this.getInt("entity-tracking-range.misc", this.miscTrackingRange); + this.displayTrackingRange = this.getInt("entity-tracking-range.display", this.displayTrackingRange); + this.otherTrackingRange = this.getInt("entity-tracking-range.other", this.otherTrackingRange); + this.log("Entity Tracking Range: Pl " + this.playerTrackingRange + " / An " + this.animalTrackingRange + " / Mo " + this.monsterTrackingRange + " / Mi " + this.miscTrackingRange + " / Di " + this.displayTrackingRange + " / Other " + this.otherTrackingRange); } public int hopperTransfer; public int hopperCheck; public int hopperAmount; public boolean hopperCanLoadChunks; - private void hoppers() - { + private void hoppers() { // Set the tick delay between hopper item movements - this.hopperTransfer = this.getInt( "ticks-per.hopper-transfer", 8 ); - if ( SpigotConfig.version < 11 ) - { - this.set( "ticks-per.hopper-check", 1 ); + this.hopperTransfer = this.getInt("ticks-per.hopper-transfer", 8); + if (SpigotConfig.version < 11) { + this.set("ticks-per.hopper-check", 1); } - this.hopperCheck = this.getInt( "ticks-per.hopper-check", 1 ); - this.hopperAmount = this.getInt( "hopper-amount", 1 ); - this.hopperCanLoadChunks = this.getBoolean( "hopper-can-load-chunks", false ); - this.log( "Hopper Transfer: " + this.hopperTransfer + " Hopper Check: " + this.hopperCheck + " Hopper Amount: " + this.hopperAmount + " Hopper Can Load Chunks: " + this.hopperCanLoadChunks ); + this.hopperCheck = this.getInt("ticks-per.hopper-check", 1); + this.hopperAmount = this.getInt("hopper-amount", 1); + this.hopperCanLoadChunks = this.getBoolean("hopper-can-load-chunks", false); + this.log("Hopper Transfer: " + this.hopperTransfer + " Hopper Check: " + this.hopperCheck + " Hopper Amount: " + this.hopperAmount + " Hopper Can Load Chunks: " + this.hopperCanLoadChunks); } public int arrowDespawnRate; public int tridentDespawnRate; - private void arrowDespawnRate() - { - this.arrowDespawnRate = this.getInt( "arrow-despawn-rate", 1200 ); - this.tridentDespawnRate = this.getInt( "trident-despawn-rate", this.arrowDespawnRate ); - this.log( "Arrow Despawn Rate: " + this.arrowDespawnRate + " Trident Respawn Rate:" + this.tridentDespawnRate ); + private void arrowDespawnRate() { + this.arrowDespawnRate = this.getInt("arrow-despawn-rate", 1200); + this.tridentDespawnRate = this.getInt("trident-despawn-rate", this.arrowDespawnRate); + this.log("Arrow Despawn Rate: " + this.arrowDespawnRate + " Trident Respawn Rate:" + this.tridentDespawnRate); } public boolean zombieAggressiveTowardsVillager; - private void zombieAggressiveTowardsVillager() - { - this.zombieAggressiveTowardsVillager = this.getBoolean( "zombie-aggressive-towards-villager", true ); - this.log( "Zombie Aggressive Towards Villager: " + this.zombieAggressiveTowardsVillager ); + private void zombieAggressiveTowardsVillager() { + this.zombieAggressiveTowardsVillager = this.getBoolean("zombie-aggressive-towards-villager", true); + this.log("Zombie Aggressive Towards Villager: " + this.zombieAggressiveTowardsVillager); } public boolean nerfSpawnerMobs; - private void nerfSpawnerMobs() - { - this.nerfSpawnerMobs = this.getBoolean( "nerf-spawner-mobs", false ); - this.log( "Nerfing mobs spawned from spawners: " + this.nerfSpawnerMobs ); + private void nerfSpawnerMobs() { + this.nerfSpawnerMobs = this.getBoolean("nerf-spawner-mobs", false); + this.log("Nerfing mobs spawned from spawners: " + this.nerfSpawnerMobs); } public boolean enableZombiePigmenPortalSpawns; - private void enableZombiePigmenPortalSpawns() - { - this.enableZombiePigmenPortalSpawns = this.getBoolean( "enable-zombie-pigmen-portal-spawns", true ); - this.log( "Allow Zombie Pigmen to spawn from portal blocks: " + this.enableZombiePigmenPortalSpawns ); + private void enableZombiePigmenPortalSpawns() { + this.enableZombiePigmenPortalSpawns = this.getBoolean("enable-zombie-pigmen-portal-spawns", true); + this.log("Allow Zombie Pigmen to spawn from portal blocks: " + this.enableZombiePigmenPortalSpawns); } public int dragonDeathSoundRadius; - private void keepDragonDeathPerWorld() - { - this.dragonDeathSoundRadius = this.getInt( "dragon-death-sound-radius", 0 ); + private void keepDragonDeathPerWorld() { + this.dragonDeathSoundRadius = this.getInt("dragon-death-sound-radius", 0); } public int witherSpawnSoundRadius; - private void witherSpawnSoundRadius() - { - this.witherSpawnSoundRadius = this.getInt( "wither-spawn-sound-radius", 0 ); + private void witherSpawnSoundRadius() { + this.witherSpawnSoundRadius = this.getInt("wither-spawn-sound-radius", 0); } public int endPortalSoundRadius; - private void endPortalSoundRadius() - { - this.endPortalSoundRadius = this.getInt( "end-portal-sound-radius", 0 ); + private void endPortalSoundRadius() { + this.endPortalSoundRadius = this.getInt("end-portal-sound-radius", 0); } public int villageSeed; @@ -375,28 +342,29 @@ public class SpigotWorldConfig public int buriedTreasureSeed; public Integer mineshaftSeed; public Long strongholdSeed; + private N getSeed(String path, java.util.function.Function toNumberFunc) { final String value = this.getString(path, "default"); return org.apache.commons.lang3.math.NumberUtils.isParsable(value) ? toNumberFunc.apply(value) : null; } + // Paper end - private void initWorldGenSeeds() - { - this.villageSeed = this.getInt( "seed-village", 10387312 ); - this.desertSeed = this.getInt( "seed-desert", 14357617 ); - this.iglooSeed = this.getInt( "seed-igloo", 14357618 ); - this.jungleSeed = this.getInt( "seed-jungle", 14357619 ); - this.swampSeed = this.getInt( "seed-swamp", 14357620 ); - this.monumentSeed = this.getInt( "seed-monument", 10387313 ); - this.shipwreckSeed = this.getInt( "seed-shipwreck", 165745295 ); - this.oceanSeed = this.getInt( "seed-ocean", 14357621 ); - this.outpostSeed = this.getInt( "seed-outpost", 165745296 ); - this.endCitySeed = this.getInt( "seed-endcity", 10387313 ); - this.slimeSeed = this.getInt( "seed-slime", 987234911 ); - this.netherSeed = this.getInt( "seed-nether", 30084232 ); - this.mansionSeed = this.getInt( "seed-mansion", 10387319 ); - this.fossilSeed = this.getInt( "seed-fossil", 14357921 ); - this.portalSeed = this.getInt( "seed-portal", 34222645 ); + private void initWorldGenSeeds() { + this.villageSeed = this.getInt("seed-village", 10387312); + this.desertSeed = this.getInt("seed-desert", 14357617); + this.iglooSeed = this.getInt("seed-igloo", 14357618); + this.jungleSeed = this.getInt("seed-jungle", 14357619); + this.swampSeed = this.getInt("seed-swamp", 14357620); + this.monumentSeed = this.getInt("seed-monument", 10387313); + this.shipwreckSeed = this.getInt("seed-shipwreck", 165745295); + this.oceanSeed = this.getInt("seed-ocean", 14357621); + this.outpostSeed = this.getInt("seed-outpost", 165745296); + this.endCitySeed = this.getInt("seed-endcity", 10387313); + this.slimeSeed = this.getInt("seed-slime", 987234911); + this.netherSeed = this.getInt("seed-nether", 30084232); + this.mansionSeed = this.getInt("seed-mansion", 10387319); + this.fossilSeed = this.getInt("seed-fossil", 14357921); + this.portalSeed = this.getInt("seed-portal", 34222645); // Paper start - add missing structure set configs this.ancientCitySeed = this.getInt("seed-ancientcity", 20083232); this.trailRuinsSeed = this.getInt("seed-trailruins", 83469867); @@ -405,8 +373,8 @@ public class SpigotWorldConfig this.mineshaftSeed = this.getSeed("seed-mineshaft", Integer::parseInt); this.strongholdSeed = this.getSeed("seed-stronghold", Long::parseLong); // Paper end - this.log( "Custom Map Seeds: Village: " + this.villageSeed + " Desert: " + this.desertSeed + " Igloo: " + this.iglooSeed + " Jungle: " + this.jungleSeed + " Swamp: " + this.swampSeed + " Monument: " + this.monumentSeed - + " Ocean: " + this.oceanSeed + " Shipwreck: " + this.shipwreckSeed + " End City: " + this.endCitySeed + " Slime: " + this.slimeSeed + " Nether: " + this.netherSeed + " Mansion: " + this.mansionSeed + " Fossil: " + this.fossilSeed + " Portal: " + this.portalSeed ); + this.log("Custom Map Seeds: Village: " + this.villageSeed + " Desert: " + this.desertSeed + " Igloo: " + this.iglooSeed + " Jungle: " + this.jungleSeed + " Swamp: " + this.swampSeed + " Monument: " + this.monumentSeed + + " Ocean: " + this.oceanSeed + " Shipwreck: " + this.shipwreckSeed + " End City: " + this.endCitySeed + " Slime: " + this.slimeSeed + " Nether: " + this.netherSeed + " Mansion: " + this.mansionSeed + " Fossil: " + this.fossilSeed + " Portal: " + this.portalSeed); } public float jumpWalkExhaustion; @@ -416,54 +384,48 @@ public class SpigotWorldConfig public float swimMultiplier; public float sprintMultiplier; public float otherMultiplier; - private void initHunger() - { - if ( SpigotConfig.version < 10 ) - { - this.set( "hunger.walk-exhaustion", null ); - this.set( "hunger.sprint-exhaustion", null ); - this.set( "hunger.combat-exhaustion", 0.1 ); - this.set( "hunger.regen-exhaustion", 6.0 ); + private void initHunger() { + if (SpigotConfig.version < 10) { + this.set("hunger.walk-exhaustion", null); + this.set("hunger.sprint-exhaustion", null); + this.set("hunger.combat-exhaustion", 0.1); + this.set("hunger.regen-exhaustion", 6.0); } - this.jumpWalkExhaustion = (float) this.getDouble( "hunger.jump-walk-exhaustion", 0.05 ); - this.jumpSprintExhaustion = (float) this.getDouble( "hunger.jump-sprint-exhaustion", 0.2 ); - this.combatExhaustion = (float) this.getDouble( "hunger.combat-exhaustion", 0.1 ); - this.regenExhaustion = (float) this.getDouble( "hunger.regen-exhaustion", 6.0 ); - this.swimMultiplier = (float) this.getDouble( "hunger.swim-multiplier", 0.01 ); - this.sprintMultiplier = (float) this.getDouble( "hunger.sprint-multiplier", 0.1 ); - this.otherMultiplier = (float) this.getDouble( "hunger.other-multiplier", 0.0 ); + this.jumpWalkExhaustion = (float) this.getDouble("hunger.jump-walk-exhaustion", 0.05); + this.jumpSprintExhaustion = (float) this.getDouble("hunger.jump-sprint-exhaustion", 0.2); + this.combatExhaustion = (float) this.getDouble("hunger.combat-exhaustion", 0.1); + this.regenExhaustion = (float) this.getDouble("hunger.regen-exhaustion", 6.0); + this.swimMultiplier = (float) this.getDouble("hunger.swim-multiplier", 0.01); + this.sprintMultiplier = (float) this.getDouble("hunger.sprint-multiplier", 0.1); + this.otherMultiplier = (float) this.getDouble("hunger.other-multiplier", 0.0); } public int currentPrimedTnt = 0; public int maxTntTicksPerTick; private void maxTntPerTick() { - if ( SpigotConfig.version < 7 ) - { - this.set( "max-tnt-per-tick", 100 ); + if (SpigotConfig.version < 7) { + this.set("max-tnt-per-tick", 100); } - this.maxTntTicksPerTick = this.getInt( "max-tnt-per-tick", 100 ); - this.log( "Max TNT Explosions: " + this.maxTntTicksPerTick ); + this.maxTntTicksPerTick = this.getInt("max-tnt-per-tick", 100); + this.log("Max TNT Explosions: " + this.maxTntTicksPerTick); } public int hangingTickFrequency; - private void hangingTickFrequency() - { - this.hangingTickFrequency = this.getInt( "hanging-tick-frequency", 100 ); + private void hangingTickFrequency() { + this.hangingTickFrequency = this.getInt("hanging-tick-frequency", 100); } public int tileMaxTickTime; public int entityMaxTickTime; - private void maxTickTimes() - { + private void maxTickTimes() { this.tileMaxTickTime = this.getInt("max-tick-time.tile", 50); this.entityMaxTickTime = this.getInt("max-tick-time.entity", 50); this.log("Tile Max Tick Time: " + this.tileMaxTickTime + "ms Entity max Tick Time: " + this.entityMaxTickTime + "ms"); } public int thunderChance; - private void thunderChance() - { + private void thunderChance() { this.thunderChance = this.getInt("thunder-chance", 100000); } diff --git a/paper-server/src/main/java/org/spigotmc/TickLimiter.java b/paper-server/src/main/java/org/spigotmc/TickLimiter.java index 4074538ea6..961489499e 100644 --- a/paper-server/src/main/java/org/spigotmc/TickLimiter.java +++ b/paper-server/src/main/java/org/spigotmc/TickLimiter.java @@ -5,8 +5,8 @@ public class TickLimiter { private final int maxTime; private long startTime; - public TickLimiter(int maxtime) { - this.maxTime = maxtime; + public TickLimiter(int maxTime) { + this.maxTime = maxTime; } public void initTick() { diff --git a/paper-server/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/paper-server/src/main/java/org/spigotmc/TicksPerSecondCommand.java index 9eb2823cc8..6d4851aa8c 100644 --- a/paper-server/src/main/java/org/spigotmc/TicksPerSecondCommand.java +++ b/paper-server/src/main/java/org/spigotmc/TicksPerSecondCommand.java @@ -1,51 +1,55 @@ package org.spigotmc; -import net.minecraft.server.MinecraftServer; -import org.bukkit.ChatColor; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.JoinConfiguration; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -public class TicksPerSecondCommand extends Command -{ +import static net.kyori.adventure.text.Component.text; - public TicksPerSecondCommand(String name) - { - super( name ); +public class TicksPerSecondCommand extends Command { + + private boolean hasShownMemoryWarning; // Paper + + public TicksPerSecondCommand(String name) { + super(name); this.description = "Gets the current ticks per second for the server"; this.usageMessage = "/tps"; - this.setPermission( "bukkit.command.tps" ); + this.setPermission("bukkit.command.tps"); } + // Paper start - private static final net.kyori.adventure.text.Component WARN_MSG = net.kyori.adventure.text.Component.text() - .append(net.kyori.adventure.text.Component.text("Warning: ", net.kyori.adventure.text.format.NamedTextColor.RED)) - .append(net.kyori.adventure.text.Component.text("Memory usage on modern garbage collectors is not a stable value and it is perfectly normal to see it reach max. Please do not pay it much attention.", net.kyori.adventure.text.format.NamedTextColor.GOLD)) + private static final Component WARN_MSG = text() + .append(text("Warning: ", NamedTextColor.RED)) + .append(text("Memory usage on modern garbage collectors is not a stable value and it is perfectly normal to see it reach max. Please do not pay it much attention.", NamedTextColor.GOLD)) .build(); // Paper end @Override - public boolean execute(CommandSender sender, String currentAlias, String[] args) - { - if ( !this.testPermission( sender ) ) - { + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!this.testPermission(sender)) { return true; } // Paper start - Further improve tick handling double[] tps = org.bukkit.Bukkit.getTPS(); - net.kyori.adventure.text.Component[] tpsAvg = new net.kyori.adventure.text.Component[tps.length]; + Component[] tpsAvg = new Component[tps.length]; - for ( int i = 0; i < tps.length; i++) { - tpsAvg[i] = TicksPerSecondCommand.format( tps[i] ); + for (int i = 0; i < tps.length; i++) { + tpsAvg[i] = TicksPerSecondCommand.format(tps[i]); } - net.kyori.adventure.text.TextComponent.Builder builder = net.kyori.adventure.text.Component.text(); - builder.append(net.kyori.adventure.text.Component.text("TPS from last 1m, 5m, 15m: ", net.kyori.adventure.text.format.NamedTextColor.GOLD)); - builder.append(net.kyori.adventure.text.Component.join(net.kyori.adventure.text.JoinConfiguration.commas(true), tpsAvg)); + TextComponent.Builder builder = text(); + builder.append(text("TPS from last 1m, 5m, 15m: ", NamedTextColor.GOLD)); + builder.append(Component.join(JoinConfiguration.commas(true), tpsAvg)); sender.sendMessage(builder.asComponent()); if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) { - sender.sendMessage(net.kyori.adventure.text.Component.text() - .append(net.kyori.adventure.text.Component.text("Current Memory Usage: ", net.kyori.adventure.text.format.NamedTextColor.GOLD)) - .append(net.kyori.adventure.text.Component.text(((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)", net.kyori.adventure.text.format.NamedTextColor.GREEN)) + sender.sendMessage(text() + .append(text("Current Memory Usage: ", NamedTextColor.GOLD)) + .append(text(((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)", NamedTextColor.GREEN)) ); if (!this.hasShownMemoryWarning) { sender.sendMessage(WARN_MSG); @@ -57,13 +61,11 @@ public class TicksPerSecondCommand extends Command return true; } - private boolean hasShownMemoryWarning; // Paper - private static net.kyori.adventure.text.Component format(double tps) // Paper - Made static - { - // Paper - net.kyori.adventure.text.format.TextColor color = ( ( tps > 18.0 ) ? net.kyori.adventure.text.format.NamedTextColor.GREEN : ( tps > 16.0 ) ? net.kyori.adventure.text.format.NamedTextColor.YELLOW : net.kyori.adventure.text.format.NamedTextColor.RED ); - String amount = Math.min(Math.round(tps * 100.0) / 100.0, 20.0) + (tps > 21.0 ? "*" : ""); // Paper - only print * at 21, we commonly peak to 20.02 as the tick sleep is not accurate enough, stop the noise - return net.kyori.adventure.text.Component.text(amount, color); + private static Component format(double tps) { // Paper - Made static + // Paper start + TextColor color = ((tps > 18.0) ? NamedTextColor.GREEN : (tps > 16.0) ? NamedTextColor.YELLOW : NamedTextColor.RED); + String amount = Math.min(Math.round(tps * 100.0) / 100.0, 20.0) + (tps > 21.0 ? "*" : ""); // Paper - only print * at 21, we commonly peak to 20.02 as the tick sleep is not accurate enough, stop the noise + return text(amount, color); // Paper end } } diff --git a/paper-server/src/main/java/org/spigotmc/TrackingRange.java b/paper-server/src/main/java/org/spigotmc/TrackingRange.java index 4835431493..05db2aab74 100644 --- a/paper-server/src/main/java/org/spigotmc/TrackingRange.java +++ b/paper-server/src/main/java/org/spigotmc/TrackingRange.java @@ -18,9 +18,7 @@ public final class TrackingRange { * Gets the range an entity should be 'tracked' by players and visible in * the client. * - * @param entity * @param defaultRange Default range defined by Mojang - * @return */ public static int getEntityTrackingRange(final Entity entity, final int defaultRange) { if (defaultRange == 0) { @@ -51,7 +49,7 @@ public final class TrackingRange { } else { if (entity instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon) { // Exempt ender dragon - return ((ServerLevel) entity.getCommandSenderWorld()).getChunkSource().chunkMap.serverViewDistance; + return ((ServerLevel) entity.level()).getChunkSource().chunkMap.serverViewDistance; } return config.otherTrackingRange; } diff --git a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java index ad282d3491..7fa7816014 100644 --- a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java +++ b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java @@ -5,11 +5,12 @@ import java.lang.management.MonitorInfo; import java.lang.management.ThreadInfo; import java.util.logging.Level; import java.util.logging.Logger; +import io.papermc.paper.configuration.GlobalConfiguration; import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.CraftServer; -public class WatchdogThread extends Thread -{ +public class WatchdogThread extends Thread { private static WatchdogThread instance; private long timeoutTime; @@ -21,160 +22,141 @@ public class WatchdogThread extends Thread private volatile long lastTick; private volatile boolean stopping; - private WatchdogThread(long timeoutTime, boolean restart) - { - super( "Paper Watchdog Thread" ); + private WatchdogThread(long timeoutTime, boolean restart) { + super("Paper Watchdog Thread"); this.timeoutTime = timeoutTime; this.restart = restart; - earlyWarningEvery = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningEvery, timeoutTime); // Paper - earlyWarningDelay = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningDelay, timeoutTime); // Paper + this.earlyWarningEvery = Math.min(GlobalConfiguration.get().watchdog.earlyWarningEvery, timeoutTime); // Paper + this.earlyWarningDelay = Math.min(GlobalConfiguration.get().watchdog.earlyWarningDelay, timeoutTime); // Paper } - private static long monotonicMillis() - { + private static long monotonicMillis() { return System.nanoTime() / 1000000L; } - public static void doStart(int timeoutTime, boolean restart) - { - if ( WatchdogThread.instance == null ) - { - WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart ); + public static void doStart(int timeoutTime, boolean restart) { + if (WatchdogThread.instance == null) { + WatchdogThread.instance = new WatchdogThread(timeoutTime * 1000L, restart); WatchdogThread.instance.start(); - } else - { + } else { WatchdogThread.instance.timeoutTime = timeoutTime * 1000L; WatchdogThread.instance.restart = restart; } } - public static void tick() - { + public static void tick() { WatchdogThread.instance.lastTick = WatchdogThread.monotonicMillis(); } - public static void doStop() - { - if ( WatchdogThread.instance != null ) - { + public static void doStop() { + if (WatchdogThread.instance != null) { WatchdogThread.instance.stopping = true; } } @Override - public void run() - { - while ( !this.stopping ) - { - // + public void run() { + while (!this.stopping) { // Paper start - Logger log = Bukkit.getServer().getLogger(); + Logger logger = Bukkit.getServer().getLogger(); long currentTime = WatchdogThread.monotonicMillis(); - if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable - { - boolean isLongTimeout = currentTime > lastTick + timeoutTime; + if (this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) { // Paper - Add property to disable + boolean isLongTimeout = currentTime > this.lastTick + this.timeoutTime; // Don't spam early warning dumps - if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue; - if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this... - lastEarlyWarning = currentTime; + if (!isLongTimeout && (this.earlyWarningEvery <= 0 || + !hasStarted || currentTime < this.lastEarlyWarning + this.earlyWarningEvery || + currentTime < this.lastTick + this.earlyWarningDelay)) + continue; + if (!isLongTimeout && MinecraftServer.getServer().hasStopped()) + continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this... + this.lastEarlyWarning = currentTime; if (isLongTimeout) { - // Paper end - log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper - log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" ); - log.log( Level.SEVERE, "\t *Especially* if it looks like HTTP or MySQL operations are occurring" ); - log.log( Level.SEVERE, "If you see a world save or edit, then it means you did far more than your server can handle at once" ); - log.log( Level.SEVERE, "\t If this is the case, consider increasing timeout-time in spigot.yml but note that this will replace the crash with LARGE lag spikes" ); - log.log( Level.SEVERE, "If you are unsure or still think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues" ); - log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" ); - log.log( Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion() ); - // - if ( net.minecraft.world.level.Level.lastPhysicsProblem != null ) - { - log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed" ); - log.log( Level.SEVERE, "near " + net.minecraft.world.level.Level.lastPhysicsProblem ); - } - // - // Paper start - Warn in watchdog if an excessive velocity was ever set - if (org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null) { - log.log(Level.SEVERE, "------------------------------"); - log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity"); - log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated"); - log.log(Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); - for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) { - log.log( Level.SEVERE, "\t\t" + stack ); + // Paper end + logger.log(Level.SEVERE, "------------------------------"); + logger.log(Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug."); // Paper + logger.log(Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author"); + logger.log(Level.SEVERE, "\t *Especially* if it looks like HTTP or MySQL operations are occurring"); + logger.log(Level.SEVERE, "If you see a world save or edit, then it means you did far more than your server can handle at once"); + logger.log(Level.SEVERE, "\t If this is the case, consider increasing timeout-time in spigot.yml but note that this will replace the crash with LARGE lag spikes"); + logger.log(Level.SEVERE, "If you are unsure or still think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues"); + logger.log(Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports"); + logger.log(Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion()); + + if (net.minecraft.world.level.Level.lastPhysicsProblem != null) { + logger.log(Level.SEVERE, "------------------------------"); + logger.log(Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed"); + logger.log(Level.SEVERE, "near " + net.minecraft.world.level.Level.lastPhysicsProblem); } - } - // Paper end - } else - { - log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); - log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump"); + + // Paper start - Warn in watchdog if an excessive velocity was ever set + if (CraftServer.excessiveVelEx != null) { + logger.log(Level.SEVERE, "------------------------------"); + logger.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity"); + logger.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated"); + logger.log(Level.SEVERE, CraftServer.excessiveVelEx.getMessage()); + for (StackTraceElement stack : CraftServer.excessiveVelEx.getStackTrace()) { + logger.log(Level.SEVERE, "\t\t" + stack); + } + } + // Paper end + } else { + logger.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); + logger.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump"); } // Paper end - Different message for short timeout - log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); - log.log( Level.SEVERE, "------------------------------" ); - // + logger.log(Level.SEVERE, "------------------------------"); + logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):"); // Paper + WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger); + logger.log(Level.SEVERE, "------------------------------"); + // Paper start - Only print full dump on long timeouts - if ( isLongTimeout ) - { - log.log( Level.SEVERE, "Entire Thread Dump:" ); - ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true ); - for ( ThreadInfo thread : threads ) - { - WatchdogThread.dumpThread( thread, log ); - } + if (isLongTimeout) { + logger.log(Level.SEVERE, "Entire Thread Dump:"); + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + for (ThreadInfo thread : threads) { + WatchdogThread.dumpThread(thread, logger); + } } else { - log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---"); + logger.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---"); } - log.log( Level.SEVERE, "------------------------------" ); + logger.log(Level.SEVERE, "------------------------------"); - if ( isLongTimeout ) - { - if ( this.restart && !MinecraftServer.getServer().hasStopped() ) - { - RestartCommand.restart(); + if (isLongTimeout) { + if (this.restart && !MinecraftServer.getServer().hasStopped()) { + RestartCommand.restart(); + } + break; } - break; - } // Paper end + // Paper end } - try - { - sleep( 1000 ); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout - } catch ( InterruptedException ex ) - { + try { + sleep(1000); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout + } catch (InterruptedException ex) { this.interrupt(); } } } - private static void dumpThread(ThreadInfo thread, Logger log) - { - log.log( Level.SEVERE, "------------------------------" ); - // - log.log( Level.SEVERE, "Current Thread: " + thread.getThreadName() ); - log.log( Level.SEVERE, "\tPID: " + thread.getThreadId() - + " | Suspended: " + thread.isSuspended() - + " | Native: " + thread.isInNative() - + " | State: " + thread.getThreadState() ); - if ( thread.getLockedMonitors().length != 0 ) - { - log.log( Level.SEVERE, "\tThread is waiting on monitor(s):" ); - for ( MonitorInfo monitor : thread.getLockedMonitors() ) - { - log.log( Level.SEVERE, "\t\tLocked on:" + monitor.getLockedStackFrame() ); + private static void dumpThread(ThreadInfo thread, Logger log) { + log.log(Level.SEVERE, "------------------------------"); + + log.log(Level.SEVERE, "Current Thread: " + thread.getThreadName()); + log.log(Level.SEVERE, "\tPID: " + thread.getThreadId() + + " | Suspended: " + thread.isSuspended() + + " | Native: " + thread.isInNative() + + " | State: " + thread.getThreadState()); + if (thread.getLockedMonitors().length != 0) { + log.log(Level.SEVERE, "\tThread is waiting on monitor(s):"); + for (MonitorInfo monitor : thread.getLockedMonitors()) { + log.log(Level.SEVERE, "\t\tLocked on:" + monitor.getLockedStackFrame()); } } - log.log( Level.SEVERE, "\tStack:" ); - // - for ( StackTraceElement stack : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(thread.getStackTrace()) ) // Paper - { - log.log( Level.SEVERE, "\t\t" + stack ); + log.log(Level.SEVERE, "\tStack:"); + + for (StackTraceElement stack : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(thread.getStackTrace())) { // Paper + log.log(Level.SEVERE, "\t\t" + stack); } } }