diff --git a/Spigot-API-Patches/0003-Timings-v2.patch b/Spigot-API-Patches/0003-Timings-v2.patch index 160e2013ca..d8e7a8f559 100644 --- a/Spigot-API-Patches/0003-Timings-v2.patch +++ b/Spigot-API-Patches/0003-Timings-v2.patch @@ -1,4 +1,4 @@ -From 54d8f0c3b52d8bd1d3e4afee2c6c3489da1c3577 Mon Sep 17 00:00:00 2001 +From 134c514dd418485e6f07d20930dc0c4398dc76fd Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 29 Feb 2016 18:48:17 -0600 Subject: [PATCH] Timings v2 @@ -1184,10 +1184,10 @@ index 00000000..623dda49 +} diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java new file mode 100644 -index 00000000..483e3669 +index 00000000..0571c9e7 --- /dev/null +++ b/src/main/java/co/aikar/timings/Timings.java -@@ -0,0 +1,274 @@ +@@ -0,0 +1,284 @@ +/* + * This file is licensed under the MIT License (MIT). + * @@ -1215,6 +1215,7 @@ index 00000000..483e3669 + +import com.google.common.base.Preconditions; +import com.google.common.collect.EvictingQueue; ++import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; @@ -1431,7 +1432,16 @@ index 00000000..483e3669 + if (sender == null) { + sender = Bukkit.getConsoleSender(); + } -+ // Schedule report for end of tick ++ TimingsExport.requestingReport.add(sender); ++ } ++ ++ /** ++ * Generates a report and sends it to the specified listener. ++ * Use with {@link org.bukkit.command.BufferedCommandSender} to get full response when done! ++ * @param sender The listener to send responses too. ++ */ ++ public static void generateReport(TimingsReportListener sender) { ++ Validate.notNull(sender); + TimingsExport.requestingReport.add(sender); + } + @@ -1589,10 +1599,10 @@ index 00000000..56b10e89 +} diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java new file mode 100644 -index 00000000..9dd36419 +index 00000000..23a3daa8 --- /dev/null +++ b/src/main/java/co/aikar/timings/TimingsExport.java -@@ -0,0 +1,394 @@ +@@ -0,0 +1,341 @@ +/* + * This file is licensed under the MIT License (MIT). + * @@ -1618,7 +1628,6 @@ index 00000000..9dd36419 + */ +package co.aikar.timings; + -+import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.apache.commons.lang.StringUtils; @@ -1626,13 +1635,9 @@ index 00000000..9dd36419 +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; -+import org.bukkit.command.ConsoleCommandSender; -+import org.bukkit.command.MultiMessageCommandSender; -+import org.bukkit.command.RemoteConsoleCommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.MemorySection; +import org.bukkit.entity.EntityType; -+import org.bukkit.plugin.Plugin; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + @@ -1640,7 +1645,6 @@ index 00000000..9dd36419 +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; -+import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.net.HttpURLConnection; @@ -1653,20 +1657,25 @@ index 00000000..9dd36419 +import java.util.zip.GZIPOutputStream; + +import static co.aikar.timings.TimingsManager.HISTORY; -+import static co.aikar.util.JSONUtil.*; ++import static co.aikar.util.JSONUtil.appendObjectData; ++import static co.aikar.util.JSONUtil.createObject; ++import static co.aikar.util.JSONUtil.pair; ++import static co.aikar.util.JSONUtil.toArray; ++import static co.aikar.util.JSONUtil.toArrayMapper; ++import static co.aikar.util.JSONUtil.toObjectMapper; + +@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) +class TimingsExport extends Thread { + -+ private final CommandSender sender; ++ private final TimingsReportListener listeners; + private final Map out; + private final TimingHistory[] history; + private static long lastReport = 0; + final static List requestingReport = Lists.newArrayList(); + -+ private TimingsExport(CommandSender sender, Map out, TimingHistory[] history) { ++ private TimingsExport(TimingsReportListener listeners, Map out, TimingHistory[] history) { + super("Timings paste thread"); -+ this.sender = sender; ++ this.listeners = listeners; + this.out = out; + this.history = history; + } @@ -1678,19 +1687,24 @@ index 00000000..9dd36419 + if (requestingReport.isEmpty()) { + return; + } -+ CommandSender sender = new MultiMessageCommandSender(requestingReport); ++ TimingsReportListener listeners = new TimingsReportListener(requestingReport); ++ listeners.addConsoleIfNeeded(); ++ + requestingReport.clear(); + long now = System.currentTimeMillis(); + final long lastReportDiff = now - lastReport; + if (lastReportDiff < 60000) { -+ sender.sendMessage(ChatColor.RED + "Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)"); ++ listeners.sendMessage(ChatColor.RED + "Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)"); ++ listeners.done(); + return; + } + final long lastStartDiff = now - TimingsManager.timingStart; + if (lastStartDiff < 180000) { -+ sender.sendMessage(ChatColor.RED + "Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)"); ++ listeners.sendMessage(ChatColor.RED + "Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)"); ++ listeners.done(); + return; + } ++ listeners.sendMessage(ChatColor.GREEN + "Preparing Timings Report..."); + lastReport = now; + Map parent = createObject( + // Get some basic system details about the server @@ -1722,12 +1736,7 @@ index 00000000..9dd36419 + pair("cpu", runtime.availableProcessors()), + pair("runtime", ManagementFactory.getRuntimeMXBean().getUptime()), + pair("flags", StringUtils.join(runtimeBean.getInputArguments(), " ")), -+ pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), new Function() { -+ @Override -+ public JSONPair apply(GarbageCollectorMXBean input) { -+ return pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime())); -+ } -+ })) ++ pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), input -> pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime())))) + ) + ); + @@ -1763,49 +1772,24 @@ index 00000000..9dd36419 + + parent.put("idmap", createObject( + pair("groups", toObjectMapper( -+ TimingIdentifier.GROUP_MAP.values(), new Function() { -+ @Override -+ public JSONPair apply(TimingIdentifier.TimingGroup group) { -+ return pair(group.id, group.name); -+ } -+ })), ++ TimingIdentifier.GROUP_MAP.values(), group -> pair(group.id, group.name))), + pair("handlers", handlers), -+ pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), new Function, JSONPair>() { -+ @Override -+ public JSONPair apply(Map.Entry input) { -+ return pair(input.getValue(), input.getKey()); -+ } -+ })), ++ pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), input -> pair(input.getValue(), input.getKey()))), + pair("tileentity", -+ toObjectMapper(tileEntityTypeSet, new Function() { -+ @Override -+ public JSONPair apply(Material input) { -+ return pair(input.getId(), input.name()); -+ } -+ })), ++ toObjectMapper(tileEntityTypeSet, input -> pair(input.getId(), input.name()))), + pair("entity", -+ toObjectMapper(entityTypeSet, new Function() { -+ @Override -+ public JSONPair apply(EntityType input) { -+ return pair(input.getTypeId(), input.name()); -+ } -+ })) ++ toObjectMapper(entityTypeSet, input -> pair(input.getTypeId(), input.name()))) + )); + + // Information about loaded plugins + + parent.put("plugins", toObjectMapper(Bukkit.getPluginManager().getPlugins(), -+ new Function() { -+ @Override -+ public JSONPair apply(Plugin plugin) { -+ return pair(plugin.getName(), createObject( -+ pair("version", plugin.getDescription().getVersion()), -+ pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()), -+ pair("website", plugin.getDescription().getWebsite()), -+ pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", ")) -+ )); -+ } -+ })); ++ plugin -> pair(plugin.getName(), createObject( ++ pair("version", plugin.getDescription().getVersion()), ++ pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()), ++ pair("website", plugin.getDescription().getWebsite()), ++ pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", ")) ++ )))); + + + @@ -1817,7 +1801,7 @@ index 00000000..9dd36419 + pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)) + )); + -+ new TimingsExport(sender, parent, history).start(); ++ new TimingsExport(listeners, parent, history).start(); + } + + static long getCost() { @@ -1874,12 +1858,7 @@ index 00000000..9dd36419 + if (!(val instanceof MemorySection)) { + if (val instanceof List) { + Iterable v = (Iterable) val; -+ return toArrayMapper(v, new Function() { -+ @Override -+ public Object apply(Object input) { -+ return valAsJSON(input, parentKey); -+ } -+ }); ++ return toArrayMapper(v, input -> valAsJSON(input, parentKey)); + } else { + return val.toString(); + } @@ -1888,30 +1867,9 @@ index 00000000..9dd36419 + } + } + -+ @SuppressWarnings("CallToThreadRun") -+ @Override -+ public synchronized void start() { -+ if (sender instanceof RemoteConsoleCommandSender) { -+ sender.sendMessage(ChatColor.RED + "Warning: Timings report done over RCON will cause lag spikes."); -+ sender.sendMessage(ChatColor.RED + "You should use " + ChatColor.YELLOW + -+ "/timings report" + ChatColor.RED + " in game or console."); -+ run(); -+ } else { -+ super.start(); -+ } -+ } -+ + @Override + public void run() { -+ sender.sendMessage(ChatColor.GREEN + "Preparing Timings Report..."); -+ -+ -+ out.put("data", toArrayMapper(history, new Function() { -+ @Override -+ public Object apply(TimingHistory input) { -+ return input.export(); -+ } -+ })); ++ out.put("data", toArrayMapper(history, TimingHistory::export)); + + + String response = null; @@ -1936,9 +1894,9 @@ index 00000000..9dd36419 + response = getResponse(con); + + if (con.getResponseCode() != 302) { -+ sender.sendMessage( ++ listeners.sendMessage( + ChatColor.RED + "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage()); -+ sender.sendMessage(ChatColor.RED + "Check your logs for more information"); ++ listeners.sendMessage(ChatColor.RED + "Check your logs for more information"); + if (response != null) { + Bukkit.getLogger().log(Level.SEVERE, response); + } @@ -1946,20 +1904,19 @@ index 00000000..9dd36419 + } + + String location = con.getHeaderField("Location"); -+ sender.sendMessage(ChatColor.GREEN + "View Timings Report: " + location); -+ if (!(sender instanceof ConsoleCommandSender)) { -+ Bukkit.getLogger().log(Level.INFO, "View Timings Report: " + location); -+ } ++ listeners.sendMessage(ChatColor.GREEN + "View Timings Report: " + location); + + if (response != null && !response.isEmpty()) { + Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response); + } + } catch (IOException ex) { -+ sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); ++ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); + if (response != null) { + Bukkit.getLogger().log(Level.SEVERE, response); + } + Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex); ++ } finally { ++ this.listeners.done(); + } + } + @@ -1977,7 +1934,7 @@ index 00000000..9dd36419 + return bos.toString(); + + } catch (IOException ex) { -+ sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); ++ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); + Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex); + return null; + } finally { @@ -2189,6 +2146,74 @@ index 00000000..58ed35e0 + return null; + } +} +diff --git a/src/main/java/co/aikar/timings/TimingsReportListener.java b/src/main/java/co/aikar/timings/TimingsReportListener.java +new file mode 100644 +index 00000000..4d492d4b +--- /dev/null ++++ b/src/main/java/co/aikar/timings/TimingsReportListener.java +@@ -0,0 +1,62 @@ ++package co.aikar.timings; ++ ++import com.google.common.collect.Lists; ++import org.apache.commons.lang.Validate; ++import org.bukkit.Bukkit; ++import org.bukkit.command.CommandSender; ++import org.bukkit.command.ConsoleCommandSender; ++import org.bukkit.command.MessageCommandSender; ++import org.bukkit.command.RemoteConsoleCommandSender; ++ ++import java.util.List; ++ ++@SuppressWarnings("WeakerAccess") ++public class TimingsReportListener implements MessageCommandSender { ++ private final List senders; ++ private final Runnable onDone; ++ ++ public TimingsReportListener(CommandSender senders) { ++ this(senders, null); ++ } ++ public TimingsReportListener(CommandSender sender, Runnable onDone) { ++ this(Lists.newArrayList(sender), onDone); ++ } ++ public TimingsReportListener(List senders) { ++ this(senders, null); ++ } ++ public TimingsReportListener(List senders, Runnable onDone) { ++ Validate.notNull(senders); ++ Validate.notEmpty(senders); ++ ++ this.senders = Lists.newArrayList(senders); ++ this.onDone = onDone; ++ } ++ ++ public void done() { ++ if (onDone != null) { ++ onDone.run(); ++ } ++ for (CommandSender sender : senders) { ++ if (sender instanceof TimingsReportListener) { ++ ((TimingsReportListener) sender).done(); ++ } ++ } ++ } ++ ++ @Override ++ public void sendMessage(String message) { ++ senders.forEach((sender) -> sender.sendMessage(message)); ++ } ++ ++ public void addConsoleIfNeeded() { ++ boolean hasConsole = false; ++ for (CommandSender sender : this.senders) { ++ if (sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) { ++ hasConsole = true; ++ } ++ } ++ if (!hasConsole) { ++ this.senders.add(Bukkit.getConsoleSender()); ++ } ++ } ++} diff --git a/src/main/java/co/aikar/timings/UnsafeTimingHandler.java b/src/main/java/co/aikar/timings/UnsafeTimingHandler.java new file mode 100644 index 00000000..5edaba12 @@ -2940,6 +2965,30 @@ index 120dba25..77cfe561 100644 /** * Sends the component to the player * +diff --git a/src/main/java/org/bukkit/command/BufferedCommandSender.java b/src/main/java/org/bukkit/command/BufferedCommandSender.java +new file mode 100644 +index 00000000..fd452bce +--- /dev/null ++++ b/src/main/java/org/bukkit/command/BufferedCommandSender.java +@@ -0,0 +1,18 @@ ++package org.bukkit.command; ++ ++public class BufferedCommandSender implements MessageCommandSender { ++ private final StringBuffer buffer = new StringBuffer(); ++ @Override ++ public void sendMessage(String message) { ++ buffer.append(message); ++ buffer.append("\n"); ++ } ++ ++ public String getBuffer() { ++ return buffer.toString(); ++ } ++ ++ public void reset() { ++ this.buffer.setLength(0); ++ } ++} diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java index 08a9739f..347d2189 100644 --- a/src/main/java/org/bukkit/command/Command.java @@ -2992,17 +3041,15 @@ index 3f07d7f4..f89ad075 100644 private static boolean inRange(int i, int j, int k) { return i >= j && i <= k; } -diff --git a/src/main/java/org/bukkit/command/MultiMessageCommandSender.java b/src/main/java/org/bukkit/command/MultiMessageCommandSender.java +diff --git a/src/main/java/org/bukkit/command/MessageCommandSender.java b/src/main/java/org/bukkit/command/MessageCommandSender.java new file mode 100644 -index 00000000..7b512fd4 +index 00000000..66232339 --- /dev/null -+++ b/src/main/java/org/bukkit/command/MultiMessageCommandSender.java -@@ -0,0 +1,114 @@ ++++ b/src/main/java/org/bukkit/command/MessageCommandSender.java +@@ -0,0 +1,99 @@ +package org.bukkit.command; + -+import com.google.common.collect.Lists; +import org.apache.commons.lang.NotImplementedException; -+import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.permissions.Permission; @@ -3010,105 +3057,92 @@ index 00000000..7b512fd4 +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + -+import java.util.List; +import java.util.Set; + +/** -+ * Used for proxying messages to multiple senders. -+ * Do not use this for anything else but messages. ++ * For when all you care about is just messaging + */ -+public class MultiMessageCommandSender implements CommandSender { -+ private final List senders; ++public interface MessageCommandSender extends CommandSender { + -+ public MultiMessageCommandSender(List senders) { -+ Validate.notNull(senders); -+ Validate.notEmpty(senders); -+ -+ this.senders = Lists.newArrayList(senders); ++ @Override ++ default void sendMessage(String[] messages) { ++ for (String message : messages) { ++ sendMessage(message); ++ } + } + + @Override -+ public void sendMessage(String message) { -+ senders.forEach((sender) -> sender.sendMessage(message)); -+ } -+ -+ @Override -+ public void sendMessage(String[] messages) { -+ senders.forEach((sender) -> sender.sendMessage(messages)); -+ } -+ -+ @Override -+ public Server getServer() { ++ default Server getServer() { + return Bukkit.getServer(); + } + + @Override -+ public String getName() { ++ default String getName() { + throw new NotImplementedException(); + } + + @Override -+ public boolean isOp() { ++ default boolean isOp() { + throw new NotImplementedException(); + } + + @Override -+ public void setOp(boolean value) { ++ default void setOp(boolean value) { + throw new NotImplementedException(); + } + + @Override -+ public boolean isPermissionSet(String name) { ++ default boolean isPermissionSet(String name) { + throw new NotImplementedException(); + } + + @Override -+ public boolean isPermissionSet(Permission perm) { ++ default boolean isPermissionSet(Permission perm) { + throw new NotImplementedException(); + } + + @Override -+ public boolean hasPermission(String name) { ++ default boolean hasPermission(String name) { + throw new NotImplementedException(); + } + + @Override -+ public boolean hasPermission(Permission perm) { ++ default boolean hasPermission(Permission perm) { + throw new NotImplementedException(); + } + + @Override -+ public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { ++ default PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + throw new NotImplementedException(); + } + + @Override -+ public PermissionAttachment addAttachment(Plugin plugin) { ++ default PermissionAttachment addAttachment(Plugin plugin) { + throw new NotImplementedException(); + } + + @Override -+ public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { ++ default PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + throw new NotImplementedException(); + } + + @Override -+ public PermissionAttachment addAttachment(Plugin plugin, int ticks) { ++ default PermissionAttachment addAttachment(Plugin plugin, int ticks) { + throw new NotImplementedException(); + } + + @Override -+ public void removeAttachment(PermissionAttachment attachment) { ++ default void removeAttachment(PermissionAttachment attachment) { + throw new NotImplementedException(); + } + + @Override -+ public void recalculatePermissions() { ++ default void recalculatePermissions() { + throw new NotImplementedException(); + } + + @Override -+ public Set getEffectivePermissions() { ++ default Set getEffectivePermissions() { + throw new NotImplementedException(); + } +} diff --git a/Spigot-Server-Patches/0005-Timings-v2.patch b/Spigot-Server-Patches/0005-Timings-v2.patch index d9368884e0..bd1cb70536 100644 --- a/Spigot-Server-Patches/0005-Timings-v2.patch +++ b/Spigot-Server-Patches/0005-Timings-v2.patch @@ -1,11 +1,11 @@ -From fab6746b634e849bb0effc92deb503dc84e72eac Mon Sep 17 00:00:00 2001 +From f6a0b22a39ad826143911fdb4e4127297e1cf862 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 04:00:11 -0600 Subject: [PATCH] Timings v2 diff --git a/pom.xml b/pom.xml -index 0e88ae2a7..31b8401aa 100644 +index 8b96966d8..8d1e8680b 100644 --- a/pom.xml +++ b/pom.xml @@ -66,6 +66,12 @@ @@ -493,7 +493,7 @@ index 81fc04ed3..bd3b16025 100644 private void z() { diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 87c07f2be..e18fb875f 100644 +index daf2c0a67..3ba489d4f 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -195,7 +195,7 @@ public class ChunkProviderServer implements IChunkProvider { @@ -555,7 +555,7 @@ index a97e7d3c2..4890023d7 100644 // return chunk; // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index cb83e4f56..4dab9e962 100644 +index cb83e4f56..e6819139f 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -23,7 +23,7 @@ import java.io.PrintStream; @@ -585,6 +585,28 @@ index cb83e4f56..4dab9e962 100644 } public boolean aa() { +@@ -692,7 +692,20 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + return remoteControlCommandListener.getMessages(); + } + }; +- processQueue.add(waitable); ++ // Paper start ++ if (s.toLowerCase().startsWith("timings") && s.toLowerCase().matches("timings (report|paste|get|merged|seperate)")) { ++ org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender(); ++ waitable = new Waitable() { ++ @Override ++ protected String evaluate() { ++ return sender.getBuffer(); ++ } ++ }; ++ co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable)); ++ } else { ++ processQueue.add(waitable); ++ } ++ // Paper end + try { + return waitable.get(); + } catch (java.util.concurrent.ExecutionException e) { diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index e7b1ebbe3..05312c6ac 100644 --- a/src/main/java/net/minecraft/server/Entity.java @@ -1832,5 +1854,5 @@ index c32d44df0..5c2fb0058 100644 } } -- -2.11.0.windows.3 +2.11.0