diff --git a/Bukkit-Patches/0003-Add-CustomTimingsHandler-for-adding-new-CraftBukkit-.patch b/Bukkit-Patches/0003-Add-CustomTimingsHandler-for-adding-new-CraftBukkit-.patch deleted file mode 100644 index 3f5a288b2..000000000 --- a/Bukkit-Patches/0003-Add-CustomTimingsHandler-for-adding-new-CraftBukkit-.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 60bbe254c90b77065770adc852e57e51b0b0ef81 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Wed, 9 Jan 2013 22:18:26 -0500 -Subject: [PATCH] Add CustomTimingsHandler for adding new CraftBukkit custom - timings - ---- - .../org/bukkit/command/defaults/ReloadCommand.java | 2 + - .../bukkit/command/defaults/TimingsCommand.java | 67 ++++++++++++++++++++-- - .../org/bukkit/event/CustomTimingsHandler.java | 60 +++++++++++++++++++ - 3 files changed, 123 insertions(+), 6 deletions(-) - create mode 100644 src/main/java/org/bukkit/event/CustomTimingsHandler.java - -diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java -index fb3c90f..fffafa5 100644 ---- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java -+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java -@@ -6,6 +6,7 @@ import org.bukkit.Bukkit; - import org.bukkit.ChatColor; - import org.bukkit.command.Command; - import org.bukkit.command.CommandSender; -+import org.bukkit.event.CustomTimingsHandler; - - public class ReloadCommand extends BukkitCommand { - public ReloadCommand(String name) { -@@ -20,6 +21,7 @@ public class ReloadCommand extends BukkitCommand { - public boolean execute(CommandSender sender, String currentAlias, String[] args) { - if (!testPermission(sender)) return true; - -+ CustomTimingsHandler.reload(); // Spigot - Bukkit.reload(); - Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); - -diff --git a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java -index 94cd62c..7c1e601 100644 ---- a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java -+++ b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java -@@ -10,6 +10,7 @@ import org.apache.commons.lang.Validate; - import org.bukkit.Bukkit; - import org.bukkit.ChatColor; - import org.bukkit.command.CommandSender; -+import org.bukkit.event.CustomTimingsHandler; - import org.bukkit.event.Event; - import org.bukkit.event.HandlerList; - import org.bukkit.plugin.Plugin; -@@ -18,15 +19,21 @@ import org.bukkit.plugin.TimedRegisteredListener; - import org.bukkit.util.StringUtil; - - import com.google.common.collect.ImmutableList; -+import java.io.ByteArrayOutputStream; -+import java.io.OutputStream; -+import java.net.HttpURLConnection; -+import java.net.URL; -+import java.net.URLEncoder; -+import java.util.logging.Level; - - public class TimingsCommand extends BukkitCommand { -- private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate"); -+ private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate", "paste"); // Spigot - - public static long timingStart = 0; // Spigot - public TimingsCommand(String name) { - super(name); - this.description = "Records timings for all plugin events"; -- this.usageMessage = "/timings "; -+ this.usageMessage = "/timings "; - this.setPermission("bukkit.command.timings"); - } - -@@ -43,6 +50,7 @@ public class TimingsCommand extends BukkitCommand { - } - - boolean separate = "separate".equals(args[0]); -+ boolean paste = "paste".equals(args[0]); - if ("reset".equals(args[0])) { - for (HandlerList handlerList : HandlerList.getHandlerLists()) { - for (RegisteredListener listener : handlerList.getRegisteredListeners()) { -@@ -51,9 +59,10 @@ public class TimingsCommand extends BukkitCommand { - } - } - } -+ CustomTimingsHandler.reload(); // Spigot - timingStart = System.nanoTime(); // Spigot - sender.sendMessage("Timings reset"); -- } else if ("merged".equals(args[0]) || separate) { -+ } else if ("merged".equals(args[0]) || separate || paste) { - - long sampleTime = System.nanoTime() - timingStart; // Spigot - int index = 0; -@@ -62,11 +71,12 @@ public class TimingsCommand extends BukkitCommand { - timingFolder.mkdirs(); - File timings = new File(timingFolder, "timings.txt"); - File names = null; -+ ByteArrayOutputStream bout = (paste) ? new ByteArrayOutputStream() : null; - while (timings.exists()) timings = new File(timingFolder, "timings" + (++index) + ".txt"); - PrintStream fileTimings = null; - PrintStream fileNames = null; - try { -- fileTimings = new PrintStream(timings); -+ fileTimings = (paste) ? new PrintStream(bout) : new PrintStream(timings); - if (separate) { - names = new File(timingFolder, "names" + index + ".txt"); - fileNames = new PrintStream(names); -@@ -95,8 +105,17 @@ public class TimingsCommand extends BukkitCommand { - } - fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)"); - } -- fileTimings.println("Sample time " + sampleTime + " (" + sampleTime / 1000000000 + "s)"); // Spigot -- sender.sendMessage("Timings written to " + timings.getPath()); -+ -+ // Spigot start -+ CustomTimingsHandler.printTimings(fileTimings); -+ fileTimings.println("Sample time " + sampleTime + " (" + sampleTime / 1000000000 + "s)"); -+ if (paste) { -+ new PasteThread(sender, bout).start(); -+ } else { -+ sender.sendMessage("Timings written to " + timings.getPath()); -+ sender.sendMessage("Paste contents of file into form at http://aikar.co/timings.php to read results."); -+ } -+ // Spigot end - if (separate) sender.sendMessage("Names written to " + names.getPath()); - } catch (IOException e) { - } finally { -@@ -122,4 +141,40 @@ public class TimingsCommand extends BukkitCommand { - } - return ImmutableList.of(); - } -+ -+ private static class PasteThread extends Thread { -+ -+ private final CommandSender sender; -+ private final ByteArrayOutputStream bout; -+ -+ public PasteThread(CommandSender sender, ByteArrayOutputStream bout) { -+ super("Timings paste thread"); -+ this.sender = sender; -+ this.bout = bout; -+ } -+ -+ @Override -+ public void run() { -+ try { -+ HttpURLConnection con = (HttpURLConnection) new URL("http://paste.ubuntu.com/").openConnection(); -+ con.setDoOutput(true); -+ con.setRequestMethod("POST"); -+ con.setInstanceFollowRedirects(false); -+ -+ OutputStream out = con.getOutputStream(); -+ out.write("poster=Spigot&syntax=text&content=".getBytes("UTF-8")); -+ out.write(URLEncoder.encode(bout.toString("UTF-8"), "UTF-8").getBytes("UTF-8")); -+ out.close(); -+ con.getInputStream().close(); -+ -+ String location = con.getHeaderField("Location"); -+ String pasteID = location.substring("http://paste.ubuntu.com/".length(), location.length() - 1); -+ sender.sendMessage(ChatColor.GREEN + "Your timings have been pasted to " + location); -+ sender.sendMessage(ChatColor.GREEN + "You can view the results at http://aikar.co/timings.php?url=" + pasteID); -+ } catch (IOException ex) { -+ sender.sendMessage(ChatColor.RED + "Error pasting timings, check your console for more information"); -+ Bukkit.getServer().getLogger().log(Level.WARNING, "Could not paste timings", ex); -+ } -+ } -+ } - } -diff --git a/src/main/java/org/bukkit/event/CustomTimingsHandler.java b/src/main/java/org/bukkit/event/CustomTimingsHandler.java -new file mode 100644 -index 0000000..ff56673 ---- /dev/null -+++ b/src/main/java/org/bukkit/event/CustomTimingsHandler.java -@@ -0,0 +1,60 @@ -+package org.bukkit.event; -+ -+ -+import org.bukkit.Bukkit; -+ -+import java.io.PrintStream; -+import java.util.ArrayList; -+ -+/** -+ * Extends RegisteredListener to include timing information -+ */ -+public class CustomTimingsHandler { -+ -+ private final String name; -+ public int count = 0; -+ public long totalTime = 0; -+ long start = 0; -+ -+ public static ArrayList allList = new ArrayList(); -+ public CustomTimingsHandler(String name) { -+ this.name = name; -+ allList.add(this); -+ } -+ -+ static public void printTimings(PrintStream printStream) { -+ printStream.println("Minecraft - ** indicates it's already counted by another timing"); -+ for (CustomTimingsHandler t : allList) { -+ long time = t.totalTime; -+ int count = t.count; -+ if (count == 0) continue; -+ long avg = time / count; -+ -+ printStream.println(" " + t.name + " Time: " + time + " Count: " + count + " Avg: " + avg); -+ } -+ } -+ -+ static public void reload() { -+ if (!Bukkit.getServer().getPluginManager().useTimings()) return; -+ for (CustomTimingsHandler t : allList) { -+ t.reset(); -+ } -+ } -+ -+ public void startTiming() { -+ if (!Bukkit.getServer().getPluginManager().useTimings()) return; -+ start = System.nanoTime(); -+ } -+ -+ public void stopTiming() { -+ if (!Bukkit.getServer().getPluginManager().useTimings()) return; -+ totalTime += System.nanoTime() - start; -+ count++; -+ } -+ -+ public void reset() { -+ count = 0; -+ totalTime = 0; -+ } -+} -+ --- -1.8.1-rc2 - diff --git a/Bukkit-Patches/0003-Improved-Timings-System.patch b/Bukkit-Patches/0003-Improved-Timings-System.patch new file mode 100644 index 000000000..39532219b --- /dev/null +++ b/Bukkit-Patches/0003-Improved-Timings-System.patch @@ -0,0 +1,411 @@ +From 1d2352eb83a0e0cd6ff7cd592999430d37a8513a Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 9 Jan 2013 22:18:26 -0500 +Subject: [PATCH] Improved Timings System + +Enables "Timings on Demand" so you can enable/disable timings without server restart. +Tracks timings on sync events a plugin registers (Single and Repeating) +Tracks how many ticks a timed area has caused the server to lose due to taking too long. +Enables automatically pasting to paste.ubuntu.com so you can quickly review the results on aikar.co/timings.php +--- + src/main/java/org/bukkit/CustomTimingsHandler.java | 134 +++++++++++++++++++++ + .../org/bukkit/command/defaults/ReloadCommand.java | 2 + + .../bukkit/command/defaults/TimingsCommand.java | 90 ++++++++++++-- + .../org/bukkit/plugin/TimedRegisteredListener.java | 12 +- + .../org/bukkit/plugin/java/JavaPluginLoader.java | 2 +- + 5 files changed, 227 insertions(+), 13 deletions(-) + create mode 100644 src/main/java/org/bukkit/CustomTimingsHandler.java + +diff --git a/src/main/java/org/bukkit/CustomTimingsHandler.java b/src/main/java/org/bukkit/CustomTimingsHandler.java +new file mode 100644 +index 0000000..8c00824 +--- /dev/null ++++ b/src/main/java/org/bukkit/CustomTimingsHandler.java +@@ -0,0 +1,134 @@ ++package org.bukkit; ++ ++import org.bukkit.event.HandlerList; ++import org.bukkit.plugin.Plugin; ++import org.bukkit.plugin.RegisteredListener; ++import org.bukkit.plugin.TimedRegisteredListener; ++ ++import java.io.PrintStream; ++import java.util.concurrent.ConcurrentLinkedQueue; ++ ++/** ++ * Provides custom timing sections for /timings merged ++ */ ++public class CustomTimingsHandler { ++ ++ final public String name; ++ public long count = 0; ++ public long start = 0; ++ public long timingDepth = 0; ++ public long totalTime = 0; ++ public long curTickTotal = 0; ++ public long violations = 0; ++ CustomTimingsHandler parent = null; ++ ++ final public static ConcurrentLinkedQueue allList = new ConcurrentLinkedQueue(); ++ ++ public CustomTimingsHandler(String name) { ++ this.name = name; ++ allList.add(this); ++ } ++ public CustomTimingsHandler(String name, CustomTimingsHandler parent) { ++ this(name); ++ this.parent = parent; ++ } ++ ++ /** ++ * Prints the timings and extra data to the printstream ++ * @param printStream ++ */ ++ public static void printTimings(PrintStream printStream) { ++ printStream.println("Minecraft"); ++ for (CustomTimingsHandler timings : allList) { ++ long time = timings.totalTime; ++ long count = timings.count; ++ if (count == 0) continue; ++ long avg = time / count; ++ ++ printStream.println(" " + timings.name + " Time: " + time + " Count: " + count + " Avg: " + avg + " Violations: " + timings.violations); ++ } ++ printStream.println("# Version " + Bukkit.getVersion()); ++ int entities = 0; ++ int livingEntities = 0; ++ for (World world : Bukkit.getWorlds()) { ++ entities += world.getEntities().size(); ++ livingEntities += world.getLivingEntities().size(); ++ } ++ printStream.println("# Entities " + entities); ++ printStream.println("# LivingEntities " + livingEntities); ++ } ++ ++ /** ++ * Resets all timings ++ */ ++ public static void reload() { ++ if (!Bukkit.getServer().getPluginManager().useTimings()) return; ++ for (CustomTimingsHandler timings : allList) { ++ timings.reset(); ++ } ++ } ++ ++ /** ++ * Ticked every tick by CraftBukkit to count the number of times a timer caused TPS loss. ++ */ ++ public static void tick() { ++ if (!Bukkit.getServer().getPluginManager().useTimings()) return; ++ for (CustomTimingsHandler timings : allList) { ++ if (timings.curTickTotal > 50000000) { ++ timings.violations += Math.ceil(timings.curTickTotal / 50000000); ++ } ++ timings.curTickTotal = 0; ++ } ++ ++ for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { ++ for (RegisteredListener listener : HandlerList.getRegisteredListeners(plugin)) { ++ if (listener instanceof TimedRegisteredListener) { ++ TimedRegisteredListener timings = (TimedRegisteredListener) listener; ++ if (timings.curTickTotal > 50000000) { ++ timings.violations += Math.ceil(timings.curTickTotal / 50000000); ++ } ++ timings.curTickTotal = 0; ++ } ++ } ++ } ++ } ++ ++ /** ++ * Starts timing to track a section of code. ++ */ ++ public void startTiming() { ++ if (!Bukkit.getServer().getPluginManager().useTimings()) return; ++ ++ if (++timingDepth != 1) { ++ return; // Already timing. ++ } ++ start = System.nanoTime(); ++ ++ if (parent != null && ++parent.timingDepth == 1) { ++ parent.start = start; ++ } ++ } ++ ++ public void stopTiming() { ++ if (!Bukkit.getServer().getPluginManager().useTimings()) return; ++ if (--timingDepth != 0 || start == 0) { ++ return; ++ } ++ long diff = System.nanoTime() - start; ++ totalTime += diff; ++ curTickTotal += diff; ++ count++; ++ start = 0; ++ if (parent != null) { ++ parent.stopTiming(); ++ } ++ } ++ ++ public void reset() { ++ count = 0; ++ violations = 0; ++ curTickTotal = 0; ++ totalTime = 0; ++ } ++} ++ +diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java +index fb3c90f..89c8414 100644 +--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java ++++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java +@@ -6,6 +6,7 @@ import org.bukkit.Bukkit; + import org.bukkit.ChatColor; + import org.bukkit.command.Command; + import org.bukkit.command.CommandSender; ++import org.bukkit.CustomTimingsHandler; + + public class ReloadCommand extends BukkitCommand { + public ReloadCommand(String name) { +@@ -20,6 +21,7 @@ public class ReloadCommand extends BukkitCommand { + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + ++ CustomTimingsHandler.reload(); // Spigot + Bukkit.reload(); + Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); + +diff --git a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java +index 94cd62c..426f9b4 100644 +--- a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java ++++ b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java +@@ -10,40 +10,59 @@ import org.apache.commons.lang.Validate; + import org.bukkit.Bukkit; + import org.bukkit.ChatColor; + import org.bukkit.command.CommandSender; ++import org.bukkit.CustomTimingsHandler; + import org.bukkit.event.Event; + import org.bukkit.event.HandlerList; + import org.bukkit.plugin.Plugin; + import org.bukkit.plugin.RegisteredListener; ++import org.bukkit.plugin.SimplePluginManager; // Spigot + import org.bukkit.plugin.TimedRegisteredListener; + import org.bukkit.util.StringUtil; + + import com.google.common.collect.ImmutableList; ++import java.io.ByteArrayOutputStream; ++import java.io.OutputStream; ++import java.net.HttpURLConnection; ++import java.net.URL; ++import java.net.URLEncoder; ++import java.util.logging.Level; + + public class TimingsCommand extends BukkitCommand { +- private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate"); ++ private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate", "paste", "on", "off"); // Spigot + + public static long timingStart = 0; // Spigot + public TimingsCommand(String name) { + super(name); + this.description = "Records timings for all plugin events"; +- this.usageMessage = "/timings "; ++ this.usageMessage = "/timings "; // Spigot + this.setPermission("bukkit.command.timings"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; +- if (args.length != 1) { ++ if (args.length < 1) { // Spigot + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } +- if (!sender.getServer().getPluginManager().useTimings()) { ++ // Spigot start - this is dynamic now ++ /*if (!sender.getServer().getPluginManager().useTimings()) { + sender.sendMessage("Please enable timings by setting \"settings.plugin-profiling\" to true in bukkit.yml"); + return true; ++ }*/ ++ if ("on".equals(args[0])) { ++ ((SimplePluginManager)Bukkit.getServer().getPluginManager()).useTimings(true); ++ sender.sendMessage("Enabled Timings"); ++ } else if ("off".equals(args[0])) { ++ ((SimplePluginManager)Bukkit.getServer().getPluginManager()).useTimings(false); ++ sender.sendMessage("Disabled Timings"); + } ++ // Spigot end + + boolean separate = "separate".equals(args[0]); +- if ("reset".equals(args[0])) { ++ boolean paste = "paste".equals(args[0]); // Spigot ++ if ("on".equals(args[0]) || "reset".equals(args[0])) { // Spigot ++ if (!"on".equals(args[0]) && !Bukkit.getServer().getPluginManager().useTimings()) {sender.sendMessage("Please enable timings by typing /timings on"); return true; } // Spigot + for (HandlerList handlerList : HandlerList.getHandlerLists()) { + for (RegisteredListener listener : handlerList.getRegisteredListeners()) { + if (listener instanceof TimedRegisteredListener) { +@@ -51,10 +70,11 @@ public class TimingsCommand extends BukkitCommand { + } + } + } ++ CustomTimingsHandler.reload(); // Spigot + timingStart = System.nanoTime(); // Spigot + sender.sendMessage("Timings reset"); +- } else if ("merged".equals(args[0]) || separate) { +- ++ } else if ("merged".equals(args[0]) || separate || paste) { // Spigot ++ if (!Bukkit.getServer().getPluginManager().useTimings()) {sender.sendMessage("Please enable timings by typing /timings on"); return true; } // Spigot + long sampleTime = System.nanoTime() - timingStart; // Spigot + int index = 0; + int pluginIdx = 0; +@@ -62,11 +82,12 @@ public class TimingsCommand extends BukkitCommand { + timingFolder.mkdirs(); + File timings = new File(timingFolder, "timings.txt"); + File names = null; ++ ByteArrayOutputStream bout = (paste) ? new ByteArrayOutputStream() : null; // Spigot + while (timings.exists()) timings = new File(timingFolder, "timings" + (++index) + ".txt"); + PrintStream fileTimings = null; + PrintStream fileNames = null; + try { +- fileTimings = new PrintStream(timings); ++ fileTimings = (paste) ? new PrintStream(bout) : new PrintStream(timings); + if (separate) { + names = new File(timingFolder, "names" + index + ".txt"); + fileNames = new PrintStream(names); +@@ -89,14 +110,23 @@ public class TimingsCommand extends BukkitCommand { + totalTime += time; + Event event = trl.getEvent(); + if (count > 0 && event != null) { +- fileTimings.println(" " + event.getClass().getSimpleName() + (trl.hasMultiple() ? " (and others)" : "") + " Time: " + time + " Count: " + count + " Avg: " + avg); ++ fileTimings.println(" " + event.getClass().getSimpleName() + (trl.hasMultiple() ? " (and others)" : "") + " Time: " + time + " Count: " + count + " Avg: " + avg + " Violations: " + trl.violations); // Spigot + } + } + } + fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)"); + } +- fileTimings.println("Sample time " + sampleTime + " (" + sampleTime / 1000000000 + "s)"); // Spigot +- sender.sendMessage("Timings written to " + timings.getPath()); ++ ++ // Spigot start ++ CustomTimingsHandler.printTimings(fileTimings); ++ fileTimings.println("Sample time " + sampleTime + " (" + sampleTime / 1000000000 + "s)"); ++ if (paste) { ++ new PasteThread(sender, bout).start(); ++ } else { ++ sender.sendMessage("Timings written to " + timings.getPath()); ++ sender.sendMessage("Paste contents of file into form at http://aikar.co/timings.php to read results."); ++ } ++ // Spigot end + if (separate) sender.sendMessage("Names written to " + names.getPath()); + } catch (IOException e) { + } finally { +@@ -122,4 +152,42 @@ public class TimingsCommand extends BukkitCommand { + } + return ImmutableList.of(); + } ++ ++ // Spigot start ++ private static class PasteThread extends Thread { ++ ++ private final CommandSender sender; ++ private final ByteArrayOutputStream bout; ++ ++ public PasteThread(CommandSender sender, ByteArrayOutputStream bout) { ++ super("Timings paste thread"); ++ this.sender = sender; ++ this.bout = bout; ++ } ++ ++ @Override ++ public void run() { ++ try { ++ HttpURLConnection con = (HttpURLConnection) new URL("http://paste.ubuntu.com/").openConnection(); ++ con.setDoOutput(true); ++ con.setRequestMethod("POST"); ++ con.setInstanceFollowRedirects(false); ++ ++ OutputStream out = con.getOutputStream(); ++ out.write("poster=Spigot&syntax=text&content=".getBytes("UTF-8")); ++ out.write(URLEncoder.encode(bout.toString("UTF-8"), "UTF-8").getBytes("UTF-8")); ++ out.close(); ++ con.getInputStream().close(); ++ ++ String location = con.getHeaderField("Location"); ++ String pasteID = location.substring("http://paste.ubuntu.com/".length(), location.length() - 1); ++ sender.sendMessage(ChatColor.GREEN + "Your timings have been pasted to " + location); ++ sender.sendMessage(ChatColor.GREEN + "You can view the results at http://aikar.co/timings.php?url=" + pasteID); ++ } catch (IOException ex) { ++ sender.sendMessage(ChatColor.RED + "Error pasting timings, check your console for more information"); ++ Bukkit.getServer().getLogger().log(Level.WARNING, "Could not paste timings", ex); ++ } ++ } ++ } ++ // Spigot end + } +diff --git a/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java b/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java +index ed25e17..47dab3e 100644 +--- a/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java ++++ b/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java +@@ -1,5 +1,6 @@ + package org.bukkit.plugin; + ++import org.bukkit.Bukkit; // Spigot + import org.bukkit.event.Event; + import org.bukkit.event.EventException; + import org.bukkit.event.EventPriority; +@@ -11,6 +12,8 @@ import org.bukkit.event.Listener; + public class TimedRegisteredListener extends RegisteredListener { + private int count; + private long totalTime; ++ public long curTickTotal = 0; // Spigot ++ public long violations = 0; // Spigot + private Event event; + private boolean multiple = false; + +@@ -20,6 +23,7 @@ public class TimedRegisteredListener extends RegisteredListener { + + @Override + public void callEvent(Event event) throws EventException { ++ if (!Bukkit.getServer().getPluginManager().useTimings()) { super.callEvent(event);return; } // Spigot + if (event.isAsynchronous()) { + super.callEvent(event); + return; +@@ -33,7 +37,11 @@ public class TimedRegisteredListener extends RegisteredListener { + } + long start = System.nanoTime(); + super.callEvent(event); +- totalTime += System.nanoTime() - start; ++ // Spigot start ++ long diff = System.nanoTime() - start; ++ curTickTotal += diff; ++ totalTime += diff; ++ // Spigot end + } + + /** +@@ -42,6 +50,8 @@ public class TimedRegisteredListener extends RegisteredListener { + public void reset() { + count = 0; + totalTime = 0; ++ curTickTotal = 0; // Spigot ++ violations = 0; // Spigot + } + + /** +diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +index 10fc26a..9c7288e 100644 +--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java ++++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +@@ -430,7 +430,7 @@ public class JavaPluginLoader implements PluginLoader { + } + } + }; +- if (useTimings) { ++ if (true) { // Spigot - TRL handles useTimings check now + eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); + } else { + eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); +-- +1.8.1.1 + diff --git a/CraftBukkit-Patches/0016-Add-Custom-Timings-to-various-points.patch b/CraftBukkit-Patches/0016-Add-Custom-Timings-to-various-points.patch deleted file mode 100644 index ba814bd3c..000000000 --- a/CraftBukkit-Patches/0016-Add-Custom-Timings-to-various-points.patch +++ /dev/null @@ -1,329 +0,0 @@ -From ede0d69949d7d00980598f1944de83052162deb4 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Thu, 10 Jan 2013 00:18:11 -0500 -Subject: [PATCH] Add Custom Timings to various points - ---- - .../net/minecraft/server/ChunkProviderServer.java | 4 ++++ - .../java/net/minecraft/server/EntityLiving.java | 21 +++++++++++++++++++++ - .../java/net/minecraft/server/PlayerConnection.java | 7 +++++++ - src/main/java/net/minecraft/server/World.java | 9 +++++++++ - src/main/java/net/minecraft/server/WorldServer.java | 4 ++++ - .../java/org/bukkit/event/WorldTimingsHandler.java | 20 ++++++++++++++++++++ - 6 files changed, 65 insertions(+) - create mode 100644 src/main/java/org/bukkit/event/WorldTimingsHandler.java - -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index c0bab0f..279ba9e 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -15,6 +15,7 @@ import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; - import org.bukkit.craftbukkit.util.LongHash; - import org.bukkit.craftbukkit.util.LongHashSet; - import org.bukkit.craftbukkit.util.LongObjectHashMap; -+import org.bukkit.event.CustomTimingsHandler; - import org.bukkit.event.world.ChunkUnloadEvent; - // CraftBukkit end - -@@ -28,6 +29,7 @@ public class ChunkProviderServer implements IChunkProvider { - public boolean forceChunkLoad = false; // true -> false - public LongObjectHashMap chunks = new LongObjectHashMap(); - public WorldServer world; -+ static private CustomTimingsHandler syncChunkLoadTimer = new CustomTimingsHandler("syncChunkLoad"); // Spigot - // CraftBukkit end - - public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) { -@@ -103,6 +105,7 @@ public class ChunkProviderServer implements IChunkProvider { - // CraftBukkit end - - if (chunk == null) { -+ syncChunkLoadTimer.startTiming(); // Spigot - chunk = this.loadChunk(i, j); - if (chunk == null) { - if (this.chunkProvider == null) { -@@ -141,6 +144,7 @@ public class ChunkProviderServer implements IChunkProvider { - // CraftBukkit end - - chunk.a(this, this, i, j); -+ syncChunkLoadTimer.stopTiming(); // Spigot - } - - // CraftBukkit start - If we didn't need to load the chunk run the callback now -diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 7d2e633..b2481aa 100644 ---- a/src/main/java/net/minecraft/server/EntityLiving.java -+++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -8,6 +8,7 @@ import java.util.Random; - - // CraftBukkit start - import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.CustomTimingsHandler; - import org.bukkit.event.entity.EntityDamageByBlockEvent; - import org.bukkit.event.entity.EntityDamageEvent; - import org.bukkit.event.entity.EntityRegainHealthEvent; -@@ -110,6 +111,14 @@ public abstract class EntityLiving extends Entity { - public int expToDrop = 0; - public int maxAirTicks = 300; - public int maxHealth = this.getMaxHealth(); -+ // Spigot Start -+ public static CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** entityBaseTick"); -+ public static CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** entityAI"); -+ public static CustomTimingsHandler timerEntityAIJump = new CustomTimingsHandler("** entityAIJump"); -+ public static CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** entityAIMove"); -+ public static CustomTimingsHandler timerEntityAILoot = new CustomTimingsHandler("** entityAILoot"); -+ public static CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** entityTickRest"); -+ // Spigot End - // CraftBukkit end - - public EntityLiving(World world) { -@@ -505,6 +514,7 @@ public abstract class EntityLiving extends Entity { - } - - public void j_() { -+ timerEntityBaseTick.startTiming(); // Spigot - super.j_(); - if (!this.world.isStatic) { - int i; -@@ -531,7 +541,9 @@ public abstract class EntityLiving extends Entity { - } - } - -+ timerEntityBaseTick.stopTiming(); // Spigot - this.c(); -+ timerEntityTickRest.startTiming(); // Spigot - double d0 = this.locX - this.lastX; - double d1 = this.locZ - this.lastZ; - float f = (float) (d0 * d0 + d1 * d1); -@@ -622,6 +634,7 @@ public abstract class EntityLiving extends Entity { - - this.world.methodProfiler.b(); - this.aD += f2; -+ timerEntityTickRest.stopTiming(); // Spigot - } - - // CraftBukkit start - delegate so we can handle providing a reason for health being regained -@@ -1228,6 +1241,7 @@ public abstract class EntityLiving extends Entity { - } - - public void c() { -+ timerEntityAI.startTiming(); // Spigot - if (this.bV > 0) { - --this.bV; - } -@@ -1279,9 +1293,11 @@ public abstract class EntityLiving extends Entity { - this.az = this.yaw; - } - } -+ timerEntityAI.stopTiming(); // Spigot - - this.world.methodProfiler.b(); - this.world.methodProfiler.a("jump"); -+ timerEntityAIJump.startTiming(); // Spigot - if (this.bF) { - if (!this.H() && !this.J()) { - if (this.onGround && this.bV == 0) { -@@ -1295,8 +1311,10 @@ public abstract class EntityLiving extends Entity { - this.bV = 0; - } - -+ timerEntityAIJump.stopTiming(); // Spigot - this.world.methodProfiler.b(); - this.world.methodProfiler.a("travel"); -+ timerEntityAIMove.startTiming(); // Spigot - this.bC *= 0.98F; - this.bD *= 0.98F; - this.bE *= 0.9F; -@@ -1305,6 +1323,7 @@ public abstract class EntityLiving extends Entity { - this.aN *= this.bB(); - this.e(this.bC, this.bD); - this.aN = f; -+ timerEntityAIMove.stopTiming(); // Spigot - this.world.methodProfiler.b(); - this.world.methodProfiler.a("push"); - if (!this.world.isStatic) { -@@ -1313,6 +1332,7 @@ public abstract class EntityLiving extends Entity { - - this.world.methodProfiler.b(); - this.world.methodProfiler.a("looting"); -+ timerEntityAILoot.startTiming(); // Spigot - // CraftBukkit - Don't run mob pickup code on players - if (!this.world.isStatic && !(this instanceof EntityPlayer) && this.canPickUpLoot && !this.bc && this.world.getGameRules().getBoolean("mobGriefing")) { - List list = this.world.a(EntityItem.class, this.boundingBox.grow(1.0D, 0.0D, 1.0D)); -@@ -1377,6 +1397,7 @@ public abstract class EntityLiving extends Entity { - } - } - -+ timerEntityAILoot.stopTiming(); // Spigot - this.world.methodProfiler.b(); - } - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 43a24f5..7ca0acf 100644 ---- a/src/main/java/net/minecraft/server/PlayerConnection.java -+++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -25,6 +25,7 @@ import org.bukkit.craftbukkit.util.Waitable; - import org.bukkit.craftbukkit.entity.CraftPlayer; - import org.bukkit.craftbukkit.event.CraftEventFactory; - import org.bukkit.entity.Player; -+import org.bukkit.event.CustomTimingsHandler; - import org.bukkit.event.Event; - import org.bukkit.event.block.Action; - import org.bukkit.event.block.SignChangeEvent; -@@ -68,6 +69,7 @@ public class PlayerConnection extends Connection { - private double q; - public boolean checkMovement = true; // CraftBukkit - private -> public - private IntHashMap s = new IntHashMap(); -+ static private CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("playerCommand"); // Spigot - - public PlayerConnection(MinecraftServer minecraftserver, INetworkManager inetworkmanager, EntityPlayer entityplayer) { - this.minecraftServer = minecraftserver; -@@ -976,6 +978,7 @@ public class PlayerConnection extends Connection { - // CraftBukkit end - - private void handleCommand(String s) { -+ playerCommandTimer.startTiming(); // Spigot - // CraftBukkit start - CraftPlayer player = this.getPlayer(); - -@@ -983,19 +986,23 @@ public class PlayerConnection extends Connection { - this.server.getPluginManager().callEvent(event); - - if (event.isCancelled()) { -+ playerCommandTimer.stopTiming(); // Spigot - return; - } - - try { - if (server.logCommands) logger.info(event.getPlayer().getName() + " issued server command: " + event.getMessage()); // Spigot - if (this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) { -+ playerCommandTimer.stopTiming(); // Spigot - return; - } - } catch (org.bukkit.command.CommandException ex) { - player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); - Logger.getLogger(PlayerConnection.class.getName()).log(Level.SEVERE, null, ex); -+ playerCommandTimer.stopTiming(); // Spigot - return; - } -+ playerCommandTimer.stopTiming(); // Spigot - // CraftBukkit end - - /* CraftBukkit start - No longer needed as we have already handled it in server.dispatchServerCommand above. -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 41f4f31..c914461 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -14,6 +14,7 @@ import java.util.concurrent.Callable; - import org.bukkit.Bukkit; - import org.bukkit.craftbukkit.util.LongHashSet; - import org.bukkit.craftbukkit.util.UnsafeList; -+import org.bukkit.event.WorldTimingsHandler; - import org.bukkit.generator.ChunkGenerator; - import org.bukkit.craftbukkit.CraftServer; - import org.bukkit.craftbukkit.CraftWorld; -@@ -114,6 +115,7 @@ public abstract class World implements IBlockAccess { - final Object chunkLock = new Object(); - private byte chunkTickRadius; - -+ public WorldTimingsHandler timings; // Spigot - public CraftWorld getWorld() { - return this.world; - } -@@ -193,6 +195,7 @@ public abstract class World implements IBlockAccess { - this.a(); - - this.getServer().addWorld(this.world); // CraftBukkit -+ timings = new WorldTimingsHandler(this); // Spigot - } - - protected abstract IChunkProvider j(); -@@ -1204,6 +1207,7 @@ public abstract class World implements IBlockAccess { - CrashReport crashreport; - CrashReportSystemDetails crashreportsystemdetails; - -+ timings.entityBaseTick.startTiming(); // Spigot - for (i = 0; i < this.i.size(); ++i) { - entity = (Entity) this.i.get(i); - // CraftBukkit start - fixed an NPE, don't process entities in chunks queued for unload -@@ -1258,7 +1262,9 @@ public abstract class World implements IBlockAccess { - - this.f.clear(); - this.methodProfiler.c("regular"); -+ timings.entityBaseTick.stopTiming(); // Spigot - -+ timings.entityTick.startTiming(); // Spigot - for (i = 0; i < this.entityList.size(); ++i) { - entity = (Entity) this.entityList.get(i); - -@@ -1311,7 +1317,9 @@ public abstract class World implements IBlockAccess { - this.methodProfiler.b(); - } - -+ timings.entityTick.stopTiming(); // Spigot - this.methodProfiler.c("tileEntities"); -+ timings.tileEntityTick.startTiming(); // Spigot - this.M = true; - Iterator iterator = this.tileEntityList.iterator(); - -@@ -1390,6 +1398,7 @@ public abstract class World implements IBlockAccess { - this.a.clear(); - } - -+ timings.tileEntityTick.stopTiming(); // Spigot - this.methodProfiler.b(); - this.methodProfiler.b(); - } -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 4aa2a19..6cb3e24 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -157,9 +157,12 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate - // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals - long time = this.worldData.getTime(); - if (this.getGameRules().getBoolean("doMobSpawning") && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) { -+ timings.mobSpawn.startTiming(); // Spigot - SpawnerCreature.spawnEntities(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L); -+ timings.mobSpawn.stopTiming(); // Spigot - } - // CraftBukkit end -+ timings.doTickRest.startTiming(); // Spigot - this.methodProfiler.c("chunkSource"); - this.chunkProvider.unloadChunks(); - int j = this.a(1.0F); -@@ -186,6 +189,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate - this.V(); - - this.getWorld().processChunkGC(); // CraftBukkit -+ timings.doTickRest.stopTiming(); // Spigot - } - - public BiomeMeta a(EnumCreatureType enumcreaturetype, int i, int j, int k) { -diff --git a/src/main/java/org/bukkit/event/WorldTimingsHandler.java b/src/main/java/org/bukkit/event/WorldTimingsHandler.java -new file mode 100644 -index 0000000..bb0c191 ---- /dev/null -+++ b/src/main/java/org/bukkit/event/WorldTimingsHandler.java -@@ -0,0 +1,20 @@ -+package org.bukkit.event; -+ -+import net.minecraft.server.World; -+ -+public class WorldTimingsHandler { -+ public CustomTimingsHandler mobSpawn; -+ public CustomTimingsHandler doTickRest; -+ public CustomTimingsHandler entityBaseTick; -+ public CustomTimingsHandler entityTick; -+ public CustomTimingsHandler tileEntityTick; -+ public WorldTimingsHandler(World server) { -+ String name = server.worldData.getName() +" - "; -+ -+ mobSpawn = new CustomTimingsHandler(name + "mobSpawn"); -+ doTickRest = new CustomTimingsHandler(name + "doTickRest"); -+ entityBaseTick = new CustomTimingsHandler(name + "entityBaseTick"); -+ entityTick = new CustomTimingsHandler(name + "entityTick"); -+ tileEntityTick = new CustomTimingsHandler(name + "tileEntityTick"); -+ } -+} --- -1.8.1-rc2 - diff --git a/CraftBukkit-Patches/0023-Tick-loop-optimization-sleep-for-as-long-as-possible.patch b/CraftBukkit-Patches/0016-Tick-loop-optimization-sleep-for-as-long-as-possible.patch similarity index 98% rename from CraftBukkit-Patches/0023-Tick-loop-optimization-sleep-for-as-long-as-possible.patch rename to CraftBukkit-Patches/0016-Tick-loop-optimization-sleep-for-as-long-as-possible.patch index 61ff2534e..a4c32f825 100644 --- a/CraftBukkit-Patches/0023-Tick-loop-optimization-sleep-for-as-long-as-possible.patch +++ b/CraftBukkit-Patches/0016-Tick-loop-optimization-sleep-for-as-long-as-possible.patch @@ -1,4 +1,4 @@ -From 5edc0ce11f85c023f0d9afb33dc152d0e26bd15f Mon Sep 17 00:00:00 2001 +From fa1eeb2d804ba81c94d259d60df735627eae989f Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 3 Feb 2013 12:28:17 +1100 Subject: [PATCH] Tick loop optimization - sleep for as long as possible. @@ -82,7 +82,7 @@ index 4bdf8aa..128016f 100644 this.a((CrashReport) null); } diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java -index 5827820..1ead152 100644 +index 4a4f949..db46037 100644 --- a/src/main/java/org/bukkit/craftbukkit/Spigot.java +++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java @@ -6,6 +6,8 @@ import org.bukkit.configuration.file.YamlConfiguration; @@ -136,5 +136,5 @@ index 0000000..f114a31 + } +} -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0017-Improved-Timings-System.patch b/CraftBukkit-Patches/0017-Improved-Timings-System.patch new file mode 100644 index 000000000..d0b71f429 --- /dev/null +++ b/CraftBukkit-Patches/0017-Improved-Timings-System.patch @@ -0,0 +1,571 @@ +From 7d318ee4bf7783ec9bca927195e5ee11d4490964 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Thu, 10 Jan 2013 00:18:11 -0500 +Subject: [PATCH] Improved Timings System + +Tracks nearly every point of minecraft internals and plugin events to give a good quick overview on what is causing TPS loss. +--- + .../net/minecraft/server/ChunkProviderServer.java | 2 + + src/main/java/net/minecraft/server/Entity.java | 5 + + .../java/net/minecraft/server/EntityLiving.java | 10 ++ + .../java/net/minecraft/server/MinecraftServer.java | 17 +++- + .../net/minecraft/server/PlayerConnection.java | 5 + + src/main/java/net/minecraft/server/TileEntity.java | 2 + + src/main/java/net/minecraft/server/World.java | 17 ++++ + .../java/net/minecraft/server/WorldServer.java | 4 + + .../java/org/bukkit/craftbukkit/SpigotTimings.java | 111 +++++++++++++++++++++ + .../bukkit/craftbukkit/scheduler/CraftTask.java | 18 ++++ + 10 files changed, 190 insertions(+), 1 deletion(-) + create mode 100644 src/main/java/org/bukkit/craftbukkit/SpigotTimings.java + +diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java +index c0bab0f..5772932 100644 +--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java ++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java +@@ -103,6 +103,7 @@ public class ChunkProviderServer implements IChunkProvider { + // CraftBukkit end + + if (chunk == null) { ++ org.bukkit.craftbukkit.SpigotTimings.syncChunkLoadTimer.startTiming(); // Spigot + chunk = this.loadChunk(i, j); + if (chunk == null) { + if (this.chunkProvider == null) { +@@ -141,6 +142,7 @@ public class ChunkProviderServer implements IChunkProvider { + // CraftBukkit end + + chunk.a(this, this, i, j); ++ org.bukkit.craftbukkit.SpigotTimings.syncChunkLoadTimer.stopTiming(); // Spigot + } + + // CraftBukkit start - If we didn't need to load the chunk run the callback now +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index d0a58f8..bf9108a 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -15,6 +15,7 @@ import org.bukkit.block.BlockFace; + import org.bukkit.entity.LivingEntity; + import org.bukkit.entity.Painting; + import org.bukkit.entity.Vehicle; ++import org.bukkit.CustomTimingsHandler; // Spigot + import org.bukkit.event.entity.EntityCombustByEntityEvent; + import org.bukkit.event.painting.PaintingBreakByEntityEvent; + import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; +@@ -111,6 +112,8 @@ public abstract class Entity { + public UUID uniqueId = UUID.randomUUID(); // CraftBukkit + public boolean valid = false; // CraftBukkit + ++ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot ++ + public Entity(World world) { + this.id = entityCount++; + this.l = 1.0D; +@@ -424,6 +427,7 @@ public abstract class Entity { + + public void move(double d0, double d1, double d2) { + if (d0 == 0 && d1 == 0 && d2 == 0) { return; } // Spigot ++ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot + if (this.Y) { + this.boundingBox.d(d0, d1, d2); + this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D; +@@ -729,6 +733,7 @@ public abstract class Entity { + + this.world.methodProfiler.b(); + } ++ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot + } + + protected void D() { +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index 7d2e633..bd1aeaa 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -505,6 +505,7 @@ public abstract class EntityLiving extends Entity { + } + + public void j_() { ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot + super.j_(); + if (!this.world.isStatic) { + int i; +@@ -531,7 +532,9 @@ public abstract class EntityLiving extends Entity { + } + } + ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot + this.c(); ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityTickRest.startTiming(); // Spigot + double d0 = this.locX - this.lastX; + double d1 = this.locZ - this.lastZ; + float f = (float) (d0 * d0 + d1 * d1); +@@ -622,6 +625,7 @@ public abstract class EntityLiving extends Entity { + + this.world.methodProfiler.b(); + this.aD += f2; ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot + } + + // CraftBukkit start - delegate so we can handle providing a reason for health being regained +@@ -1228,6 +1232,7 @@ public abstract class EntityLiving extends Entity { + } + + public void c() { ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityAI.startTiming(); // Spigot + if (this.bV > 0) { + --this.bV; + } +@@ -1279,6 +1284,7 @@ public abstract class EntityLiving extends Entity { + this.az = this.yaw; + } + } ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityAI.stopTiming(); // Spigot + + this.world.methodProfiler.b(); + this.world.methodProfiler.a("jump"); +@@ -1297,6 +1303,7 @@ public abstract class EntityLiving extends Entity { + + this.world.methodProfiler.b(); + this.world.methodProfiler.a("travel"); ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityAIMove.startTiming(); // Spigot + this.bC *= 0.98F; + this.bD *= 0.98F; + this.bE *= 0.9F; +@@ -1305,11 +1312,14 @@ public abstract class EntityLiving extends Entity { + this.aN *= this.bB(); + this.e(this.bC, this.bD); + this.aN = f; ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot + this.world.methodProfiler.b(); + this.world.methodProfiler.a("push"); ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityAICollision.startTiming(); // Spigot + if (!this.world.isStatic) { + this.bd(); + } ++ org.bukkit.craftbukkit.SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot + + this.world.methodProfiler.b(); + this.world.methodProfiler.a("looting"); +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 128016f..aa6a14a 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -6,7 +6,6 @@ import java.security.KeyPair; + import java.text.SimpleDateFormat; + import java.util.ArrayList; + import java.util.Date; +-import java.util.Iterator; + import java.util.List; + import java.util.concurrent.Callable; + import java.util.logging.Level; +@@ -21,6 +20,7 @@ import jline.console.ConsoleReader; + import joptsimple.OptionSet; + + import org.bukkit.World.Environment; ++import org.bukkit.craftbukkit.SpigotTimings; // Spigot + import org.bukkit.craftbukkit.util.Waitable; + import org.bukkit.event.server.RemoteServerCommandEvent; + import org.bukkit.event.world.WorldSaveEvent; +@@ -417,7 +417,10 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + currentTPS = (currentTPS * 0.95) + (1E9 / (curTime - lastTick) * 0.05); + lastTick = curTime; + MinecraftServer.currentTick++; ++ SpigotTimings.serverTickTimer.startTiming(); + this.q(); ++ SpigotTimings.serverTickTimer.stopTiming(); ++ org.bukkit.CustomTimingsHandler.tick(); + } + // Spigot end + } else { +@@ -517,6 +520,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + this.methodProfiler.a("levels"); + + // CraftBukkit start - only send timeupdates to the people in that world ++ SpigotTimings.schedulerTimer.startTiming(); // Spigot + this.server.getScheduler().mainThreadHeartbeat(this.ticks); + + // Run tasks that are waiting on processing +@@ -524,7 +528,10 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + processQueue.remove().run(); + } + ++ SpigotTimings.schedulerTimer.stopTiming(); // Spigot ++ SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot + org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick(); ++ SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot + + // Send timeupdates to everyone, it will get the right time from the world the player is in. + if (this.ticks % 20 == 0) { +@@ -576,7 +583,9 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + + this.methodProfiler.b(); + this.methodProfiler.a("tracker"); ++ worldserver.timings.tracker.startTiming(); // Spigot + worldserver.getTracker().updatePlayers(); ++ worldserver.timings.tracker.stopTiming(); // Spigot + this.methodProfiler.b(); + this.methodProfiler.b(); + // } // CraftBukkit +@@ -585,14 +594,20 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + } + + this.methodProfiler.c("connection"); ++ SpigotTimings.connectionTimer.startTiming(); // Spigot + this.ae().b(); ++ SpigotTimings.connectionTimer.stopTiming(); // Spigot + this.methodProfiler.c("players"); ++ SpigotTimings.playerListTimer.startTiming(); // Spigot + this.t.tick(); ++ SpigotTimings.playerListTimer.stopTiming(); // Spigot + this.methodProfiler.c("tickables"); + ++ SpigotTimings.tickablesTimer.startTiming(); // Spigot + for (i = 0; i < this.p.size(); ++i) { + ((IUpdatePlayerListBox) this.p.get(i)).a(); + } ++ SpigotTimings.tickablesTimer.stopTiming(); // Spigot + + this.methodProfiler.b(); + } +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 43a24f5..d2c2305 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -976,6 +976,7 @@ public class PlayerConnection extends Connection { + // CraftBukkit end + + private void handleCommand(String s) { ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot + // CraftBukkit start + CraftPlayer player = this.getPlayer(); + +@@ -983,19 +984,23 @@ public class PlayerConnection extends Connection { + this.server.getPluginManager().callEvent(event); + + if (event.isCancelled()) { ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } + + try { + if (server.logCommands) logger.info(event.getPlayer().getName() + " issued server command: " + event.getMessage()); // Spigot + if (this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) { ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } + } catch (org.bukkit.command.CommandException ex) { + player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); + Logger.getLogger(PlayerConnection.class.getName()).log(Level.SEVERE, null, ex); ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + // CraftBukkit end + + /* CraftBukkit start - No longer needed as we have already handled it in server.dispatchServerCommand above. +diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java +index d8eb6b9..b6b0d5f 100644 +--- a/src/main/java/net/minecraft/server/TileEntity.java ++++ b/src/main/java/net/minecraft/server/TileEntity.java +@@ -4,10 +4,12 @@ import java.util.HashMap; + import java.util.Map; + import java.util.concurrent.Callable; + ++import org.bukkit.CustomTimingsHandler; // Spigot + import org.bukkit.inventory.InventoryHolder; // CraftBukkit + + public class TileEntity { + ++ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot + private static Map a = new HashMap(); + private static Map b = new HashMap(); + public World world; // CraftBukkit - protected -> public +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 41f4f31..ec1a08f 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -13,6 +13,7 @@ import java.util.concurrent.Callable; + // CraftBukkit start + import org.bukkit.Bukkit; + import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.craftbukkit.SpigotTimings; // Spigot + import org.bukkit.craftbukkit.util.UnsafeList; + import org.bukkit.generator.ChunkGenerator; + import org.bukkit.craftbukkit.CraftServer; +@@ -114,6 +115,8 @@ public abstract class World implements IBlockAccess { + final Object chunkLock = new Object(); + private byte chunkTickRadius; + ++ public final SpigotTimings.WorldTimingsHandler timings; // Spigot ++ + public CraftWorld getWorld() { + return this.world; + } +@@ -193,6 +196,7 @@ public abstract class World implements IBlockAccess { + this.a(); + + this.getServer().addWorld(this.world); // CraftBukkit ++ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot + } + + protected abstract IChunkProvider j(); +@@ -1259,6 +1263,7 @@ public abstract class World implements IBlockAccess { + this.f.clear(); + this.methodProfiler.c("regular"); + ++ timings.entityTick.startTiming(); // Spigot + for (i = 0; i < this.entityList.size(); ++i) { + entity = (Entity) this.entityList.get(i); + +@@ -1281,7 +1286,9 @@ public abstract class World implements IBlockAccess { + this.methodProfiler.a("tick"); + if (!entity.dead) { + try { ++ SpigotTimings.tickEntityTimer.startTiming(); // Spigot + this.playerJoinedWorld(entity); ++ SpigotTimings.tickEntityTimer.stopTiming(); // Spigot + } catch (Throwable throwable1) { + crashreport = CrashReport.a(throwable1, "Ticking entity"); + crashreportsystemdetails = crashreport.a("Entity being ticked"); +@@ -1311,7 +1318,9 @@ public abstract class World implements IBlockAccess { + this.methodProfiler.b(); + } + ++ timings.entityTick.stopTiming(); // Spigot + this.methodProfiler.c("tileEntities"); ++ timings.tileEntityTick.startTiming(); // Spigot + this.M = true; + Iterator iterator = this.tileEntityList.iterator(); + +@@ -1326,8 +1335,11 @@ public abstract class World implements IBlockAccess { + + if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) { + try { ++ tileentity.tickTimer.startTiming(); // Spigot + tileentity.g(); ++ tileentity.tickTimer.stopTiming(); // Spigot + } catch (Throwable throwable2) { ++ tileentity.tickTimer.stopTiming(); // Spigot + crashreport = CrashReport.a(throwable2, "Ticking tile entity"); + crashreportsystemdetails = crashreport.a("Tile entity being ticked"); + if (tileentity == null) { +@@ -1352,6 +1364,8 @@ public abstract class World implements IBlockAccess { + } + } + ++ timings.tileEntityTick.stopTiming(); // Spigot ++ timings.tileEntityPending.startTiming(); // Spigot + this.M = false; + if (!this.b.isEmpty()) { + this.tileEntityList.removeAll(this.b); +@@ -1390,6 +1404,7 @@ public abstract class World implements IBlockAccess { + this.a.clear(); + } + ++ timings.tileEntityPending.stopTiming(); // Spigot + this.methodProfiler.b(); + this.methodProfiler.b(); + } +@@ -1412,6 +1427,7 @@ public abstract class World implements IBlockAccess { + byte b0 = 32; + + if (!flag || this.d(i - b0, 0, j - b0, i + b0, 0, j + b0)) { ++ entity.tickTimer.startTiming(); // Spigot + entity.T = entity.locX; + entity.U = entity.locY; + entity.V = entity.locZ; +@@ -1473,6 +1489,7 @@ public abstract class World implements IBlockAccess { + entity.passenger = null; + } + } ++ entity.tickTimer.stopTiming(); // Spigot + } + } + +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 4aa2a19..6cb3e24 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -157,9 +157,12 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate + // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals + long time = this.worldData.getTime(); + if (this.getGameRules().getBoolean("doMobSpawning") && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) { ++ timings.mobSpawn.startTiming(); // Spigot + SpawnerCreature.spawnEntities(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L); ++ timings.mobSpawn.stopTiming(); // Spigot + } + // CraftBukkit end ++ timings.doTickRest.startTiming(); // Spigot + this.methodProfiler.c("chunkSource"); + this.chunkProvider.unloadChunks(); + int j = this.a(1.0F); +@@ -186,6 +189,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate + this.V(); + + this.getWorld().processChunkGC(); // CraftBukkit ++ timings.doTickRest.stopTiming(); // Spigot + } + + public BiomeMeta a(EnumCreatureType enumcreaturetype, int i, int j, int k) { +diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java +new file mode 100644 +index 0000000..df837a3 +--- /dev/null ++++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java +@@ -0,0 +1,111 @@ ++package org.bukkit.craftbukkit; ++ ++import net.minecraft.server.*; ++import org.bukkit.CustomTimingsHandler; ++import org.bukkit.plugin.Plugin; ++import org.bukkit.scheduler.BukkitTask; ++ ++import java.util.HashMap; ++ ++public class SpigotTimings { ++ ++ public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick"); ++ public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List"); ++ public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection"); ++ public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables"); ++ public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler"); ++ public static final CustomTimingsHandler chunkIOTickTimer = new CustomTimingsHandler("ChunkIOTick"); ++ public static final CustomTimingsHandler syncChunkLoadTimer = new CustomTimingsHandler("syncChunkLoad"); ++ ++ public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove"); ++ public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity"); ++ public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity"); ++ public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity"); ++ ++ public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick"); ++ public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI"); ++ public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision"); ++ public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove"); ++ public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest"); ++ ++ public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand"); ++ ++ public static final HashMap entityTypeTimingMap = new HashMap(); ++ public static final HashMap tileEntityTypeTimingMap = new HashMap(); ++ public static final HashMap pluginTaskTimingMap = new HashMap(); ++ ++ /** ++ * Gets a timer associated with a plugins tasks. ++ * @param task ++ * @param period ++ * @return ++ */ ++ public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) { ++ String plugin = task.getOwner().getDescription().getFullName(); ++ if (period > 0) { ++ String name = "Task: " + plugin +" Id:(interval:" + period + ":id:"+task.getTaskId()+")"; ++ return new CustomTimingsHandler(name); ++ } else { ++ String name = "Task: " + plugin + " Id:(Single)"; ++ CustomTimingsHandler result = pluginTaskTimingMap.get(name); ++ if (result == null) { ++ result = new CustomTimingsHandler(name); ++ pluginTaskTimingMap.put(name, result); ++ } ++ return result; ++ } ++ } ++ ++ /** ++ * Get a named timer for the specified entity type to track type specific timings. ++ * @param entity ++ * @return ++ */ ++ public static CustomTimingsHandler getEntityTimings(Entity entity) { ++ String entityType = entity.getClass().getSimpleName(); ++ CustomTimingsHandler result = entityTypeTimingMap.get(entityType); ++ if (result == null) { ++ result = new CustomTimingsHandler("** tickEntity - " + entityType, activatedEntityTimer); ++ entityTypeTimingMap.put(entityType, result); ++ } ++ return result; ++ } ++ ++ /** ++ * Get a named timer for the specified tile entity type to track type specific timings. ++ * @param entity ++ * @return ++ */ ++ public static CustomTimingsHandler getTileEntityTimings(TileEntity entity) { ++ String entityType = entity.getClass().getSimpleName(); ++ CustomTimingsHandler result = tileEntityTypeTimingMap.get(entityType); ++ if (result == null) { ++ result = new CustomTimingsHandler("** tickTileEntity - " + entityType, tickTileEntityTimer); ++ tileEntityTypeTimingMap.put(entityType, result); ++ } ++ return result; ++ } ++ ++ /** ++ * Set of timers per world, to track world specific timings. ++ */ ++ public static class WorldTimingsHandler { ++ public final CustomTimingsHandler mobSpawn; ++ public final CustomTimingsHandler doTickRest; ++ public final CustomTimingsHandler entityTick; ++ public final CustomTimingsHandler tileEntityTick; ++ public final CustomTimingsHandler tileEntityPending; ++ public final CustomTimingsHandler tracker; ++ ++ public WorldTimingsHandler(World server) { ++ String name = server.worldData.getName() +" - "; ++ ++ mobSpawn = new CustomTimingsHandler(name + "mobSpawn"); ++ doTickRest = new CustomTimingsHandler(name + "doTickRest"); ++ entityTick = new CustomTimingsHandler(name + "entityTick"); ++ tileEntityTick = new CustomTimingsHandler(name + "tileEntityTick"); ++ tileEntityPending = new CustomTimingsHandler(name + "tileEntityPending"); ++ tracker = new CustomTimingsHandler(name + "tracker"); ++ } ++ } ++} +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +index 55db3ff..df134e3 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +@@ -1,6 +1,8 @@ + package org.bukkit.craftbukkit.scheduler; + + import org.bukkit.Bukkit; ++import org.bukkit.craftbukkit.SpigotTimings; // Spigot ++import org.bukkit.CustomTimingsHandler; // Spigot + import org.bukkit.plugin.Plugin; + import org.bukkit.scheduler.BukkitTask; + +@@ -22,6 +24,7 @@ class CraftTask implements BukkitTask, Runnable { + private final Plugin plugin; + private final int id; + ++ CustomTimingsHandler timings = null; // Spigot + CraftTask() { + this(null, null, -1, -1); + } +@@ -50,7 +53,22 @@ class CraftTask implements BukkitTask, Runnable { + } + + public void run() { ++ // Spigot start - Wrap custom timings on Tasks ++ if (!Bukkit.getServer().getPluginManager().useTimings()) { ++ task.run(); ++ return; ++ } ++ if (timings == null && this.getOwner() != null && this.isSync()) { ++ timings = SpigotTimings.getPluginTaskTimings(this, period); ++ } ++ if (timings != null) { ++ timings.startTiming(); ++ } + task.run(); ++ if (timings != null) { ++ timings.stopTiming(); ++ } ++ // Spigot end + } + + long getPeriod() { +-- +1.8.1.1 + diff --git a/CraftBukkit-Patches/0017-Better-more-flexible-itemstack-merging.patch b/CraftBukkit-Patches/0018-Better-more-flexible-itemstack-merging.patch similarity index 95% rename from CraftBukkit-Patches/0017-Better-more-flexible-itemstack-merging.patch rename to CraftBukkit-Patches/0018-Better-more-flexible-itemstack-merging.patch index 30e62bf03..1f01abe02 100644 --- a/CraftBukkit-Patches/0017-Better-more-flexible-itemstack-merging.patch +++ b/CraftBukkit-Patches/0018-Better-more-flexible-itemstack-merging.patch @@ -1,4 +1,4 @@ -From f36116f21a496382c52e7cd3f0f97820c183fc49 Mon Sep 17 00:00:00 2001 +From a21753931b6180bc32da505ed261fce5ea0461c9 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 25 Jan 2013 18:24:54 +1100 Subject: [PATCH] Better + more flexible itemstack merging @@ -40,10 +40,10 @@ index a7baa0f..5e3ac84 100644 } } else { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index c914461..88007c3 100644 +index ec1a08f..2fe9b1d 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -923,31 +923,8 @@ public abstract class World implements IBlockAccess { +@@ -924,31 +924,8 @@ public abstract class World implements IBlockAccess { event = CraftEventFactory.callCreatureSpawnEvent((EntityLiving) entity, spawnReason); } else if (entity instanceof EntityItem) { event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity); @@ -77,7 +77,7 @@ index c914461..88007c3 100644 EntityExperienceOrb xp = (EntityExperienceOrb) entity; double radius = this.getWorld().expMergeRadius; if (radius > 0) { -@@ -962,8 +939,8 @@ public abstract class World implements IBlockAccess { +@@ -963,8 +940,8 @@ public abstract class World implements IBlockAccess { } } } @@ -89,5 +89,5 @@ index c914461..88007c3 100644 event = CraftEventFactory.callProjectileLaunchEvent(entity); } -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0018-Add-oreobfuscator-for-Spigot.patch b/CraftBukkit-Patches/0019-Add-oreobfuscator-for-Spigot.patch similarity index 98% rename from CraftBukkit-Patches/0018-Add-oreobfuscator-for-Spigot.patch rename to CraftBukkit-Patches/0019-Add-oreobfuscator-for-Spigot.patch index f3cba7f2e..20ac57715 100644 --- a/CraftBukkit-Patches/0018-Add-oreobfuscator-for-Spigot.patch +++ b/CraftBukkit-Patches/0019-Add-oreobfuscator-for-Spigot.patch @@ -1,4 +1,4 @@ -From f7efe872d9e6c29ebdc4f8c9857a8724eee1300d Mon Sep 17 00:00:00 2001 +From 57dc2265b21dba57997f39f0ba07f6ca8a1fff5d Mon Sep 17 00:00:00 2001 From: lishid Date: Sat, 16 Feb 2013 10:05:25 +1100 Subject: [PATCH] Add oreobfuscator for Spigot. @@ -170,7 +170,7 @@ index 94e07fe..21bd64a 100644 public int cactusGrowthModifier = 100; diff --git a/src/main/java/org/bukkit/craftbukkit/OrebfuscatorManager.java b/src/main/java/org/bukkit/craftbukkit/OrebfuscatorManager.java new file mode 100644 -index 0000000..fe14f6d +index 0000000..5213f99 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/OrebfuscatorManager.java @@ -0,0 +1,146 @@ @@ -180,7 +180,7 @@ index 0000000..fe14f6d +import java.util.List; +import net.minecraft.server.Block; +import net.minecraft.server.World; -+import org.bukkit.event.CustomTimingsHandler; ++import org.bukkit.CustomTimingsHandler; + +public class OrebfuscatorManager { + @@ -321,10 +321,10 @@ index 0000000..fe14f6d + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java -index 4a4f949..3bfeb49 100644 +index db46037..ad65bca 100644 --- a/src/main/java/org/bukkit/craftbukkit/Spigot.java +++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java -@@ -13,6 +13,14 @@ public class Spigot { +@@ -15,6 +15,14 @@ public class Spigot { server.commandComplete = configuration.getBoolean("settings.command-complete", true); server.spamGuardExclusions = configuration.getStringList("settings.spam-exclusions"); @@ -354,5 +354,5 @@ index 0c92b66..78e9a66 100644 + disabled-worlds: + - world_the_end -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0019-Reduce-number-of-LivingEntity-collision-checks.patch b/CraftBukkit-Patches/0020-Reduce-number-of-LivingEntity-collision-checks.patch similarity index 87% rename from CraftBukkit-Patches/0019-Reduce-number-of-LivingEntity-collision-checks.patch rename to CraftBukkit-Patches/0020-Reduce-number-of-LivingEntity-collision-checks.patch index 9eaf78251..1973d4a3f 100644 --- a/CraftBukkit-Patches/0019-Reduce-number-of-LivingEntity-collision-checks.patch +++ b/CraftBukkit-Patches/0020-Reduce-number-of-LivingEntity-collision-checks.patch @@ -1,4 +1,4 @@ -From aedb805a7d9546c33994de3acee0da1814c0f6b5 Mon Sep 17 00:00:00 2001 +From a9525c7ac96f2692c584fcbd9c6469271e226364 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 18 Jan 2013 19:31:14 -0500 Subject: [PATCH] Reduce number of LivingEntity collision checks. @@ -8,10 +8,10 @@ Subject: [PATCH] Reduce number of LivingEntity collision checks. 1 file changed, 8 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index b2481aa..bbbb008 100644 +index bd1aeaa..01b16ac 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -1402,12 +1402,20 @@ public abstract class EntityLiving extends Entity { +@@ -1391,12 +1391,20 @@ public abstract class EntityLiving extends Entity { } protected void bd() { @@ -33,5 +33,5 @@ index b2481aa..bbbb008 100644 this.o(entity); } -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0020-Only-count-entities-in-chunks-being-processed-for-th.patch b/CraftBukkit-Patches/0021-Only-count-entities-in-chunks-being-processed-for-th.patch similarity index 98% rename from CraftBukkit-Patches/0020-Only-count-entities-in-chunks-being-processed-for-th.patch rename to CraftBukkit-Patches/0021-Only-count-entities-in-chunks-being-processed-for-th.patch index 3f4ebfcf6..45050799b 100644 --- a/CraftBukkit-Patches/0020-Only-count-entities-in-chunks-being-processed-for-th.patch +++ b/CraftBukkit-Patches/0021-Only-count-entities-in-chunks-being-processed-for-th.patch @@ -1,4 +1,4 @@ -From 7a0b264ffa3d6c7d4110f3e25059cc3f1bffee88 Mon Sep 17 00:00:00 2001 +From 0699ed06c2f350269703b4f2c62a268c80e1d9d2 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 29 Jan 2013 13:25:53 -0500 Subject: [PATCH] Only count entities in chunks being processed for the spawn @@ -105,5 +105,5 @@ index 9b3e262..2173af7 100644 continue label110; } -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0021-Only-send-maps-in-item-frames-upon-tracking.patch b/CraftBukkit-Patches/0022-Only-send-maps-in-item-frames-upon-tracking.patch similarity index 98% rename from CraftBukkit-Patches/0021-Only-send-maps-in-item-frames-upon-tracking.patch rename to CraftBukkit-Patches/0022-Only-send-maps-in-item-frames-upon-tracking.patch index e70cccbd8..ea0ce39ea 100644 --- a/CraftBukkit-Patches/0021-Only-send-maps-in-item-frames-upon-tracking.patch +++ b/CraftBukkit-Patches/0022-Only-send-maps-in-item-frames-upon-tracking.patch @@ -1,4 +1,4 @@ -From d2a991ef24ccf92299160afc6a56128eed966733 Mon Sep 17 00:00:00 2001 +From 14f2f48d062b71bdd20a50cb8bbd3a7a8a0d3621 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 19 Feb 2013 17:26:20 -0500 Subject: [PATCH] Only send maps in item frames upon tracking @@ -85,5 +85,5 @@ index a026c4c..75c146d 100644 } } -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0022-Detect-remove-and-warn-about-null-tile-entities.patch b/CraftBukkit-Patches/0023-Detect-remove-and-warn-about-null-tile-entities.patch similarity index 87% rename from CraftBukkit-Patches/0022-Detect-remove-and-warn-about-null-tile-entities.patch rename to CraftBukkit-Patches/0023-Detect-remove-and-warn-about-null-tile-entities.patch index e13c2db69..a482c74c9 100644 --- a/CraftBukkit-Patches/0022-Detect-remove-and-warn-about-null-tile-entities.patch +++ b/CraftBukkit-Patches/0023-Detect-remove-and-warn-about-null-tile-entities.patch @@ -1,4 +1,4 @@ -From 04cff8e45e1fe99b3679b15d672c41ac1de31ffb Mon Sep 17 00:00:00 2001 +From 5f8e123bf8262bf21389a5cac3396188c7097463 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 3 Feb 2013 09:20:19 +1100 Subject: [PATCH] Detect, remove and warn about null tile entities. @@ -8,10 +8,10 @@ Subject: [PATCH] Detect, remove and warn about null tile entities. 1 file changed, 7 insertions(+) diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 88007c3..9f05a52 100644 +index 2fe9b1d..4fc1233 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1302,6 +1302,13 @@ public abstract class World implements IBlockAccess { +@@ -1303,6 +1303,13 @@ public abstract class World implements IBlockAccess { while (iterator.hasNext()) { TileEntity tileentity = (TileEntity) iterator.next(); @@ -26,5 +26,5 @@ index 88007c3..9f05a52 100644 ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer; if (chunkProviderServer.unloadQueue.contains(tileentity.x >> 4, tileentity.z >> 4)) { -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0024-Entity-Activation-Range-This-feature-gives-3-new-con.patch b/CraftBukkit-Patches/0024-Entity-Activation-Range-This-feature-gives-3-new-con.patch deleted file mode 100644 index ee2fd4788..000000000 --- a/CraftBukkit-Patches/0024-Entity-Activation-Range-This-feature-gives-3-new-con.patch +++ /dev/null @@ -1,327 +0,0 @@ -From 45fe88e1961a395c0330f1056ef602444cb963eb Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 16 Feb 2013 19:45:09 +1100 -Subject: [PATCH] Entity Activation Range# This feature gives 3 new - configurable ranges that if an entity of the matching type is outside of this - radius of any player, will tick at 5% of its normal rate. - -This will drastically cut down on tick timings for entities that are not in range of a user to actually be "used". -This change can have dramatic impact on gameplay if configured too low. Balance according to your servers desired gameplay. ---- - src/main/java/net/minecraft/server/Entity.java | 8 ++ - .../java/net/minecraft/server/EntityArrow.java | 2 +- - src/main/java/net/minecraft/server/World.java | 3 +- - .../java/org/bukkit/craftbukkit/CraftWorld.java | 13 ++ - src/main/java/org/bukkit/craftbukkit/Spigot.java | 149 +++++++++++++++++++++ - .../java/org/bukkit/event/WorldTimingsHandler.java | 2 + - src/main/resources/configurations/bukkit.yml | 3 + - 7 files changed, 178 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index d0a58f8..9da5035 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -111,6 +111,13 @@ public abstract class Entity { - public UUID uniqueId = UUID.randomUUID(); // CraftBukkit - public boolean valid = false; // CraftBukkit - -+ // Spigot start -+ public boolean inWater = false; -+ public final byte activationType = org.bukkit.craftbukkit.Spigot.initializeEntityActivationType(this); -+ public final boolean defaultActivationState = org.bukkit.craftbukkit.Spigot.initializeEntityActivationState(this); -+ public boolean isActivated = defaultActivationState; -+ // Spigot end -+ - public Entity(World world) { - this.id = entityCount++; - this.l = 1.0D; -@@ -862,6 +869,7 @@ public abstract class Entity { - this.ad = false; - } - -+ this.inWater = this.ad; // Spigot - return this.ad; - } - -diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java -index 916b9dc..bdd18f6 100644 ---- a/src/main/java/net/minecraft/server/EntityArrow.java -+++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -16,7 +16,7 @@ public class EntityArrow extends Entity implements IProjectile { - private int f = -1; - private int g = 0; - private int h = 0; -- private boolean inGround = false; -+ public boolean inGround = false; // Spigot - private -> public - public int fromPlayer = 0; - public int shake = 0; - public Entity shooter; -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 9f05a52..b1ccf1f 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -1241,6 +1241,7 @@ public abstract class World implements IBlockAccess { - this.methodProfiler.c("regular"); - timings.entityBaseTick.stopTiming(); // Spigot - -+ org.bukkit.craftbukkit.Spigot.activateEntities(this); // Spigot - timings.entityTick.startTiming(); // Spigot - for (i = 0; i < this.entityList.size(); ++i) { - entity = (Entity) this.entityList.get(i); -@@ -1404,7 +1405,7 @@ public abstract class World implements IBlockAccess { - int j = MathHelper.floor(entity.locZ); - byte b0 = 32; - -- if (!flag || this.d(i - b0, 0, j - b0, i + b0, 0, j + b0)) { -+ if (entity instanceof EntityFireworks || !flag || this.d(i - b0, 0, j - b0, i + b0, 0, j + b0)) { // Spigot - Not safe to skip a firework. - entity.T = entity.locX; - entity.U = entity.locY; - entity.V = entity.locZ; -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 21bd64a..a083ae4 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -100,6 +100,10 @@ public class CraftWorld implements World { - treeGrowthModifier = configuration.getInt("world-settings.default.tree-growth-modifier", treeGrowthModifier); - mushroomGrowthModifier = configuration.getInt("world-settings.default.mushroom-growth-modifier", mushroomGrowthModifier); - -+ miscEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-misc", miscEntityActivationRange); -+ animalEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-animals", animalEntityActivationRange); -+ monsterEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-monsters", monsterEntityActivationRange); -+ - //override defaults with world specific, if they exist - growthPerTick = configuration.getInt("world-settings." + name + ".growth-chunks-per-tick", growthPerTick); - itemMergeRadius = configuration.getDouble("world-settings." + name + ".item-merge-radius", itemMergeRadius); -@@ -121,6 +125,10 @@ public class CraftWorld implements World { - - obfuscated = !world.getServer().orebfuscatorDisabledWorlds.contains(name); - -+ miscEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-misc", miscEntityActivationRange); -+ animalEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-animals", animalEntityActivationRange); -+ monsterEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-monsters", monsterEntityActivationRange); -+ - server.getLogger().info("-------------- Spigot ----------------"); - server.getLogger().info("-------- World Settings For [" + name + "] --------"); - server.getLogger().info("Growth Per Chunk: " + growthPerTick); -@@ -138,6 +146,7 @@ public class CraftWorld implements World { - server.getLogger().info("Mushroom Growth Modifier: " + mushroomGrowthModifier); - server.getLogger().info("View distance: " + viewDistance); - server.getLogger().info("Oreobfuscator: " + obfuscated); -+ server.getLogger().info("Entity Activation Range: An " + animalEntityActivationRange + " / Mo " + monsterEntityActivationRange + " / Mi " + miscEntityActivationRange); - server.getLogger().info("-------------------------------------------------"); - // Spigot end - } -@@ -158,6 +167,10 @@ public class CraftWorld implements World { - public int sugarGrowthModifier = 100; - public int treeGrowthModifier = 100; - public int mushroomGrowthModifier = 100; -+ -+ public int miscEntityActivationRange = 0; -+ public int animalEntityActivationRange = 0; -+ public int monsterEntityActivationRange = 0; - // Spigot end - - public Block getBlockAt(int x, int y, int z) { -diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java -index ad65bca..bc28d7b 100644 ---- a/src/main/java/org/bukkit/craftbukkit/Spigot.java -+++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java -@@ -1,7 +1,10 @@ - package org.bukkit.craftbukkit; - -+import java.util.ArrayList; -+import net.minecraft.server.*; - import org.bukkit.command.SimpleCommandMap; - import org.bukkit.configuration.file.YamlConfiguration; -+import java.util.List; - - public class Spigot { - -@@ -26,5 +29,151 @@ public class Spigot { - if (server.chunkGCPeriod == 0) { - server.getLogger().severe("[Spigot] You should not disable chunk-gc, unexpected behaviour may occur!"); - } -+ -+ } -+ -+ /** -+ * Initializes an entities type on construction to specify what group this -+ * entity is in for activation ranges. -+ * -+ * @param entity -+ * @return group id -+ */ -+ public static byte initializeEntityActivationType(Entity entity) { -+ if (entity instanceof EntityMonster || entity instanceof EntitySlime) { -+ return 1; // Monster -+ } else if (entity instanceof EntityCreature || entity instanceof EntityAmbient) { -+ return 2; // Animal -+ } else { -+ return 3; // Misc -+ } -+ } -+ -+ /** -+ * These entities are excluded from Activation range checks. -+ * -+ * @param entity -+ * @return boolean If it should always tick. -+ */ -+ public static boolean initializeEntityActivationState(Entity entity) { -+ if (entity instanceof EntityHuman -+ || entity instanceof EntityArrow -+ || entity instanceof EntityProjectile -+ || entity instanceof EntityEnderDragon -+ || entity instanceof EntityComplexPart -+ || entity instanceof EntityWither -+ || entity instanceof EntityFireball -+ || entity instanceof EntityWeather -+ || entity instanceof EntityTNTPrimed -+ || entity instanceof EntityEnderCrystal -+ || entity instanceof EntityFireworks) { -+ return true; -+ } -+ return false; -+ } -+ -+ /** -+ * Utility method to grow an AABB without creating a new AABB or touching -+ * the pool, so we can re-use ones we have. -+ * -+ * @param target -+ * @param source -+ * @param x -+ * @param y -+ * @param z -+ */ -+ public static void growBB(AxisAlignedBB target, AxisAlignedBB source, int x, int y, int z) { -+ target.a = source.a - x; -+ target.b = source.b - y; -+ target.c = source.c - z; -+ target.d = source.d + x; -+ target.e = source.e + y; -+ target.f = source.f + z; -+ } -+ -+ /** -+ * Find what entities are in range of the players in the world and set -+ * active if in range. -+ * -+ * @param world -+ */ -+ public static void activateEntities(World world) { -+ final int miscActivationRange = world.getWorld().miscEntityActivationRange; -+ final int animalActivationRange = world.getWorld().animalEntityActivationRange; -+ final int monsterActivationRange = world.getWorld().monsterEntityActivationRange; -+ -+ -+ world.timings.activationCheck.startTiming(); -+ int maxRange = Math.max(monsterActivationRange, animalActivationRange); -+ maxRange = Math.max(maxRange, miscActivationRange); -+ if (miscActivationRange == 0 || animalActivationRange == 0 || monsterActivationRange == 0) { -+ // One of them is disabled, set to view-distance -+ maxRange = world.getWorld().viewDistance << 4; -+ } else { -+ maxRange = Math.min(world.getWorld().viewDistance << 4, maxRange); // Do not tick on edge of unloaded chunks - vanilla behavior. -+ } -+ -+ AxisAlignedBB maxBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); -+ AxisAlignedBB miscBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); -+ AxisAlignedBB animalBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); -+ AxisAlignedBB monsterBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); -+ -+ for (Entity player : new ArrayList(world.players)) { -+ growBB(maxBB, player.boundingBox, maxRange, 256, maxRange); -+ growBB(miscBB, player.boundingBox, miscActivationRange, 256, miscActivationRange); -+ growBB(animalBB, player.boundingBox, animalActivationRange, 256, animalActivationRange); -+ growBB(monsterBB, player.boundingBox, monsterActivationRange, 256, monsterActivationRange); -+ -+ final List list = world.getEntities(player, maxBB); -+ for (Entity entity : list) { -+ if (!entity.defaultActivationState) { -+ boolean isInRange = false; -+ switch (entity.activationType) { -+ case 1: -+ if (monsterActivationRange == 0 || monsterBB.a(entity.boundingBox)) { -+ isInRange = true; -+ } -+ break; -+ case 2: -+ if (animalActivationRange == 0 || animalBB.a(entity.boundingBox)) { -+ isInRange = true; -+ } -+ break; -+ case 3: -+ default: -+ if (miscActivationRange == 0 || miscBB.a(entity.boundingBox)) { -+ isInRange = true; -+ } -+ } -+ -+ entity.isActivated = isInRange; -+ } -+ } -+ } -+ world.timings.activationCheck.stopTiming(); -+ } -+ -+ /** -+ * If an entity is not in range, do some more checks to see if we should -+ * give it a shot. -+ * -+ * @param entity -+ * @return -+ */ -+ public static boolean checkIfActive(Entity entity) { -+ // quick checks. -+ if (entity.ticksLived % 20 == 0 || !entity.onGround || entity.inWater || entity.passenger != null || entity.vehicle != null) { -+ return true; -+ } -+ // special cases. -+ if (entity instanceof EntityAnimal) { -+ EntityAnimal animal = (EntityAnimal) entity; -+ if (animal.isBaby() || animal.r() /*love*/) { -+ return true; -+ } -+ return (entity instanceof EntitySheep && ((EntitySheep) entity).isSheared()); -+ } -+ return (entity instanceof EntityArrow && !((EntityArrow) entity).inGround); -+ - } - } -diff --git a/src/main/java/org/bukkit/event/WorldTimingsHandler.java b/src/main/java/org/bukkit/event/WorldTimingsHandler.java -index bb0c191..6a4a05e 100644 ---- a/src/main/java/org/bukkit/event/WorldTimingsHandler.java -+++ b/src/main/java/org/bukkit/event/WorldTimingsHandler.java -@@ -8,6 +8,7 @@ public class WorldTimingsHandler { - public CustomTimingsHandler entityBaseTick; - public CustomTimingsHandler entityTick; - public CustomTimingsHandler tileEntityTick; -+ public CustomTimingsHandler activationCheck; - public WorldTimingsHandler(World server) { - String name = server.worldData.getName() +" - "; - -@@ -16,5 +17,6 @@ public class WorldTimingsHandler { - entityBaseTick = new CustomTimingsHandler(name + "entityBaseTick"); - entityTick = new CustomTimingsHandler(name + "entityTick"); - tileEntityTick = new CustomTimingsHandler(name + "tileEntityTick"); -+ activationCheck = new CustomTimingsHandler("** " + name + "activateEntities"); - } - } -diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml -index 78e9a66..54e28db 100644 ---- a/src/main/resources/configurations/bukkit.yml -+++ b/src/main/resources/configurations/bukkit.yml -@@ -46,6 +46,9 @@ world-settings: - sugar-growth-modifier: 100 - tree-growth-modifier: 100 - mushroom-growth-modifier: 100 -+ entity-activation-range-animals: 48 -+ entity-activation-range-monsters: 48 -+ entity-activation-range-misc: 16 - world: - growth-chunks-per-tick: 1000 - world_nether: --- -1.8.1-rc2 - diff --git a/CraftBukkit-Patches/0024-Entity-Activation-Range.patch b/CraftBukkit-Patches/0024-Entity-Activation-Range.patch new file mode 100644 index 000000000..56d7d3837 --- /dev/null +++ b/CraftBukkit-Patches/0024-Entity-Activation-Range.patch @@ -0,0 +1,444 @@ +From a4fdbca267e36d8b233d2922a0104b208c3af50d Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 3 Feb 2013 05:10:21 -0500 +Subject: [PATCH] Entity Activation Range + +This feature gives 3 new configurable ranges that if an entity of the matching type is outside of this radius of any player, will tick at 5% of its normal rate. + +This will drastically cut down on tick timings for entities that are not in range of a user to actually be "used". +This change can have dramatic impact on gameplay if configured too low. Balance according to your servers desired gameplay. +--- + src/main/java/net/minecraft/server/Entity.java | 9 +- + .../java/net/minecraft/server/EntityArrow.java | 2 +- + src/main/java/net/minecraft/server/EntityItem.java | 5 +- + src/main/java/net/minecraft/server/World.java | 14 +- + .../java/org/bukkit/craftbukkit/CraftWorld.java | 15 +- + src/main/java/org/bukkit/craftbukkit/Spigot.java | 219 +++++++++++++++++++++ + .../java/org/bukkit/craftbukkit/SpigotTimings.java | 3 + + src/main/resources/configurations/bukkit.yml | 3 + + 8 files changed, 259 insertions(+), 11 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index bf9108a..807b4d1 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -89,7 +89,7 @@ public abstract class Entity { + public int ticksLived; + public int maxFireTicks; + public int fireTicks; // CraftBukkit - private -> public +- protected boolean ad; ++ public boolean ad; // Spigot - private -> public isInWater - If this renames, update Spigot.checkEntityImmunities + public int noDamageTicks; + private boolean justCreated; + protected boolean fireProof; +@@ -112,8 +112,14 @@ public abstract class Entity { + public UUID uniqueId = UUID.randomUUID(); // CraftBukkit + public boolean valid = false; // CraftBukkit + ++ // Spigot start + public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot + ++ public final byte activationType = org.bukkit.craftbukkit.Spigot.initializeEntityActivationType(this); ++ public final boolean defaultActivationState; ++ public long activatedTick = 0; ++ // Spigot end ++ + public Entity(World world) { + this.id = entityCount++; + this.l = 1.0D; +@@ -150,6 +156,7 @@ public abstract class Entity { + this.invulnerable = false; + this.as = EnumEntitySize.SIZE_2; + this.world = world; ++ this.defaultActivationState = org.bukkit.craftbukkit.Spigot.initializeEntityActivationState(this, world.getWorld()); // Spigot + this.setPosition(0.0D, 0.0D, 0.0D); + if (world != null) { + this.dimension = world.worldProvider.dimension; +diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java +index 916b9dc..bdd18f6 100644 +--- a/src/main/java/net/minecraft/server/EntityArrow.java ++++ b/src/main/java/net/minecraft/server/EntityArrow.java +@@ -16,7 +16,7 @@ public class EntityArrow extends Entity implements IProjectile { + private int f = -1; + private int g = 0; + private int h = 0; +- private boolean inGround = false; ++ public boolean inGround = false; // Spigot - private -> public + public int fromPlayer = 0; + public int shake = 0; + public Entity shooter; +diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java +index 5e3ac84..fdfd763 100644 +--- a/src/main/java/net/minecraft/server/EntityItem.java ++++ b/src/main/java/net/minecraft/server/EntityItem.java +@@ -100,8 +100,9 @@ public class EntityItem extends Entity { + if (this.onGround) { + this.motY *= -0.5D; + } +- } // Spigot +- ++this.age; ++ } ++ this.age = ticksLived; ++ // Spigot + if (!this.world.isStatic && this.age >= 6000) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 4fc1233..7d2bad3 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -13,6 +13,7 @@ import java.util.concurrent.Callable; + // CraftBukkit start + import org.bukkit.Bukkit; + import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.craftbukkit.Spigot; // Spigot + import org.bukkit.craftbukkit.SpigotTimings; // Spigot + import org.bukkit.craftbukkit.util.UnsafeList; + import org.bukkit.generator.ChunkGenerator; +@@ -1240,6 +1241,7 @@ public abstract class World implements IBlockAccess { + this.f.clear(); + this.methodProfiler.c("regular"); + ++ org.bukkit.craftbukkit.Spigot.activateEntities(this); // Spigot + timings.entityTick.startTiming(); // Spigot + for (i = 0; i < this.entityList.size(); ++i) { + entity = (Entity) this.entityList.get(i); +@@ -1406,12 +1408,12 @@ public abstract class World implements IBlockAccess { + } + + public void entityJoinedWorld(Entity entity, boolean flag) { +- int i = MathHelper.floor(entity.locX); +- int j = MathHelper.floor(entity.locZ); +- byte b0 = 32; +- +- if (!flag || this.d(i - b0, 0, j - b0, i + b0, 0, j + b0)) { +- entity.tickTimer.startTiming(); // Spigot ++ // Spigot start ++ if (!Spigot.checkIfActive(entity)) { ++ entity.ticksLived++; ++ } else { ++ entity.tickTimer.startTiming(); ++ // Spigot end + entity.T = entity.locX; + entity.U = entity.locY; + entity.V = entity.locZ; +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 21bd64a..33df602 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -100,10 +100,14 @@ public class CraftWorld implements World { + treeGrowthModifier = configuration.getInt("world-settings.default.tree-growth-modifier", treeGrowthModifier); + mushroomGrowthModifier = configuration.getInt("world-settings.default.mushroom-growth-modifier", mushroomGrowthModifier); + ++ miscEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-misc"); ++ animalEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-animals"); ++ monsterEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-monsters"); ++ + //override defaults with world specific, if they exist + growthPerTick = configuration.getInt("world-settings." + name + ".growth-chunks-per-tick", growthPerTick); + itemMergeRadius = configuration.getDouble("world-settings." + name + ".item-merge-radius", itemMergeRadius); +- expMergeRadius = configuration.getDouble("world-settings." + name + ".exp-merge-radius", expMergeRadius); ++ expMergeRadius = configuration.getDouble("world-settings." + name + ".exp-merge-radius", expMergeRadius); + randomLightingUpdates = configuration.getBoolean("world-settings." + name + ".random-light-updates", randomLightingUpdates); + mobSpawnRange = configuration.getInt("world-settings." + name + ".mob-spawn-range", mobSpawnRange); + aggregateTicks = Math.max(1, configuration.getInt("world-settings." + name + ".aggregate-chunkticks", aggregateTicks)); +@@ -121,6 +125,10 @@ public class CraftWorld implements World { + + obfuscated = !world.getServer().orebfuscatorDisabledWorlds.contains(name); + ++ miscEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-misc", miscEntityActivationRange); ++ animalEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-animals", animalEntityActivationRange); ++ monsterEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-monsters", monsterEntityActivationRange); ++ + server.getLogger().info("-------------- Spigot ----------------"); + server.getLogger().info("-------- World Settings For [" + name + "] --------"); + server.getLogger().info("Growth Per Chunk: " + growthPerTick); +@@ -138,6 +146,7 @@ public class CraftWorld implements World { + server.getLogger().info("Mushroom Growth Modifier: " + mushroomGrowthModifier); + server.getLogger().info("View distance: " + viewDistance); + server.getLogger().info("Oreobfuscator: " + obfuscated); ++ server.getLogger().info("Entity Activation Range: An " + animalEntityActivationRange + " / Mo " + monsterEntityActivationRange + " / Mi " + miscEntityActivationRange); + server.getLogger().info("-------------------------------------------------"); + // Spigot end + } +@@ -158,6 +167,10 @@ public class CraftWorld implements World { + public int sugarGrowthModifier = 100; + public int treeGrowthModifier = 100; + public int mushroomGrowthModifier = 100; ++ ++ public int miscEntityActivationRange = 16; ++ public int animalEntityActivationRange = 32; ++ public int monsterEntityActivationRange = 32; + // Spigot end + + public Block getBlockAt(int x, int y, int z) { +diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java +index ad65bca..572527f 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Spigot.java ++++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java +@@ -1,9 +1,16 @@ + package org.bukkit.craftbukkit; + ++import net.minecraft.server.*; + import org.bukkit.command.SimpleCommandMap; + import org.bukkit.configuration.file.YamlConfiguration; + ++import java.util.List; ++ + public class Spigot { ++ static AxisAlignedBB maxBB = AxisAlignedBB.a(0,0,0,0,0,0); ++ static AxisAlignedBB miscBB = AxisAlignedBB.a(0,0,0,0,0,0); ++ static AxisAlignedBB animalBB = AxisAlignedBB.a(0,0,0,0,0,0); ++ static AxisAlignedBB monsterBB = AxisAlignedBB.a(0,0,0,0,0,0); + + public static void initialize(CraftServer server, SimpleCommandMap commandMap, YamlConfiguration configuration) { + commandMap.register("bukkit", new org.bukkit.craftbukkit.command.TicksPerSecondCommand("tps")); +@@ -26,5 +33,217 @@ public class Spigot { + if (server.chunkGCPeriod == 0) { + server.getLogger().severe("[Spigot] You should not disable chunk-gc, unexpected behaviour may occur!"); + } ++ ++ } ++ ++ /** ++ * Initializes an entities type on construction to specify what group this ++ * entity is in for activation ranges. ++ * @param entity ++ * @return group id ++ */ ++ public static byte initializeEntityActivationType(Entity entity) { ++ if (entity instanceof EntityMonster || entity instanceof EntitySlime) { ++ return 1; // Monster ++ } else if (entity instanceof EntityCreature || entity instanceof EntityAmbient) { ++ return 2; // Animal ++ } else { ++ return 3; // Misc ++ } ++ } ++ ++ /** ++ * These entities are excluded from Activation range checks. ++ * ++ * @param entity ++ * @param world ++ * @return boolean If it should always tick. ++ */ ++ public static boolean initializeEntityActivationState(Entity entity, CraftWorld world) { ++ if ( (entity.activationType == 3 && world.miscEntityActivationRange == 0) ++ || (entity.activationType == 2 && world.animalEntityActivationRange == 0) ++ || (entity.activationType == 1 && world.monsterEntityActivationRange == 0) ++ || entity instanceof EntityHuman ++ || entity instanceof EntityItemFrame ++ || entity instanceof EntityProjectile ++ || entity instanceof EntityEnderDragon ++ || entity instanceof EntityComplexPart ++ || entity instanceof EntityWither ++ || entity instanceof EntityFireball ++ || entity instanceof EntityWeather ++ || entity instanceof EntityTNTPrimed ++ || entity instanceof EntityEnderCrystal ++ || entity instanceof EntityFireworks ++ ) { ++ return true; ++ } ++ ++ return false; ++ } ++ ++ /** ++ * Utility method to grow an AABB without creating a new AABB or touching ++ * the pool, so we can re-use ones we have. ++ * @param target ++ * @param source ++ * @param x ++ * @param y ++ * @param z ++ */ ++ public static void growBB(AxisAlignedBB target, AxisAlignedBB source, int x, int y, int z) { ++ target.a = source.a - x; ++ target.b = source.b - y; ++ target.c = source.c - z; ++ target.d = source.d + x; ++ target.e = source.e + y; ++ target.f = source.f + z; ++ } ++ ++ /** ++ * Find what entities are in range of the players in the world and set ++ * active if in range. ++ * @param world ++ */ ++ public static void activateEntities(World world) { ++ SpigotTimings.entityActivationCheckTimer.startTiming(); ++ final int miscActivationRange = world.getWorld().miscEntityActivationRange; ++ final int animalActivationRange = world.getWorld().animalEntityActivationRange; ++ final int monsterActivationRange = world.getWorld().monsterEntityActivationRange; ++ ++ int maxRange = Math.max(monsterActivationRange, animalActivationRange); ++ maxRange = Math.max(maxRange, miscActivationRange); ++ maxRange = Math.min((world.getWorld().viewDistance << 4) - 8, maxRange); ++ ++ for (Entity player : (List) world.players) { ++ ++ player.activatedTick = MinecraftServer.currentTick; ++ growBB(maxBB, player.boundingBox, maxRange, 256, maxRange); ++ growBB(miscBB, player.boundingBox, miscActivationRange, 256, miscActivationRange); ++ growBB(animalBB, player.boundingBox, animalActivationRange, 256, animalActivationRange); ++ growBB(monsterBB, player.boundingBox, monsterActivationRange, 256, monsterActivationRange); ++ ++ int i = MathHelper.floor(maxBB.a / 16.0D); ++ int j = MathHelper.floor(maxBB.d / 16.0D); ++ int k = MathHelper.floor(maxBB.c / 16.0D); ++ int l = MathHelper.floor(maxBB.f / 16.0D); ++ ++ for (int i1 = i; i1 <= j; ++i1) { ++ for (int j1 = k; j1 <= l; ++j1) { ++ if (world.getWorld().isChunkLoaded(i1, j1)) { ++ activateChunkEntities(world.getChunkAt(i1, j1)); ++ } ++ } ++ } ++ } ++ SpigotTimings.entityActivationCheckTimer.stopTiming(); ++ } ++ ++ /** ++ * Checks for the activation state of all entities in this chunk. ++ * @param chunk ++ */ ++ private static void activateChunkEntities(Chunk chunk) { ++ for (List slice : chunk.entitySlices) { ++ for (Entity entity : slice) { ++ if (MinecraftServer.currentTick > entity.activatedTick) { ++ if (entity.defaultActivationState) { ++ entity.activatedTick = MinecraftServer.currentTick; ++ continue; ++ } ++ switch (entity.activationType) { ++ case 1: ++ if (monsterBB.a(entity.boundingBox)) { ++ entity.activatedTick = MinecraftServer.currentTick; ++ } ++ break; ++ case 2: ++ if (animalBB.a(entity.boundingBox)) { ++ entity.activatedTick = MinecraftServer.currentTick; ++ } ++ break; ++ case 3: ++ default: ++ if (miscBB.a(entity.boundingBox)) { ++ entity.activatedTick = MinecraftServer.currentTick; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ /** ++ * If an entity is not in range, do some more checks to see if we should ++ * give it a shot. ++ * @param entity ++ * @return ++ */ ++ public static boolean checkEntityImmunities(Entity entity) { ++ // quick checks. ++ if (entity.ad /* isInWater */ || entity.fireTicks > 0) { ++ return true; ++ } ++ if (!(entity instanceof EntityArrow)) { ++ if (!entity.onGround || entity.passenger != null ++ || entity.vehicle != null) { ++ return true; ++ } ++ } else if (!((EntityArrow) entity).inGround) { ++ return true; ++ } ++ // special cases. ++ if (entity instanceof EntityLiving) { ++ EntityLiving living = (EntityLiving) entity; ++ if (living.attackTicks > 0 || living.hurtTicks > 0 || living.effects.size() > 0) { ++ return true; ++ } ++ if (entity instanceof EntityCreature && ((EntityCreature) entity).target != null) { ++ return true; ++ } ++ if (entity instanceof EntityAnimal) { ++ EntityAnimal animal = (EntityAnimal) entity; ++ if (animal.isBaby() || animal.r() /*love*/) { ++ return true; ++ } ++ if (entity instanceof EntitySheep && ((EntitySheep) entity).isSheared()) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Checks if the entity is active for this tick. ++ * @param entity ++ * @return ++ */ ++ public static boolean checkIfActive(Entity entity) { ++ SpigotTimings.checkIfActiveTimer.startTiming(); ++ int x = MathHelper.floor(entity.locX); ++ int z = MathHelper.floor(entity.locZ); ++ // Make sure not on edge of unloaded chunk ++ if (!entity.world.areChunksLoaded(x, 0, z, 16)) { ++ SpigotTimings.checkIfActiveTimer.stopTiming(); ++ return false; ++ } ++ boolean isActive = entity.activatedTick >= MinecraftServer.currentTick || entity.defaultActivationState; ++ ++ // Should this entity tick? ++ if (!isActive) { ++ if ((MinecraftServer.currentTick - entity.activatedTick - 1) % 20 == 0) { ++ // Check immunities every 20 ticks. ++ if (checkEntityImmunities(entity)) { ++ // Triggered some sort of immunity, give 20 full ticks before we check again. ++ entity.activatedTick = MinecraftServer.currentTick + 20; ++ } ++ isActive = true; ++ } ++ // Add a little performance juice to active entities. Skip 1/4 if not immune. ++ } else if (!entity.defaultActivationState && entity.ticksLived % 4 == 0 && !checkEntityImmunities(entity)) { ++ isActive = false; ++ } ++ SpigotTimings.checkIfActiveTimer.stopTiming(); ++ return isActive; + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java +index df837a3..9a1bcc5 100644 +--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java ++++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java +@@ -30,6 +30,9 @@ public class SpigotTimings { + + public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand"); + ++ public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck"); ++ public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive"); ++ + public static final HashMap entityTypeTimingMap = new HashMap(); + public static final HashMap tileEntityTypeTimingMap = new HashMap(); + public static final HashMap pluginTaskTimingMap = new HashMap(); +diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml +index 78e9a66..e568bf6 100644 +--- a/src/main/resources/configurations/bukkit.yml ++++ b/src/main/resources/configurations/bukkit.yml +@@ -46,6 +46,9 @@ world-settings: + sugar-growth-modifier: 100 + tree-growth-modifier: 100 + mushroom-growth-modifier: 100 ++ entity-activation-range-animals: 32 ++ entity-activation-range-monsters: 32 ++ entity-activation-range-misc: 16 + world: + growth-chunks-per-tick: 1000 + world_nether: +-- +1.8.1.1 + diff --git a/CraftBukkit-Patches/0027-Metrics.-Rewrite-the-Metrics-system-to-be-closer-to-.patch b/CraftBukkit-Patches/0027-Metrics.-Rewrite-the-Metrics-system-to-be-closer-to-.patch index 093d480e7..e4bcb5a19 100644 --- a/CraftBukkit-Patches/0027-Metrics.-Rewrite-the-Metrics-system-to-be-closer-to-.patch +++ b/CraftBukkit-Patches/0027-Metrics.-Rewrite-the-Metrics-system-to-be-closer-to-.patch @@ -1,27 +1,28 @@ -From ec31c15be3a7f53f13ec8e75a0480b3b956a16be Mon Sep 17 00:00:00 2001 +From 678a6d96738e6fa5ac3cacfc80ab621d3d99554e Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 23 Feb 2013 08:58:35 +1100 Subject: [PATCH] Metrics. Rewrite the Metrics system to be closer to the Bukkit version. --- - src/main/java/org/bukkit/craftbukkit/Spigot.java | 17 + + src/main/java/org/bukkit/craftbukkit/Spigot.java | 19 + src/main/java/org/spigotmc/Metrics.java | 645 +++++++++++++++++++++++ - 2 files changed, 662 insertions(+) + 2 files changed, 664 insertions(+) create mode 100644 src/main/java/org/spigotmc/Metrics.java diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java -index bc28d7b..ced4bd4 100644 +index 572527f..3171411 100644 --- a/src/main/java/org/bukkit/craftbukkit/Spigot.java +++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java -@@ -1,12 +1,19 @@ +@@ -1,10 +1,16 @@ package org.bukkit.craftbukkit; +import java.io.IOException; - import java.util.ArrayList; ++import java.util.ArrayList; import net.minecraft.server.*; import org.bukkit.command.SimpleCommandMap; import org.bukkit.configuration.file.YamlConfiguration; + import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; @@ -29,12 +30,18 @@ index bc28d7b..ced4bd4 100644 +import org.spigotmc.Metrics; public class Spigot { + static AxisAlignedBB maxBB = AxisAlignedBB.a(0,0,0,0,0,0); +@@ -12,6 +18,9 @@ public class Spigot { + static AxisAlignedBB animalBB = AxisAlignedBB.a(0,0,0,0,0,0); + static AxisAlignedBB monsterBB = AxisAlignedBB.a(0,0,0,0,0,0); + + public static boolean tabPing = false; + private static Metrics metrics; - ++ public static void initialize(CraftServer server, SimpleCommandMap commandMap, YamlConfiguration configuration) { commandMap.register("bukkit", new org.bukkit.craftbukkit.command.TicksPerSecondCommand("tps")); -@@ -30,6 +37,16 @@ public class Spigot { + +@@ -34,6 +43,16 @@ public class Spigot { server.getLogger().severe("[Spigot] You should not disable chunk-gc, unexpected behaviour may occur!"); } @@ -704,5 +711,5 @@ index 0000000..f1690a2 +} \ No newline at end of file -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0028-Watchdog-Thread.patch b/CraftBukkit-Patches/0028-Watchdog-Thread.patch index e97fe782b..da4b0cba2 100644 --- a/CraftBukkit-Patches/0028-Watchdog-Thread.patch +++ b/CraftBukkit-Patches/0028-Watchdog-Thread.patch @@ -1,31 +1,31 @@ -From bcc479e29c57f5e24066b2971a911e1e0aab02c7 Mon Sep 17 00:00:00 2001 +From 5a0d969c584b848bd8fcb62f4b3178c071801edb Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 23 Feb 2013 12:33:20 +1100 Subject: [PATCH] Watchdog Thread. --- .../java/net/minecraft/server/MinecraftServer.java | 2 + - src/main/java/org/bukkit/craftbukkit/Spigot.java | 77 +++++++++++++++++- + src/main/java/org/bukkit/craftbukkit/Spigot.java | 76 +++++++++++++++++- src/main/java/org/spigotmc/RestartCommand.java | 23 ++++++ src/main/java/org/spigotmc/WatchdogThread.java | 93 ++++++++++++++++++++++ src/main/resources/configurations/bukkit.yml | 3 + - 5 files changed, 196 insertions(+), 2 deletions(-) + 5 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/spigotmc/RestartCommand.java create mode 100644 src/main/java/org/spigotmc/WatchdogThread.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 128016f..3a6b620 100644 +index aa6a14a..6005fac 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -418,6 +418,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo - lastTick = curTime; - MinecraftServer.currentTick++; +@@ -421,6 +421,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo this.q(); + SpigotTimings.serverTickTimer.stopTiming(); + org.bukkit.CustomTimingsHandler.tick(); + org.spigotmc.WatchdogThread.tick(); } // Spigot end } else { -@@ -445,6 +446,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -448,6 +449,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo this.a(crashreport); } finally { try { @@ -34,7 +34,7 @@ index 128016f..3a6b620 100644 this.isStopped = true; } catch (Throwable throwable1) { diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java -index ced4bd4..15acc97 100644 +index 3171411..6f54f7e 100644 --- a/src/main/java/org/bukkit/craftbukkit/Spigot.java +++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java @@ -1,5 +1,6 @@ @@ -44,8 +44,8 @@ index ced4bd4..15acc97 100644 import java.io.IOException; import java.util.ArrayList; import net.minecraft.server.*; -@@ -7,16 +8,20 @@ import org.bukkit.command.SimpleCommandMap; - import org.bukkit.configuration.file.YamlConfiguration; +@@ -8,9 +9,11 @@ import org.bukkit.configuration.file.YamlConfiguration; + import java.util.List; import java.util.logging.Level; -import java.util.logging.Logger; @@ -56,9 +56,8 @@ index ced4bd4..15acc97 100644 +import org.spigotmc.WatchdogThread; public class Spigot { -+ - public static boolean tabPing = false; - private static Metrics metrics; + static AxisAlignedBB maxBB = AxisAlignedBB.a(0,0,0,0,0,0); +@@ -23,6 +26,7 @@ public class Spigot { public static void initialize(CraftServer server, SimpleCommandMap commandMap, YamlConfiguration configuration) { commandMap.register("bukkit", new org.bukkit.craftbukkit.command.TicksPerSecondCommand("tps")); @@ -66,7 +65,7 @@ index ced4bd4..15acc97 100644 server.whitelistMessage = configuration.getString("settings.whitelist-message", server.whitelistMessage); server.stopMessage = configuration.getString("settings.stop-message", server.stopMessage); -@@ -25,12 +30,21 @@ public class Spigot { +@@ -31,12 +35,21 @@ public class Spigot { server.commandComplete = configuration.getBoolean("settings.command-complete", true); server.spamGuardExclusions = configuration.getStringList("settings.spam-exclusions"); @@ -89,9 +88,9 @@ index ced4bd4..15acc97 100644 } if (server.chunkGCPeriod == 0) { -@@ -193,4 +207,63 @@ public class Spigot { - return (entity instanceof EntityArrow && !((EntityArrow) entity).inGround); - +@@ -265,4 +278,63 @@ public class Spigot { + SpigotTimings.checkIfActiveTimer.stopTiming(); + return isActive; } + + public static void restart() { @@ -282,7 +281,7 @@ index 0000000..10390b8 + } +} diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml -index 54e28db..e04ebce 100644 +index e568bf6..7c18391 100644 --- a/src/main/resources/configurations/bukkit.yml +++ b/src/main/resources/configurations/bukkit.yml @@ -31,6 +31,9 @@ settings: @@ -296,5 +295,5 @@ index 54e28db..e04ebce 100644 default: growth-chunks-per-tick: 650 -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0029-Netty.patch b/CraftBukkit-Patches/0029-Netty.patch index 4ef5def86..ba72d05e0 100644 --- a/CraftBukkit-Patches/0029-Netty.patch +++ b/CraftBukkit-Patches/0029-Netty.patch @@ -1,4 +1,4 @@ -From d8aa2999094cf94e7a231d7ff5bd0b034ba5ba8a Mon Sep 17 00:00:00 2001 +From 9f7d30b2630ab0b4f7f3f650456f08dd6c6409b6 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 14 Feb 2013 17:32:20 +1100 Subject: [PATCH] Netty @@ -223,10 +223,10 @@ index 58d30eb..e4e5049 100644 // CraftBukkit end this.pendingConnection = pendingconnection; diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java -index 15acc97..dbc3e48 100644 +index 6f54f7e..2ba6c14 100644 --- a/src/main/java/org/bukkit/craftbukkit/Spigot.java +++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java -@@ -18,6 +18,8 @@ public class Spigot { +@@ -23,6 +23,8 @@ public class Spigot { public static boolean tabPing = false; private static Metrics metrics; @@ -235,7 +235,7 @@ index 15acc97..dbc3e48 100644 public static void initialize(CraftServer server, SimpleCommandMap commandMap, YamlConfiguration configuration) { commandMap.register("bukkit", new org.bukkit.craftbukkit.command.TicksPerSecondCommand("tps")); -@@ -53,6 +55,12 @@ public class Spigot { +@@ -58,6 +60,12 @@ public class Spigot { tabPing = configuration.getBoolean("settings.tab-ping", tabPing); @@ -1185,7 +1185,7 @@ index 0000000..5dc3754 + DATA; +} diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml -index e04ebce..7ccac52 100644 +index 7c18391..45a8a00 100644 --- a/src/main/resources/configurations/bukkit.yml +++ b/src/main/resources/configurations/bukkit.yml @@ -34,6 +34,8 @@ settings: @@ -1198,5 +1198,5 @@ index e04ebce..7ccac52 100644 default: growth-chunks-per-tick: 650 -- -1.8.1-rc2 +1.8.1.1 diff --git a/CraftBukkit-Patches/0030-Kick-player-on-exception-for-built-in-PluginChannels.patch b/CraftBukkit-Patches/0030-Kick-player-on-exception-for-built-in-PluginChannels.patch index 653ade811..1db74c8f1 100644 --- a/CraftBukkit-Patches/0030-Kick-player-on-exception-for-built-in-PluginChannels.patch +++ b/CraftBukkit-Patches/0030-Kick-player-on-exception-for-built-in-PluginChannels.patch @@ -1,4 +1,4 @@ -From 90a010f980ef943857f4437f64e76761ad6c37d3 Mon Sep 17 00:00:00 2001 +From f79f9c8a4b8dea443b5477c742d76f4ca8a780bb Mon Sep 17 00:00:00 2001 From: Eimref Date: Wed, 6 Feb 2013 18:59:07 -0500 Subject: [PATCH] Kick player on exception for built-in PluginChannels; Fixes @@ -9,10 +9,10 @@ Subject: [PATCH] Kick player on exception for built-in PluginChannels; Fixes 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 7ca0acf..d1e0207 100644 +index d2c2305..b960a87 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -1483,6 +1483,7 @@ public class PlayerConnection extends Connection { +@@ -1481,6 +1481,7 @@ public class PlayerConnection extends Connection { } } catch (Exception exception) { exception.printStackTrace(); @@ -20,7 +20,7 @@ index 7ca0acf..d1e0207 100644 } } else if ("MC|BSign".equals(packet250custompayload.tag)) { try { -@@ -1500,9 +1501,8 @@ public class PlayerConnection extends Connection { +@@ -1498,9 +1499,8 @@ public class PlayerConnection extends Connection { itemstack1.id = Item.WRITTEN_BOOK.id; } } catch (Exception exception1) { @@ -32,7 +32,7 @@ index 7ca0acf..d1e0207 100644 } } else { int i; -@@ -1518,6 +1518,7 @@ public class PlayerConnection extends Connection { +@@ -1516,6 +1516,7 @@ public class PlayerConnection extends Connection { } } catch (Exception exception2) { exception2.printStackTrace(); @@ -40,7 +40,7 @@ index 7ca0acf..d1e0207 100644 } } else { int j; -@@ -1541,6 +1542,7 @@ public class PlayerConnection extends Connection { +@@ -1539,6 +1540,7 @@ public class PlayerConnection extends Connection { } } catch (Exception exception3) { exception3.printStackTrace(); @@ -48,7 +48,7 @@ index 7ca0acf..d1e0207 100644 } } else { this.player.sendMessage(this.player.a("advMode.notAllowed", new Object[0])); -@@ -1564,6 +1566,7 @@ public class PlayerConnection extends Connection { +@@ -1562,6 +1564,7 @@ public class PlayerConnection extends Connection { } } catch (Exception exception4) { exception4.printStackTrace(); @@ -56,7 +56,7 @@ index 7ca0acf..d1e0207 100644 } } } else if ("MC|ItemName".equals(packet250custompayload.tag) && this.player.activeContainer instanceof ContainerAnvil) { -@@ -1588,6 +1591,7 @@ public class PlayerConnection extends Connection { +@@ -1586,6 +1589,7 @@ public class PlayerConnection extends Connection { } } catch (UnsupportedEncodingException ex) { Logger.getLogger(PlayerConnection.class.getName()).log(Level.SEVERE, "Could not parse REGISTER payload in plugin message packet", ex); @@ -64,7 +64,7 @@ index 7ca0acf..d1e0207 100644 } } else if (packet250custompayload.tag.equals("UNREGISTER")) { try { -@@ -1597,6 +1601,7 @@ public class PlayerConnection extends Connection { +@@ -1595,6 +1599,7 @@ public class PlayerConnection extends Connection { } } catch (UnsupportedEncodingException ex) { Logger.getLogger(PlayerConnection.class.getName()).log(Level.SEVERE, "Could not parse UNREGISTER payload in plugin message packet", ex); @@ -73,5 +73,5 @@ index 7ca0acf..d1e0207 100644 } else { server.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packet250custompayload.tag, packet250custompayload.data); -- -1.8.1-rc2 +1.8.1.1